Scippy

SCIP

Solving Constraint Integer Programs

scip_var.c
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-2025 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file scip_var.c
26 * @ingroup OTHER_CFILES
27 * @brief public methods for SCIP variables
28 * @author Tobias Achterberg
29 * @author Timo Berthold
30 * @author Gerald Gamrath
31 * @author Leona Gottwald
32 * @author Stefan Heinz
33 * @author Gregor Hendel
34 * @author Thorsten Koch
35 * @author Alexander Martin
36 * @author Marc Pfetsch
37 * @author Michael Winkler
38 * @author Kati Wolter
39 * @author Rolf van der Hulst
40 *
41 * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE
42 */
43
44/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
45
46#include <ctype.h>
48#include "lpi/lpi.h"
49#include "scip/branch.h"
50#include "scip/clock.h"
51#include "scip/conflict.h"
52#include "scip/debug.h"
53#include "scip/rational.h"
54#include "scip/history.h"
55#include "scip/implics.h"
56#include "scip/lp.h"
57#include "scip/prob.h"
58#include "scip/pub_cons.h"
59#include "scip/pub_implics.h"
60#include "scip/pub_lp.h"
61#include "scip/pub_message.h"
62#include "scip/pub_misc.h"
63#include "scip/pub_tree.h"
64#include "scip/pub_var.h"
65#include "scip/relax.h"
67#include "scip/scip_exact.h"
68#include "scip/scip_general.h"
69#include "scip/scip_lp.h"
70#include "scip/scip_mem.h"
71#include "scip/scip_message.h"
72#include "scip/scip_numerics.h"
73#include "scip/scip_prob.h"
74#include "scip/scip_probing.h"
75#include "scip/scip_sol.h"
77#include "scip/scip_tree.h"
78#include "scip/scip_var.h"
79#include "scip/set.h"
80#include "scip/sol.h"
81#include "scip/solve.h"
82#include "scip/stat.h"
83#include "scip/struct_lp.h"
84#include "scip/struct_mem.h"
85#include "scip/struct_primal.h"
86#include "scip/struct_prob.h"
87#include "scip/struct_scip.h"
88#include "scip/struct_set.h"
89#include "scip/struct_stat.h"
90#include "scip/struct_tree.h"
91#include "scip/struct_var.h"
92#include "scip/tree.h"
93#include "scip/certificate.h"
94#include "scip/var.h"
95
96/** creates and captures problem variable
97 *
98 * If variable is of integral type, fractional bounds are automatically rounded.
99 * An integer variable with bounds zero and one is automatically converted into a binary variable.
100 *
101 * @warning When doing column generation and the original problem is a maximization problem, notice that SCIP will
102 * transform the problem into a minimization problem by multiplying the objective function by -1. Thus, the
103 * original objective function value of variables created during the solving process has to be multiplied by
104 * -1, too.
105 *
106 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
107 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
108 *
109 * @pre This method can be called if @p scip is in one of the following stages:
110 * - \ref SCIP_STAGE_PROBLEM
111 * - \ref SCIP_STAGE_TRANSFORMING
112 * - \ref SCIP_STAGE_INITPRESOLVE
113 * - \ref SCIP_STAGE_PRESOLVING
114 * - \ref SCIP_STAGE_EXITPRESOLVE
115 * - \ref SCIP_STAGE_PRESOLVED
116 * - \ref SCIP_STAGE_SOLVING
117 *
118 * @note the variable gets captured, hence at one point you have to release it using the method SCIPreleaseVar()
119 */
121 SCIP* scip, /**< SCIP data structure */
122 SCIP_VAR** var, /**< pointer to variable object */
123 const char* name, /**< name of variable, or NULL for automatic name creation */
124 SCIP_Real lb, /**< lower bound of variable */
125 SCIP_Real ub, /**< upper bound of variable */
126 SCIP_Real obj, /**< objective function value */
127 SCIP_VARTYPE vartype, /**< type of variable */
128 SCIP_Bool initial, /**< should var's column be present in the initial root LP? */
129 SCIP_Bool removable, /**< is var's column removable from the LP (due to aging or cleanup)? */
130 SCIP_DECL_VARDELORIG ((*vardelorig)), /**< frees user data of original variable, or NULL */
131 SCIP_DECL_VARTRANS ((*vartrans)), /**< creates transformed user data by transforming original user data, or NULL */
132 SCIP_DECL_VARDELTRANS ((*vardeltrans)), /**< frees user data of transformed variable, or NULL */
133 SCIP_DECL_VARCOPY ((*varcopy)), /**< copies variable data if wanted to subscip, or NULL */
134 SCIP_VARDATA* vardata /**< user data for this specific variable, or NULL */
135 )
136{
137 assert(var != NULL);
138 assert(lb <= ub);
139
141
143 /* For now, we help users and automatically convert the variable to an implied integral one if they are using the
144 * deprecated variable type. This feature will be deprecated in a future version */
145 if( vartype == SCIP_DEPRECATED_VARTYPE_IMPLINT )
146 {
147 vartype = SCIP_VARTYPE_CONTINUOUS;
148 impltype = SCIP_IMPLINTTYPE_WEAK;
149 }
150 SCIP_CALL( SCIPcreateVarImpl(scip, var, name, lb, ub, obj, vartype, impltype,
151 initial, removable, vardelorig, vartrans, vardeltrans, varcopy, vardata) );
152 return SCIP_OKAY;
153}
154
155/** creates and captures problem variable without setting optional callbacks and variable data.
156 *
157 * Callbacks and variable data can be set in the following using SCIPvarSetDelorigData(), SCIPvarSetTransData(),
158 * SCIPvarSetDeltransData(), SCIPvarSetCopy(), and SCIPvarSetData().
159 *
160 * Variable flags are set as initial = TRUE and removable = FALSE, and can be adjusted by using SCIPvarSetInitial() and SCIPvarSetRemovable(), resp.
161 *
162 * If variable is of integral type, fractional bounds are automatically rounded.
163 * An integer variable with bounds zero and one is automatically converted into a binary variable.
164 *
165 * @warning When doing column generation and the original problem is a maximization problem, notice that SCIP will
166 * transform the problem into a minimization problem by multiplying the objective function by -1. Thus, the
167 * original objective function value of variables created during the solving process has to be multiplied by
168 * -1, too.
169 *
170 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
171 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
172 *
173 * @pre This method can be called if @p scip is in one of the following stages:
174 * - \ref SCIP_STAGE_PROBLEM
175 * - \ref SCIP_STAGE_TRANSFORMING
176 * - \ref SCIP_STAGE_INITPRESOLVE
177 * - \ref SCIP_STAGE_PRESOLVING
178 * - \ref SCIP_STAGE_EXITPRESOLVE
179 * - \ref SCIP_STAGE_PRESOLVED
180 * - \ref SCIP_STAGE_SOLVING
181 *
182 * @note the variable gets captured, hence at one point you have to release it using the method SCIPreleaseVar()
183 */
185 SCIP* scip, /**< SCIP data structure */
186 SCIP_VAR** var, /**< pointer to variable object */
187 const char* name, /**< name of variable, or NULL for automatic name creation */
188 SCIP_Real lb, /**< lower bound of variable */
189 SCIP_Real ub, /**< upper bound of variable */
190 SCIP_Real obj, /**< objective function value */
191 SCIP_VARTYPE vartype /**< type of variable */
192 )
193{
194 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateVarBasic", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
195
196 SCIP_CALL( SCIPcreateVar(scip, var, name, lb, ub, obj, vartype, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
197
198 return SCIP_OKAY;
199}
200
201/** creates and captures problem variable that may be implied integral
202 *
203 * If variable is of integral type, fractional bounds are automatically rounded.
204 * An integer variable with bounds zero and one is automatically converted into a binary variable.
205 *
206 * @warning When doing column generation and the original problem is a maximization problem, notice that SCIP will
207 * transform the problem into a minimization problem by multiplying the objective function by -1. Thus, the
208 * original objective function value of variables created during the solving process has to be multiplied by
209 * -1, too.
210 *
211 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
212 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
213 *
214 * @pre This method can be called if @p scip is in one of the following stages:
215 * - \ref SCIP_STAGE_PROBLEM
216 * - \ref SCIP_STAGE_TRANSFORMING
217 * - \ref SCIP_STAGE_INITPRESOLVE
218 * - \ref SCIP_STAGE_PRESOLVING
219 * - \ref SCIP_STAGE_EXITPRESOLVE
220 * - \ref SCIP_STAGE_PRESOLVED
221 * - \ref SCIP_STAGE_SOLVING
222 *
223 * @note the variable gets captured, hence at one point you have to release it using the method SCIPreleaseVar()
224 */
226 SCIP* scip, /**< SCIP data structure */
227 SCIP_VAR** var, /**< pointer to variable object */
228 const char* name, /**< name of variable, or NULL for automatic name creation */
229 SCIP_Real lb, /**< lower bound of variable */
230 SCIP_Real ub, /**< upper bound of variable */
231 SCIP_Real obj, /**< objective function value */
232 SCIP_VARTYPE vartype, /**< type of variable */
233 SCIP_IMPLINTTYPE impltype, /**< implied integral type of the variable */
234 SCIP_Bool initial, /**< should var's column be present in the initial root LP? */
235 SCIP_Bool removable, /**< is var's column removable from the LP (due to aging or cleanup)? */
236 SCIP_DECL_VARDELORIG ((*vardelorig)), /**< frees user data of original variable, or NULL */
237 SCIP_DECL_VARTRANS ((*vartrans)), /**< creates transformed user data by transforming original user data, or NULL */
238 SCIP_DECL_VARDELTRANS ((*vardeltrans)), /**< frees user data of transformed variable, or NULL */
239 SCIP_DECL_VARCOPY ((*varcopy)), /**< copies variable data if wanted to subscip, or NULL */
240 SCIP_VARDATA* vardata /**< user data for this specific variable */
241 )
242{
243 assert(var != NULL);
244 assert(lb <= ub);
245
246 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateVarImpl", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
247
248 /* forbid infinite objective function values */
249 if( SCIPisInfinity(scip, REALABS(obj)) )
250 {
251 SCIPerrorMessage("invalid objective function value: value is infinite\n");
252 return SCIP_INVALIDDATA;
253 }
254 if( vartype == SCIP_DEPRECATED_VARTYPE_IMPLINT )
255 {
256 SCIPerrorMessage("using SCIP_VARTYPE_IMPLINT deprecated, define impltype instead\n");
257 return SCIP_INVALIDDATA;
258 }
259
260 switch( scip->set->stage )
261 {
263 SCIP_CALL( SCIPvarCreateOriginal(var, scip->mem->probmem, scip->set, scip->stat,
264 name, lb, ub, obj, vartype, impltype, initial, removable, vardelorig, vartrans, vardeltrans, varcopy, vardata) );
265 break;
266
273 SCIP_CALL( SCIPvarCreateTransformed(var, scip->mem->probmem, scip->set, scip->stat,
274 name, lb, ub, obj, vartype, impltype, initial, removable, vardelorig, vartrans, vardeltrans, varcopy, vardata) );
275 break;
276
277 default:
278 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
279 return SCIP_INVALIDCALL;
280 } /*lint !e788*/
281
282 return SCIP_OKAY;
283}
284
285/** adds exact data to variable
286 *
287 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
288 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
289 *
290 * @pre This method can be called if @p scip is in one of the following stages:
291 * - \ref SCIP_STAGE_PROBLEM
292 * - \ref SCIP_STAGE_TRANSFORMING
293 * - \ref SCIP_STAGE_INITPRESOLVE
294 * - \ref SCIP_STAGE_PRESOLVING
295 * - \ref SCIP_STAGE_EXITPRESOLVE
296 * - \ref SCIP_STAGE_PRESOLVED
297 * - \ref SCIP_STAGE_SOLVING
298 */
300 SCIP* scip, /**< SCIP data structure */
301 SCIP_VAR* var, /**< pointer to variable */
302 SCIP_RATIONAL* lb, /**< lower bound of variable */
303 SCIP_RATIONAL* ub, /**< upper bound of variable */
304 SCIP_RATIONAL* obj /**< objective function value */
305 )
306{
307 assert(var != NULL);
308 assert(lb == NULL || ub == NULL || SCIPrationalIsLE(lb, ub));
309
310 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarExactData", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
311
312 /* real objective should be finite but abort anyway */
313 assert(obj != NULL || !SCIPisInfinity(scip, REALABS(SCIPvarGetObj(var))));
314
315 /* forbid infinite objective function values */
316 if( (obj != NULL && SCIPrationalIsAbsInfinity(obj)) || (obj == NULL && SCIPisInfinity(scip, REALABS(SCIPvarGetObj(var)))) )
317 {
318 SCIPerrorMessage("invalid objective coefficient: value is infinite\n");
319 return SCIP_INVALIDDATA;
320 }
321
322 switch( scip->set->stage )
323 {
331 SCIP_CALL( SCIPvarAddExactData(var, scip->mem->probmem, lb, ub, obj) );
332 break;
333
334 default:
335 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
336 return SCIP_INVALIDCALL;
337 } /*lint !e788*/
338
339 return SCIP_OKAY;
340}
341
342/** outputs the variable name to the file stream
343 *
344 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
345 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
346 *
347 * @pre This method can be called if @p scip is in one of the following stages:
348 * - \ref SCIP_STAGE_PROBLEM
349 * - \ref SCIP_STAGE_TRANSFORMING
350 * - \ref SCIP_STAGE_TRANSFORMED
351 * - \ref SCIP_STAGE_INITPRESOLVE
352 * - \ref SCIP_STAGE_PRESOLVING
353 * - \ref SCIP_STAGE_EXITPRESOLVE
354 * - \ref SCIP_STAGE_PRESOLVED
355 * - \ref SCIP_STAGE_INITSOLVE
356 * - \ref SCIP_STAGE_SOLVING
357 * - \ref SCIP_STAGE_SOLVED
358 * - \ref SCIP_STAGE_EXITSOLVE
359 * - \ref SCIP_STAGE_FREETRANS
360 */
362 SCIP* scip, /**< SCIP data structure */
363 FILE* file, /**< output file, or NULL for stdout */
364 SCIP_VAR* var, /**< variable to output */
365 SCIP_Bool type /**< should the variable type be also posted */
366 )
367{
368 assert(scip != NULL);
369 assert(var != NULL);
370
371 SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarName", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
372
373 /* print variable name */
374 if( SCIPvarIsNegated(var) )
375 {
376 SCIP_VAR* negatedvar;
377
378 SCIP_CALL( SCIPgetNegatedVar(scip, var, &negatedvar) );
379 SCIPinfoMessage(scip, file, "<~%s>", SCIPvarGetName(negatedvar));
380 }
381 else
382 {
383 SCIPinfoMessage(scip, file, "<%s>", SCIPvarGetName(var));
384 }
385
386 if( type )
387 {
388 /* print variable type */
389 SCIPinfoMessage(scip, file, "[%c]",
393 }
394
395 return SCIP_OKAY;
396}
397
398/** print the given list of variables to output stream separated by the given delimiter character;
399 *
400 * i. e. the variables x1, x2, ..., xn with given delimiter ',' are written as: <x1>, <x2>, ..., <xn>;
401 *
402 * the method SCIPparseVarsList() can parse such a string
403 *
404 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
405 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
406 *
407 * @pre This method can be called if @p scip is in one of the following stages:
408 * - \ref SCIP_STAGE_PROBLEM
409 * - \ref SCIP_STAGE_TRANSFORMING
410 * - \ref SCIP_STAGE_TRANSFORMED
411 * - \ref SCIP_STAGE_INITPRESOLVE
412 * - \ref SCIP_STAGE_PRESOLVING
413 * - \ref SCIP_STAGE_EXITPRESOLVE
414 * - \ref SCIP_STAGE_PRESOLVED
415 * - \ref SCIP_STAGE_INITSOLVE
416 * - \ref SCIP_STAGE_SOLVING
417 * - \ref SCIP_STAGE_SOLVED
418 * - \ref SCIP_STAGE_EXITSOLVE
419 * - \ref SCIP_STAGE_FREETRANS
420 *
421 * @note The printing process is done via the message handler system.
422 */
424 SCIP* scip, /**< SCIP data structure */
425 FILE* file, /**< output file, or NULL for stdout */
426 SCIP_VAR** vars, /**< variable array to output */
427 int nvars, /**< number of variables */
428 SCIP_Bool type, /**< should the variable type be also posted */
429 char delimiter /**< character which is used for delimitation */
430 )
431{
432 int v;
433
434 SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsList", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
435
436 for( v = 0; v < nvars; ++v )
437 {
438 if( v > 0 )
439 {
440 SCIPinfoMessage(scip, file, "%c", delimiter);
441 }
442
443 /* print variable name */
444 SCIP_CALL( SCIPwriteVarName(scip, file, vars[v], type) );
445 }
446
447 return SCIP_OKAY;
448}
449
450/** print the given variables and coefficients as linear sum in the following form
451 * c1 <x1> + c2 <x2> ... + cn <xn>
452 *
453 * This string can be parsed by the method SCIPparseVarsLinearsum().
454 *
455 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
456 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
457 *
458 * @pre This method can be called if @p scip is in one of the following stages:
459 * - \ref SCIP_STAGE_PROBLEM
460 * - \ref SCIP_STAGE_TRANSFORMING
461 * - \ref SCIP_STAGE_TRANSFORMED
462 * - \ref SCIP_STAGE_INITPRESOLVE
463 * - \ref SCIP_STAGE_PRESOLVING
464 * - \ref SCIP_STAGE_EXITPRESOLVE
465 * - \ref SCIP_STAGE_PRESOLVED
466 * - \ref SCIP_STAGE_INITSOLVE
467 * - \ref SCIP_STAGE_SOLVING
468 * - \ref SCIP_STAGE_SOLVED
469 * - \ref SCIP_STAGE_EXITSOLVE
470 * - \ref SCIP_STAGE_FREETRANS
471 *
472 * @note The printing process is done via the message handler system.
473 */
475 SCIP* scip, /**< SCIP data structure */
476 FILE* file, /**< output file, or NULL for stdout */
477 SCIP_VAR** vars, /**< variable array to output */
478 SCIP_Real* vals, /**< array of coefficients or NULL if all coefficients are 1.0 */
479 int nvars, /**< number of variables */
480 SCIP_Bool type /**< should the variable type be also posted */
481 )
482{
483 int v;
484
485 SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsLinearsum", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
486
487 for( v = 0; v < nvars; ++v )
488 {
489 if( vals != NULL )
490 {
491 if( vals[v] == 1.0 )
492 {
493 if( v > 0 )
494 SCIPinfoMessage(scip, file, " +");
495 }
496 else if( vals[v] == -1.0 )
497 SCIPinfoMessage(scip, file, " -");
498 else
499 SCIPinfoMessage(scip, file, " %+.15g", vals[v]);
500 }
501 else if( v > 0 )
502 SCIPinfoMessage(scip, file, " +");
503
504 /* print variable name */
505 SCIP_CALL( SCIPwriteVarName(scip, file, vars[v], type) );
506 }
507
508 return SCIP_OKAY;
509}
510
511/** print the given variables and rational coefficients as linear sum in the following form
512 * c1 <x1> + c2 <x2> ... + cn <xn>
513 *
514 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
515 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
516 *
517 * @pre This method can be called if @p scip is in one of the following stages:
518 * - \ref SCIP_STAGE_PROBLEM
519 * - \ref SCIP_STAGE_TRANSFORMING
520 * - \ref SCIP_STAGE_TRANSFORMED
521 * - \ref SCIP_STAGE_INITPRESOLVE
522 * - \ref SCIP_STAGE_PRESOLVING
523 * - \ref SCIP_STAGE_EXITPRESOLVE
524 * - \ref SCIP_STAGE_PRESOLVED
525 * - \ref SCIP_STAGE_INITSOLVE
526 * - \ref SCIP_STAGE_SOLVING
527 * - \ref SCIP_STAGE_SOLVED
528 * - \ref SCIP_STAGE_EXITSOLVE
529 * - \ref SCIP_STAGE_FREETRANS
530 *
531 * @note The printing process is done via the message handler system.
532 */
534 SCIP* scip, /**< SCIP data structure */
535 FILE* file, /**< output file, or NULL for stdout */
536 SCIP_VAR** vars, /**< variable array to output */
537 SCIP_RATIONAL** vals, /**< array of coefficients or NULL if all coefficients are 1.0 */
538 int nvars, /**< number of variables */
539 SCIP_Bool type /**< should the variable type be also posted */
540 )
541{
542 int v;
543
544 SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsLinearsumExact", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
545
546 for( v = 0; v < nvars; ++v )
547 {
548 if( vals != NULL )
549 {
550 if( SCIPrationalIsEQReal(vals[v], 1.0) )
551 {
552 if( v > 0 )
553 SCIPinfoMessage(scip, file, " +");
554 }
555 else if( SCIPrationalIsEQReal(vals[v], -1.0) )
556 SCIPinfoMessage(scip, file, " -");
557 else
558 {
559 SCIPinfoMessage(scip, file, " ");
560 if( !SCIPrationalIsNegative(vals[v]) )
561 SCIPinfoMessage(scip, file, "+");
563 }
564 }
565 else if( v > 0 )
566 SCIPinfoMessage(scip, file, " +");
567
568 /* print variable name */
569 SCIP_CALL( SCIPwriteVarName(scip, file, vars[v], type) );
570 }
571
572 return SCIP_OKAY;
573}
574
575/** print the given monomials as polynomial in the following form
576 * c1 <x11>^e11 <x12>^e12 ... <x1n>^e1n + c2 <x21>^e21 <x22>^e22 ... + ... + cn <xn1>^en1 ...
577 *
578 * This string can be parsed by the method SCIPparseVarsPolynomial().
579 *
580 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
581 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
582 *
583 * @pre This method can be called if @p scip is in one of the following stages:
584 * - \ref SCIP_STAGE_PROBLEM
585 * - \ref SCIP_STAGE_TRANSFORMING
586 * - \ref SCIP_STAGE_TRANSFORMED
587 * - \ref SCIP_STAGE_INITPRESOLVE
588 * - \ref SCIP_STAGE_PRESOLVING
589 * - \ref SCIP_STAGE_EXITPRESOLVE
590 * - \ref SCIP_STAGE_PRESOLVED
591 * - \ref SCIP_STAGE_INITSOLVE
592 * - \ref SCIP_STAGE_SOLVING
593 * - \ref SCIP_STAGE_SOLVED
594 * - \ref SCIP_STAGE_EXITSOLVE
595 * - \ref SCIP_STAGE_FREETRANS
596 *
597 * @note The printing process is done via the message handler system.
598 */
600 SCIP* scip, /**< SCIP data structure */
601 FILE* file, /**< output file, or NULL for stdout */
602 SCIP_VAR*** monomialvars, /**< arrays with variables for each monomial */
603 SCIP_Real** monomialexps, /**< arrays with variable exponents, or NULL if always 1.0 */
604 SCIP_Real* monomialcoefs, /**< array with monomial coefficients */
605 int* monomialnvars, /**< array with number of variables for each monomial */
606 int nmonomials, /**< number of monomials */
607 SCIP_Bool type /**< should the variable type be also posted */
608 )
609{
610 int i;
611 int v;
612
613 assert(scip != NULL);
614 assert(monomialvars != NULL || nmonomials == 0);
615 assert(monomialcoefs != NULL || nmonomials == 0);
616 assert(monomialnvars != NULL || nmonomials == 0);
617
618 SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsPolynomial", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
619
620 if( nmonomials == 0 )
621 {
622 SCIPinfoMessage(scip, file, " 0 ");
623 return SCIP_OKAY;
624 }
625
626 for( i = 0; i < nmonomials; ++i )
627 {
628 if( monomialcoefs[i] == 1.0 ) /*lint !e613*/
629 {
630 if( i > 0 )
631 SCIPinfoMessage(scip, file, " +");
632 }
633 else if( monomialcoefs[i] == -1.0 ) /*lint !e613*/
634 SCIPinfoMessage(scip, file, " -");
635 else
636 SCIPinfoMessage(scip, file, " %+.15g", monomialcoefs[i]); /*lint !e613*/
637
638 assert(monomialvars[i] != NULL || monomialnvars[i] == 0); /*lint !e613*/
639
640 for( v = 0; v < monomialnvars[i]; ++v ) /*lint !e613*/
641 {
642 SCIP_CALL( SCIPwriteVarName(scip, file, monomialvars[i][v], type) ); /*lint !e613*/
643 if( monomialexps != NULL && monomialexps[i] != NULL && monomialexps[i][v] != 1.0 )
644 {
645 SCIPinfoMessage(scip, file, "^%.15g", monomialexps[i][v]);
646 }
647 }
648 }
649
650 return SCIP_OKAY;
651}
652
653/** parses variable information (in cip format) out of a string; if the parsing process was successful a variable is
654 * created and captured; if variable is of integral type, fractional bounds are automatically rounded; an integer
655 * variable with bounds zero and one is automatically converted into a binary variable
656 *
657 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
658 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
659 *
660 * @pre This method can be called if @p scip is in one of the following stages:
661 * - \ref SCIP_STAGE_PROBLEM
662 * - \ref SCIP_STAGE_TRANSFORMING
663 * - \ref SCIP_STAGE_INITPRESOLVE
664 * - \ref SCIP_STAGE_PRESOLVING
665 * - \ref SCIP_STAGE_EXITPRESOLVE
666 * - \ref SCIP_STAGE_PRESOLVED
667 * - \ref SCIP_STAGE_SOLVING
668 */
670 SCIP* scip, /**< SCIP data structure */
671 SCIP_VAR** var, /**< pointer to store the problem variable */
672 const char* str, /**< string to parse */
673 SCIP_Bool initial, /**< should var's column be present in the initial root LP? */
674 SCIP_Bool removable, /**< is var's column removable from the LP (due to aging or cleanup)? */
675 SCIP_DECL_VARCOPY ((*varcopy)), /**< copies variable data if wanted to subscip, or NULL */
676 SCIP_DECL_VARDELORIG ((*vardelorig)), /**< frees user data of original variable */
677 SCIP_DECL_VARTRANS ((*vartrans)), /**< creates transformed user data by transforming original user data */
678 SCIP_DECL_VARDELTRANS ((*vardeltrans)), /**< frees user data of transformed variable */
679 SCIP_VARDATA* vardata, /**< user data for this specific variable */
680 char** endptr, /**< pointer to store the final string position if successful */
681 SCIP_Bool* success /**< pointer store if the paring process was successful */
682 )
683{
684 assert(var != NULL);
685
687
688 switch( scip->set->stage )
689 {
691 SCIP_CALL( SCIPvarParseOriginal(var, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
692 str, initial, removable, varcopy, vardelorig, vartrans, vardeltrans, vardata, endptr, success) );
693 break;
694
701 SCIP_CALL( SCIPvarParseTransformed(var, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
702 str, initial, removable, varcopy, vardelorig, vartrans, vardeltrans, vardata, endptr, success) );
703 break;
704
705 default:
706 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
707 return SCIP_INVALIDCALL;
708 } /*lint !e788*/
709
710 return SCIP_OKAY;
711}
712
713/** parses the given string for a variable name and stores the variable in the corresponding pointer if such a variable
714 * exits and returns the position where the parsing stopped
715 *
716 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
717 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
718 *
719 * @pre This method can be called if @p scip is in one of the following stages:
720 * - \ref SCIP_STAGE_PROBLEM
721 * - \ref SCIP_STAGE_TRANSFORMING
722 * - \ref SCIP_STAGE_INITPRESOLVE
723 * - \ref SCIP_STAGE_PRESOLVING
724 * - \ref SCIP_STAGE_EXITPRESOLVE
725 * - \ref SCIP_STAGE_PRESOLVED
726 * - \ref SCIP_STAGE_SOLVING
727 */
729 SCIP* scip, /**< SCIP data structure */
730 const char* str, /**< string to parse */
731 SCIP_VAR** var, /**< pointer to store the problem variable, or NULL if it does not exit */
732 char** endptr /**< pointer to store the final string position if successful */
733 )
734{
735 char varname[SCIP_MAXSTRLEN];
736
737 assert(str != NULL);
738 assert(var != NULL);
739 assert(endptr != NULL);
740
741 SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarName", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
742
743 SCIPstrCopySection(str, '<', '>', varname, SCIP_MAXSTRLEN, endptr);
744 assert(*endptr != NULL);
745
746 if( *endptr == str )
747 {
748 *var = NULL;
749 return SCIP_OKAY;
750 }
751
752 /* check if we have a negated variable */
753 if( *varname == '~' )
754 {
755 SCIPdebugMsg(scip, "parsed negated variable name <%s>\n", &varname[1]);
756
757 /* search for the variable and ignore '~' */
758 (*var) = SCIPfindVar(scip, &varname[1]);
759
760 if( *var != NULL )
761 {
762 SCIP_CALL( SCIPgetNegatedVar(scip, *var, var) );
763 }
764 }
765 else
766 {
767 SCIPdebugMsg(scip, "parsed variable name <%s>\n", varname);
768
769 /* search for the variable */
770 (*var) = SCIPfindVar(scip, varname);
771 }
772
773 str = *endptr;
774
775 /* skip additional variable type marker */
776 if( *str == '[' && ( str[1] == SCIP_VARTYPE_BINARY_CHAR || str[1] == SCIP_VARTYPE_INTEGER_CHAR
777 || str[1] == SCIP_DEPRECATED_VARTYPE_IMPLINT_CHAR || str[1] == SCIP_VARTYPE_CONTINUOUS_CHAR ) && str[2] == ']' )
778 (*endptr) += 3;
779
780 return SCIP_OKAY;
781}
782
783/** parse the given string as variable list (here ',' is the delimiter)) (<x1>, <x2>, ..., <xn>) (see
784 * SCIPwriteVarsList() ); if it was successful, the pointer success is set to TRUE
785 *
786 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
787 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
788 *
789 * @pre This method can be called if @p scip is in one of the following stages:
790 * - \ref SCIP_STAGE_PROBLEM
791 * - \ref SCIP_STAGE_TRANSFORMING
792 * - \ref SCIP_STAGE_INITPRESOLVE
793 * - \ref SCIP_STAGE_PRESOLVING
794 * - \ref SCIP_STAGE_EXITPRESOLVE
795 * - \ref SCIP_STAGE_PRESOLVED
796 * - \ref SCIP_STAGE_SOLVING
797 *
798 * @note The pointer success in only set to FALSE in the case that a variable with a parsed variable name does not exist.
799 *
800 * @note If the number of (parsed) variables is greater than the available slots in the variable array, nothing happens
801 * except that the required size is stored in the corresponding integer; the reason for this approach is that we
802 * cannot reallocate memory, since we do not know how the memory has been allocated (e.g., by a C++ 'new' or SCIP
803 * memory functions).
804 */
806 SCIP* scip, /**< SCIP data structure */
807 const char* str, /**< string to parse */
808 SCIP_VAR** vars, /**< array to store the parsed variable */
809 int* nvars, /**< pointer to store number of parsed variables */
810 int varssize, /**< size of the variable array */
811 int* requiredsize, /**< pointer to store the required array size for the active variables */
812 char** endptr, /**< pointer to store the final string position if successful */
813 char delimiter, /**< character which is used for delimitation */
814 SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
815 )
816{
817 SCIP_VAR** tmpvars;
818 SCIP_VAR* var;
819 int ntmpvars = 0;
820 int v;
821
822 assert( nvars != NULL );
823 assert( requiredsize != NULL );
824 assert( endptr != NULL );
825 assert( success != NULL );
826
827 SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsList", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
828
829 /* allocate buffer memory for temporary storing the parsed variables */
830 SCIP_CALL( SCIPallocBufferArray(scip, &tmpvars, varssize) );
831
832 *success = TRUE;
833
834 do
835 {
836 *endptr = (char*)str;
837
838 /* parse variable name */
839 SCIP_CALL( SCIPparseVarName(scip, str, &var, endptr) );
840
841 if( var == NULL )
842 break;
843
844 str = *endptr;
845
846 /* store the variable in the tmp array */
847 if( ntmpvars < varssize )
848 tmpvars[ntmpvars] = var;
849
850 ntmpvars++;
851
852 SCIP_CALL( SCIPskipSpace((char**)&str) );
853 }
854 while( *str == delimiter );
855
856 *endptr = (char*)str;
857
858 /* if all variable name searches were successful and the variable array has enough slots, copy the collected variables */
859 if( (*success) && ntmpvars <= varssize )
860 {
861 for( v = 0; v < ntmpvars; ++v )
862 vars[v] = tmpvars[v];
863
864 (*nvars) = ntmpvars;
865 }
866 else
867 (*nvars) = 0;
868
869 (*requiredsize) = ntmpvars;
870
871 /* free buffer arrays */
872 SCIPfreeBufferArray(scip, &tmpvars);
873
874 return SCIP_OKAY;
875}
876
877/** parse the given string as linear sum of variables and coefficients (c1 <x1> + c2 <x2> + ... + cn <xn>)
878 * (see SCIPwriteVarsLinearsum() ); if it was successful, the pointer success is set to TRUE
879 *
880 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
881 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
882 *
883 * @pre This method can be called if @p scip is in one of the following stages:
884 * - \ref SCIP_STAGE_PROBLEM
885 * - \ref SCIP_STAGE_TRANSFORMING
886 * - \ref SCIP_STAGE_INITPRESOLVE
887 * - \ref SCIP_STAGE_PRESOLVING
888 * - \ref SCIP_STAGE_EXITPRESOLVE
889 * - \ref SCIP_STAGE_PRESOLVED
890 * - \ref SCIP_STAGE_SOLVING
891 *
892 * @note The pointer success in only set to FALSE in the case that a variable with a parsed variable name does not exist.
893 *
894 * @note If the number of (parsed) variables is greater than the available slots in the variable array, nothing happens
895 * except that the required size is stored in the corresponding integer; the reason for this approach is that we
896 * cannot reallocate memory, since we do not know how the memory has been allocated (e.g., by a C++ 'new' or SCIP
897 * memory functions).
898 */
900 SCIP* scip, /**< SCIP data structure */
901 const char* str, /**< string to parse */
902 SCIP_VAR** vars, /**< array to store the parsed variables */
903 SCIP_Real* vals, /**< array to store the parsed coefficients */
904 int* nvars, /**< pointer to store number of parsed variables */
905 int varssize, /**< size of the variable array */
906 int* requiredsize, /**< pointer to store the required array size for the active variables */
907 char** endptr, /**< pointer to store the final string position if successful */
908 SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
909 )
910{
911 SCIP_VAR*** monomialvars;
912 SCIP_Real** monomialexps;
913 SCIP_Real* monomialcoefs;
914 int* monomialnvars;
915 int nmonomials;
916
917 SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsLinearsum", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
918
919 assert(scip != NULL);
920 assert(str != NULL);
921 assert(vars != NULL || varssize == 0);
922 assert(vals != NULL || varssize == 0);
923 assert(nvars != NULL);
924 assert(requiredsize != NULL);
925 assert(endptr != NULL);
926 assert(success != NULL);
927
928 *requiredsize = 0;
929
930 SCIP_CALL( SCIPparseVarsPolynomial(scip, str, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, &nmonomials, endptr, success) );
931
932 if( !*success )
933 {
934 assert(nmonomials == 0); /* SCIPparseVarsPolynomial should have freed all buffers, so no need to call free here */
935 return SCIP_OKAY;
936 }
937
938 /* check if linear sum is just "0" */
939 if( nmonomials == 1 && monomialnvars[0] == 0 && monomialcoefs[0] == 0.0 )
940 {
941 *nvars = 0;
942 *requiredsize = 0;
943
944 SCIPfreeParseVarsPolynomialData(scip, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, nmonomials);
945
946 return SCIP_OKAY;
947 }
948
949 *nvars = nmonomials;
950 *requiredsize = nmonomials;
951
952 /* if we have enough slots in the variables array, copy variables over */
953 if( varssize >= nmonomials )
954 {
955 int v;
956
957 for( v = 0; v < nmonomials; ++v )
958 {
959 if( monomialnvars[v] == 0 )
960 {
961 SCIPerrorMessage("constant in linear sum\n");
962 *success = FALSE;
963 break;
964 }
965 if( monomialnvars[v] > 1 || monomialexps[v][0] != 1.0 )
966 {
967 SCIPerrorMessage("nonlinear monomial in linear sum\n");
968 *success = FALSE;
969 break;
970 }
971 assert(monomialnvars[v] == 1);
972 assert(monomialvars[v][0] != NULL);
973 assert(monomialexps[v][0] == 1.0);
974
975 vars[v] = monomialvars[v][0]; /*lint !e613*/
976 vals[v] = monomialcoefs[v]; /*lint !e613*/
977 }
978 }
979
980 SCIPfreeParseVarsPolynomialData(scip, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, nmonomials);
981
982 return SCIP_OKAY;
983}
984
985/** parse the given string as linear sum of variables and coefficients (c1 <x1> + c2 <x2> + ... + cn <xn>)
986 * (see SCIPwriteVarsLinearsum() ); if it was successful, the pointer success is set to TRUE
987 *
988 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
989 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
990 *
991 * @pre This method can be called if @p scip is in one of the following stages:
992 * - \ref SCIP_STAGE_PROBLEM
993 * - \ref SCIP_STAGE_TRANSFORMING
994 * - \ref SCIP_STAGE_INITPRESOLVE
995 * - \ref SCIP_STAGE_PRESOLVING
996 * - \ref SCIP_STAGE_EXITPRESOLVE
997 * - \ref SCIP_STAGE_PRESOLVED
998 * - \ref SCIP_STAGE_SOLVING
999 *
1000 * @note The pointer success in only set to FALSE in the case that a variable with a parsed variable name does not exist.
1001 *
1002 * @note If the number of (parsed) variables is greater than the available slots in the variable array, nothing happens
1003 * except that the required size is stored in the corresponding integer; the reason for this approach is that we
1004 * cannot reallocate memory, since we do not know how the memory has been allocated (e.g., by a C++ 'new' or SCIP
1005 * memory functions).
1006 */
1008 SCIP* scip, /**< SCIP data structure */
1009 char* str, /**< string to parse */
1010 SCIP_VAR** vars, /**< array to store the parsed variables */
1011 SCIP_RATIONAL** vals, /**< array to store the parsed coefficients */
1012 int* nvars, /**< pointer to store number of parsed variables */
1013 int varssize, /**< size of the variable array */
1014 int* requiredsize, /**< pointer to store the required array size for the active variables */
1015 char** endptr, /**< pointer to store the final string position if successful */
1016 SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
1017 )
1018{
1019 SCIP_VAR*** monomialvars;
1020 SCIP_RATIONAL** monomialcoefs;
1021 int nmonomials;
1022
1023 SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsLinearsumExact", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1024
1025 assert(scip != NULL);
1026 assert(str != NULL);
1027 assert(vars != NULL || varssize == 0);
1028 assert(vals != NULL || varssize == 0);
1029 assert(nvars != NULL);
1030 assert(requiredsize != NULL);
1031 assert(endptr != NULL);
1032 assert(success != NULL);
1033
1034 *requiredsize = 0;
1035
1036 SCIP_CALL( SCIPparseVarsPolynomialExact(scip, str, &monomialvars, &monomialcoefs, &nmonomials, endptr, success) );
1037
1038 if( !*success )
1039 {
1040 assert(nmonomials == 0); /* SCIPparseVarsPolynomial should have freed all buffers, so no need to call free here */
1041 return SCIP_OKAY;
1042 }
1043
1044 /* check if linear sum is just "0" */
1045 if( nmonomials == 1 && SCIPrationalIsZero(monomialcoefs[0]) )
1046 {
1047 *nvars = 0;
1048 *requiredsize = 0;
1049
1050 SCIPfreeParseVarsPolynomialDataExact(scip, &monomialvars, &monomialcoefs, nmonomials);
1051
1052 return SCIP_OKAY;
1053 }
1054
1055 *nvars = nmonomials;
1056 *requiredsize = nmonomials;
1057
1058 /* if we have enough slots in the variables array, copy variables over */
1059 if( varssize >= nmonomials )
1060 {
1061 int v;
1062
1063 for( v = 0; v < nmonomials; ++v )
1064 {
1065 assert(monomialvars[v][0] != NULL);
1066
1067 vars[v] = monomialvars[v][0]; /*lint !e613*/
1068 SCIPrationalSetRational(vals[v], monomialcoefs[v]); /*lint !e613*/
1069 }
1070 }
1071
1072 SCIPfreeParseVarsPolynomialDataExact(scip, &monomialvars, &monomialcoefs, nmonomials);
1073
1074 return SCIP_OKAY;
1075}
1076
1077/** parse the given string as signomial of variables and coefficients
1078 * (c1 <x11>^e11 <x12>^e12 ... <x1n>^e1n + c2 <x21>^e21 <x22>^e22 ... + ... + cn <xn1>^en1 ...)
1079 * (see SCIPwriteVarsPolynomial()); if it was successful, the pointer success is set to TRUE
1080 *
1081 * The user has to call SCIPfreeParseVarsPolynomialData(scip, monomialvars, monomialexps,
1082 * monomialcoefs, monomialnvars, *nmonomials) short after SCIPparseVarsPolynomial to free all the
1083 * allocated memory again.
1084 *
1085 * Parsing is stopped at the end of string (indicated by the \\0-character) or when no more monomials
1086 * are recognized.
1087 *
1088 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1089 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1090 *
1091 * @pre This method can be called if @p scip is in one of the following stages:
1092 * - \ref SCIP_STAGE_PROBLEM
1093 * - \ref SCIP_STAGE_TRANSFORMING
1094 * - \ref SCIP_STAGE_INITPRESOLVE
1095 * - \ref SCIP_STAGE_PRESOLVING
1096 * - \ref SCIP_STAGE_EXITPRESOLVE
1097 * - \ref SCIP_STAGE_PRESOLVED
1098 * - \ref SCIP_STAGE_SOLVING
1099 */
1101 SCIP* scip, /**< SCIP data structure */
1102 const char* str, /**< string to parse */
1103 SCIP_VAR**** monomialvars, /**< pointer to store arrays with variables for each monomial */
1104 SCIP_Real*** monomialexps, /**< pointer to store arrays with variable exponents */
1105 SCIP_Real** monomialcoefs, /**< pointer to store array with monomial coefficients */
1106 int** monomialnvars, /**< pointer to store array with number of variables for each monomial */
1107 int* nmonomials, /**< pointer to store number of parsed monomials */
1108 char** endptr, /**< pointer to store the final string position if successful */
1109 SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
1110 )
1111{
1112 typedef enum
1113 {
1114 SCIPPARSEPOLYNOMIAL_STATE_BEGIN, /* we are at the beginning of a monomial */
1115 SCIPPARSEPOLYNOMIAL_STATE_INTERMED, /* we are in between the factors of a monomial */
1116 SCIPPARSEPOLYNOMIAL_STATE_COEF, /* we parse the coefficient of a monomial */
1117 SCIPPARSEPOLYNOMIAL_STATE_VARS, /* we parse monomial variables */
1118 SCIPPARSEPOLYNOMIAL_STATE_EXPONENT, /* we parse the exponent of a variable */
1119 SCIPPARSEPOLYNOMIAL_STATE_END, /* we are at the end the polynomial */
1120 SCIPPARSEPOLYNOMIAL_STATE_ERROR /* a parsing error occured */
1121 } SCIPPARSEPOLYNOMIAL_STATES;
1122
1123 SCIPPARSEPOLYNOMIAL_STATES state;
1124 int monomialssize;
1125
1126 /* data of currently parsed monomial */
1127 int varssize;
1128 int nvars;
1129 SCIP_VAR** vars;
1130 SCIP_Real* exponents;
1131 SCIP_Real coef;
1132
1133 assert(scip != NULL);
1134 assert(str != NULL);
1135 assert(monomialvars != NULL);
1136 assert(monomialexps != NULL);
1137 assert(monomialnvars != NULL);
1138 assert(monomialcoefs != NULL);
1139 assert(nmonomials != NULL);
1140 assert(endptr != NULL);
1141 assert(success != NULL);
1142
1143 SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsPolynomial", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1144
1145 *success = FALSE;
1146 *nmonomials = 0;
1147 monomialssize = 0;
1148 *monomialvars = NULL;
1149 *monomialexps = NULL;
1150 *monomialcoefs = NULL;
1151 *monomialnvars = NULL;
1152
1153 /* initialize state machine */
1154 state = SCIPPARSEPOLYNOMIAL_STATE_BEGIN;
1155 varssize = 0;
1156 nvars = 0;
1157 vars = NULL;
1158 exponents = NULL;
1159 coef = 0.0;
1160
1161 SCIPdebugMsg(scip, "parsing polynomial from '%s'\n", str);
1162
1163 while( *str && state != SCIPPARSEPOLYNOMIAL_STATE_END && state != SCIPPARSEPOLYNOMIAL_STATE_ERROR )
1164 {
1165 /* skip white space */
1166 SCIP_CALL( SCIPskipSpace((char**)&str) );
1167
1168 assert(state != SCIPPARSEPOLYNOMIAL_STATE_END);
1169
1170 switch( state )
1171 {
1172 case SCIPPARSEPOLYNOMIAL_STATE_BEGIN:
1173 {
1174 if( coef != 0.0 ) /*lint !e777*/
1175 {
1176 SCIPdebugMsg(scip, "push monomial with coefficient <%g> and <%d> vars\n", coef, nvars);
1177
1178 /* push previous monomial */
1179 if( monomialssize <= *nmonomials )
1180 {
1181 monomialssize = SCIPcalcMemGrowSize(scip, *nmonomials+1);
1182
1183 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, *nmonomials, monomialssize) );
1184 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, *nmonomials, monomialssize) );
1185 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, *nmonomials, monomialssize) );
1186 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, *nmonomials, monomialssize) );
1187 }
1188
1189 if( nvars > 0 )
1190 {
1191 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*monomialvars)[*nmonomials], vars, nvars) ); /*lint !e866*/
1192 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*monomialexps)[*nmonomials], exponents, nvars) ); /*lint !e866*/
1193 }
1194 else
1195 {
1196 (*monomialvars)[*nmonomials] = NULL;
1197 (*monomialexps)[*nmonomials] = NULL;
1198 }
1199 (*monomialcoefs)[*nmonomials] = coef;
1200 (*monomialnvars)[*nmonomials] = nvars;
1201 ++*nmonomials;
1202
1203 nvars = 0;
1204 coef = 0.0;
1205 }
1206
1207 if( *str == '<' )
1208 {
1209 /* there seem to come a variable at the beginning of a monomial
1210 * so assume the coefficient is 1.0
1211 */
1212 state = SCIPPARSEPOLYNOMIAL_STATE_VARS;
1213 coef = 1.0;
1214 }
1215 else if( *str == '-' || *str == '+' || isdigit((unsigned char)*str) )
1216 state = SCIPPARSEPOLYNOMIAL_STATE_COEF;
1217 else
1218 state = SCIPPARSEPOLYNOMIAL_STATE_END;
1219
1220 break;
1221 }
1222
1223 case SCIPPARSEPOLYNOMIAL_STATE_INTERMED:
1224 {
1225 if( *str == '<' )
1226 {
1227 /* there seem to come another variable */
1228 state = SCIPPARSEPOLYNOMIAL_STATE_VARS;
1229 }
1230 else if( *str == '-' || *str == '+' || isdigit((unsigned char)*str) )
1231 {
1232 /* there seem to come a coefficient, which means the next monomial */
1233 state = SCIPPARSEPOLYNOMIAL_STATE_BEGIN;
1234 }
1235 else /* since we cannot detect the symbols we stop parsing the polynomial */
1236 state = SCIPPARSEPOLYNOMIAL_STATE_END;
1237
1238 break;
1239 }
1240
1241 case SCIPPARSEPOLYNOMIAL_STATE_COEF:
1242 {
1243 if( *str == '+' && !isdigit((unsigned char)str[1]) )
1244 {
1245 /* only a plus sign, without number */
1246 coef = 1.0;
1247 ++str;
1248 }
1249 else if( *str == '-' && !isdigit((unsigned char)str[1]) )
1250 {
1251 /* only a minus sign, without number */
1252 coef = -1.0;
1253 ++str;
1254 }
1255 else if( SCIPstrToRealValue(str, &coef, endptr) )
1256 {
1257 str = *endptr;
1258 }
1259 else
1260 {
1261 SCIPerrorMessage("could not parse number in the beginning of '%s'\n", str);
1262 state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
1263 break;
1264 }
1265
1266 /* after the coefficient we go into the intermediate state, i.e., expecting next variables */
1267 state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED; /*lint !e838*/
1268
1269 break;
1270 }
1271
1272 case SCIPPARSEPOLYNOMIAL_STATE_VARS:
1273 {
1274 SCIP_VAR* var;
1275
1276 assert(*str == '<');
1277
1278 /* parse variable name */
1279 SCIP_CALL( SCIPparseVarName(scip, str, &var, endptr) );
1280
1281 /* check if variable name was parsed */
1282 if( *endptr == str )
1283 {
1284 state = SCIPPARSEPOLYNOMIAL_STATE_END;
1285 break;
1286 }
1287
1288 if( var == NULL )
1289 {
1290 SCIPerrorMessage("did not find variable in the beginning of %s\n", str);
1291 state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
1292 break;
1293 }
1294
1295 /* add variable to vars array */
1296 if( nvars + 1 > varssize )
1297 {
1298 varssize = SCIPcalcMemGrowSize(scip, nvars+1);
1299 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &vars, nvars, varssize) );
1300 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &exponents, nvars, varssize) );
1301 }
1302 assert(vars != NULL);
1303 assert(exponents != NULL);
1304
1305 vars[nvars] = var;
1306 exponents[nvars] = 1.0;
1307 ++nvars;
1308
1309 str = *endptr;
1310
1311 if( *str == '^' )
1312 state = SCIPPARSEPOLYNOMIAL_STATE_EXPONENT;
1313 else
1314 state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED;
1315
1316 break;
1317 }
1318
1319 case SCIPPARSEPOLYNOMIAL_STATE_EXPONENT:
1320 {
1321 assert(*str == '^');
1322 assert(nvars > 0); /* we should be in a monomial that has already a variable */
1323 assert(exponents != NULL);
1324 ++str;
1325
1326 if( !SCIPstrToRealValue(str, &exponents[nvars-1], endptr) )
1327 {
1328 SCIPerrorMessage("could not parse number in the beginning of '%s'\n", str);
1329 state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
1330 break;
1331 }
1332 str = *endptr;
1333
1334 /* after the exponent we go into the intermediate state, i.e., expecting next variables */
1335 state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED; /*lint !e838*/
1336 break;
1337 }
1338
1339 /* coverity[dead_error_line] */
1340 case SCIPPARSEPOLYNOMIAL_STATE_END:
1341 /* coverity[dead_error_line] */
1342 case SCIPPARSEPOLYNOMIAL_STATE_ERROR:
1343 default:
1344 SCIPerrorMessage("unexpected state\n");
1345 return SCIP_READERROR;
1346 }
1347 }
1348
1349 /* set end pointer */
1350 *endptr = (char*)str;
1351
1352 /* check state at end of string */
1353 switch( state )
1354 {
1355 case SCIPPARSEPOLYNOMIAL_STATE_BEGIN:
1356 case SCIPPARSEPOLYNOMIAL_STATE_END:
1357 case SCIPPARSEPOLYNOMIAL_STATE_INTERMED:
1358 {
1359 if( coef != 0.0 ) /*lint !e777*/
1360 {
1361 /* push last monomial */
1362 SCIPdebugMsg(scip, "push monomial with coefficient <%g> and <%d> vars\n", coef, nvars);
1363 if( monomialssize <= *nmonomials )
1364 {
1365 monomialssize = *nmonomials+1;
1366 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, *nmonomials, monomialssize) );
1367 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, *nmonomials, monomialssize) );
1368 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, *nmonomials, monomialssize) );
1369 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, *nmonomials, monomialssize) );
1370 }
1371
1372 if( nvars > 0 )
1373 {
1374 /* shrink vars and exponents array to needed size and take over ownership */
1375 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &vars, varssize, nvars) );
1376 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &exponents, varssize, nvars) );
1377 (*monomialvars)[*nmonomials] = vars;
1378 (*monomialexps)[*nmonomials] = exponents;
1379 vars = NULL;
1380 exponents = NULL;
1381 }
1382 else
1383 {
1384 (*monomialvars)[*nmonomials] = NULL;
1385 (*monomialexps)[*nmonomials] = NULL;
1386 }
1387 (*monomialcoefs)[*nmonomials] = coef;
1388 (*monomialnvars)[*nmonomials] = nvars;
1389 ++*nmonomials;
1390 }
1391
1392 *success = TRUE;
1393 break;
1394 }
1395
1396 case SCIPPARSEPOLYNOMIAL_STATE_COEF:
1397 case SCIPPARSEPOLYNOMIAL_STATE_VARS:
1398 case SCIPPARSEPOLYNOMIAL_STATE_EXPONENT:
1399 {
1400 SCIPerrorMessage("unexpected parsing state at end of polynomial string\n");
1401 }
1402 /*lint -fallthrough*/
1403 case SCIPPARSEPOLYNOMIAL_STATE_ERROR:
1404 assert(!*success);
1405 break;
1406 }
1407
1408 /* free memory to store current monomial, if still existing */
1409 SCIPfreeBlockMemoryArrayNull(scip, &vars, varssize);
1410 SCIPfreeBlockMemoryArrayNull(scip, &exponents, varssize);
1411
1412 if( *success && *nmonomials > 0 )
1413 {
1414 /* shrink arrays to required size, so we do not need to keep monomialssize around */
1415 assert(*nmonomials <= monomialssize);
1416 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, monomialssize, *nmonomials) );
1417 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, monomialssize, *nmonomials) );
1418 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, monomialssize, *nmonomials) );
1419 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, monomialssize, *nmonomials) );
1420
1421 /* SCIPwriteVarsPolynomial(scip, NULL, *monomialvars, *monomialexps, *monomialcoefs, *monomialnvars, *nmonomials, FALSE); */
1422 }
1423 else
1424 {
1425 /* in case of error, cleanup all data here */
1426 SCIPfreeParseVarsPolynomialData(scip, monomialvars, monomialexps, monomialcoefs, monomialnvars, *nmonomials);
1427 *nmonomials = 0;
1428 }
1429
1430 return SCIP_OKAY;
1431}
1432
1433/** parse the given string as signomial of variables and coefficients
1434 * (c1 <x11>^e11 <x12>^e12 ... <x1n>^e1n + c2 <x21>^e21 <x22>^e22 ... + ... + cn <xn1>^en1 ...)
1435 * (see SCIPwriteVarsPolynomial()); if it was successful, the pointer success is set to TRUE
1436 *
1437 * The user has to call SCIPfreeParseVarsPolynomialData(scip, monomialvars, monomialexps,
1438 * monomialcoefs, monomialnvars, *nmonomials) short after SCIPparseVarsPolynomial to free all the
1439 * allocated memory again.
1440 *
1441 * Parsing is stopped at the end of string (indicated by the \\0-character) or when no more monomials
1442 * are recognized.
1443 *
1444 * @pre This method can be called if @p scip is in one of the following stages:
1445 * - \ref SCIP_STAGE_PROBLEM
1446 * - \ref SCIP_STAGE_TRANSFORMING
1447 * - \ref SCIP_STAGE_INITPRESOLVE
1448 * - \ref SCIP_STAGE_PRESOLVING
1449 * - \ref SCIP_STAGE_EXITPRESOLVE
1450 * - \ref SCIP_STAGE_PRESOLVED
1451 * - \ref SCIP_STAGE_SOLVING
1452 */
1454 SCIP* scip, /**< SCIP data structure */
1455 char* str, /**< string to parse */
1456 SCIP_VAR**** monomialvars, /**< pointer to store arrays with variables for each monomial */
1457 SCIP_RATIONAL*** monomialcoefs, /**< pointer to store array with monomial coefficients */
1458 int* nmonomials, /**< pointer to store number of parsed monomials */
1459 char** endptr, /**< pointer to store the final string position if successful */
1460 SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
1461 )
1462{
1463 typedef enum
1464 {
1465 SCIPPARSEPOLYNOMIAL_STATE_BEGIN, /* we are at the beginning of a monomial */
1466 SCIPPARSEPOLYNOMIAL_STATE_INTERMED, /* we are in between the factors of a monomial */
1467 SCIPPARSEPOLYNOMIAL_STATE_COEF, /* we parse the coefficient of a monomial */
1468 SCIPPARSEPOLYNOMIAL_STATE_VARS, /* we parse monomial variables */
1469 SCIPPARSEPOLYNOMIAL_STATE_EXPONENT, /* we parse the exponent of a variable */
1470 SCIPPARSEPOLYNOMIAL_STATE_END, /* we are at the end the polynomial */
1471 SCIPPARSEPOLYNOMIAL_STATE_ERROR /* a parsing error occured */
1472 } SCIPPARSEPOLYNOMIAL_STATES;
1473
1474 SCIPPARSEPOLYNOMIAL_STATES state;
1475 int monomialssize;
1476
1477 /* data of currently parsed monomial */
1478 int varssize;
1479 int nvars;
1480 SCIP_VAR** vars;
1481 SCIP_RATIONAL* coef;
1482
1483 assert(scip != NULL);
1484 assert(str != NULL);
1485 assert(monomialvars != NULL);
1486 assert(monomialcoefs != NULL);
1487 assert(nmonomials != NULL);
1488 assert(endptr != NULL);
1489 assert(success != NULL);
1490
1491 SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsPolynomialExact", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1492
1493 *success = FALSE;
1494 *nmonomials = 0;
1495 monomialssize = 0;
1496 *monomialvars = NULL;
1497 *monomialcoefs = NULL;
1498
1499 /* initialize state machine */
1500 state = SCIPPARSEPOLYNOMIAL_STATE_BEGIN;
1501 varssize = 0;
1502 nvars = 0;
1503 vars = NULL;
1504
1506 SCIPrationalSetReal(coef, 0.0);
1507
1508 SCIPdebugMsg(scip, "parsing polynomial from '%s'\n", str);
1509
1510 while( *str && state != SCIPPARSEPOLYNOMIAL_STATE_END && state != SCIPPARSEPOLYNOMIAL_STATE_ERROR )
1511 {
1512 /* skip white space */
1513 SCIP_CALL( SCIPskipSpace((char**)&str) );
1514
1515 assert(state != SCIPPARSEPOLYNOMIAL_STATE_END);
1516
1517 switch( state )
1518 {
1519 case SCIPPARSEPOLYNOMIAL_STATE_BEGIN:
1520 {
1521 if( !SCIPrationalIsZero(coef) )
1522 {
1523 SCIPdebugMsg(scip, "push monomial with coefficient <%g> and <%d> vars\n", SCIPrationalGetReal(coef), nvars);
1524
1525 /* push previous monomial */
1526 if( monomialssize <= *nmonomials )
1527 {
1528 monomialssize = SCIPcalcMemGrowSize(scip, *nmonomials+1);
1529
1530 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, *nmonomials, monomialssize) );
1531 SCIP_CALL( SCIPrationalReallocBlockArray(SCIPblkmem(scip), monomialcoefs, *nmonomials, monomialssize) );
1532 }
1533
1534 if( nvars > 0 )
1535 {
1536 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*monomialvars)[*nmonomials], vars, nvars) ); /*lint !e866*/
1537 }
1538 else
1539 {
1540 (*monomialvars)[*nmonomials] = NULL;
1541 }
1542
1543 SCIPrationalSetRational((*monomialcoefs)[*nmonomials], coef);
1544 ++*nmonomials;
1545
1546 nvars = 0;
1547 SCIPrationalSetReal(coef, 0.0);
1548 }
1549
1550 if( *str == '<' )
1551 {
1552 /* there seem to come a variable at the beginning of a monomial
1553 * so assume the coefficient is 1.0
1554 */
1555 state = SCIPPARSEPOLYNOMIAL_STATE_VARS;
1556 SCIPrationalSetString(coef, "1");
1557 }
1558 else if( *str == '-' || *str == '+' || isdigit((unsigned char)*str) )
1559 state = SCIPPARSEPOLYNOMIAL_STATE_COEF;
1560 else
1561 state = SCIPPARSEPOLYNOMIAL_STATE_END;
1562
1563 break;
1564 }
1565
1566 case SCIPPARSEPOLYNOMIAL_STATE_INTERMED:
1567 {
1568 if( *str == '<' )
1569 {
1570 /* there seem to come another variable */
1571 state = SCIPPARSEPOLYNOMIAL_STATE_VARS;
1572 }
1573 else if( *str == '-' || *str == '+' || isdigit((unsigned char)*str) )
1574 {
1575 /* there seem to come a coefficient, which means the next monomial */
1576 state = SCIPPARSEPOLYNOMIAL_STATE_BEGIN;
1577 }
1578 else /* since we cannot detect the symbols we stop parsing the polynomial */
1579 state = SCIPPARSEPOLYNOMIAL_STATE_END;
1580
1581 break;
1582 }
1583
1584 case SCIPPARSEPOLYNOMIAL_STATE_COEF:
1585 {
1586 if( *str == '+' && !isdigit((unsigned char)str[1]) )
1587 {
1588 /* only a plus sign, without number */
1589 SCIPrationalSetString(coef, "1");
1590 ++str;
1591 }
1592 else if( *str == '-' && !isdigit((unsigned char)str[1]) )
1593 {
1594 /* only a minus sign, without number */
1595 SCIPrationalSetString(coef, "-1");
1596 ++str;
1597 }
1598 else if( SCIPstrToRationalValue(str, coef, endptr) )
1599 {
1600 str = *endptr;
1601 }
1602 else
1603 {
1604 SCIPerrorMessage("could not parse number in the beginning of '%s'\n", str);
1605 state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
1606 break;
1607 }
1608
1609 /* after the coefficient we go into the intermediate state, i.e., expecting next variables */
1610 state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED; /*lint !e838*/
1611
1612 break;
1613 }
1614
1615 case SCIPPARSEPOLYNOMIAL_STATE_VARS:
1616 {
1617 SCIP_VAR* var;
1618
1619 assert(*str == '<');
1620
1621 /* parse variable name */
1622 SCIP_CALL( SCIPparseVarName(scip, str, &var, endptr) );
1623
1624 /* check if variable name was parsed */
1625 if( *endptr == str )
1626 {
1627 state = SCIPPARSEPOLYNOMIAL_STATE_END;
1628 break;
1629 }
1630
1631 if( var == NULL )
1632 {
1633 SCIPerrorMessage("did not find variable in the beginning of %s\n", str);
1634 state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
1635 break;
1636 }
1637
1638 /* add variable to vars array */
1639 if( nvars + 1 > varssize )
1640 {
1641 varssize = SCIPcalcMemGrowSize(scip, nvars+1);
1642 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &vars, nvars, varssize) );
1643 }
1644 assert(vars != NULL);
1645
1646 vars[nvars] = var;
1647 ++nvars;
1648
1649 str = *endptr;
1650
1651 if( *str == '^' )
1652 state = SCIPPARSEPOLYNOMIAL_STATE_EXPONENT;
1653 else
1654 state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED;
1655
1656 break;
1657 }
1658
1659 case SCIPPARSEPOLYNOMIAL_STATE_END:
1660 case SCIPPARSEPOLYNOMIAL_STATE_ERROR:
1661 case SCIPPARSEPOLYNOMIAL_STATE_EXPONENT:
1662 default:
1663 SCIPerrorMessage("unexpected state\n");
1664 return SCIP_READERROR;
1665 }
1666 }
1667
1668 /* set end pointer */
1669 *endptr = (char*)str;
1670
1671 /* check state at end of string */
1672 switch( state )
1673 {
1674 case SCIPPARSEPOLYNOMIAL_STATE_BEGIN:
1675 case SCIPPARSEPOLYNOMIAL_STATE_END:
1676 case SCIPPARSEPOLYNOMIAL_STATE_INTERMED:
1677 {
1678 if( !SCIPrationalIsZero(coef) )
1679 {
1680 /* push last monomial */
1681 SCIPdebugMsg(scip, "push monomial with coefficient <%g> and <%d> vars\n", SCIPrationalGetReal(coef), nvars);
1682 if( monomialssize <= *nmonomials )
1683 {
1684 monomialssize = *nmonomials+1;
1685 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, *nmonomials, monomialssize) );
1686 SCIP_CALL( SCIPrationalReallocBlockArray(SCIPblkmem(scip), monomialcoefs, *nmonomials, monomialssize) );
1687 }
1688
1689 if( nvars > 0 )
1690 {
1691 /* shrink vars and exponents array to needed size and take over ownership */
1692 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &vars, varssize, nvars) );
1693 (*monomialvars)[*nmonomials] = vars;
1694 vars = NULL;
1695 }
1696 else
1697 {
1698 (*monomialvars)[*nmonomials] = NULL;
1699 }
1700 SCIPrationalSetRational((*monomialcoefs)[*nmonomials], coef);
1701 ++*nmonomials;
1702 }
1703
1704 *success = TRUE;
1705 break;
1706 }
1707
1708 case SCIPPARSEPOLYNOMIAL_STATE_COEF:
1709 case SCIPPARSEPOLYNOMIAL_STATE_VARS:
1710 case SCIPPARSEPOLYNOMIAL_STATE_EXPONENT:
1711 {
1712 SCIPerrorMessage("unexpected parsing state at end of polynomial string\n");
1713 }
1714 /*lint -fallthrough*/
1715 case SCIPPARSEPOLYNOMIAL_STATE_ERROR:
1716 assert(!*success);
1717 break;
1718 }
1719
1720 /* free memory to store current monomial, if still existing */
1721 SCIPfreeBlockMemoryArrayNull(scip, &vars, varssize);
1722
1723 if( *success && *nmonomials > 0 )
1724 {
1725 /* shrink arrays to required size, so we do not need to keep monomialssize around */
1726 assert(*nmonomials <= monomialssize);
1727 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, monomialssize, *nmonomials) );
1728 SCIP_CALL( SCIPrationalReallocBlockArray(SCIPblkmem(scip), monomialcoefs, monomialssize, *nmonomials) );
1729
1730 /* SCIPwriteVarsPolynomial(scip, NULL, *monomialvars, *monomialexps, *monomialcoefs, *monomialnvars, *nmonomials, FALSE); */
1731 }
1732 else
1733 {
1734 /* in case of error, cleanup all data here */
1735 SCIPfreeParseVarsPolynomialDataExact(scip, monomialvars, monomialcoefs, *nmonomials);
1736 *nmonomials = 0;
1737 }
1738
1740
1741 return SCIP_OKAY;
1742}
1743
1744/** frees memory allocated when parsing a signomial from a string
1745 *
1746 * @pre This method can be called if @p scip is in one of the following stages:
1747 * - \ref SCIP_STAGE_PROBLEM
1748 * - \ref SCIP_STAGE_TRANSFORMING
1749 * - \ref SCIP_STAGE_INITPRESOLVE
1750 * - \ref SCIP_STAGE_PRESOLVING
1751 * - \ref SCIP_STAGE_EXITPRESOLVE
1752 * - \ref SCIP_STAGE_PRESOLVED
1753 * - \ref SCIP_STAGE_SOLVING
1754 */
1756 SCIP* scip, /**< SCIP data structure */
1757 SCIP_VAR**** monomialvars, /**< pointer to store arrays with variables for each monomial */
1758 SCIP_Real*** monomialexps, /**< pointer to store arrays with variable exponents */
1759 SCIP_Real** monomialcoefs, /**< pointer to store array with monomial coefficients */
1760 int** monomialnvars, /**< pointer to store array with number of variables for each monomial */
1761 int nmonomials /**< pointer to store number of parsed monomials */
1762 )
1763{
1764 int i;
1765
1766 assert(scip != NULL);
1767 assert(monomialvars != NULL);
1768 assert(monomialexps != NULL);
1769 assert(monomialcoefs != NULL);
1770 assert(monomialnvars != NULL);
1771 assert(nmonomials >= 0);
1772
1773 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPfreeParseVarsPolynomialData", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1774
1775 if( nmonomials == 0 )
1776 return;
1777
1778 assert(*monomialvars != NULL);
1779 assert(*monomialexps != NULL);
1780 assert(*monomialcoefs != NULL);
1781 assert(*monomialnvars != NULL);
1782
1783 for( i = nmonomials - 1; i >= 0; --i )
1784 {
1785 SCIPfreeBlockMemoryArrayNull(scip, &(*monomialexps)[i], (*monomialnvars)[i]);
1786 SCIPfreeBlockMemoryArrayNull(scip, &(*monomialvars)[i], (*monomialnvars)[i]);
1787 }
1788
1789 SCIPfreeBlockMemoryArray(scip, monomialcoefs, nmonomials);
1790 SCIPfreeBlockMemoryArray(scip, monomialnvars, nmonomials);
1791 SCIPfreeBlockMemoryArray(scip, monomialexps, nmonomials);
1792 SCIPfreeBlockMemoryArray(scip, monomialvars, nmonomials);
1793}
1794
1795/** frees memory allocated when parsing a signomial from a string
1796 *
1797 * @pre This method can be called if @p scip is in one of the following stages:
1798 * - \ref SCIP_STAGE_PROBLEM
1799 * - \ref SCIP_STAGE_TRANSFORMING
1800 * - \ref SCIP_STAGE_INITPRESOLVE
1801 * - \ref SCIP_STAGE_PRESOLVING
1802 * - \ref SCIP_STAGE_EXITPRESOLVE
1803 * - \ref SCIP_STAGE_PRESOLVED
1804 * - \ref SCIP_STAGE_SOLVING
1805 */
1807 SCIP* scip, /**< SCIP data structure */
1808 SCIP_VAR**** monomialvars, /**< pointer to store arrays with variables for each monomial */
1809 SCIP_RATIONAL*** monomialcoefs, /**< pointer to store array with monomial coefficients */
1810 int nmonomials /**< pointer to store number of parsed monomials */
1811 )
1812{
1813 int i;
1814
1815 assert(scip != NULL);
1816 assert(monomialvars != NULL);
1817 assert(monomialcoefs != NULL);
1818 assert((*monomialvars != NULL) == (nmonomials > 0));
1819 assert((*monomialcoefs != NULL) == (nmonomials > 0));
1820
1821 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPfreeParseVarsPolynomialDataExact", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1822
1823 if( nmonomials == 0 )
1824 return;
1825
1826 for( i = nmonomials - 1; i >= 0; --i )
1827 {
1828 SCIPfreeBlockMemoryArrayNull(scip, &(*monomialvars)[i], 1);
1829 }
1830
1831 SCIPrationalFreeBlockArray(SCIPblkmem(scip), monomialcoefs, nmonomials);
1832 SCIPfreeBlockMemoryArray(scip, monomialvars, nmonomials);
1833}
1834
1835/** increases usage counter of variable
1836 *
1837 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1838 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1839 *
1840 * @pre This method can be called if @p scip is in one of the following stages:
1841 * - \ref SCIP_STAGE_PROBLEM
1842 * - \ref SCIP_STAGE_TRANSFORMING
1843 * - \ref SCIP_STAGE_TRANSFORMED
1844 * - \ref SCIP_STAGE_INITPRESOLVE
1845 * - \ref SCIP_STAGE_PRESOLVING
1846 * - \ref SCIP_STAGE_EXITPRESOLVE
1847 * - \ref SCIP_STAGE_PRESOLVED
1848 * - \ref SCIP_STAGE_INITSOLVE
1849 * - \ref SCIP_STAGE_SOLVING
1850 * - \ref SCIP_STAGE_SOLVED
1851 * - \ref SCIP_STAGE_EXITSOLVE
1852 */
1854 SCIP* scip, /**< SCIP data structure */
1855 SCIP_VAR* var /**< variable to capture */
1856 )
1857{
1858 SCIP_CALL( SCIPcheckStage(scip, "SCIPcaptureVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1859 assert(var->scip == scip);
1860
1861 SCIPvarCapture(var);
1862
1863 return SCIP_OKAY;
1864}
1865
1866/** decreases usage counter of variable, if the usage pointer reaches zero the variable gets freed
1867 *
1868 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1869 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1870 *
1871 * @pre This method can be called if @p scip is in one of the following stages:
1872 * - \ref SCIP_STAGE_PROBLEM
1873 * - \ref SCIP_STAGE_TRANSFORMING
1874 * - \ref SCIP_STAGE_TRANSFORMED
1875 * - \ref SCIP_STAGE_INITPRESOLVE
1876 * - \ref SCIP_STAGE_PRESOLVING
1877 * - \ref SCIP_STAGE_EXITPRESOLVE
1878 * - \ref SCIP_STAGE_PRESOLVED
1879 * - \ref SCIP_STAGE_INITSOLVE
1880 * - \ref SCIP_STAGE_SOLVING
1881 * - \ref SCIP_STAGE_SOLVED
1882 * - \ref SCIP_STAGE_EXITSOLVE
1883 * - \ref SCIP_STAGE_FREETRANS
1884 *
1885 * @note the pointer of the variable will be NULLed
1886 */
1888 SCIP* scip, /**< SCIP data structure */
1889 SCIP_VAR** var /**< pointer to variable */
1890 )
1891{
1892 assert(var != NULL);
1893 assert(*var != NULL);
1894 assert((*var)->scip == scip);
1895
1896 SCIP_CALL( SCIPcheckStage(scip, "SCIPreleaseVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1897
1898 switch( scip->set->stage )
1899 {
1900 case SCIP_STAGE_PROBLEM:
1901 SCIP_CALL( SCIPvarRelease(var, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp) );
1902 return SCIP_OKAY;
1903
1911 case SCIP_STAGE_SOLVING:
1912 case SCIP_STAGE_SOLVED:
1915 if( !SCIPvarIsTransformed(*var) && (*var)->nuses == 1 && (*var)->data.original.transvar != NULL )
1916 {
1917 SCIPerrorMessage("cannot release last use of original variable while associated transformed variable exists\n");
1918 return SCIP_INVALIDCALL;
1919 }
1920 SCIP_CALL( SCIPvarRelease(var, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp) );
1921 return SCIP_OKAY;
1922
1923 default:
1924 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
1925 return SCIP_INVALIDCALL;
1926 } /*lint !e788*/
1927}
1928
1929/** changes the name of a variable
1930 *
1931 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1932 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1933 *
1934 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PROBLEM
1935 *
1936 * @note to get the current name of a variable, use SCIPvarGetName() from pub_var.h
1937 */
1939 SCIP* scip, /**< SCIP data structure */
1940 SCIP_VAR* var, /**< variable */
1941 const char* name /**< new name of constraint */
1942 )
1943{
1945 assert( var->scip == scip );
1946
1948 {
1949 SCIPerrorMessage("variable names can only be changed in problem creation stage\n");
1950 SCIPABORT();
1951 return SCIP_INVALIDCALL; /*lint !e527*/
1952 }
1953
1954 /* remove variable's name from the namespace if the variable was already added */
1955 if( SCIPvarGetProbindex(var) != -1 )
1956 {
1957 SCIP_CALL( SCIPprobRemoveVarName(scip->origprob, var) );
1958 }
1959
1960 /* change variable name */
1961 SCIP_CALL( SCIPvarChgName(var, SCIPblkmem(scip), name) );
1962
1963 /* add variable's name to the namespace if the variable was already added */
1964 if( SCIPvarGetProbindex(var) != -1 )
1965 {
1966 SCIP_CALL( SCIPprobAddVarName(scip->origprob, var) );
1967 }
1968
1969 return SCIP_OKAY;
1970}
1971
1972/** gets and captures transformed variable of a given variable; if the variable is not yet transformed,
1973 * a new transformed variable for this variable is created
1974 *
1975 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1976 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1977 *
1978 * @pre This method can be called if @p scip is in one of the following stages:
1979 * - \ref SCIP_STAGE_TRANSFORMING
1980 * - \ref SCIP_STAGE_TRANSFORMED
1981 * - \ref SCIP_STAGE_INITPRESOLVE
1982 * - \ref SCIP_STAGE_PRESOLVING
1983 * - \ref SCIP_STAGE_EXITPRESOLVE
1984 * - \ref SCIP_STAGE_PRESOLVED
1985 * - \ref SCIP_STAGE_INITSOLVE
1986 * - \ref SCIP_STAGE_SOLVING
1987 */
1989 SCIP* scip, /**< SCIP data structure */
1990 SCIP_VAR* var, /**< variable to get/create transformed variable for */
1991 SCIP_VAR** transvar /**< pointer to store the transformed variable */
1992 )
1993{
1994 assert(transvar != NULL);
1995
1996 SCIP_CALL( SCIPcheckStage(scip, "SCIPtransformVar", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1997
1998 if( SCIPvarIsTransformed(var) )
1999 {
2000 *transvar = var;
2001 SCIPvarCapture(*transvar);
2002 }
2003 else
2004 {
2005 SCIP_CALL( SCIPvarTransform(var, scip->mem->probmem, scip->set, scip->stat, scip->origprob->objsense, transvar) );
2006 }
2007
2008 return SCIP_OKAY;
2009}
2010
2011/** gets and captures transformed variables for an array of variables;
2012 * if a variable of the array is not yet transformed, a new transformed variable for this variable is created;
2013 * it is possible to call this method with vars == transvars
2014 *
2015 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2016 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2017 *
2018 * @pre This method can be called if @p scip is in one of the following stages:
2019 * - \ref SCIP_STAGE_TRANSFORMING
2020 * - \ref SCIP_STAGE_TRANSFORMED
2021 * - \ref SCIP_STAGE_INITPRESOLVE
2022 * - \ref SCIP_STAGE_PRESOLVING
2023 * - \ref SCIP_STAGE_EXITPRESOLVE
2024 * - \ref SCIP_STAGE_PRESOLVED
2025 * - \ref SCIP_STAGE_INITSOLVE
2026 * - \ref SCIP_STAGE_SOLVING
2027 */
2029 SCIP* scip, /**< SCIP data structure */
2030 int nvars, /**< number of variables to get/create transformed variables for */
2031 SCIP_VAR** vars, /**< array with variables to get/create transformed variables for */
2032 SCIP_VAR** transvars /**< array to store the transformed variables */
2033 )
2034{
2035 int v;
2036
2037 assert(nvars == 0 || vars != NULL);
2038 assert(nvars == 0 || transvars != NULL);
2039
2040 SCIP_CALL( SCIPcheckStage(scip, "SCIPtransformVars", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2041
2042 for( v = 0; v < nvars; ++v )
2043 {
2044 if( SCIPvarIsTransformed(vars[v]) )
2045 {
2046 transvars[v] = vars[v];
2047 SCIPvarCapture(transvars[v]);
2048 }
2049 else
2050 {
2051 SCIP_CALL( SCIPvarTransform(vars[v], scip->mem->probmem, scip->set, scip->stat, scip->origprob->objsense,
2052 &transvars[v]) );
2053 }
2054 }
2055
2056 return SCIP_OKAY;
2057}
2058
2059/** gets corresponding transformed variable of a given variable;
2060 * returns NULL as transvar, if transformed variable is not yet existing
2061 *
2062 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2063 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2064 *
2065 * @pre This method can be called if @p scip is in one of the following stages:
2066 * - \ref SCIP_STAGE_TRANSFORMING
2067 * - \ref SCIP_STAGE_TRANSFORMED
2068 * - \ref SCIP_STAGE_INITPRESOLVE
2069 * - \ref SCIP_STAGE_PRESOLVING
2070 * - \ref SCIP_STAGE_EXITPRESOLVE
2071 * - \ref SCIP_STAGE_PRESOLVED
2072 * - \ref SCIP_STAGE_INITSOLVE
2073 * - \ref SCIP_STAGE_SOLVING
2074 * - \ref SCIP_STAGE_SOLVED
2075 * - \ref SCIP_STAGE_EXITSOLVE
2076 * - \ref SCIP_STAGE_FREETRANS
2077 */
2079 SCIP* scip, /**< SCIP data structure */
2080 SCIP_VAR* var, /**< variable to get transformed variable for */
2081 SCIP_VAR** transvar /**< pointer to store the transformed variable */
2082 )
2083{
2084 assert(transvar != NULL);
2085
2086 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetTransformedVar", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
2087
2088 if( SCIPvarIsTransformed(var) )
2089 *transvar = var;
2090 else
2091 {
2092 SCIP_CALL( SCIPvarGetTransformed(var, scip->mem->probmem, scip->set, scip->stat, transvar) );
2093 }
2094
2095 return SCIP_OKAY;
2096}
2097
2098/** gets corresponding transformed variables for an array of variables;
2099 * stores NULL in a transvars slot, if the transformed variable is not yet existing;
2100 * it is possible to call this method with vars == transvars, but remember that variables that are not
2101 * yet transformed will be replaced with NULL
2102 *
2103 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2104 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2105 *
2106 * @pre This method can be called if @p scip is in one of the following stages:
2107 * - \ref SCIP_STAGE_TRANSFORMING
2108 * - \ref SCIP_STAGE_TRANSFORMED
2109 * - \ref SCIP_STAGE_INITPRESOLVE
2110 * - \ref SCIP_STAGE_PRESOLVING
2111 * - \ref SCIP_STAGE_EXITPRESOLVE
2112 * - \ref SCIP_STAGE_PRESOLVED
2113 * - \ref SCIP_STAGE_INITSOLVE
2114 * - \ref SCIP_STAGE_SOLVING
2115 * - \ref SCIP_STAGE_SOLVED
2116 * - \ref SCIP_STAGE_EXITSOLVE
2117 * - \ref SCIP_STAGE_FREETRANS
2118 */
2120 SCIP* scip, /**< SCIP data structure */
2121 int nvars, /**< number of variables to get transformed variables for */
2122 SCIP_VAR** vars, /**< array with variables to get transformed variables for */
2123 SCIP_VAR** transvars /**< array to store the transformed variables */
2124 )
2125{
2126 int v;
2127
2128 assert(nvars == 0 || vars != NULL);
2129 assert(nvars == 0 || transvars != NULL);
2130
2131 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetTransformedVars", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
2132
2133 for( v = 0; v < nvars; ++v )
2134 {
2135 if( SCIPvarIsTransformed(vars[v]) )
2136 transvars[v] = vars[v];
2137 else
2138 {
2139 SCIP_CALL( SCIPvarGetTransformed(vars[v], scip->mem->probmem, scip->set, scip->stat, &transvars[v]) );
2140 }
2141 }
2142
2143 return SCIP_OKAY;
2144}
2145
2146/** gets negated variable x' = lb + ub - x of variable x; negated variable is created, if not yet existing;
2147 * in difference to \ref SCIPcreateVar, the negated variable must not be released (unless captured explicitly)
2148 *
2149 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2150 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2151 *
2152 * @pre This method can be called if @p scip is in one of the following stages:
2153 * - \ref SCIP_STAGE_PROBLEM
2154 * - \ref SCIP_STAGE_TRANSFORMING
2155 * - \ref SCIP_STAGE_TRANSFORMED
2156 * - \ref SCIP_STAGE_INITPRESOLVE
2157 * - \ref SCIP_STAGE_PRESOLVING
2158 * - \ref SCIP_STAGE_EXITPRESOLVE
2159 * - \ref SCIP_STAGE_PRESOLVED
2160 * - \ref SCIP_STAGE_INITSOLVE
2161 * - \ref SCIP_STAGE_SOLVING
2162 * - \ref SCIP_STAGE_SOLVED
2163 * - \ref SCIP_STAGE_EXITSOLVE
2164 * - \ref SCIP_STAGE_FREETRANS
2165 */
2167 SCIP* scip, /**< SCIP data structure */
2168 SCIP_VAR* var, /**< variable to get negated variable for */
2169 SCIP_VAR** negvar /**< pointer to store the negated variable */
2170 )
2171{
2172 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNegatedVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
2173 assert( var->scip == scip );
2174
2175 SCIP_CALL( SCIPvarNegate(var, scip->mem->probmem, scip->set, scip->stat, negvar) );
2176
2177 return SCIP_OKAY;
2178}
2179
2180/** gets negated variables x' = lb + ub - x of variables x; negated variables are created, if not yet existing
2181 *
2182 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2183 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2184 *
2185 * @pre This method can be called if @p scip is in one of the following stages:
2186 * - \ref SCIP_STAGE_PROBLEM
2187 * - \ref SCIP_STAGE_TRANSFORMING
2188 * - \ref SCIP_STAGE_TRANSFORMED
2189 * - \ref SCIP_STAGE_INITPRESOLVE
2190 * - \ref SCIP_STAGE_PRESOLVING
2191 * - \ref SCIP_STAGE_EXITPRESOLVE
2192 * - \ref SCIP_STAGE_PRESOLVED
2193 * - \ref SCIP_STAGE_INITSOLVE
2194 * - \ref SCIP_STAGE_SOLVING
2195 * - \ref SCIP_STAGE_SOLVED
2196 * - \ref SCIP_STAGE_EXITSOLVE
2197 * - \ref SCIP_STAGE_FREETRANS
2198 */
2200 SCIP* scip, /**< SCIP data structure */
2201 int nvars, /**< number of variables to get negated variables for */
2202 SCIP_VAR** vars, /**< array of variables to get negated variables for */
2203 SCIP_VAR** negvars /**< array to store the negated variables */
2204 )
2205{
2206 int v;
2207
2208 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNegatedVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
2209
2210 for( v = 0; v < nvars; ++v )
2211 {
2212 SCIP_CALL( SCIPvarNegate(vars[v], scip->mem->probmem, scip->set, scip->stat, &(negvars[v])) );
2213 }
2214
2215 return SCIP_OKAY;
2216}
2217
2218/** gets a binary variable that is equal to the given binary variable, and that is either active, fixed, or
2219 * multi-aggregated, or the negated variable of an active, fixed, or multi-aggregated variable
2220 *
2221 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2222 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2223 *
2224 * @pre This method can be called if @p scip is in one of the following stages:
2225 * - \ref SCIP_STAGE_PROBLEM
2226 * - \ref SCIP_STAGE_TRANSFORMED
2227 * - \ref SCIP_STAGE_INITPRESOLVE
2228 * - \ref SCIP_STAGE_PRESOLVING
2229 * - \ref SCIP_STAGE_EXITPRESOLVE
2230 * - \ref SCIP_STAGE_PRESOLVED
2231 * - \ref SCIP_STAGE_INITSOLVE
2232 * - \ref SCIP_STAGE_SOLVING
2233 * - \ref SCIP_STAGE_SOLVED
2234 * - \ref SCIP_STAGE_EXITSOLVE
2235 */
2237 SCIP* scip, /**< SCIP data structure */
2238 SCIP_VAR* var, /**< binary variable to get binary representative for */
2239 SCIP_VAR** repvar, /**< pointer to store the binary representative */
2240 SCIP_Bool* negated /**< pointer to store whether the negation of an active variable was returned */
2241 )
2242{
2243 assert(scip != NULL);
2244 assert(var != NULL);
2245 assert(repvar != NULL);
2246 assert(negated != NULL);
2247 assert(var->scip == scip);
2248
2249 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetBinvarRepresentative", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
2250
2251 /* get the active representative of the given variable */
2252 *repvar = var;
2253 *negated = FALSE;
2254 SCIP_CALL( SCIPvarGetProbvarBinary(repvar, negated) );
2255
2256 /* negate the representative, if it corresponds to the negation of the given variable */
2257 if( *negated )
2258 {
2259 SCIP_CALL( SCIPgetNegatedVar(scip, *repvar, repvar) );
2260 }
2261
2262 return SCIP_OKAY;
2263}
2264
2265/** gets binary variables that are equal to the given binary variables, and which are either active, fixed, or
2266 * multi-aggregated, or the negated variables of active, fixed, or multi-aggregated variables
2267 *
2268 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2269 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2270 *
2271 * @pre This method can be called if @p scip is in one of the following stages:
2272 * - \ref SCIP_STAGE_PROBLEM
2273 * - \ref SCIP_STAGE_TRANSFORMED
2274 * - \ref SCIP_STAGE_INITPRESOLVE
2275 * - \ref SCIP_STAGE_PRESOLVING
2276 * - \ref SCIP_STAGE_EXITPRESOLVE
2277 * - \ref SCIP_STAGE_PRESOLVED
2278 * - \ref SCIP_STAGE_INITSOLVE
2279 * - \ref SCIP_STAGE_SOLVING
2280 * - \ref SCIP_STAGE_SOLVED
2281 * - \ref SCIP_STAGE_EXITSOLVE
2282 */
2284 SCIP* scip, /**< SCIP data structure */
2285 int nvars, /**< number of binary variables to get representatives for */
2286 SCIP_VAR** vars, /**< binary variables to get binary representatives for */
2287 SCIP_VAR** repvars, /**< array to store the binary representatives */
2288 SCIP_Bool* negated /**< array to store whether the negation of an active variable was returned */
2289 )
2290{
2291 int v;
2292
2293 assert(scip != NULL);
2294 assert(vars != NULL || nvars == 0);
2295 assert(repvars != NULL || nvars == 0);
2296 assert(negated != NULL || nvars == 0);
2297
2298 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetBinvarRepresentatives", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
2299
2300 if( nvars == 0 )
2301 return SCIP_OKAY;
2302
2303 /* get the active representative of the given variable */
2304 BMScopyMemoryArray(repvars, vars, nvars);
2305 BMSclearMemoryArray(negated, nvars);
2306 SCIP_CALL( SCIPvarsGetProbvarBinary(&repvars, &negated, nvars) );
2307
2308 /* negate the representatives, if they correspond to the negation of the given variables */
2309 for( v = nvars - 1; v >= 0; --v )
2310 if( negated[v] )
2311 {
2312 SCIP_CALL( SCIPgetNegatedVar(scip, repvars[v], &(repvars[v])) );
2313 }
2314
2315 return SCIP_OKAY;
2316}
2317
2318/** flattens aggregation graph of multi-aggregated variable in order to avoid exponential recursion later on
2319 *
2320 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2321 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2322 *
2323 * @pre This method can be called if @p scip is in one of the following stages:
2324 * - \ref SCIP_STAGE_INITPRESOLVE
2325 * - \ref SCIP_STAGE_PRESOLVING
2326 * - \ref SCIP_STAGE_EXITPRESOLVE
2327 * - \ref SCIP_STAGE_PRESOLVED
2328 * - \ref SCIP_STAGE_INITSOLVE
2329 * - \ref SCIP_STAGE_SOLVING
2330 * - \ref SCIP_STAGE_SOLVED
2331 */
2333 SCIP* scip, /**< SCIP data structure */
2334 SCIP_VAR* var /**< problem variable */
2335 )
2336{
2337 assert( scip != NULL );
2338 assert( var != NULL );
2339 SCIP_CALL( SCIPcheckStage(scip, "SCIPflattenVarAggregationGraph", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
2340
2341 SCIP_CALL( SCIPvarFlattenAggregationGraph(var, scip->mem->probmem, scip->set, scip->eventqueue) );
2342
2343 return SCIP_OKAY;
2344}
2345
2346/** Transforms a given linear sum of variables, that is a_1*x_1 + ... + a_n*x_n + c into a corresponding linear sum of
2347 * active variables, that is b_1*y_1 + ... + b_m*y_m + d.
2348 *
2349 * If the number of needed active variables is greater than the available slots in the variable array, nothing happens
2350 * except that an upper bound on the required size is stored in the variable requiredsize; otherwise, the active
2351 * variable representation is stored in the arrays.
2352 *
2353 * The reason for this approach is that we cannot reallocate memory, since we do not know how the memory has been
2354 * allocated (e.g., by a C++ 'new' or SCIP functions). Note that requiredsize is an upper bound due to possible
2355 * cancelations.
2356 *
2357 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2358 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2359 *
2360 * @pre This method can be called if @p scip is in one of the following stages:
2361 * - \ref SCIP_STAGE_TRANSFORMED
2362 * - \ref SCIP_STAGE_INITPRESOLVE
2363 * - \ref SCIP_STAGE_PRESOLVING
2364 * - \ref SCIP_STAGE_EXITPRESOLVE
2365 * - \ref SCIP_STAGE_PRESOLVED
2366 * - \ref SCIP_STAGE_INITSOLVE
2367 * - \ref SCIP_STAGE_SOLVING
2368 * - \ref SCIP_STAGE_SOLVED
2369 * - \ref SCIP_STAGE_EXITSOLVE
2370 * - \ref SCIP_STAGE_FREETRANS
2371 *
2372 * @note The resulting linear sum is stored into the given variable array, scalar array, and constant. That means the
2373 * given entries are overwritten.
2374 *
2375 * @note That method can be used to convert a single variables into variable space of active variables. Therefore call
2376 * the method with the linear sum 1.0*x + 0.0.
2377 */
2379 SCIP* scip, /**< SCIP data structure */
2380 SCIP_VAR** vars, /**< variable array x_1, ..., x_n in the linear sum which will be
2381 * overwritten by the variable array y_1, ..., y_m in the linear sum
2382 * w.r.t. active variables */
2383 SCIP_Real* scalars, /**< scalars a_1, ..., a_n in linear sum which will be overwritten to the
2384 * scalars b_1, ..., b_m in the linear sum of the active variables */
2385 int* nvars, /**< pointer to number of variables in the linear sum which will be
2386 * overwritten by the number of variables in the linear sum corresponding
2387 * to the active variables */
2388 int varssize, /**< available slots in vars and scalars array which is needed to check if
2389 * the array are large enough for the linear sum w.r.t. active
2390 * variables */
2391 SCIP_Real* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c which
2392 * will chnage to constant d in the linear sum b_1*y_1 + ... + b_m*y_m +
2393 * d w.r.t. the active variables */
2394 int* requiredsize /**< pointer to store an upper bound on the required size for the linear sum
2395 * w.r.t. the active variables */
2396 )
2397{
2398 assert( scip != NULL );
2399 assert( nvars != NULL );
2400 assert( vars != NULL || *nvars == 0 );
2401 assert( scalars != NULL || *nvars == 0 );
2402 assert( constant != NULL );
2403 assert( requiredsize != NULL );
2404 assert( *nvars <= varssize );
2405
2406 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetProbvarLinearSum", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
2407 SCIP_CALL( SCIPvarGetActiveRepresentatives(scip->set, vars, scalars, nvars, varssize, constant, requiredsize) );
2408
2409 return SCIP_OKAY;
2410}
2411
2412/** Transforms a given linear sum of variables, that is a_1*x_1 + ... + a_n*x_n + c into a corresponding linear sum of
2413 * active variables, that is b_1*y_1 + ... + b_m*y_m + d.
2414 *
2415 * If the number of needed active variables is greater than the available slots in the variable array, nothing happens
2416 * except that the required size is stored in the corresponding variable (requiredsize). Otherwise, the active variable
2417 * representation is stored in the variable array, scalar array and constant.
2418 *
2419 * The reason for this approach is that we cannot reallocate memory, since we do not know how the memory has been
2420 * allocated (e.g., by a C++ 'new' or SCIP functions).
2421 *
2422 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2423 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2424 *
2425 * @pre This method can be called if @p scip is in one of the following stages:
2426 * - \ref SCIP_STAGE_TRANSFORMED
2427 * - \ref SCIP_STAGE_INITPRESOLVE
2428 * - \ref SCIP_STAGE_PRESOLVING
2429 * - \ref SCIP_STAGE_EXITPRESOLVE
2430 * - \ref SCIP_STAGE_PRESOLVED
2431 * - \ref SCIP_STAGE_INITSOLVE
2432 * - \ref SCIP_STAGE_SOLVING
2433 * - \ref SCIP_STAGE_SOLVED
2434 * - \ref SCIP_STAGE_EXITSOLVE
2435 * - \ref SCIP_STAGE_FREETRANS
2436 *
2437 * @note The resulting linear sum is stored into the given variable array, scalar array, and constant. That means the
2438 * given entries are overwritten.
2439 *
2440 * @note That method can be used to convert a single variables into variable space of active variables. Therefore call
2441 * the method with the linear sum 1.0*x + 0.0.
2442 */
2444 SCIP* scip, /**< SCIP data structure */
2445 SCIP_VAR** vars, /**< variable array x_1, ..., x_n in the linear sum which will be
2446 * overwritten by the variable array y_1, ..., y_m in the linear sum
2447 * w.r.t. active variables */
2448 SCIP_RATIONAL** scalars, /**< scalars a_1, ..., a_n in linear sum which will be overwritten to the
2449 * scalars b_1, ..., b_m in the linear sum of the active variables */
2450 int* nvars, /**< pointer to number of variables in the linear sum which will be
2451 * overwritten by the number of variables in the linear sum corresponding
2452 * to the active variables */
2453 int varssize, /**< available slots in vars and scalars array which is needed to check if
2454 * the array are large enough for the linear sum w.r.t. active
2455 * variables */
2456 SCIP_RATIONAL* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c which
2457 * will chnage to constant d in the linear sum b_1*y_1 + ... + b_m*y_m +
2458 * d w.r.t. the active variables */
2459 int* requiredsize, /**< pointer to store the required array size for the linear sum w.r.t. the
2460 * active variables */
2461 SCIP_Bool mergemultiples /**< should multiple occurrences of a var be replaced by a single coeff? */
2462 )
2463{
2464 assert( scip != NULL );
2465 assert( nvars != NULL );
2466 assert( vars != NULL || *nvars == 0 );
2467 assert( scalars != NULL || *nvars == 0 );
2468 assert( constant != NULL );
2469 assert( requiredsize != NULL );
2470 assert( *nvars <= varssize );
2471
2472 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetProbvarLinearSumExact", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
2473 SCIP_CALL( SCIPvarGetActiveRepresentativesExact(scip->set, vars, scalars, nvars, varssize, constant, requiredsize, mergemultiples) );
2474
2475 return SCIP_OKAY;
2476}
2477
2478/** transforms given variable, scalar and constant to the corresponding active, fixed, or
2479 * multi-aggregated variable, scalar and constant; if the variable resolves to a fixed variable,
2480 * "scalar" will be 0.0 and the value of the sum will be stored in "constant"; a multi-aggregation
2481 * with only one active variable (this can happen due to fixings after the multi-aggregation),
2482 * is treated like an aggregation; if the multi-aggregation constant is infinite, "scalar" will be 0.0
2483 *
2484 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2485 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2486 *
2487 * @pre This method can be called if @p scip is in one of the following stages:
2488 * - \ref SCIP_STAGE_TRANSFORMED
2489 * - \ref SCIP_STAGE_INITPRESOLVE
2490 * - \ref SCIP_STAGE_PRESOLVING
2491 * - \ref SCIP_STAGE_EXITPRESOLVE
2492 * - \ref SCIP_STAGE_PRESOLVED
2493 * - \ref SCIP_STAGE_INITSOLVE
2494 * - \ref SCIP_STAGE_SOLVING
2495 * - \ref SCIP_STAGE_SOLVED
2496 * - \ref SCIP_STAGE_EXITSOLVE
2497 * - \ref SCIP_STAGE_FREETRANS
2498 */
2500 SCIP* scip, /**< SCIP data structure */
2501 SCIP_VAR** var, /**< pointer to problem variable x in sum a*x + c */
2502 SCIP_Real* scalar, /**< pointer to scalar a in sum a*x + c */
2503 SCIP_Real* constant /**< pointer to constant c in sum a*x + c */
2504 )
2505{
2506 assert(scip != NULL);
2507 assert(var != NULL);
2508 assert(scalar != NULL);
2509 assert(constant != NULL);
2510
2511 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetProbvarSum", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
2512 SCIP_CALL( SCIPvarGetProbvarSum(var, scip->set, scalar, constant) );
2513
2514 return SCIP_OKAY;
2515}
2516
2517/** transforms given variable, scalar and constant to the corresponding active, fixed, or
2518 * multi-aggregated variable, scalar and constant; if the variable resolves to a fixed variable,
2519 * "scalar" will be 0.0 and the value of the sum will be stored in "constant"; a multi-aggregation
2520 * with only one active variable (this can happen due to fixings after the multi-aggregation),
2521 * is treated like an aggregation; if the multi-aggregation constant is infinite, "scalar" will be 0.0
2522 *
2523 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2524 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2525 *
2526 * @pre This method can be called if @p scip is in one of the following stages:
2527 * - \ref SCIP_STAGE_TRANSFORMED
2528 * - \ref SCIP_STAGE_INITPRESOLVE
2529 * - \ref SCIP_STAGE_PRESOLVING
2530 * - \ref SCIP_STAGE_EXITPRESOLVE
2531 * - \ref SCIP_STAGE_PRESOLVED
2532 * - \ref SCIP_STAGE_INITSOLVE
2533 * - \ref SCIP_STAGE_SOLVING
2534 * - \ref SCIP_STAGE_SOLVED
2535 * - \ref SCIP_STAGE_EXITSOLVE
2536 * - \ref SCIP_STAGE_FREETRANS
2537 */
2539 SCIP* scip, /**< SCIP data structure */
2540 SCIP_VAR** var, /**< pointer to problem variable x in sum a*x + c */
2541 SCIP_RATIONAL* scalar, /**< pointer to scalar a in sum a*x + c */
2542 SCIP_RATIONAL* constant /**< pointer to constant c in sum a*x + c */
2543 )
2544{
2545 assert(scip != NULL);
2546 assert(var != NULL);
2547 assert(scalar != NULL);
2548 assert(constant != NULL);
2549
2550 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetProbvarSumExact", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
2551 SCIP_CALL( SCIPvarGetProbvarSumExact(var, scalar, constant) );
2552
2553 return SCIP_OKAY;
2554}
2555
2556/** return for given variables all their active counterparts; all active variables will be pairwise different
2557 * @note It does not hold that the first output variable is the active variable for the first input variable.
2558 *
2559 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2560 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2561 *
2562 * @pre This method can be called if @p scip is in one of the following stages:
2563 * - \ref SCIP_STAGE_TRANSFORMED
2564 * - \ref SCIP_STAGE_INITPRESOLVE
2565 * - \ref SCIP_STAGE_PRESOLVING
2566 * - \ref SCIP_STAGE_EXITPRESOLVE
2567 * - \ref SCIP_STAGE_PRESOLVED
2568 * - \ref SCIP_STAGE_INITSOLVE
2569 * - \ref SCIP_STAGE_SOLVING
2570 * - \ref SCIP_STAGE_SOLVED
2571 * - \ref SCIP_STAGE_EXITSOLVE
2572 * - \ref SCIP_STAGE_FREETRANS
2573 */
2575 SCIP* scip, /**< SCIP data structure */
2576 SCIP_VAR** vars, /**< variable array with given variables and as output all active
2577 * variables, if enough slots exist
2578 */
2579 int* nvars, /**< number of given variables, and as output number of active variables,
2580 * if enough slots exist
2581 */
2582 int varssize, /**< available slots in vars array */
2583 int* requiredsize /**< pointer to store the required array size for the active variables */
2584 )
2585{
2586 assert(scip != NULL);
2587 assert(nvars != NULL);
2588 assert(vars != NULL || *nvars == 0);
2589 assert(varssize >= *nvars);
2590 assert(requiredsize != NULL);
2591
2592 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetActiveVars", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
2593 SCIP_CALL( SCIPvarsGetActiveVars(scip->set, vars, nvars, varssize, requiredsize) );
2594
2595 return SCIP_OKAY;
2596}
2597
2598/** returns the reduced costs of the variable in the current node's LP relaxation;
2599 * the current node has to have a feasible LP.
2600 *
2601 * returns SCIP_INVALID if the variable is active but not in the current LP;
2602 * returns 0 if the variable has been aggregated out or fixed in presolving.
2603 *
2604 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
2605 *
2606 * @note The return value of this method should be used carefully if the dual feasibility check was explictely disabled.
2607 */
2609 SCIP* scip, /**< SCIP data structure */
2610 SCIP_VAR* var /**< variable to get reduced costs, should be a column in current node LP */
2611 )
2612{
2613 assert( scip != NULL );
2614 assert( var != NULL );
2615 assert( var->scip == scip );
2616
2617 switch( SCIPvarGetStatus(var) )
2618 {
2620 if( var->data.original.transvar == NULL )
2621 return SCIP_INVALID;
2623
2625 return SCIPgetColRedcost(scip, SCIPvarGetCol(var));
2626
2628 return SCIP_INVALID;
2629
2634 return 0.0;
2635
2636 default:
2637 SCIPerrorMessage("unknown variable status\n");
2638 SCIPABORT();
2639 return 0.0; /*lint !e527*/
2640 }
2641}
2642
2643/** returns the implied reduced costs of the variable in the current node's LP relaxation;
2644 * the current node has to have a feasible LP.
2645 *
2646 * returns SCIP_INVALID if the variable is active but not in the current LP;
2647 * returns 0 if the variable has been aggregated out or fixed in presolving.
2648 *
2649 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
2650 *
2651 * @note The return value of this method should be used carefully if the dual feasibility check was explictely disabled.
2652 */
2654 SCIP* scip, /**< SCIP data structure */
2655 SCIP_VAR* var, /**< variable to get reduced costs, should be a column in current node LP */
2656 SCIP_Bool varfixing /**< FALSE if for x == 0, TRUE for x == 1 */
2657 )
2658{
2659 assert( scip != NULL );
2660 assert( var != NULL );
2661 assert( var->scip == scip );
2662
2663 switch( SCIPvarGetStatus(var) )
2664 {
2666 if( var->data.original.transvar == NULL )
2667 return SCIP_INVALID;
2668 return SCIPgetVarImplRedcost(scip, var->data.original.transvar, varfixing);
2669
2671 return SCIPvarGetImplRedcost(var, scip->set, varfixing, scip->stat, scip->transprob, scip->lp);
2672
2674 return SCIP_INVALID;
2675
2680 return 0.0;
2681
2682 default:
2683 SCIPerrorMessage("unknown variable status\n");
2684 SCIPABORT();
2685 return 0.0; /*lint !e527*/
2686 }
2687}
2688
2689
2690/** returns the Farkas coefficient of the variable in the current node's LP relaxation;
2691 * the current node has to have an infeasible LP.
2692 *
2693 * returns SCIP_INVALID if the variable is active but not in the current LP;
2694 * returns 0 if the variable has been aggregated out or fixed in presolving.
2695 *
2696 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
2697 */
2699 SCIP* scip, /**< SCIP data structure */
2700 SCIP_VAR* var /**< variable to get reduced costs, should be a column in current node LP */
2701 )
2702{
2703 assert(scip != NULL);
2704 assert(var != NULL);
2705 assert(var->scip == scip);
2706
2707 switch( SCIPvarGetStatus(var) )
2708 {
2710 if( var->data.original.transvar == NULL )
2711 return SCIP_INVALID;
2713
2716
2718 return SCIP_INVALID;
2719
2724 return 0.0;
2725
2726 default:
2727 SCIPerrorMessage("unknown variable status\n");
2728 SCIPABORT();
2729 return 0.0; /*lint !e527*/
2730 }
2731}
2732
2733/** returns lower bound of variable directly before or after the bound change given by the bound change index
2734 * was applied
2735 */
2737 SCIP* scip, /**< SCIP data structure */
2738 SCIP_VAR* var, /**< problem variable */
2739 SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2740 SCIP_Bool after /**< should the bound change with given index be included? */
2741 )
2742{
2743 SCIP_VARSTATUS varstatus;
2744 SCIP_BDCHGINFO* bdchginfo;
2745 assert(var != NULL);
2746
2747 varstatus = SCIPvarGetStatus(var);
2748
2749 /* get bounds of attached variables */
2750 switch( varstatus )
2751 {
2753 assert(var->data.original.transvar != NULL);
2754 return SCIPgetVarLbAtIndex(scip, var->data.original.transvar, bdchgidx, after);
2755
2758 if( bdchgidx == NULL )
2759 return SCIPvarGetLbLocal(var);
2760 else
2761 {
2762 bdchginfo = SCIPvarGetLbchgInfo(var, bdchgidx, after);
2763 if( bdchginfo != NULL )
2764 return SCIPbdchginfoGetNewbound(bdchginfo);
2765 else
2766 return var->glbdom.lb;
2767 }
2768
2770 return var->glbdom.lb;
2771
2772 case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c -> y = (x-c)/a */
2773 assert(var->data.aggregate.var != NULL);
2774 if( var->data.aggregate.scalar > 0.0 )
2775 {
2776 SCIP_Real lb;
2777
2778 lb = SCIPgetVarLbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2779
2780 /* a > 0 -> get lower bound of y */
2781 if( SCIPisInfinity(scip, -lb) )
2782 return -SCIPinfinity(scip);
2783 else if( SCIPisInfinity(scip, lb) )
2784 return SCIPinfinity(scip);
2785 else
2786 return var->data.aggregate.scalar * lb + var->data.aggregate.constant;
2787 }
2788 else if( var->data.aggregate.scalar < 0.0 )
2789 {
2790 SCIP_Real ub;
2791
2792 ub = SCIPgetVarUbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2793
2794 /* a < 0 -> get upper bound of y */
2795 if( SCIPisInfinity(scip, -ub) )
2796 return SCIPinfinity(scip);
2797 else if( SCIPisInfinity(scip, ub) )
2798 return -SCIPinfinity(scip);
2799 else
2800 return var->data.aggregate.scalar * ub + var->data.aggregate.constant;
2801 }
2802 else
2803 {
2804 SCIPerrorMessage("scalar is zero in aggregation\n");
2805 SCIPABORT();
2806 return SCIP_INVALID; /*lint !e527*/
2807 }
2808
2810 /* handle multi-aggregated variables depending on one variable only (possibly caused by SCIPvarFlattenAggregationGraph()) */
2811 if ( var->data.multaggr.nvars == 1 )
2812 {
2813 assert(var->data.multaggr.vars != NULL);
2814 assert(var->data.multaggr.scalars != NULL);
2815 assert(var->data.multaggr.vars[0] != NULL);
2816
2817 if( var->data.multaggr.scalars[0] > 0.0 )
2818 {
2819 SCIP_Real lb;
2820
2821 lb = SCIPgetVarLbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2822
2823 /* a > 0 -> get lower bound of y */
2824 if( SCIPisInfinity(scip, -lb) )
2825 return -SCIPinfinity(scip);
2826 else if( SCIPisInfinity(scip, lb) )
2827 return SCIPinfinity(scip);
2828 else
2829 return var->data.multaggr.scalars[0] * lb + var->data.multaggr.constant;
2830 }
2831 else if( var->data.multaggr.scalars[0] < 0.0 )
2832 {
2833 SCIP_Real ub;
2834
2835 ub = SCIPgetVarUbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2836
2837 /* a < 0 -> get upper bound of y */
2838 if( SCIPisInfinity(scip, -ub) )
2839 return SCIPinfinity(scip);
2840 else if( SCIPisInfinity(scip, ub) )
2841 return -SCIPinfinity(scip);
2842 else
2843 return var->data.multaggr.scalars[0] * ub + var->data.multaggr.constant;
2844 }
2845 else
2846 {
2847 SCIPerrorMessage("scalar is zero in multi-aggregation\n");
2848 SCIPABORT();
2849 return SCIP_INVALID; /*lint !e527*/
2850 }
2851 }
2852 SCIPerrorMessage("cannot get the bounds of a multi-aggregated variable.\n");
2853 SCIPABORT();
2854 return SCIP_INVALID; /*lint !e527*/
2855
2856 case SCIP_VARSTATUS_NEGATED: /* x' = offset - x -> x = offset - x' */
2857 assert(var->negatedvar != NULL);
2859 assert(var->negatedvar->negatedvar == var);
2860 return var->data.negate.constant - SCIPgetVarUbAtIndex(scip, var->negatedvar, bdchgidx, after);
2861
2862 default:
2863 SCIPerrorMessage("unknown variable status\n");
2864 SCIPABORT();
2865 return SCIP_INVALID; /*lint !e527*/
2866 }
2867}
2868
2869/** returns upper bound of variable directly before or after the bound change given by the bound change index
2870 * was applied
2871 */
2873 SCIP* scip, /**< SCIP data structure */
2874 SCIP_VAR* var, /**< problem variable */
2875 SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2876 SCIP_Bool after /**< should the bound change with given index be included? */
2877 )
2878{
2879 SCIP_VARSTATUS varstatus;
2880 SCIP_BDCHGINFO* bdchginfo;
2881 assert(var != NULL);
2882
2883 varstatus = SCIPvarGetStatus(var);
2884
2885 /* get bounds of attached variables */
2886 switch( varstatus )
2887 {
2889 assert(var->data.original.transvar != NULL);
2890 return SCIPgetVarUbAtIndex(scip, var->data.original.transvar, bdchgidx, after);
2891
2894 if( bdchgidx == NULL )
2895 return SCIPvarGetUbLocal(var);
2896 else
2897 {
2898 bdchginfo = SCIPvarGetUbchgInfo(var, bdchgidx, after);
2899 if( bdchginfo != NULL )
2900 return SCIPbdchginfoGetNewbound(bdchginfo);
2901 else
2902 return var->glbdom.ub;
2903 }
2904
2906 return var->glbdom.ub;
2907
2908 case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c -> y = (x-c)/a */
2909 assert(var->data.aggregate.var != NULL);
2910 if( var->data.aggregate.scalar > 0.0 )
2911 {
2912 SCIP_Real ub;
2913
2914 ub = SCIPgetVarUbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2915
2916 /* a > 0 -> get lower bound of y */
2917 if( SCIPisInfinity(scip, -ub) )
2918 return -SCIPinfinity(scip);
2919 else if( SCIPisInfinity(scip, ub) )
2920 return SCIPinfinity(scip);
2921 else
2922 return var->data.aggregate.scalar * ub + var->data.aggregate.constant;
2923 }
2924 else if( var->data.aggregate.scalar < 0.0 )
2925 {
2926 SCIP_Real lb;
2927
2928 lb = SCIPgetVarLbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2929
2930 /* a < 0 -> get upper bound of y */
2931 if ( SCIPisInfinity(scip, -lb) )
2932 return SCIPinfinity(scip);
2933 else if ( SCIPisInfinity(scip, lb) )
2934 return -SCIPinfinity(scip);
2935 else
2936 return var->data.aggregate.scalar * lb + var->data.aggregate.constant;
2937 }
2938 else
2939 {
2940 SCIPerrorMessage("scalar is zero in aggregation\n");
2941 SCIPABORT();
2942 return SCIP_INVALID; /*lint !e527*/
2943 }
2944
2946 /* handle multi-aggregated variables depending on one variable only (possibly caused by SCIPvarFlattenAggregationGraph()) */
2947 if ( var->data.multaggr.nvars == 1 )
2948 {
2949 assert(var->data.multaggr.vars != NULL);
2950 assert(var->data.multaggr.scalars != NULL);
2951 assert(var->data.multaggr.vars[0] != NULL);
2952
2953 if( var->data.multaggr.scalars[0] > 0.0 )
2954 {
2955 SCIP_Real ub;
2956
2957 ub = SCIPgetVarUbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2958
2959 /* a > 0 -> get lower bound of y */
2960 if ( SCIPisInfinity(scip, -ub) )
2961 return -SCIPinfinity(scip);
2962 else if ( SCIPisInfinity(scip, ub) )
2963 return SCIPinfinity(scip);
2964 else
2965 return var->data.multaggr.scalars[0] * ub + var->data.multaggr.constant;
2966 }
2967 else if( var->data.multaggr.scalars[0] < 0.0 )
2968 {
2969 SCIP_Real lb;
2970
2971 lb = SCIPgetVarLbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2972
2973 /* a < 0 -> get upper bound of y */
2974 if ( SCIPisInfinity(scip, -lb) )
2975 return SCIPinfinity(scip);
2976 else if ( SCIPisInfinity(scip, lb) )
2977 return -SCIPinfinity(scip);
2978 else
2979 return var->data.multaggr.scalars[0] * lb + var->data.multaggr.constant;
2980 }
2981 else
2982 {
2983 SCIPerrorMessage("scalar is zero in multi-aggregation\n");
2984 SCIPABORT();
2985 return SCIP_INVALID; /*lint !e527*/
2986 }
2987 }
2988 SCIPerrorMessage("cannot get the bounds of a multiple aggregated variable.\n");
2989 SCIPABORT();
2990 return SCIP_INVALID; /*lint !e527*/
2991
2992 case SCIP_VARSTATUS_NEGATED: /* x' = offset - x -> x = offset - x' */
2993 assert(var->negatedvar != NULL);
2995 assert(var->negatedvar->negatedvar == var);
2996 return var->data.negate.constant - SCIPgetVarLbAtIndex(scip, var->negatedvar, bdchgidx, after);
2997
2998 default:
2999 SCIPerrorMessage("unknown variable status\n");
3000 SCIPABORT();
3001 return SCIP_INVALID; /*lint !e527*/
3002 }
3003}
3004
3005/** returns lower or upper bound of variable directly before or after the bound change given by the bound change index
3006 * was applied
3007 */
3009 SCIP* scip, /**< SCIP data structure */
3010 SCIP_VAR* var, /**< problem variable */
3011 SCIP_BOUNDTYPE boundtype, /**< type of bound: lower or upper bound */
3012 SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
3013 SCIP_Bool after /**< should the bound change with given index be included? */
3014 )
3015{
3016 if( boundtype == SCIP_BOUNDTYPE_LOWER )
3017 return SCIPgetVarLbAtIndex(scip, var, bdchgidx, after);
3018 else
3019 {
3020 assert(boundtype == SCIP_BOUNDTYPE_UPPER);
3021 return SCIPgetVarUbAtIndex(scip, var, bdchgidx, after);
3022 }
3023}
3024
3025/** returns whether the binary variable was fixed at the time given by the bound change index */
3027 SCIP* scip, /**< SCIP data structure */
3028 SCIP_VAR* var, /**< problem variable */
3029 SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
3030 SCIP_Bool after /**< should the bound change with given index be included? */
3031 )
3032{
3033 assert(var != NULL);
3034 assert(SCIPvarIsBinary(var));
3035
3036 /* check the current bounds first in order to decide at which bound change information we have to look
3037 * (which is expensive because we have to follow the aggregation tree to the active variable)
3038 */
3039 return ((SCIPvarGetLbLocal(var) > 0.5 && SCIPgetVarLbAtIndex(scip, var, bdchgidx, after) > 0.5)
3040 || (SCIPvarGetUbLocal(var) < 0.5 && SCIPgetVarUbAtIndex(scip, var, bdchgidx, after) < 0.5));
3041}
3042
3043/** gets solution value for variable in current node
3044 *
3045 * @return solution value for variable in current node
3046 *
3047 * @pre This method can be called if @p scip is in one of the following stages:
3048 * - \ref SCIP_STAGE_PRESOLVED
3049 * - \ref SCIP_STAGE_SOLVING
3050 */
3052 SCIP* scip, /**< SCIP data structure */
3053 SCIP_VAR* var /**< variable to get solution value for */
3054 )
3055{
3057 assert( var->scip == scip );
3058
3059 return SCIPvarGetSol(var, SCIPtreeHasCurrentNodeLP(scip->tree));
3060}
3061
3062/** gets solution values of multiple variables in current node
3063 *
3064 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3065 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3066 *
3067 * @pre This method can be called if @p scip is in one of the following stages:
3068 * - \ref SCIP_STAGE_PRESOLVED
3069 * - \ref SCIP_STAGE_SOLVING
3070 */
3072 SCIP* scip, /**< SCIP data structure */
3073 int nvars, /**< number of variables to get solution value for */
3074 SCIP_VAR** vars, /**< array with variables to get value for */
3075 SCIP_Real* vals /**< array to store solution values of variables */
3076 )
3077{
3078 int v;
3079
3080 assert(nvars == 0 || vars != NULL);
3081 assert(nvars == 0 || vals != NULL);
3082
3084
3085 if( SCIPtreeHasCurrentNodeLP(scip->tree) )
3086 {
3087 for( v = 0; v < nvars; ++v )
3088 vals[v] = SCIPvarGetLPSol(vars[v]);
3089 }
3090 else
3091 {
3092 for( v = 0; v < nvars; ++v )
3093 vals[v] = SCIPvarGetPseudoSol(vars[v]);
3094 }
3095
3096 return SCIP_OKAY;
3097}
3098
3099/** sets the solution value of all variables in the global relaxation solution to zero
3100 *
3101 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3102 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3103 *
3104 * @pre This method can be called if @p scip is in one of the following stages:
3105 * - \ref SCIP_STAGE_PRESOLVED
3106 * - \ref SCIP_STAGE_SOLVING
3107 */
3109 SCIP* scip, /**< SCIP data structure */
3110 SCIP_RELAX* relax /**< relaxator data structure */
3111 )
3112{
3113 SCIP_VAR** vars;
3114 int nvars;
3115 int v;
3116
3117 assert(scip != NULL);
3118
3119 SCIP_CALL( SCIPcheckStage(scip, "SCIPclearRelaxSolVals", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3120
3121 /* update the responsible relax pointer */
3122 SCIPrelaxationSetSolRelax(scip->relaxation, relax);
3123
3124 /* the relaxation solution is already cleared */
3125 if( SCIPrelaxationIsSolZero(scip->relaxation) )
3126 return SCIP_OKAY;
3127
3128 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
3129
3130 for( v = 0; v < nvars; v++ )
3131 {
3132 SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, 0.0, FALSE) );
3133 }
3134
3135 SCIPrelaxationSetSolObj(scip->relaxation, 0.0);
3136 SCIPrelaxationSetSolZero(scip->relaxation, TRUE);
3137
3138 return SCIP_OKAY;
3139}
3140
3141/** sets the value of the given variable in the global relaxation solution;
3142 * this solution can be filled by the relaxation handlers and can be used by heuristics and for separation;
3143 * You can use SCIPclearRelaxSolVals() to set all values to zero, initially;
3144 * after setting all solution values, you have to call SCIPmarkRelaxSolValid()
3145 * to inform SCIP that the stored solution is valid
3146 *
3147 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3148 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3149 *
3150 * @pre This method can be called if @p scip is in one of the following stages:
3151 * - \ref SCIP_STAGE_PRESOLVED
3152 * - \ref SCIP_STAGE_SOLVING
3153 *
3154 * @note This method incrementally updates the objective value of the relaxation solution. If the whole solution
3155 * should be updated, using SCIPsetRelaxSolVals() instead or calling SCIPclearRelaxSolVals() before setting
3156 * the first value to reset the solution and the objective value to 0 may help the numerics.
3157 */
3159 SCIP* scip, /**< SCIP data structure */
3160 SCIP_RELAX* relax, /**< relaxator data structure */
3161 SCIP_VAR* var, /**< variable to set value for */
3162 SCIP_Real val /**< solution value of variable */
3163 )
3164{
3165 assert(scip != NULL);
3166
3168
3169 SCIP_CALL( SCIPvarSetRelaxSol(var, scip->set, scip->relaxation, val, TRUE) );
3170
3171 if( val != 0.0 )
3172 SCIPrelaxationSetSolZero(scip->relaxation, FALSE);
3174 SCIPrelaxationSetSolRelax(scip->relaxation, relax);
3175
3176 return SCIP_OKAY;
3177}
3178
3179/** sets the values of the given variables in the global relaxation solution and informs SCIP about the validity
3180 * and whether the solution can be enforced via linear cuts;
3181 * this solution can be filled by the relaxation handlers and can be used by heuristics and for separation;
3182 * the solution is automatically cleared, s.t. all other variables get value 0.0
3183 *
3184 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3185 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3186 *
3187 * @pre This method can be called if @p scip is in one of the following stages:
3188 * - \ref SCIP_STAGE_PRESOLVED
3189 * - \ref SCIP_STAGE_SOLVING
3190 */
3192 SCIP* scip, /**< SCIP data structure */
3193 SCIP_RELAX* relax, /**< relaxator data structure */
3194 int nvars, /**< number of variables to set relaxation solution value for */
3195 SCIP_VAR** vars, /**< array with variables to set value for */
3196 SCIP_Real* vals, /**< array with solution values of variables */
3197 SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
3198 )
3199{
3200 int v;
3201
3202 assert(scip != NULL);
3203 assert(nvars == 0 || vars != NULL);
3204 assert(nvars == 0 || vals != NULL);
3205
3206 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolVals", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3207
3209
3210 for( v = 0; v < nvars; v++ )
3211 {
3212 SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, vals[v], TRUE) );
3213 }
3214
3215 SCIPrelaxationSetSolZero(scip->relaxation, FALSE);
3216 SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
3217 SCIPrelaxationSetSolRelax(scip->relaxation, relax);
3218
3219 return SCIP_OKAY;
3220}
3221
3222/** sets the values of the variables in the global relaxation solution to the values in the given primal solution
3223 * and informs SCIP about the validity and whether the solution can be enforced via linear cuts;
3224 * the relaxation solution can be filled by the relaxation handlers and might be used by heuristics and for separation
3225 *
3226 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3227 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3228 *
3229 * @pre This method can be called if @p scip is in one of the following stages:
3230 * - \ref SCIP_STAGE_PRESOLVED
3231 * - \ref SCIP_STAGE_SOLVING
3232 */
3234 SCIP* scip, /**< SCIP data structure */
3235 SCIP_RELAX* relax, /**< relaxator data structure */
3236 SCIP_SOL* sol, /**< primal relaxation solution */
3237 SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
3238 )
3239{
3240 SCIP_VAR** vars;
3241 SCIP_Real* vals;
3242 int nvars;
3243 int v;
3244
3245 assert(scip != NULL);
3246
3247 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolValsSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3248
3249 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
3250
3251 /* alloc buffer array for solution values of the variables and get the values */
3252 SCIP_CALL( SCIPallocBufferArray(scip, &vals, nvars) );
3253 SCIP_CALL( SCIPgetSolVals(scip, sol, nvars, vars, vals) );
3254
3256
3257 for( v = 0; v < nvars; v++ )
3258 {
3259 SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, vals[v], FALSE) );
3260 }
3261
3262 SCIPrelaxationSetSolObj(scip->relaxation, SCIPsolGetObj(sol, scip->set, scip->transprob, scip->origprob));
3263
3264 SCIPrelaxationSetSolZero(scip->relaxation, FALSE);
3265 SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
3266 SCIPrelaxationSetSolRelax(scip->relaxation, relax);
3267
3268 SCIPfreeBufferArray(scip, &vals);
3269
3270 return SCIP_OKAY;
3271}
3272
3273/** returns whether the relaxation solution is valid
3274 *
3275 * @return TRUE, if the relaxation solution is valid; FALSE, otherwise
3276 *
3277 * @pre This method can be called if @p scip is in one of the following stages:
3278 * - \ref SCIP_STAGE_PRESOLVED
3279 * - \ref SCIP_STAGE_SOLVING
3280 */
3282 SCIP* scip /**< SCIP data structure */
3283 )
3284{
3285 assert(scip != NULL);
3286
3288
3289 return SCIPrelaxationIsSolValid(scip->relaxation);
3290}
3291
3292/** informs SCIP that the relaxation solution is valid and whether the relaxation can be enforced through linear cuts
3293 *
3294 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3295 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3296 *
3297 * @pre This method can be called if @p scip is in one of the following stages:
3298 * - \ref SCIP_STAGE_PRESOLVED
3299 * - \ref SCIP_STAGE_SOLVING
3300 */
3302 SCIP* scip, /**< SCIP data structure */
3303 SCIP_RELAX* relax, /**< relaxator data structure that set the current relaxation solution */
3304 SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
3305 )
3306{
3307 assert(scip != NULL);
3308
3309 SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkRelaxSolValid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3310
3311 SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
3312 SCIPrelaxationSetSolRelax(scip->relaxation, relax);
3313
3314 return SCIP_OKAY;
3315}
3316
3317/** informs SCIP, that the relaxation solution is invalid
3318 *
3319 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3320 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3321 *
3322 * @pre This method can be called if @p scip is in one of the following stages:
3323 * - \ref SCIP_STAGE_PRESOLVED
3324 * - \ref SCIP_STAGE_SOLVING
3325 */
3327 SCIP* scip /**< SCIP data structure */
3328 )
3329{
3330 assert(scip != NULL);
3331
3332 SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkRelaxSolInvalid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3333
3335
3336 return SCIP_OKAY;
3337}
3338
3339/** gets the relaxation solution value of the given variable
3340 *
3341 * @return the relaxation solution value of the given variable
3342 *
3343 * @pre This method can be called if @p scip is in one of the following stages:
3344 * - \ref SCIP_STAGE_PRESOLVED
3345 * - \ref SCIP_STAGE_SOLVING
3346 */
3348 SCIP* scip, /**< SCIP data structure */
3349 SCIP_VAR* var /**< variable to get value for */
3350 )
3351{
3352 assert(scip != NULL);
3353 assert(var != NULL);
3354 assert(var->scip == scip);
3355
3357
3358 if( !SCIPrelaxationIsSolValid(scip->relaxation) )
3359 {
3360 SCIPerrorMessage("Relaxation Solution is not valid!\n");
3361 SCIPABORT();
3362 return SCIP_INVALID; /*lint !e527*/
3363 }
3364
3365 return SCIPvarGetRelaxSol(var, scip->set);
3366}
3367
3368/** gets the relaxation solution objective value
3369 *
3370 * @return the objective value of the relaxation solution
3371 *
3372 * @pre This method can be called if @p scip is in one of the following stages:
3373 * - \ref SCIP_STAGE_PRESOLVED
3374 * - \ref SCIP_STAGE_SOLVING
3375 */
3377 SCIP* scip /**< SCIP data structure */
3378 )
3379{
3380 assert(scip != NULL);
3381
3383
3384 if( !SCIPrelaxationIsSolValid(scip->relaxation) )
3385 {
3386 SCIPerrorMessage("Relaxation Solution is not valid!\n");
3387 SCIPABORT();
3388 return SCIP_INVALID; /*lint !e527*/
3389 }
3390
3391 return SCIPrelaxationGetSolObj(scip->relaxation);
3392}
3393
3394/** determine which branching direction should be evaluated first by strong branching
3395 *
3396 * @return TRUE iff strong branching should first evaluate the down child
3397 *
3398 */
3400 SCIP* scip, /**< SCIP data structure */
3401 SCIP_VAR* var /**< variable to determine the branching direction on */
3402 )
3403{
3404 switch( scip->set->branch_firstsbchild )
3405 {
3406 case 'u':
3407 return FALSE;
3408 case 'd':
3409 return TRUE;
3410 case 'a':
3411 return (SCIPvarGetNLocksDown(var) > SCIPvarGetNLocksUp(var));
3412 default:
3413 assert(scip->set->branch_firstsbchild == 'h');
3415 }
3416}
3417
3418/** start strong branching - call before any strong branching
3419 *
3420 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3421 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3422 *
3423 * @pre This method can be called if @p scip is in one of the following stages:
3424 * - \ref SCIP_STAGE_PRESOLVED
3425 * - \ref SCIP_STAGE_SOLVING
3426 *
3427 * @note if propagation is enabled, strong branching is not done directly on the LP, but probing nodes are created
3428 * which allow to perform propagation but also creates some overhead
3429 */
3431 SCIP* scip, /**< SCIP data structure */
3432 SCIP_Bool enablepropagation /**< should propagation be done before solving the strong branching LP? */
3433 )
3434{
3435 assert( scip != NULL );
3436 SCIP_CALL( SCIPcheckStage(scip, "SCIPstartStrongbranch", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3437
3438 assert(!SCIPinProbing(scip));
3439
3440 SCIPdebugMsg(scip, "starting strong branching mode%s: lpcount=%" SCIP_LONGINT_FORMAT "\n", enablepropagation ? " with propagation" : "", scip->stat->lpcount - scip->stat->nsbdivinglps);
3441
3442 /* start probing mode to allow propagation before solving the strong branching LPs; if no propagation should be done,
3443 * start the strong branching mode in the LP interface
3444 */
3445 if( enablepropagation )
3446 {
3447 if( SCIPtreeProbing(scip->tree) )
3448 {
3449 SCIPerrorMessage("cannot start strong branching with propagation while in probing mode\n");
3450 return SCIP_INVALIDCALL;
3451 }
3452
3453 if( scip->lp != NULL && SCIPlpDiving(scip->lp) )
3454 {
3455 SCIPerrorMessage("cannot start strong branching with propagation while in diving mode\n");
3456 return SCIP_INVALIDCALL;
3457 }
3458
3459 /* other then in SCIPstartProbing(), we do not disable collecting variable statistics during strong branching;
3460 * we cannot disable it, because the pseudo costs would not be updated, otherwise,
3461 * and reliability branching would end up doing strong branching all the time
3462 */
3463 SCIP_CALL( SCIPtreeStartProbing(scip->tree, scip->mem->probmem, scip->set, scip->lp, scip->relaxation, scip->transprob, TRUE) );
3464
3465 /* inform the LP that the current probing mode is used for strong branching */
3467 }
3468 else
3469 {
3471 }
3472
3473 /* reset local strong branching info */
3474 scip->stat->lastsblpsolstats[0] = scip->stat->lastsblpsolstats[1] = SCIP_LPSOLSTAT_NOTSOLVED;
3475
3476 return SCIP_OKAY;
3477}
3478
3479/** end strong branching - call after any strong branching
3480 *
3481 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3482 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3483 *
3484 * @pre This method can be called if @p scip is in one of the following stages:
3485 * - \ref SCIP_STAGE_PRESOLVED
3486 * - \ref SCIP_STAGE_SOLVING
3487 */
3489 SCIP* scip /**< SCIP data structure */
3490 )
3491{
3492 assert( scip != NULL );
3493
3494 SCIP_CALL( SCIPcheckStage(scip, "SCIPendStrongbranch", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3495
3496 /* depending on whether the strong branching mode was started with propagation enabled or not, we end the strong
3497 * branching probing mode or the LP strong branching mode
3498 */
3499 if( SCIPtreeProbing(scip->tree) )
3500 {
3501 SCIP_NODE* node;
3502 SCIP_DOMCHG* domchg;
3503 SCIP_VAR** boundchgvars;
3504 SCIP_Real* bounds;
3505 SCIP_BOUNDTYPE* boundtypes;
3506 int nboundchgs;
3507 int nbnds;
3508 int i;
3509
3510 /* collect all bound changes deducted during probing, which were applied at the probing root and apply them to the
3511 * focusnode
3512 */
3513 node = SCIPgetCurrentNode(scip);
3515 assert(SCIPgetProbingDepth(scip) == 0);
3516
3517 domchg = SCIPnodeGetDomchg(node);
3518 nboundchgs = SCIPdomchgGetNBoundchgs(domchg);
3519
3520 SCIP_CALL( SCIPallocBufferArray(scip, &boundchgvars, nboundchgs) );
3521 SCIP_CALL( SCIPallocBufferArray(scip, &bounds, nboundchgs) );
3522 SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, nboundchgs) );
3523
3524 for( i = 0, nbnds = 0; i < nboundchgs; ++i )
3525 {
3526 SCIP_BOUNDCHG* boundchg;
3527
3528 boundchg = SCIPdomchgGetBoundchg(domchg, i);
3529
3530 /* ignore redundant bound changes */
3531 if( SCIPboundchgIsRedundant(boundchg) )
3532 continue;
3533
3534 boundchgvars[nbnds] = SCIPboundchgGetVar(boundchg);
3535 bounds[nbnds] = SCIPboundchgGetNewbound(boundchg);
3536 boundtypes[nbnds] = SCIPboundchgGetBoundtype(boundchg);
3537 ++nbnds;
3538 }
3539
3540 SCIPdebugMsg(scip, "ending strong branching with probing: %d bound changes collected\n", nbnds);
3541
3542 /* inform the LP that the probing mode is not used for strong branching anymore */
3544
3545 /* switch back from probing to normal operation mode and restore variables and constraints to focus node */
3546 SCIP_CALL( SCIPtreeEndProbing(scip->tree, scip->reopt, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
3547 scip->transprob, scip->origprob, scip->lp, scip->relaxation, scip->primal,
3548 scip->branchcand, scip->eventqueue, scip->eventfilter, scip->cliquetable) );
3549
3550 /* apply the collected bound changes */
3551 for( i = 0; i < nbnds; ++i )
3552 {
3553 if( boundtypes[i] == SCIP_BOUNDTYPE_LOWER )
3554 {
3555 SCIPdebugMsg(scip, "apply probing lower bound change <%s> >= %.9g\n", SCIPvarGetName(boundchgvars[i]), bounds[i]);
3556 SCIP_CALL( SCIPchgVarLb(scip, boundchgvars[i], bounds[i]) );
3557 }
3558 else
3559 {
3560 SCIPdebugMsg(scip, "apply probing upper bound change <%s> <= %.9g\n", SCIPvarGetName(boundchgvars[i]), bounds[i]);
3561 SCIP_CALL( SCIPchgVarUb(scip, boundchgvars[i], bounds[i]) );
3562 }
3563 }
3564
3565 SCIPfreeBufferArray(scip, &boundtypes);
3566 SCIPfreeBufferArray(scip, &bounds);
3567 SCIPfreeBufferArray(scip, &boundchgvars);
3568 }
3569 else
3570 {
3571 SCIPdebugMsg(scip, "ending strong branching\n");
3572
3574 }
3575
3576 return SCIP_OKAY;
3577}
3578
3579/** analyze the strong branching for the given variable; that includes conflict analysis for infeasible branches and
3580 * storing of root reduced cost information
3581 */
3582static
3584 SCIP* scip, /**< SCIP data structure */
3585 SCIP_VAR* var, /**< variable to analyze */
3586 SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
3587 SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
3588 SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
3589 * infeasible downwards branch, or NULL */
3590 SCIP_Bool* upconflict /**< pointer to store whether a conflict constraint was created for an
3591 * infeasible upwards branch, or NULL */
3592 )
3593{
3594 SCIP_COL* col;
3595 SCIP_Bool downcutoff;
3596 SCIP_Bool upcutoff;
3597
3598 col = SCIPvarGetCol(var);
3599 assert(col != NULL);
3600
3601 downcutoff = col->sbdownvalid && SCIPsetIsGE(scip->set, col->sbdown, scip->lp->cutoffbound);
3602 upcutoff = col->sbupvalid && SCIPsetIsGE(scip->set, col->sbup, scip->lp->cutoffbound);
3603
3604 if( downinf != NULL && !SCIPisExact(scip) )
3605 *downinf = downcutoff;
3606 if( upinf != NULL && !SCIPisExact(scip) )
3607 *upinf = upcutoff;
3608
3609 /* analyze infeasible strong branching sub problems:
3610 * because the strong branching's bound change is necessary for infeasibility, it cannot be undone;
3611 * therefore, infeasible strong branchings on non-binary variables will not produce a valid conflict constraint
3612 */
3613 if( scip->set->conf_enable && scip->set->conf_usesb && scip->set->nconflicthdlrs > 0
3614 && SCIPvarIsBinary(var) && SCIPtreeGetCurrentDepth(scip->tree) > 0 )
3615 {
3616 if( (downcutoff && SCIPsetFeasCeil(scip->set, col->primsol-1.0) >= col->lb - 0.5)
3617 || (upcutoff && SCIPsetFeasFloor(scip->set, col->primsol+1.0) <= col->ub + 0.5) )
3618 {
3619 assert(downconflict != NULL);
3620 assert(upconflict != NULL);
3621 SCIP_CALL( SCIPconflictAnalyzeStrongbranch(scip->conflict, scip->conflictstore, scip->mem->probmem, scip->set, scip->stat,
3622 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter, \
3623 scip->cliquetable, col, downconflict, upconflict) );
3624 }
3625 }
3626
3627 /* the strong branching results can be used to strengthen the root reduced cost information which is used for example
3628 * to propagate against the cutoff bound
3629 *
3630 * @note Ignore the results if the LP solution of the down (up) branch LP is smaller which should not happened by
3631 * theory but can arise due to numerical issues.
3632 */
3634 {
3635 SCIP_Real lpobjval;
3636
3638
3639 lpobjval = SCIPlpGetObjval(scip->lp, scip->set, scip->transprob);
3640
3641 if( col->sbdownvalid && SCIPsetFeasCeil(scip->set, col->primsol-1.0) >= col->lb - 0.5 && lpobjval < col->sbdown )
3642 SCIPvarUpdateBestRootSol(var, scip->set, SCIPvarGetUbGlobal(var), -(col->sbdown - lpobjval), lpobjval);
3643 if( col->sbupvalid && SCIPsetFeasFloor(scip->set, col->primsol+1.0) <= col->ub + 0.5 && lpobjval < col->sbup )
3644 SCIPvarUpdateBestRootSol(var, scip->set, SCIPvarGetLbGlobal(var), col->sbup - lpobjval, lpobjval);
3645 }
3646
3647 return SCIP_OKAY;
3648}
3649
3650/** gets strong branching information on column variable with fractional value
3651 *
3652 * Before calling this method, the strong branching mode must have been activated by calling SCIPstartStrongbranch();
3653 * after strong branching was done for all candidate variables, the strong branching mode must be ended by
3654 * SCIPendStrongbranch(). Since this method does not apply domain propagation before strongbranching,
3655 * propagation should not be enabled in the SCIPstartStrongbranch() call.
3656 *
3657 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3658 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3659 *
3660 * @pre This method can be called if @p scip is in one of the following stages:
3661 * - \ref SCIP_STAGE_PRESOLVED
3662 * - \ref SCIP_STAGE_SOLVING
3663 */
3665 SCIP* scip, /**< SCIP data structure */
3666 SCIP_VAR* var, /**< variable to get strong branching values for */
3667 int itlim, /**< iteration limit for strong branchings */
3668 SCIP_Bool idempotent, /**< should scip's state remain the same after the call (statistics, column states...), or should it be updated ? */
3669 SCIP_Real* down, /**< stores dual bound after branching column down */
3670 SCIP_Real* up, /**< stores dual bound after branching column up */
3671 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
3672 * otherwise, it can only be used as an estimate value */
3673 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
3674 * otherwise, it can only be used as an estimate value */
3675 SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
3676 SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
3677 SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
3678 * infeasible downwards branch, or NULL */
3679 SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
3680 * infeasible upwards branch, or NULL */
3681 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3682 * solving process should be stopped (e.g., due to a time limit) */
3683 )
3684{
3685 SCIP_COL* col;
3686 SCIP_Real lpobjval;
3687 SCIP_Real localdown;
3688 SCIP_Real localup;
3689 SCIP_Bool localdownvalid;
3690 SCIP_Bool localupvalid;
3691
3692 assert(var != NULL);
3693 assert(lperror != NULL);
3694 assert(!SCIPinProbing(scip)); /* we should not be in strong branching with propagation mode */
3695 assert(var->scip == scip);
3696
3697 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchFrac", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3698
3699 lpobjval = SCIPgetLPObjval(scip);
3700 if( downvalid != NULL )
3701 *downvalid = FALSE;
3702 if( upvalid != NULL )
3703 *upvalid = FALSE;
3704 if( downinf != NULL )
3705 *downinf = FALSE;
3706 if( upinf != NULL )
3707 *upinf = FALSE;
3708 if( downconflict != NULL )
3709 *downconflict = FALSE;
3710 if( upconflict != NULL )
3711 *upconflict = FALSE;
3712
3714 {
3715 SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3716 return SCIP_INVALIDDATA;
3717 }
3718
3719 col = SCIPvarGetCol(var);
3720 assert(col != NULL);
3721
3722 if( !SCIPcolIsInLP(col) )
3723 {
3724 SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3725 return SCIP_INVALIDDATA;
3726 }
3727
3728 /* check if the solving process should be aborted */
3729 if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3730 {
3731 /* mark this as if the LP failed */
3732 *lperror = TRUE;
3733 return SCIP_OKAY;
3734 }
3735
3736 /* call strong branching for column with fractional value */
3737 SCIP_CALL( SCIPcolGetStrongbranch(col, FALSE, scip->set, scip->stat, scip->transprob, scip->lp, itlim, !idempotent, !idempotent,
3738 &localdown, &localup, &localdownvalid, &localupvalid, lperror) );
3739
3740 /* update lower bound by the higher pseudo objective value */
3741 if( !SCIPisZero(scip, SCIPvarGetObj(var)) )
3742 {
3743 SCIP_Real oldbound;
3744 SCIP_Real newbound;
3745 SCIP_Real pseudoobjval;
3746 SCIP_BOUNDTYPE boundtype = SCIPvarGetBestBoundType(var);
3747
3748 if( boundtype == SCIP_BOUNDTYPE_UPPER )
3749 {
3750 oldbound = SCIPvarGetUbLocal(var);
3751 newbound = SCIPfeasFloor(scip, SCIPvarGetLPSol(var));
3752 }
3753 else
3754 {
3755 oldbound = SCIPvarGetLbLocal(var);
3756 newbound = SCIPfeasCeil(scip, SCIPvarGetLPSol(var));
3757 }
3758
3759 pseudoobjval = SCIPlpGetModifiedPseudoObjval(scip->lp, scip->set, scip->transprob, var, oldbound, newbound, boundtype);
3760
3761 if( pseudoobjval > lpobjval )
3762 {
3763 if( boundtype == SCIP_BOUNDTYPE_UPPER )
3764 {
3765 if( !localdownvalid || localdown < pseudoobjval )
3766 {
3767 localdown = pseudoobjval;
3768 localdownvalid = TRUE;
3769 }
3770 }
3771 else
3772 {
3773 if( !localupvalid || localup < pseudoobjval )
3774 {
3775 localup = pseudoobjval;
3776 localupvalid = TRUE;
3777 }
3778 }
3779 }
3780 }
3781
3782 /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3783 * declare the sub nodes infeasible
3784 */
3785 if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) )
3786 {
3787 if( !idempotent ) /*lint !e774*/
3788 {
3789 SCIP_CALL( analyzeStrongbranch(scip, var, NULL, NULL, downconflict, upconflict) );
3790 }
3791
3792 if( downinf != NULL )
3793 *downinf = localdownvalid && SCIPsetIsGE(scip->set, localdown, scip->lp->cutoffbound);
3794 if( upinf != NULL )
3795 *upinf = localupvalid && SCIPsetIsGE(scip->set, localup, scip->lp->cutoffbound);
3796 }
3797
3798 if( down != NULL )
3799 *down = localdown;
3800 if( up != NULL )
3801 *up = localup;
3802 if( downvalid != NULL )
3803 *downvalid = localdownvalid;
3804 if( upvalid != NULL )
3805 *upvalid = localupvalid;
3806
3807 return SCIP_OKAY;
3808}
3809
3810/** create, solve, and evaluate a single strong branching child (for strong branching with propagation) */
3811static
3813 SCIP* scip, /**< SCIP data structure */
3814 SCIP_VAR* var, /**< variable to get strong branching values for */
3815 SCIP_Bool down, /**< do we regard the down child? */
3816 SCIP_Bool firstchild, /**< is this the first of the two strong branching children? */
3817 SCIP_Bool propagate, /**< should domain propagation be performed? */
3818 SCIP_Real newbound, /**< new bound to apply at the strong branching child */
3819 int itlim, /**< iteration limit for strong branchings */
3820 int maxproprounds, /**< maximum number of propagation rounds (-1: no limit, -2: parameter
3821 * settings) */
3822 SCIP_Real* value, /**< stores dual bound for strong branching child */
3823 SCIP_Bool* valid, /**< stores whether the returned value is a valid dual bound, or NULL;
3824 * otherwise, it can only be used as an estimate value */
3825 SCIP_Longint* ndomreductions, /**< pointer to store the number of domain reductions found, or NULL */
3826 SCIP_Bool* conflict, /**< pointer to store whether a conflict constraint was created for an
3827 * infeasible strong branching child, or NULL */
3828 SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred or the
3829 * solving process should be stopped (e.g., due to a time limit) */
3830 SCIP_VAR** vars, /**< active problem variables */
3831 int nvars, /**< number of active problem variables */
3832 SCIP_Real* newlbs, /**< array to store valid lower bounds for all active variables, or NULL */
3833 SCIP_Real* newubs, /**< array to store valid upper bounds for all active variables, or NULL */
3834 SCIP_Bool* foundsol, /**< pointer to store whether a primal solution was found during strong branching */
3835 SCIP_Bool* cutoff /**< pointer to store whether the strong branching child is infeasible */
3836 )
3837{
3838 SCIP_Longint ndomreds;
3839
3840 assert(value != NULL);
3841 assert(foundsol != NULL);
3842 assert(cutoff != NULL);
3843 assert(lperror != NULL);
3844 assert(valid != NULL ? !(*valid) : TRUE);
3845
3846 *foundsol = FALSE;
3847 *cutoff = FALSE;
3848 *lperror = FALSE;
3849
3850 /* check whether the strong branching child is already infeasible due to the bound change */
3851 if( down )
3852 {
3853 /* the down branch is infeasible due to the branching bound change; since this means that solval is not within the
3854 * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3855 * are valid for and were already applied at the probing root
3856 */
3857 if( newbound < SCIPvarGetLbLocal(var) - 0.5 )
3858 {
3859 *value = SCIPinfinity(scip);
3860
3861 if( valid != NULL )
3862 *valid = TRUE;
3863
3864 /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3865 if( conflict != NULL )
3866 *conflict = TRUE;
3867
3868 *cutoff = TRUE;
3869
3870 return SCIP_OKAY;
3871 }
3872 }
3873 else
3874 {
3875 /* the up branch is infeasible due to the branching bound change; since this means that solval is not within the
3876 * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3877 * are valid for and were already applied at the probing root
3878 */
3879 if( newbound > SCIPvarGetUbLocal(var) + 0.5 )
3880 {
3881 *value = SCIPinfinity(scip);
3882
3883 if( valid != NULL )
3884 *valid = TRUE;
3885
3886 /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3887 if( conflict != NULL )
3888 *conflict = TRUE;
3889
3890 *cutoff = TRUE;
3891
3892 return SCIP_OKAY;
3893 }
3894 }
3895
3896 /* we need to ensure that we can create at least one new probing node without exceeding the maximal tree depth */
3898 {
3899 /* create a new probing node for the strong branching child and apply the new bound for the variable */
3901
3902 if( down )
3903 {
3904 assert(SCIPisGE(scip, newbound, SCIPvarGetLbLocal(var)));
3905 if( SCIPisLT(scip, newbound, SCIPvarGetUbLocal(var)) )
3906 {
3907 SCIP_CALL( SCIPchgVarUbProbing(scip, var, newbound) );
3908 }
3909 }
3910 else
3911 {
3912 assert(SCIPisLE(scip, newbound, SCIPvarGetUbLocal(var)));
3913 if( SCIPisGT(scip, newbound, SCIPvarGetLbLocal(var)) )
3914 {
3915 SCIP_CALL( SCIPchgVarLbProbing(scip, var, newbound) );
3916 }
3917 }
3918 }
3919 else
3920 {
3921 if( valid != NULL )
3922 *valid = FALSE;
3923
3924 *cutoff = FALSE;
3925
3926 if( conflict != NULL )
3927 *conflict = FALSE;
3928
3929 return SCIP_OKAY;
3930 }
3931
3932 /* propagate domains at the probing node */
3933 if( propagate )
3934 {
3935 /* start time measuring */
3936 SCIPclockStart(scip->stat->strongpropclock, scip->set);
3937
3938 ndomreds = 0;
3939 SCIP_CALL( SCIPpropagateProbing(scip, maxproprounds, cutoff, &ndomreds) );
3940
3941 /* store number of domain reductions in strong branching */
3942 if( down )
3943 SCIPstatAdd(scip->stat, scip->set, nsbdowndomchgs, ndomreds);
3944 else
3945 SCIPstatAdd(scip->stat, scip->set, nsbupdomchgs, ndomreds);
3946
3947 if( ndomreductions != NULL )
3948 *ndomreductions = ndomreds;
3949
3950 /* stop time measuring */
3951 SCIPclockStop(scip->stat->strongpropclock, scip->set);
3952
3953 if( *cutoff )
3954 {
3955 *value = SCIPinfinity(scip);
3956
3957 if( valid != NULL )
3958 *valid = TRUE;
3959
3960 SCIPdebugMsg(scip, "%s branch of var <%s> detected infeasible during propagation\n",
3961 down ? "down" : "up", SCIPvarGetName(var));
3962 }
3963 }
3964
3965 /* if propagation did not already detect infeasibility, solve the probing LP */
3966 if( !(*cutoff) )
3967 {
3968 SCIP_CALL( SCIPsolveProbingLP(scip, itlim, lperror, cutoff) );
3969 assert(SCIPisLPRelax(scip));
3970
3971 if( *cutoff )
3972 {
3973 assert(!(*lperror));
3974
3975 *value = SCIPinfinity(scip);
3976
3977 if( valid != NULL )
3978 *valid = TRUE;
3979
3980 SCIPdebugMsg(scip, "%s branch of var <%s> detected infeasible in LP solving: status=%d\n",
3981 down ? "down" : "up", SCIPvarGetName(var), SCIPgetLPSolstat(scip));
3982 }
3983 else if( !(*lperror) )
3984 {
3985 /* save the lp solution status */
3986 scip->stat->lastsblpsolstats[down ? 0 : 1] = SCIPgetLPSolstat(scip);
3987
3988 switch( SCIPgetLPSolstat(scip) )
3989 {
3991 {
3992 *value = SCIPgetLPObjval(scip);
3993 assert(SCIPisLT(scip, *value, SCIPgetCutoffbound(scip)));
3994
3995 SCIPdebugMsg(scip, "probing LP solved to optimality, objective value: %16.9g\n", *value);
3996
3997 if( valid != NULL )
3998 *valid = TRUE;
3999
4000 /* check the strong branching LP solution for feasibility */
4001 SCIP_CALL( SCIPtryStrongbranchLPSol(scip, foundsol, cutoff) );
4002 break;
4003 }
4005 ++scip->stat->nsbtimesiterlimhit;
4006 /*lint -fallthrough*/
4008 {
4009 /* use LP value as estimate */
4010 SCIP_LPI* lpi;
4011 SCIP_Real objval;
4012 SCIP_Real looseobjval;
4013
4014 SCIPdebugMsg(scip, "probing LP hit %s limit\n", SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_ITERLIMIT ? "iteration" : "time");
4015
4016 /* we access the LPI directly, because when a time limit was hit, we cannot access objective value and dual
4017 * feasibility using the SCIPlp... methods; we should try to avoid direct calls to the LPI, but this is rather
4018 * uncritical here, because we are immediately after the SCIPsolveProbingLP() call, because we access the LPI
4019 * read-only, and we check SCIPlpiWasSolved() first
4020 */
4021 SCIP_CALL( SCIPgetLPI(scip, &lpi) );
4022
4023 if( SCIPlpiWasSolved(lpi) )
4024 {
4025 SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
4026 looseobjval = SCIPlpGetLooseObjval(scip->lp, scip->set, scip->transprob);
4027
4028 /* the infinity value in the LPI should not be smaller than SCIP's infinity value */
4029 assert(!SCIPlpiIsInfinity(lpi, objval) || SCIPisInfinity(scip, objval));
4030
4031 /* we use SCIP's infinity value here because a value larger than this is counted as infeasible by SCIP */
4032 if( SCIPisInfinity(scip, objval) )
4033 *value = SCIPinfinity(scip);
4034 else if( SCIPisInfinity(scip, -looseobjval) )
4035 *value = -SCIPinfinity(scip);
4036 else
4037 *value = objval + looseobjval;
4038
4039 if( SCIPlpiIsDualFeasible(lpi) )
4040 {
4041 if( valid != NULL )
4042 *valid = TRUE;
4043
4044 if( SCIPisGE(scip, *value, SCIPgetCutoffbound(scip)) )
4045 *cutoff = TRUE;
4046 }
4047 }
4048 break;
4049 }
4052 *lperror = TRUE;
4053 break;
4054 case SCIP_LPSOLSTAT_NOTSOLVED: /* should only be the case for *cutoff = TRUE or *lperror = TRUE */
4055 case SCIP_LPSOLSTAT_OBJLIMIT: /* in this case, *cutoff should be TRUE and we should not get here */
4056 case SCIP_LPSOLSTAT_INFEASIBLE: /* in this case, *cutoff should be TRUE and we should not get here */
4057 default:
4058 SCIPerrorMessage("invalid LP solution status <%d>\n", SCIPgetLPSolstat(scip));
4059 return SCIP_INVALIDDATA;
4060 } /*lint !e788*/
4061 }
4062
4063 /* If columns are missing in the LP, the cutoff flag may be wrong. Therefore, we need to set it and the valid pointer
4064 * to false here.
4065 */
4066 if( (*cutoff) && !SCIPallColsInLP(scip) )
4067 {
4068 *cutoff = FALSE;
4069 }
4070
4071#ifndef NDEBUG
4072 if( *lperror )
4073 {
4074 SCIPdebugMsg(scip, "error during strong branching probing LP solving: status=%d\n", SCIPgetLPSolstat(scip));
4075 }
4076#endif
4077 }
4078
4079 /* if the subproblem was feasible, we store the local bounds of the variables after propagation and (possibly)
4080 * conflict analysis
4081 * @todo do this after propagation? should be able to get valid bounds more often, but they might be weaker
4082 */
4083 if( !(*cutoff) && newlbs != NULL)
4084 {
4085 int v;
4086
4087 assert(newubs != NULL);
4088
4089 /* initialize the newlbs and newubs to the current local bounds */
4090 if( firstchild )
4091 {
4092 for( v = 0; v < nvars; ++v )
4093 {
4094 newlbs[v] = SCIPvarGetLbLocal(vars[v]);
4095 newubs[v] = SCIPvarGetUbLocal(vars[v]);
4096 }
4097 }
4098 /* update newlbs and newubs: take the weaker of the already stored bounds and the current local bounds */
4099 else
4100 {
4101 for( v = 0; v < nvars; ++v )
4102 {
4103 SCIP_Real lb = SCIPvarGetLbLocal(vars[v]);
4104 SCIP_Real ub = SCIPvarGetUbLocal(vars[v]);
4105
4106 newlbs[v] = MIN(newlbs[v], lb);
4107 newubs[v] = MAX(newubs[v], ub);
4108 }
4109 }
4110 }
4111
4112 /* revert all changes at the probing node */
4114
4115 return SCIP_OKAY;
4116}
4117
4118/** gets strong branching information with previous domain propagation on column variable
4119 *
4120 * Before calling this method, the strong branching mode must have been activated by calling SCIPstartStrongbranch();
4121 * after strong branching was done for all candidate variables, the strong branching mode must be ended by
4122 * SCIPendStrongbranch(). Since this method applies domain propagation before strongbranching, propagation has to be be
4123 * enabled in the SCIPstartStrongbranch() call.
4124 *
4125 * Before solving the strong branching LP, domain propagation can be performed. The number of propagation rounds
4126 * can be specified by the parameter @p maxproprounds.
4127 *
4128 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4129 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4130 *
4131 * @pre This method can be called if @p scip is in one of the following stages:
4132 * - \ref SCIP_STAGE_PRESOLVED
4133 * - \ref SCIP_STAGE_SOLVING
4134 *
4135 * @warning When using this method, LP banching candidates and solution values must be copied beforehand, because
4136 * they are updated w.r.t. the strong branching LP solution.
4137 */
4139 SCIP* scip, /**< SCIP data structure */
4140 SCIP_VAR* var, /**< variable to get strong branching values for */
4141 SCIP_Real solval, /**< value of the variable in the current LP solution */
4142 SCIP_Real lpobjval, /**< LP objective value of the current LP solution */
4143 int itlim, /**< iteration limit for strong branchings */
4144 int maxproprounds, /**< maximum number of propagation rounds (-1: no limit, -2: parameter
4145 * settings) */
4146 SCIP_Real* down, /**< stores dual bound after branching column down */
4147 SCIP_Real* up, /**< stores dual bound after branching column up */
4148 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4149 * otherwise, it can only be used as an estimate value */
4150 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4151 * otherwise, it can only be used as an estimate value */
4152 SCIP_Longint* ndomredsdown, /**< pointer to store the number of domain reductions down, or NULL */
4153 SCIP_Longint* ndomredsup, /**< pointer to store the number of domain reductions up, or NULL */
4154 SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
4155 SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
4156 SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
4157 * infeasible downwards branch, or NULL */
4158 SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
4159 * infeasible upwards branch, or NULL */
4160 SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred or the
4161 * solving process should be stopped (e.g., due to a time limit) */
4162 SCIP_Real* newlbs, /**< array to store valid lower bounds for all active variables, or NULL */
4163 SCIP_Real* newubs /**< array to store valid upper bounds for all active variables, or NULL */
4164 )
4165{
4166 SCIP_COL* col;
4167 SCIP_VAR** vars;
4168 SCIP_Longint oldniters;
4169 SCIP_Real newub;
4170 SCIP_Real newlb;
4171 SCIP_Bool propagate;
4172 SCIP_Bool cutoff;
4173 SCIP_Bool downchild;
4174 SCIP_Bool firstchild;
4175 SCIP_Bool foundsol;
4176 SCIP_Bool downvalidlocal;
4177 SCIP_Bool upvalidlocal;
4178 SCIP_Bool allcolsinlp;
4179 SCIP_Bool enabledconflict;
4180 int oldnconflicts;
4181 int nvars;
4182
4183 assert(var != NULL);
4184 assert(SCIPvarIsIntegral(var));
4185 assert(down != NULL);
4186 assert(up != NULL);
4187 assert(lperror != NULL);
4188 assert((newlbs != NULL) == (newubs != NULL));
4189 assert(SCIPinProbing(scip));
4190 assert(var->scip == scip);
4191
4192 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchWithPropagation", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4193
4194 /* check whether propagation should be performed */
4195 propagate = (maxproprounds != 0 && maxproprounds != -3);
4196
4197 /* Check, if all existing columns are in LP.
4198 * If this is not the case, we may still return that the up and down dual bounds are valid, because the branching
4199 * rule should not apply them otherwise.
4200 * However, we must not set the downinf or upinf pointers to TRUE based on the dual bound, because we cannot
4201 * guarantee that this node can be cut off.
4202 */
4203 allcolsinlp = SCIPallColsInLP(scip);
4204
4205 /* if maxproprounds is -2, change it to 0, which for the following calls means using the parameter settings */
4206 if( maxproprounds == -2 )
4207 maxproprounds = 0;
4208
4209 *down = lpobjval;
4210 *up = lpobjval;
4211 if( downvalid != NULL )
4212 *downvalid = FALSE;
4213 if( upvalid != NULL )
4214 *upvalid = FALSE;
4215 if( downinf != NULL )
4216 *downinf = FALSE;
4217 if( upinf != NULL )
4218 *upinf = FALSE;
4219 if( downconflict != NULL )
4220 *downconflict = FALSE;
4221 if( upconflict != NULL )
4222 *upconflict = FALSE;
4223 if( ndomredsdown != NULL )
4224 *ndomredsdown = 0;
4225 if( ndomredsup != NULL )
4226 *ndomredsup = 0;
4227
4228 *lperror = FALSE;
4229
4230 vars = SCIPgetVars(scip);
4231 nvars = SCIPgetNVars(scip);
4232
4233 scip->stat->lastsblpsolstats[0] = scip->stat->lastsblpsolstats[1] = SCIP_LPSOLSTAT_NOTSOLVED;
4234
4235 /* check if the solving process should be aborted */
4236 if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
4237 {
4238 /* mark this as if the LP failed */
4239 *lperror = TRUE;
4240 return SCIP_OKAY;
4241 }
4242
4244 {
4245 SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
4246 return SCIP_INVALIDDATA;
4247 }
4248
4249 col = SCIPvarGetCol(var);
4250 assert(col != NULL);
4251
4252 if( !SCIPcolIsInLP(col) )
4253 {
4254 SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
4255 return SCIP_INVALIDDATA;
4256 }
4257
4258 newlb = SCIPfeasFloor(scip, solval + 1.0);
4259 newub = SCIPfeasCeil(scip, solval - 1.0);
4260
4261 SCIPdebugMsg(scip, "strong branching on var <%s>: solval=%g, lb=%g, ub=%g\n", SCIPvarGetName(var), solval,
4263
4264 /* the up branch is infeasible due to the branching bound change; since this means that solval is not within the
4265 * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
4266 * are valid for and were already applied at the probing root
4267 */
4268 if( newlb > SCIPvarGetUbLocal(var) + 0.5 )
4269 {
4270 *up = SCIPinfinity(scip);
4271
4272 if( upinf != NULL )
4273 *upinf = TRUE;
4274
4275 if( upvalid != NULL )
4276 *upvalid = TRUE;
4277
4278 /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
4279 if( upconflict != NULL )
4280 *upconflict = TRUE;
4281
4282 SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
4283 *down, *up, FALSE, TRUE, 0LL, INT_MAX);
4284
4285 /* we do not regard the down branch; its valid pointer stays set to FALSE */
4286 return SCIP_OKAY;
4287 }
4288
4289 /* the down branch is infeasible due to the branching bound change; since this means that solval is not within the
4290 * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
4291 * are valid for and were already applied at the probing root
4292 */
4293 if( newub < SCIPvarGetLbLocal(var) - 0.5 )
4294 {
4295 *down = SCIPinfinity(scip);
4296
4297 if( downinf != NULL )
4298 *downinf = TRUE;
4299
4300 if( downvalid != NULL )
4301 *downvalid = TRUE;
4302
4303 /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
4304 if( downconflict != NULL )
4305 *downconflict = TRUE;
4306
4307 SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
4308 *down, *up, TRUE, FALSE, 0LL, INT_MAX);
4309
4310 /* we do not regard the up branch; its valid pointer stays set to FALSE */
4311 return SCIP_OKAY;
4312 }
4313
4314 /* We now do strong branching by creating the two potential child nodes as probing nodes and solving them one after
4315 * the other. We will stop when the first child is detected infeasible, saving the effort we would need for the
4316 * second child. Since empirically, the up child tends to be infeasible more often, we do strongbranching first on
4317 * the up branch.
4318 */
4319 oldniters = scip->stat->nsbdivinglpiterations;
4320 firstchild = TRUE;
4321 cutoff = FALSE;
4322
4323 /* switch conflict analysis according to usesb parameter */
4324 enabledconflict = scip->set->conf_enable;
4325 scip->set->conf_enable = (scip->set->conf_enable && scip->set->conf_usesb);
4326
4327 /* @todo: decide the branch to look at first based on the cutoffs in previous calls? */
4328 downchild = SCIPisStrongbranchDownFirst(scip, var);
4329
4330 downvalidlocal = FALSE;
4331 upvalidlocal = FALSE;
4332
4333 do
4334 {
4335 oldnconflicts = SCIPconflictGetNConflicts(scip->conflict);
4336
4337 if( downchild )
4338 {
4339 SCIP_CALL( performStrongbranchWithPropagation(scip, var, downchild, firstchild || cutoff, propagate, newub, itlim, maxproprounds,
4340 down, &downvalidlocal, ndomredsdown, downconflict, lperror, vars, nvars, newlbs, newubs, &foundsol, &cutoff) );
4341
4342 /* check for infeasibility */
4343 if( cutoff )
4344 {
4345 if( downinf != NULL )
4346 *downinf = TRUE;
4347
4348 if( downconflict != NULL
4349 && ( SCIPvarGetLbLocal(var) > newub + 0.5 || SCIPconflictGetNConflicts(scip->conflict) > oldnconflicts ) )
4350 *downconflict = TRUE;
4351 }
4352
4353 /* check whether new solutions rendered the other child infeasible */
4354 if( foundsol && allcolsinlp && SCIPisGE(scip, upvalidlocal ? *up : lpobjval, SCIPgetCutoffbound(scip)) )
4355 {
4356 if( upinf != NULL )
4357 *upinf = TRUE;
4358
4359 upvalidlocal = TRUE;
4360 cutoff = TRUE;
4361 }
4362 }
4363 else
4364 {
4365 SCIP_CALL( performStrongbranchWithPropagation(scip, var, downchild, firstchild || cutoff, propagate, newlb, itlim, maxproprounds,
4366 up, &upvalidlocal, ndomredsup, upconflict, lperror, vars, nvars, newlbs, newubs, &foundsol, &cutoff) );
4367
4368 /* check for infeasibility */
4369 if( cutoff )
4370 {
4371 if( upinf != NULL )
4372 *upinf = TRUE;
4373
4374 if( upconflict != NULL
4375 && ( SCIPvarGetUbLocal(var) < newlb - 0.5 || SCIPconflictGetNConflicts(scip->conflict) > oldnconflicts ) )
4376 *upconflict = TRUE;
4377 }
4378
4379 /* check whether new solutions rendered the other child infeasible */
4380 if( foundsol && allcolsinlp && SCIPisGE(scip, downvalidlocal ? *down : lpobjval, SCIPgetCutoffbound(scip)) )
4381 {
4382 if( downinf != NULL )
4383 *downinf = TRUE;
4384
4385 downvalidlocal = TRUE;
4386 cutoff = TRUE;
4387 }
4388 }
4389
4390 downchild = !downchild;
4391 firstchild = !firstchild;
4392 }
4393 /* if a child is cut off and forceall is FALSE, we do not regard the other child */
4394 while( !firstchild && ( !cutoff || scip->set->branch_forceall ) );
4395
4396 /* update lower bound by the higher pseudo objective value */
4397 if( ( downinf == NULL || !(*downinf) ) && ( upinf == NULL || !(*upinf) ) && !SCIPisZero(scip, SCIPvarGetObj(var)) )
4398 {
4399 SCIP_Real oldbound;
4400 SCIP_Real newbound;
4401 SCIP_Real pseudoobjval;
4402 SCIP_BOUNDTYPE boundtype = SCIPvarGetBestBoundType(var);
4403
4404 if( boundtype == SCIP_BOUNDTYPE_UPPER )
4405 {
4406 oldbound = SCIPvarGetUbLocal(var);
4407 newbound = newub;
4408 }
4409 else
4410 {
4411 oldbound = SCIPvarGetLbLocal(var);
4412 newbound = newlb;
4413 }
4414
4415 pseudoobjval = SCIPlpGetModifiedPseudoObjval(scip->lp, scip->set, scip->transprob, var, oldbound, newbound, boundtype);
4416
4417 if( pseudoobjval > lpobjval )
4418 {
4419 if( boundtype == SCIP_BOUNDTYPE_UPPER )
4420 {
4421 if( !downvalidlocal || *down < pseudoobjval )
4422 {
4423 *down = pseudoobjval;
4424 downvalidlocal = TRUE;
4425
4426 if( downinf != NULL && allcolsinlp && SCIPisGE(scip, *down, SCIPgetCutoffbound(scip)) )
4427 *downinf = TRUE;
4428 }
4429 }
4430 else
4431 {
4432 if( !upvalidlocal || *up < pseudoobjval )
4433 {
4434 *up = pseudoobjval;
4435 upvalidlocal = TRUE;
4436
4437 if( upinf != NULL && allcolsinlp && SCIPisGE(scip, *up, SCIPgetCutoffbound(scip)) )
4438 *upinf = TRUE;
4439 }
4440 }
4441 }
4442 }
4443
4444 /* set strong branching information in column */
4445 if( *lperror )
4446 {
4447 SCIPcolInvalidateStrongbranchData(col, scip->set, scip->stat, scip->lp);
4448 }
4449 else
4450 {
4451 SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
4452 *down, *up, downvalidlocal, upvalidlocal, scip->stat->nsbdivinglpiterations - oldniters, itlim);
4453 }
4454
4455 if( downvalid != NULL )
4456 *downvalid = downvalidlocal;
4457 if( upvalid != NULL )
4458 *upvalid = upvalidlocal;
4459
4460 scip->set->conf_enable = enabledconflict;
4461
4462 return SCIP_OKAY; /*lint !e438*/
4463}
4464
4465/** gets strong branching information on column variable x with integral LP solution value (val); that is, the down branch
4466 * is (val -1.0) and the up brach ins (val +1.0)
4467 *
4468 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4469 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4470 *
4471 * @pre This method can be called if @p scip is in one of the following stages:
4472 * - \ref SCIP_STAGE_PRESOLVED
4473 * - \ref SCIP_STAGE_SOLVING
4474 *
4475 * @note If the integral LP solution value is the lower or upper bound of the variable, the corresponding branch will be
4476 * marked as infeasible. That is, the valid pointer and the infeasible pointer are set to TRUE.
4477 */
4479 SCIP* scip, /**< SCIP data structure */
4480 SCIP_VAR* var, /**< variable to get strong branching values for */
4481 int itlim, /**< iteration limit for strong branchings */
4482 SCIP_Bool idempotent, /**< should scip's state remain the same after the call (statistics, column states...), or should it be updated ? */
4483 SCIP_Real* down, /**< stores dual bound after branching column down */
4484 SCIP_Real* up, /**< stores dual bound after branching column up */
4485 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4486 * otherwise, it can only be used as an estimate value */
4487 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4488 * otherwise, it can only be used as an estimate value */
4489 SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
4490 SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
4491 SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
4492 * infeasible downwards branch, or NULL */
4493 SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
4494 * infeasible upwards branch, or NULL */
4495 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
4496 * solving process should be stopped (e.g., due to a time limit) */
4497 )
4498{
4499 SCIP_COL* col;
4500 SCIP_Real lpobjval;
4501 SCIP_Real localdown;
4502 SCIP_Real localup;
4503 SCIP_Bool localdownvalid;
4504 SCIP_Bool localupvalid;
4505
4506 assert(var != NULL);
4507 assert(lperror != NULL);
4508 assert(var->scip == scip);
4509
4510 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchInt", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4511
4512 lpobjval = SCIPgetLPObjval(scip);
4513 if( downvalid != NULL )
4514 *downvalid = FALSE;
4515 if( upvalid != NULL )
4516 *upvalid = FALSE;
4517 if( downinf != NULL )
4518 *downinf = FALSE;
4519 if( upinf != NULL )
4520 *upinf = FALSE;
4521 if( downconflict != NULL )
4522 *downconflict = FALSE;
4523 if( upconflict != NULL )
4524 *upconflict = FALSE;
4525
4527 {
4528 SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
4529 return SCIP_INVALIDDATA;
4530 }
4531
4532 col = SCIPvarGetCol(var);
4533 assert(col != NULL);
4534
4535 if( !SCIPcolIsInLP(col) )
4536 {
4537 SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
4538 return SCIP_INVALIDDATA;
4539 }
4540
4541 /* check if the solving process should be aborted */
4542 if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
4543 {
4544 /* mark this as if the LP failed */
4545 *lperror = TRUE;
4546 return SCIP_OKAY;
4547 }
4548
4549 /* call strong branching for column */
4550 SCIP_CALL( SCIPcolGetStrongbranch(col, TRUE, scip->set, scip->stat, scip->transprob, scip->lp, itlim, !idempotent, !idempotent,
4551 &localdown, &localup, &localdownvalid, &localupvalid, lperror) );
4552
4553 /* update lower bound by the higher pseudo objective value */
4554 if( !SCIPisZero(scip, SCIPvarGetObj(var)) )
4555 {
4556 SCIP_Real oldbound;
4557 SCIP_Real newbound;
4558 SCIP_Real pseudoobjval;
4559 SCIP_BOUNDTYPE boundtype = SCIPvarGetBestBoundType(var);
4560
4561 if( boundtype == SCIP_BOUNDTYPE_UPPER )
4562 {
4563 oldbound = SCIPvarGetUbLocal(var);
4564 newbound = SCIPfeasCeil(scip, SCIPvarGetLPSol(var)) - 1.0;
4565 }
4566 else
4567 {
4568 oldbound = SCIPvarGetLbLocal(var);
4569 newbound = SCIPfeasFloor(scip, SCIPvarGetLPSol(var)) + 1.0;
4570 }
4571
4572 pseudoobjval = SCIPlpGetModifiedPseudoObjval(scip->lp, scip->set, scip->transprob, var, oldbound, newbound, boundtype);
4573
4574 if( pseudoobjval > lpobjval )
4575 {
4576 if( boundtype == SCIP_BOUNDTYPE_UPPER )
4577 {
4578 if( !localdownvalid || localdown < pseudoobjval )
4579 {
4580 localdown = pseudoobjval;
4581 localdownvalid = TRUE;
4582 }
4583 }
4584 else
4585 {
4586 if( !localupvalid || localup < pseudoobjval )
4587 {
4588 localup = pseudoobjval;
4589 localupvalid = TRUE;
4590 }
4591 }
4592 }
4593 }
4594
4595 /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
4596 * declare the sub nodes infeasible
4597 */
4598 if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) )
4599 {
4600 if( !idempotent ) /*lint !e774*/
4601 {
4602 SCIP_CALL( analyzeStrongbranch(scip, var, NULL, NULL, downconflict, upconflict) );
4603 }
4604
4605 if( downinf != NULL )
4606 *downinf = localdownvalid && SCIPsetIsGE(scip->set, localdown, scip->lp->cutoffbound);
4607 if( upinf != NULL )
4608 *upinf = localupvalid && SCIPsetIsGE(scip->set, localup, scip->lp->cutoffbound);
4609 }
4610
4611 if( down != NULL )
4612 *down = localdown;
4613 if( up != NULL )
4614 *up = localup;
4615 if( downvalid != NULL )
4616 *downvalid = localdownvalid;
4617 if( upvalid != NULL )
4618 *upvalid = localupvalid;
4619
4620 return SCIP_OKAY;
4621}
4622
4623/** gets strong branching information on column variables with fractional values
4624 *
4625 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4626 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4627 *
4628 * @pre This method can be called if @p scip is in one of the following stages:
4629 * - \ref SCIP_STAGE_PRESOLVED
4630 * - \ref SCIP_STAGE_SOLVING
4631 */
4633 SCIP* scip, /**< SCIP data structure */
4634 SCIP_VAR** vars, /**< variables to get strong branching values for */
4635 int nvars, /**< number of variables */
4636 int itlim, /**< iteration limit for strong branchings */
4637 SCIP_Real* down, /**< stores dual bounds after branching variables down */
4638 SCIP_Real* up, /**< stores dual bounds after branching variables up */
4639 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
4640 * otherwise, they can only be used as an estimate value */
4641 SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
4642 * otherwise, they can only be used as an estimate value */
4643 SCIP_Bool* downinf, /**< array to store whether the downward branches are infeasible, or NULL */
4644 SCIP_Bool* upinf, /**< array to store whether the upward branches are infeasible, or NULL */
4645 SCIP_Bool* downconflict, /**< array to store whether conflict constraints were created for
4646 * infeasible downward branches, or NULL */
4647 SCIP_Bool* upconflict, /**< array to store whether conflict constraints were created for
4648 * infeasible upward branches, or NULL */
4649 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
4650 * solving process should be stopped (e.g., due to a time limit) */
4651 )
4652{
4653 SCIP_COL** cols;
4654 int j;
4655
4656 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarsStrongbranchesFrac", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4657
4658 assert( lperror != NULL );
4659 assert( vars != NULL );
4660
4661 /* set up data */
4662 cols = NULL;
4663 SCIP_CALL( SCIPallocBufferArray(scip, &cols, nvars) );
4664 assert(cols != NULL);
4665 for( j = 0; j < nvars; ++j )
4666 {
4667 SCIP_VAR* var;
4668 SCIP_COL* col;
4669
4670 if( downvalid != NULL )
4671 downvalid[j] = FALSE;
4672 if( upvalid != NULL )
4673 upvalid[j] = FALSE;
4674 if( downinf != NULL )
4675 downinf[j] = FALSE;
4676 if( upinf != NULL )
4677 upinf[j] = FALSE;
4678 if( downconflict != NULL )
4679 downconflict[j] = FALSE;
4680 if( upconflict != NULL )
4681 upconflict[j] = FALSE;
4682
4683 var = vars[j];
4684 assert( var != NULL );
4686 {
4687 SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
4688 SCIPfreeBufferArray(scip, &cols);
4689 return SCIP_INVALIDDATA;
4690 }
4691
4692 col = SCIPvarGetCol(var);
4693 assert(col != NULL);
4694 cols[j] = col;
4695
4696 if( !SCIPcolIsInLP(col) )
4697 {
4698 SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
4699 SCIPfreeBufferArray(scip, &cols);
4700 return SCIP_INVALIDDATA;
4701 }
4702 }
4703
4704 /* check if the solving process should be aborted */
4705 if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
4706 {
4707 /* mark this as if the LP failed */
4708 *lperror = TRUE;
4709 }
4710 else
4711 {
4712 /* call strong branching for columns with fractional value */
4713 SCIP_CALL( SCIPcolGetStrongbranches(cols, nvars, FALSE, scip->set, scip->stat, scip->transprob, scip->lp, itlim,
4714 down, up, downvalid, upvalid, lperror) );
4715
4716 /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
4717 * declare the sub nodes infeasible
4718 */
4719 if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) )
4720 {
4721 for( j = 0; j < nvars; ++j )
4722 {
4723 SCIP_CALL( analyzeStrongbranch(scip, vars[j], (downinf != NULL) ? (&(downinf[j])) : NULL,
4724 (upinf != NULL) ? (&(upinf[j])) : NULL, (downconflict != NULL) ? (&(downconflict[j])) : NULL,
4725 (upconflict != NULL) ? (&(upconflict[j])) : NULL) );
4726 }
4727 }
4728 }
4729 SCIPfreeBufferArray(scip, &cols);
4730
4731 return SCIP_OKAY;
4732}
4733
4734/** gets strong branching information on column variables with integral values
4735 *
4736 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4737 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4738 *
4739 * @pre This method can be called if @p scip is in one of the following stages:
4740 * - \ref SCIP_STAGE_PRESOLVED
4741 * - \ref SCIP_STAGE_SOLVING
4742 */
4744 SCIP* scip, /**< SCIP data structure */
4745 SCIP_VAR** vars, /**< variables to get strong branching values for */
4746 int nvars, /**< number of variables */
4747 int itlim, /**< iteration limit for strong branchings */
4748 SCIP_Real* down, /**< stores dual bounds after branching variables down */
4749 SCIP_Real* up, /**< stores dual bounds after branching variables up */
4750 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
4751 * otherwise, they can only be used as an estimate value */
4752 SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
4753 * otherwise, they can only be used as an estimate value */
4754 SCIP_Bool* downinf, /**< array to store whether the downward branches are infeasible, or NULL */
4755 SCIP_Bool* upinf, /**< array to store whether the upward branches are infeasible, or NULL */
4756 SCIP_Bool* downconflict, /**< array to store whether conflict constraints were created for
4757 * infeasible downward branches, or NULL */
4758 SCIP_Bool* upconflict, /**< array to store whether conflict constraints were created for
4759 * infeasible upward branches, or NULL */
4760 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
4761 * solving process should be stopped (e.g., due to a time limit) */
4762 )
4763{
4764 SCIP_COL** cols;
4765 int j;
4766
4767 assert(lperror != NULL);
4768
4769 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarsStrongbranchesInt", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4770
4771 assert( vars != NULL );
4772
4773 /* set up data */
4774 cols = NULL;
4775 SCIP_CALL( SCIPallocBufferArray(scip, &cols, nvars) );
4776 assert(cols != NULL);
4777 for( j = 0; j < nvars; ++j )
4778 {
4779 SCIP_VAR* var;
4780 SCIP_COL* col;
4781
4782 if( downvalid != NULL )
4783 downvalid[j] = FALSE;
4784 if( upvalid != NULL )
4785 upvalid[j] = FALSE;
4786 if( downinf != NULL )
4787 downinf[j] = FALSE;
4788 if( upinf != NULL )
4789 upinf[j] = FALSE;
4790 if( downconflict != NULL )
4791 downconflict[j] = FALSE;
4792 if( upconflict != NULL )
4793 upconflict[j] = FALSE;
4794
4795 var = vars[j];
4796 assert( var != NULL );
4798 {
4799 SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
4800 SCIPfreeBufferArray(scip, &cols);
4801 return SCIP_INVALIDDATA;
4802 }
4803
4804 col = SCIPvarGetCol(var);
4805 assert(col != NULL);
4806 cols[j] = col;
4807
4808 if( !SCIPcolIsInLP(col) )
4809 {
4810 SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
4811 SCIPfreeBufferArray(scip, &cols);
4812 return SCIP_INVALIDDATA;
4813 }
4814 }
4815
4816 /* check if the solving process should be aborted */
4817 if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
4818 {
4819 /* mark this as if the LP failed */
4820 *lperror = TRUE;
4821 }
4822 else
4823 {
4824 /* call strong branching for columns */
4825 SCIP_CALL( SCIPcolGetStrongbranches(cols, nvars, TRUE, scip->set, scip->stat, scip->transprob, scip->lp, itlim,
4826 down, up, downvalid, upvalid, lperror) );
4827
4828 /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
4829 * declare the sub nodes infeasible
4830 */
4831 if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) )
4832 {
4833 for( j = 0; j < nvars; ++j )
4834 {
4835 SCIP_CALL( analyzeStrongbranch(scip, vars[j], (downinf != NULL) ? (&(downinf[j])) : NULL,
4836 (upinf != NULL) ? (&(upinf[j])) : NULL, (downconflict != NULL) ? (&(downconflict[j])) : NULL,
4837 (upconflict != NULL) ? (&(upconflict[j])) : NULL) );
4838 }
4839 }
4840 }
4841 SCIPfreeBufferArray(scip, &cols);
4842
4843 return SCIP_OKAY;
4844}
4845
4846/** get LP solution status of last strong branching call (currently only works for strong branching with propagation) */
4848 SCIP* scip, /**< SCIP data structure */
4849 SCIP_BRANCHDIR branchdir /**< branching direction for which LP solution status is requested */
4850 )
4851{
4852 assert(NULL != scip);
4853 assert(branchdir == SCIP_BRANCHDIR_DOWNWARDS || branchdir == SCIP_BRANCHDIR_UPWARDS);
4854
4855 return scip->stat->lastsblpsolstats[branchdir == SCIP_BRANCHDIR_DOWNWARDS ? 0 : 1];
4856}
4857
4858/** gets strong branching information on COLUMN variable of the last SCIPgetVarStrongbranch() call;
4859 * returns values of SCIP_INVALID, if strong branching was not yet called on the given variable;
4860 * keep in mind, that the returned old values may have nothing to do with the current LP solution
4861 *
4862 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4863 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4864 *
4865 * @pre This method can be called if @p scip is in one of the following stages:
4866 * - \ref SCIP_STAGE_SOLVING
4867 * - \ref SCIP_STAGE_SOLVED
4868 */
4870 SCIP* scip, /**< SCIP data structure */
4871 SCIP_VAR* var, /**< variable to get last strong branching values for */
4872 SCIP_Real* down, /**< stores dual bound after branching column down */
4873 SCIP_Real* up, /**< stores dual bound after branching column up */
4874 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4875 * otherwise, it can only be used as an estimate value */
4876 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4877 * otherwise, it can only be used as an estimate value */
4878 SCIP_Real* solval, /**< stores LP solution value of variable at the last strong branching call, or NULL */
4879 SCIP_Real* lpobjval /**< stores LP objective value at last strong branching call, or NULL */
4880 )
4881{
4882 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchLast", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
4883
4885 {
4886 SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable\n");
4887 return SCIP_INVALIDDATA;
4888 }
4889
4890 SCIPcolGetStrongbranchLast(SCIPvarGetCol(var), down, up, downvalid, upvalid, solval, lpobjval);
4891
4892 return SCIP_OKAY;
4893}
4894
4895/** sets strong branching information for a column variable
4896 *
4897 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4898 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4899 *
4900 * @pre This method can be called if @p scip is in one of the following stages:
4901 * - \ref SCIP_STAGE_SOLVING
4902 */
4904 SCIP* scip, /**< SCIP data structure */
4905 SCIP_VAR* var, /**< variable to set last strong branching values for */
4906 SCIP_Real lpobjval, /**< objective value of the current LP */
4907 SCIP_Real primsol, /**< primal solution value of the column in the current LP */
4908 SCIP_Real down, /**< dual bound after branching column down */
4909 SCIP_Real up, /**< dual bound after branching column up */
4910 SCIP_Bool downvalid, /**< is the returned down value a valid dual bound? */
4911 SCIP_Bool upvalid, /**< is the returned up value a valid dual bound? */
4912 SCIP_Longint iter, /**< total number of strong branching iterations */
4913 int itlim /**< iteration limit applied to the strong branching call */
4914 )
4915{
4916 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetVarStrongbranchData", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4917
4919 {
4920 SCIPerrorMessage("cannot set strong branching information on non-COLUMN variable\n");
4921 return SCIP_INVALIDDATA;
4922 }
4923
4924 SCIPcolSetStrongbranchData(SCIPvarGetCol(var), scip->set, scip->stat, scip->lp, lpobjval, primsol,
4925 down, up, downvalid, upvalid, iter, itlim);
4926
4927 return SCIP_OKAY;
4928}
4929
4930/** rounds the current solution and tries it afterwards; if feasible, adds it to storage
4931 *
4932 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4933 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4934 *
4935 * @pre This method can be called if @p scip is in one of the following stages:
4936 * - \ref SCIP_STAGE_SOLVING
4937 */
4939 SCIP* scip, /**< SCIP data structure */
4940 SCIP_Bool* foundsol, /**< stores whether solution was feasible and good enough to keep */
4941 SCIP_Bool* cutoff /**< stores whether solution was cutoff due to exceeding the cutoffbound */
4942 )
4943{
4944 assert(scip != NULL);
4945 assert(foundsol != NULL);
4946 assert(cutoff != NULL);
4947
4948 SCIP_CALL( SCIPcheckStage(scip, "SCIPtryStrongbranchLPSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4949
4950 if( scip->set->branch_checksbsol )
4951 {
4952 SCIP_SOL* sol;
4953 SCIP_Bool rounded = TRUE;
4955 SCIP_Longint oldnbestsolsfound = scip->primal->nbestsolsfound;
4956
4957 /* start clock for strong branching solutions */
4958 SCIPclockStart(scip->stat->sbsoltime, scip->set);
4959
4962
4963 /* try to round the strong branching solution */
4964 if( scip->set->branch_roundsbsol )
4965 {
4966 SCIP_CALL( SCIProundSol(scip, sol, &rounded) );
4967 }
4968
4969 /* check the solution for feasibility if rounding worked well (or was not tried) */
4970 if( rounded )
4971 {
4972 SCIP_CALL( SCIPtrySolFree(scip, &sol, FALSE, FALSE, FALSE, TRUE, FALSE, foundsol) );
4973 }
4974 else
4975 {
4976 SCIP_CALL( SCIPfreeSol(scip, &sol) );
4977 }
4978
4979 if( *foundsol )
4980 {
4981 SCIPdebugMsg(scip, "found new solution in strong branching\n");
4982
4983 scip->stat->nsbsolsfound++;
4984
4985 if( scip->primal->nbestsolsfound != oldnbestsolsfound )
4986 {
4987 scip->stat->nsbbestsolsfound++;
4988 }
4989
4990 if( SCIPisGE(scip, value, SCIPgetCutoffbound(scip)) )
4991 *cutoff = TRUE;
4992 }
4993
4994 /* stop clock for strong branching solutions */
4995 SCIPclockStop(scip->stat->sbsoltime, scip->set);
4996 }
4997 return SCIP_OKAY;
4998}
4999
5000
5001/** gets node number of the last node in current branch and bound run, where strong branching was used on the
5002 * given variable, or -1 if strong branching was never applied to the variable in current run
5003 *
5004 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5005 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5006 *
5007 * @pre This method can be called if @p scip is in one of the following stages:
5008 * - \ref SCIP_STAGE_TRANSFORMING
5009 * - \ref SCIP_STAGE_TRANSFORMED
5010 * - \ref SCIP_STAGE_INITPRESOLVE
5011 * - \ref SCIP_STAGE_PRESOLVING
5012 * - \ref SCIP_STAGE_EXITPRESOLVE
5013 * - \ref SCIP_STAGE_PRESOLVED
5014 * - \ref SCIP_STAGE_INITSOLVE
5015 * - \ref SCIP_STAGE_SOLVING
5016 * - \ref SCIP_STAGE_SOLVED
5017 * - \ref SCIP_STAGE_EXITSOLVE
5018 */
5020 SCIP* scip, /**< SCIP data structure */
5021 SCIP_VAR* var /**< variable to get last strong branching node for */
5022 )
5023{
5024 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarStrongbranchNode", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
5025
5026 assert( var->scip == scip );
5027
5029 return -1;
5030
5032}
5033
5034/** if strong branching was already applied on the variable at the current node, returns the number of LPs solved after
5035 * the LP where the strong branching on this variable was applied;
5036 * if strong branching was not yet applied on the variable at the current node, returns INT_MAX
5037 *
5038 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5039 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5040 *
5041 * @pre This method can be called if @p scip is in one of the following stages:
5042 * - \ref SCIP_STAGE_TRANSFORMING
5043 * - \ref SCIP_STAGE_TRANSFORMED
5044 * - \ref SCIP_STAGE_INITPRESOLVE
5045 * - \ref SCIP_STAGE_PRESOLVING
5046 * - \ref SCIP_STAGE_EXITPRESOLVE
5047 * - \ref SCIP_STAGE_PRESOLVED
5048 * - \ref SCIP_STAGE_INITSOLVE
5049 * - \ref SCIP_STAGE_SOLVING
5050 * - \ref SCIP_STAGE_SOLVED
5051 * - \ref SCIP_STAGE_EXITSOLVE
5052 */
5054 SCIP* scip, /**< SCIP data structure */
5055 SCIP_VAR* var /**< variable to get strong branching LP age for */
5056 )
5057{
5058 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarStrongbranchLPAge", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
5059
5060 assert( var->scip == scip );
5061
5063 return SCIP_LONGINT_MAX;
5064
5066}
5067
5068/** gets number of times, strong branching was applied in current run on the given variable
5069 *
5070 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5071 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5072 *
5073 * @pre This method can be called if @p scip is in one of the following stages:
5074 * - \ref SCIP_STAGE_TRANSFORMING
5075 * - \ref SCIP_STAGE_TRANSFORMED
5076 * - \ref SCIP_STAGE_INITPRESOLVE
5077 * - \ref SCIP_STAGE_PRESOLVING
5078 * - \ref SCIP_STAGE_EXITPRESOLVE
5079 * - \ref SCIP_STAGE_PRESOLVED
5080 * - \ref SCIP_STAGE_INITSOLVE
5081 * - \ref SCIP_STAGE_SOLVING
5082 * - \ref SCIP_STAGE_SOLVED
5083 * - \ref SCIP_STAGE_EXITSOLVE
5084 */
5086 SCIP* scip, /**< SCIP data structure */
5087 SCIP_VAR* var /**< variable to get last strong branching node for */
5088 )
5089{
5090 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarNStrongbranchs", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
5091
5092 assert( var->scip == scip );
5093
5095 return 0;
5096
5098}
5099
5100/** adds given values to lock numbers of type @p locktype of variable for rounding
5101 *
5102 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5103 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5104 *
5105 * @pre This method can be called if @p scip is in one of the following stages:
5106 * - \ref SCIP_STAGE_PROBLEM
5107 * - \ref SCIP_STAGE_TRANSFORMING
5108 * - \ref SCIP_STAGE_TRANSFORMED
5109 * - \ref SCIP_STAGE_INITPRESOLVE
5110 * - \ref SCIP_STAGE_PRESOLVING
5111 * - \ref SCIP_STAGE_EXITPRESOLVE
5112 * - \ref SCIP_STAGE_PRESOLVED
5113 * - \ref SCIP_STAGE_INITSOLVE
5114 * - \ref SCIP_STAGE_SOLVING
5115 * - \ref SCIP_STAGE_EXITSOLVE
5116 * - \ref SCIP_STAGE_FREETRANS
5117 */
5119 SCIP* scip, /**< SCIP data structure */
5120 SCIP_VAR* var, /**< problem variable */
5121 SCIP_LOCKTYPE locktype, /**< type of the variable locks */
5122 int nlocksdown, /**< modification in number of rounding down locks */
5123 int nlocksup /**< modification in number of rounding up locks */
5124 )
5125{
5126 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarLocksType", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
5127
5128 assert( var->scip == scip );
5129
5130 switch( scip->set->stage )
5131 {
5132 case SCIP_STAGE_PROBLEM:
5133 assert(!SCIPvarIsTransformed(var));
5134 /*lint -fallthrough*/
5142 case SCIP_STAGE_SOLVING:
5145 SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, locktype, nlocksdown, nlocksup) );
5146 return SCIP_OKAY;
5147
5148 default:
5149 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5150 return SCIP_INVALIDCALL;
5151 } /*lint !e788*/
5152}
5153
5154/** adds given values to lock numbers of variable for rounding
5155 *
5156 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5157 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5158 *
5159 * @pre This method can be called if @p scip is in one of the following stages:
5160 * - \ref SCIP_STAGE_PROBLEM
5161 * - \ref SCIP_STAGE_TRANSFORMING
5162 * - \ref SCIP_STAGE_TRANSFORMED
5163 * - \ref SCIP_STAGE_INITPRESOLVE
5164 * - \ref SCIP_STAGE_PRESOLVING
5165 * - \ref SCIP_STAGE_EXITPRESOLVE
5166 * - \ref SCIP_STAGE_PRESOLVED
5167 * - \ref SCIP_STAGE_INITSOLVE
5168 * - \ref SCIP_STAGE_SOLVING
5169 * - \ref SCIP_STAGE_EXITSOLVE
5170 * - \ref SCIP_STAGE_FREETRANS
5171 *
5172 * @note This method will always add variable locks of type model
5173 *
5174 * @note It is recommented to use SCIPaddVarLocksType()
5175 */
5177 SCIP* scip, /**< SCIP data structure */
5178 SCIP_VAR* var, /**< problem variable */
5179 int nlocksdown, /**< modification in number of rounding down locks */
5180 int nlocksup /**< modification in number of rounding up locks */
5181 )
5182{
5183 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarLocks", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
5184
5185 SCIP_CALL( SCIPaddVarLocksType(scip, var, SCIP_LOCKTYPE_MODEL, nlocksdown, nlocksup) );
5186
5187 return SCIP_OKAY;
5188}
5189
5190/** add locks of variable with respect to the lock status of the constraint and its negation;
5191 * this method should be called whenever the lock status of a variable in a constraint changes, for example if
5192 * the coefficient of the variable changed its sign or if the left or right hand sides of the constraint were
5193 * added or removed
5194 *
5195 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5196 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5197 *
5198 * @pre This method can be called if @p scip is in one of the following stages:
5199 * - \ref SCIP_STAGE_PROBLEM
5200 * - \ref SCIP_STAGE_TRANSFORMING
5201 * - \ref SCIP_STAGE_TRANSFORMED
5202 * - \ref SCIP_STAGE_INITPRESOLVE
5203 * - \ref SCIP_STAGE_PRESOLVING
5204 * - \ref SCIP_STAGE_EXITPRESOLVE
5205 * - \ref SCIP_STAGE_INITSOLVE
5206 * - \ref SCIP_STAGE_SOLVING
5207 * - \ref SCIP_STAGE_EXITSOLVE
5208 * - \ref SCIP_STAGE_FREETRANS
5209 */
5211 SCIP* scip, /**< SCIP data structure */
5212 SCIP_VAR* var, /**< problem variable */
5213 SCIP_CONS* cons, /**< constraint */
5214 SCIP_Bool lockdown, /**< should the rounding be locked in downwards direction? */
5215 SCIP_Bool lockup /**< should the rounding be locked in upwards direction? */
5216 )
5217{
5218 int nlocksdown[NLOCKTYPES];
5219 int nlocksup[NLOCKTYPES];
5220 int i;
5221
5222 SCIP_CALL( SCIPcheckStage(scip, "SCIPlockVarCons", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
5223
5224 assert( var->scip == scip );
5225
5226 for( i = 0; i < NLOCKTYPES; i++ )
5227 {
5228 nlocksdown[i] = 0;
5229 nlocksup[i] = 0;
5230
5231 if( SCIPconsIsLockedTypePos(cons, (SCIP_LOCKTYPE) i) )
5232 {
5233 if( lockdown )
5234 ++nlocksdown[i];
5235 if( lockup )
5236 ++nlocksup[i];
5237 }
5238 if( SCIPconsIsLockedTypeNeg(cons, (SCIP_LOCKTYPE) i) )
5239 {
5240 if( lockdown )
5241 ++nlocksup[i];
5242 if( lockup )
5243 ++nlocksdown[i];
5244 }
5245 }
5246
5247 switch( scip->set->stage )
5248 {
5249 case SCIP_STAGE_PROBLEM:
5250 assert(!SCIPvarIsTransformed(var));
5251 /*lint -fallthrough*/
5258 case SCIP_STAGE_SOLVING:
5261 for( i = 0; i < NLOCKTYPES; i++ )
5262 {
5263 if( nlocksdown[i] == 0 && nlocksup[i] == 0 )
5264 continue;
5265
5266 SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, (SCIP_LOCKTYPE) i, nlocksdown[i], nlocksup[i]) );
5267 }
5268 return SCIP_OKAY;
5269
5270 default:
5271 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5272 return SCIP_INVALIDCALL;
5273 } /*lint !e788*/
5274}
5275
5276/** remove locks of type @p locktype of variable with respect to the lock status of the constraint and its negation;
5277 * this method should be called whenever the lock status of a variable in a constraint changes, for example if
5278 * the coefficient of the variable changed its sign or if the left or right hand sides of the constraint were
5279 * added or removed
5280 *
5281 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5282 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5283 *
5284 * @pre This method can be called if @p scip is in one of the following stages:
5285 * - \ref SCIP_STAGE_PROBLEM
5286 * - \ref SCIP_STAGE_TRANSFORMING
5287 * - \ref SCIP_STAGE_TRANSFORMED
5288 * - \ref SCIP_STAGE_INITPRESOLVE
5289 * - \ref SCIP_STAGE_PRESOLVING
5290 * - \ref SCIP_STAGE_EXITPRESOLVE
5291 * - \ref SCIP_STAGE_INITSOLVE
5292 * - \ref SCIP_STAGE_SOLVING
5293 * - \ref SCIP_STAGE_EXITSOLVE
5294 * - \ref SCIP_STAGE_FREETRANS
5295 */
5297 SCIP* scip, /**< SCIP data structure */
5298 SCIP_VAR* var, /**< problem variable */
5299 SCIP_CONS* cons, /**< constraint */
5300 SCIP_Bool lockdown, /**< should the rounding be unlocked in downwards direction? */
5301 SCIP_Bool lockup /**< should the rounding be unlocked in upwards direction? */
5302 )
5303{
5304 int nlocksdown[NLOCKTYPES];
5305 int nlocksup[NLOCKTYPES];
5306 int i;
5307
5308 SCIP_CALL( SCIPcheckStage(scip, "SCIPunlockVarCons", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
5309
5310 assert( var->scip == scip );
5311
5312 for( i = 0; i < NLOCKTYPES; i++ )
5313 {
5314 nlocksdown[i] = 0;
5315 nlocksup[i] = 0;
5316
5317 if( SCIPconsIsLockedTypePos(cons, (SCIP_LOCKTYPE) i) )
5318 {
5319 if( lockdown )
5320 ++nlocksdown[i];
5321 if( lockup )
5322 ++nlocksup[i];
5323 }
5324 if( SCIPconsIsLockedTypeNeg(cons, (SCIP_LOCKTYPE) i) )
5325 {
5326 if( lockdown )
5327 ++nlocksup[i];
5328 if( lockup )
5329 ++nlocksdown[i];
5330 }
5331 }
5332 switch( scip->set->stage )
5333 {
5334 case SCIP_STAGE_PROBLEM:
5335 assert(!SCIPvarIsTransformed(var));
5336 /*lint -fallthrough*/
5343 case SCIP_STAGE_SOLVING:
5346 for( i = 0; i < NLOCKTYPES; i++ )
5347 {
5348 if( nlocksdown[i] == 0 && nlocksup[i] == 0 )
5349 continue;
5350
5351 SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, (SCIP_LOCKTYPE) i, -nlocksdown[i], -nlocksup[i]) );
5352 }
5353 return SCIP_OKAY;
5354
5355 default:
5356 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5357 return SCIP_INVALIDCALL;
5358 } /*lint !e788*/
5359}
5360
5361/** changes variable's objective value
5362 *
5363 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5364 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5365 *
5366 * @pre This method can be called if @p scip is in one of the following stages:
5367 * - \ref SCIP_STAGE_PROBLEM
5368 * - \ref SCIP_STAGE_TRANSFORMING
5369 * - \ref SCIP_STAGE_PRESOLVING
5370 * - \ref SCIP_STAGE_PRESOLVED
5371 */
5373 SCIP* scip, /**< SCIP data structure */
5374 SCIP_VAR* var, /**< variable to change the objective value for */
5375 SCIP_Real newobj /**< new objective value */
5376 )
5377{
5379
5380 assert( var->scip == scip );
5381
5382 /* forbid infinite objective values */
5383 if( SCIPisInfinity(scip, REALABS(newobj)) )
5384 {
5385 SCIPerrorMessage("invalid objective value: objective value is infinite\n");
5386 return SCIP_INVALIDDATA;
5387 }
5388
5389 switch( scip->set->stage )
5390 {
5391 case SCIP_STAGE_PROBLEM:
5392 assert(!SCIPvarIsTransformed(var));
5393 SCIP_CALL( SCIPvarChgObj(var, scip->mem->probmem, scip->set, scip->origprob, scip->primal, scip->lp, scip->eventqueue, newobj) );
5394 return SCIP_OKAY;
5395
5400 SCIP_CALL( SCIPvarChgObj(var, scip->mem->probmem, scip->set, scip->transprob, scip->primal, scip->lp, scip->eventqueue, newobj) );
5401 return SCIP_OKAY;
5402
5403 default:
5404 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5405 return SCIP_INVALIDCALL;
5406 } /*lint !e788*/
5407}
5408
5409/** changes variable's exact objective value
5410 *
5411 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5412 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5413 *
5414 * @pre This method can be called if @p scip is in one of the following stages:
5415 * - \ref SCIP_STAGE_PROBLEM
5416 * - \ref SCIP_STAGE_TRANSFORMING
5417 * - \ref SCIP_STAGE_PRESOLVING
5418 * - \ref SCIP_STAGE_PRESOLVED
5419 */
5421 SCIP* scip, /**< SCIP data structure */
5422 SCIP_VAR* var, /**< variable to change the objective value for */
5423 SCIP_RATIONAL* newobj /**< new objective value */
5424 )
5425{
5426 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarObjExact", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
5427
5428 assert( var->scip == scip );
5429
5430 /* forbid infinite objective values */
5431 if( SCIPrationalIsAbsInfinity(newobj) )
5432 {
5433 SCIPerrorMessage("invalid objective value: objective value is infinite\n");
5434 return SCIP_INVALIDDATA;
5435 }
5436
5437 switch( scip->set->stage )
5438 {
5439 case SCIP_STAGE_PROBLEM:
5440 assert(!SCIPvarIsTransformed(var));
5441 SCIP_CALL( SCIPvarChgObjExact(var, scip->mem->probmem, scip->set, scip->origprob, scip->primal, scip->lpexact, scip->eventqueue, newobj) );
5442 return SCIP_OKAY;
5443
5448 SCIP_CALL( SCIPvarChgObjExact(var, scip->mem->probmem, scip->set, scip->transprob, scip->primal, scip->lpexact, scip->eventqueue, newobj) );
5449 return SCIP_OKAY;
5450
5451 default:
5452 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5453 return SCIP_INVALIDCALL;
5454 } /*lint !e788*/
5455}
5456
5457/** changes exact global upper bound of variable;
5458 *
5459 *
5460 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5461 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5462 *
5463 * @pre This method can be called if @p scip is in one of the following stages:
5464 * - \ref SCIP_STAGE_PROBLEM
5465 *
5466 */
5468 SCIP* scip, /**< SCIP data structure */
5469 SCIP_VAR* var, /**< variable to change the bound for */
5470 SCIP_RATIONAL* newbound /**< new value for bound */
5471 )
5472{
5473 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbGlobalExact", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
5474
5475 assert(!SCIPvarIsTransformed(var));
5476 SCIP_CALL( SCIPvarChgUbGlobalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
5477 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5478
5479 return SCIP_OKAY;
5480}
5481
5482/** changes exact global lower bound of variable;
5483 *
5484 *
5485 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5486 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5487 *
5488 * @pre This method can be called if @p scip is in one of the following stages:
5489 * - \ref SCIP_STAGE_PROBLEM
5490 *
5491 */
5493 SCIP* scip, /**< SCIP data structure */
5494 SCIP_VAR* var, /**< variable to change the bound for */
5495 SCIP_RATIONAL* newbound /**< new value for bound */
5496 )
5497{
5498 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbGlobalExact", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
5499
5500 assert(!SCIPvarIsTransformed(var));
5501 SCIP_CALL( SCIPvarChgLbGlobalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
5502 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5503
5504 return SCIP_OKAY;
5505}
5506
5507/** adds value to variable's objective value
5508 *
5509 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5510 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5511 *
5512 * @pre This method can be called if @p scip is in one of the following stages:
5513 * - \ref SCIP_STAGE_PROBLEM
5514 * - \ref SCIP_STAGE_TRANSFORMING
5515 * - \ref SCIP_STAGE_PRESOLVING
5516 * - \ref SCIP_STAGE_EXITPRESOLVE
5517 * - \ref SCIP_STAGE_PRESOLVED
5518 */
5520 SCIP* scip, /**< SCIP data structure */
5521 SCIP_VAR* var, /**< variable to change the objective value for */
5522 SCIP_Real addobj /**< additional objective value */
5523 )
5524{
5526
5527 assert( var->scip == scip );
5528
5529 switch( scip->set->stage )
5530 {
5531 case SCIP_STAGE_PROBLEM:
5532 assert(!SCIPvarIsTransformed(var));
5533 SCIP_CALL( SCIPvarAddObj(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->primal,
5534 scip->tree, scip->reopt, scip->lp, scip->eventqueue, scip->eventfilter, addobj) );
5535 return SCIP_OKAY;
5536
5541 SCIP_CALL( SCIPvarAddObj(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->primal,
5542 scip->tree, scip->reopt, scip->lp, scip->eventqueue, scip->eventfilter, addobj) );
5543 return SCIP_OKAY;
5544
5545 default:
5546 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5547 return SCIP_INVALIDCALL;
5548 } /*lint !e788*/
5549}
5550
5551/** returns the adjusted (i.e. rounded, if the given variable is of integral type) lower bound value;
5552 * does not change the bounds of the variable
5553 *
5554 * @return adjusted lower bound for the given variable; the bound of the variable is not changed
5555 *
5556 * @pre This method can be called if @p scip is in one of the following stages:
5557 * - \ref SCIP_STAGE_PROBLEM
5558 * - \ref SCIP_STAGE_TRANSFORMING
5559 * - \ref SCIP_STAGE_TRANSFORMED
5560 * - \ref SCIP_STAGE_INITPRESOLVE
5561 * - \ref SCIP_STAGE_PRESOLVING
5562 * - \ref SCIP_STAGE_EXITPRESOLVE
5563 * - \ref SCIP_STAGE_PRESOLVED
5564 * - \ref SCIP_STAGE_INITSOLVE
5565 * - \ref SCIP_STAGE_SOLVING
5566 * - \ref SCIP_STAGE_SOLVED
5567 * - \ref SCIP_STAGE_EXITSOLVE
5568 * - \ref SCIP_STAGE_FREETRANS
5569 */
5571 SCIP* scip, /**< SCIP data structure */
5572 SCIP_VAR* var, /**< variable to adjust the bound for */
5573 SCIP_Real lb /**< lower bound value to adjust */
5574 )
5575{
5576 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPadjustedVarLb", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
5577
5578 SCIPvarAdjustLb(var, scip->set, &lb);
5579
5580 return lb;
5581}
5582
5583/** returns the adjusted (i.e. rounded, if the given variable is of integral type) lower bound value;
5584 * does not change the bounds of the variable
5585 *
5586 * @return adjusted lower bound for the given variable; the bound of the variable is not changed
5587 *
5588 * @pre This method can be called if @p scip is in one of the following stages:
5589 * - \ref SCIP_STAGE_PROBLEM
5590 * - \ref SCIP_STAGE_TRANSFORMING
5591 * - \ref SCIP_STAGE_TRANSFORMED
5592 * - \ref SCIP_STAGE_INITPRESOLVE
5593 * - \ref SCIP_STAGE_PRESOLVING
5594 * - \ref SCIP_STAGE_EXITPRESOLVE
5595 * - \ref SCIP_STAGE_PRESOLVED
5596 * - \ref SCIP_STAGE_INITSOLVE
5597 * - \ref SCIP_STAGE_SOLVING
5598 * - \ref SCIP_STAGE_SOLVED
5599 * - \ref SCIP_STAGE_EXITSOLVE
5600 * - \ref SCIP_STAGE_FREETRANS
5601 */
5603 SCIP* scip, /**< SCIP data structure */
5604 SCIP_VAR* var, /**< variable to adjust the bound for */
5605 SCIP_Real lb /**< lower bound value to adjust */
5606 )
5607{
5608 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPadjustedVarLbExactFloat", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
5609
5610 SCIPvarAdjustLbExactFloat(var, scip->set, &lb);
5611
5612 return lb;
5613}
5614
5615/** returns the adjusted (i.e. rounded, if the given variable is of integral type) upper bound value;
5616 * does not change the bounds of the variable
5617 *
5618 * @return adjusted upper bound for the given variable; the bound of the variable is not changed
5619 *
5620 * @pre This method can be called if @p scip is in one of the following stages:
5621 * - \ref SCIP_STAGE_PROBLEM
5622 * - \ref SCIP_STAGE_TRANSFORMING
5623 * - \ref SCIP_STAGE_TRANSFORMED
5624 * - \ref SCIP_STAGE_INITPRESOLVE
5625 * - \ref SCIP_STAGE_PRESOLVING
5626 * - \ref SCIP_STAGE_EXITPRESOLVE
5627 * - \ref SCIP_STAGE_PRESOLVED
5628 * - \ref SCIP_STAGE_INITSOLVE
5629 * - \ref SCIP_STAGE_SOLVING
5630 * - \ref SCIP_STAGE_SOLVED
5631 * - \ref SCIP_STAGE_EXITSOLVE
5632 * - \ref SCIP_STAGE_FREETRANS
5633 */
5635 SCIP* scip, /**< SCIP data structure */
5636 SCIP_VAR* var, /**< variable to adjust the bound for */
5637 SCIP_Real ub /**< upper bound value to adjust */
5638 )
5639{
5640 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPadjustedVarUb", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
5641
5642 SCIPvarAdjustUb(var, scip->set, &ub);
5643
5644 return ub;
5645}
5646
5647/** returns the adjusted (i.e. rounded, if the given variable is of integral type) upper bound value;
5648 * does not change the bounds of the variable
5649 *
5650 * @return adjusted upper bound for the given variable; the bound of the variable is not changed
5651 *
5652 * @pre This method can be called if @p scip is in one of the following stages:
5653 * - \ref SCIP_STAGE_PROBLEM
5654 * - \ref SCIP_STAGE_TRANSFORMING
5655 * - \ref SCIP_STAGE_TRANSFORMED
5656 * - \ref SCIP_STAGE_INITPRESOLVE
5657 * - \ref SCIP_STAGE_PRESOLVING
5658 * - \ref SCIP_STAGE_EXITPRESOLVE
5659 * - \ref SCIP_STAGE_PRESOLVED
5660 * - \ref SCIP_STAGE_INITSOLVE
5661 * - \ref SCIP_STAGE_SOLVING
5662 * - \ref SCIP_STAGE_SOLVED
5663 * - \ref SCIP_STAGE_EXITSOLVE
5664 * - \ref SCIP_STAGE_FREETRANS
5665 */
5667 SCIP* scip, /**< SCIP data structure */
5668 SCIP_VAR* var, /**< variable to adjust the bound for */
5669 SCIP_Real ub /**< upper bound value to adjust */
5670 )
5671{
5672 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPadjustedVarUbExactFloat", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
5673
5674 SCIPvarAdjustUbExactFloat(var, scip->set, &ub);
5675
5676 return ub;
5677}
5678
5679/** depending on SCIP's stage, changes lower bound of variable in the problem, in preprocessing, or in current node;
5680 * if possible, adjusts bound to integral value; doesn't store any inference information in the bound change, such
5681 * that in conflict analysis, this change is treated like a branching decision
5682 *
5683 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5684 * SCIPgetVars()) gets re-sorted.
5685 *
5686 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5687 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5688 *
5689 * @pre This method can be called if @p scip is in one of the following stages:
5690 * - \ref SCIP_STAGE_PROBLEM
5691 * - \ref SCIP_STAGE_TRANSFORMING
5692 * - \ref SCIP_STAGE_PRESOLVING
5693 * - \ref SCIP_STAGE_SOLVING
5694 *
5695 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5696 */
5698 SCIP* scip, /**< SCIP data structure */
5699 SCIP_VAR* var, /**< variable to change the bound for */
5700 SCIP_Real newbound /**< new value for bound */
5701 )
5702{
5704
5705 SCIPvarAdjustLb(var, scip->set, &newbound);
5706
5707 /* ignore tightenings of lower bounds to +infinity during solving process */
5709 {
5710#ifndef NDEBUG
5711 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
5712 SCIPvarGetLbLocal(var));
5713#endif
5714 return SCIP_OKAY;
5715 }
5716
5717 switch( scip->set->stage )
5718 {
5719 case SCIP_STAGE_PROBLEM:
5720 assert(!SCIPvarIsTransformed(var));
5721 SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
5722 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5723 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5724 SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5725 scip->branchcand, scip->eventqueue, newbound) );
5726 break;
5727
5730 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5731 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5732 break;
5733
5735 if( !SCIPinProbing(scip) )
5736 {
5737 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5738 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5739
5740 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5741 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5742 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
5743
5745 {
5746 SCIP_Bool infeasible;
5747
5748 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
5749 assert(!infeasible);
5750 }
5751 break;
5752 }
5753 /*lint -fallthrough*/
5754 case SCIP_STAGE_SOLVING:
5755 SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
5756 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5757 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
5758 break;
5759
5760 default:
5761 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5762 return SCIP_INVALIDCALL;
5763 } /*lint !e788*/
5764
5765 return SCIP_OKAY;
5766}
5767
5768/** depending on SCIP's stage, changes exact lower bound of variable in the problem, in preprocessing, or in current node;
5769 * if possible, adjusts bound to integral value; doesn't store any inference information in the bound change, such
5770 * that in conflict analysis, this change is treated like a branching decision
5771 *
5772 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5773 * SCIPgetVars()) gets resorted.
5774 *
5775 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5776 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5777 *
5778 * @pre This method can be called if @p scip is in one of the following stages:
5779 * - \ref SCIP_STAGE_PROBLEM
5780 * - \ref SCIP_STAGE_TRANSFORMING
5781 * - \ref SCIP_STAGE_PRESOLVING
5782 * - \ref SCIP_STAGE_SOLVING
5783 *
5784 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5785 */
5787 SCIP* scip, /**< SCIP data structure */
5788 SCIP_VAR* var, /**< variable to change the bound for */
5789 SCIP_RATIONAL* newbound /**< new value for bound */
5790 )
5791{
5792 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbExact", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5793
5794 SCIPvarAdjustLbExact(var, scip->set, newbound);
5795
5796 /* ignore tightenings of lower bounds to +infinity during solving process */
5798 {
5799#ifndef NDEBUG
5800 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
5801 SCIPvarGetLbLocal(var));
5802#endif
5803 return SCIP_OKAY;
5804 }
5805
5806 switch( scip->set->stage )
5807 {
5808 case SCIP_STAGE_PROBLEM:
5809 assert(!SCIPvarIsTransformed(var));
5810 SCIP_CALL( SCIPvarChgLbOriginalExact(var, scip->set, newbound) );
5811 SCIP_CALL( SCIPvarChgLbGlobalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
5812 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5813 SCIP_CALL( SCIPvarChgLbLocalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
5814 scip->branchcand, scip->eventqueue, newbound) );
5815 break;
5816
5819 SCIP_CALL( SCIPvarChgLbGlobalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
5820 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5821 break;
5822
5824 if( !SCIPinProbing(scip) )
5825 {
5826 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5827 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5828
5829 SCIP_CALL( SCIPnodeAddBoundchgExact(scip->tree->root, scip->mem->probmem, scip->set, scip->stat,
5830 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lpexact, scip->branchcand,
5831 scip->eventqueue, scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
5832
5834 {
5835 SCIP_Bool infeasible;
5836
5837 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
5838 assert(!infeasible);
5839 }
5840 break;
5841 }
5842 /*lint -fallthrough*/
5843 case SCIP_STAGE_SOLVING:
5845 scip->stat, scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lpexact, scip->branchcand,
5846 scip->eventqueue, scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
5847 break;
5848
5849 default:
5850 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5851 return SCIP_INVALIDCALL;
5852 } /*lint !e788*/
5853
5854 return SCIP_OKAY;
5855}
5856
5857/** depending on SCIP's stage, changes upper bound of variable in the problem, in preprocessing, or in current node;
5858 * if possible, adjusts bound to integral value; doesn't store any inference information in the bound change, such
5859 * that in conflict analysis, this change is treated like a branching decision
5860 *
5861 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5862 * SCIPgetVars()) gets re-sorted.
5863 *
5864 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5865 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5866 *
5867 * @pre This method can be called if @p scip is in one of the following stages:
5868 * - \ref SCIP_STAGE_PROBLEM
5869 * - \ref SCIP_STAGE_TRANSFORMING
5870 * - \ref SCIP_STAGE_PRESOLVING
5871 * - \ref SCIP_STAGE_SOLVING
5872 *
5873 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5874 */
5876 SCIP* scip, /**< SCIP data structure */
5877 SCIP_VAR* var, /**< variable to change the bound for */
5878 SCIP_Real newbound /**< new value for bound */
5879 )
5880{
5882
5883 SCIPvarAdjustUb(var, scip->set, &newbound);
5884
5885 /* ignore tightenings of upper bounds to -infinity during solving process */
5886 if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5887 {
5888#ifndef NDEBUG
5889 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5890 SCIPvarGetUbLocal(var));
5891#endif
5892 return SCIP_OKAY;
5893 }
5894
5895 switch( scip->set->stage )
5896 {
5897 case SCIP_STAGE_PROBLEM:
5898 assert(!SCIPvarIsTransformed(var));
5899 SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
5900 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5901 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5902 SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5903 scip->branchcand, scip->eventqueue, newbound) );
5904 break;
5905
5908 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5909 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5910 break;
5911
5913 if( !SCIPinProbing(scip) )
5914 {
5915 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5916 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5917
5918 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5919 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5920 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
5921
5923 {
5924 SCIP_Bool infeasible;
5925
5926 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
5927 assert(!infeasible);
5928 }
5929 break;
5930 }
5931 /*lint -fallthrough*/
5932 case SCIP_STAGE_SOLVING:
5933 SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
5934 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5935 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
5936 break;
5937
5938 default:
5939 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5940 return SCIP_INVALIDCALL;
5941 } /*lint !e788*/
5942
5943 return SCIP_OKAY;
5944}
5945
5946/** depending on SCIP's stage, changes exact upper bound of variable in the problem, in preprocessing, or in current node;
5947 * if possible, adjusts bound to integral value; doesn't store any inference information in the bound change, such
5948 * that in conflict analysis, this change is treated like a branching decision
5949 *
5950 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5951 * SCIPgetVars()) gets resorted.
5952 *
5953 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5954 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5955 *
5956 * @pre This method can be called if @p scip is in one of the following stages:
5957 * - \ref SCIP_STAGE_PROBLEM
5958 * - \ref SCIP_STAGE_TRANSFORMING
5959 * - \ref SCIP_STAGE_PRESOLVING
5960 * - \ref SCIP_STAGE_SOLVING
5961 *
5962 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5963 */
5965 SCIP* scip, /**< SCIP data structure */
5966 SCIP_VAR* var, /**< variable to change the bound for */
5967 SCIP_RATIONAL* newbound /**< new value for bound */
5968 )
5969{
5970 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbExact", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5971
5972 SCIPvarAdjustUbExact(var, scip->set, newbound);
5973
5974 /* ignore tightenings of upper bounds to -infinity during solving process */
5976 {
5977#ifndef NDEBUG
5978 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5979 SCIPvarGetUbLocal(var));
5980#endif
5981 return SCIP_OKAY;
5982 }
5983
5984 switch( scip->set->stage )
5985 {
5986 case SCIP_STAGE_PROBLEM:
5987 assert(!SCIPvarIsTransformed(var));
5988 SCIP_CALL( SCIPvarChgUbOriginalExact(var, scip->set, newbound) );
5989 SCIP_CALL( SCIPvarChgUbGlobalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
5990 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5991 SCIP_CALL( SCIPvarChgUbLocalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
5992 scip->branchcand, scip->eventqueue, newbound) );
5993 break;
5994
5997 SCIP_CALL( SCIPvarChgUbGlobalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
5998 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5999 break;
6000
6002 if( !SCIPinProbing(scip) )
6003 {
6004 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6005 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6006
6007 SCIP_CALL( SCIPnodeAddBoundchgExact(scip->tree->root, scip->mem->probmem, scip->set, scip->stat,
6008 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lpexact, scip->branchcand,
6009 scip->eventqueue, scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
6010
6012 {
6013 SCIP_Bool infeasible;
6014
6015 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
6016 assert(!infeasible);
6017 }
6018 break;
6019 }
6020 /*lint -fallthrough*/
6021 case SCIP_STAGE_SOLVING:
6023 scip->stat, scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lpexact, scip->branchcand,
6024 scip->eventqueue, scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
6025 break;
6026
6027 default:
6028 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6029 return SCIP_INVALIDCALL;
6030 } /*lint !e788*/
6031
6032 return SCIP_OKAY;
6033}
6034
6035/** changes lower bound of variable in the given node; if possible, adjust bound to integral value; doesn't store any
6036 * inference information in the bound change, such that in conflict analysis, this change is treated like a branching
6037 * decision
6038 *
6039 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6040 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6041 *
6042 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
6043 */
6045 SCIP* scip, /**< SCIP data structure */
6046 SCIP_NODE* node, /**< node to change bound at, or NULL for current node */
6047 SCIP_VAR* var, /**< variable to change the bound for */
6048 SCIP_Real newbound /**< new value for bound */
6049 )
6050{
6052
6053 if( node == NULL )
6054 {
6055 SCIP_CALL( SCIPchgVarLb(scip, var, newbound) );
6056 }
6057 else
6058 {
6059 SCIPvarAdjustLb(var, scip->set, &newbound);
6060
6061 /* ignore tightenings of lower bounds to +infinity during solving process */
6063 {
6064#ifndef NDEBUG
6065 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
6066 SCIPvarGetLbLocal(var));
6067#endif
6068 return SCIP_OKAY;
6069 }
6070
6071 SCIP_CALL( SCIPnodeAddBoundchg(node, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6072 scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
6073 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
6074 }
6075
6076 return SCIP_OKAY;
6077}
6078
6079/** changes upper bound of variable in the given node; if possible, adjust bound to integral value; doesn't store any
6080 * inference information in the bound change, such that in conflict analysis, this change is treated like a branching
6081 * decision
6082 *
6083 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6084 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6085 *
6086 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
6087 */
6089 SCIP* scip, /**< SCIP data structure */
6090 SCIP_NODE* node, /**< node to change bound at, or NULL for current node */
6091 SCIP_VAR* var, /**< variable to change the bound for */
6092 SCIP_Real newbound /**< new value for bound */
6093 )
6094{
6096
6097 if( node == NULL )
6098 {
6099 SCIP_CALL( SCIPchgVarUb(scip, var, newbound) );
6100 }
6101 else
6102 {
6103 SCIPvarAdjustUb(var, scip->set, &newbound);
6104
6105 /* ignore tightenings of upper bounds to -infinity during solving process */
6106 if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6107 {
6108#ifndef NDEBUG
6109 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
6110 SCIPvarGetUbLocal(var));
6111#endif
6112 return SCIP_OKAY;
6113 }
6114
6115 SCIP_CALL( SCIPnodeAddBoundchg(node, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6116 scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
6117 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
6118 }
6119
6120 return SCIP_OKAY;
6121}
6122
6123/** changes global lower bound of variable; if possible, adjust bound to integral value; also tightens the local bound,
6124 * if the global bound is better than the local bound
6125 *
6126 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6127 * SCIPgetVars()) gets re-sorted.
6128 *
6129 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6130 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6131 *
6132 * @pre This method can be called if @p scip is in one of the following stages:
6133 * - \ref SCIP_STAGE_PROBLEM
6134 * - \ref SCIP_STAGE_TRANSFORMING
6135 * - \ref SCIP_STAGE_TRANSFORMED
6136 * - \ref SCIP_STAGE_PRESOLVING
6137 * - \ref SCIP_STAGE_SOLVING
6138 *
6139 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6140 */
6142 SCIP* scip, /**< SCIP data structure */
6143 SCIP_VAR* var, /**< variable to change the bound for */
6144 SCIP_Real newbound /**< new value for bound */
6145 )
6146{
6147 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbGlobal", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6148
6149 SCIPvarAdjustLb(var, scip->set, &newbound);
6150
6151 /* ignore tightenings of lower bounds to +infinity during solving process */
6153 {
6154#ifndef NDEBUG
6155 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
6156 SCIPvarGetLbLocal(var));
6157#endif
6158 return SCIP_OKAY;
6159 }
6160
6161 switch( scip->set->stage )
6162 {
6163 case SCIP_STAGE_PROBLEM:
6164 assert(!SCIPvarIsTransformed(var));
6165 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6166 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6167 SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6168 scip->branchcand, scip->eventqueue, newbound) );
6169 SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
6170 break;
6171
6174 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6175 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6176 break;
6177
6179 if( !SCIPinProbing(scip) )
6180 {
6181 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6182 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6183
6184 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6185 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
6186 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
6187
6189 {
6190 SCIP_Bool infeasible;
6191
6192 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
6193 assert(!infeasible);
6194 }
6195 break;
6196 }
6197 /*lint -fallthrough*/
6198 case SCIP_STAGE_SOLVING:
6199 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6200 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
6201 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
6202 break;
6203
6204 default:
6205 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6206 return SCIP_INVALIDCALL;
6207 } /*lint !e788*/
6208
6209 return SCIP_OKAY;
6210}
6211
6212/** changes global upper bound of variable; if possible, adjust bound to integral value; also tightens the local bound,
6213 * if the global bound is better than the local bound
6214 *
6215 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6216 * SCIPgetVars()) gets re-sorted.
6217 *
6218 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6219 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6220 *
6221 * @pre This method can be called if @p scip is in one of the following stages:
6222 * - \ref SCIP_STAGE_PROBLEM
6223 * - \ref SCIP_STAGE_TRANSFORMING
6224 * - \ref SCIP_STAGE_TRANSFORMED
6225 * - \ref SCIP_STAGE_PRESOLVING
6226 * - \ref SCIP_STAGE_SOLVING
6227 *
6228 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6229 */
6231 SCIP* scip, /**< SCIP data structure */
6232 SCIP_VAR* var, /**< variable to change the bound for */
6233 SCIP_Real newbound /**< new value for bound */
6234 )
6235{
6236 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbGlobal", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6237
6238 SCIPvarAdjustUb(var, scip->set, &newbound);
6239
6240 /* ignore tightenings of upper bounds to -infinity during solving process */
6241 if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6242 {
6243#ifndef NDEBUG
6244 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
6245 SCIPvarGetUbLocal(var));
6246#endif
6247 return SCIP_OKAY;
6248 }
6249
6250 switch( scip->set->stage )
6251 {
6252 case SCIP_STAGE_PROBLEM:
6253 assert(!SCIPvarIsTransformed(var));
6254 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6255 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6256 SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6257 scip->branchcand, scip->eventqueue, newbound) );
6258 SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
6259 break;
6260
6263 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6264 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6265 break;
6266
6268 if( !SCIPinProbing(scip) )
6269 {
6270 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6271 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6272
6273 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6274 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
6275 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
6276
6278 {
6279 SCIP_Bool infeasible;
6280
6281 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
6282 assert(!infeasible);
6283 }
6284 break;
6285 }
6286 /*lint -fallthrough*/
6287 case SCIP_STAGE_SOLVING:
6288 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6289 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
6290 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
6291 break;
6292
6293 default:
6294 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6295 return SCIP_INVALIDCALL;
6296 } /*lint !e788*/
6297
6298 return SCIP_OKAY;
6299}
6300
6301/** changes lazy lower bound of the variable, this is only possible if the variable is not in the LP yet
6302 *
6303 * Lazy bounds are bounds that are already enforced by constraints and the objective function.
6304 * Setting a lazy lower bound has the consequence that for variables which lower bound equals the lazy lower bound,
6305 * the lower bound does not need to be passed on to the LP solver.
6306 * This is especially useful in a column generation (branch-and-price) setting.
6307 *
6308 * @attention If the variable has a global lower bound below lazylb, then the global lower bound is tightened to
6309 * lazylb by a call to SCIPchgVarLbGlobal().
6310 *
6311 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6312 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6313 *
6314 * @pre This method can be called if @p scip is in one of the following stages:
6315 * - \ref SCIP_STAGE_PROBLEM
6316 * - \ref SCIP_STAGE_TRANSFORMING
6317 * - \ref SCIP_STAGE_TRANSFORMED
6318 * - \ref SCIP_STAGE_PRESOLVING
6319 * - \ref SCIP_STAGE_SOLVING
6320 */
6322 SCIP* scip, /**< SCIP data structure */
6323 SCIP_VAR* var, /**< problem variable */
6324 SCIP_Real lazylb /**< the lazy lower bound to be set */
6325 )
6326{
6327 assert(scip != NULL);
6328 assert(var != NULL);
6329
6331
6332 if( SCIPisGT(scip, lazylb, SCIPvarGetLbGlobal(var)) )
6333 {
6334 SCIP_CALL( SCIPchgVarLbGlobal(scip, var, lazylb) );
6335 }
6336
6337 SCIP_CALL( SCIPvarChgLbLazy(var, scip->set, lazylb) );
6338
6339 return SCIP_OKAY;
6340}
6341
6342/** changes lazy upper bound of the variable, this is only possible if the variable is not in the LP yet
6343 *
6344 * Lazy bounds are bounds that are already enforced by constraints and the objective function.
6345 * Setting a lazy upper bound has the consequence that for variables which upper bound equals the lazy upper bound,
6346 * the upper bound does not need to be passed on to the LP solver.
6347 * This is especially useful in a column generation (branch-and-price) setting.
6348 *
6349 * @attention If the variable has a global upper bound above lazyub, then the global upper bound is tightened to
6350 * lazyub by a call to SCIPchgVarUbGlobal().
6351 *
6352 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6353 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6354 *
6355 * @pre This method can be called if @p scip is in one of the following stages:
6356 * - \ref SCIP_STAGE_PROBLEM
6357 * - \ref SCIP_STAGE_TRANSFORMING
6358 * - \ref SCIP_STAGE_TRANSFORMED
6359 * - \ref SCIP_STAGE_PRESOLVING
6360 * - \ref SCIP_STAGE_SOLVING
6361 */
6363 SCIP* scip, /**< SCIP data structure */
6364 SCIP_VAR* var, /**< problem variable */
6365 SCIP_Real lazyub /**< the lazy lower bound to be set */
6366 )
6367{
6368 assert(scip != NULL);
6369 assert(var != NULL);
6370
6372
6373 if( SCIPisLT(scip, lazyub, SCIPvarGetUbGlobal(var)) )
6374 {
6375 SCIP_CALL( SCIPchgVarUbGlobal(scip, var, lazyub) );
6376 }
6377
6378 SCIP_CALL( SCIPvarChgUbLazy(var, scip->set, lazyub) );
6379
6380 return SCIP_OKAY;
6381}
6382
6383/** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
6384 * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
6385 * doesn't store any inference information in the bound change, such that in conflict analysis, this change
6386 * is treated like a branching decision
6387 *
6388 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6389 * SCIPgetVars()) gets re-sorted.
6390 *
6391 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6392 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6393 *
6394 * @pre This method can be called if @p scip is in one of the following stages:
6395 * - \ref SCIP_STAGE_PROBLEM
6396 * - \ref SCIP_STAGE_PRESOLVING
6397 * - \ref SCIP_STAGE_SOLVING
6398 *
6399 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6400 */
6402 SCIP* scip, /**< SCIP data structure */
6403 SCIP_VAR* var, /**< variable to change the bound for */
6404 SCIP_Real newbound, /**< new value for bound */
6405 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6406 SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
6407 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6408 )
6409{
6410 SCIP_Real lb;
6411 SCIP_Real ub;
6412
6413 assert(infeasible != NULL);
6414
6416 /** @todo if needed provide pending local/global bound changes that will be flushed after leaving diving mode (as in struct_tree.h) */
6418
6419 *infeasible = FALSE;
6420 if( tightened != NULL )
6421 *tightened = FALSE;
6422
6423 SCIPvarAdjustLb(var, scip->set, &newbound);
6424
6425 /* ignore tightenings of lower bounds to +infinity during solving process */
6427 {
6428#ifndef NDEBUG
6429 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
6430 SCIPvarGetLbLocal(var));
6431#endif
6432 return SCIP_OKAY;
6433 }
6434
6435 /* get current bounds */
6436 lb = SCIPcomputeVarLbLocal(scip, var);
6437 ub = SCIPcomputeVarUbLocal(scip, var);
6438 assert(SCIPsetIsLE(scip->set, lb, ub));
6439
6440 if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
6441 {
6442 *infeasible = TRUE;
6443 return SCIP_OKAY;
6444 }
6445 newbound = MIN(newbound, ub);
6446
6447 if( (force && SCIPsetIsLE(scip->set, newbound, lb)) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
6448 return SCIP_OKAY;
6449
6450 switch( scip->set->stage )
6451 {
6452 case SCIP_STAGE_PROBLEM:
6453 assert(!SCIPvarIsTransformed(var));
6454 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6455 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6456 SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6457 scip->branchcand, scip->eventqueue, newbound) );
6458 SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
6459 break;
6461 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6462 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6463 break;
6465 if( !SCIPinProbing(scip) )
6466 {
6467 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6468 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6469
6470 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6471 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
6472 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
6473
6475 {
6476 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6477 assert(!(*infeasible));
6478 }
6479 break;
6480 }
6481 /*lint -fallthrough*/
6482 case SCIP_STAGE_SOLVING:
6483 SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
6484 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
6485 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
6486 break;
6487
6488 default:
6489 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6490 return SCIP_INVALIDCALL;
6491 } /*lint !e788*/
6492
6493 /* check whether the lower bound improved */
6494 if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
6495 *tightened = TRUE;
6496
6497 return SCIP_OKAY;
6498}
6499
6500/** changes exact lower bound of variable in preprocessing or in the current node, if the new bound is tighter
6501 * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
6502 * doesn't store any inference information in the bound change, such that in conflict analysis, this change
6503 * is treated like a branching decision
6504 *
6505 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6506 * SCIPgetVars()) gets resorted.
6507 *
6508 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6509 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6510 *
6511 * @pre This method can be called if @p scip is in one of the following stages:
6512 * - \ref SCIP_STAGE_PROBLEM
6513 * - \ref SCIP_STAGE_PRESOLVING
6514 * - \ref SCIP_STAGE_SOLVING
6515 *
6516 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6517 */
6519 SCIP* scip, /**< SCIP data structure */
6520 SCIP_VAR* var, /**< variable to change the bound for */
6521 SCIP_RATIONAL* newbound, /**< new value for bound */
6522 SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
6523 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6524 )
6525{
6526 SCIP_RATIONAL* lb;
6527 SCIP_RATIONAL* ub;
6528
6529 assert(infeasible != NULL);
6530 assert(SCIPisExact(scip));
6531
6532 SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarLbExact", FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6533 /** @todo if needed provide pending local/global bound changes that will be flushed after leaving diving mode (as in struct_tree.h) */
6535
6536 *infeasible = FALSE;
6537 if( tightened != NULL )
6538 *tightened = FALSE;
6539
6540 SCIPvarAdjustLbExact(var, scip->set, newbound);
6541
6542 /* ignore tightenings of lower bounds to +infinity during solving process */
6544 {
6545#ifndef NDEBUG
6546 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
6547 SCIPvarGetLbLocal(var));
6548#endif
6549 return SCIP_OKAY;
6550 }
6551
6554
6555 /* get current bounds */
6558
6559 assert(SCIPrationalIsLE(lb, ub));
6560
6561 if( SCIPrationalIsGT(newbound, ub) )
6562 {
6563 *infeasible = TRUE;
6566
6567 return SCIP_OKAY;
6568 }
6569
6570 SCIPrationalMin(newbound, newbound, ub);
6571 if( SCIPrationalIsLE(newbound, lb) )
6572 {
6575
6576 return SCIP_OKAY;
6577 }
6578
6579 switch( scip->set->stage )
6580 {
6581 case SCIP_STAGE_PROBLEM:
6582 assert(!SCIPvarIsTransformed(var));
6583 SCIP_CALL( SCIPvarChgLbGlobalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
6584 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6585 SCIP_CALL( SCIPvarChgLbLocalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
6586 scip->branchcand, scip->eventqueue, newbound) );
6587 SCIP_CALL( SCIPvarChgLbOriginalExact(var, scip->set, newbound) );
6588 break;
6590 SCIP_CALL( SCIPvarChgLbGlobalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
6591 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6592 break;
6594 if( !SCIPinProbing(scip) )
6595 {
6596 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6597 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6598
6599 SCIP_CALL( SCIPnodeAddBoundchgExact(scip->tree->root, scip->mem->probmem, scip->set, scip->stat,
6600 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lpexact, scip->branchcand,
6601 scip->eventqueue, scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
6602
6604 {
6605 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6606 assert(!(*infeasible));
6607 }
6608 break;
6609 }
6610 /*lint -fallthrough*/
6611 case SCIP_STAGE_SOLVING:
6613 scip->stat, scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lpexact, scip->branchcand,
6614 scip->eventqueue, scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
6615 break;
6616
6617 default:
6618 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6619 return SCIP_INVALIDCALL;
6620 } /*lint !e788*/
6621
6622 /* check whether the lower bound improved */
6623 SCIP_CALL( SCIPcomputeVarLbLocalExact(scip, var, newbound) );
6624 if( tightened != NULL && SCIPrationalIsLT(lb, newbound) )
6625 *tightened = TRUE;
6626
6629
6630 return SCIP_OKAY;
6631}
6632
6633/** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
6634 * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
6635 * doesn't store any inference information in the bound change, such that in conflict analysis, this change
6636 * is treated like a branching decision
6637 *
6638 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6639 * SCIPgetVars()) gets re-sorted.
6640 *
6641 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6642 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6643 *
6644 * @pre This method can be called if @p scip is in one of the following stages:
6645 * - \ref SCIP_STAGE_PROBLEM
6646 * - \ref SCIP_STAGE_PRESOLVING
6647 * - \ref SCIP_STAGE_SOLVING
6648 *
6649 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6650 */
6652 SCIP* scip, /**< SCIP data structure */
6653 SCIP_VAR* var, /**< variable to change the bound for */
6654 SCIP_Real newbound, /**< new value for bound */
6655 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6656 SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
6657 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6658 )
6659{
6660 SCIP_Real lb;
6661 SCIP_Real ub;
6662
6663 assert(infeasible != NULL);
6665
6666 /** @todo if needed provide pending local/global bound changes that will be flushed after leaving diving mode (as in struct_tree.h) */
6668
6669 *infeasible = FALSE;
6670 if( tightened != NULL )
6671 *tightened = FALSE;
6672
6673 SCIPvarAdjustUb(var, scip->set, &newbound);
6674
6675 /* ignore tightenings of upper bounds to -infinity during solving process */
6676 if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6677 {
6678#ifndef NDEBUG
6679 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
6680 SCIPvarGetUbLocal(var));
6681#endif
6682 return SCIP_OKAY;
6683 }
6684
6685 /* get current bounds */
6686 lb = SCIPcomputeVarLbLocal(scip, var);
6687 ub = SCIPcomputeVarUbLocal(scip, var);
6688 assert(SCIPsetIsLE(scip->set, lb, ub));
6689
6690 if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
6691 {
6692 *infeasible = TRUE;
6693 return SCIP_OKAY;
6694 }
6695 newbound = MAX(newbound, lb);
6696
6697 if( (force && SCIPsetIsGE(scip->set, newbound, ub)) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
6698 return SCIP_OKAY;
6699
6700 switch( scip->set->stage )
6701 {
6702 case SCIP_STAGE_PROBLEM:
6703 assert(!SCIPvarIsTransformed(var));
6704 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6705 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6706 SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6707 scip->branchcand, scip->eventqueue, newbound) );
6708 SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
6709 break;
6711 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6712 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6713 break;
6715 if( !SCIPinProbing(scip) )
6716 {
6717 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6718 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6719
6720 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6721 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
6722 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
6723
6725 {
6726 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6727 assert(!(*infeasible));
6728 }
6729 break;
6730 }
6731 /*lint -fallthrough*/
6732 case SCIP_STAGE_SOLVING:
6733 SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
6734 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
6735 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
6736 break;
6737
6738 default:
6739 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6740 return SCIP_INVALIDCALL;
6741 } /*lint !e788*/
6742
6743 /* check whether the upper bound improved */
6744 if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
6745 *tightened = TRUE;
6746
6747 return SCIP_OKAY;
6748}
6749
6750/** changes exact upper bound of variable in preprocessing or in the current node, if the new bound is tighter
6751 * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
6752 * doesn't store any inference information in the bound change, such that in conflict analysis, this change
6753 * is treated like a branching decision
6754 *
6755 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6756 * SCIPgetVars()) gets resorted.
6757 *
6758 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6759 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6760 *
6761 * @pre This method can be called if @p scip is in one of the following stages:
6762 * - \ref SCIP_STAGE_PROBLEM
6763 * - \ref SCIP_STAGE_PRESOLVING
6764 * - \ref SCIP_STAGE_SOLVING
6765 *
6766 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6767 */
6769 SCIP* scip, /**< SCIP data structure */
6770 SCIP_VAR* var, /**< variable to change the bound for */
6771 SCIP_RATIONAL* newbound, /**< new value for bound */
6772 SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
6773 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6774 )
6775{
6776 SCIP_RATIONAL* lb;
6777 SCIP_RATIONAL* ub;
6778
6779 assert(infeasible != NULL);
6780 assert(SCIPisExact(scip));
6781
6782 SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarUbExact", FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6783 /** @todo if needed provide pending local/global bound changes that will be flushed after leaving diving mode (as in struct_tree.h) */
6785
6786 *infeasible = FALSE;
6787 if( tightened != NULL )
6788 *tightened = FALSE;
6789
6790 SCIPvarAdjustUbExact(var, scip->set, newbound);
6791
6792 /* ignore tightenings of upper bounds to -infinity during solving process */
6794 {
6795#ifndef NDEBUG
6796 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
6797 SCIPvarGetUbLocal(var));
6798#endif
6799 return SCIP_OKAY;
6800 }
6801
6804
6805 /* get current bounds */
6808
6809 assert(SCIPrationalIsLE(lb, ub));
6810
6811 if( SCIPrationalIsLT(newbound, lb) )
6812 {
6815
6816 *infeasible = TRUE;
6817 return SCIP_OKAY;
6818 }
6819
6820 SCIPrationalMax(newbound, newbound, lb);
6821 if( SCIPrationalIsGE(newbound, ub) )
6822 {
6825
6826 return SCIP_OKAY;
6827 }
6828
6829 switch( scip->set->stage )
6830 {
6831 case SCIP_STAGE_PROBLEM:
6832 assert(!SCIPvarIsTransformed(var));
6833 SCIP_CALL( SCIPvarChgUbGlobalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
6834 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6835 SCIP_CALL( SCIPvarChgUbLocalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
6836 scip->branchcand, scip->eventqueue, newbound) );
6837 SCIP_CALL( SCIPvarChgUbOriginalExact(var, scip->set, newbound) );
6838 break;
6840 SCIP_CALL( SCIPvarChgUbGlobalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
6841 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6842 break;
6844 if( !SCIPinProbing(scip) )
6845 {
6846 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6847 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6848
6849 SCIP_CALL( SCIPnodeAddBoundchgExact(scip->tree->root, scip->mem->probmem, scip->set, scip->stat,
6850 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lpexact, scip->branchcand,
6851 scip->eventqueue, scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
6852
6854 {
6855 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6856 assert(!(*infeasible));
6857 }
6858 break;
6859 }
6860 /*lint -fallthrough*/
6861 case SCIP_STAGE_SOLVING:
6863 scip->stat, scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lpexact, scip->branchcand,
6864 scip->eventqueue, scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
6865 break;
6866
6867 default:
6868 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6869 return SCIP_INVALIDCALL;
6870 } /*lint !e788*/
6871
6872 /* check whether the lower bound improved */
6873 if( tightened != NULL && SCIPrationalIsGT(ub, newbound) )
6874 *tightened = TRUE;
6875
6878
6879 return SCIP_OKAY;
6880}
6881
6882/** fixes variable in preprocessing or in the current node, if the new bound is tighter (w.r.t. bound strengthening
6883 * epsilon) than the current bound; if possible, adjusts bound to integral value; the given inference constraint is
6884 * stored, such that the conflict analysis is able to find out the reason for the deduction of the bound change
6885 *
6886 * @note In presolving stage when not in probing mode the variable will be fixed directly, otherwise this method
6887 * changes first the lowerbound by calling SCIPinferVarLbCons and second the upperbound by calling
6888 * SCIPinferVarUbCons
6889 *
6890 * @note If SCIP is in presolving stage, it can happen that the internal variable array (which get be accessed via
6891 * SCIPgetVars()) gets re-sorted.
6892 *
6893 * @note During presolving, an integer variable which bound changes to {0,1} is upgraded to a binary variable.
6894 */
6896 SCIP* scip, /**< SCIP data structure */
6897 SCIP_VAR* var, /**< variable to change the bound for */
6898 SCIP_Real fixedval, /**< new value for fixation */
6899 SCIP_CONS* infercons, /**< constraint that deduced the bound change */
6900 int inferinfo, /**< user information for inference to help resolving the conflict */
6901 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6902 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
6903 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6904 )
6905{
6906 assert(scip != NULL);
6907 assert(var != NULL);
6908 assert(infeasible != NULL);
6909
6910 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarFixCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6911
6912 if( tightened != NULL )
6913 *tightened = FALSE;
6914
6915 /* in presolving case we take the shortcut to directly fix the variables */
6917 {
6918 SCIP_Bool fixed;
6919
6920 SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6921 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
6922 scip->eventfilter, scip->cliquetable, fixedval, infeasible, &fixed) );
6923
6924 if( tightened != NULL )
6925 *tightened = fixed;
6926 }
6927 /* otherwise we use the lb and ub methods */
6928 else
6929 {
6930 SCIP_Bool lbtightened;
6931
6932 SCIP_CALL( SCIPinferVarLbCons(scip, var, fixedval, infercons, inferinfo, force, infeasible, &lbtightened) );
6933
6934 if( ! (*infeasible) )
6935 {
6936 SCIP_CALL( SCIPinferVarUbCons(scip, var, fixedval, infercons, inferinfo, force, infeasible, tightened) );
6937
6938 if( tightened != NULL )
6939 *tightened |= lbtightened;
6940 }
6941 }
6942
6943 return SCIP_OKAY;
6944}
6945
6946/** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
6947 * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
6948 * the given inference constraint is stored, such that the conflict analysis is able to find out the reason
6949 * for the deduction of the bound change
6950 *
6951 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6952 * SCIPgetVars()) gets re-sorted.
6953 *
6954 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6955 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6956 *
6957 * @pre This method can be called if @p scip is in one of the following stages:
6958 * - \ref SCIP_STAGE_PROBLEM
6959 * - \ref SCIP_STAGE_PRESOLVING
6960 * - \ref SCIP_STAGE_SOLVING
6961 *
6962 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6963 */
6965 SCIP* scip, /**< SCIP data structure */
6966 SCIP_VAR* var, /**< variable to change the bound for */
6967 SCIP_Real newbound, /**< new value for bound */
6968 SCIP_CONS* infercons, /**< constraint that deduced the bound change */
6969 int inferinfo, /**< user information for inference to help resolving the conflict */
6970 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6971 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
6972 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6973 )
6974{
6975 SCIP_Real lb;
6976 SCIP_Real ub;
6977
6978 assert(infeasible != NULL);
6979
6980 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarLbCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6981
6982 *infeasible = FALSE;
6983 if( tightened != NULL )
6984 *tightened = FALSE;
6985
6986 SCIPvarAdjustLb(var, scip->set, &newbound);
6987
6988 /* get current bounds */
6989 lb = SCIPvarGetLbLocal(var);
6990 ub = SCIPvarGetUbLocal(var);
6991 assert(SCIPsetIsLE(scip->set, lb, ub));
6992
6993 if( SCIPisInfinity(scip, newbound) || SCIPisFeasGT(scip, newbound, ub) || (scip->set->exact_enable && ub < newbound) )
6994 {
6995 *infeasible = TRUE;
6996 return SCIP_OKAY;
6997 }
6998
6999 newbound = MIN(newbound, ub);
7000
7001 if( (force && SCIPsetIsLE(scip->set, newbound, lb)) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
7002 return SCIP_OKAY;
7003
7004 switch( scip->set->stage )
7005 {
7006 case SCIP_STAGE_PROBLEM:
7007 assert(!SCIPvarIsTransformed(var));
7008 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
7009 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
7010 SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
7011 scip->branchcand, scip->eventqueue, newbound) );
7012 SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
7013 break;
7014
7016 if( !SCIPinProbing(scip) )
7017 {
7018 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
7019 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
7020
7021 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
7022 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
7023 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
7024
7026 {
7027 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
7028 assert(!(*infeasible));
7029 }
7030 break;
7031 }
7032 /*lint -fallthrough*/
7033 case SCIP_STAGE_SOLVING:
7034 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
7035 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
7036 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, infercons, NULL, inferinfo, FALSE) );
7037 break;
7038
7039 default:
7040 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
7041 return SCIP_INVALIDCALL;
7042 } /*lint !e788*/
7043
7044 /* check whether the lower bound improved */
7045 if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
7046 *tightened = TRUE;
7047
7048 return SCIP_OKAY;
7049}
7050
7051/** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
7052 * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
7053 * the given inference constraint is stored, such that the conflict analysis is able to find out the reason
7054 * for the deduction of the bound change
7055 *
7056 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
7057 * SCIPgetVars()) gets re-sorted.
7058 *
7059 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7060 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7061 *
7062 * @pre This method can be called if @p scip is in one of the following stages:
7063 * - \ref SCIP_STAGE_PROBLEM
7064 * - \ref SCIP_STAGE_PRESOLVING
7065 * - \ref SCIP_STAGE_SOLVING
7066 *
7067 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
7068 */
7070 SCIP* scip, /**< SCIP data structure */
7071 SCIP_VAR* var, /**< variable to change the bound for */
7072 SCIP_Real newbound, /**< new value for bound */
7073 SCIP_CONS* infercons, /**< constraint that deduced the bound change */
7074 int inferinfo, /**< user information for inference to help resolving the conflict */
7075 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
7076 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
7077 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
7078 )
7079{
7080 SCIP_Real lb;
7081 SCIP_Real ub;
7082
7083 assert(infeasible != NULL);
7084
7085 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarUbCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7086
7087 *infeasible = FALSE;
7088 if( tightened != NULL )
7089 *tightened = FALSE;
7090
7091 SCIPvarAdjustUb(var, scip->set, &newbound);
7092
7093 /* get current bounds */
7094 lb = SCIPvarGetLbLocal(var);
7095 ub = SCIPvarGetUbLocal(var);
7096 assert(SCIPsetIsLE(scip->set, lb, ub));
7097
7098 if( SCIPisInfinity(scip, -newbound) || SCIPisFeasLT(scip, newbound, lb) || (scip->set->exact_enable && lb > newbound) )
7099 {
7100 *infeasible = TRUE;
7101 return SCIP_OKAY;
7102 }
7103
7104 newbound = MAX(newbound, lb);
7105
7106 if( (force && SCIPsetIsGE(scip->set, newbound, ub)) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
7107 return SCIP_OKAY;
7108
7109 switch( scip->set->stage )
7110 {
7111 case SCIP_STAGE_PROBLEM:
7112 assert(!SCIPvarIsTransformed(var));
7113 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
7114 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
7115 SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
7116 scip->branchcand, scip->eventqueue, newbound) );
7117 SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
7118 break;
7119
7121 if( !SCIPinProbing(scip) )
7122 {
7123 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
7124 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
7125
7126 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
7127 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
7128 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
7129
7131 {
7132 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
7133 assert(!(*infeasible));
7134 }
7135 break;
7136 }
7137 /*lint -fallthrough*/
7138 case SCIP_STAGE_SOLVING:
7139 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
7140 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
7141 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, infercons, NULL, inferinfo, FALSE) );
7142 break;
7143
7144 default:
7145 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
7146 return SCIP_INVALIDCALL;
7147 } /*lint !e788*/
7148
7149 /* check whether the upper bound improved */
7150 if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
7151 *tightened = TRUE;
7152
7153 return SCIP_OKAY;
7154}
7155
7156/** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
7157 * than the current bound; if possible, adjusts bound to integral value;
7158 * the given inference constraint is stored, such that the conflict analysis is able to find out the reason
7159 * for the deduction of the bound change
7160 *
7161 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
7162 * SCIPgetVars()) gets resorted.
7163 *
7164 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7165 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7166 *
7167 * @pre This method can be called if @p scip is in one of the following stages:
7168 * - \ref SCIP_STAGE_PROBLEM
7169 * - \ref SCIP_STAGE_PRESOLVING
7170 * - \ref SCIP_STAGE_SOLVING
7171 *
7172 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
7173 */
7175 SCIP* scip, /**< SCIP data structure */
7176 SCIP_VAR* var, /**< variable to change the bound for */
7177 SCIP_RATIONAL* newbound, /**< new value for bound */
7178 SCIP_CONS* infercons, /**< constraint that deduced the bound change */
7179 int inferinfo, /**< user information for inference to help resolving the conflict */
7180 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
7181 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
7182 )
7183{
7184 SCIP_RATIONAL* lb;
7185 SCIP_RATIONAL* ub;
7186 SCIP_RATIONAL* adjustedBound;
7188 SCIPrationalSetRational(adjustedBound, newbound);
7189 assert(infeasible != NULL);
7190
7191 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarUbConsExact", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7192
7193 *infeasible = FALSE;
7194 if( tightened != NULL )
7195 *tightened = FALSE;
7196
7197 SCIPvarAdjustUbExact(var, scip->set, adjustedBound);
7198
7199 /* ignore tightenings of upper bounds to -infinity during solving process */
7201 {
7202#ifndef NDEBUG
7203 SCIPrationalDebugMessage("ignore upper bound tightening for %s from %q to -infinity\n", SCIPvarGetName(var),
7205#endif
7206 goto RETURN_SCIP_OKAY;
7207 }
7208
7209 /* get current bounds */
7210 lb = SCIPvarGetLbLocalExact(var);
7211 ub = SCIPvarGetUbLocalExact(var);
7212 assert(SCIPrationalIsLE(lb, ub));
7213
7214 if( SCIPrationalIsLT(adjustedBound, lb) )
7215 {
7216 *infeasible = TRUE;
7219 var, NULL, adjustedBound, -1L, SCIPcertificateGetCurrentIndex(SCIPgetCertificate(scip)) - 1L) );
7220 goto RETURN_SCIP_OKAY;
7221 }
7222
7223 if( SCIPrationalIsGE(adjustedBound, ub) ) {
7224 goto RETURN_SCIP_OKAY;
7225 }
7226
7227 /* We have tightened the upper bound */
7228 if( tightened != NULL)
7229 *tightened = TRUE;
7230
7231 switch( scip->set->stage )
7232 {
7233 case SCIP_STAGE_PROBLEM:
7234 assert(!SCIPvarIsTransformed(var));
7235 SCIP_CALL( SCIPvarChgUbGlobalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
7236 scip->branchcand, scip->eventqueue, scip->cliquetable, adjustedBound) );
7237 SCIP_CALL( SCIPvarChgUbLocalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
7238 scip->branchcand, scip->eventqueue, adjustedBound) );
7239 SCIP_CALL( SCIPvarChgUbOriginalExact(var, scip->set, adjustedBound) );
7240 break;
7241
7243 if( !SCIPinProbing(scip) )
7244 {
7245 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
7246 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
7247
7248 SCIP_CALL( SCIPnodeAddBoundchgExact(scip->tree->root, scip->mem->probmem, scip->set, scip->stat,
7249 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lpexact, scip->branchcand,
7250 scip->eventqueue, scip->eventfilter, scip->cliquetable, var, adjustedBound, SCIP_BOUNDTYPE_UPPER,
7251 FALSE) );
7252
7254 {
7255 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
7256 assert(!(*infeasible));
7257 }
7258 break;
7259 }
7260 /*lint -fallthrough*/
7261 case SCIP_STAGE_SOLVING:
7263 scip->stat, scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lpexact, scip->branchcand,
7264 scip->eventqueue, scip->eventfilter, scip->cliquetable, var, adjustedBound, SCIP_BOUNDTYPE_UPPER,
7265 infercons, NULL, inferinfo, FALSE) );
7266 break;
7267
7268 default:
7269 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
7270 SCIPrationalFreeBuffer(SCIPbuffer(scip), &adjustedBound);
7271 return SCIP_INVALIDCALL;
7272 } /*lint !e788*/
7273RETURN_SCIP_OKAY:
7274 SCIPrationalFreeBuffer(SCIPbuffer(scip), &adjustedBound);
7275 return SCIP_OKAY;
7276}
7277
7278/** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
7279 * than the current bound; if possible, adjusts bound to integral value;
7280 * the given inference constraint is stored, such that the conflict analysis is able to find out the reason
7281 * for the deduction of the bound change
7282 *
7283 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
7284 * SCIPgetVars()) gets resorted.
7285 *
7286 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7287 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7288 *
7289 * @pre This method can be called if @p scip is in one of the following stages:
7290 * - \ref SCIP_STAGE_PROBLEM
7291 * - \ref SCIP_STAGE_PRESOLVING
7292 * - \ref SCIP_STAGE_SOLVING
7293 *
7294 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
7295 */
7297 SCIP* scip, /**< SCIP data structure */
7298 SCIP_VAR* var, /**< variable to change the bound for */
7299 SCIP_RATIONAL* newbound, /**< new value for bound */
7300 SCIP_CONS* infercons, /**< constraint that deduced the bound change */
7301 int inferinfo, /**< user information for inference to help resolving the conflict */
7302 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
7303 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
7304 )
7305{
7306 SCIP_RATIONAL* ub;
7307 SCIP_RATIONAL* lb;
7308 SCIP_RATIONAL* adjustedBound;
7310 SCIPrationalSetRational(adjustedBound, newbound);
7311 assert(infeasible != NULL);
7312
7313 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarLbConsExact", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7314
7315 *infeasible = FALSE;
7316 if( tightened != NULL )
7317 *tightened = FALSE;
7318
7319 SCIPvarAdjustLbExact(var, scip->set, adjustedBound);
7320
7321 /* ignore tightenings of upper bounds to -infinity during solving process */
7323 {
7324#ifndef NDEBUG
7325 SCIPrationalDebugMessage("ignore upper bound tightening for %s from %q to -infinity\n", SCIPvarGetName(var),
7327#endif
7328 goto RETURN_SCIP_OKAY;
7329 }
7330
7331 /* get current bounds */
7332 lb = SCIPvarGetLbLocalExact(var);
7333 ub = SCIPvarGetUbLocalExact(var);
7334 assert(SCIPrationalIsLE(lb, ub));
7335
7336 if( SCIPrationalIsGT(adjustedBound, ub) )
7337 {
7338 *infeasible = TRUE;
7341 var, adjustedBound, NULL, SCIPcertificateGetCurrentIndex(SCIPgetCertificate(scip)) -1L, -1L) );
7342 goto RETURN_SCIP_OKAY;
7343 }
7344
7345 if( SCIPrationalIsLE(adjustedBound, lb) ) {
7346 goto RETURN_SCIP_OKAY;
7347 }
7348
7349 /* We have tightened the upper bound */
7350 if( tightened != NULL)
7351 *tightened = TRUE;
7352
7353 switch( scip->set->stage )
7354 {
7355 case SCIP_STAGE_PROBLEM:
7356 assert(!SCIPvarIsTransformed(var));
7357 SCIP_CALL( SCIPvarChgLbGlobalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
7358 scip->branchcand, scip->eventqueue, scip->cliquetable, adjustedBound) );
7359 SCIP_CALL( SCIPvarChgLbLocalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
7360 scip->branchcand, scip->eventqueue, adjustedBound) );
7361 SCIP_CALL( SCIPvarChgLbOriginalExact(var, scip->set, adjustedBound) );
7362 break;
7363
7365 if( !SCIPinProbing(scip) )
7366 {
7367 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
7368 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
7369
7370 SCIP_CALL( SCIPnodeAddBoundchgExact(scip->tree->root, scip->mem->probmem, scip->set, scip->stat,
7371 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lpexact, scip->branchcand,
7372 scip->eventqueue, scip->eventfilter, scip->cliquetable, var, adjustedBound, SCIP_BOUNDTYPE_LOWER,
7373 FALSE) );
7374
7376 {
7377 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
7378 assert(!(*infeasible));
7379 }
7380 break;
7381 }
7382 /*lint -fallthrough*/
7383 case SCIP_STAGE_SOLVING:
7385 scip->stat, scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lpexact, scip->branchcand,
7386 scip->eventqueue, scip->eventfilter, scip->cliquetable, var, adjustedBound, SCIP_BOUNDTYPE_LOWER,
7387 infercons, NULL, inferinfo, FALSE) );
7388 break;
7389
7390 default:
7391 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
7392 SCIPrationalFreeBuffer(SCIPbuffer(scip), &adjustedBound);
7393 return SCIP_INVALIDCALL;
7394 } /*lint !e788*/
7395RETURN_SCIP_OKAY:
7396 SCIPrationalFreeBuffer(SCIPbuffer(scip), &adjustedBound);
7397 return SCIP_OKAY;
7398}
7399
7400/** depending on SCIP's stage, fixes binary variable in the problem, in preprocessing, or in current node;
7401 * the given inference constraint is stored, such that the conflict analysis is able to find out the reason for the
7402 * deduction of the fixing
7403 *
7404 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7405 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7406 *
7407 * @pre This method can be called if @p scip is in one of the following stages:
7408 * - \ref SCIP_STAGE_PROBLEM
7409 * - \ref SCIP_STAGE_PRESOLVING
7410 * - \ref SCIP_STAGE_SOLVING
7411 */
7413 SCIP* scip, /**< SCIP data structure */
7414 SCIP_VAR* var, /**< binary variable to fix */
7415 SCIP_Bool fixedval, /**< value to fix binary variable to */
7416 SCIP_CONS* infercons, /**< constraint that deduced the fixing */
7417 int inferinfo, /**< user information for inference to help resolving the conflict */
7418 SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
7419 SCIP_Bool* tightened /**< pointer to store whether the fixing tightened the local bounds, or NULL */
7420 )
7421{
7422 SCIP_Real lb;
7423 SCIP_Real ub;
7424
7425 assert(SCIPvarIsBinary(var));
7426 assert(fixedval == TRUE || fixedval == FALSE);
7427 assert(infeasible != NULL);
7428
7429 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferBinvarCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7430
7431 *infeasible = FALSE;
7432 if( tightened != NULL )
7433 *tightened = FALSE;
7434
7435 /* get current bounds */
7436 lb = SCIPvarGetLbLocal(var);
7437 ub = SCIPvarGetUbLocal(var);
7438 assert(SCIPsetIsEQ(scip->set, lb, 0.0) || SCIPsetIsEQ(scip->set, lb, 1.0));
7439 assert(SCIPsetIsEQ(scip->set, ub, 0.0) || SCIPsetIsEQ(scip->set, ub, 1.0));
7440 assert(SCIPsetIsLE(scip->set, lb, ub));
7441
7442 /* check, if variable is already fixed */
7443 if( (lb > 0.5) || (ub < 0.5) )
7444 {
7445 *infeasible = (fixedval == (lb < 0.5));
7446
7447 return SCIP_OKAY;
7448 }
7449
7450 /* apply the fixing */
7451 switch( scip->set->stage )
7452 {
7453 case SCIP_STAGE_PROBLEM:
7454 assert(!SCIPvarIsTransformed(var));
7455 if( fixedval == TRUE )
7456 {
7457 SCIP_CALL( SCIPchgVarLb(scip, var, 1.0) );
7458 }
7459 else
7460 {
7461 SCIP_CALL( SCIPchgVarUb(scip, var, 0.0) );
7462 }
7463 break;
7464
7466 if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
7467 {
7468 SCIP_Bool fixed;
7469
7470 SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
7471 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
7472 scip->cliquetable, (SCIP_Real)fixedval, infeasible, &fixed) );
7473 break;
7474 }
7475 /*lint -fallthrough*/
7476 case SCIP_STAGE_SOLVING:
7477 if( fixedval == TRUE )
7478 {
7479 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
7480 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
7481 scip->eventfilter, scip->cliquetable, var, 1.0, SCIP_BOUNDTYPE_LOWER, infercons, NULL, inferinfo, FALSE) );
7482 }
7483 else
7484 {
7485 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
7486 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
7487 scip->eventfilter, scip->cliquetable, var, 0.0, SCIP_BOUNDTYPE_UPPER, infercons, NULL, inferinfo, FALSE) );
7488 }
7489 break;
7490
7491 default:
7492 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
7493 return SCIP_INVALIDCALL;
7494 } /*lint !e788*/
7495
7496 if( tightened != NULL )
7497 *tightened = TRUE;
7498
7499 return SCIP_OKAY;
7500}
7501
7502/** fixes variable in preprocessing or in the current node, if the new bound is tighter (w.r.t. bound strengthening
7503 * epsilon) than the current bound; if possible, adjusts bound to integral value; the given inference constraint is
7504 * stored, such that the conflict analysis is able to find out the reason for the deduction of the bound change
7505 *
7506 * @note In presolving stage when not in probing mode the variable will be fixed directly, otherwise this method
7507 * changes first the lowerbound by calling SCIPinferVarLbProp and second the upperbound by calling
7508 * SCIPinferVarUbProp
7509 *
7510 * @note If SCIP is in presolving stage, it can happen that the internal variable array (which get be accessed via
7511 * SCIPgetVars()) gets re-sorted.
7512 *
7513 * @note During presolving, an integer variable which bound changes to {0,1} is upgraded to a binary variable.
7514 */
7516 SCIP* scip, /**< SCIP data structure */
7517 SCIP_VAR* var, /**< variable to change the bound for */
7518 SCIP_Real fixedval, /**< new value for fixation */
7519 SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
7520 int inferinfo, /**< user information for inference to help resolving the conflict */
7521 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
7522 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
7523 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
7524 )
7525{
7526 assert(scip != NULL);
7527 assert(var != NULL);
7528 assert(infeasible != NULL);
7529
7530 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarFixProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7531
7532 if( tightened != NULL )
7533 *tightened = FALSE;
7534
7535 /* in presolving case we take the shortcut to directly fix the variables */
7537 {
7538 SCIP_Bool fixed;
7539
7540 SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
7541 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
7542 scip->cliquetable, fixedval, infeasible, &fixed) );
7543
7544 if( tightened != NULL )
7545 *tightened = fixed;
7546 }
7547 /* otherwise we use the lb and ub methods */
7548 else
7549 {
7550 SCIP_Bool lbtightened;
7551
7552 SCIP_CALL( SCIPinferVarLbProp(scip, var, fixedval, inferprop, inferinfo, force, infeasible, &lbtightened) );
7553
7554 if( ! (*infeasible) )
7555 {
7556 SCIP_CALL( SCIPinferVarUbProp(scip, var, fixedval, inferprop, inferinfo, force, infeasible, tightened) );
7557
7558 if( tightened != NULL )
7559 *tightened |= lbtightened;
7560 }
7561 }
7562
7563 return SCIP_OKAY;
7564}
7565
7566/** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
7567 * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
7568 * the given inference propagator is stored, such that the conflict analysis is able to find out the reason
7569 * for the deduction of the bound change
7570 *
7571 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
7572 * SCIPgetVars()) gets re-sorted.
7573 *
7574 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7575 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7576 *
7577 * @pre This method can be called if @p scip is in one of the following stages:
7578 * - \ref SCIP_STAGE_PROBLEM
7579 * - \ref SCIP_STAGE_PRESOLVING
7580 * - \ref SCIP_STAGE_SOLVING
7581 *
7582 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
7583 */
7585 SCIP* scip, /**< SCIP data structure */
7586 SCIP_VAR* var, /**< variable to change the bound for */
7587 SCIP_Real newbound, /**< new value for bound */
7588 SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
7589 int inferinfo, /**< user information for inference to help resolving the conflict */
7590 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
7591 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
7592 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
7593 )
7594{
7595 SCIP_Real lb;
7596 SCIP_Real ub;
7597
7598 assert(infeasible != NULL);
7599
7600 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarLbProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7601
7602 *infeasible = FALSE;
7603 if( tightened != NULL )
7604 *tightened = FALSE;
7605
7606 SCIPvarAdjustLb(var, scip->set, &newbound);
7607
7608 /* ignore tightenings of lower bounds to +infinity during solving process */
7610 {
7611#ifndef NDEBUG
7612 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
7613 SCIPvarGetLbLocal(var));
7614#endif
7615 return SCIP_OKAY;
7616 }
7617
7618 /* get current bounds */
7619 lb = SCIPvarGetLbLocal(var);
7620 ub = SCIPvarGetUbLocal(var);
7621 assert(SCIPsetIsLE(scip->set, lb, ub));
7622
7623 if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
7624 {
7625 *infeasible = TRUE;
7626 return SCIP_OKAY;
7627 }
7628 newbound = MIN(newbound, ub);
7629
7630 if( (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub))
7631 || SCIPsetIsLE(scip->set, newbound, lb) )
7632 return SCIP_OKAY;
7633
7634 switch( scip->set->stage )
7635 {
7636 case SCIP_STAGE_PROBLEM:
7637 assert(!SCIPvarIsTransformed(var));
7638 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
7639 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
7640 SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
7641 scip->branchcand, scip->eventqueue, newbound) );
7642 SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
7643 break;
7644
7646 if( !SCIPinProbing(scip) )
7647 {
7648 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
7649 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
7650
7651 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
7652 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
7653 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
7654
7656 {
7657 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
7658 assert(!(*infeasible));
7659 }
7660 break;
7661 }
7662 /*lint -fallthrough*/
7663 case SCIP_STAGE_SOLVING:
7664 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
7665 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
7666 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, NULL, inferprop, inferinfo, FALSE) );
7667 break;
7668
7669 default:
7670 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
7671 return SCIP_INVALIDCALL;
7672 } /*lint !e788*/
7673
7674 /* check whether the lower bound improved */
7675 if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
7676 *tightened = TRUE;
7677
7678 return SCIP_OKAY;
7679}
7680
7681/** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
7682 * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
7683 * the given inference propagator is stored, such that the conflict analysis is able to find out the reason
7684 * for the deduction of the bound change
7685 *
7686 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
7687 * SCIPgetVars()) gets re-sorted.
7688 *
7689 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7690 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7691 *
7692 * @pre This method can be called if @p scip is in one of the following stages:
7693 * - \ref SCIP_STAGE_PROBLEM
7694 * - \ref SCIP_STAGE_PRESOLVING
7695 * - \ref SCIP_STAGE_SOLVING
7696 *
7697 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
7698 */
7700 SCIP* scip, /**< SCIP data structure */
7701 SCIP_VAR* var, /**< variable to change the bound for */
7702 SCIP_Real newbound, /**< new value for bound */
7703 SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
7704 int inferinfo, /**< user information for inference to help resolving the conflict */
7705 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
7706 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
7707 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
7708 )
7709{
7710 SCIP_Real lb;
7711 SCIP_Real ub;
7712
7713 assert(infeasible != NULL);
7714
7715 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarUbProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7716
7717 *infeasible = FALSE;
7718 if( tightened != NULL )
7719 *tightened = FALSE;
7720
7721 SCIPvarAdjustUb(var, scip->set, &newbound);
7722
7723 /* ignore tightenings of upper bounds to -infinity during solving process */
7724 if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
7725 {
7726#ifndef NDEBUG
7727 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
7728 SCIPvarGetUbLocal(var));
7729#endif
7730 return SCIP_OKAY;
7731 }
7732
7733 /* get current bounds */
7734 lb = SCIPvarGetLbLocal(var);
7735 ub = SCIPvarGetUbLocal(var);
7736 assert(SCIPsetIsLE(scip->set, lb, ub));
7737
7738 if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
7739 {
7740 *infeasible = TRUE;
7741 return SCIP_OKAY;
7742 }
7743 newbound = MAX(newbound, lb);
7744
7745 if( (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub))
7746 || SCIPsetIsGE(scip->set, newbound, ub) )
7747 return SCIP_OKAY;
7748
7749 switch( scip->set->stage )
7750 {
7751 case SCIP_STAGE_PROBLEM:
7752 assert(!SCIPvarIsTransformed(var));
7753 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
7754 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
7755 SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
7756 scip->branchcand, scip->eventqueue, newbound) );
7757 SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
7758 break;
7759
7761 if( !SCIPinProbing(scip) )
7762 {
7763 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
7764 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
7765
7766 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
7767 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
7768 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
7769
7771 {
7772 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
7773 assert(!(*infeasible));
7774 }
7775 break;
7776 }
7777 /*lint -fallthrough*/
7778 case SCIP_STAGE_SOLVING:
7779 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
7780 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
7781 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, NULL, inferprop, inferinfo, FALSE) );
7782 break;
7783
7784 default:
7785 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
7786 return SCIP_INVALIDCALL;
7787 } /*lint !e788*/
7788
7789 /* check whether the upper bound improved */
7790 if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
7791 *tightened = TRUE;
7792
7793 return SCIP_OKAY;
7794}
7795
7796/** depending on SCIP's stage, fixes binary variable in the problem, in preprocessing, or in current node;
7797 * the given inference propagator is stored, such that the conflict analysis is able to find out the reason for the
7798 * deduction of the fixing
7799 *
7800 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7801 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7802 *
7803 * @pre This method can be called if @p scip is in one of the following stages:
7804 * - \ref SCIP_STAGE_PROBLEM
7805 * - \ref SCIP_STAGE_PRESOLVING
7806 * - \ref SCIP_STAGE_PRESOLVED
7807 * - \ref SCIP_STAGE_SOLVING
7808 */
7810 SCIP* scip, /**< SCIP data structure */
7811 SCIP_VAR* var, /**< binary variable to fix */
7812 SCIP_Bool fixedval, /**< value to fix binary variable to */
7813 SCIP_PROP* inferprop, /**< propagator that deduced the fixing */
7814 int inferinfo, /**< user information for inference to help resolving the conflict */
7815 SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
7816 SCIP_Bool* tightened /**< pointer to store whether the fixing tightened the local bounds, or NULL */
7817 )
7818{
7819 SCIP_Real lb;
7820 SCIP_Real ub;
7821
7822 assert(SCIPvarIsBinary(var));
7823 assert(fixedval == TRUE || fixedval == FALSE);
7824 assert(infeasible != NULL);
7825
7826 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferBinvarProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7827
7828 *infeasible = FALSE;
7829 if( tightened != NULL )
7830 *tightened = FALSE;
7831
7832 /* get current bounds */
7833 lb = SCIPvarGetLbLocal(var);
7834 ub = SCIPvarGetUbLocal(var);
7835 assert(SCIPsetIsEQ(scip->set, lb, 0.0) || SCIPsetIsEQ(scip->set, lb, 1.0));
7836 assert(SCIPsetIsEQ(scip->set, ub, 0.0) || SCIPsetIsEQ(scip->set, ub, 1.0));
7837 assert(SCIPsetIsLE(scip->set, lb, ub));
7838
7839 /* check, if variable is already fixed */
7840 if( (lb > 0.5) || (ub < 0.5) )
7841 {
7842 *infeasible = (fixedval == (lb < 0.5));
7843
7844 return SCIP_OKAY;
7845 }
7846
7847 /* apply the fixing */
7848 switch( scip->set->stage )
7849 {
7850 case SCIP_STAGE_PROBLEM:
7851 assert(!SCIPvarIsTransformed(var));
7852 if( fixedval == TRUE )
7853 {
7854 SCIP_CALL( SCIPchgVarLb(scip, var, 1.0) );
7855 }
7856 else
7857 {
7858 SCIP_CALL( SCIPchgVarUb(scip, var, 0.0) );
7859 }
7860 break;
7861
7863 if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
7864 {
7865 SCIP_Bool fixed;
7866
7867 SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
7868 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
7869 scip->cliquetable, (SCIP_Real)fixedval, infeasible, &fixed) );
7870 break;
7871 }
7872 /*lint -fallthrough*/
7873 case SCIP_STAGE_SOLVING:
7874 if( fixedval == TRUE )
7875 {
7876 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
7877 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
7878 scip->eventfilter, scip->cliquetable, var, 1.0, SCIP_BOUNDTYPE_LOWER, NULL, inferprop, inferinfo, FALSE) );
7879 }
7880 else
7881 {
7882 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
7883 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
7884 scip->eventfilter, scip->cliquetable, var, 0.0, SCIP_BOUNDTYPE_UPPER, NULL, inferprop, inferinfo, FALSE) );
7885 }
7886 break;
7887
7888 default:
7889 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
7890 return SCIP_INVALIDCALL;
7891 } /*lint !e788*/
7892
7893 if( tightened != NULL )
7894 *tightened = TRUE;
7895
7896 return SCIP_OKAY;
7897}
7898
7899/** exact submethod of SCIPtightenVarLbGlobal(); it does not check for the stage */
7900static
7902 SCIP* scip, /**< SCIP data structure */
7903 SCIP_VAR* var, /**< variable to change the bound for */
7904 SCIP_Real newbound, /**< new value for bound */
7905 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
7906 SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
7907 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
7908 )
7909{
7910 SCIP_Real lb;
7911 SCIP_Real ub;
7912 SCIP_RATIONAL* newboundexact;
7913
7914 assert(infeasible != NULL);
7915
7916 *infeasible = FALSE;
7917 if( tightened != NULL )
7918 *tightened = FALSE;
7919
7920 SCIPvarAdjustLbExactFloat(var, scip->set, &newbound);
7921
7922 /* ignore tightenings of lower bounds to +infinity during solving process */
7924 {
7925#ifndef NDEBUG
7926 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
7927 SCIPvarGetLbLocal(var));
7928#endif
7929 return SCIP_OKAY;
7930 }
7931
7932 /* get current bounds */
7933 lb = SCIPvarGetLbGlobal(var);
7934 ub = SCIPvarGetUbGlobal(var);
7935 assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPsetIsLE(scip->set, lb, ub));
7936
7937 if( newbound > ub )
7938 {
7939 *infeasible = TRUE;
7940 return SCIP_OKAY;
7941 }
7942 newbound = MIN(newbound, ub);
7943
7944 /* bound changes of less than epsilon are ignored by SCIPvarChgLb or raise an assert in SCIPnodeAddBoundinfer,
7945 * so don't apply them even if force is set
7946 */
7947 if( SCIPsetIsEQ(scip->set, lb, newbound) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
7948 return SCIP_OKAY;
7949
7951 SCIPrationalSetReal(newboundexact, newbound);
7952
7953 switch( scip->set->stage )
7954 {
7955 case SCIP_STAGE_PROBLEM:
7956 assert(!SCIPvarIsTransformed(var));
7957 SCIP_CALL( SCIPvarChgLbGlobalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
7958 scip->branchcand, scip->eventqueue, scip->cliquetable, newboundexact) );
7959 SCIP_CALL( SCIPvarChgLbLocalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
7960 scip->branchcand, scip->eventqueue, newboundexact) );
7961 SCIP_CALL( SCIPvarChgLbOriginalExact(var, scip->set, newboundexact) );
7962 break;
7963
7965 SCIP_CALL( SCIPvarChgLbGlobalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
7966 scip->branchcand, scip->eventqueue, scip->cliquetable, newboundexact) );
7967 break;
7968
7970 if( !SCIPinProbing(scip) )
7971 {
7972 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
7973 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
7974
7975 SCIP_CALL( SCIPnodeAddBoundchgExact(scip->tree->root, scip->mem->probmem, scip->set, scip->stat,
7976 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lpexact, scip->branchcand,
7977 scip->eventqueue, scip->eventfilter, scip->cliquetable, var, newboundexact, SCIP_BOUNDTYPE_LOWER,
7978 FALSE) );
7979
7981 {
7982 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
7983 assert(!(*infeasible));
7984 }
7985 break;
7986 }
7987 /*lint -fallthrough*/
7988 case SCIP_STAGE_SOLVING:
7989 SCIP_CALL( SCIPnodeAddBoundchgExact(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
7990 scip->origprob, scip->tree, scip->reopt, scip->lpexact, scip->branchcand, scip->eventqueue,
7991 scip->eventfilter, scip->cliquetable, var, newboundexact, SCIP_BOUNDTYPE_LOWER, FALSE) );
7992 break;
7993
7994 default:
7995 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
7996 return SCIP_INVALIDCALL;
7997 } /*lint !e788*/
7998
7999 /* coverity: unreachable code */
8000 if( tightened != NULL && lb < SCIPcomputeVarLbGlobal(scip, var) )
8001 *tightened = TRUE;
8002
8003 SCIPrationalFreeBuffer(SCIPbuffer(scip), &newboundexact);
8004
8005 return SCIP_OKAY;
8006}
8007
8008/** changes global lower bound of variable in preprocessing or in the current node, if the new bound is tighter
8009 * (w.r.t. bound strengthening epsilon) than the current global bound; if possible, adjusts bound to integral value;
8010 * also tightens the local bound, if the global bound is better than the local bound
8011 *
8012 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
8013 * SCIPgetVars()) gets re-sorted.
8014 *
8015 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8016 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8017 *
8018 * @pre This method can be called if @p scip is in one of the following stages:
8019 * - \ref SCIP_STAGE_PROBLEM
8020 * - \ref SCIP_STAGE_TRANSFORMING
8021 * - \ref SCIP_STAGE_PRESOLVING
8022 * - \ref SCIP_STAGE_SOLVING
8023 *
8024 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
8025 */
8027 SCIP* scip, /**< SCIP data structure */
8028 SCIP_VAR* var, /**< variable to change the bound for */
8029 SCIP_Real newbound, /**< new value for bound */
8030 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
8031 SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
8032 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
8033 )
8034{
8035 SCIP_Real lb;
8036 SCIP_Real ub;
8037
8038 assert(infeasible != NULL);
8039
8040 SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarLbGlobal", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8041
8042 if( SCIPisExact(scip) )
8043 return tightenVarLbGlobalSafe(scip, var, newbound, force, infeasible, tightened);
8044
8045 *infeasible = FALSE;
8046 if( tightened != NULL )
8047 *tightened = FALSE;
8048
8049 SCIPvarAdjustLb(var, scip->set, &newbound);
8050
8051 /* ignore tightenings of lower bounds to +infinity during solving process */
8053 {
8054#ifndef NDEBUG
8055 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
8056 SCIPvarGetLbLocal(var));
8057#endif
8058 return SCIP_OKAY;
8059 }
8060
8061 /* get current bounds */
8062 lb = SCIPvarGetLbGlobal(var);
8063 ub = SCIPvarGetUbGlobal(var);
8064 assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPsetIsLE(scip->set, lb, ub));
8065
8066 if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
8067 {
8068 *infeasible = TRUE;
8069 return SCIP_OKAY;
8070 }
8071 newbound = MIN(newbound, ub);
8072
8073 /* bound changes of less than epsilon are ignored by SCIPvarChgLb or raise an assert in SCIPnodeAddBoundinfer,
8074 * so don't apply them even if force is set
8075 */
8076 if( SCIPsetIsEQ(scip->set, lb, newbound) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
8077 return SCIP_OKAY;
8078
8079 switch( scip->set->stage )
8080 {
8081 case SCIP_STAGE_PROBLEM:
8082 assert(!SCIPvarIsTransformed(var));
8083 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
8084 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
8085 SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
8086 scip->branchcand, scip->eventqueue, newbound) );
8087 SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
8088 break;
8089
8091 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
8092 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
8093 break;
8094
8096 if( !SCIPinProbing(scip) )
8097 {
8098 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
8099 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
8100
8101 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
8102 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
8103 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
8104
8106 {
8107 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
8108 assert(!(*infeasible));
8109 }
8110 break;
8111 }
8112 /*lint -fallthrough*/
8113 case SCIP_STAGE_SOLVING:
8114 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
8115 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
8116 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
8117 break;
8118
8119 default:
8120 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
8121 return SCIP_INVALIDCALL;
8122 } /*lint !e788*/
8123
8124 /* coverity: unreachable code */
8125 if( tightened != NULL && lb < SCIPcomputeVarLbGlobal(scip, var) )
8126 *tightened = TRUE;
8127
8128 return SCIP_OKAY;
8129}
8130
8131/** */
8132static
8134 SCIP* scip, /**< SCIP data structure */
8135 SCIP_VAR* var, /**< variable to change the bound for */
8136 SCIP_Real newbound, /**< new value for bound */
8137 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
8138 SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
8139 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
8140 )
8141{
8142 SCIP_Real lb;
8143 SCIP_Real ub;
8144 SCIP_RATIONAL* newboundexact;
8145
8146 assert(infeasible != NULL);
8147
8148 *infeasible = FALSE;
8149 if( tightened != NULL )
8150 *tightened = FALSE;
8151
8152 SCIPvarAdjustUbExactFloat(var, scip->set, &newbound);
8153
8154 /* ignore tightenings of upper bounds to -infinity during solving process */
8155 if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
8156 {
8157#ifndef NDEBUG
8158 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
8159 SCIPvarGetUbLocal(var));
8160#endif
8161 return SCIP_OKAY;
8162 }
8163
8164 /* get current bounds */
8165 lb = SCIPvarGetLbGlobal(var);
8166 ub = SCIPvarGetUbGlobal(var);
8167 assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPsetIsLE(scip->set, lb, ub));
8168
8169 if( newbound < lb )
8170 {
8171 *infeasible = TRUE;
8172 return SCIP_OKAY;
8173 }
8174 newbound = MAX(newbound, lb);
8175
8176 /* bound changes of less than epsilon are ignored by SCIPvarChgUb or raise an assert in SCIPnodeAddBoundinfer,
8177 * so don't apply them even if force is set
8178 */
8179 if( SCIPsetIsEQ(scip->set, ub, newbound) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
8180 return SCIP_OKAY;
8181
8183 SCIPrationalSetReal(newboundexact, newbound);
8184
8185 switch( scip->set->stage )
8186 {
8187 case SCIP_STAGE_PROBLEM:
8188 assert(!SCIPvarIsTransformed(var));
8189 SCIP_CALL( SCIPvarChgUbGlobalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
8190 scip->branchcand, scip->eventqueue, scip->cliquetable, newboundexact) );
8191 SCIP_CALL( SCIPvarChgUbLocalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
8192 scip->branchcand, scip->eventqueue, newboundexact) );
8193 SCIP_CALL( SCIPvarChgUbOriginalExact(var, scip->set, newboundexact) );
8194 break;
8195
8197 SCIP_CALL( SCIPvarChgUbGlobalExact(var, scip->mem->probmem, scip->set, scip->stat, scip->lpexact,
8198 scip->branchcand, scip->eventqueue, scip->cliquetable, newboundexact) );
8199 break;
8200
8202 if( !SCIPinProbing(scip) )
8203 {
8204 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
8205 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
8206
8207 SCIP_CALL( SCIPnodeAddBoundchgExact(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
8208 scip->origprob, scip->tree, scip->reopt, scip->lpexact, scip->branchcand, scip->eventqueue,
8209 scip->eventfilter, scip->cliquetable, var, newboundexact, SCIP_BOUNDTYPE_UPPER, FALSE) );
8210
8212 {
8213 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
8214 assert(!(*infeasible));
8215 }
8216 break;
8217 }
8218 /*lint -fallthrough*/
8219 case SCIP_STAGE_SOLVING:
8220 SCIP_CALL( SCIPnodeAddBoundchgExact(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
8221 scip->origprob, scip->tree, scip->reopt, scip->lpexact, scip->branchcand, scip->eventqueue,
8222 scip->eventfilter, scip->cliquetable, var, newboundexact, SCIP_BOUNDTYPE_UPPER, FALSE) );
8223 break;
8224
8225 default:
8226 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
8227 return SCIP_INVALIDCALL;
8228 } /*lint !e788*/
8229
8230 /* coverity: unreachable code */
8231 if( tightened != NULL && ub > SCIPcomputeVarUbGlobal(scip, var) )
8232 *tightened = TRUE;
8233
8234 SCIPrationalFreeBuffer(SCIPbuffer(scip), &newboundexact);
8235
8236 return SCIP_OKAY;
8237}
8238
8239/** changes global upper bound of variable in preprocessing or in the current node, if the new bound is tighter
8240 * (w.r.t. bound strengthening epsilon) than the current global bound; if possible, adjusts bound to integral value;
8241 * also tightens the local bound, if the global bound is better than the local bound
8242 *
8243 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
8244 * SCIPgetVars()) gets re-sorted.
8245 *
8246 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8247 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8248 *
8249 * @pre This method can be called if @p scip is in one of the following stages:
8250 * - \ref SCIP_STAGE_PROBLEM
8251 * - \ref SCIP_STAGE_TRANSFORMING
8252 * - \ref SCIP_STAGE_PRESOLVING
8253 * - \ref SCIP_STAGE_SOLVING
8254 *
8255 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
8256 */
8258 SCIP* scip, /**< SCIP data structure */
8259 SCIP_VAR* var, /**< variable to change the bound for */
8260 SCIP_Real newbound, /**< new value for bound */
8261 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
8262 SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
8263 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
8264 )
8265{
8266 SCIP_Real lb;
8267 SCIP_Real ub;
8268
8269 assert(infeasible != NULL);
8270
8271 SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarUbGlobal", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8272
8273 if( SCIPisExact(scip) )
8274 return tightenVarUbGlobalSafe(scip, var, newbound, force, infeasible, tightened);
8275
8276 *infeasible = FALSE;
8277 if( tightened != NULL )
8278 *tightened = FALSE;
8279
8280 SCIPvarAdjustUb(var, scip->set, &newbound);
8281
8282 /* ignore tightenings of upper bounds to -infinity during solving process */
8283 if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
8284 {
8285#ifndef NDEBUG
8286 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
8287 SCIPvarGetUbLocal(var));
8288#endif
8289 return SCIP_OKAY;
8290 }
8291
8292 /* get current bounds */
8293 lb = SCIPvarGetLbGlobal(var);
8294 ub = SCIPvarGetUbGlobal(var);
8295 assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPsetIsLE(scip->set, lb, ub));
8296
8297 if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
8298 {
8299 *infeasible = TRUE;
8300 return SCIP_OKAY;
8301 }
8302 newbound = MAX(newbound, lb);
8303
8304 /* bound changes of less than epsilon are ignored by SCIPvarChgUb or raise an assert in SCIPnodeAddBoundinfer,
8305 * so don't apply them even if force is set
8306 */
8307 if( SCIPsetIsEQ(scip->set, ub, newbound) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
8308 return SCIP_OKAY;
8309
8310 switch( scip->set->stage )
8311 {
8312 case SCIP_STAGE_PROBLEM:
8313 assert(!SCIPvarIsTransformed(var));
8314 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
8315 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
8316 SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
8317 scip->branchcand, scip->eventqueue, newbound) );
8318 SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
8319 break;
8320
8322 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
8323 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
8324 break;
8325
8327 if( !SCIPinProbing(scip) )
8328 {
8329 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
8330 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
8331
8332 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
8333 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
8334 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
8335
8337 {
8338 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
8339 assert(!(*infeasible));
8340 }
8341 break;
8342 }
8343 /*lint -fallthrough*/
8344 case SCIP_STAGE_SOLVING:
8345 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
8346 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
8347 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
8348 break;
8349
8350 default:
8351 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
8352 return SCIP_INVALIDCALL;
8353 } /*lint !e788*/
8354
8355 /* coverity: unreachable code */
8356 if( tightened != NULL && ub > SCIPcomputeVarUbGlobal(scip, var) )
8357 *tightened = TRUE;
8358
8359 return SCIP_OKAY;
8360}
8361
8362/* some simple variable functions implemented as defines */
8363#undef SCIPcomputeVarLbGlobal
8364#undef SCIPcomputeVarUbGlobal
8365#undef SCIPcomputeVarLbLocal
8366#undef SCIPcomputeVarUbLocal
8367
8368/** for a multi-aggregated variable, returns the global lower bound computed by adding the global bounds from all aggregation variables
8369 *
8370 * This global bound may be tighter than the one given by SCIPvarGetLbGlobal, since the latter is not updated if bounds of aggregation variables are changing
8371 * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetLbGlobal.
8372 *
8373 * @return the global lower bound computed by adding the global bounds from all aggregation variables
8374 */
8376 SCIP* scip, /**< SCIP data structure */
8377 SCIP_VAR* var /**< variable to compute the bound for */
8378 )
8379{
8380 assert(scip != NULL);
8381 assert(var != NULL);
8382
8384 return SCIPvarGetMultaggrLbGlobal(var, scip->set);
8385 else
8386 return SCIPvarGetLbGlobal(var);
8387}
8388
8389/** for a multi-aggregated variable, returns the global upper bound computed by adding the global bounds from all aggregation variables
8390 *
8391 * This global bound may be tighter than the one given by SCIPvarGetUbGlobal, since the latter is not updated if bounds of aggregation variables are changing
8392 * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetUbGlobal
8393 *
8394 * @return the global upper bound computed by adding the global bounds from all aggregation variables
8395 */
8397 SCIP* scip, /**< SCIP data structure */
8398 SCIP_VAR* var /**< variable to compute the bound for */
8399 )
8400{
8401 assert(scip != NULL);
8402 assert(var != NULL);
8403
8405 return SCIPvarGetMultaggrUbGlobal(var, scip->set);
8406 else
8407 return SCIPvarGetUbGlobal(var);
8408}
8409
8410/** for a multi-aggregated variable, returns the local lower bound computed by adding the local bounds from all aggregation variables
8411 *
8412 * This local bound may be tighter than the one given by SCIPvarGetLbLocal, since the latter is not updated if bounds of aggregation variables are changing
8413 * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetLbLocal.
8414 *
8415 * @return the local lower bound computed by adding the global bounds from all aggregation variables
8416 */
8418 SCIP* scip, /**< SCIP data structure */
8419 SCIP_VAR* var /**< variable to compute the bound for */
8420 )
8421{
8422 assert(scip != NULL);
8423 assert(var != NULL);
8424
8426 return SCIPvarGetMultaggrLbLocal(var, scip->set);
8427 else
8428 return SCIPvarGetLbLocal(var);
8429}
8430
8431/** for a multi-aggregated variable, returns the local lower bound computed by adding the local bounds from all aggregation variables
8432 *
8433 * This local bound may be tighter than the one given by SCIPvarGetLbLocal, since the latter is not updated if bounds of aggregation variables are changing
8434 * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetLbLocal.
8435 *
8436 * @return the local lower bound computed by adding the global bounds from all aggregation variables
8437 */
8439 SCIP* scip, /**< SCIP data structure */
8440 SCIP_VAR* var, /**< variable to compute the bound for */
8441 SCIP_RATIONAL* result /**< rational to store the resulting bound */
8442 )
8443{
8444 assert(scip != NULL);
8445 assert(var != NULL);
8446
8448 SCIP_CALL( SCIPvarGetMultaggrLbLocalExact(var, scip->set, result) );
8449 else
8451
8452 return SCIP_OKAY;
8453}
8454
8455/** for a multi-aggregated variable, returns the local upper bound computed by adding the local bounds from all aggregation variables
8456 *
8457 * This local bound may be tighter than the one given by SCIPvarGetUbLocal, since the latter is not updated if bounds of aggregation variables are changing
8458 * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetUbLocal.
8459 *
8460 * @return the local upper bound computed by adding the global bounds from all aggregation variables
8461 */
8463 SCIP* scip, /**< SCIP data structure */
8464 SCIP_VAR* var /**< variable to compute the bound for */
8465 )
8466{
8467 assert(scip != NULL);
8468 assert(var != NULL);
8469
8471 return SCIPvarGetMultaggrUbLocal(var, scip->set);
8472 else
8473 return SCIPvarGetUbLocal(var);
8474}
8475
8476/** for a multi-aggregated variable, returns the local upper bound computed by adding the local bounds from all aggregation variables
8477 *
8478 * This local bound may be tighter than the one given by SCIPvarGetUbLocal, since the latter is not updated if bounds of aggregation variables are changing
8479 * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetUbLocal.
8480 *
8481 * @return the local upper bound computed by adding the global bounds from all aggregation variables
8482 */
8484 SCIP* scip, /**< SCIP data structure */
8485 SCIP_VAR* var, /**< variable to compute the bound for */
8486 SCIP_RATIONAL* result /**< rational to store the resulting bound */
8487 )
8488{
8489 assert(scip != NULL);
8490 assert(var != NULL);
8491
8493 SCIP_CALL( SCIPvarGetMultaggrUbLocalExact(var, scip->set, result) );
8494 else
8496
8497 return SCIP_OKAY;
8498}
8499
8500/** for a multi-aggregated variable, gives the global lower bound computed by adding the global bounds from all
8501 * aggregation variables, this global bound may be tighter than the one given by SCIPvarGetLbGlobal, since the latter is
8502 * not updated if bounds of aggregation variables are changing
8503 *
8504 * calling this function for a non-multi-aggregated variable is not allowed
8505 */
8507 SCIP* scip, /**< SCIP data structure */
8508 SCIP_VAR* var /**< variable to compute the bound for */
8509 )
8510{
8512 return SCIPvarGetMultaggrLbGlobal(var, scip->set);
8513}
8514
8515/** for a multi-aggregated variable, gives the global upper bound computed by adding the global bounds from all
8516 * aggregation variables, this upper bound may be tighter than the one given by SCIPvarGetUbGlobal, since the latter is
8517 * not updated if bounds of aggregation variables are changing
8518 *
8519 * calling this function for a non-multi-aggregated variable is not allowed
8520 */
8522 SCIP* scip, /**< SCIP data structure */
8523 SCIP_VAR* var /**< variable to compute the bound for */
8524 )
8525{
8527 return SCIPvarGetMultaggrUbGlobal(var, scip->set);
8528}
8529
8530/** for a multi-aggregated variable, gives the local lower bound computed by adding the local bounds from all
8531 * aggregation variables, this lower bound may be tighter than the one given by SCIPvarGetLbLocal, since the latter is
8532 * not updated if bounds of aggregation variables are changing
8533 *
8534 * calling this function for a non-multi-aggregated variable is not allowed
8535 */
8537 SCIP* scip, /**< SCIP data structure */
8538 SCIP_VAR* var /**< variable to compute the bound for */
8539 )
8540{
8542 return SCIPvarGetMultaggrLbLocal(var, scip->set);
8543}
8544
8545/** for a multi-aggregated variable, gives the local upper bound computed by adding the local bounds from all
8546 * aggregation variables, this upper bound may be tighter than the one given by SCIPvarGetUbLocal, since the latter is
8547 * not updated if bounds of aggregation variables are changing
8548 *
8549 * calling this function for a non-multi-aggregated variable is not allowed
8550 */
8552 SCIP* scip, /**< SCIP data structure */
8553 SCIP_VAR* var /**< variable to compute the bound for */
8554 )
8555{
8557 return SCIPvarGetMultaggrUbLocal(var, scip->set);
8558}
8559
8560/** returns solution value and index of variable lower bound that is closest to the variable's value in the given primal
8561 * solution or current LP solution if no primal solution is given; returns an index of -1 if no variable lower bound is
8562 * available
8563 *
8564 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8565 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8566 *
8567 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
8568 */
8570 SCIP* scip, /**< SCIP data structure */
8571 SCIP_VAR* var, /**< active problem variable */
8572 SCIP_SOL* sol, /**< primal solution, or NULL for LP solution */
8573 SCIP_Real* closestvlb, /**< pointer to store the value of the closest variable lower bound */
8574 int* closestvlbidx /**< pointer to store the index of the closest variable lower bound */
8575 )
8576{
8577 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarClosestVlb", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8578
8579 SCIPvarGetClosestVlb(var, sol, scip->set, scip->stat, closestvlb, closestvlbidx);
8580
8581 return SCIP_OKAY;
8582}
8583
8584/** returns solution value and index of variable upper bound that is closest to the variable's value in the given primal solution;
8585 * or current LP solution if no primal solution is given; returns an index of -1 if no variable upper bound is available
8586 *
8587 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8588 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8589 *
8590 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
8591 */
8593 SCIP* scip, /**< SCIP data structure */
8594 SCIP_VAR* var, /**< active problem variable */
8595 SCIP_SOL* sol, /**< primal solution, or NULL for LP solution */
8596 SCIP_Real* closestvub, /**< pointer to store the value of the closest variable lower bound */
8597 int* closestvubidx /**< pointer to store the index of the closest variable lower bound */
8598 )
8599{
8600 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarClosestVub", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8601
8602 SCIPvarGetClosestVub(var, sol, scip->set, scip->stat, closestvub, closestvubidx);
8603
8604 return SCIP_OKAY;
8605}
8606
8607/** informs variable x about a globally valid variable lower bound x >= b*z + d with integer variable z;
8608 * if z is binary, the corresponding valid implication for z is also added;
8609 * if z is non-continuous and 1/b not too small, the corresponding valid upper/lower bound
8610 * z <= (x-d)/b or z >= (x-d)/b (depending on the sign of of b) is added, too;
8611 * improves the global bounds of the variable and the vlb variable if possible
8612 *
8613 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8614 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8615 *
8616 * @pre This method can be called if @p scip is in one of the following stages:
8617 * - \ref SCIP_STAGE_PRESOLVING
8618 * - \ref SCIP_STAGE_PRESOLVED
8619 * - \ref SCIP_STAGE_SOLVING
8620 */
8622 SCIP* scip, /**< SCIP data structure */
8623 SCIP_VAR* var, /**< problem variable */
8624 SCIP_VAR* vlbvar, /**< variable z in x >= b*z + d */
8625 SCIP_Real vlbcoef, /**< coefficient b in x >= b*z + d */
8626 SCIP_Real vlbconstant, /**< constant d in x >= b*z + d */
8627 SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
8628 int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
8629 )
8630{
8631 int nlocalbdchgs;
8632
8634
8635 SCIP_CALL( SCIPvarAddVlb(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->tree,
8636 scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, scip->eventfilter, vlbvar, vlbcoef,
8637 vlbconstant, TRUE, infeasible, &nlocalbdchgs) );
8638
8639 *nbdchgs = nlocalbdchgs;
8640
8641 /* if x is not continuous we add a variable bound for z; do not add it if cofficient would be too small or we already
8642 * detected infeasibility
8643 */
8644 if( !(*infeasible) && SCIPvarIsIntegral(var) && !SCIPisZero(scip, 1.0/vlbcoef) )
8645 {
8646 if( vlbcoef > 0.0 )
8647 {
8648 /* if b > 0, we have a variable upper bound: x >= b*z + d => z <= (x-d)/b */
8649 SCIP_CALL( SCIPvarAddVub(vlbvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8650 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, scip->eventfilter,
8651 var, 1.0/vlbcoef, -vlbconstant/vlbcoef, TRUE, infeasible, &nlocalbdchgs) );
8652 }
8653 else
8654 {
8655 /* if b < 0, we have a variable lower bound: x >= b*z + d => z >= (x-d)/b */
8656 SCIP_CALL( SCIPvarAddVlb(vlbvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8657 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, scip->eventfilter,
8658 var, 1.0/vlbcoef, -vlbconstant/vlbcoef, TRUE, infeasible, &nlocalbdchgs) );
8659 }
8660 *nbdchgs += nlocalbdchgs;
8661 }
8662
8663 return SCIP_OKAY;
8664}
8665
8666/** informs variable x about a globally valid variable upper bound x <= b*z + d with integer variable z;
8667 * if z is binary, the corresponding valid implication for z is also added;
8668 * if z is non-continuous and 1/b not too small, the corresponding valid lower/upper bound
8669 * z >= (x-d)/b or z <= (x-d)/b (depending on the sign of of b) is added, too;
8670 * improves the global bounds of the variable and the vlb variable if possible
8671 *
8672 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8673 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8674 *
8675 * @pre This method can be called if @p scip is in one of the following stages:
8676 * - \ref SCIP_STAGE_PRESOLVING
8677 * - \ref SCIP_STAGE_PRESOLVED
8678 * - \ref SCIP_STAGE_SOLVING
8679 */
8681 SCIP* scip, /**< SCIP data structure */
8682 SCIP_VAR* var, /**< problem variable */
8683 SCIP_VAR* vubvar, /**< variable z in x <= b*z + d */
8684 SCIP_Real vubcoef, /**< coefficient b in x <= b*z + d */
8685 SCIP_Real vubconstant, /**< constant d in x <= b*z + d */
8686 SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
8687 int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
8688 )
8689{
8690 int nlocalbdchgs;
8691
8693
8694 SCIP_CALL( SCIPvarAddVub(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->tree,
8695 scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, scip->eventfilter, vubvar, vubcoef,
8696 vubconstant, TRUE, infeasible, &nlocalbdchgs) );
8697
8698 *nbdchgs = nlocalbdchgs;
8699
8700 /* if x is not continuous we add a variable bound for z; do not add it if cofficient would be too small or we already
8701 * detected infeasibility
8702 */
8703 if( !(*infeasible) && SCIPvarIsIntegral(var) && !SCIPisZero(scip, 1.0/vubcoef) )
8704 {
8705 if( vubcoef > 0.0 )
8706 {
8707 /* if b < 0, we have a variable lower bound: x >= b*z + d => z >= (x-d)/b */
8708 SCIP_CALL( SCIPvarAddVlb(vubvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8709 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, scip->eventfilter,
8710 var, 1.0/vubcoef, -vubconstant/vubcoef, TRUE, infeasible, &nlocalbdchgs) );
8711 }
8712 else
8713 {
8714 /* if b > 0, we have a variable upper bound: x >= b*z + d => z <= (x-d)/b */
8715 SCIP_CALL( SCIPvarAddVub(vubvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8716 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, scip->eventfilter,
8717 var, 1.0/vubcoef, -vubconstant/vubcoef, TRUE, infeasible, &nlocalbdchgs) );
8718 }
8719 *nbdchgs += nlocalbdchgs;
8720 }
8721
8722 return SCIP_OKAY;
8723}
8724
8725/** informs binary variable x about a globally valid implication: x == 0 or x == 1 ==> y <= b or y >= b;
8726 * also adds the corresponding implication or variable bound to the implied variable;
8727 * if the implication is conflicting, the variable is fixed to the opposite value;
8728 * if the variable is already fixed to the given value, the implication is performed immediately;
8729 * if the implication is redundant with respect to the variables' global bounds, it is ignored
8730 *
8731 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8732 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8733 *
8734 * @pre This method can be called if @p scip is in one of the following stages:
8735 * - \ref SCIP_STAGE_TRANSFORMED
8736 * - \ref SCIP_STAGE_PRESOLVING
8737 * - \ref SCIP_STAGE_PRESOLVED
8738 * - \ref SCIP_STAGE_SOLVING
8739 */
8741 SCIP* scip, /**< SCIP data structure */
8742 SCIP_VAR* var, /**< problem variable */
8743 SCIP_Bool varfixing, /**< FALSE if y should be added in implications for x == 0, TRUE for x == 1 */
8744 SCIP_VAR* implvar, /**< variable y in implication y <= b or y >= b */
8745 SCIP_BOUNDTYPE impltype, /**< type of implication y <= b (SCIP_BOUNDTYPE_UPPER)
8746 * or y >= b (SCIP_BOUNDTYPE_LOWER) */
8747 SCIP_Real implbound, /**< bound b in implication y <= b or y >= b */
8748 SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
8749 int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
8750 )
8751{
8752 SCIP_VAR* implprobvar;
8753
8754 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarImplication", FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8755
8756 assert(infeasible != NULL);
8757 *infeasible = FALSE;
8758
8759 if ( nbdchgs != NULL )
8760 *nbdchgs = 0;
8761
8762 if( !SCIPvarIsBinary(var) )
8763 {
8764 SCIPerrorMessage("can't add implication for nonbinary variable\n");
8765 return SCIP_INVALIDDATA;
8766 }
8767
8768 implprobvar = SCIPvarGetProbvar(implvar);
8769 /* transform implication containing two binary variables to a clique; the condition ensures that the active representative
8770 * of implvar is actually binary
8771 */
8772 if( SCIPvarIsBinary(implvar) && (SCIPvarIsActive(implvar) || (implprobvar != NULL && SCIPvarIsBinary(implprobvar))) )
8773 {
8774 assert(SCIPisFeasEQ(scip, implbound, 1.0) || SCIPisFeasZero(scip, implbound));
8775 assert((impltype == SCIP_BOUNDTYPE_UPPER) == SCIPisFeasZero(scip, implbound));
8776
8777 /* only add clique if implication is not redundant with respect to global bounds of the implication variable */
8778 if( (impltype == SCIP_BOUNDTYPE_LOWER && SCIPvarGetLbGlobal(implvar) < 0.5) ||
8779 (impltype == SCIP_BOUNDTYPE_UPPER && SCIPvarGetUbGlobal(implvar) > 0.5) )
8780 {
8781 SCIP_VAR* vars[2];
8782 SCIP_Bool vals[2];
8783
8784 vars[0] = var;
8785 vars[1] = implvar;
8786 vals[0] = varfixing;
8787 vals[1] = (impltype == SCIP_BOUNDTYPE_UPPER);
8788
8789 SCIP_CALL( SCIPaddClique(scip, vars, vals, 2, FALSE, infeasible, nbdchgs) );
8790 }
8791
8792 return SCIP_OKAY;
8793 }
8794
8795 /* the implication graph can only handle 'real' binary (SCIP_VARTYPE_BINARY) variables, therefore we transform the
8796 * implication in variable bounds, (lowerbound of y will be abbreviated by lby, upperbound equivalent) the following
8797 * four cases are:
8798 *
8799 * 1. (x >= 1 => y >= b) => y >= (b - lby) * x + lby
8800 * 2. (x >= 1 => y <= b) => y <= (b - uby) * x + uby
8801 * 3. (x <= 0 => y >= b) => y >= (lby - b) * x + b
8802 * 4. (x <= 0 => y <= b) => y <= (uby - b) * x + b
8803 */
8804 /* TODO: check how this works with implied binaries */
8806 {
8807 SCIP_Real lby;
8808 SCIP_Real uby;
8809
8810 lby = SCIPvarGetLbGlobal(implvar);
8811 uby = SCIPvarGetUbGlobal(implvar);
8812
8813 if( varfixing == TRUE )
8814 {
8815 if( impltype == SCIP_BOUNDTYPE_LOWER )
8816 {
8817 /* we return if the lower bound is infinity */
8818 if( SCIPisInfinity(scip, -lby) )
8819 return SCIP_OKAY;
8820
8821 SCIP_CALL( SCIPvarAddVlb(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8822 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, scip->eventfilter,
8823 var, implbound - lby, lby, TRUE, infeasible, nbdchgs) );
8824 }
8825 else
8826 {
8827 /* we return if the upper bound is infinity */
8828 if( SCIPisInfinity(scip, uby) )
8829 return SCIP_OKAY;
8830
8831 SCIP_CALL( SCIPvarAddVub(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8832 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, scip->eventfilter,
8833 var, implbound - uby, uby, TRUE, infeasible, nbdchgs) );
8834 }
8835 }
8836 else
8837 {
8838 if( impltype == SCIP_BOUNDTYPE_LOWER )
8839 {
8840 /* we return if the lower bound is infinity */
8841 if( SCIPisInfinity(scip, -lby) )
8842 return SCIP_OKAY;
8843
8844 SCIP_CALL( SCIPvarAddVlb(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8845 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, scip->eventfilter,
8846 var, lby - implbound, implbound, TRUE, infeasible, nbdchgs) );
8847 }
8848 else
8849 {
8850 /* we return if the upper bound is infinity */
8851 if( SCIPisInfinity(scip, uby) )
8852 return SCIP_OKAY;
8853
8854 SCIP_CALL( SCIPvarAddVub(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8855 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, scip->eventfilter,
8856 var, uby - implbound, implbound, TRUE, infeasible, nbdchgs) );
8857 }
8858 }
8859 }
8860 else
8861 {
8862 SCIP_CALL( SCIPvarAddImplic(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8863 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, scip->eventfilter,
8864 varfixing, implvar, impltype, implbound, TRUE, infeasible, nbdchgs) );
8865 }
8866
8867 return SCIP_OKAY;
8868}
8869
8870/** adds a clique information to SCIP, stating that at most one of the given binary variables can be set to 1;
8871 * if a variable appears twice in the same clique, the corresponding implications are performed
8872 *
8873 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8874 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8875 *
8876 * @pre This method can be called if @p scip is in one of the following stages:
8877 * - \ref SCIP_STAGE_TRANSFORMED
8878 * - \ref SCIP_STAGE_PRESOLVING
8879 * - \ref SCIP_STAGE_PRESOLVED
8880 * - \ref SCIP_STAGE_SOLVING
8881 */
8883 SCIP* scip, /**< SCIP data structure */
8884 SCIP_VAR** vars, /**< binary variables in the clique from which at most one can be set to 1 */
8885 SCIP_Bool* values, /**< values of the variables in the clique; NULL to use TRUE for all vars */
8886 int nvars, /**< number of variables in the clique */
8887 SCIP_Bool isequation, /**< is the clique an equation or an inequality? */
8888 SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
8889 int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
8890 )
8891{
8893
8894 *infeasible = FALSE;
8895 if( nbdchgs != NULL )
8896 *nbdchgs = 0;
8897
8898 if( nvars > 1 )
8899 {
8900 /* add the clique to the clique table */
8901 SCIP_CALL( SCIPcliquetableAdd(scip->cliquetable, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
8902 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
8903 vars, values, nvars, isequation, infeasible, nbdchgs) );
8904 }
8905
8906 return SCIP_OKAY;
8907}
8908
8909#define MAXNUMEARCHCLIQUE 10000 /**< maximal number of cliques of variable for addLargestCliquePart() to search a suitable clique */
8910
8911/** add largest clique containing a given variable to part of clique partitioning */
8912static
8914 SCIP_VAR* var, /**< variable to treat */
8915 SCIP_Bool value, /**< value of variable */
8916 int varidx, /**< index of variable */
8917 int* idx, /**< mapping of problem variable indices to given subset */
8918 SCIP_Bool* values, /**< values of variables in given subset */
8919 int p, /**< part index */
8920 int nvars, /**< number of variables in the array */
8921 int nbinvars, /**< total number of binary variables */
8922 int* cliquepartition, /**< array of length nvars to store the clique partition */
8923 int* ncliqueparts /**< array to store the size of each part */
8924 )
8925{
8926 assert( var != NULL );
8927 assert( idx != NULL );
8928 assert( values != NULL );
8929 assert( cliquepartition != NULL );
8930 assert( ncliqueparts != NULL );
8931 assert( ncliqueparts[p] == 0 );
8932 assert( values[varidx] == value );
8933
8934 /* put variable into part p */
8935 cliquepartition[varidx] = p;
8936 ncliqueparts[p] = 1;
8937
8938 /* if variable is active, then add largest clique */
8939 if( SCIPvarIsActive(var) )
8940 {
8941 int nvarcliques;
8942
8943 nvarcliques = SCIPvarGetNCliques(var, value);
8944
8945 /* A performance analysis showed that the following is a bottleneck for instances with a very large number of
8946 * cliques, e.g., neos-5129192-manaia. We therefore limit the size. */
8947 if( nvarcliques > 0 && nvarcliques < MAXNUMEARCHCLIQUE )
8948 {
8949 SCIP_CLIQUE** varcliques;
8950 int selectedidx = -1;
8951 int selectedsmallestidx = nvars + 1;
8952 int l;
8953
8954 varcliques = SCIPvarGetCliques(var, value);
8955 assert( varcliques != NULL );
8956
8957 /* loop through all cliques */
8958 for( l = 0; l < nvarcliques; ++l )
8959 {
8960 SCIP_VAR** cliquevars;
8961 SCIP_Bool* cliquevals;
8962 SCIP_CLIQUE* clique;
8963 int nvarclique;
8964 int smallestidx = nvars + 1;
8965 int k;
8966
8967 clique = varcliques[l];
8968 assert( clique != NULL );
8969 nvarclique = SCIPcliqueGetNVars(clique);
8970 cliquevars = SCIPcliqueGetVars(clique);
8971 cliquevals = SCIPcliqueGetValues(clique);
8972
8973 /* loop through clique */
8974 for( k = 0; k < nvarclique; ++k )
8975 {
8976 SCIP_VAR* othervar;
8977 int probidx;
8978 int j;
8979
8980 othervar = cliquevars[k];
8981 assert( othervar != NULL );
8982
8983 if( SCIPvarIsActive(othervar) )
8984 {
8985 probidx = SCIPvarGetProbindex(othervar);
8986 assert( 0 <= probidx && probidx < nbinvars );
8987
8988 j = idx[probidx];
8989 if( j >= 0 && cliquevals[k] == values[j] && cliquepartition[j] < 0 )
8990 {
8991 assert( j < nvars );
8992
8993 /* consider smallest index of variables larger than varidx */
8994 if ( j > varidx && j < smallestidx )
8995 {
8996 smallestidx = j;
8997
8998 /* All variables before varidx have been considered, i.e., have cliquepartition[j] >= 0; thus,
8999 * if the smallestidx is one larger than varidx, we cannot improve and can stop. */
9000 if ( smallestidx == varidx + 1 )
9001 break;
9002 }
9003 }
9004 }
9005 }
9006
9007 /* We sort according to the smallest index appearing in the clique. This hopefully helps to preserve the
9008 * sorting of variables, which often is helpful for the knapsack constraint handler. */
9009 if( smallestidx < selectedsmallestidx )
9010 {
9011 selectedidx = l;
9012 selectedsmallestidx = smallestidx;
9013
9014 /* All variables before varidx have been considered, i.e., have cliquepartition[j] >= 0; thus,
9015 * if the smallestidx is one larger than varidx, we cannot improve and can stop. */
9016 if ( smallestidx == varidx + 1 )
9017 break;
9018 }
9019 }
9020
9021 /* add clique */
9022 if( selectedidx >= 0 )
9023 {
9024 SCIP_VAR** cliquevars;
9025 SCIP_Bool* cliquevals;
9026 SCIP_CLIQUE* clique;
9027 int nvarclique;
9028 int k;
9029
9030 assert( selectedidx <= nvarcliques );
9031 clique = varcliques[selectedidx];
9032 assert( clique != NULL );
9033 nvarclique = SCIPcliqueGetNVars(clique);
9034 cliquevars = SCIPcliqueGetVars(clique);
9035 cliquevals = SCIPcliqueGetValues(clique);
9036
9037 /* loop through clique and add it to part */
9038 for( k = 0; k < nvarclique; ++k )
9039 {
9040 SCIP_VAR* othervar;
9041 int probidx;
9042 int j;
9043
9044 othervar = cliquevars[k];
9045 assert( othervar != NULL );
9046
9047 if( SCIPvarIsActive(othervar) )
9048 {
9049 probidx = SCIPvarGetProbindex(othervar);
9050 assert( 0 <= probidx && probidx < nbinvars );
9051
9052 j = idx[probidx];
9053 if( j >= 0 && cliquevals[k] == values[j] && cliquepartition[j] < 0 )
9054 {
9055 assert( j < nvars );
9056 assert( othervar != var );
9057 cliquepartition[j] = p;
9058 ++(ncliqueparts[p]);
9059 }
9060 }
9061 }
9062 }
9063 }
9064 }
9065}
9066
9067/** calculates a partition of the given set of binary variables into cliques
9068 *
9069 * The output array contains one value for each variable, such that two variables have the same value iff they
9070 * were assigned to the same clique;
9071 * the first variable is always assigned to clique 0, and a variable can only be assigned to clique i if at least one of
9072 * the preceding variables was assigned to clique i-1;
9073 * for each clique at most 1 variables can be set to TRUE in a feasible solution;
9074 *
9075 * The implementation currently runs in O(n^2) time, because we have to clear the counter array nneigh. It could be
9076 * turned into a linear time algorithm by using a clean buffer.
9077 */
9078static
9080 SCIP*const scip, /**< SCIP data structure */
9081 SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
9082 SCIP_Bool*const values, /**< clique value (TRUE or FALSE) for each variable in the clique */
9083 int const nvars, /**< number of variables in the array */
9084 int** probtoidxmap, /**< cleared memory array with default values -1 */
9085 int* probtoidxmapsize, /**< returns size of probtoidxmap */
9086 int*const cliquepartition, /**< array of length nvars to store the clique partition */
9087 int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
9088 )
9089{
9090 int* nneigh;
9091 int* idx;
9092 int* ncliqueparts;
9093 int* marked;
9094 int nbinvars;
9095 int i;
9096 int k;
9097
9098 assert( vars != NULL );
9099 assert( values != NULL );
9100 assert( nvars > 0 );
9101 assert( probtoidxmap != NULL );
9102 assert( probtoidxmapsize != NULL );
9103
9104 /* allocate temporary memory for storing the number of neighors in the parts */
9105 SCIP_CALL( SCIPallocClearBufferArray(scip, &marked, nvars) );
9106 SCIP_CALL( SCIPallocBufferArray(scip, &nneigh, nvars) );
9107 SCIP_CALL( SCIPallocClearBufferArray(scip, &ncliqueparts, nvars) );
9108
9109 /* all variables which are of integral type can be potentially of binary type; this can be checked via the method SCIPvarIsBinary(var) */
9110 nbinvars = SCIPgetNVars(scip) - SCIPgetNContVars(scip);
9111
9112 /* prepare mapping of probvarindex to indices in given list */
9113 if ( *probtoidxmapsize < nbinvars )
9114 {
9115 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, probtoidxmap, *probtoidxmapsize, nbinvars) );
9116 *probtoidxmapsize = nbinvars;
9117 idx = *probtoidxmap;
9118 for( i = 0; i < nbinvars; ++i )
9119 idx[i] = -1;
9120 }
9121 else
9122 idx = *probtoidxmap;
9123 assert( idx != NULL );
9124
9125#ifndef NDEBUG
9126 /* probtoidxmap should be cleared */
9127 for( i = 0; i < nbinvars; ++i )
9128 assert( idx[i] == -1 );
9129#endif
9130
9131 /* initialize the cliquepartition array with -1 and idx */
9132 for( i = 0; i < nvars; ++i )
9133 {
9134 int probidx;
9135
9136 cliquepartition[i] = -1;
9137
9138 /* note that it could happen that variables appear multiple times in vars; we arbitrarily take the first */
9139 probidx = SCIPvarGetProbindex(vars[i]);
9140 if( probidx >= 0 && idx[probidx] < 0 )
9141 {
9142 assert( probidx <= nbinvars );
9143 idx[probidx] = i;
9144 }
9145 }
9146
9147 /* add largest clique containing first variable to part 0 */
9148 addLargestCliquePart(vars[0], values[0], 0, idx, values, 0, nvars, nbinvars, cliquepartition, ncliqueparts);
9149 *ncliques = 1;
9150
9151 /* loop through remaining variables */
9152 for( i = 1; i < nvars; ++i )
9153 {
9154 SCIP_VAR* var;
9155 SCIP_Bool value;
9156 int nvarcliques;
9157 int p;
9158
9159 /* skip already treated variables */
9160 if( cliquepartition[i] >= 0 )
9161 continue;
9162
9163 var = vars[i];
9164 value = values[i];
9165 nvarcliques = SCIPvarGetNCliques(var, value);
9166
9167 /* if variable is not active (multi-aggregated or fixed) or isolated, it will be moved to a new part below */
9168 if( nvarcliques > 0 && SCIPvarIsActive(var) )
9169 {
9170 SCIP_Bool foundpart = FALSE;
9171 SCIP_CLIQUE** varcliques;
9172 int l;
9173
9174 varcliques = SCIPvarGetCliques(var, value);
9175 assert( varcliques != NULL );
9176
9177 /* clear neighborhood counter */
9178 BMSclearMemoryArray(nneigh, *ncliques);
9179
9180 /* loop through all cliques */
9181 for( l = 0; l < nvarcliques && ! foundpart; ++l )
9182 {
9183 SCIP_VAR** cliquevars;
9184 SCIP_Bool* cliquevals;
9185 SCIP_VAR* othervar;
9186 int nvarclique;
9187 int probidx;
9188 int j;
9189
9190 assert( varcliques[l] != NULL );
9191 nvarclique = SCIPcliqueGetNVars(varcliques[l]);
9192 cliquevars = SCIPcliqueGetVars(varcliques[l]);
9193 cliquevals = SCIPcliqueGetValues(varcliques[l]);
9194
9195 /* loop through clique and count neighbors of i */
9196 for( k = 0; k < nvarclique; ++k )
9197 {
9198 othervar = cliquevars[k];
9199 assert( othervar != NULL );
9200
9201 if ( ! SCIPvarIsActive(othervar) || othervar == var )
9202 continue;
9203
9204 probidx = SCIPvarGetProbindex(othervar);
9205 assert( 0 <= probidx && probidx < nbinvars );
9206
9207 j = idx[probidx];
9208 if( j >= 0 )
9209 {
9210 assert( j < nvars );
9211 p = cliquepartition[j];
9212 if( p >= 0 && cliquevals[k] == values[j] && marked[j] != i )
9213 {
9214 assert( 0 <= p && p < *ncliques );
9215 ++nneigh[p];
9216 marked[j] = i;
9217
9218 /* if all nodes in the part are neighbors, add variable to it */
9219 if( nneigh[p] == ncliqueparts[p] )
9220 {
9221 assert( ! foundpart );
9222 cliquepartition[i] = p;
9223 ++(ncliqueparts[p]);
9224 foundpart = TRUE;
9225 break;
9226 }
9227 }
9228 }
9229 }
9230 }
9231
9232 /* if part has not been found, add corresponding clique */
9233 if( ! foundpart )
9234 {
9235#ifndef NDEBUG
9236 for( p = 0; p < *ncliques; ++p )
9237 assert( nneigh[p] < ncliqueparts[p] );
9238#endif
9239 assert( ncliqueparts[*ncliques] == 0 );
9240
9241 addLargestCliquePart(vars[i], values[i], i, idx, values, *ncliques, nvars, nbinvars, cliquepartition, ncliqueparts);
9242 ++(*ncliques);
9243 }
9244 }
9245 else
9246 {
9247 ncliqueparts[*ncliques] = 1;
9248 cliquepartition[i] = (*ncliques)++;
9249 }
9250 }
9251
9252 /* clear probtoidxmap */
9253 for( i = 0; i < nvars; ++i )
9254 {
9255 int probidx;
9256 probidx = SCIPvarGetProbindex(vars[i]);
9257 if ( probidx >= 0 )
9258 idx[probidx] = -1;
9259 }
9260
9261 SCIPfreeBufferArray(scip, &ncliqueparts);
9262 SCIPfreeBufferArray(scip, &nneigh);
9263 SCIPfreeBufferArray(scip, &marked);
9264
9265 return SCIP_OKAY;
9266}
9267
9268#ifndef NDEBUG
9269/** test whether a clique partition is correct */
9270static
9272 SCIP* scip, /**< SCIP data structure */
9273 SCIP_VAR** vars, /**< binary variables in the clique from which at most one can be set to 1 */
9274 int nvars, /**< number of variables in the clique */
9275 const int* cliquepartition, /**< array of length nvars to store the clique partition */
9276 int ncliques /**< pointer to store the number of cliques actually contained in the partition */
9277 )
9278{
9279 int p;
9280
9281 /* loop through all parts and check that they are cliques */
9282 for( p = 0; p < ncliques; ++p )
9283 {
9284 SCIP_VAR* vari;
9285 SCIP_VAR* varj;
9286 SCIP_Bool vali;
9287 SCIP_Bool valj;
9288 int i;
9289 int j;
9290
9291 for( i = 0; i < nvars; ++i )
9292 {
9293 assert(0 <= cliquepartition[i] && cliquepartition[i] < ncliques );
9294 if( cliquepartition[i] != p )
9295 continue;
9296
9297 vari = vars[i];
9298 vali = TRUE;
9299 SCIP_CALL( SCIPvarGetProbvarBinary(&vari, &vali) );
9300
9301 for( j = i+1; j < nvars; ++j )
9302 {
9303 if( cliquepartition[j] != p )
9304 continue;
9305
9306 varj = vars[j];
9307 valj = TRUE;
9308 SCIP_CALL( SCIPvarGetProbvarBinary(&varj, &valj) );
9309
9310 assert( SCIPvarsHaveCommonClique(vari, vali, varj, valj, FALSE) );
9311 }
9312 }
9313 }
9314 return SCIP_OKAY;
9315}
9316#endif
9317
9318/** calculates a partition of the given set of binary variables into cliques
9319 *
9320 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9321 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9322 *
9323 * @pre This method can be called if @p scip is in one of the following stages:
9324 * - \ref SCIP_STAGE_INITPRESOLVE
9325 * - \ref SCIP_STAGE_PRESOLVING
9326 * - \ref SCIP_STAGE_EXITPRESOLVE
9327 * - \ref SCIP_STAGE_PRESOLVED
9328 * - \ref SCIP_STAGE_SOLVING
9329 */
9331 SCIP* scip, /**< SCIP data structure */
9332 SCIP_VAR** vars, /**< binary variables in the clique from which at most one can be set to 1 */
9333 int nvars, /**< number of variables in the clique */
9334 int** probtoidxmap, /**< cleared memory array with default values -1 */
9335 int* probtoidxmapsize, /**< returns size of probtoidxmap */
9336 int* cliquepartition, /**< array of length nvars to store the clique partition */
9337 int* ncliques /**< pointer to store the number of cliques actually contained in the partition */
9338 )
9339{
9340 SCIP_VAR** tmpvars;
9341 SCIP_Bool* tmpvalues;
9342 int i;
9343
9344 assert(scip != NULL);
9345 assert(nvars == 0 || vars != NULL);
9346 assert(nvars == 0 || cliquepartition != NULL);
9347 assert(ncliques != NULL);
9348
9349 SCIP_CALL( SCIPcheckStage(scip, "SCIPcalcCliquePartition", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
9350
9351 if( nvars == 0 )
9352 {
9353 *ncliques = 0;
9354 return SCIP_OKAY;
9355 }
9356
9357 /* early abort if no cliques are present */
9358 if( SCIPgetNCliques(scip) == 0 )
9359 {
9360 for( i = 0; i < nvars; ++i )
9361 cliquepartition[i] = i;
9362
9363 *ncliques = nvars;
9364
9365 return SCIP_OKAY;
9366 }
9367
9368 SCIP_CALL( SCIPallocBufferArray(scip, &tmpvalues, nvars) );
9369 SCIP_CALL( SCIPduplicateBufferArray(scip, &tmpvars, vars, nvars) );
9370
9371 /* initialize array */
9372 for( i = nvars - 1; i >= 0; --i )
9373 tmpvalues[i] = TRUE;
9374
9375 /* get corresponding active problem variables */
9376 SCIP_CALL( SCIPvarsGetProbvarBinary(&tmpvars, &tmpvalues, nvars) );
9377
9378 /* call greedy clique algorithm for all component variables */
9379 SCIP_CALL( calcCliquePartitionGreedy(scip, tmpvars, tmpvalues, nvars, probtoidxmap, probtoidxmapsize, cliquepartition, ncliques) );
9380
9381 assert(*ncliques >= 1);
9382
9383 SCIPfreeBufferArray(scip, &tmpvars);
9384 SCIPfreeBufferArray(scip, &tmpvalues);
9385
9386#ifndef NDEBUG
9387 SCIP_CALL( SCIPtestCliquePartition(scip, vars, nvars, cliquepartition, *ncliques) );
9388#endif
9389
9390 return SCIP_OKAY;
9391}
9392
9393/** calculates a partition of the given set of binary variables into negated cliques;
9394 * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
9395 * were assigned to the same negated clique;
9396 * the first variable is always assigned to clique 0 and a variable can only be assigned to clique i if at least one of
9397 * the preceding variables was assigned to clique i-1;
9398 * for each clique with n_c variables at least n_c-1 variables can be set to TRUE in a feasible solution;
9399 *
9400 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9401 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9402 *
9403 * @pre This method can be called if @p scip is in one of the following stages:
9404 * - \ref SCIP_STAGE_INITPRESOLVE
9405 * - \ref SCIP_STAGE_PRESOLVING
9406 * - \ref SCIP_STAGE_EXITPRESOLVE
9407 * - \ref SCIP_STAGE_PRESOLVED
9408 * - \ref SCIP_STAGE_SOLVING
9409 */
9411 SCIP* scip, /**< SCIP data structure */
9412 SCIP_VAR** vars, /**< binary variables in the clique from which at most one can be set to 1 */
9413 int nvars, /**< number of variables in the clique */
9414 int** probtoidxmap, /**< cleared memory array with default values -1 */
9415 int* probtoidxmapsize, /**< returns size of probtoidxmap */
9416 int* cliquepartition, /**< array of length nvars to store the clique partition */
9417 int* ncliques /**< pointer to store the number of cliques actually contained in the partition */
9418 )
9419{
9420 SCIP_VAR** negvars;
9421 int v;
9422
9423 assert(scip != NULL);
9424 assert(cliquepartition != NULL || nvars == 0);
9425 assert(ncliques != NULL);
9426
9427 if( nvars == 0 )
9428 {
9429 *ncliques = 0;
9430 return SCIP_OKAY;
9431 }
9432 assert(vars != NULL);
9433
9434 /* allocate temporary memory */
9435 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &negvars, nvars) );
9436
9437 /* get all negated variables */
9438 for( v = nvars - 1; v >= 0; --v )
9439 {
9440 SCIP_CALL( SCIPgetNegatedVar(scip, vars[v], &(negvars[v])) );
9441 }
9442
9443 /* calculate cliques on negated variables, which are "negated" cliques on normal variables array */
9444 SCIP_CALL( SCIPcalcCliquePartition(scip, negvars, nvars, probtoidxmap, probtoidxmapsize, cliquepartition, ncliques) );
9445
9446 /* free temporary memory */
9447 SCIPsetFreeBufferArray(scip->set, &negvars);
9448
9449 return SCIP_OKAY;
9450}
9451
9452
9453/** force SCIP to clean up all cliques; cliques do not get automatically cleaned up after presolving. Use
9454 * this method to prevent inactive variables in cliques when retrieved via SCIPgetCliques()
9455 *
9456 * @return SCIP_OKAY if everything worked, otherwise a suitable error code is passed
9457 *
9458 * @pre This method can be called if @p scip is in one of the following stages:
9459 * - \ref SCIP_STAGE_TRANSFORMED
9460 * - \ref SCIP_STAGE_INITPRESOLVE
9461 * - \ref SCIP_STAGE_PRESOLVING
9462 * - \ref SCIP_STAGE_EXITPRESOLVE
9463 * - \ref SCIP_STAGE_PRESOLVED
9464 * - \ref SCIP_STAGE_INITSOLVE
9465 * - \ref SCIP_STAGE_SOLVING
9466 * - \ref SCIP_STAGE_SOLVED
9467 * - \ref SCIP_STAGE_EXITSOLVE
9468 */
9470 SCIP* scip, /**< SCIP data structure */
9471 SCIP_Bool* infeasible /**< pointer to store if cleanup detected infeasibility */
9472 )
9473{
9474 int nlocalbdchgs;
9475 SCIP_Bool globalinfeasibility;
9476
9477 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPcleanupCliques", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
9478
9479 globalinfeasibility = FALSE;
9480 nlocalbdchgs = 0;
9481 SCIP_CALL( SCIPcliquetableCleanup(scip->cliquetable, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
9482 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
9483 &nlocalbdchgs, &globalinfeasibility) );
9484
9485 if( infeasible != NULL )
9486 *infeasible = globalinfeasibility;
9487
9488 if( globalinfeasibility )
9489 scip->stat->status = SCIP_STATUS_INFEASIBLE;
9490
9491 return SCIP_OKAY;
9492}
9493
9494/** gets the number of cliques in the clique table
9495 *
9496 * @return number of cliques in the clique table
9497 *
9498 * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
9499 * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
9500 *
9501 * @pre This method can be called if @p scip is in one of the following stages:
9502 * - \ref SCIP_STAGE_TRANSFORMED
9503 * - \ref SCIP_STAGE_INITPRESOLVE
9504 * - \ref SCIP_STAGE_PRESOLVING
9505 * - \ref SCIP_STAGE_EXITPRESOLVE
9506 * - \ref SCIP_STAGE_PRESOLVED
9507 * - \ref SCIP_STAGE_INITSOLVE
9508 * - \ref SCIP_STAGE_SOLVING
9509 * - \ref SCIP_STAGE_SOLVED
9510 * - \ref SCIP_STAGE_EXITSOLVE
9511 */
9513 SCIP* scip /**< SCIP data structure */
9514 )
9515{
9517
9518 return SCIPcliquetableGetNCliques(scip->cliquetable);
9519}
9520
9521/** gets the number of cliques created so far by the cliquetable
9522 *
9523 * @return number of cliques created so far by the cliquetable
9524 *
9525 * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
9526 * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
9527 *
9528 * @pre This method can be called if @p scip is in one of the following stages:
9529 * - \ref SCIP_STAGE_TRANSFORMED
9530 * - \ref SCIP_STAGE_INITPRESOLVE
9531 * - \ref SCIP_STAGE_PRESOLVING
9532 * - \ref SCIP_STAGE_EXITPRESOLVE
9533 * - \ref SCIP_STAGE_PRESOLVED
9534 * - \ref SCIP_STAGE_INITSOLVE
9535 * - \ref SCIP_STAGE_SOLVING
9536 * - \ref SCIP_STAGE_SOLVED
9537 * - \ref SCIP_STAGE_EXITSOLVE
9538 */
9540 SCIP* scip /**< SCIP data structure */
9541 )
9542{
9543 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNCliquesCreated", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
9544
9545 return SCIPcliquetableGetNCliquesCreated(scip->cliquetable);
9546}
9547
9548/** gets the array of cliques in the clique table
9549 *
9550 * @return array of cliques in the clique table
9551 *
9552 * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
9553 * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
9554 *
9555 * @pre This method can be called if @p scip is in one of the following stages:
9556 * - \ref SCIP_STAGE_TRANSFORMED
9557 * - \ref SCIP_STAGE_INITPRESOLVE
9558 * - \ref SCIP_STAGE_PRESOLVING
9559 * - \ref SCIP_STAGE_EXITPRESOLVE
9560 * - \ref SCIP_STAGE_PRESOLVED
9561 * - \ref SCIP_STAGE_INITSOLVE
9562 * - \ref SCIP_STAGE_SOLVING
9563 * - \ref SCIP_STAGE_SOLVED
9564 * - \ref SCIP_STAGE_EXITSOLVE
9565 */
9567 SCIP* scip /**< SCIP data structure */
9568 )
9569{
9571
9572 return SCIPcliquetableGetCliques(scip->cliquetable);
9573}
9574
9575/** returns whether there is a clique that contains both given variable/value pairs;
9576 * the variables must be active binary variables;
9577 * if regardimplics is FALSE, only the cliques in the clique table are looked at;
9578 * if regardimplics is TRUE, both the cliques and the implications of the implication graph are regarded
9579 *
9580 * @return TRUE, if there is a clique that contains both variable/clique pairs; FALSE, otherwise
9581 *
9582 * @pre This method can be called if @p scip is in one of the following stages:
9583 * - \ref SCIP_STAGE_TRANSFORMED
9584 * - \ref SCIP_STAGE_INITPRESOLVE
9585 * - \ref SCIP_STAGE_PRESOLVING
9586 * - \ref SCIP_STAGE_EXITPRESOLVE
9587 * - \ref SCIP_STAGE_PRESOLVED
9588 * - \ref SCIP_STAGE_INITSOLVE
9589 * - \ref SCIP_STAGE_SOLVING
9590 * - \ref SCIP_STAGE_SOLVED
9591 * - \ref SCIP_STAGE_EXITSOLVE
9592 *
9593 * @note a variable with it's negated variable are NOT! in a clique
9594 * @note a variable with itself are in a clique
9595 */
9597 SCIP* scip, /**< SCIP data structure */
9598 SCIP_VAR* var1, /**< first variable */
9599 SCIP_Bool value1, /**< value of first variable */
9600 SCIP_VAR* var2, /**< second variable */
9601 SCIP_Bool value2, /**< value of second variable */
9602 SCIP_Bool regardimplics /**< should the implication graph also be searched for a clique? */
9603 )
9604{
9605 assert(scip != NULL);
9606 assert(var1 != NULL);
9607 assert(var2 != NULL);
9608 assert(SCIPvarIsActive(var1));
9609 assert(SCIPvarIsActive(var2));
9610 assert(SCIPvarIsBinary(var1));
9611 assert(SCIPvarIsBinary(var2));
9612
9613 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPhaveVarsCommonClique", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
9614
9615 /* if both variables together have more cliques then actual cliques exist, then they have a common clique (in debug
9616 * mode we check this for correctness), otherwise we need to call the pairwise comparison method for these variables
9617 */
9618#ifndef NDEBUG
9619 assert((SCIPvarGetNCliques(var1, value1) + SCIPvarGetNCliques(var2, value2) > SCIPcliquetableGetNCliques(scip->cliquetable)) ? SCIPvarsHaveCommonClique(var1, value1, var2, value2, FALSE) : TRUE);
9620#endif
9621
9622 return (SCIPvarGetNCliques(var1, value1) + SCIPvarGetNCliques(var2, value2) > SCIPcliquetableGetNCliques(scip->cliquetable)
9623 || SCIPvarsHaveCommonClique(var1, value1, var2, value2, regardimplics));
9624}
9625
9626/** writes the clique graph to a gml file
9627 *
9628 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9629 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9630 *
9631 * @pre This method can be called if @p scip is in one of the following stages:
9632 * - \ref SCIP_STAGE_TRANSFORMED
9633 * - \ref SCIP_STAGE_INITPRESOLVE
9634 * - \ref SCIP_STAGE_PRESOLVING
9635 * - \ref SCIP_STAGE_EXITPRESOLVE
9636 * - \ref SCIP_STAGE_PRESOLVED
9637 * - \ref SCIP_STAGE_INITSOLVE
9638 * - \ref SCIP_STAGE_SOLVING
9639 * - \ref SCIP_STAGE_SOLVED
9640 * - \ref SCIP_STAGE_EXITSOLVE
9641 *
9642 * @note there can be duplicated arcs in the output file
9643 *
9644 * If @p writenodeweights is true, only nodes corresponding to variables that have a fractional value and only edges
9645 * between such nodes are written.
9646 */
9648 SCIP* scip, /**< SCIP data structure */
9649 const char* fname, /**< name of file */
9650 SCIP_Bool writenodeweights /**< should we write weights of nodes? */
9651 )
9652{
9653 FILE* gmlfile;
9654 SCIP_HASHMAP* nodehashmap;
9655 SCIP_CLIQUE** cliques;
9656 SCIP_VAR** clqvars;
9657 SCIP_VAR** allvars;
9658 SCIP_Bool* clqvalues;
9659 char nodename[SCIP_MAXSTRLEN];
9660 int nallvars;
9661 int nbinvars;
9662 int nintvars;
9663 int nimplvars;
9664 int ncliques;
9665 int c;
9666 int v1;
9667 int v2;
9668 int id1;
9669 int id2;
9670
9671 assert(scip != NULL);
9672 assert(fname != NULL);
9673
9674 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPwriteCliqueGraph", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
9675
9676 /* get all active variables */
9677 SCIP_CALL( SCIPgetVarsData(scip, &allvars, &nallvars, &nbinvars, &nintvars, &nimplvars, NULL) );
9678
9679 /* no possible variables for cliques exist */
9680 if( nbinvars + nimplvars == 0 )
9681 return SCIP_OKAY;
9682
9683 ncliques = SCIPgetNCliques(scip);
9684
9685 /* no cliques and do not wont to check for binary implications */
9686 if( ncliques == 0 )
9687 return SCIP_OKAY;
9688
9689 /* open gml file */
9690 gmlfile = fopen(fname, "w");
9691
9692 if( gmlfile == NULL )
9693 {
9694 SCIPerrorMessage("cannot open graph file <%s>\n", fname);
9695 SCIPABORT();
9696 return SCIP_INVALIDDATA; /*lint !e527*/
9697 }
9698
9699 /* create the hash map */
9700 SCIP_CALL_FINALLY( SCIPhashmapCreate(&nodehashmap, SCIPblkmem(scip), nbinvars+nimplvars), fclose(gmlfile) );
9701
9702 /* write starting of gml file */
9703 SCIPgmlWriteOpening(gmlfile, TRUE);
9704
9705 cliques = SCIPgetCliques(scip);
9706
9707 /* write nodes and arcs for all cliques */
9708 for( c = ncliques - 1; c >= 0; --c )
9709 {
9710 clqvalues = SCIPcliqueGetValues(cliques[c]);
9711 clqvars = SCIPcliqueGetVars(cliques[c]);
9712
9713 for( v1 = SCIPcliqueGetNVars(cliques[c]) - 1; v1 >= 0; --v1 )
9714 {
9715 id1 = clqvalues[v1] ? SCIPvarGetProbindex(clqvars[v1]) : (nallvars + SCIPvarGetProbindex(clqvars[v1]));
9716
9717 /* if corresponding node was not added yet, add it */
9718 if( !SCIPhashmapExists(nodehashmap, (void*)(size_t)id1) )
9719 {
9720 assert(id1 >= 0);
9721 SCIP_CALL_FINALLY( SCIPhashmapInsertInt(nodehashmap, (void*)(size_t)id1, 1), fclose(gmlfile) ); /*lint !e571*/
9722
9723 (void) SCIPsnprintf(nodename, SCIP_MAXSTRLEN, "%s%s", (id1 >= nallvars ? "~" : ""), SCIPvarGetName(clqvars[v1]));
9724
9725 /* write new gml node for new variable */
9726 if ( writenodeweights )
9727 {
9728 if ( ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v1])) )
9729 SCIPgmlWriteNodeWeight(gmlfile, (unsigned int)id1, nodename, NULL, NULL, NULL, SCIPgetSolVal(scip, NULL, clqvars[v1]));
9730 }
9731 else
9732 {
9733 SCIPgmlWriteNode(gmlfile, (unsigned int)id1, nodename, NULL, NULL, NULL);
9734 }
9735 }
9736
9737 for( v2 = SCIPcliqueGetNVars(cliques[c]) - 1; v2 >= 0; --v2 )
9738 {
9739 if( v1 == v2 )
9740 continue;
9741
9742 id2 = clqvalues[v2] ? SCIPvarGetProbindex(clqvars[v2]) : (nallvars + SCIPvarGetProbindex(clqvars[v2]));
9743
9744 /* if corresponding node was not added yet, add it */
9745 if( !SCIPhashmapExists(nodehashmap, (void*)(size_t)id2) )
9746 {
9747 assert(id2 >= 0);
9748 SCIP_CALL_FINALLY( SCIPhashmapInsertInt(nodehashmap, (void*)(size_t)id2, 1), fclose(gmlfile) ); /*lint !e571*/
9749
9750 (void) SCIPsnprintf(nodename, SCIP_MAXSTRLEN, "%s%s", (id2 >= nallvars ? "~" : ""), SCIPvarGetName(clqvars[v2]));
9751
9752 /* write new gml node for new variable */
9753 if ( writenodeweights )
9754 {
9755 if ( ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v2])) )
9756 SCIPgmlWriteNodeWeight(gmlfile, (unsigned int)id2, nodename, NULL, NULL, NULL, SCIPgetSolVal(scip, NULL, clqvars[v2]));
9757 }
9758 else
9759 {
9760 SCIPgmlWriteNode(gmlfile, (unsigned int)id2, nodename, NULL, NULL, NULL);
9761 }
9762 }
9763
9764 /* write gml arc between resultant and operand */
9765 if ( ! writenodeweights || ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v2])) )
9766 SCIPgmlWriteArc(gmlfile, (unsigned int)id1, (unsigned int)id2, NULL, NULL);
9767 }
9768 }
9769 }
9770
9771 /* free the hash map */
9772 SCIPhashmapFree(&nodehashmap);
9773
9774 SCIPgmlWriteClosing(gmlfile);
9775 fclose(gmlfile);
9776
9777 return SCIP_OKAY;
9778}
9779
9780/** Removes (irrelevant) variable from all its global structures, i.e. cliques, implications and variable bounds.
9781 * This is an advanced method which should be used with care.
9782 *
9783 * @return SCIP_OKAY if everything worked, otherwise a suitable error code is passed
9784 *
9785 * @pre This method can be called if @p scip is in one of the following stages:
9786 * - \ref SCIP_STAGE_TRANSFORMED
9787 * - \ref SCIP_STAGE_INITPRESOLVE
9788 * - \ref SCIP_STAGE_PRESOLVING
9789 * - \ref SCIP_STAGE_EXITPRESOLVE
9790 * - \ref SCIP_STAGE_PRESOLVED
9791 * - \ref SCIP_STAGE_INITSOLVE
9792 * - \ref SCIP_STAGE_SOLVING
9793 * - \ref SCIP_STAGE_SOLVED
9794 * - \ref SCIP_STAGE_EXITSOLVE
9795 */
9797 SCIP* scip, /**< SCIP data structure */
9798 SCIP_VAR* var /**< variable to remove from global structures */
9799 )
9800{
9801 assert(scip != NULL);
9802
9803 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPremoveVarFromGlobalStructures", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
9804
9805 /* mark the variable as deletable from global structures - This is necessary for the delayed clean up of cliques */
9807
9808 /* remove variable from all its cliques, implications, and variable bounds */
9810
9811 return SCIP_OKAY;
9812}
9813
9814/** sets the branch factor of the variable; this value can be used in the branching methods to scale the score
9815 * values of the variables; higher factor leads to a higher probability that this variable is chosen for branching
9816 *
9817 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9818 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9819 *
9820 * @pre This method can be called if @p scip is in one of the following stages:
9821 * - \ref SCIP_STAGE_PROBLEM
9822 * - \ref SCIP_STAGE_TRANSFORMING
9823 * - \ref SCIP_STAGE_TRANSFORMED
9824 * - \ref SCIP_STAGE_INITPRESOLVE
9825 * - \ref SCIP_STAGE_PRESOLVING
9826 * - \ref SCIP_STAGE_EXITPRESOLVE
9827 * - \ref SCIP_STAGE_PRESOLVED
9828 * - \ref SCIP_STAGE_SOLVING
9829 */
9831 SCIP* scip, /**< SCIP data structure */
9832 SCIP_VAR* var, /**< problem variable */
9833 SCIP_Real branchfactor /**< factor to weigh variable's branching score with */
9834 )
9835{
9836 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
9837
9838 SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, branchfactor) );
9839
9840 return SCIP_OKAY;
9841}
9842
9843/** scales the branch factor of the variable with the given value
9844 *
9845 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9846 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9847 *
9848 * @pre This method can be called if @p scip is in one of the following stages:
9849 * - \ref SCIP_STAGE_PROBLEM
9850 * - \ref SCIP_STAGE_TRANSFORMING
9851 * - \ref SCIP_STAGE_TRANSFORMED
9852 * - \ref SCIP_STAGE_INITPRESOLVE
9853 * - \ref SCIP_STAGE_PRESOLVING
9854 * - \ref SCIP_STAGE_EXITPRESOLVE
9855 * - \ref SCIP_STAGE_PRESOLVED
9856 * - \ref SCIP_STAGE_SOLVING
9857 */
9859 SCIP* scip, /**< SCIP data structure */
9860 SCIP_VAR* var, /**< problem variable */
9861 SCIP_Real scale /**< factor to scale variable's branching factor with */
9862 )
9863{
9864 SCIP_CALL( SCIPcheckStage(scip, "SCIPscaleVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
9865
9866 SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, scale * SCIPvarGetBranchFactor(var)) );
9867
9868 return SCIP_OKAY;
9869}
9870
9871/** adds the given value to the branch factor of the variable
9872 *
9873 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9874 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9875 *
9876 * @pre This method can be called if @p scip is in one of the following stages:
9877 * - \ref SCIP_STAGE_PROBLEM
9878 * - \ref SCIP_STAGE_TRANSFORMING
9879 * - \ref SCIP_STAGE_TRANSFORMED
9880 * - \ref SCIP_STAGE_INITPRESOLVE
9881 * - \ref SCIP_STAGE_PRESOLVING
9882 * - \ref SCIP_STAGE_EXITPRESOLVE
9883 * - \ref SCIP_STAGE_PRESOLVED
9884 * - \ref SCIP_STAGE_SOLVING
9885 */
9887 SCIP* scip, /**< SCIP data structure */
9888 SCIP_VAR* var, /**< problem variable */
9889 SCIP_Real addfactor /**< value to add to the branch factor of the variable */
9890 )
9891{
9892 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
9893
9894 SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, addfactor + SCIPvarGetBranchFactor(var)) );
9895
9896 return SCIP_OKAY;
9897}
9898
9899/** sets the branch priority of the variable; variables with higher branch priority are always preferred to variables
9900 * with lower priority in selection of branching variable
9901 *
9902 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9903 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9904 *
9905 * @pre This method can be called if @p scip is in one of the following stages:
9906 * - \ref SCIP_STAGE_PROBLEM
9907 * - \ref SCIP_STAGE_TRANSFORMING
9908 * - \ref SCIP_STAGE_TRANSFORMED
9909 * - \ref SCIP_STAGE_INITPRESOLVE
9910 * - \ref SCIP_STAGE_PRESOLVING
9911 * - \ref SCIP_STAGE_EXITPRESOLVE
9912 * - \ref SCIP_STAGE_PRESOLVED
9913 * - \ref SCIP_STAGE_SOLVING
9914 *
9915 * @note the default branching priority is 0
9916 */
9918 SCIP* scip, /**< SCIP data structure */
9919 SCIP_VAR* var, /**< problem variable */
9920 int branchpriority /**< branch priority of the variable */
9921 )
9922{
9923 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
9924
9925 assert( var->scip == scip );
9926
9927 if( SCIPisTransformed(scip) )
9928 {
9929 assert(scip->branchcand != NULL);
9930
9931 /* inform the pseudo branch candidates that the branch priority changes and change the branch priority */
9932 SCIP_CALL( SCIPbranchcandUpdateVarBranchPriority(scip->branchcand, scip->set, var, branchpriority) );
9933 }
9934 else
9935 {
9936 /* change the branching priority of the variable */
9937 SCIP_CALL( SCIPvarChgBranchPriority(var, branchpriority) );
9938 }
9939
9940 return SCIP_OKAY;
9941}
9942
9943/** changes the branch priority of the variable to the given value, if it is larger than the current priority
9944 *
9945 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9946 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9947 *
9948 * @pre This method can be called if @p scip is in one of the following stages:
9949 * - \ref SCIP_STAGE_PROBLEM
9950 * - \ref SCIP_STAGE_TRANSFORMING
9951 * - \ref SCIP_STAGE_TRANSFORMED
9952 * - \ref SCIP_STAGE_INITPRESOLVE
9953 * - \ref SCIP_STAGE_PRESOLVING
9954 * - \ref SCIP_STAGE_EXITPRESOLVE
9955 * - \ref SCIP_STAGE_PRESOLVED
9956 * - \ref SCIP_STAGE_SOLVING
9957 */
9959 SCIP* scip, /**< SCIP data structure */
9960 SCIP_VAR* var, /**< problem variable */
9961 int branchpriority /**< new branch priority of the variable, if it is larger than current priority */
9962 )
9963{
9964 SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
9965
9966 assert( var->scip == scip );
9967
9968 if( branchpriority > SCIPvarGetBranchPriority(var) )
9969 {
9970 SCIP_CALL( SCIPvarChgBranchPriority(var, branchpriority) );
9971 }
9972
9973 return SCIP_OKAY;
9974}
9975
9976/** adds the given value to the branch priority of the variable
9977 *
9978 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9979 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9980 *
9981 * @pre This method can be called if @p scip is in one of the following stages:
9982 * - \ref SCIP_STAGE_PROBLEM
9983 * - \ref SCIP_STAGE_TRANSFORMING
9984 * - \ref SCIP_STAGE_TRANSFORMED
9985 * - \ref SCIP_STAGE_INITPRESOLVE
9986 * - \ref SCIP_STAGE_PRESOLVING
9987 * - \ref SCIP_STAGE_EXITPRESOLVE
9988 * - \ref SCIP_STAGE_PRESOLVED
9989 * - \ref SCIP_STAGE_SOLVING
9990 */
9992 SCIP* scip, /**< SCIP data structure */
9993 SCIP_VAR* var, /**< problem variable */
9994 int addpriority /**< value to add to the branch priority of the variable */
9995 )
9996{
9997 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
9998
9999 assert( var->scip == scip );
10000
10002
10003 return SCIP_OKAY;
10004}
10005
10006/** sets the branch direction of the variable (-1: prefer downwards branch, 0: automatic selection, +1: prefer upwards
10007 * branch)
10008 *
10009 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
10010 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
10011 *
10012 * @pre This method can be called if @p scip is in one of the following stages:
10013 * - \ref SCIP_STAGE_PROBLEM
10014 * - \ref SCIP_STAGE_TRANSFORMING
10015 * - \ref SCIP_STAGE_TRANSFORMED
10016 * - \ref SCIP_STAGE_INITPRESOLVE
10017 * - \ref SCIP_STAGE_PRESOLVING
10018 * - \ref SCIP_STAGE_EXITPRESOLVE
10019 * - \ref SCIP_STAGE_PRESOLVED
10020 * - \ref SCIP_STAGE_SOLVING
10021 */
10023 SCIP* scip, /**< SCIP data structure */
10024 SCIP_VAR* var, /**< problem variable */
10025 SCIP_BRANCHDIR branchdirection /**< preferred branch direction of the variable (downwards, upwards, auto) */
10026 )
10027{
10028 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchDirection", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
10029
10030 assert( var->scip == scip );
10031
10032 SCIP_CALL( SCIPvarChgBranchDirection(var, branchdirection) );
10033
10034 return SCIP_OKAY;
10035}
10036
10037/** tightens the variable bounds due to a new variable type */
10038static
10040 SCIP* scip, /**< SCIP data structure */
10041 SCIP_VAR* var, /**< variable to change the bound for */
10042 SCIP_Bool integral, /**< did the variable become integral? */
10043 SCIP_Bool* infeasible /**< pointer to store whether an infeasibility was detected (, due to
10044 * integrality condition of the new variable type) */
10045 )
10046{
10047 assert(scip != NULL);
10049 assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPvarIsTransformed(var));
10050 assert(var->scip == scip);
10051
10052 *infeasible = FALSE;
10053
10054 /* adjusts bounds if the variable type changed form continuous to non-continuous (integral) */
10055 if( !SCIPvarIsIntegral(var) && integral )
10056 {
10057 SCIP_Bool tightened;
10058
10059 /* we adjust variable bounds to integers first, since otherwise a later bound tightening with a fractional old
10060 * bound may give an assert because SCIP expects non-continuous variables to have non-fractional bounds
10061 *
10062 * we adjust bounds with a fractionality within [eps,feastol] only if the resulting bound change is a bound
10063 * tightening, because relaxing bounds may not be allowed
10064 */
10069 )
10070 {
10071 SCIP_CALL( SCIPtightenVarLbGlobal(scip, var, SCIPfeasCeil(scip, SCIPvarGetLbGlobal(var)), TRUE, infeasible, &tightened) );
10072 if( *infeasible )
10073 return SCIP_OKAY;
10074
10075 /* the only reason for not applying a forced boundchange is when the new bound is reduced because the variables upper bound is below the new bound
10076 * in a concrete case, lb == ub == 100.99999001; even though within feastol of 101, the lower bound cannot be tighented to 101 due to the upper bound
10077 */
10078 assert(tightened || SCIPisFeasLE(scip, SCIPvarGetUbGlobal(var), SCIPfeasCeil(scip, SCIPvarGetLbGlobal(var))));
10079 }
10082 )
10083 {
10084 SCIP_CALL( SCIPtightenVarUbGlobal(scip, var, SCIPfeasFloor(scip, SCIPvarGetUbGlobal(var)), TRUE, infeasible, &tightened) );
10085 if( *infeasible )
10086 return SCIP_OKAY;
10087
10088 assert(tightened || SCIPisFeasGE(scip, SCIPvarGetLbGlobal(var), SCIPfeasFloor(scip, SCIPvarGetUbGlobal(var))));
10089 }
10090 }
10091
10092 return SCIP_OKAY;
10093}
10094
10095/** changes type of variable in the problem;
10096 *
10097 * @warning This type change might change the variable array returned from SCIPgetVars() and SCIPgetVarsData();
10098 *
10099 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
10100 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
10101 *
10102 * @pre This method can be called if @p scip is in one of the following stages:
10103 * - \ref SCIP_STAGE_PROBLEM
10104 * - \ref SCIP_STAGE_TRANSFORMING
10105 * - \ref SCIP_STAGE_PRESOLVING
10106 *
10107 * @note If SCIP is already beyond the SCIP_STAGE_PROBLEM and a original variable is passed, the variable type of the
10108 * corresponding transformed variable is changed; the type of the original variable does not change
10109 *
10110 * @note If the type changes from a continuous variable to a non-continuous variable the bounds of the variable get
10111 * adjusted w.r.t. to integrality information
10112 */
10114 SCIP* scip, /**< SCIP data structure */
10115 SCIP_VAR* var, /**< variable to change the bound for */
10116 SCIP_VARTYPE vartype, /**< new type of variable */
10117 SCIP_Bool* infeasible /**< pointer to store whether an infeasibility was detected (, due to
10118 * integrality condition of the new variable type) */
10119 )
10120{
10122
10123 assert(var != NULL);
10124 assert(var->scip == scip);
10125
10126 if( SCIPvarIsNegated(var) )
10127 {
10128 SCIPdebugMsg(scip, "upgrading type of negated variable <%s> from %d to %d\n", SCIPvarGetName(var), SCIPvarGetType(var), vartype);
10129 var = SCIPvarGetNegationVar(var);
10130 }
10131#ifndef NDEBUG
10132 else
10133 {
10135 {
10136 SCIPdebugMsg(scip, "upgrading type of variable <%s> from %d to %d\n", SCIPvarGetName(var), SCIPvarGetType(var), vartype);
10137 }
10138 }
10139#endif
10140
10141 /* change variable type */
10142 switch( scip->set->stage )
10143 {
10144 case SCIP_STAGE_PROBLEM:
10145 assert(!SCIPvarIsTransformed(var));
10146
10147 /* first adjust the variable due to new integrality information */
10148 SCIP_CALL( tightenBounds(scip, var, SCIPvarIsIntegral(var), infeasible) );
10149
10150 /* second change variable type */
10151 if( SCIPvarGetProbindex(var) >= 0 )
10152 {
10153 SCIP_CALL( SCIPprobChgVarType(scip->origprob, scip->mem->probmem, scip->set, scip->primal, scip->lp,
10154 scip->branchcand, scip->eventqueue, scip->cliquetable, var, vartype) );
10155 }
10156 else
10157 {
10158 SCIP_CALL( SCIPvarChgType(var, scip->mem->probmem, scip->set, scip->primal, scip->lp,
10159 scip->eventqueue, vartype) );
10160 }
10161 break;
10162
10164 if( !SCIPvarIsTransformed(var) )
10165 {
10166 SCIP_VAR* transvar;
10167
10168 SCIP_CALL( SCIPgetTransformedVar(scip, var, &transvar) );
10169 assert(transvar != NULL);
10170
10171 /* recall method with transformed variable */
10172 SCIP_CALL( SCIPchgVarType(scip, transvar, vartype, infeasible) );
10173 return SCIP_OKAY;
10174 }
10175
10176 /* first adjust the variable due to new integrality information */
10177 SCIP_CALL( tightenBounds(scip, var, SCIPvarIsIntegral(var), infeasible) );
10178
10179 /* second change variable type */
10180 if( SCIPvarGetProbindex(var) >= 0 )
10181 {
10182 SCIP_CALL( SCIPprobChgVarType(scip->transprob, scip->mem->probmem, scip->set, scip->primal, scip->lp,
10183 scip->branchcand, scip->eventqueue, scip->cliquetable, var, vartype) );
10184 }
10185 else
10186 {
10187 SCIP_CALL( SCIPvarChgType(var, scip->mem->probmem, scip->set, scip->primal, scip->lp,
10188 scip->eventqueue, vartype) );
10189 }
10190 break;
10191
10192 default:
10193 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
10194 return SCIP_INVALIDCALL;
10195 } /*lint !e788*/
10196
10197 return SCIP_OKAY;
10198}
10199
10200/** changes implied integral type of variable in the problem
10201 *
10202 * @warning This type change might change the variable array returned from SCIPgetVars() and SCIPgetVarsData();
10203 *
10204 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
10205 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
10206 *
10207 * @pre This method can be called if @p scip is in one of the following stages:
10208 * - \ref SCIP_STAGE_PROBLEM
10209 * - \ref SCIP_STAGE_TRANSFORMING
10210 * - \ref SCIP_STAGE_PRESOLVING
10211 *
10212 * @note If SCIP is already beyond the SCIP_STAGE_PROBLEM and a original variable is passed, the implied integral type of the
10213 * corresponding transformed variable is changed; the type of the original variable does not change
10214 *
10215 * @note If the implied integral type is adjusted to weak or strong for a continuous variable, the bounds of the variable get
10216 * adjusted w.r.t. to integrality information
10217 */
10219 SCIP* scip, /**< SCIP data structure */
10220 SCIP_VAR* var, /**< variable to change the type for */
10221 SCIP_IMPLINTTYPE impltype, /**< new type of variable */
10222 SCIP_Bool* infeasible /**< pointer to store whether an infeasibility was detected (, due to
10223 * integrality condition of the new variable type) */
10224 )
10225{
10226 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarImplType", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
10227
10228 assert(var != NULL);
10229 assert(var->scip == scip);
10230
10231 if( SCIPvarIsNegated(var) )
10232 {
10233 SCIPdebugMsg(scip, "changing implied integral type of negated variable <%s> from %d to %d\n", SCIPvarGetName(var), SCIPvarGetImplType(var), impltype);
10234 var = SCIPvarGetNegationVar(var);
10235 }
10236#ifndef NDEBUG
10237 else
10238 {
10240 {
10241 SCIPdebugMsg(scip, "changing implied integral type of variable <%s> from %d to %d\n", SCIPvarGetName(var), SCIPvarGetImplType(var), impltype);
10242 }
10243 }
10244#endif
10245
10246 /* change variable type */
10247 switch( scip->set->stage )
10248 {
10249 case SCIP_STAGE_PROBLEM:
10250 assert(!SCIPvarIsTransformed(var));
10251
10252 /* first adjust the variable due to new integrality information */
10253 SCIP_CALL( tightenBounds(scip, var, impltype != SCIP_IMPLINTTYPE_NONE, infeasible) );
10254
10255 /* second change variable type */
10256 if( SCIPvarGetProbindex(var) >= 0 )
10257 {
10258 SCIP_CALL( SCIPprobChgVarImplType(scip->origprob, scip->mem->probmem, scip->set, scip->primal, scip->lp,
10259 scip->branchcand, scip->eventqueue, scip->cliquetable, var, impltype) );
10260 }
10261 else
10262 {
10263 SCIP_CALL( SCIPvarChgImplType(var, scip->mem->probmem, scip->set, scip->primal, scip->lp,
10264 scip->eventqueue, impltype) );
10265 }
10266 break;
10267
10269 if( !SCIPvarIsTransformed(var) )
10270 {
10271 SCIP_VAR* transvar;
10272
10273 SCIP_CALL( SCIPgetTransformedVar(scip, var, &transvar) );
10274 assert(transvar != NULL);
10275
10276 /* recall method with transformed variable */
10277 SCIP_CALL( SCIPchgVarImplType(scip, transvar, impltype, infeasible) );
10278 return SCIP_OKAY;
10279 }
10280
10281 /* first adjust the variable due to new integrality information */
10282 SCIP_CALL( tightenBounds(scip, var, impltype != SCIP_IMPLINTTYPE_NONE, infeasible) );
10283
10284 /* second change variable type */
10285 if( SCIPvarGetProbindex(var) >= 0 )
10286 {
10287 SCIP_CALL( SCIPprobChgVarImplType(scip->transprob, scip->mem->probmem, scip->set, scip->primal, scip->lp,
10288 scip->branchcand, scip->eventqueue, scip->cliquetable, var, impltype) );
10289 }
10290 else
10291 {
10292 SCIP_CALL( SCIPvarChgImplType(var, scip->mem->probmem, scip->set, scip->primal, scip->lp,
10293 scip->eventqueue, impltype) );
10294 }
10295 break;
10296
10297 default:
10298 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
10299 return SCIP_INVALIDCALL;
10300 } /*lint !e788*/
10301
10302 return SCIP_OKAY;
10303}
10304
10305/** in problem creation and solving stage, both bounds of the variable are set to the given value;
10306 * in presolving stage, the variable is converted into a fixed variable, and bounds are changed respectively;
10307 * conversion into a fixed variable changes the vars array returned from SCIPgetVars() and SCIPgetVarsData(),
10308 * and also renders arrays returned from the SCIPvarGetImpl...() methods invalid
10309 *
10310 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
10311 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
10312 *
10313 * @pre This method can be called if @p scip is in one of the following stages:
10314 * - \ref SCIP_STAGE_PROBLEM
10315 * - \ref SCIP_STAGE_PRESOLVING
10316 * - \ref SCIP_STAGE_SOLVING
10317 */
10319 SCIP* scip, /**< SCIP data structure */
10320 SCIP_VAR* var, /**< variable to fix */
10321 SCIP_Real fixedval, /**< value to fix variable to */
10322 SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
10323 SCIP_Bool* fixed /**< pointer to store whether the fixing was performed (variable was unfixed) */
10324 )
10325{
10326 assert(var != NULL);
10327 assert(infeasible != NULL);
10328 assert(fixed != NULL);
10329
10331
10332 *infeasible = FALSE;
10333 *fixed = FALSE;
10334
10335 /* in the problem creation stage, modify the bounds as requested, independently from the current bounds */
10336 if( scip->set->stage != SCIP_STAGE_PROBLEM )
10337 {
10339 {
10340 *infeasible = !SCIPsetIsFeasEQ(scip->set, fixedval, SCIPvarGetLbLocal(var));
10341 return SCIP_OKAY;
10342 }
10343 else if( ( SCIPvarIsIntegral(var) && !SCIPsetIsFeasIntegral(scip->set, fixedval) )
10344 || SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetLbLocal(var))
10345 || SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
10346 {
10347 *infeasible = TRUE;
10348 return SCIP_OKAY;
10349 }
10350 }
10351 else
10353
10354 switch( scip->set->stage )
10355 {
10356 case SCIP_STAGE_PROBLEM:
10357 /* in the problem creation stage, modify the bounds as requested, independently from the current bounds */
10358 SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
10359 SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
10360 *fixed = TRUE;
10361 return SCIP_OKAY;
10362
10364 if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
10365 {
10366 SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
10367 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
10368 scip->cliquetable, fixedval, infeasible, fixed) );
10369 return SCIP_OKAY;
10370 }
10371 /*lint -fallthrough*/
10372 case SCIP_STAGE_SOLVING:
10373 if( SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetLbLocal(var)) )
10374 {
10375 if( SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
10376 {
10377 *infeasible = TRUE;
10378 return SCIP_OKAY;
10379 }
10380 else
10381 {
10382 SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
10383 *fixed = TRUE;
10384 }
10385 }
10386 if( SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
10387 {
10388 if( SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetLbLocal(var)) )
10389 {
10390 *infeasible = TRUE;
10391 return SCIP_OKAY;
10392 }
10393 else
10394 {
10395 SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
10396 *fixed = TRUE;
10397 }
10398 }
10399 return SCIP_OKAY;
10400
10401 default:
10402 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
10403 return SCIP_INVALIDCALL;
10404 } /*lint !e788*/
10405}
10406
10407/** in problem creation and solving stage, both bounds of the variable are set to the given value;
10408 * in presolving stage, the variable is converted into a fixed variable, and bounds are changed respectively;
10409 * conversion into a fixed variable changes the vars array returned from SCIPgetVars() and SCIPgetVarsData(),
10410 * and also renders arrays returned from the SCIPvarGetImpl...() methods invalid
10411 *
10412 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
10413 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
10414 *
10415 * @pre This method can be called if @p scip is in one of the following stages:
10416 * - \ref SCIP_STAGE_PROBLEM
10417 * - \ref SCIP_STAGE_PRESOLVING
10418 * - \ref SCIP_STAGE_SOLVING
10419 */
10421 SCIP* scip, /**< SCIP data structure */
10422 SCIP_VAR* var, /**< variable to fix */
10423 SCIP_RATIONAL* fixedval, /**< value to fix variable to */
10424 SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
10425 SCIP_Bool* fixed /**< pointer to store whether the fixing was performed (variable was unfixed) */
10426 )
10427{
10428 assert(var != NULL);
10429 assert(infeasible != NULL);
10430 assert(fixed != NULL);
10431 assert(SCIPisExact(scip));
10432 assert(var->exactdata != NULL);
10433
10434 if( !SCIPisExact(scip) )
10435 return SCIP_OKAY;
10436
10438
10439 *infeasible = FALSE;
10440 *fixed = FALSE;
10441
10442 /* in the problem creation stage, modify the bounds as requested, independently from the current bounds */
10443 if( scip->set->stage != SCIP_STAGE_PROBLEM )
10444 {
10446 || SCIPrationalIsLT(fixedval, SCIPvarGetLbLocalExact(var))
10447 || SCIPrationalIsGT(fixedval, SCIPvarGetUbLocalExact(var)) )
10448 {
10449 *infeasible = TRUE;
10450 return SCIP_OKAY;
10451 }
10452 else if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED )
10453 {
10454 *infeasible = !SCIPrationalIsEQ(fixedval, SCIPvarGetLbLocalExact(var));
10455 return SCIP_OKAY;
10456 }
10457 }
10458 else
10460
10461 switch( scip->set->stage )
10462 {
10463 case SCIP_STAGE_PROBLEM:
10464 /* in the problem creation stage, modify the bounds as requested, independently from the current bounds;
10465 * we have to make sure, that the order of the bound changes does not intermediately produce an invalid
10466 * interval lb > ub
10467 */
10468 if( SCIPrationalIsLE(fixedval, SCIPvarGetLbLocalExact(var)) )
10469 {
10472 *fixed = TRUE;
10473 }
10474 else
10475 {
10478 *fixed = TRUE;
10479 }
10480 return SCIP_OKAY;
10481
10483 if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
10484 {
10485 SCIP_CALL( SCIPvarFixExact(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
10486 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
10487 scip->cliquetable, fixedval, infeasible, fixed) );
10488 return SCIP_OKAY;
10489 }
10490 /*lint -fallthrough*/
10491 case SCIP_STAGE_SOLVING:
10492 if( SCIPrationalIsGT(fixedval, SCIPvarGetLbLocalExact(var)) )
10493 {
10494 if( SCIPrationalIsGT(fixedval, SCIPvarGetUbLocalExact(var)) )
10495 {
10496 *infeasible = TRUE;
10497 return SCIP_OKAY;
10498 }
10499 else
10500 {
10502 *fixed = TRUE;
10503 }
10504 }
10505 if( SCIPrationalIsLT(fixedval, SCIPvarGetUbLocalExact(var)) )
10506 {
10507 if( SCIPrationalIsLT(fixedval, SCIPvarGetLbLocalExact(var)) )
10508 {
10509 *infeasible = TRUE;
10510 return SCIP_OKAY;
10511 }
10512 else
10513 {
10515 *fixed = TRUE;
10516 }
10517 }
10518 return SCIP_OKAY;
10519
10520 default:
10521 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
10522 return SCIP_INVALIDCALL;
10523 } /*lint !e788*/
10524}
10525
10526/** From a given equality a*x + b*y == c, aggregates one of the variables and removes it from the set of
10527 * active problem variables. This changes the vars array returned from SCIPgetVars() and SCIPgetVarsData(),
10528 * and also renders the arrays returned from the SCIPvarGetImpl...() methods for the two variables invalid.
10529 * In the first step, the equality is transformed into an equality with active problem variables
10530 * a'*x' + b'*y' == c'. If x' == y', this leads to the detection of redundancy if a' == -b' and c' == 0,
10531 * of infeasibility, if a' == -b' and c' != 0, or to a variable fixing x' == c'/(a'+b') (and possible
10532 * infeasibility) otherwise.
10533 * In the second step, the variable to be aggregated is chosen among x' and y', prefering a less strict variable
10534 * type as aggregation variable (i.e. continuous variables are preferred over implicit integers, implicit integers
10535 * over integers, and integers over binaries). If none of the variables is continuous, it is tried to find an integer
10536 * aggregation (i.e. integral coefficients a'' and b'', such that a''*x' + b''*y' == c''). This can lead to
10537 * the detection of infeasibility (e.g. if c'' is fractional), or to a rejection of the aggregation (denoted by
10538 * aggregated == FALSE), if the resulting integer coefficients are too large and thus numerically instable.
10539 *
10540 * The output flags have the following meaning:
10541 * - infeasible: the problem is infeasible
10542 * - redundant: the equality can be deleted from the constraint set
10543 * - aggregated: the aggregation was successfully performed (the variables were not aggregated before)
10544 *
10545 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
10546 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
10547 *
10548 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PRESOLVING
10549 */
10551 SCIP* scip, /**< SCIP data structure */
10552 SCIP_VAR* varx, /**< variable x in equality a*x + b*y == c */
10553 SCIP_VAR* vary, /**< variable y in equality a*x + b*y == c */
10554 SCIP_Real scalarx, /**< multiplier a in equality a*x + b*y == c */
10555 SCIP_Real scalary, /**< multiplier b in equality a*x + b*y == c */
10556 SCIP_Real rhs, /**< right hand side c in equality a*x + b*y == c */
10557 SCIP_Bool* infeasible, /**< pointer to store whether the aggregation is infeasible */
10558 SCIP_Bool* redundant, /**< pointer to store whether the equality is (now) redundant */
10559 SCIP_Bool* aggregated /**< pointer to store whether the aggregation was successful */
10560 )
10561{
10562 SCIP_Real constantx;
10563 SCIP_Real constanty;
10564
10565 assert(infeasible != NULL);
10566 assert(redundant != NULL);
10567 assert(aggregated != NULL);
10568
10570
10571 *infeasible = FALSE;
10572 *redundant = FALSE;
10573 *aggregated = FALSE;
10574
10575 if( SCIPtreeProbing(scip->tree) )
10576 {
10577 SCIPerrorMessage("cannot aggregate variables during probing\n");
10578 return SCIP_INVALIDCALL;
10579 }
10580 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
10581
10582 /* do not perform aggregation if it is globally deactivated */
10583 if( scip->set->presol_donotaggr )
10584 return SCIP_OKAY;
10585
10586 /* get the corresponding equality in active problem variable space:
10587 * transform both expressions "a*x + 0" and "b*y + 0" into problem variable space
10588 */
10589 constantx = 0.0;
10590 constanty = 0.0;
10591 SCIP_CALL( SCIPvarGetProbvarSum(&varx, scip->set, &scalarx, &constantx) );
10592 SCIP_CALL( SCIPvarGetProbvarSum(&vary, scip->set, &scalary, &constanty) );
10593
10594 /* we cannot aggregate multi-aggregated variables */
10596 return SCIP_OKAY;
10597
10598 /* move the constant to the right hand side to acquire the form "a'*x' + b'*y' == c'" */
10599 rhs -= (constantx + constanty);
10600
10601 /* if a scalar is zero, treat the variable as fixed-to-zero variable */
10602 if( SCIPsetIsZero(scip->set, scalarx) )
10603 varx = NULL;
10604 if( SCIPsetIsZero(scip->set, scalary) )
10605 vary = NULL;
10606
10607 /* capture the special cases that less than two variables are left, due to resolutions to a fixed variable or
10608 * to the same active variable
10609 */
10610 if( varx == NULL && vary == NULL )
10611 {
10612 /* both variables were resolved to fixed variables */
10613 *infeasible = !SCIPsetIsZero(scip->set, rhs);
10614 *redundant = TRUE;
10615 }
10616 else if( varx == NULL )
10617 {
10618 assert(SCIPsetIsZero(scip->set, scalarx));
10619 assert(!SCIPsetIsZero(scip->set, scalary));
10620
10621 /* variable x was resolved to fixed variable: variable y can be fixed to c'/b' */
10622 SCIP_CALL( SCIPvarFix(vary, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
10623 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
10624 scip->cliquetable, rhs/scalary, infeasible, aggregated) );
10625 *redundant = TRUE;
10626 }
10627 else if( vary == NULL )
10628 {
10629 assert(SCIPsetIsZero(scip->set, scalary));
10630 assert(!SCIPsetIsZero(scip->set, scalarx));
10631
10632 /* variable y was resolved to fixed variable: variable x can be fixed to c'/a' */
10633 SCIP_CALL( SCIPvarFix(varx, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
10634 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
10635 scip->cliquetable, rhs/scalarx, infeasible, aggregated) );
10636 *redundant = TRUE;
10637 }
10638 else if( varx == vary )
10639 {
10640 /* both variables were resolved to the same active problem variable: this variable can be fixed */
10641 scalarx += scalary;
10642 if( SCIPsetIsZero(scip->set, scalarx) )
10643 {
10644 /* left hand side of equality is zero: equality is potentially infeasible */
10645 *infeasible = !SCIPsetIsZero(scip->set, rhs);
10646 }
10647 else
10648 {
10649 /* sum of scalars is not zero: fix variable x' == y' to c'/(a'+b') */
10650 SCIP_CALL( SCIPvarFix(varx, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
10651 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
10652 scip->cliquetable, rhs/scalarx, infeasible, aggregated) );
10653 }
10654 *redundant = TRUE;
10655 }
10656 else
10657 {
10658 /* both variables are different active problem variables, and both scalars are non-zero: try to aggregate them */
10659 SCIP_CALL( SCIPvarTryAggregateVars(scip->set, scip->mem->probmem, scip->stat, scip->transprob, scip->origprob,
10660 scip->primal, scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue,
10661 scip->eventfilter, varx, vary, scalarx, scalary, rhs, infeasible, aggregated) );
10662 *redundant = *aggregated;
10663 }
10664
10665 return SCIP_OKAY;
10666}
10667
10668/** From a given equality a*x + b*y == c, aggregates one of the variables and removes it from the set of
10669 * active problem variables. This changes the vars array returned from SCIPgetVars() and SCIPgetVarsData(),
10670 * and also renders the arrays returned from the SCIPvarGetImpl...() methods for the two variables invalid.
10671 * In the first step, the equality is transformed into an equality with active problem variables
10672 * a'*x' + b'*y' == c'. If x' == y', this leads to the detection of redundancy if a' == -b' and c' == 0,
10673 * of infeasibility, if a' == -b' and c' != 0, or to a variable fixing x' == c'/(a'+b') (and possible
10674 * infeasibility) otherwise.
10675 * In the second step, the variable to be aggregated is chosen among x' and y', prefering a less strict variable
10676 * type as aggregation variable (i.e. continuous variables are preferred over implicit integers, implicit integers
10677 * over integers, and integers over binaries). If none of the variables is continuous, it is tried to find an integer
10678 * aggregation (i.e. integral coefficients a'' and b'', such that a''*x' + b''*y' == c''). This can lead to
10679 * the detection of infeasibility (e.g. if c'' is fractional), or to a rejection of the aggregation (denoted by
10680 * aggregated == FALSE), if the resulting integer coefficients are too large and thus numerically instable.
10681 *
10682 * The output flags have the following meaning:
10683 * - infeasible: the problem is infeasible
10684 * - redundant: the equality can be deleted from the constraint set
10685 * - aggregated: the aggregation was successfully performed (the variables were not aggregated before)
10686 *
10687 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
10688 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
10689 *
10690 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PRESOLVING
10691 */
10693 SCIP* scip, /**< SCIP data structure */
10694 SCIP_VAR* varx, /**< variable x in equality a*x + b*y == c */
10695 SCIP_VAR* vary, /**< variable y in equality a*x + b*y == c */
10696 SCIP_RATIONAL* scalarx, /**< multiplier a in equality a*x + b*y == c */
10697 SCIP_RATIONAL* scalary, /**< multiplier b in equality a*x + b*y == c */
10698 SCIP_RATIONAL* rhs, /**< right hand side c in equality a*x + b*y == c */
10699 SCIP_Bool* infeasible, /**< pointer to store whether the aggregation is infeasible */
10700 SCIP_Bool* redundant, /**< pointer to store whether the equality is (now) redundant */
10701 SCIP_Bool* aggregated /**< pointer to store whether the aggregation was successful */
10702 )
10703{
10704 SCIP_RATIONAL* constantx;
10705 SCIP_RATIONAL* constanty;
10706
10709
10710 assert(infeasible != NULL);
10711 assert(redundant != NULL);
10712 assert(aggregated != NULL);
10713
10714 SCIP_CALL( SCIPcheckStage(scip, "SCIPaggregateVarsExact", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
10715
10716 *infeasible = FALSE;
10717 *redundant = FALSE;
10718 *aggregated = FALSE;
10719
10720 if( SCIPtreeProbing(scip->tree) )
10721 {
10722 SCIPerrorMessage("cannot aggregate variables during probing\n");
10723 return SCIP_INVALIDCALL;
10724 }
10725 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
10726
10727 /* do not perform aggregation if it is globally deactivated */
10728 if( scip->set->presol_donotaggr )
10729 return SCIP_OKAY;
10730
10731 /* get the corresponding equality in active problem variable space:
10732 * transform both expressions "a*x + 0" and "b*y + 0" into problem variable space
10733 */
10734 SCIP_CALL( SCIPvarGetProbvarSumExact(&varx, scalarx, constantx) );
10735 SCIP_CALL( SCIPvarGetProbvarSumExact(&vary, scalary, constanty) );
10736
10737 /* we cannot aggregate multi-aggregated variables */
10739 return SCIP_OKAY;
10740
10741 /* move the constant to the right hand side to acquire the form "a'*x' + b'*y' == c'" */
10742 SCIPrationalDiff(rhs, rhs, constantx);
10743 SCIPrationalDiff(rhs, rhs, constanty);
10744
10745 /* if a scalar is zero, treat the variable as fixed-to-zero variable */
10746 if( SCIPrationalIsZero(scalarx) )
10747 varx = NULL;
10748 if( SCIPrationalIsZero(scalary) )
10749 vary = NULL;
10750
10751 /* capture the special cases that less than two variables are left, due to resolutions to a fixed variable or
10752 * to the same active variable
10753 */
10754 if( varx == NULL && vary == NULL )
10755 {
10756 /* both variables were resolved to fixed variables */
10757 *infeasible = !SCIPrationalIsZero(rhs);
10758 *redundant = TRUE;
10759 }
10760 else if( varx == NULL )
10761 {
10762 assert(SCIPrationalIsZero(scalarx));
10763 assert(!SCIPrationalIsZero(scalary));
10764
10765 SCIPrationalDiv(rhs, rhs, scalary);
10766 /* variable x was resolved to fixed variable: variable y can be fixed to c'/b' */
10767 SCIP_CALL( SCIPvarFixExact(vary, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
10768 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
10769 scip->cliquetable, rhs, infeasible, aggregated) );
10770 *redundant = TRUE;
10771 }
10772 else if( vary == NULL )
10773 {
10774 assert(SCIPrationalIsZero(scalarx));
10775 assert(!SCIPrationalIsZero(scalary));
10776
10777 SCIPrationalDiv(rhs, rhs, scalarx);
10778 /* variable y was resolved to fixed variable: variable x can be fixed to c'/a' */
10779 SCIP_CALL( SCIPvarFixExact(varx, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
10780 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
10781 scip->cliquetable, rhs, infeasible, aggregated) );
10782 *redundant = TRUE;
10783 }
10784 else if( varx == vary )
10785 {
10786 /* both variables were resolved to the same active problem variable: this variable can be fixed */
10787 SCIPrationalAdd(scalarx, scalarx, scalary);
10788 if( SCIPrationalIsZero(scalarx) )
10789 {
10790 /* left hand side of equality is zero: equality is potentially infeasible */
10791 *infeasible = !SCIPrationalIsZero(rhs);
10792 }
10793 else
10794 {
10795 SCIPrationalDiv(rhs, rhs, scalarx);
10796 /* sum of scalars is not zero: fix variable x' == y' to c'/(a'+b') */
10797 SCIP_CALL( SCIPvarFixExact(varx, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
10798 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
10799 scip->cliquetable, rhs, infeasible, aggregated) );
10800 }
10801 *redundant = TRUE;
10802 }
10803 else
10804 {
10805 /* both variables are different active problem variables, and both scalars are non-zero: try to aggregate them */
10806 SCIP_CALL( SCIPvarTryAggregateVarsExact(scip->set, scip->mem->probmem, scip->stat, scip->transprob, scip->origprob,
10807 scip->primal, scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue,
10808 scip->eventfilter, varx, vary, scalarx, scalary, rhs, infeasible, aggregated) );
10809 *redundant = *aggregated;
10810 }
10811
10814
10815 return SCIP_OKAY;
10816}
10817
10818/** converts variable into multi-aggregated variable; this changes the variable array returned from
10819 * SCIPgetVars() and SCIPgetVarsData();
10820 *
10821 * @warning The integrality condition is not checked anymore on the multi-aggregated variable. You must not
10822 * multi-aggregate an integer variable without being sure, that integrality on the aggregation variables
10823 * implies integrality on the aggregated variable.
10824 *
10825 * The output flags have the following meaning:
10826 * - infeasible: the problem is infeasible
10827 * - aggregated: the aggregation was successfully performed (the variables were not aggregated before)
10828 *
10829 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
10830 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
10831 *
10832 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PRESOLVING
10833 */
10835 SCIP* scip, /**< SCIP data structure */
10836 SCIP_VAR* var, /**< variable x to aggregate */
10837 int naggvars, /**< number n of variables in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
10838 SCIP_VAR** aggvars, /**< variables y_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
10839 SCIP_Real* scalars, /**< multipliers a_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
10840 SCIP_Real constant, /**< constant shift c in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
10841 SCIP_Bool* infeasible, /**< pointer to store whether the aggregation is infeasible */
10842 SCIP_Bool* aggregated /**< pointer to store whether the aggregation was successful */
10843 )
10844{
10845 SCIP_CALL( SCIPcheckStage(scip, "SCIPmultiaggregateVar", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
10846
10847 assert(var->scip == scip);
10848
10849 if( SCIPtreeProbing(scip->tree) )
10850 {
10851 SCIPerrorMessage("cannot multi-aggregate variables during probing\n");
10852 return SCIP_INVALIDCALL;
10853 }
10854 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
10855
10856 SCIP_CALL( SCIPvarMultiaggregate(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
10857 scip->primal, scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue,
10858 scip->eventfilter, naggvars, aggvars, scalars, constant, infeasible, aggregated) );
10859
10860 return SCIP_OKAY;
10861}
10862
10863/** converts variable into exact multi-aggregated variable; this changes the variable array returned from
10864 * SCIPgetVars() and SCIPgetVarsData();
10865 *
10866 * @warning The integrality condition is not checked anymore on the multi-aggregated variable. You must not
10867 * multi-aggregate an integer variable without being sure, that integrality on the aggregation variables
10868 * implies integrality on the aggregated variable.
10869 *
10870 * The output flags have the following meaning:
10871 * - infeasible: the problem is infeasible
10872 * - aggregated: the aggregation was successfully performed (the variables were not aggregated before)
10873 *
10874 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
10875 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
10876 *
10877 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PRESOLVING
10878 */
10880 SCIP* scip, /**< SCIP data structure */
10881 SCIP_VAR* var, /**< variable x to aggregate */
10882 int naggvars, /**< number n of variables in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
10883 SCIP_VAR** aggvars, /**< variables y_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
10884 SCIP_RATIONAL** scalars, /**< multipliers a_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
10885 SCIP_RATIONAL* constant, /**< constant shift c in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
10886 SCIP_Bool* infeasible, /**< pointer to store whether the aggregation is infeasible */
10887 SCIP_Bool* aggregated /**< pointer to store whether the aggregation was successful */
10888 )
10889{
10890 SCIP_CALL( SCIPcheckStage(scip, "SCIPmultiaggregateVarExact", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
10891
10892 assert(var->scip == scip);
10893
10894 if( SCIPtreeProbing(scip->tree) )
10895 {
10896 SCIPerrorMessage("cannot multi-aggregate variables during probing\n");
10897 return SCIP_INVALIDCALL;
10898 }
10899 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
10900
10901 SCIP_CALL( SCIPvarMultiaggregateExact(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
10902 scip->primal, scip->tree, scip->reopt, scip->lpexact, scip->cliquetable, scip->branchcand, scip->eventqueue,
10903 scip->eventfilter, naggvars, aggvars, scalars, constant, infeasible, aggregated) );
10904
10905 return SCIP_OKAY;
10906}
10907
10908/** returns whether aggregation of variables is not allowed */
10910 SCIP* scip /**< SCIP data structure */
10911 )
10912{
10913 assert(scip != NULL);
10914
10915 return scip->set->presol_donotaggr;
10916}
10917
10918/** returns whether multi-aggregation is disabled */
10920 SCIP* scip /**< SCIP data structure */
10921 )
10922{
10923 assert(scip != NULL);
10924
10925 return scip->set->presol_donotmultaggr;
10926}
10927
10928/** returns whether variable is not allowed to be aggregated */
10930 SCIP* scip, /**< SCIP data structure */
10931 SCIP_VAR* var /**< variable x to aggregate */
10932 )
10933{
10934 assert(scip != NULL);
10935 assert(var != NULL);
10936 assert(var->scip == scip);
10937
10938 return scip->set->presol_donotaggr || SCIPvarDoNotAggr(var);
10939}
10940
10941/** returns whether variable is not allowed to be multi-aggregated */
10943 SCIP* scip, /**< SCIP data structure */
10944 SCIP_VAR* var /**< variable x to aggregate */
10945 )
10946{
10947 assert(scip != NULL);
10948 assert(var != NULL);
10949 assert(var->scip == scip);
10950
10951 return scip->set->presol_donotmultaggr || SCIPvarDoNotMultaggr(var);
10952}
10953
10954/** checks whether a loose variable can be used in a new aggregation with given coefficient
10955 *
10956 * Checks whether multiplying the bounds on the coefficient with which the variable appears in aggregations
10957 * (SCIPvarGetMinAggrCoef(), SCIPvarGetMaxAggrCoef()) by the given scalar would exceed acceptable values
10958 * (numerics/sumepsilon and 1.0 / numerics/sumepsilon).
10959 *
10960 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PRESOLVING
10961 */
10963 SCIP* scip, /**< SCIP data structure */
10964 SCIP_VAR* var, /**< problem variable */
10965 SCIP_Real scalar /**< aggregation scalar */
10966 )
10967{
10968 assert(scip != NULL);
10969 assert(var != NULL);
10970 assert(scalar != 0.0);
10971 assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
10972
10973 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisVarAggrCoefAcceptable", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
10974
10975 return SCIPvarIsAggrCoefAcceptable(scip->set, var, scalar);
10976}
10977
10978/** returns whether strong dual reductions are allowed during propagation and presolving
10979 *
10980 * @note A reduction is called strong dual, if it may discard feasible/optimal solutions, but leaves at least one
10981 * optimal solution intact. Often such reductions are based on analyzing the objective function and variable
10982 * locks.
10983 */
10985 SCIP* scip /**< SCIP data structure */
10986 )
10987{
10988 assert(scip != NULL);
10989
10990 return !scip->set->reopt_enable && scip->set->misc_allowstrongdualreds;
10991}
10992
10993/** returns whether weak dual reductions are allowed during propagation and presolving
10994 *
10995 * @note A reduction is called weak dual, if it may discard feasible solutions, but leaves at all optimal solutions
10996 * intact. Often such reductions are based on analyzing the objective function, reduced costs, and/or dual LPs.
10997 */
10999 SCIP* scip /**< SCIP data structure */
11000 )
11001{
11002 assert(scip != NULL);
11003
11004 return !scip->set->reopt_enable && scip->set->misc_allowweakdualreds;
11005}
11006
11007/** marks the variable that it must not be aggregated
11008 *
11009 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
11010 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
11011 *
11012 * @pre This method can be called if @p scip is in one of the following stages:
11013 * - \ref SCIP_STAGE_INIT
11014 * - \ref SCIP_STAGE_PROBLEM
11015 * - \ref SCIP_STAGE_TRANSFORMING
11016 * - \ref SCIP_STAGE_TRANSFORMED
11017 * - \ref SCIP_STAGE_INITPRESOLVE
11018 * - \ref SCIP_STAGE_PRESOLVING
11019 * - \ref SCIP_STAGE_EXITPRESOLVE
11020 *
11021 * @note There exists no "unmark" method since it has to be ensured that if a plugin requires that a variable is not
11022 * aggregated that this is will be the case.
11023 */
11025 SCIP* scip, /**< SCIP data structure */
11026 SCIP_VAR* var /**< variable to delete */
11027 )
11028{
11029 assert(scip != NULL);
11030 assert(var != NULL);
11031 assert(var->scip == scip);
11032
11033 SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkDoNotAggrVar", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE) );
11034
11036
11037 return SCIP_OKAY;
11038}
11039
11040/** marks the variable that it must not be multi-aggregated
11041 *
11042 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
11043 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
11044 *
11045 * @pre This method can be called if @p scip is in one of the following stages:
11046 * - \ref SCIP_STAGE_INIT
11047 * - \ref SCIP_STAGE_PROBLEM
11048 * - \ref SCIP_STAGE_TRANSFORMING
11049 * - \ref SCIP_STAGE_TRANSFORMED
11050 * - \ref SCIP_STAGE_INITPRESOLVE
11051 * - \ref SCIP_STAGE_PRESOLVING
11052 * - \ref SCIP_STAGE_EXITPRESOLVE
11053 *
11054 * @note There exists no "unmark" method since it has to be ensured that if a plugin requires that a variable is not
11055 * multi-aggregated that this is will be the case.
11056 */
11058 SCIP* scip, /**< SCIP data structure */
11059 SCIP_VAR* var /**< variable to delete */
11060 )
11061{
11062 assert(scip != NULL);
11063 assert(var != NULL);
11064 assert(var->scip == scip);
11065
11066 SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkDoNotMultaggrVar", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE) );
11067
11069
11070 return SCIP_OKAY;
11071}
11072
11073/** enables the collection of statistics for a variable
11074 *
11075 * @pre This method can be called if @p scip is in one of the following stages:
11076 * - \ref SCIP_STAGE_PROBLEM
11077 * - \ref SCIP_STAGE_INITPRESOLVE
11078 * - \ref SCIP_STAGE_PRESOLVING
11079 * - \ref SCIP_STAGE_EXITPRESOLVE
11080 * - \ref SCIP_STAGE_SOLVING
11081 * - \ref SCIP_STAGE_SOLVED
11082 */
11084 SCIP* scip /**< SCIP data structure */
11085 )
11086{
11087 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPenableVarHistory", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11088
11090}
11091
11092/** disables the collection of any statistic for a variable
11093 *
11094 * @pre This method can be called if @p scip is in one of the following stages:
11095 * - \ref SCIP_STAGE_PROBLEM
11096 * - \ref SCIP_STAGE_INITPRESOLVE
11097 * - \ref SCIP_STAGE_PRESOLVING
11098 * - \ref SCIP_STAGE_EXITPRESOLVE
11099 * - \ref SCIP_STAGE_SOLVING
11100 * - \ref SCIP_STAGE_SOLVED
11101 */
11103 SCIP* scip /**< SCIP data structure */
11104 )
11105{
11106 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPdisableVarHistory", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11107
11109}
11110
11111/** updates the pseudo costs of the given variable and the global pseudo costs after a change of "solvaldelta" in the
11112 * variable's solution value and resulting change of "objdelta" in the in the LP's objective value;
11113 * the update is ignored, if the objective value difference is infinite
11114 *
11115 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
11116 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
11117 *
11118 * @pre This method can be called if @p scip is in one of the following stages:
11119 * - \ref SCIP_STAGE_SOLVING
11120 * - \ref SCIP_STAGE_SOLVED
11121 */
11123 SCIP* scip, /**< SCIP data structure */
11124 SCIP_VAR* var, /**< problem variable */
11125 SCIP_Real solvaldelta, /**< difference of variable's new LP value - old LP value */
11126 SCIP_Real objdelta, /**< difference of new LP's objective value - old LP's objective value */
11127 SCIP_Real weight /**< weight in (0,1] of this update in pseudo cost sum */
11128 )
11129{
11130 SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateVarPseudocost", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11131
11132 if( !SCIPsetIsInfinity(scip->set, 2*objdelta) ) /* differences infinity - eps should also be treated as infinity */
11133 {
11134 if( scip->set->branch_divingpscost || (!scip->lp->diving && !SCIPtreeProbing(scip->tree)) )
11135 {
11136 SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, solvaldelta, objdelta, weight) );
11137 }
11138 }
11139
11140 return SCIP_OKAY;
11141}
11142
11143/** updates the ancestor pseudo costs of the given variable and the global ancestor pseudo costs after a change of "solvaldelta" in the
11144 * variable's solution value and resulting change of "objdelta" in the in the LP's objective value;
11145 * the update is ignored, if the objective value difference is infinite
11146 *
11147 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
11148 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
11149 *
11150 * @pre This method can be called if @p scip is in one of the following stages:
11151 * - \ref SCIP_STAGE_SOLVING
11152 * - \ref SCIP_STAGE_SOLVED
11153 */
11155 SCIP* scip, /**< SCIP data structure */
11156 SCIP_VAR* var, /**< problem variable */
11157 SCIP_Real solvaldelta, /**< difference of variable's new LP value - old LP value */
11158 SCIP_Real objdelta, /**< difference of new LP's objective value - old LP's objective value */
11159 SCIP_Real weight /**< weight in (0,1] of this update in pseudo cost sum */
11160 )
11161{
11162 SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateVarAncPseudocost", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11163
11164 if( !SCIPsetIsInfinity(scip->set, 2*objdelta) ) /* differences infinity - eps should also be treated as infinity */
11165 {
11166 if( scip->set->branch_divingpscost || (!scip->lp->diving && !SCIPtreeProbing(scip->tree)) )
11167 {
11168 SCIP_CALL( SCIPvarUpdateAncPseudocost(var, scip->set, scip->stat, solvaldelta, objdelta, weight) );
11169 }
11170 }
11171
11172 return SCIP_OKAY;
11173}
11174
11175/** gets the variable's pseudo cost value for the given change of the variable's LP value
11176 *
11177 * @return the variable's pseudo cost value for the given change of the variable's LP value
11178 *
11179 * @pre This method can be called if @p scip is in one of the following stages:
11180 * - \ref SCIP_STAGE_INITPRESOLVE
11181 * - \ref SCIP_STAGE_PRESOLVING
11182 * - \ref SCIP_STAGE_EXITPRESOLVE
11183 * - \ref SCIP_STAGE_PRESOLVED
11184 * - \ref SCIP_STAGE_INITSOLVE
11185 * - \ref SCIP_STAGE_SOLVING
11186 * - \ref SCIP_STAGE_SOLVED
11187 */
11189 SCIP* scip, /**< SCIP data structure */
11190 SCIP_VAR* var, /**< problem variable */
11191 SCIP_Real solvaldelta /**< difference of variable's new LP value - old LP value */
11192 )
11193{
11194 assert( var->scip == scip );
11195
11196 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostVal", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11197
11198 return SCIPvarGetPseudocost(var, scip->stat, solvaldelta);
11199}
11200
11201/** gets the variable's ancestral pseudo cost value for the given change of the variable's LP value
11202 *
11203 * @return the variable's ancestral pseudo cost value for the given change of the variable's LP value
11204 *
11205 * @pre This method can be called if @p scip is in one of the following stages:
11206 * - \ref SCIP_STAGE_INITPRESOLVE
11207 * - \ref SCIP_STAGE_PRESOLVING
11208 * - \ref SCIP_STAGE_EXITPRESOLVE
11209 * - \ref SCIP_STAGE_PRESOLVED
11210 * - \ref SCIP_STAGE_INITSOLVE
11211 * - \ref SCIP_STAGE_SOLVING
11212 * - \ref SCIP_STAGE_SOLVED
11213 */
11215 SCIP* scip, /**< SCIP data structure */
11216 SCIP_VAR* var, /**< problem variable */
11217 SCIP_Real solvaldelta /**< difference of variable's new LP value - old LP value */
11218 )
11219{
11220 assert( var->scip == scip );
11221
11222 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAncPseudocostVal", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11223
11224 return SCIPvarGetAncPseudocost(var, scip->stat, solvaldelta);
11225}
11226
11227/** gets the variable's pseudo cost value for the given change of the variable's LP value,
11228 * only using the pseudo cost information of the current run
11229 *
11230 * @return the variable's pseudo cost value for the given change of the variable's LP value,
11231 * only using the pseudo cost information of the current run
11232 *
11233 * @pre This method can be called if @p scip is in one of the following stages:
11234 * - \ref SCIP_STAGE_INITPRESOLVE
11235 * - \ref SCIP_STAGE_PRESOLVING
11236 * - \ref SCIP_STAGE_EXITPRESOLVE
11237 * - \ref SCIP_STAGE_PRESOLVED
11238 * - \ref SCIP_STAGE_INITSOLVE
11239 * - \ref SCIP_STAGE_SOLVING
11240 * - \ref SCIP_STAGE_SOLVED
11241 */
11243 SCIP* scip, /**< SCIP data structure */
11244 SCIP_VAR* var, /**< problem variable */
11245 SCIP_Real solvaldelta /**< difference of variable's new LP value - old LP value */
11246 )
11247{
11248 assert( var->scip == scip );
11249
11250 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostValCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11251
11252 return SCIPvarGetPseudocostCurrentRun(var, scip->stat, solvaldelta);
11253}
11254
11255/** gets the variable's pseudo cost value for the given direction
11256 *
11257 * @return the variable's pseudo cost value for the given direction
11258 *
11259 * @pre This method can be called if @p scip is in one of the following stages:
11260 * - \ref SCIP_STAGE_INITPRESOLVE
11261 * - \ref SCIP_STAGE_PRESOLVING
11262 * - \ref SCIP_STAGE_EXITPRESOLVE
11263 * - \ref SCIP_STAGE_PRESOLVED
11264 * - \ref SCIP_STAGE_INITSOLVE
11265 * - \ref SCIP_STAGE_SOLVING
11266 * - \ref SCIP_STAGE_SOLVED
11267 */
11269 SCIP* scip, /**< SCIP data structure */
11270 SCIP_VAR* var, /**< problem variable */
11271 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
11272 )
11273{
11274 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocost", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11275 assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
11276 assert(var->scip == scip);
11277
11278 return SCIPvarGetPseudocost(var, scip->stat, dir == SCIP_BRANCHDIR_DOWNWARDS ? -1.0 : 1.0);
11279}
11280
11281/** gets the variable's pseudo cost value for the given direction,
11282 * only using the pseudo cost information of the current run
11283 *
11284 * @return the variable's pseudo cost value for the given direction,
11285 * only using the pseudo cost information of the current run
11286 *
11287 * @pre This method can be called if @p scip is in one of the following stages:
11288 * - \ref SCIP_STAGE_INITPRESOLVE
11289 * - \ref SCIP_STAGE_PRESOLVING
11290 * - \ref SCIP_STAGE_EXITPRESOLVE
11291 * - \ref SCIP_STAGE_PRESOLVED
11292 * - \ref SCIP_STAGE_INITSOLVE
11293 * - \ref SCIP_STAGE_SOLVING
11294 * - \ref SCIP_STAGE_SOLVED
11295 */
11297 SCIP* scip, /**< SCIP data structure */
11298 SCIP_VAR* var, /**< problem variable */
11299 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
11300 )
11301{
11302 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11303 assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
11304 assert(var->scip == scip);
11305
11306 return SCIPvarGetPseudocostCurrentRun(var, scip->stat, dir == SCIP_BRANCHDIR_DOWNWARDS ? -1.0 : 1.0);
11307}
11308
11309/** gets the variable's (possible fractional) number of pseudo cost updates for the given direction
11310 *
11311 * @return the variable's (possible fractional) number of pseudo cost updates for the given direction
11312 *
11313 * @pre This method can be called if @p scip is in one of the following stages:
11314 * - \ref SCIP_STAGE_INITPRESOLVE
11315 * - \ref SCIP_STAGE_PRESOLVING
11316 * - \ref SCIP_STAGE_EXITPRESOLVE
11317 * - \ref SCIP_STAGE_PRESOLVED
11318 * - \ref SCIP_STAGE_INITSOLVE
11319 * - \ref SCIP_STAGE_SOLVING
11320 * - \ref SCIP_STAGE_SOLVED
11321 */
11323 SCIP* scip, /**< SCIP data structure */
11324 SCIP_VAR* var, /**< problem variable */
11325 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
11326 )
11327{
11328 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCount", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11329 assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
11330 assert(var->scip == scip);
11331
11332 return SCIPvarGetPseudocostCount(var, dir);
11333}
11334
11335/** gets the variable's (possible fractional) number of pseudo cost updates for the given direction,
11336 * only using the pseudo cost information of the current run
11337 *
11338 * @return the variable's (possible fractional) number of pseudo cost updates for the given direction,
11339 * only using the pseudo cost information of the current run
11340 *
11341 * @pre This method can be called if @p scip is in one of the following stages:
11342 * - \ref SCIP_STAGE_INITPRESOLVE
11343 * - \ref SCIP_STAGE_PRESOLVING
11344 * - \ref SCIP_STAGE_EXITPRESOLVE
11345 * - \ref SCIP_STAGE_PRESOLVED
11346 * - \ref SCIP_STAGE_INITSOLVE
11347 * - \ref SCIP_STAGE_SOLVING
11348 * - \ref SCIP_STAGE_SOLVED
11349 */
11351 SCIP* scip, /**< SCIP data structure */
11352 SCIP_VAR* var, /**< problem variable */
11353 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
11354 )
11355{
11356 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCountCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11357 assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
11358 assert(var->scip == scip);
11359
11360 return SCIPvarGetPseudocostCountCurrentRun(var, dir);
11361}
11362
11363/** gets the variable's (possible fractional) number of ancestor pseudo cost updates for the given direction,
11364 * only using the pseudo cost information of the current run
11365 *
11366 * @return the variable's (possible fractional) number of ancestor pseudo cost updates for the given direction,
11367 * only using the pseudo cost information of the current run
11368 *
11369 * @pre This method can be called if @p scip is in one of the following stages:
11370 * - \ref SCIP_STAGE_INITPRESOLVE
11371 * - \ref SCIP_STAGE_PRESOLVING
11372 * - \ref SCIP_STAGE_EXITPRESOLVE
11373 * - \ref SCIP_STAGE_PRESOLVED
11374 * - \ref SCIP_STAGE_INITSOLVE
11375 * - \ref SCIP_STAGE_SOLVING
11376 * - \ref SCIP_STAGE_SOLVED
11377 */
11379 SCIP* scip, /**< SCIP data structure */
11380 SCIP_VAR* var, /**< problem variable */
11381 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
11382 )
11383{
11384 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAncPseudocostCountCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11385 assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
11386 assert(var->scip == scip);
11387
11389}
11390
11391/** get pseudo cost variance of the variable, either for entire solve or only for current branch and bound run
11392 *
11393 * @return returns the (corrected) variance of pseudo code information collected so far.
11394 *
11395 * @pre This method can be called if @p scip is in one of the following stages:
11396 * - \ref SCIP_STAGE_INITPRESOLVE
11397 * - \ref SCIP_STAGE_PRESOLVING
11398 * - \ref SCIP_STAGE_EXITPRESOLVE
11399 * - \ref SCIP_STAGE_PRESOLVED
11400 * - \ref SCIP_STAGE_INITSOLVE
11401 * - \ref SCIP_STAGE_SOLVING
11402 * - \ref SCIP_STAGE_SOLVED
11403 */
11405 SCIP* scip, /**< SCIP data structure */
11406 SCIP_VAR* var, /**< problem variable */
11407 SCIP_BRANCHDIR dir, /**< branching direction (downwards, or upwards) */
11408 SCIP_Bool onlycurrentrun /**< only for pseudo costs of current branch and bound run */
11409 )
11410{
11411 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostVariance", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11412 assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
11413 assert(var->scip == scip);
11414
11415 return SCIPvarGetPseudocostVariance(var, dir, onlycurrentrun);
11416}
11417
11418/** calculates a confidence bound for this variable under the assumption of normally distributed pseudo costs
11419 *
11420 * The confidence bound \f$ \theta \geq 0\f$ denotes the interval borders \f$ [X - \theta, \ X + \theta]\f$, which contains
11421 * the true pseudo costs of the variable, i.e., the expected value of the normal distribution, with a probability
11422 * of 2 * clevel - 1.
11423 *
11424 * @return value of confidence bound for this variable
11425 */
11427 SCIP* scip, /**< SCIP data structure */
11428 SCIP_VAR* var, /**< variable in question */
11429 SCIP_BRANCHDIR dir, /**< the branching direction for the confidence bound */
11430 SCIP_Bool onlycurrentrun, /**< should only the current run be taken into account */
11431 SCIP_CONFIDENCELEVEL clevel /**< confidence level for the interval */
11432 )
11433{
11434 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPcalculatePscostConfidenceBound", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11435
11436 return SCIPvarCalcPscostConfidenceBound(var, scip->set, dir, onlycurrentrun, clevel);
11437}
11438
11439/** check if variable pseudo-costs have a significant difference in location. The significance depends on
11440 * the choice of \p clevel and on the kind of tested hypothesis. The one-sided hypothesis, which
11441 * should be rejected, is that fracy * mu_y >= fracx * mu_x, where mu_y and mu_x denote the
11442 * unknown location means of the underlying pseudo-cost distributions of x and y.
11443 *
11444 * This method is applied best if variable x has a better pseudo-cost score than y. The method hypothesizes that y were actually
11445 * better than x (despite the current information), meaning that y can be expected to yield branching
11446 * decisions as least as good as x in the long run. If the method returns TRUE, the current history information is
11447 * sufficient to safely rely on the alternative hypothesis that x yields indeed a better branching score (on average)
11448 * than y.
11449 *
11450 * @note The order of x and y matters for the one-sided hypothesis
11451 *
11452 * @note set \p onesided to FALSE if you are not sure which variable is better. The hypothesis tested then reads
11453 * fracy * mu_y == fracx * mu_x vs the alternative hypothesis fracy * mu_y != fracx * mu_x.
11454 *
11455 * @return TRUE if the hypothesis can be safely rejected at the given confidence level
11456 */
11458 SCIP* scip, /**< SCIP data structure */
11459 SCIP_VAR* varx, /**< variable x */
11460 SCIP_Real fracx, /**< the fractionality of variable x */
11461 SCIP_VAR* vary, /**< variable y */
11462 SCIP_Real fracy, /**< the fractionality of variable y */
11463 SCIP_BRANCHDIR dir, /**< branching direction */
11464 SCIP_CONFIDENCELEVEL clevel, /**< confidence level for rejecting hypothesis */
11465 SCIP_Bool onesided /**< should a one-sided hypothesis y >= x be tested? */
11466 )
11467{
11468 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPsignificantVarPscostDifference", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11469
11470 return SCIPvarSignificantPscostDifference(scip->set, scip->stat, varx, fracx, vary, fracy, dir, clevel, onesided);
11471}
11472
11473/** tests at a given confidence level whether the variable pseudo-costs only have a small probability to
11474 * exceed a \p threshold. This is useful to determine if past observations provide enough evidence
11475 * to skip an expensive strong-branching step if there is already a candidate that has been proven to yield an improvement
11476 * of at least \p threshold.
11477 *
11478 * @note use \p clevel to adjust the level of confidence. For SCIP_CONFIDENCELEVEL_MIN, the method returns TRUE if
11479 * the estimated probability to exceed \p threshold is less than 25 %.
11480 *
11481 * @see SCIP_Confidencelevel for a list of available levels. The used probability limits refer to the one-sided levels
11482 * of confidence.
11483 *
11484 * @return TRUE if the variable pseudo-cost probabilistic model is likely to be smaller than \p threshold
11485 * at the given confidence level \p clevel.
11486 */
11488 SCIP* scip, /**< SCIP data structure */
11489 SCIP_VAR* var, /**< variable x */
11490 SCIP_Real frac, /**< the fractionality of variable x */
11491 SCIP_Real threshold, /**< the threshold to test against */
11492 SCIP_BRANCHDIR dir, /**< branching direction */
11493 SCIP_CONFIDENCELEVEL clevel /**< confidence level for rejecting hypothesis */
11494 )
11495{
11496 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPpscostThresholdProbabilityTest", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11497
11498 return SCIPvarPscostThresholdProbabilityTest(scip->set, scip->stat, var, frac, threshold, dir, clevel);
11499}
11500
11501/** check if the current pseudo cost relative error in a direction violates the given threshold. The Relative
11502 * Error is calculated at a specific confidence level
11503 *
11504 * @return TRUE if relative error in variable pseudo costs is smaller than \p threshold
11505 */
11507 SCIP* scip, /**< SCIP data structure */
11508 SCIP_VAR* var, /**< variable in question */
11509 SCIP_Real threshold, /**< threshold for relative errors to be considered reliable (enough) */
11510 SCIP_CONFIDENCELEVEL clevel /**< a given confidence level */
11511 )
11512{
11513 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisVarPscostRelerrorReliable", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11514
11515 return SCIPvarIsPscostRelerrorReliable(var, scip->set, scip->stat, threshold, clevel);
11516}
11517
11518/** gets the variable's pseudo cost score value for the given LP solution value
11519 *
11520 * @return the variable's pseudo cost score value for the given LP solution value
11521 *
11522 * @pre This method can be called if @p scip is in one of the following stages:
11523 * - \ref SCIP_STAGE_INITPRESOLVE
11524 * - \ref SCIP_STAGE_PRESOLVING
11525 * - \ref SCIP_STAGE_EXITPRESOLVE
11526 * - \ref SCIP_STAGE_PRESOLVED
11527 * - \ref SCIP_STAGE_INITSOLVE
11528 * - \ref SCIP_STAGE_SOLVING
11529 * - \ref SCIP_STAGE_SOLVED
11530 */
11532 SCIP* scip, /**< SCIP data structure */
11533 SCIP_VAR* var, /**< problem variable */
11534 SCIP_Real solval /**< variable's LP solution value */
11535 )
11536{
11537 SCIP_Real downsol;
11538 SCIP_Real upsol;
11539 SCIP_Real pscostdown;
11540 SCIP_Real pscostup;
11541
11542 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11543
11544 assert( var->scip == scip );
11545
11546 downsol = SCIPsetFeasCeil(scip->set, solval-1.0);
11547 upsol = SCIPsetFeasFloor(scip->set, solval+1.0);
11548 pscostdown = SCIPvarGetPseudocost(var, scip->stat, downsol-solval);
11549 pscostup = SCIPvarGetPseudocost(var, scip->stat, upsol-solval);
11550
11551 return SCIPbranchGetScore(scip->set, var, pscostdown, pscostup);
11552}
11553
11554/** gets the variable's discounted pseudo cost score value for the given LP solution value.
11555 *
11556 * This combines both pscost and ancpscost fields.
11557 *
11558 * @return the variable's discounted pseudo cost score value for the given LP solution value,
11559 * combining both pscost and ancpscost fields.
11560 *
11561 * @pre This method can be called if @p scip is in one of the following stages:
11562 * - \ref SCIP_STAGE_INITPRESOLVE
11563 * - \ref SCIP_STAGE_PRESOLVING
11564 * - \ref SCIP_STAGE_EXITPRESOLVE
11565 * - \ref SCIP_STAGE_PRESOLVED
11566 * - \ref SCIP_STAGE_INITSOLVE
11567 * - \ref SCIP_STAGE_SOLVING
11568 * - \ref SCIP_STAGE_SOLVED
11569 */
11571 SCIP* scip, /**< SCIP data structure */
11572 SCIP_VAR* var, /**< problem variable */
11573 SCIP_Real solval, /**< variable's LP solution value */
11574 SCIP_Real discountfac /**< discount factor for discounted pseudocost */
11575 )
11576{
11577 SCIP_Real downsol;
11578 SCIP_Real upsol;
11579 SCIP_Real pscostdown;
11580 SCIP_Real pscostup;
11581
11582 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarDPseudocostScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11583
11584 assert( var->scip == scip );
11585
11586 downsol = SCIPsetFeasCeil(scip->set, solval-1.0);
11587 upsol = SCIPsetFeasFloor(scip->set, solval+1.0);
11588 pscostdown = SCIPvarGetPseudocost(var, scip->stat, downsol-solval)
11589 + discountfac * SCIPvarGetAncPseudocost(var, scip->stat, downsol-solval);
11590 pscostup = SCIPvarGetPseudocost(var, scip->stat, upsol-solval)
11591 + discountfac * SCIPvarGetAncPseudocost(var, scip->stat, upsol-solval);
11592 pscostdown /= (1 + discountfac);
11593 pscostup /= (1 + discountfac);
11594
11595 return SCIPbranchGetScore(scip->set, var, pscostdown, pscostup);
11596}
11597
11598/** gets the variable's pseudo cost score value for the given LP solution value,
11599 * only using the pseudo cost information of the current run
11600 *
11601 * @return the variable's pseudo cost score value for the given LP solution value,
11602 * only using the pseudo cost information of the current run
11603 *
11604 * @pre This method can be called if @p scip is in one of the following stages:
11605 * - \ref SCIP_STAGE_INITPRESOLVE
11606 * - \ref SCIP_STAGE_PRESOLVING
11607 * - \ref SCIP_STAGE_EXITPRESOLVE
11608 * - \ref SCIP_STAGE_PRESOLVED
11609 * - \ref SCIP_STAGE_INITSOLVE
11610 * - \ref SCIP_STAGE_SOLVING
11611 * - \ref SCIP_STAGE_SOLVED
11612 */
11614 SCIP* scip, /**< SCIP data structure */
11615 SCIP_VAR* var, /**< problem variable */
11616 SCIP_Real solval /**< variable's LP solution value */
11617 )
11618{
11619 SCIP_Real downsol;
11620 SCIP_Real upsol;
11621 SCIP_Real pscostdown;
11622 SCIP_Real pscostup;
11623
11624 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11625
11626 assert( var->scip == scip );
11627
11628 downsol = SCIPsetFeasCeil(scip->set, solval-1.0);
11629 upsol = SCIPsetFeasFloor(scip->set, solval+1.0);
11630 pscostdown = SCIPvarGetPseudocostCurrentRun(var, scip->stat, downsol-solval);
11631 pscostup = SCIPvarGetPseudocostCurrentRun(var, scip->stat, upsol-solval);
11632
11633 return SCIPbranchGetScore(scip->set, var, pscostdown, pscostup);
11634}
11635
11636/** returns the variable's VSIDS value
11637 *
11638 * @return the variable's VSIDS value
11639 *
11640 * @pre This method can be called if @p scip is in one of the following stages:
11641 * - \ref SCIP_STAGE_INITPRESOLVE
11642 * - \ref SCIP_STAGE_PRESOLVING
11643 * - \ref SCIP_STAGE_EXITPRESOLVE
11644 * - \ref SCIP_STAGE_PRESOLVED
11645 * - \ref SCIP_STAGE_INITSOLVE
11646 * - \ref SCIP_STAGE_SOLVING
11647 * - \ref SCIP_STAGE_SOLVED
11648 */
11650 SCIP* scip, /**< SCIP data structure */
11651 SCIP_VAR* var, /**< problem variable */
11652 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
11653 )
11654{
11656
11657 assert( var->scip == scip );
11658
11660 {
11661 SCIPerrorMessage("invalid branching direction %d when asking for VSIDS value\n", dir);
11662 return SCIP_INVALID;
11663 }
11664
11665 return SCIPvarGetVSIDS(var, scip->stat, dir);
11666}
11667
11668/** returns the variable's VSIDS value only using conflicts of the current run
11669 *
11670 * @return the variable's VSIDS value only using conflicts of the current run
11671 *
11672 * @pre This method can be called if @p scip is in one of the following stages:
11673 * - \ref SCIP_STAGE_INITPRESOLVE
11674 * - \ref SCIP_STAGE_PRESOLVING
11675 * - \ref SCIP_STAGE_EXITPRESOLVE
11676 * - \ref SCIP_STAGE_PRESOLVED
11677 * - \ref SCIP_STAGE_INITSOLVE
11678 * - \ref SCIP_STAGE_SOLVING
11679 * - \ref SCIP_STAGE_SOLVED
11680 */
11682 SCIP* scip, /**< SCIP data structure */
11683 SCIP_VAR* var, /**< problem variable */
11684 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
11685 )
11686{
11687 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarVSIDSCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11688
11689 assert( var->scip == scip );
11690
11692 {
11693 SCIPerrorMessage("invalid branching direction %d when asking for VSIDS value\n", dir);
11694 return SCIP_INVALID;
11695 }
11696
11697 return SCIPvarGetVSIDSCurrentRun(var, scip->stat, dir);
11698}
11699
11700/** returns the variable's conflict score value
11701 *
11702 * @return the variable's conflict score value
11703 *
11704 * @pre This method can be called if @p scip is in one of the following stages:
11705 * - \ref SCIP_STAGE_INITPRESOLVE
11706 * - \ref SCIP_STAGE_PRESOLVING
11707 * - \ref SCIP_STAGE_EXITPRESOLVE
11708 * - \ref SCIP_STAGE_PRESOLVED
11709 * - \ref SCIP_STAGE_INITSOLVE
11710 * - \ref SCIP_STAGE_SOLVING
11711 * - \ref SCIP_STAGE_SOLVED
11712 */
11714 SCIP* scip, /**< SCIP data structure */
11715 SCIP_VAR* var /**< problem variable */
11716 )
11717{
11718 SCIP_Real downscore;
11719 SCIP_Real upscore;
11720
11721 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11722
11723 assert( var->scip == scip );
11724
11725 downscore = SCIPvarGetVSIDS(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
11726 upscore = SCIPvarGetVSIDS(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
11727
11728 return SCIPbranchGetScore(scip->set, var, downscore, upscore);
11729}
11730
11731/** returns the variable's conflict score value only using conflicts of the current run
11732 *
11733 * @return the variable's conflict score value only using conflicts of the current run
11734 *
11735 * @pre This method can be called if @p scip is in one of the following stages:
11736 * - \ref SCIP_STAGE_INITPRESOLVE
11737 * - \ref SCIP_STAGE_PRESOLVING
11738 * - \ref SCIP_STAGE_EXITPRESOLVE
11739 * - \ref SCIP_STAGE_PRESOLVED
11740 * - \ref SCIP_STAGE_INITSOLVE
11741 * - \ref SCIP_STAGE_SOLVING
11742 * - \ref SCIP_STAGE_SOLVED
11743 */
11745 SCIP* scip, /**< SCIP data structure */
11746 SCIP_VAR* var /**< problem variable */
11747 )
11748{
11749 SCIP_Real downscore;
11750 SCIP_Real upscore;
11751
11752 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11753
11754 assert( var->scip == scip );
11755
11758
11759 return SCIPbranchGetScore(scip->set, var, downscore, upscore);
11760}
11761
11762/** returns the variable's conflict length score
11763 *
11764 * @return the variable's conflict length score
11765 *
11766 * @pre This method can be called if @p scip is in one of the following stages:
11767 * - \ref SCIP_STAGE_INITPRESOLVE
11768 * - \ref SCIP_STAGE_PRESOLVING
11769 * - \ref SCIP_STAGE_EXITPRESOLVE
11770 * - \ref SCIP_STAGE_PRESOLVED
11771 * - \ref SCIP_STAGE_INITSOLVE
11772 * - \ref SCIP_STAGE_SOLVING
11773 * - \ref SCIP_STAGE_SOLVED
11774 */
11776 SCIP* scip, /**< SCIP data structure */
11777 SCIP_VAR* var /**< problem variable */
11778 )
11779{
11780 SCIP_Real downscore;
11781 SCIP_Real upscore;
11782
11783 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictlengthScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11784
11785 assert( var->scip == scip );
11786
11789
11790 return SCIPbranchGetScore(scip->set, var, downscore, upscore);
11791}
11792
11793/** returns the variable's conflict length score only using conflicts of the current run
11794 *
11795 * @return the variable's conflict length score only using conflicts of the current run
11796 *
11797 * @pre This method can be called if @p scip is in one of the following stages:
11798 * - \ref SCIP_STAGE_INITPRESOLVE
11799 * - \ref SCIP_STAGE_PRESOLVING
11800 * - \ref SCIP_STAGE_EXITPRESOLVE
11801 * - \ref SCIP_STAGE_PRESOLVED
11802 * - \ref SCIP_STAGE_INITSOLVE
11803 * - \ref SCIP_STAGE_SOLVING
11804 * - \ref SCIP_STAGE_SOLVED
11805 */
11807 SCIP* scip, /**< SCIP data structure */
11808 SCIP_VAR* var /**< problem variable */
11809 )
11810{
11811 SCIP_Real downscore;
11812 SCIP_Real upscore;
11813
11814 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictlengthScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11815
11816 assert( var->scip == scip );
11817
11820
11821 return SCIPbranchGetScore(scip->set, var, downscore, upscore);
11822}
11823
11824/** returns the variable's average conflict length
11825 *
11826 * @return the variable's average conflict length
11827 *
11828 * @pre This method can be called if @p scip is in one of the following stages:
11829 * - \ref SCIP_STAGE_INITPRESOLVE
11830 * - \ref SCIP_STAGE_PRESOLVING
11831 * - \ref SCIP_STAGE_EXITPRESOLVE
11832 * - \ref SCIP_STAGE_PRESOLVED
11833 * - \ref SCIP_STAGE_INITSOLVE
11834 * - \ref SCIP_STAGE_SOLVING
11835 * - \ref SCIP_STAGE_SOLVED
11836 */
11838 SCIP* scip, /**< SCIP data structure */
11839 SCIP_VAR* var, /**< problem variable */
11840 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
11841 )
11842{
11843 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgConflictlength", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11844
11845 assert( var->scip == scip );
11846
11847 return SCIPvarGetAvgConflictlength(var, dir);
11848}
11849
11850/** returns the variable's average conflict length only using conflicts of the current run
11851 *
11852 * @return the variable's average conflict length only using conflicts of the current run
11853 *
11854 * @pre This method can be called if @p scip is in one of the following stages:
11855 * - \ref SCIP_STAGE_INITPRESOLVE
11856 * - \ref SCIP_STAGE_PRESOLVING
11857 * - \ref SCIP_STAGE_EXITPRESOLVE
11858 * - \ref SCIP_STAGE_PRESOLVED
11859 * - \ref SCIP_STAGE_INITSOLVE
11860 * - \ref SCIP_STAGE_SOLVING
11861 * - \ref SCIP_STAGE_SOLVED
11862 */
11864 SCIP* scip, /**< SCIP data structure */
11865 SCIP_VAR* var, /**< problem variable */
11866 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
11867 )
11868{
11869 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgConflictlengthCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11870
11871 assert( var->scip == scip );
11872
11874}
11875
11876/** returns the average number of inferences found after branching on the variable in given direction;
11877 * if branching on the variable in the given direction was yet evaluated, the average number of inferences
11878 * over all variables for branching in the given direction is returned
11879 *
11880 * @return the average number of inferences found after branching on the variable in given direction
11881 *
11882 * @pre This method can be called if @p scip is in one of the following stages:
11883 * - \ref SCIP_STAGE_INITPRESOLVE
11884 * - \ref SCIP_STAGE_PRESOLVING
11885 * - \ref SCIP_STAGE_EXITPRESOLVE
11886 * - \ref SCIP_STAGE_PRESOLVED
11887 * - \ref SCIP_STAGE_INITSOLVE
11888 * - \ref SCIP_STAGE_SOLVING
11889 * - \ref SCIP_STAGE_SOLVED
11890 */
11892 SCIP* scip, /**< SCIP data structure */
11893 SCIP_VAR* var, /**< problem variable */
11894 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
11895 )
11896{
11897 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferences", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11898
11899 assert( var->scip == scip );
11900
11901 return SCIPvarGetAvgInferences(var, scip->stat, dir);
11902}
11903
11904/** returns the average number of inferences found after branching on the variable in given direction in the current run;
11905 * if branching on the variable in the given direction was yet evaluated, the average number of inferences
11906 * over all variables for branching in the given direction is returned
11907 *
11908 * @return the average number of inferences found after branching on the variable in given direction in the current run
11909 *
11910 * @pre This method can be called if @p scip is in one of the following stages:
11911 * - \ref SCIP_STAGE_INITPRESOLVE
11912 * - \ref SCIP_STAGE_PRESOLVING
11913 * - \ref SCIP_STAGE_EXITPRESOLVE
11914 * - \ref SCIP_STAGE_PRESOLVED
11915 * - \ref SCIP_STAGE_INITSOLVE
11916 * - \ref SCIP_STAGE_SOLVING
11917 * - \ref SCIP_STAGE_SOLVED
11918 */
11920 SCIP* scip, /**< SCIP data structure */
11921 SCIP_VAR* var, /**< problem variable */
11922 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
11923 )
11924{
11925 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferencesCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11926
11927 assert( var->scip == scip );
11928
11929 return SCIPvarGetAvgInferencesCurrentRun(var, scip->stat, dir);
11930}
11931
11932/** returns the variable's average inference score value
11933 *
11934 * @return the variable's average inference score value
11935 *
11936 * @pre This method can be called if @p scip is in one of the following stages:
11937 * - \ref SCIP_STAGE_INITPRESOLVE
11938 * - \ref SCIP_STAGE_PRESOLVING
11939 * - \ref SCIP_STAGE_EXITPRESOLVE
11940 * - \ref SCIP_STAGE_PRESOLVED
11941 * - \ref SCIP_STAGE_INITSOLVE
11942 * - \ref SCIP_STAGE_SOLVING
11943 * - \ref SCIP_STAGE_SOLVED
11944 */
11946 SCIP* scip, /**< SCIP data structure */
11947 SCIP_VAR* var /**< problem variable */
11948 )
11949{
11950 SCIP_Real inferdown;
11951 SCIP_Real inferup;
11952
11953 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11954
11955 assert( var->scip == scip );
11956
11957 inferdown = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
11959
11960 return SCIPbranchGetScore(scip->set, var, inferdown, inferup);
11961}
11962
11963/** returns the variable's average inference score value only using inferences of the current run
11964 *
11965 * @return the variable's average inference score value only using inferences of the current run
11966 *
11967 * @pre This method can be called if @p scip is in one of the following stages:
11968 * - \ref SCIP_STAGE_INITPRESOLVE
11969 * - \ref SCIP_STAGE_PRESOLVING
11970 * - \ref SCIP_STAGE_EXITPRESOLVE
11971 * - \ref SCIP_STAGE_PRESOLVED
11972 * - \ref SCIP_STAGE_INITSOLVE
11973 * - \ref SCIP_STAGE_SOLVING
11974 * - \ref SCIP_STAGE_SOLVED
11975 */
11977 SCIP* scip, /**< SCIP data structure */
11978 SCIP_VAR* var /**< problem variable */
11979 )
11980{
11981 SCIP_Real inferdown;
11982 SCIP_Real inferup;
11983
11984 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
11985
11986 assert( var->scip == scip );
11987
11990
11991 return SCIPbranchGetScore(scip->set, var, inferdown, inferup);
11992}
11993
11994/** initializes the upwards and downwards pseudocosts, conflict scores, conflict lengths, inference scores, cutoff scores
11995 * of a variable to the given values
11996 *
11997 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
11998 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
11999 *
12000 * @pre This method can be called if @p scip is in one of the following stages:
12001 * - \ref SCIP_STAGE_TRANSFORMED
12002 * - \ref SCIP_STAGE_INITPRESOLVE
12003 * - \ref SCIP_STAGE_PRESOLVING
12004 * - \ref SCIP_STAGE_EXITPRESOLVE
12005 * - \ref SCIP_STAGE_PRESOLVED
12006 * - \ref SCIP_STAGE_INITSOLVE
12007 * - \ref SCIP_STAGE_SOLVING
12008 */
12010 SCIP* scip, /**< SCIP data structure */
12011 SCIP_VAR* var, /**< variable which should be initialized */
12012 SCIP_Real downpscost, /**< value to which pseudocosts for downwards branching should be initialized */
12013 SCIP_Real uppscost, /**< value to which pseudocosts for upwards branching should be initialized */
12014 SCIP_Real downvsids, /**< value to which VSIDS score for downwards branching should be initialized */
12015 SCIP_Real upvsids, /**< value to which VSIDS score for upwards branching should be initialized */
12016 SCIP_Real downconflen, /**< value to which conflict length score for downwards branching should be initialized */
12017 SCIP_Real upconflen, /**< value to which conflict length score for upwards branching should be initialized */
12018 SCIP_Real downinfer, /**< value to which inference counter for downwards branching should be initialized */
12019 SCIP_Real upinfer, /**< value to which inference counter for upwards branching should be initialized */
12020 SCIP_Real downcutoff, /**< value to which cutoff counter for downwards branching should be initialized */
12021 SCIP_Real upcutoff /**< value to which cutoff counter for upwards branching should be initialized */
12022 )
12023{
12024 SCIP_CALL( SCIPcheckStage(scip, "SCIPinitVarBranchStats", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
12025
12026 assert(downpscost >= 0.0 && uppscost >= 0.0);
12027 assert(downvsids >= 0.0 && upvsids >= 0.0);
12028 assert(downconflen >= 0.0 && upconflen >= 0.0);
12029 assert(downinfer >= 0.0 && upinfer >= 0.0);
12030 assert(downcutoff >= 0.0 && upcutoff >= 0.0);
12031
12032 if( !SCIPisFeasZero(scip, downpscost) || !SCIPisFeasZero(scip, downvsids)
12033 || !SCIPisFeasZero(scip, downinfer) || !SCIPisFeasZero(scip, downcutoff) )
12034 {
12036 SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, -1.0, downpscost, 1.0) );
12038 SCIP_CALL( SCIPvarIncVSIDS(var, NULL, scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, SCIP_UNKNOWN, downvsids) );
12040 }
12041
12042 if( !SCIPisFeasZero(scip, downconflen) )
12043 {
12045 }
12046
12047 if( !SCIPisFeasZero(scip, uppscost) || !SCIPisFeasZero(scip, upvsids)
12048 || !SCIPisFeasZero(scip, upinfer) || !SCIPisFeasZero(scip, upcutoff) )
12049 {
12051 SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, 1.0, uppscost, 1.0) );
12055 }
12056
12057 if( !SCIPisFeasZero(scip, upconflen) )
12058 {
12060 }
12061
12062 return SCIP_OKAY;
12063}
12064
12065/** initializes the upwards and downwards conflict scores, conflict lengths, inference scores, cutoff scores of a
12066 * variable w.r.t. a value by the given values (SCIP_VALUEHISTORY)
12067 *
12068 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
12069 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
12070 *
12071 * @pre This method can be called if @p scip is in one of the following stages:
12072 * - \ref SCIP_STAGE_TRANSFORMED
12073 * - \ref SCIP_STAGE_INITPRESOLVE
12074 * - \ref SCIP_STAGE_PRESOLVING
12075 * - \ref SCIP_STAGE_EXITPRESOLVE
12076 * - \ref SCIP_STAGE_PRESOLVED
12077 * - \ref SCIP_STAGE_INITSOLVE
12078 * - \ref SCIP_STAGE_SOLVING
12079 */
12081 SCIP* scip, /**< SCIP data structure */
12082 SCIP_VAR* var, /**< variable which should be initialized */
12083 SCIP_Real value, /**< domain value, or SCIP_UNKNOWN */
12084 SCIP_Real downvsids, /**< value to which VSIDS score for downwards branching should be initialized */
12085 SCIP_Real upvsids, /**< value to which VSIDS score for upwards branching should be initialized */
12086 SCIP_Real downconflen, /**< value to which conflict length score for downwards branching should be initialized */
12087 SCIP_Real upconflen, /**< value to which conflict length score for upwards branching should be initialized */
12088 SCIP_Real downinfer, /**< value to which inference counter for downwards branching should be initialized */
12089 SCIP_Real upinfer, /**< value to which inference counter for upwards branching should be initialized */
12090 SCIP_Real downcutoff, /**< value to which cutoff counter for downwards branching should be initialized */
12091 SCIP_Real upcutoff /**< value to which cutoff counter for upwards branching should be initialized */
12092 )
12093{
12094 SCIP_CALL( SCIPcheckStage(scip, "SCIPinitVarValueBranchStats", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
12095
12096 assert(downvsids >= 0.0 && upvsids >= 0.0);
12097 assert(downconflen >= 0.0 && upconflen >= 0.0);
12098 assert(downinfer >= 0.0 && upinfer >= 0.0);
12099 assert(downcutoff >= 0.0 && upcutoff >= 0.0);
12100
12101 if( !SCIPisFeasZero(scip, downvsids) || !SCIPisFeasZero(scip, downinfer) || !SCIPisFeasZero(scip, downcutoff) )
12102 {
12104 SCIP_CALL( SCIPvarIncInferenceSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downinfer) );
12105 SCIP_CALL( SCIPvarIncVSIDS(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downvsids) );
12106 SCIP_CALL( SCIPvarIncCutoffSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downcutoff) );
12107 }
12108
12109 if( !SCIPisFeasZero(scip, downconflen) )
12110 {
12111 SCIP_CALL( SCIPvarIncNActiveConflicts(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downconflen) );
12112 }
12113
12114 if( !SCIPisFeasZero(scip, upvsids) || !SCIPisFeasZero(scip, upinfer) || !SCIPisFeasZero(scip, upcutoff) )
12115 {
12117 SCIP_CALL( SCIPvarIncInferenceSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upinfer) );
12118 SCIP_CALL( SCIPvarIncVSIDS(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upvsids) );
12119 SCIP_CALL( SCIPvarIncCutoffSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upcutoff) );
12120 }
12121
12122 if( !SCIPisFeasZero(scip, upconflen) )
12123 {
12124 SCIP_CALL( SCIPvarIncNActiveConflicts(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upconflen) );
12125 }
12126
12127 return SCIP_OKAY;
12128}
12129
12130/** returns the average number of cutoffs found after branching on the variable in given direction;
12131 * if branching on the variable in the given direction was yet evaluated, the average number of cutoffs
12132 * over all variables for branching in the given direction is returned
12133 *
12134 * @return the average number of cutoffs found after branching on the variable in given direction
12135 *
12136 * @pre This method can be called if @p scip is in one of the following stages:
12137 * - \ref SCIP_STAGE_INITPRESOLVE
12138 * - \ref SCIP_STAGE_PRESOLVING
12139 * - \ref SCIP_STAGE_EXITPRESOLVE
12140 * - \ref SCIP_STAGE_PRESOLVED
12141 * - \ref SCIP_STAGE_INITSOLVE
12142 * - \ref SCIP_STAGE_SOLVING
12143 * - \ref SCIP_STAGE_SOLVED
12144 */
12146 SCIP* scip, /**< SCIP data structure */
12147 SCIP_VAR* var, /**< problem variable */
12148 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
12149 )
12150{
12151 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffs", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
12152
12153 assert( var->scip == scip );
12154
12155 return SCIPvarGetAvgCutoffs(var, scip->stat, dir);
12156}
12157
12158/** returns the average number of cutoffs found after branching on the variable in given direction in the current run;
12159 * if branching on the variable in the given direction was yet evaluated, the average number of cutoffs
12160 * over all variables for branching in the given direction is returned
12161 *
12162 * @return the average number of cutoffs found after branching on the variable in given direction in the current run
12163 *
12164 * @pre This method can be called if @p scip is in one of the following stages:
12165 * - \ref SCIP_STAGE_INITPRESOLVE
12166 * - \ref SCIP_STAGE_PRESOLVING
12167 * - \ref SCIP_STAGE_EXITPRESOLVE
12168 * - \ref SCIP_STAGE_PRESOLVED
12169 * - \ref SCIP_STAGE_INITSOLVE
12170 * - \ref SCIP_STAGE_SOLVING
12171 * - \ref SCIP_STAGE_SOLVED
12172 */
12174 SCIP* scip, /**< SCIP data structure */
12175 SCIP_VAR* var, /**< problem variable */
12176 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
12177 )
12178{
12179 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffsCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
12180
12181 assert( var->scip == scip );
12182
12183 return SCIPvarGetAvgCutoffsCurrentRun(var, scip->stat, dir);
12184}
12185
12186/** returns the variable's average cutoff score value
12187 *
12188 * @return the variable's average cutoff score value
12189 *
12190 * @pre This method can be called if @p scip is in one of the following stages:
12191 * - \ref SCIP_STAGE_INITPRESOLVE
12192 * - \ref SCIP_STAGE_PRESOLVING
12193 * - \ref SCIP_STAGE_EXITPRESOLVE
12194 * - \ref SCIP_STAGE_PRESOLVED
12195 * - \ref SCIP_STAGE_INITSOLVE
12196 * - \ref SCIP_STAGE_SOLVING
12197 * - \ref SCIP_STAGE_SOLVED
12198 */
12200 SCIP* scip, /**< SCIP data structure */
12201 SCIP_VAR* var /**< problem variable */
12202 )
12203{
12204 SCIP_Real cutoffdown;
12205 SCIP_Real cutoffup;
12206
12207 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
12208
12209 assert( var->scip == scip );
12210
12211 cutoffdown = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
12212 cutoffup = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
12213
12214 return SCIPbranchGetScore(scip->set, var, cutoffdown, cutoffup);
12215}
12216
12217/** returns the variable's average cutoff score value, only using cutoffs of the current run
12218 *
12219 * @return the variable's average cutoff score value, only using cutoffs of the current run
12220 *
12221 * @pre This method can be called if @p scip is in one of the following stages:
12222 * - \ref SCIP_STAGE_INITPRESOLVE
12223 * - \ref SCIP_STAGE_PRESOLVING
12224 * - \ref SCIP_STAGE_EXITPRESOLVE
12225 * - \ref SCIP_STAGE_PRESOLVED
12226 * - \ref SCIP_STAGE_INITSOLVE
12227 * - \ref SCIP_STAGE_SOLVING
12228 * - \ref SCIP_STAGE_SOLVED
12229 */
12231 SCIP* scip, /**< SCIP data structure */
12232 SCIP_VAR* var /**< problem variable */
12233 )
12234{
12235 SCIP_Real cutoffdown;
12236 SCIP_Real cutoffup;
12237
12238 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
12239
12240 assert( var->scip == scip );
12241
12244
12245 return SCIPbranchGetScore(scip->set, var, cutoffdown, cutoffup);
12246}
12247
12248/** returns the variable's average inference/cutoff score value, weighting the cutoffs of the variable with the given
12249 * factor
12250 *
12251 * @return the variable's average inference/cutoff score value
12252 *
12253 * @pre This method can be called if @p scip is in one of the following stages:
12254 * - \ref SCIP_STAGE_INITPRESOLVE
12255 * - \ref SCIP_STAGE_PRESOLVING
12256 * - \ref SCIP_STAGE_EXITPRESOLVE
12257 * - \ref SCIP_STAGE_PRESOLVED
12258 * - \ref SCIP_STAGE_INITSOLVE
12259 * - \ref SCIP_STAGE_SOLVING
12260 * - \ref SCIP_STAGE_SOLVED
12261 */
12263 SCIP* scip, /**< SCIP data structure */
12264 SCIP_VAR* var, /**< problem variable */
12265 SCIP_Real cutoffweight /**< factor to weigh average number of cutoffs in branching score */
12266 )
12267{
12268 SCIP_Real avginferdown;
12269 SCIP_Real avginferup;
12270 SCIP_Real avginfer;
12271 SCIP_Real inferdown;
12272 SCIP_Real inferup;
12273 SCIP_Real cutoffdown;
12274 SCIP_Real cutoffup;
12275
12276 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceCutoffScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
12277
12278 assert( var->scip == scip );
12279
12280 avginferdown = SCIPhistoryGetAvgInferences(scip->stat->glbhistory, SCIP_BRANCHDIR_DOWNWARDS);
12281 avginferup = SCIPhistoryGetAvgInferences(scip->stat->glbhistory, SCIP_BRANCHDIR_UPWARDS);
12282 avginfer = (avginferdown + avginferup)/2.0;
12283 inferdown = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
12285 cutoffdown = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
12286 cutoffup = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
12287
12288 return SCIPbranchGetScore(scip->set, var,
12289 inferdown + cutoffweight * avginfer * cutoffdown, inferup + cutoffweight * avginfer * cutoffup);
12290}
12291
12292/** returns the variable's average inference/cutoff score value, weighting the cutoffs of the variable with the given
12293 * factor, only using inferences and cutoffs of the current run
12294 *
12295 * @return the variable's average inference/cutoff score value, only using inferences and cutoffs of the current run
12296 *
12297 * @pre This method can be called if @p scip is in one of the following stages:
12298 * - \ref SCIP_STAGE_INITPRESOLVE
12299 * - \ref SCIP_STAGE_PRESOLVING
12300 * - \ref SCIP_STAGE_EXITPRESOLVE
12301 * - \ref SCIP_STAGE_PRESOLVED
12302 * - \ref SCIP_STAGE_INITSOLVE
12303 * - \ref SCIP_STAGE_SOLVING
12304 * - \ref SCIP_STAGE_SOLVED
12305 */
12307 SCIP* scip, /**< SCIP data structure */
12308 SCIP_VAR* var, /**< problem variable */
12309 SCIP_Real cutoffweight /**< factor to weigh average number of cutoffs in branching score */
12310 )
12311{
12312 SCIP_Real avginferdown;
12313 SCIP_Real avginferup;
12314 SCIP_Real avginfer;
12315 SCIP_Real inferdown;
12316 SCIP_Real inferup;
12317 SCIP_Real cutoffdown;
12318 SCIP_Real cutoffup;
12319
12320 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceCutoffScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
12321
12322 assert( var->scip == scip );
12323
12324 avginferdown = SCIPhistoryGetAvgInferences(scip->stat->glbhistorycrun, SCIP_BRANCHDIR_DOWNWARDS);
12325 avginferup = SCIPhistoryGetAvgInferences(scip->stat->glbhistorycrun, SCIP_BRANCHDIR_UPWARDS);
12326 avginfer = (avginferdown + avginferup)/2.0;
12331
12332 return SCIPbranchGetScore(scip->set, var,
12333 inferdown + cutoffweight * avginfer * cutoffdown, inferup + cutoffweight * avginfer * cutoffup);
12334}
12335
12336/** returns the variable's average GMI efficacy score value
12337 *
12338 * @return the variable's average GMI efficacy score value
12339 *
12340 * @pre This method can be called if @p scip is in one of the following stages:
12341 * - \ref SCIP_STAGE_INITPRESOLVE
12342 * - \ref SCIP_STAGE_PRESOLVING
12343 * - \ref SCIP_STAGE_EXITPRESOLVE
12344 * - \ref SCIP_STAGE_PRESOLVED
12345 * - \ref SCIP_STAGE_INITSOLVE
12346 * - \ref SCIP_STAGE_SOLVING
12347 * - \ref SCIP_STAGE_SOLVED
12348 */
12350 SCIP* scip, /**< SCIP data structure */
12351 SCIP_VAR* var /**< problem variable */
12352 )
12353{
12354 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgGMIScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
12355
12356 assert( var->scip == scip );
12357
12358 return SCIPvarGetAvgGMIScore(var, scip->stat);
12359}
12360
12361/** sets the variable's average GMI efficacy score value
12362 *
12363 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
12364 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
12365 *
12366 * @pre This method can be called if @p scip is in one of the following stages:
12367 * - \ref SCIP_STAGE_INITPRESOLVE
12368 * - \ref SCIP_STAGE_PRESOLVING
12369 * - \ref SCIP_STAGE_EXITPRESOLVE
12370 * - \ref SCIP_STAGE_PRESOLVED
12371 * - \ref SCIP_STAGE_INITSOLVE
12372 * - \ref SCIP_STAGE_SOLVING
12373 * - \ref SCIP_STAGE_SOLVED
12374 */
12376 SCIP* scip, /**< SCIP data structure */
12377 SCIP_VAR* var, /**< problem variable */
12378 SCIP_Real gmieff /**< Efficacy of last GMI cut generated from when var was basic /frac */
12379 )
12380{
12381 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPincVarGMISumScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
12382
12383 assert( var->scip == scip );
12384
12385 SCIP_CALL( SCIPvarIncGMIeffSum(var, scip->stat, gmieff) );
12386
12387 return SCIP_OKAY;
12388}
12389
12390/** returns the variable's last GMI efficacy score value
12391 *
12392 * @return the variable's last GMI efficacy score value
12393 *
12394 * @pre This method can be called if @p scip is in one of the following stages:
12395 * - \ref SCIP_STAGE_INITPRESOLVE
12396 * - \ref SCIP_STAGE_PRESOLVING
12397 * - \ref SCIP_STAGE_EXITPRESOLVE
12398 * - \ref SCIP_STAGE_PRESOLVED
12399 * - \ref SCIP_STAGE_INITSOLVE
12400 * - \ref SCIP_STAGE_SOLVING
12401 * - \ref SCIP_STAGE_SOLVED
12402 */
12404 SCIP* scip, /**< SCIP data structure */
12405 SCIP_VAR* var /**< problem variable */
12406 )
12407{
12408 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarLastGMIScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
12409
12410 assert( var->scip == scip );
12411
12412 return SCIPvarGetLastGMIScore(var, scip->stat);
12413}
12414
12415/** sets the variable's last GMI efficacy score value
12416 *
12417 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
12418 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
12419 *
12420 * @pre This method can be called if @p scip is in one of the following stages:
12421 * - \ref SCIP_STAGE_INITPRESOLVE
12422 * - \ref SCIP_STAGE_PRESOLVING
12423 * - \ref SCIP_STAGE_EXITPRESOLVE
12424 * - \ref SCIP_STAGE_PRESOLVED
12425 * - \ref SCIP_STAGE_INITSOLVE
12426 * - \ref SCIP_STAGE_SOLVING
12427 * - \ref SCIP_STAGE_SOLVED
12428 */
12430 SCIP* scip, /**< SCIP data structure */
12431 SCIP_VAR* var, /**< problem variable */
12432 SCIP_Real gmieff /**< efficacy of GMI cut from tableau row when variable is basic / frac */
12433 )
12434{
12435 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPsetVarLastGMIScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
12436
12437 assert( var->scip == scip );
12438
12439 SCIP_CALL( SCIPvarSetLastGMIScore(var, scip->stat, gmieff) );
12440
12441 return SCIP_OKAY;
12442}
12443
12444/** outputs variable information to file stream via the message system
12445 *
12446 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
12447 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
12448 *
12449 * @pre This method can be called if @p scip is in one of the following stages:
12450 * - \ref SCIP_STAGE_PROBLEM
12451 * - \ref SCIP_STAGE_TRANSFORMING
12452 * - \ref SCIP_STAGE_TRANSFORMED
12453 * - \ref SCIP_STAGE_INITPRESOLVE
12454 * - \ref SCIP_STAGE_PRESOLVING
12455 * - \ref SCIP_STAGE_EXITPRESOLVE
12456 * - \ref SCIP_STAGE_PRESOLVED
12457 * - \ref SCIP_STAGE_INITSOLVE
12458 * - \ref SCIP_STAGE_SOLVING
12459 * - \ref SCIP_STAGE_SOLVED
12460 * - \ref SCIP_STAGE_EXITSOLVE
12461 * - \ref SCIP_STAGE_FREETRANS
12462 *
12463 * @note If the message handler is set to a NULL pointer nothing will be printed
12464 */
12466 SCIP* scip, /**< SCIP data structure */
12467 SCIP_VAR* var, /**< problem variable */
12468 FILE* file /**< output file (or NULL for standard output) */
12469 )
12470{
12471 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
12472
12473 SCIP_CALL( SCIPvarPrint(var, scip->set, scip->messagehdlr, file) );
12474
12475 return SCIP_OKAY;
12476}
SCIP_RETCODE SCIPbranchcandUpdateVarBranchPriority(SCIP_BRANCHCAND *branchcand, SCIP_SET *set, SCIP_VAR *var, int branchpriority)
Definition: branch.c:1209
SCIP_Real SCIPbranchGetScore(SCIP_SET *set, SCIP_VAR *var, SCIP_Real downgain, SCIP_Real upgain)
Definition: branch.c:2236
internal methods for branching rules and branching candidate storage
SCIP_CERTIFICATE * SCIPgetCertificate(SCIP *scip)
SCIP_Longint SCIPcertificateGetCurrentIndex(SCIP_CERTIFICATE *certificate)
SCIP_RETCODE SCIPcertificatePrintCutoffConflictingBounds(SCIP *scip, SCIP_CERTIFICATE *certificate, SCIP_VAR *var, SCIP_RATIONAL *lb, SCIP_RATIONAL *ub, SCIP_Longint lbindex, SCIP_Longint ubindex)
methods for certificate output
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:360
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:290
internal methods for clocks and timing issues
internal methods for conflict analysis
int SCIPconflictGetNConflicts(SCIP_CONFLICT *conflict)
SCIP_RETCODE SCIPconflictAnalyzeStrongbranch(SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_COL *col, SCIP_Bool *downconflict, SCIP_Bool *upconflict)
methods for debugging
#define SCIPcheckStage(scip, method, init, problem, transforming, transformed, initpresolve, presolving, exitpresolve, presolved, initsolve, solving, solved, exitsolve, freetrans, freescip)
Definition: debug.h:364
#define NULL
Definition: def.h:248
#define SCIP_MAXSTRLEN
Definition: def.h:269
#define SCIP_Longint
Definition: def.h:141
#define SCIP_MAXTREEDEPTH
Definition: def.h:297
#define SCIP_INVALID
Definition: def.h:178
#define SCIP_Bool
Definition: def.h:91
#define MIN(x, y)
Definition: def.h:224
#define SCIP_Real
Definition: def.h:156
#define SCIP_UNKNOWN
Definition: def.h:179
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define MAX(x, y)
Definition: def.h:220
#define SCIP_CALL_ABORT(x)
Definition: def.h:334
#define SCIP_LONGINT_FORMAT
Definition: def.h:148
#define SCIPABORT()
Definition: def.h:327
#define REALABS(x)
Definition: def.h:182
#define SCIP_LONGINT_MAX
Definition: def.h:142
#define SCIP_CALL(x)
Definition: def.h:355
#define SCIP_CALL_FINALLY(x, y)
Definition: def.h:397
void SCIPgmlWriteNodeWeight(FILE *file, unsigned int id, const char *label, const char *nodetype, const char *fillcolor, const char *bordercolor, SCIP_Real weight)
Definition: misc.c:549
void SCIPgmlWriteNode(FILE *file, unsigned int id, const char *label, const char *nodetype, const char *fillcolor, const char *bordercolor)
Definition: misc.c:501
void SCIPgmlWriteClosing(FILE *file)
Definition: misc.c:703
void SCIPgmlWriteOpening(FILE *file, SCIP_Bool directed)
Definition: misc.c:687
void SCIPgmlWriteArc(FILE *file, unsigned int source, unsigned int target, const char *label, const char *color)
Definition: misc.c:643
SCIP_Bool SCIPisTransformed(SCIP *scip)
Definition: scip_general.c:647
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:444
int SCIPgetNContVars(SCIP *scip)
Definition: scip_prob.c:2569
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition: scip_prob.c:2115
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:2246
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:2201
SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
Definition: scip_prob.c:3189
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:3095
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3061
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3466
SCIP_RETCODE SCIPhashmapInsertInt(SCIP_HASHMAP *hashmap, void *origin, int image)
Definition: misc.c:3179
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
Definition: lpi_clp.cpp:3959
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_clp.cpp:2794
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2637
SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2414
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
SCIP_MESSAGEHDLR * SCIPgetMessagehdlr(SCIP *scip)
Definition: scip_message.c:88
#define SCIPdebugMsg
Definition: scip_message.h:78
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
SCIP_Bool SCIPshouldCertificateTrackBounds(SCIP *scip)
SCIP_Real SCIPgetColRedcost(SCIP *scip, SCIP_COL *col)
Definition: scip_lp.c:1163
SCIP_Longint SCIPcolGetStrongbranchNode(SCIP_COL *col)
Definition: lp.c:17567
int SCIPcolGetNStrongbranchs(SCIP_COL *col)
Definition: lp.c:17577
SCIP_Bool SCIPcolIsInLP(SCIP_COL *col)
Definition: lp.c:17509
SCIP_Real SCIPgetColFarkasCoef(SCIP *scip, SCIP_COL *col)
Definition: scip_lp.c:1189
SCIP_Bool SCIPconsIsLockedTypePos(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
Definition: cons.c:8758
SCIP_Bool SCIPconsIsLockedTypeNeg(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
Definition: cons.c:8770
SCIP_Bool SCIPisExact(SCIP *scip)
Definition: scip_exact.c:193
SCIP_Bool SCIPinDive(SCIP *scip)
Definition: scip_lp.c:2740
SCIP_Bool SCIPisLPRelax(SCIP *scip)
Definition: scip_lp.c:231
SCIP_RETCODE SCIPgetLPI(SCIP *scip, SCIP_LPI **lpi)
Definition: scip_lp.c:994
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip_lp.c:174
SCIP_Bool SCIPallColsInLP(SCIP *scip)
Definition: scip_lp.c:655
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition: scip_lp.c:253
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:110
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:57
BMS_BUFMEM * SCIPbuffer(SCIP *scip)
Definition: scip_mem.c:72
#define SCIPallocClearBufferArray(scip, ptr, num)
Definition: scip_mem.h:126
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:139
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip_mem.h:132
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip_mem.h:99
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip_mem.h:111
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:105
SCIP_NODETYPE SCIPnodeGetType(SCIP_NODE *node)
Definition: tree.c:8473
SCIP_DOMCHG * SCIPnodeGetDomchg(SCIP_NODE *node)
Definition: tree.c:8588
int SCIPgetProbingDepth(SCIP *scip)
Definition: scip_probing.c:199
SCIP_RETCODE SCIPchgVarUbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_probing.c:346
SCIP_RETCODE SCIPchgVarLbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_probing.c:302
SCIP_RETCODE SCIPpropagateProbing(SCIP *scip, int maxproprounds, SCIP_Bool *cutoff, SCIP_Longint *ndomredsfound)
Definition: scip_probing.c:581
SCIP_RETCODE SCIPbacktrackProbing(SCIP *scip, int probingdepth)
Definition: scip_probing.c:226
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip_probing.c:98
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
Definition: scip_probing.c:166
SCIP_RETCODE SCIPsolveProbingLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition: scip_probing.c:825
void SCIPrationalMin(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
Definition: rational.cpp:1342
void SCIPrationalAdd(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
Definition: rational.cpp:935
SCIP_Real SCIPrationalGetReal(SCIP_RATIONAL *rational)
Definition: rational.cpp:2085
#define SCIPrationalDebugMessage
Definition: rational.h:641
void SCIPrationalDiv(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
Definition: rational.cpp:1132
SCIP_Bool SCIPrationalIsAbsInfinity(SCIP_RATIONAL *rational)
Definition: rational.cpp:1680
SCIP_Bool SCIPrationalIsLT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
Definition: rational.cpp:1503
void SCIPrationalSetReal(SCIP_RATIONAL *res, SCIP_Real real)
Definition: rational.cpp:603
SCIP_Bool SCIPrationalIsGT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
Definition: rational.cpp:1474
void SCIPrationalFreeBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
Definition: rational.cpp:473
void SCIPrationalDiff(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
Definition: rational.cpp:983
SCIP_RETCODE SCIPrationalCreateBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
Definition: rational.cpp:123
SCIP_Bool SCIPrationalIsZero(SCIP_RATIONAL *rational)
Definition: rational.cpp:1624
void SCIPrationalSetRational(SCIP_RATIONAL *res, SCIP_RATIONAL *src)
Definition: rational.cpp:569
void SCIPrationalSetString(SCIP_RATIONAL *res, const char *desc)
Definition: rational.cpp:716
SCIP_Bool SCIPrationalIsIntegral(SCIP_RATIONAL *rational)
Definition: rational.cpp:1691
void SCIPrationalMax(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
Definition: rational.cpp:1373
SCIP_Bool SCIPrationalIsGE(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
Definition: rational.cpp:1512
SCIP_Bool SCIPstrToRationalValue(char *desc, SCIP_RATIONAL *value, char **endptr)
Definition: rational.cpp:822
void SCIPrationalMessage(SCIP_MESSAGEHDLR *msg, FILE *file, SCIP_RATIONAL *rational)
Definition: rational.cpp:1790
SCIP_Bool SCIPrationalIsNegative(SCIP_RATIONAL *rational)
Definition: rational.cpp:1650
SCIP_Bool SCIPrationalIsInfinity(SCIP_RATIONAL *rational)
Definition: rational.cpp:1660
void SCIPrationalFreeBlockArray(BMS_BLKMEM *mem, SCIP_RATIONAL ***ratblockarray, int size)
Definition: rational.cpp:501
SCIP_Real SCIPrationalRoundReal(SCIP_RATIONAL *rational, SCIP_ROUNDMODE_RAT roundmode)
Definition: rational.cpp:2110
SCIP_Bool SCIPrationalIsEQReal(SCIP_RATIONAL *rat, SCIP_Real real)
Definition: rational.cpp:1437
SCIP_Bool SCIPrationalIsNegInfinity(SCIP_RATIONAL *rational)
Definition: rational.cpp:1670
SCIP_RETCODE SCIPrationalReallocBlockArray(BMS_BLKMEM *mem, SCIP_RATIONAL ***result, int oldlen, int newlen)
Definition: rational.cpp:344
SCIP_Bool SCIPrationalIsEQ(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
Definition: rational.cpp:1404
SCIP_Bool SCIPrationalIsLE(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
Definition: rational.cpp:1521
void SCIPsolSetStrongbranching(SCIP_SOL *sol)
Definition: sol.c:4364
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip_sol.c:1252
SCIP_RETCODE SCIPcreateLPSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip_sol.c:608
SCIP_RETCODE SCIPgetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip_sol.c:1846
SCIP_RETCODE SCIProundSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
Definition: scip_sol.c:3123
SCIP_RETCODE SCIPtrySolFree(SCIP *scip, SCIP_SOL **sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition: scip_sol.c:4109
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1765
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition: scip_tree.c:91
SCIP_RETCODE SCIPgetVarStrongbranchFrac(SCIP *scip, SCIP_VAR *var, int itlim, SCIP_Bool idempotent, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *downconflict, SCIP_Bool *upconflict, SCIP_Bool *lperror)
Definition: scip_var.c:3664
SCIP_Real SCIPgetRelaxSolObj(SCIP *scip)
Definition: scip_var.c:3376
SCIP_RETCODE SCIPinitVarBranchStats(SCIP *scip, SCIP_VAR *var, SCIP_Real downpscost, SCIP_Real uppscost, SCIP_Real downvsids, SCIP_Real upvsids, SCIP_Real downconflen, SCIP_Real upconflen, SCIP_Real downinfer, SCIP_Real upinfer, SCIP_Real downcutoff, SCIP_Real upcutoff)
Definition: scip_var.c:12009
SCIP_Real SCIPgetVarAncPseudocostCountCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:11378
SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6401
SCIP_Real SCIPgetVarBdAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:3008
SCIP_RETCODE SCIPinitVarValueBranchStats(SCIP *scip, SCIP_VAR *var, SCIP_Real value, SCIP_Real downvsids, SCIP_Real upvsids, SCIP_Real downconflen, SCIP_Real upconflen, SCIP_Real downinfer, SCIP_Real upinfer, SCIP_Real downcutoff, SCIP_Real upcutoff)
Definition: scip_var.c:12080
SCIP_RETCODE SCIPaddVarLocks(SCIP *scip, SCIP_VAR *var, int nlocksdown, int nlocksup)
Definition: scip_var.c:5176
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:23683
SCIP_Real SCIPgetVarMultaggrLbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8506
SCIP_Bool SCIPpscostThresholdProbabilityTest(SCIP *scip, SCIP_VAR *var, SCIP_Real frac, SCIP_Real threshold, SCIP_BRANCHDIR dir, SCIP_CONFIDENCELEVEL clevel)
Definition: scip_var.c:11487
SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:5210
SCIP_BOUNDTYPE SCIPvarGetBestBoundType(SCIP_VAR *var)
Definition: var.c:24372
SCIP_RETCODE SCIPremoveVarFromGlobalStructures(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9796
SCIP_Real SCIPvarGetSol(SCIP_VAR *var, SCIP_Bool getlpval)
Definition: var.c:19007
SCIP_RETCODE SCIPtightenVarUbExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6768
SCIP_Bool SCIPdoNotAggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:10929
void SCIPdisableVarHistory(SCIP *scip)
Definition: scip_var.c:11102
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:23642
SCIP_Bool SCIPgetVarWasFixedAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:3026
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:23478
SCIP_RETCODE SCIPincVarGMISumScore(SCIP *scip, SCIP_VAR *var, SCIP_Real gmieff)
Definition: scip_var.c:12375
SCIP_RETCODE SCIPinferVarFixProp(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_PROP *inferprop, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:7515
SCIP_BOUNDTYPE SCIPboundchgGetBoundtype(SCIP_BOUNDCHG *boundchg)
Definition: var.c:23194
SCIP_RETCODE SCIPchgVarUbExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound)
Definition: scip_var.c:5964
SCIP_Real SCIPgetVarMultaggrLbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8536
SCIP_RETCODE SCIPinferVarUbProp(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_PROP *inferprop, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:7699
SCIP_RETCODE SCIPaddClique(SCIP *scip, SCIP_VAR **vars, SCIP_Bool *values, int nvars, SCIP_Bool isequation, SCIP_Bool *infeasible, int *nbdchgs)
Definition: scip_var.c:8882
SCIP_RETCODE SCIPsetRelaxSolVal(SCIP *scip, SCIP_RELAX *relax, SCIP_VAR *var, SCIP_Real val)
Definition: scip_var.c:3158
SCIP_RETCODE SCIPtightenVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:8257
SCIP_Real SCIPgetVarAvgInferenceScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:11976
SCIP_RETCODE SCIPgetVarStrongbranchInt(SCIP *scip, SCIP_VAR *var, int itlim, SCIP_Bool idempotent, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *downconflict, SCIP_Bool *upconflict, SCIP_Bool *lperror)
Definition: scip_var.c:4478
SCIP_VAR * SCIPboundchgGetVar(SCIP_BOUNDCHG *boundchg)
Definition: var.c:23174
SCIP_Real SCIPgetVarPseudocostCountCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:11350
SCIP_Real SCIPgetVarAvgInferenceScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:11945
SCIP_RETCODE SCIPscaleVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real scale)
Definition: scip_var.c:9858
SCIP_RETCODE SCIPendStrongbranch(SCIP *scip)
Definition: scip_var.c:3488
SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:5697
SCIP_Real SCIPgetVarMultaggrUbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8521
SCIP_BOUNDCHG * SCIPdomchgGetBoundchg(SCIP_DOMCHG *domchg, int pos)
Definition: var.c:23222
SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition: scip_var.c:2119
SCIP_Real SCIPgetVarPseudocostCount(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:11322
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:23386
SCIP_Real SCIPadjustedVarLbExactFloat(SCIP *scip, SCIP_VAR *var, SCIP_Real lb)
Definition: scip_var.c:5602
SCIP_Real SCIPgetVarPseudocostCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:11296
SCIP_RETCODE SCIPwriteCliqueGraph(SCIP *scip, const char *fname, SCIP_Bool writenodeweights)
Definition: scip_var.c:9647
SCIP_RETCODE SCIPchgVarName(SCIP *scip, SCIP_VAR *var, const char *name)
Definition: scip_var.c:1938
SCIP_RETCODE SCIPcalcNegatedCliquePartition(SCIP *scip, SCIP_VAR **vars, int nvars, int **probtoidxmap, int *probtoidxmapsize, int *cliquepartition, int *ncliques)
Definition: scip_var.c:9410
SCIP_Bool SCIPdoNotAggr(SCIP *scip)
Definition: scip_var.c:10909
SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
Definition: var.c:23498
SCIP_Real SCIPgetVarMultaggrUbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8551
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:24268
int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition: var.c:4449
SCIP_RETCODE SCIPaggregateVarsExact(SCIP *scip, SCIP_VAR *varx, SCIP_VAR *vary, SCIP_RATIONAL *scalarx, SCIP_RATIONAL *scalary, SCIP_RATIONAL *rhs, SCIP_Bool *infeasible, SCIP_Bool *redundant, SCIP_Bool *aggregated)
Definition: scip_var.c:10692
SCIP_RETCODE SCIPupdateVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition: scip_var.c:9958
SCIP_Real SCIPgetVarAvgConflictlength(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:11837
SCIP_Bool SCIPisVarPscostRelerrorReliable(SCIP *scip, SCIP_VAR *var, SCIP_Real threshold, SCIP_CONFIDENCELEVEL clevel)
Definition: scip_var.c:11506
SCIP_RETCODE SCIPgetBinvarRepresentatives(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **repvars, SCIP_Bool *negated)
Definition: scip_var.c:2283
SCIP_BDCHGINFO * SCIPvarGetLbchgInfo(SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: var.c:22629
SCIP_Bool SCIPdoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:10942
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition: var.c:23430
SCIP_Real SCIPgetVarPseudocost(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:11268
SCIP_RETCODE SCIPparseVarsList(SCIP *scip, const char *str, SCIP_VAR **vars, int *nvars, int varssize, int *requiredsize, char **endptr, char delimiter, SCIP_Bool *success)
Definition: scip_var.c:805
SCIP_Real SCIPgetVarAvgCutoffScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:12230
SCIP_RETCODE SCIPaggregateVars(SCIP *scip, SCIP_VAR *varx, SCIP_VAR *vary, SCIP_Real scalarx, SCIP_Real scalary, SCIP_Real rhs, SCIP_Bool *infeasible, SCIP_Bool *redundant, SCIP_Bool *aggregated)
Definition: scip_var.c:10550
SCIP_RETCODE SCIPinferVarUbCons(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:7069
SCIP_RETCODE SCIPparseVarsPolynomialExact(SCIP *scip, char *str, SCIP_VAR ****monomialvars, SCIP_RATIONAL ***monomialcoefs, int *nmonomials, char **endptr, SCIP_Bool *success)
Definition: scip_var.c:1453
SCIP_Real SCIPboundchgGetNewbound(SCIP_BOUNDCHG *boundchg)
Definition: var.c:23154
SCIP_RETCODE SCIPaddVarExactData(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *lb, SCIP_RATIONAL *ub, SCIP_RATIONAL *obj)
Definition: scip_var.c:299
SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:5875
SCIP_RETCODE SCIPchgVarUbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:6088
SCIP_Real SCIPgetVarAvgInferencesCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:11919
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:23900
SCIP_VAR * SCIPvarGetProbvar(SCIP_VAR *var)
Definition: var.c:17550
SCIP_RETCODE SCIPchgVarImplType(SCIP *scip, SCIP_VAR *var, SCIP_IMPLINTTYPE impltype, SCIP_Bool *infeasible)
Definition: scip_var.c:10218
SCIP_CLIQUE ** SCIPgetCliques(SCIP *scip)
Definition: scip_var.c:9566
SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6651
SCIP_RETCODE SCIPparseVarName(SCIP *scip, const char *str, SCIP_VAR **var, char **endptr)
Definition: scip_var.c:728
SCIP_RETCODE SCIPparseVar(SCIP *scip, SCIP_VAR **var, const char *str, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARCOPY((*varcopy)), SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_VARDATA *vardata, char **endptr, SCIP_Bool *success)
Definition: scip_var.c:669
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:23453
SCIP_RETCODE SCIPgetProbvarSum(SCIP *scip, SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: scip_var.c:2499
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:24142
SCIP_RETCODE SCIPchgVarBranchDirection(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR branchdirection)
Definition: scip_var.c:10022
SCIP_VARSTATUS SCIPvarGetStatusExact(SCIP_VAR *var)
Definition: var.c:23396
SCIP_RETCODE SCIPaddVarVub(SCIP *scip, SCIP_VAR *var, SCIP_VAR *vubvar, SCIP_Real vubcoef, SCIP_Real vubconstant, SCIP_Bool *infeasible, int *nbdchgs)
Definition: scip_var.c:8680
SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
Definition: scip_var.c:5118
SCIP_RETCODE SCIPchgVarLbGlobalExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound)
Definition: scip_var.c:5492
SCIP_RETCODE SCIPaddVarVlb(SCIP *scip, SCIP_VAR *var, SCIP_VAR *vlbvar, SCIP_Real vlbcoef, SCIP_Real vlbconstant, SCIP_Bool *infeasible, int *nbdchgs)
Definition: scip_var.c:8621
SCIP_RETCODE SCIPchgVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition: scip_var.c:9917
SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:5296
SCIP_RETCODE SCIPchgVarUbGlobalExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound)
Definition: scip_var.c:5467
SCIP_RETCODE SCIPinferVarLbConsExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:7296
SCIP_Real SCIPgetVarFarkasCoef(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:2698
SCIP_RETCODE SCIPgetVarClosestVub(SCIP *scip, SCIP_VAR *var, SCIP_SOL *sol, SCIP_Real *closestvub, int *closestvubidx)
Definition: scip_var.c:8592
SCIP_Real SCIPgetVarAvgCutoffsCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:12173
SCIP_RETCODE SCIPcreateVarImpl(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_IMPLINTTYPE impltype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
Definition: scip_var.c:225
SCIP_RETCODE SCIPchgVarLbLazy(SCIP *scip, SCIP_VAR *var, SCIP_Real lazylb)
Definition: scip_var.c:6321
SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2872
int SCIPdomchgGetNBoundchgs(SCIP_DOMCHG *domchg)
Definition: var.c:23214
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:23662
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:23267
SCIP_Longint SCIPgetVarStrongbranchNode(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:5019
SCIP_RETCODE SCIPtransformVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition: scip_var.c:2028
SCIP_RETCODE SCIPcalcCliquePartition(SCIP *scip, SCIP_VAR **vars, int nvars, int **probtoidxmap, int *probtoidxmapsize, int *cliquepartition, int *ncliques)
Definition: scip_var.c:9330
SCIP_Real SCIPgetVarDPseudocostScore(SCIP *scip, SCIP_VAR *var, SCIP_Real solval, SCIP_Real discountfac)
Definition: scip_var.c:11570
SCIP_RETCODE SCIPmultiaggregateVar(SCIP *scip, SCIP_VAR *var, int naggvars, SCIP_VAR **aggvars, SCIP_Real *scalars, SCIP_Real constant, SCIP_Bool *infeasible, SCIP_Bool *aggregated)
Definition: scip_var.c:10834
void SCIPfreeParseVarsPolynomialData(SCIP *scip, SCIP_VAR ****monomialvars, SCIP_Real ***monomialexps, SCIP_Real **monomialcoefs, int **monomialnvars, int nmonomials)
Definition: scip_var.c:1755
SCIP_LPSOLSTAT SCIPgetLastStrongbranchLPSolStat(SCIP *scip, SCIP_BRANCHDIR branchdir)
Definition: scip_var.c:4847
SCIP_RETCODE SCIPaddVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real addfactor)
Definition: scip_var.c:9886
int SCIPgetNCliquesCreated(SCIP *scip)
Definition: scip_var.c:9539
SCIP_RETCODE SCIPcleanupCliques(SCIP *scip, SCIP_Bool *infeasible)
Definition: scip_var.c:9469
void SCIPvarMarkDeleteGlobalStructures(SCIP_VAR *var)
Definition: var.c:23570
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1887
SCIP_Real SCIPadjustedVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real ub)
Definition: scip_var.c:5634
SCIP_Longint SCIPgetVarStrongbranchLPAge(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:5053
SCIP_RETCODE SCIPchgVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:6141
SCIP_RETCODE SCIPgetProbvarLinearSumExact(SCIP *scip, SCIP_VAR **vars, SCIP_RATIONAL **scalars, int *nvars, int varssize, SCIP_RATIONAL *constant, int *requiredsize, SCIP_Bool mergemultiples)
Definition: scip_var.c:2443
SCIP_RETCODE SCIPmarkRelaxSolValid(SCIP *scip, SCIP_RELAX *relax, SCIP_Bool includeslp)
Definition: scip_var.c:3301
SCIP_RETCODE SCIPgetVarsStrongbranchesFrac(SCIP *scip, SCIP_VAR **vars, int nvars, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *downconflict, SCIP_Bool *upconflict, SCIP_Bool *lperror)
Definition: scip_var.c:4632
SCIP_RATIONAL * SCIPvarGetUbLocalExact(SCIP_VAR *var)
Definition: var.c:24278
SCIP_RETCODE SCIPsetVarStrongbranchData(SCIP *scip, SCIP_VAR *var, SCIP_Real lpobjval, SCIP_Real primsol, SCIP_Real down, SCIP_Real up, SCIP_Bool downvalid, SCIP_Bool upvalid, SCIP_Longint iter, int itlim)
Definition: scip_var.c:4903
SCIP_Real SCIPvarGetBranchFactor(SCIP_VAR *var)
Definition: var.c:24450
SCIP_Bool SCIPdoNotMultaggr(SCIP *scip)
Definition: scip_var.c:10919
SCIP_Real SCIPgetVarPseudocostVal(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta)
Definition: scip_var.c:11188
SCIP_RETCODE SCIPparseVarsLinearsum(SCIP *scip, const char *str, SCIP_VAR **vars, SCIP_Real *vals, int *nvars, int varssize, int *requiredsize, char **endptr, SCIP_Bool *success)
Definition: scip_var.c:899
SCIP_Real SCIPgetVarConflictlengthScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:11775
SCIP_Bool SCIPsignificantVarPscostDifference(SCIP *scip, SCIP_VAR *varx, SCIP_Real fracx, SCIP_VAR *vary, SCIP_Real fracy, SCIP_BRANCHDIR dir, SCIP_CONFIDENCELEVEL clevel, SCIP_Bool onesided)
Definition: scip_var.c:11457
SCIP_RETCODE SCIPgetProbvarLinearSum(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize)
Definition: scip_var.c:2378
SCIP_Real SCIPgetRelaxSolVal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:3347
SCIP_RETCODE SCIPgetVarStrongbranchWithPropagation(SCIP *scip, SCIP_VAR *var, SCIP_Real solval, SCIP_Real lpobjval, int itlim, int maxproprounds, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Longint *ndomredsdown, SCIP_Longint *ndomredsup, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *downconflict, SCIP_Bool *upconflict, SCIP_Bool *lperror, SCIP_Real *newlbs, SCIP_Real *newubs)
Definition: scip_var.c:4138
SCIP_Real SCIPadjustedVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real lb)
Definition: scip_var.c:5570
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:23490
SCIP_Real SCIPgetVarAvgCutoffs(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:12145
SCIP_Real SCIPvarGetPseudoSol(SCIP_VAR *var)
Definition: var.c:24756
SCIP_Real SCIPgetVarAncPseudocostVal(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta)
Definition: scip_var.c:11214
SCIP_Bool SCIPisRelaxSolValid(SCIP *scip)
Definition: scip_var.c:3281
SCIP_RETCODE SCIPgetVarClosestVlb(SCIP *scip, SCIP_VAR *var, SCIP_SOL *sol, SCIP_Real *closestvlb, int *closestvlbidx)
Definition: scip_var.c:8569
SCIP_RETCODE SCIPparseVarsLinearsumExact(SCIP *scip, char *str, SCIP_VAR **vars, SCIP_RATIONAL **vals, int *nvars, int varssize, int *requiredsize, char **endptr, SCIP_Bool *success)
Definition: scip_var.c:1007
SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:10113
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
Definition: var.c:24664
SCIP_RETCODE SCIPflattenVarAggregationGraph(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:2332
SCIP_Real SCIPcomputeVarLbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8375
SCIP_Real SCIPgetVarSol(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:3051
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip_var.c:2166
SCIP_Real SCIPgetVarPseudocostScoreCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real solval)
Definition: scip_var.c:11613
SCIP_RETCODE SCIPinferVarUbConsExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:7174
SCIP_Bool SCIPhaveVarsCommonClique(SCIP *scip, SCIP_VAR *var1, SCIP_Bool value1, SCIP_VAR *var2, SCIP_Bool value2, SCIP_Bool regardimplics)
Definition: scip_var.c:9596
SCIP_RETCODE SCIPaddVarImplication(SCIP *scip, SCIP_VAR *var, SCIP_Bool varfixing, SCIP_VAR *implvar, SCIP_BOUNDTYPE impltype, SCIP_Real implbound, SCIP_Bool *infeasible, int *nbdchgs)
Definition: scip_var.c:8740
SCIP_RETCODE SCIPsetRelaxSolVals(SCIP *scip, SCIP_RELAX *relax, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Bool includeslp)
Definition: scip_var.c:3191
SCIP_Real SCIPcalculatePscostConfidenceBound(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun, SCIP_CONFIDENCELEVEL clevel)
Definition: scip_var.c:11426
int SCIPvarGetNCliques(SCIP_VAR *var, SCIP_Bool varfixing)
Definition: var.c:24642
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:24234
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:23443
SCIP_RETCODE SCIPchgVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:6230
SCIP_Real SCIPcomputeVarLbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8417
SCIP_RETCODE SCIPwriteVarsPolynomial(SCIP *scip, FILE *file, SCIP_VAR ***monomialvars, SCIP_Real **monomialexps, SCIP_Real *monomialcoefs, int *monomialnvars, int nmonomials, SCIP_Bool type)
Definition: scip_var.c:599
SCIP_Bool SCIPboundchgIsRedundant(SCIP_BOUNDCHG *boundchg)
Definition: var.c:23204
SCIP_Real SCIPgetVarPseudocostValCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta)
Definition: scip_var.c:11242
SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
Definition: var.c:23878
SCIP_RETCODE SCIPupdateVarPseudocost(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
Definition: scip_var.c:11122
int SCIPgetNCliques(SCIP *scip)
Definition: scip_var.c:9512
SCIP_BDCHGINFO * SCIPvarGetUbchgInfo(SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: var.c:22685
SCIP_Real SCIPgetVarAvgGMIScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:12349
int SCIPvarGetBranchPriority(SCIP_VAR *var)
Definition: var.c:24462
SCIP_RETCODE SCIPcreateVar(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
Definition: scip_var.c:120
SCIP_Real SCIPadjustedVarUbExactFloat(SCIP *scip, SCIP_VAR *var, SCIP_Real ub)
Definition: scip_var.c:5666
SCIP_RETCODE SCIPaddVarBranchPriority(SCIP *scip, SCIP_VAR *var, int addpriority)
Definition: scip_var.c:9991
SCIP_RETCODE SCIPtransformVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip_var.c:1988
SCIP_CLIQUE ** SCIPvarGetCliques(SCIP_VAR *var, SCIP_Bool varfixing)
Definition: var.c:24653
SCIP_Real SCIPgetVarRedcost(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:2608
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:24120
SCIP_RETCODE SCIPmarkDoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:11057
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition: scip_var.c:10318
SCIP_RETCODE SCIPmarkRelaxSolInvalid(SCIP *scip)
Definition: scip_var.c:3326
SCIP_Real SCIPgetVarAvgInferenceCutoffScoreCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real cutoffweight)
Definition: scip_var.c:12306
SCIP_RETCODE SCIPinferVarLbCons(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6964
SCIP_RETCODE SCIPgetVarsStrongbranchesInt(SCIP *scip, SCIP_VAR **vars, int nvars, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *downconflict, SCIP_Bool *upconflict, SCIP_Bool *lperror)
Definition: scip_var.c:4743
SCIP_RATIONAL * SCIPvarGetLbLocalExact(SCIP_VAR *var)
Definition: var.c:24244
SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2736
SCIP_IMPLINTTYPE SCIPvarGetImplType(SCIP_VAR *var)
Definition: var.c:23463
SCIP_RETCODE SCIPparseVarsPolynomial(SCIP *scip, const char *str, SCIP_VAR ****monomialvars, SCIP_Real ***monomialexps, SCIP_Real **monomialcoefs, int **monomialnvars, int *nmonomials, char **endptr, SCIP_Bool *success)
Definition: scip_var.c:1100
SCIP_Real SCIPgetVarLastGMIScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:12403
SCIP_Real SCIPgetVarConflictScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:11713
SCIP_RETCODE SCIPprintVar(SCIP *scip, SCIP_VAR *var, FILE *file)
Definition: scip_var.c:12465
SCIP_Real SCIPgetVarAvgCutoffScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:12199
SCIP_RETCODE SCIPchgVarLbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:6044
SCIP_RETCODE SCIPvarGetProbvarBinary(SCIP_VAR **var, SCIP_Bool *negated)
Definition: var.c:17642
SCIP_RETCODE SCIPcreateVarBasic(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype)
Definition: scip_var.c:184
SCIP_RETCODE SCIPsetVarLastGMIScore(SCIP *scip, SCIP_VAR *var, SCIP_Real gmieff)
Definition: scip_var.c:12429
SCIP_RETCODE SCIPchgVarUbLazy(SCIP *scip, SCIP_VAR *var, SCIP_Real lazyub)
Definition: scip_var.c:6362
SCIP_RETCODE SCIPinferBinvarCons(SCIP *scip, SCIP_VAR *var, SCIP_Bool fixedval, SCIP_CONS *infercons, int inferinfo, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:7412
int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition: var.c:4462
SCIP_RETCODE SCIPtryStrongbranchLPSol(SCIP *scip, SCIP_Bool *foundsol, SCIP_Bool *cutoff)
Definition: scip_var.c:4938
SCIP_RETCODE SCIPchgVarObjExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newobj)
Definition: scip_var.c:5420
SCIP_RETCODE SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
Definition: scip_var.c:361
SCIP_RETCODE SCIPgetVarSols(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip_var.c:3071
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:5372
SCIP_RETCODE SCIPupdateVarAncPseudocost(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
Definition: scip_var.c:11154
SCIP_RETCODE SCIPchgVarLbExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound)
Definition: scip_var.c:5786
SCIP_RETCODE SCIPgetBinvarRepresentative(SCIP *scip, SCIP_VAR *var, SCIP_VAR **repvar, SCIP_Bool *negated)
Definition: scip_var.c:2236
SCIP_Real SCIPgetVarAvgInferenceCutoffScore(SCIP *scip, SCIP_VAR *var, SCIP_Real cutoffweight)
Definition: scip_var.c:12262
SCIP_RETCODE SCIPwriteVarsList(SCIP *scip, FILE *file, SCIP_VAR **vars, int nvars, SCIP_Bool type, char delimiter)
Definition: scip_var.c:423
SCIP_Real SCIPcomputeVarUbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8396
SCIP_Real SCIPcomputeVarUbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8462
SCIP_RETCODE SCIPgetActiveVars(SCIP *scip, SCIP_VAR **vars, int *nvars, int varssize, int *requiredsize)
Definition: scip_var.c:2574
int SCIPgetVarNStrongbranchs(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:5085
SCIP_RETCODE SCIPwriteVarsLinearsum(SCIP *scip, FILE *file, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Bool type)
Definition: scip_var.c:474
SCIP_RETCODE SCIPgetProbvarSumExact(SCIP *scip, SCIP_VAR **var, SCIP_RATIONAL *scalar, SCIP_RATIONAL *constant)
Definition: scip_var.c:2538
SCIP_RETCODE SCIPgetVarStrongbranchLast(SCIP *scip, SCIP_VAR *var, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Real *solval, SCIP_Real *lpobjval)
Definition: scip_var.c:4869
SCIP_Real SCIPgetVarVSIDS(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:11649
SCIP_Bool SCIPvarsHaveCommonClique(SCIP_VAR *var1, SCIP_Bool value1, SCIP_VAR *var2, SCIP_Bool value2, SCIP_Bool regardimplics)
Definition: var.c:16807
SCIP_Real SCIPgetVarConflictlengthScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:11806
SCIP_Bool SCIPisVarAggrCoefAcceptable(SCIP *scip, SCIP_VAR *var, SCIP_Real scalar)
Definition: scip_var.c:10962
SCIP_Real SCIPgetVarVSIDSCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:11681
SCIP_Bool SCIPisStrongbranchDownFirst(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:3399
SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:24919
void SCIPenableVarHistory(SCIP *scip)
Definition: scip_var.c:11083
SCIP_Real SCIPgetVarImplRedcost(SCIP *scip, SCIP_VAR *var, SCIP_Bool varfixing)
Definition: scip_var.c:2653
SCIP_Bool SCIPallowWeakDualReds(SCIP *scip)
Definition: scip_var.c:10998
SCIP_Real SCIPgetVarPseudocostVariance(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun)
Definition: scip_var.c:11404
SCIP_RETCODE SCIPgetNegatedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **negvars)
Definition: scip_var.c:2199
SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip_var.c:2078
SCIP_RETCODE SCIPmultiaggregateVarExact(SCIP *scip, SCIP_VAR *var, int naggvars, SCIP_VAR **aggvars, SCIP_RATIONAL **scalars, SCIP_RATIONAL *constant, SCIP_Bool *infeasible, SCIP_Bool *aggregated)
Definition: scip_var.c:10879
SCIP_Real SCIPgetVarConflictScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:11744
SCIP_RETCODE SCIPtightenVarLbExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6518
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1853
SCIP_Real SCIPgetVarPseudocostScore(SCIP *scip, SCIP_VAR *var, SCIP_Real solval)
Definition: scip_var.c:11531
SCIP_RETCODE SCIPstartStrongbranch(SCIP *scip, SCIP_Bool enablepropagation)
Definition: scip_var.c:3430
SCIP_RETCODE SCIPclearRelaxSolVals(SCIP *scip, SCIP_RELAX *relax)
Definition: scip_var.c:3108
SCIP_RETCODE SCIPmarkDoNotAggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:11024
SCIP_Real SCIPgetVarAvgInferences(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:11891
SCIP_Bool SCIPallowStrongDualReds(SCIP *scip)
Definition: scip_var.c:10984
SCIP_RETCODE SCIPinferBinvarProp(SCIP *scip, SCIP_VAR *var, SCIP_Bool fixedval, SCIP_PROP *inferprop, int inferinfo, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:7809
SCIP_RETCODE SCIPwriteVarsLinearsumExact(SCIP *scip, FILE *file, SCIP_VAR **vars, SCIP_RATIONAL **vals, int nvars, SCIP_Bool type)
Definition: scip_var.c:533
SCIP_RETCODE SCIPvarsGetProbvarBinary(SCIP_VAR ***vars, SCIP_Bool **negatedarr, int nvars)
Definition: var.c:17610
SCIP_RETCODE SCIPinferVarFixCons(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6895
SCIP_Real SCIPgetVarAvgConflictlengthCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:11863
void SCIPfreeParseVarsPolynomialDataExact(SCIP *scip, SCIP_VAR ****monomialvars, SCIP_RATIONAL ***monomialcoefs, int nmonomials)
Definition: scip_var.c:1806
SCIP_RETCODE SCIPsetRelaxSolValsSol(SCIP *scip, SCIP_RELAX *relax, SCIP_SOL *sol, SCIP_Bool includeslp)
Definition: scip_var.c:3233
SCIP_RETCODE SCIPchgVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real branchfactor)
Definition: scip_var.c:9830
SCIP_RETCODE SCIPtightenVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:8026
SCIP_RETCODE SCIPcomputeVarLbLocalExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *result)
Definition: scip_var.c:8438
SCIP_RETCODE SCIPfixVarExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition: scip_var.c:10420
SCIP_RETCODE SCIPinferVarLbProp(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_PROP *inferprop, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:7584
SCIP_RETCODE SCIPaddVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real addobj)
Definition: scip_var.c:5519
SCIP_RETCODE SCIPcomputeVarUbLocalExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *result)
Definition: scip_var.c:8483
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10827
SCIP_Bool SCIPstrToRealValue(const char *str, SCIP_Real *value, char **endptr)
Definition: misc.c:10955
void SCIPstrCopySection(const char *str, char startchar, char endchar, char *token, int size, char **endptr)
Definition: misc.c:10985
SCIP_RETCODE SCIPskipSpace(char **s)
Definition: misc.c:10816
SCIP_Real SCIPhistoryGetAvgInferences(SCIP_HISTORY *history, SCIP_BRANCHDIR dir)
Definition: history.c:790
internal methods for branching and inference history
SCIP_RETCODE SCIPcliquetableAdd(SCIP_CLIQUETABLE *cliquetable, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_VAR **vars, SCIP_Bool *values, int nvars, SCIP_Bool isequation, SCIP_Bool *infeasible, int *nbdchgs)
Definition: implics.c:2377
int SCIPcliquetableGetNCliquesCreated(SCIP_CLIQUETABLE *cliquetable)
Definition: implics.c:3520
SCIP_VAR ** SCIPcliqueGetVars(SCIP_CLIQUE *clique)
Definition: implics.c:3384
int SCIPcliqueGetNVars(SCIP_CLIQUE *clique)
Definition: implics.c:3374
SCIP_Bool * SCIPcliqueGetValues(SCIP_CLIQUE *clique)
Definition: implics.c:3396
int SCIPcliquetableGetNCliques(SCIP_CLIQUETABLE *cliquetable)
Definition: implics.c:3510
SCIP_RETCODE SCIPcliquetableCleanup(SCIP_CLIQUETABLE *cliquetable, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int *nchgbds, SCIP_Bool *infeasible)
Definition: implics.c:2923
SCIP_CLIQUE ** SCIPcliquetableGetCliques(SCIP_CLIQUETABLE *cliquetable)
Definition: implics.c:3530
methods for implications, variable bounds, and cliques
SCIP_Real SCIPlpGetLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13475
SCIP_RETCODE SCIPlpStartStrongbranch(SCIP_LP *lp)
Definition: lp.c:4375
SCIP_Real SCIPlpGetModifiedPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype)
Definition: lp.c:13711
void SCIPcolInvalidateStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4459
SCIP_RETCODE SCIPcolGetStrongbranch(SCIP_COL *col, SCIP_Bool integral, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp, int itlim, SCIP_Bool updatecol, SCIP_Bool updatestat, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *lperror)
Definition: lp.c:4494
SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13436
SCIP_RETCODE SCIPlpEndStrongbranch(SCIP_LP *lp)
Definition: lp.c:4390
SCIP_Longint SCIPcolGetStrongbranchLPAge(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4932
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition: lp.c:18251
void SCIPcolGetStrongbranchLast(SCIP_COL *col, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Real *solval, SCIP_Real *lpobjval)
Definition: lp.c:4900
void SCIPlpStartStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16729
void SCIPlpEndStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16742
SCIP_Bool SCIPlpIsDualReliable(SCIP_LP *lp)
Definition: lp.c:18231
static const SCIP_Real scalars[]
Definition: lp.c:5959
void SCIPcolSetStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Real lpobjval, SCIP_Real primsol, SCIP_Real sbdown, SCIP_Real sbup, SCIP_Bool sbdownvalid, SCIP_Bool sbupvalid, SCIP_Longint iter, int itlim)
Definition: lp.c:4405
SCIP_RETCODE SCIPcolGetStrongbranches(SCIP_COL **cols, int ncols, SCIP_Bool integral, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *lperror)
Definition: lp.c:4677
internal methods for LP management
interface methods for specific LP solvers
memory allocation routines
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:134
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:130
SCIP_RETCODE SCIPprobAddVarName(SCIP_PROB *prob, SCIP_VAR *var)
Definition: prob.c:1065
SCIP_RETCODE SCIPprobRemoveVarName(SCIP_PROB *prob, SCIP_VAR *var)
Definition: prob.c:1081
SCIP_RETCODE SCIPprobChgVarImplType(SCIP_PROB *prob, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_VAR *var, SCIP_IMPLINTTYPE impltype)
Definition: prob.c:1358
SCIP_RETCODE SCIPprobChgVarType(SCIP_PROB *prob, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_VAR *var, SCIP_VARTYPE vartype)
Definition: prob.c:1304
SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
Definition: prob.c:2825
internal methods for storing and manipulating the main problem
public methods for managing constraints
public methods for implications, variable bounds, and cliques
public methods for LP management
public methods for message output
#define SCIPerrorMessage
Definition: pub_message.h:64
public data structures and miscellaneous methods
public methods for branch and bound tree
public methods for problem variables
wrapper for rational number arithmetic
SCIP_Bool SCIPrelaxationIsSolZero(SCIP_RELAXATION *relaxation)
Definition: relax.c:800
void SCIPrelaxationSetSolZero(SCIP_RELAXATION *relaxation, SCIP_Bool iszero)
Definition: relax.c:789
void SCIPrelaxationSetSolValid(SCIP_RELAXATION *relaxation, SCIP_Bool isvalid, SCIP_Bool includeslp)
Definition: relax.c:810
void SCIPrelaxationSetSolObj(SCIP_RELAXATION *relaxation, SCIP_Real obj)
Definition: relax.c:843
SCIP_Real SCIPrelaxationGetSolObj(SCIP_RELAXATION *relaxation)
Definition: relax.c:854
void SCIPrelaxationSetSolRelax(SCIP_RELAXATION *relaxation, SCIP_RELAX *relax)
Definition: relax.c:895
SCIP_Bool SCIPrelaxationIsSolValid(SCIP_RELAXATION *relaxation)
Definition: relax.c:823
internal methods for relaxators
public methods for certified solving
public methods for exact solving
general public methods
public methods for the LP relaxation, rows and columns
public methods for memory management
public methods for message handling
public methods for numerical tolerances
public methods for global and local (sub)problems
public methods for the probing mode
public methods for solutions
public methods for querying solving statistics
public methods for the branch-and-bound tree
static SCIP_RETCODE analyzeStrongbranch(SCIP *scip, SCIP_VAR *var, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *downconflict, SCIP_Bool *upconflict)
Definition: scip_var.c:3583
static SCIP_RETCODE performStrongbranchWithPropagation(SCIP *scip, SCIP_VAR *var, SCIP_Bool down, SCIP_Bool firstchild, SCIP_Bool propagate, SCIP_Real newbound, int itlim, int maxproprounds, SCIP_Real *value, SCIP_Bool *valid, SCIP_Longint *ndomreductions, SCIP_Bool *conflict, SCIP_Bool *lperror, SCIP_VAR **vars, int nvars, SCIP_Real *newlbs, SCIP_Real *newubs, SCIP_Bool *foundsol, SCIP_Bool *cutoff)
Definition: scip_var.c:3812
static SCIP_RETCODE calcCliquePartitionGreedy(SCIP *const scip, SCIP_VAR **const vars, SCIP_Bool *const values, int const nvars, int **probtoidxmap, int *probtoidxmapsize, int *const cliquepartition, int *const ncliques)
Definition: scip_var.c:9079
static SCIP_RETCODE SCIPtestCliquePartition(SCIP *scip, SCIP_VAR **vars, int nvars, const int *cliquepartition, int ncliques)
Definition: scip_var.c:9271
static void addLargestCliquePart(SCIP_VAR *var, SCIP_Bool value, int varidx, int *idx, SCIP_Bool *values, int p, int nvars, int nbinvars, int *cliquepartition, int *ncliqueparts)
Definition: scip_var.c:8913
static SCIP_RETCODE tightenBounds(SCIP *scip, SCIP_VAR *var, SCIP_Bool integral, SCIP_Bool *infeasible)
Definition: scip_var.c:10039
static SCIP_RETCODE tightenVarLbGlobalSafe(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:7901
static SCIP_RETCODE tightenVarUbGlobalSafe(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:8133
#define MAXNUMEARCHCLIQUE
Definition: scip_var.c:8909
public methods for SCIP variables
SCIP_Bool SCIPsetIsLbBetter(SCIP_SET *set, SCIP_Real newlb, SCIP_Real oldlb, SCIP_Real oldub)
Definition: set.c:7402
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6617
SCIP_Real SCIPsetFeasCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:7136
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:7017
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6945
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6577
SCIP_Real SCIPsetFeasFloor(SCIP_SET *set, SCIP_Real val)
Definition: set.c:7124
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6537
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6969
SCIP_Bool SCIPsetIsUbBetter(SCIP_SET *set, SCIP_Real newub, SCIP_Real oldlb, SCIP_Real oldub)
Definition: set.c:7426
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6515
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6637
SCIP_Bool SCIPsetIsFeasIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:7098
internal methods for global SCIP settings
#define SCIPsetFreeBufferArray(set, ptr)
Definition: set.h:1782
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1775
SCIP_Real SCIPsolGetObj(SCIP_SOL *sol, SCIP_SET *set, SCIP_PROB *transprob, SCIP_PROB *origprob)
Definition: sol.c:2257
internal methods for storing primal CIP solutions
SCIP_Bool SCIPsolveIsStopped(SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool checknodelimits)
Definition: solve.c:110
internal methods for main solving loop and node processing
void SCIPstatEnableVarHistory(SCIP_STAT *stat)
Definition: stat.c:191
void SCIPstatDisableVarHistory(SCIP_STAT *stat)
Definition: stat.c:181
internal methods for problem statistics
#define SCIPstatAdd(stat, set, field, val)
Definition: stat.h:280
SCIP_VAR * var
Definition: struct_var.h:212
SCIP_Real scalar
Definition: struct_var.h:210
SCIP_Real constant
Definition: struct_var.h:211
SCIP_Real lb
Definition: struct_lp.h:140
SCIP_Real ub
Definition: struct_lp.h:141
SCIP_Real sbdown
Definition: struct_lp.h:155
SCIP_Real sbup
Definition: struct_lp.h:156
unsigned int sbupvalid
Definition: struct_lp.h:193
SCIP_Real primsol
Definition: struct_lp.h:150
unsigned int sbdownvalid
Definition: struct_lp.h:191
SCIP_Real lb
Definition: struct_var.h:176
SCIP_Real ub
Definition: struct_var.h:177
SCIP_VAR ** vars
Definition: struct_var.h:227
SCIP_Real constant
Definition: struct_var.h:225
SCIP_Real * scalars
Definition: struct_var.h:226
SCIP_Real constant
Definition: struct_var.h:242
SCIP_VAR * transvar
Definition: struct_var.h:194
SCIP_ORIGINAL original
Definition: struct_var.h:283
SCIP_AGGREGATE aggregate
Definition: struct_var.h:286
SCIP_VAR * negatedvar
Definition: struct_var.h:298
SCIP * scip
Definition: struct_var.h:345
SCIP_DOM glbdom
Definition: struct_var.h:279
unsigned int vartype
Definition: struct_var.h:336
SCIP_VARDATAEXACT * exactdata
Definition: struct_var.h:290
SCIP_MULTAGGR multaggr
Definition: struct_var.h:287
union SCIP_Var::@24 data
SCIP_NEGATE negate
Definition: struct_var.h:285
data structures for LP management
datastructures for block memory pools and memory buffers
datastructures for collecting primal CIP solutions and primal informations
datastructures for storing and manipulating the main problem
SCIP main data structure.
datastructures for global SCIP settings
datastructures for problem statistics
data structures for branch and bound tree
datastructures for problem variables
SCIP_RETCODE SCIPnodeAddBoundchgExact(SCIP_NODE *node, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LPEXACT *lpexact, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_VAR *var, SCIP_RATIONAL *newbound, SCIP_BOUNDTYPE boundtype, SCIP_Bool probingchange)
Definition: tree.c:2568
SCIP_Bool SCIPtreeProbing(SCIP_TREE *tree)
Definition: tree.c:9361
SCIP_RETCODE SCIPnodeAddBoundchg(SCIP_NODE *node, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_VAR *var, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype, SCIP_Bool probingchange)
Definition: tree.c:2539
int SCIPtreeGetProbingDepth(SCIP_TREE *tree)
Definition: tree.c:9507
SCIP_RETCODE SCIPtreeStartProbing(SCIP_TREE *tree, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp, SCIP_RELAXATION *relaxation, SCIP_PROB *transprob, SCIP_Bool strongbranching)
Definition: tree.c:7377
SCIP_NODE * SCIPtreeGetCurrentNode(SCIP_TREE *tree)
Definition: tree.c:9462
SCIP_Bool SCIPtreeHasCurrentNodeLP(SCIP_TREE *tree)
Definition: tree.c:9496
SCIP_RETCODE SCIPnodeAddBoundinferExact(SCIP_NODE *node, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LPEXACT *lpexact, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_VAR *var, SCIP_RATIONAL *newbound, SCIP_BOUNDTYPE boundtype, SCIP_CONS *infercons, SCIP_PROP *inferprop, int inferinfo, SCIP_Bool probingchange)
Definition: tree.c:2229
SCIP_RETCODE SCIPtreeEndProbing(SCIP_TREE *tree, SCIP_REOPT *reopt, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_LP *lp, SCIP_RELAXATION *relaxation, SCIP_PRIMAL *primal, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable)
Definition: tree.c:7814
int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
Definition: tree.c:9479
SCIP_RETCODE SCIPnodeAddBoundinfer(SCIP_NODE *node, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_VAR *var, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype, SCIP_CONS *infercons, SCIP_PROP *inferprop, int inferinfo, SCIP_Bool probingchange)
Definition: tree.c:1909
internal methods for branch and bound tree
@ SCIP_BRANCHDIR_DOWNWARDS
Definition: type_history.h:43
@ SCIP_BRANCHDIR_UPWARDS
Definition: type_history.h:44
enum SCIP_BranchDir SCIP_BRANCHDIR
Definition: type_history.h:48
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition: type_lp.h:52
@ SCIP_BOUNDTYPE_UPPER
Definition: type_lp.h:58
@ SCIP_BOUNDTYPE_LOWER
Definition: type_lp.h:57
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:60
@ SCIP_LPSOLSTAT_ERROR
Definition: type_lp.h:50
@ SCIP_LPSOLSTAT_NOTSOLVED
Definition: type_lp.h:43
@ SCIP_LPSOLSTAT_OPTIMAL
Definition: type_lp.h:44
@ SCIP_LPSOLSTAT_TIMELIMIT
Definition: type_lp.h:49
@ SCIP_LPSOLSTAT_UNBOUNDEDRAY
Definition: type_lp.h:46
@ SCIP_LPSOLSTAT_INFEASIBLE
Definition: type_lp.h:45
@ SCIP_LPSOLSTAT_OBJLIMIT
Definition: type_lp.h:47
@ SCIP_LPSOLSTAT_ITERLIMIT
Definition: type_lp.h:48
enum SCIP_Confidencelevel SCIP_CONFIDENCELEVEL
Definition: type_misc.h:53
@ SCIP_R_ROUND_UPWARDS
Definition: type_rational.h:58
@ SCIP_R_ROUND_DOWNWARDS
Definition: type_rational.h:57
@ SCIP_READERROR
Definition: type_retcode.h:45
@ SCIP_INVALIDDATA
Definition: type_retcode.h:52
@ SCIP_OKAY
Definition: type_retcode.h:42
@ SCIP_INVALIDCALL
Definition: type_retcode.h:51
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
@ SCIP_STAGE_PROBLEM
Definition: type_set.h:45
@ SCIP_STAGE_INITPRESOLVE
Definition: type_set.h:48
@ SCIP_STAGE_SOLVED
Definition: type_set.h:54
@ SCIP_STAGE_PRESOLVING
Definition: type_set.h:49
@ SCIP_STAGE_TRANSFORMED
Definition: type_set.h:47
@ SCIP_STAGE_INITSOLVE
Definition: type_set.h:52
@ SCIP_STAGE_EXITPRESOLVE
Definition: type_set.h:50
@ SCIP_STAGE_EXITSOLVE
Definition: type_set.h:55
@ SCIP_STAGE_FREETRANS
Definition: type_set.h:56
@ SCIP_STAGE_SOLVING
Definition: type_set.h:53
@ SCIP_STAGE_TRANSFORMING
Definition: type_set.h:46
@ SCIP_STAGE_PRESOLVED
Definition: type_set.h:51
@ SCIP_STATUS_INFEASIBLE
Definition: type_stat.h:44
@ SCIP_NODETYPE_PROBINGNODE
Definition: type_tree.h:42
struct SCIP_VarData SCIP_VARDATA
Definition: type_var.h:167
#define SCIP_DEPRECATED_VARTYPE_IMPLINT_CHAR
Definition: type_var.h:85
#define NLOCKTYPES
Definition: type_var.h:138
enum SCIP_ImplintType SCIP_IMPLINTTYPE
Definition: type_var.h:117
@ SCIP_IMPLINTTYPE_NONE
Definition: type_var.h:90
@ SCIP_IMPLINTTYPE_WEAK
Definition: type_var.h:91
#define SCIP_DECL_VARDELORIG(x)
Definition: type_var.h:180
#define SCIP_VARTYPE_INTEGER_CHAR
Definition: type_var.h:83
#define SCIP_DECL_VARTRANS(x)
Definition: type_var.h:200
#define SCIP_DEPRECATED_VARTYPE_IMPLINT
Definition: type_var.h:79
@ SCIP_VARTYPE_INTEGER
Definition: type_var.h:65
@ SCIP_VARTYPE_CONTINUOUS
Definition: type_var.h:71
@ SCIP_VARTYPE_BINARY
Definition: type_var.h:64
@ SCIP_VARSTATUS_ORIGINAL
Definition: type_var.h:51
@ SCIP_VARSTATUS_FIXED
Definition: type_var.h:54
@ SCIP_VARSTATUS_COLUMN
Definition: type_var.h:53
@ SCIP_VARSTATUS_MULTAGGR
Definition: type_var.h:56
@ SCIP_VARSTATUS_NEGATED
Definition: type_var.h:57
@ SCIP_VARSTATUS_AGGREGATED
Definition: type_var.h:55
@ SCIP_VARSTATUS_LOOSE
Definition: type_var.h:52
#define SCIP_DECL_VARCOPY(x)
Definition: type_var.h:243
#define SCIP_DECL_VARDELTRANS(x)
Definition: type_var.h:213
enum SCIP_LockType SCIP_LOCKTYPE
Definition: type_var.h:144
@ SCIP_LOCKTYPE_MODEL
Definition: type_var.h:141
#define SCIP_VARTYPE_BINARY_CHAR
Definition: type_var.h:82
enum SCIP_Vartype SCIP_VARTYPE
Definition: type_var.h:73
enum SCIP_Varstatus SCIP_VARSTATUS
Definition: type_var.h:59
#define SCIP_VARTYPE_CONTINUOUS_CHAR
Definition: type_var.h:84
SCIP_Real SCIPvarGetPseudocost(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real solvaldelta)
Definition: var.c:20437
SCIP_RETCODE SCIPvarsGetActiveVars(SCIP_SET *set, SCIP_VAR **vars, int *nvars, int varssize, int *requiredsize)
Definition: var.c:17338
SCIP_RETCODE SCIPvarMultiaggregate(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_CLIQUETABLE *cliquetable, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int naggvars, SCIP_VAR **aggvars, SCIP_Real *scalars, SCIP_Real constant, SCIP_Bool *infeasible, SCIP_Bool *aggregated)
Definition: var.c:8055
SCIP_RETCODE SCIPvarTryAggregateVarsExact(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_CLIQUETABLE *cliquetable, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_VAR *varx, SCIP_VAR *vary, SCIP_RATIONAL *scalarx, SCIP_RATIONAL *scalary, SCIP_RATIONAL *rhs, SCIP_Bool *infeasible, SCIP_Bool *aggregated)
Definition: var.c:7863
SCIP_RETCODE SCIPvarIncNBranchings(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_BRANCHDIR dir, SCIP_Real value, int depth)
Definition: var.c:21499
SCIP_RETCODE SCIPvarChgLbLazy(SCIP_VAR *var, SCIP_SET *set, SCIP_Real lazylb)
Definition: var.c:11771
SCIP_Real SCIPvarGetPseudocostCount(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:20580
SCIP_RETCODE SCIPvarGetTransformed(SCIP_VAR *origvar, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR **transvar)
Definition: var.c:4581
SCIP_RETCODE SCIPvarChgObj(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_Real newobj)
Definition: var.c:9419
SCIP_Real SCIPvarGetPseudocostVariance(SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun)
Definition: var.c:20744
SCIP_Real SCIPvarGetImplRedcost(SCIP_VAR *var, SCIP_SET *set, SCIP_Bool varfixing, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp)
Definition: var.c:19233
SCIP_RETCODE SCIPvarSetLastGMIScore(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real gmieff)
Definition: var.c:22535
SCIP_RETCODE SCIPvarChgUbGlobalExact(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LPEXACT *lpexact, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_RATIONAL *newbound)
Definition: var.c:11618
SCIP_Real SCIPvarGetAncPseudocostCountCurrentRun(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:20670
SCIP_RETCODE SCIPvarIncInferenceSum(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_BRANCHDIR dir, SCIP_Real value, SCIP_Real weight)
Definition: var.c:21583
SCIP_RETCODE SCIPvarChgLbGlobalExact(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LPEXACT *lpexact, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_RATIONAL *newbound)
Definition: var.c:11321
SCIP_RETCODE SCIPvarTryAggregateVars(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_CLIQUETABLE *cliquetable, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_VAR *varx, SCIP_VAR *vary, SCIP_Real scalarx, SCIP_Real scalary, SCIP_Real rhs, SCIP_Bool *infeasible, SCIP_Bool *aggregated)
Definition: var.c:7688
SCIP_RETCODE SCIPvarIncVSIDS(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_BRANCHDIR dir, SCIP_Real value, SCIP_Real weight)
Definition: var.c:21103
SCIP_RETCODE SCIPvarChgUbLocalExact(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LPEXACT *lpexact, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_RATIONAL *newbound)
Definition: var.c:13112
SCIP_Real SCIPvarGetAvgCutoffs(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:22317
SCIP_RETCODE SCIPvarGetProbvarSumExact(SCIP_VAR **var, SCIP_RATIONAL *scalar, SCIP_RATIONAL *constant)
Definition: var.c:18205
SCIP_RETCODE SCIPvarGetMultaggrUbLocalExact(SCIP_VAR *var, SCIP_SET *set, SCIP_RATIONAL *result)
Definition: var.c:13786
SCIP_RETCODE SCIPvarUpdatePseudocost(SCIP_VAR *var, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
Definition: var.c:20274
SCIP_RETCODE SCIPvarTransform(SCIP_VAR *origvar, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_OBJSENSE objsense, SCIP_VAR **transvar)
Definition: var.c:4494
SCIP_Real SCIPvarGetAvgInferencesCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:22176
SCIP_RETCODE SCIPvarRelease(SCIP_VAR **var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: var.c:3787
void SCIPvarGetClosestVub(SCIP_VAR *var, SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real *closestvub, int *closestvubidx)
Definition: var.c:19963
SCIP_RETCODE SCIPvarIncNActiveConflicts(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_BRANCHDIR dir, SCIP_Real value, SCIP_Real length)
Definition: var.c:21239
void SCIPvarAdjustLb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *lb)
Definition: var.c:9910
void SCIPvarAdjustLbExact(SCIP_VAR *var, SCIP_SET *set, SCIP_RATIONAL *lb)
Definition: var.c:9927
SCIP_RETCODE SCIPvarChgLbGlobal(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_Real newbound)
Definition: var.c:11178
SCIP_Real SCIPvarCalcPscostConfidenceBound(SCIP_VAR *var, SCIP_SET *set, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun, SCIP_CONFIDENCELEVEL clevel)
Definition: var.c:20798
SCIP_Bool SCIPvarIsPscostRelerrorReliable(SCIP_VAR *var, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real threshold, SCIP_CONFIDENCELEVEL clevel)
Definition: var.c:20836
SCIP_RETCODE SCIPvarChgLbOriginal(SCIP_VAR *var, SCIP_SET *set, SCIP_Real newbound)
Definition: var.c:10028
SCIP_RETCODE SCIPvarPrint(SCIP_VAR *var, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: var.c:3953
SCIP_Real SCIPvarGetAvgGMIScore(SCIP_VAR *var, SCIP_STAT *stat)
Definition: var.c:22411
SCIP_Real SCIPvarGetVSIDS(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:24782
SCIP_RETCODE SCIPvarIncCutoffSum(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_BRANCHDIR dir, SCIP_Real value, SCIP_Real weight)
Definition: var.c:21667
SCIP_Real SCIPvarGetMultaggrLbLocal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:13574
SCIP_Bool SCIPvarSignificantPscostDifference(SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *varx, SCIP_Real fracx, SCIP_VAR *vary, SCIP_Real fracy, SCIP_BRANCHDIR dir, SCIP_CONFIDENCELEVEL clevel, SCIP_Bool onesided)
Definition: var.c:20913
void SCIPvarCapture(SCIP_VAR *var)
Definition: var.c:3762
SCIP_RETCODE SCIPvarChgBranchDirection(SCIP_VAR *var, SCIP_BRANCHDIR branchdirection)
Definition: var.c:17150
SCIP_Real SCIPvarGetPseudocostCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real solvaldelta)
Definition: var.c:20533
SCIP_Bool SCIPvarDoNotAggr(SCIP_VAR *var)
Definition: var.c:8843
SCIP_RETCODE SCIPvarChgType(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_VARTYPE vartype)
Definition: var.c:9242
SCIP_RETCODE SCIPvarFlattenAggregationGraph(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: var.c:5989
void SCIPvarAdjustUbExact(SCIP_VAR *var, SCIP_SET *set, SCIP_RATIONAL *ub)
Definition: var.c:9978
SCIP_RETCODE SCIPvarCreateOriginal(SCIP_VAR **var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_IMPLINTTYPE impltype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
Definition: var.c:2487
void SCIPvarUpdateBestRootSol(SCIP_VAR *var, SCIP_SET *set, SCIP_Real rootsol, SCIP_Real rootredcost, SCIP_Real rootlpobjval)
Definition: var.c:19045
SCIP_RETCODE SCIPvarFixExact(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_RATIONAL *fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition: var.c:4987
SCIP_RETCODE SCIPvarChgImplType(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_IMPLINTTYPE impltype)
Definition: var.c:9301
SCIP_Real SCIPvarGetAvgConflictlength(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:21412
SCIP_Real SCIPvarGetPseudocostCountCurrentRun(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:20625
SCIP_RETCODE SCIPvarChgUbGlobal(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_Real newbound)
Definition: var.c:11475
SCIP_RETCODE SCIPvarMultiaggregateExact(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LPEXACT *lpexact, SCIP_CLIQUETABLE *cliquetable, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int naggvars, SCIP_VAR **aggvars, SCIP_RATIONAL **scalars, SCIP_RATIONAL *constant, SCIP_Bool *infeasible, SCIP_Bool *aggregated)
Definition: var.c:8415
SCIP_RETCODE SCIPvarChgUbOriginalExact(SCIP_VAR *var, SCIP_SET *set, SCIP_RATIONAL *newbound)
Definition: var.c:10220
SCIP_RETCODE SCIPvarCreateTransformed(SCIP_VAR **var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_IMPLINTTYPE impltype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
Definition: var.c:2531
SCIP_RETCODE SCIPvarParseTransformed(SCIP_VAR **var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, const char *str, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARCOPY((*varcopy)), SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_VARDATA *vardata, char **endptr, SCIP_Bool *success)
Definition: var.c:3357
SCIP_Real SCIPvarGetAncPseudocost(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real solvaldelta)
Definition: var.c:20484
SCIP_RETCODE SCIPvarChgUbOriginal(SCIP_VAR *var, SCIP_SET *set, SCIP_Real newbound)
Definition: var.c:10161
SCIP_Real SCIPvarGetAvgInferences(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:22119
SCIP_RETCODE SCIPvarAddObj(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_Real addobj)
Definition: var.c:9589
SCIP_Real SCIPvarGetMultaggrUbGlobal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:13936
void SCIPvarGetClosestVlb(SCIP_VAR *var, SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real *closestvlb, int *closestvlbidx)
Definition: var.c:19888
SCIP_RETCODE SCIPvarChgUbLazy(SCIP_VAR *var, SCIP_SET *set, SCIP_Real lazyub)
Definition: var.c:11794
SCIP_RETCODE SCIPvarChgLbOriginalExact(SCIP_VAR *var, SCIP_SET *set, SCIP_RATIONAL *newbound)
Definition: var.c:10087
SCIP_Bool SCIPvarPscostThresholdProbabilityTest(SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var, SCIP_Real frac, SCIP_Real threshold, SCIP_BRANCHDIR dir, SCIP_CONFIDENCELEVEL clevel)
Definition: var.c:20979
SCIP_RETCODE SCIPvarAddVlb(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_CLIQUETABLE *cliquetable, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_VAR *vlbvar, SCIP_Real vlbcoef, SCIP_Real vlbconstant, SCIP_Bool transitive, SCIP_Bool *infeasible, int *nbdchgs)
Definition: var.c:15316
SCIP_RETCODE SCIPvarUpdateAncPseudocost(SCIP_VAR *var, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
Definition: var.c:20374
SCIP_Real SCIPvarGetRelaxSol(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:19688
SCIP_RETCODE SCIPvarMarkDoNotAggr(SCIP_VAR *var)
Definition: var.c:9170
SCIP_RETCODE SCIPvarChgLbLocal(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_Real newbound)
Definition: var.c:12715
SCIP_RETCODE SCIPvarChgBranchPriority(SCIP_VAR *var, int branchpriority)
Definition: var.c:17019
SCIP_RETCODE SCIPvarChgLbLocalExact(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LPEXACT *lpexact, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_RATIONAL *newbound)
Definition: var.c:12845
SCIP_RETCODE SCIPvarMarkDoNotMultaggr(SCIP_VAR *var)
Definition: var.c:9206
SCIP_RETCODE SCIPvarAddLocks(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LOCKTYPE locktype, int addnlocksdown, int addnlocksup)
Definition: var.c:4200
SCIP_RETCODE SCIPvarNegate(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR **negvar)
Definition: var.c:8979
SCIP_Real SCIPvarGetMultaggrUbLocal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:13722
SCIP_RETCODE SCIPvarGetProbvarSum(SCIP_VAR **var, SCIP_SET *set, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:18075
SCIP_Bool SCIPvarIsAggrCoefAcceptable(SCIP_SET *set, SCIP_VAR *var, SCIP_Real scalar)
Definition: var.c:8909
SCIP_RETCODE SCIPvarAddExactData(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_RATIONAL *lb, SCIP_RATIONAL *ub, SCIP_RATIONAL *obj)
Definition: var.c:2578
SCIP_RETCODE SCIPvarIncGMIeffSum(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real gmieff)
Definition: var.c:22451
SCIP_Real SCIPvarGetLastGMIScore(SCIP_VAR *var, SCIP_STAT *stat)
Definition: var.c:22495
void SCIPvarAdjustUb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *ub)
Definition: var.c:9961
SCIP_RETCODE SCIPvarGetActiveRepresentatives(SCIP_SET *set, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize)
Definition: var.c:5180
SCIP_RETCODE SCIPvarFix(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition: var.c:4820
SCIP_Real SCIPvarGetAvgConflictlengthCurrentRun(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:21456
SCIP_RETCODE SCIPvarChgUbLocal(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_Real newbound)
Definition: var.c:12983
SCIP_RETCODE SCIPvarParseOriginal(SCIP_VAR **var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, const char *str, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARCOPY((*varcopy)), SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_VARDATA *vardata, char **endptr, SCIP_Bool *success)
Definition: var.c:3234
SCIP_RETCODE SCIPvarAddVub(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_CLIQUETABLE *cliquetable, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_VAR *vubvar, SCIP_Real vubcoef, SCIP_Real vubconstant, SCIP_Bool transitive, SCIP_Bool *infeasible, int *nbdchgs)
Definition: var.c:15783
SCIP_Real SCIPvarGetVSIDSCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:21980
SCIP_RETCODE SCIPvarChgName(SCIP_VAR *var, BMS_BLKMEM *blkmem, const char *name)
Definition: var.c:3828
void SCIPvarAdjustUbExactFloat(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *ub)
Definition: var.c:9995
SCIP_Real SCIPvarGetMultaggrLbGlobal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:13870
SCIP_RETCODE SCIPvarSetRelaxSol(SCIP_VAR *var, SCIP_SET *set, SCIP_RELAXATION *relaxation, SCIP_Real solval, SCIP_Bool updateobj)
Definition: var.c:19627
void SCIPvarAdjustLbExactFloat(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *lb)
Definition: var.c:9944
SCIP_RETCODE SCIPvarChgBranchFactor(SCIP_VAR *var, SCIP_SET *set, SCIP_Real branchfactor)
Definition: var.c:16892
SCIP_RETCODE SCIPvarAddImplic(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_CLIQUETABLE *cliquetable, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_Bool varfixing, SCIP_VAR *implvar, SCIP_BOUNDTYPE impltype, SCIP_Real implbound, SCIP_Bool transitive, SCIP_Bool *infeasible, int *nbdchgs)
Definition: var.c:16241
SCIP_RETCODE SCIPvarChgObjExact(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_LPEXACT *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_RATIONAL *newobj)
Definition: var.c:9494
SCIP_Real SCIPvarGetAvgCutoffsCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:22364
SCIP_Bool SCIPvarDoNotMultaggr(SCIP_VAR *var)
Definition: var.c:8876
SCIP_RETCODE SCIPvarRemoveCliquesImplicsVbs(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_CLIQUETABLE *cliquetable, SCIP_SET *set, SCIP_Bool irrelevantvar, SCIP_Bool onlyredundant, SCIP_Bool removefromvar)
Definition: var.c:2006
SCIP_RETCODE SCIPvarGetMultaggrLbLocalExact(SCIP_VAR *var, SCIP_SET *set, SCIP_RATIONAL *result)
Definition: var.c:13638
SCIP_RETCODE SCIPvarGetActiveRepresentativesExact(SCIP_SET *set, SCIP_VAR **vars, SCIP_RATIONAL **scalars, int *nvars, int varssize, SCIP_RATIONAL *constant, int *requiredsize, SCIP_Bool mergemultiples)
Definition: var.c:5511
internal methods for problem variables