SCIP Doxygen Documentation
 
Loading...
Searching...
No Matches
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-2024 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 *
40 * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE
41 */
42
43/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
44
45#include <ctype.h>
47#include "lpi/lpi.h"
48#include "scip/branch.h"
49#include "scip/clock.h"
50#include "scip/conflict.h"
51#include "scip/debug.h"
52#include "scip/history.h"
53#include "scip/implics.h"
54#include "scip/lp.h"
55#include "scip/prob.h"
56#include "scip/pub_cons.h"
57#include "scip/pub_implics.h"
58#include "scip/pub_lp.h"
59#include "scip/pub_message.h"
60#include "scip/pub_misc.h"
61#include "scip/pub_tree.h"
62#include "scip/pub_var.h"
63#include "scip/relax.h"
64#include "scip/scip_general.h"
65#include "scip/scip_lp.h"
66#include "scip/scip_mem.h"
67#include "scip/scip_message.h"
68#include "scip/scip_numerics.h"
69#include "scip/scip_prob.h"
70#include "scip/scip_probing.h"
71#include "scip/scip_sol.h"
73#include "scip/scip_tree.h"
74#include "scip/scip_var.h"
75#include "scip/set.h"
76#include "scip/sol.h"
77#include "scip/solve.h"
78#include "scip/stat.h"
79#include "scip/struct_lp.h"
80#include "scip/struct_mem.h"
81#include "scip/struct_primal.h"
82#include "scip/struct_prob.h"
83#include "scip/struct_scip.h"
84#include "scip/struct_set.h"
85#include "scip/struct_stat.h"
86#include "scip/struct_tree.h"
87#include "scip/struct_var.h"
88#include "scip/tree.h"
89#include "scip/var.h"
90
91
92/** creates and captures problem variable; if variable is of integral type, fractional bounds are automatically rounded;
93 * an integer variable with bounds zero and one is automatically converted into a binary variable;
94 *
95 * @warning When doing column generation and the original problem is a maximization problem, notice that SCIP will
96 * transform the problem into a minimization problem by multiplying the objective function by -1. Thus, the
97 * original objective function value of variables created during the solving process has to be multiplied by
98 * -1, too.
99 *
100 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
101 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
102 *
103 * @pre This method can be called if @p scip is in one of the following stages:
104 * - \ref SCIP_STAGE_PROBLEM
105 * - \ref SCIP_STAGE_TRANSFORMING
106 * - \ref SCIP_STAGE_INITPRESOLVE
107 * - \ref SCIP_STAGE_PRESOLVING
108 * - \ref SCIP_STAGE_EXITPRESOLVE
109 * - \ref SCIP_STAGE_PRESOLVED
110 * - \ref SCIP_STAGE_SOLVING
111 *
112 * @note the variable gets captured, hence at one point you have to release it using the method SCIPreleaseVar()
113 */
115 SCIP* scip, /**< SCIP data structure */
116 SCIP_VAR** var, /**< pointer to variable object */
117 const char* name, /**< name of variable, or NULL for automatic name creation */
118 SCIP_Real lb, /**< lower bound of variable */
119 SCIP_Real ub, /**< upper bound of variable */
120 SCIP_Real obj, /**< objective function value */
121 SCIP_VARTYPE vartype, /**< type of variable */
122 SCIP_Bool initial, /**< should var's column be present in the initial root LP? */
123 SCIP_Bool removable, /**< is var's column removable from the LP (due to aging or cleanup)? */
124 SCIP_DECL_VARDELORIG ((*vardelorig)), /**< frees user data of original variable, or NULL */
125 SCIP_DECL_VARTRANS ((*vartrans)), /**< creates transformed user data by transforming original user data, or NULL */
126 SCIP_DECL_VARDELTRANS ((*vardeltrans)), /**< frees user data of transformed variable, or NULL */
127 SCIP_DECL_VARCOPY ((*varcopy)), /**< copies variable data if wanted to subscip, or NULL */
128 SCIP_VARDATA* vardata /**< user data for this specific variable */
129 )
130{
131 assert(var != NULL);
132 assert(lb <= ub);
133
135
136 /* forbid infinite objective function values */
138 {
139 SCIPerrorMessage("invalid objective function value: value is infinite\n");
140 return SCIP_INVALIDDATA;
141 }
142
143 switch( scip->set->stage )
144 {
146 SCIP_CALL( SCIPvarCreateOriginal(var, scip->mem->probmem, scip->set, scip->stat,
147 name, lb, ub, obj, vartype, initial, removable, vardelorig, vartrans, vardeltrans, varcopy, vardata) );
148 break;
149
156 SCIP_CALL( SCIPvarCreateTransformed(var, scip->mem->probmem, scip->set, scip->stat,
157 name, lb, ub, obj, vartype, initial, removable, vardelorig, vartrans, vardeltrans, varcopy, vardata) );
158 break;
159
160 default:
161 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
162 return SCIP_INVALIDCALL;
163 } /*lint !e788*/
164
165 return SCIP_OKAY;
166}
167
168/** creates and captures problem variable with optional callbacks and variable data set to NULL, which can be set
169 * afterwards using SCIPvarSetDelorigData(), SCIPvarSetTransData(),
170 * SCIPvarSetDeltransData(), SCIPvarSetCopy(), and SCIPvarSetData(); sets variable flags initial=TRUE
171 * and removable = FALSE, which can be adjusted by using SCIPvarSetInitial() and SCIPvarSetRemovable(), resp.;
172 * if variable is of integral type, fractional bounds are automatically rounded;
173 * an integer variable with bounds zero and one is automatically converted into a binary variable;
174 *
175 * @warning When doing column generation and the original problem is a maximization problem, notice that SCIP will
176 * transform the problem into a minimization problem by multiplying the objective function by -1. Thus, the
177 * original objective function value of variables created during the solving process has to be multiplied by
178 * -1, too.
179 *
180 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
181 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
182 *
183 * @pre This method can be called if @p scip is in one of the following stages:
184 * - \ref SCIP_STAGE_PROBLEM
185 * - \ref SCIP_STAGE_TRANSFORMING
186 * - \ref SCIP_STAGE_INITPRESOLVE
187 * - \ref SCIP_STAGE_PRESOLVING
188 * - \ref SCIP_STAGE_EXITPRESOLVE
189 * - \ref SCIP_STAGE_PRESOLVED
190 * - \ref SCIP_STAGE_SOLVING
191 *
192 * @note the variable gets captured, hence at one point you have to release it using the method SCIPreleaseVar()
193 */
195 SCIP* scip, /**< SCIP data structure */
196 SCIP_VAR** var, /**< pointer to variable object */
197 const char* name, /**< name of variable, or NULL for automatic name creation */
198 SCIP_Real lb, /**< lower bound of variable */
199 SCIP_Real ub, /**< upper bound of variable */
200 SCIP_Real obj, /**< objective function value */
201 SCIP_VARTYPE vartype /**< type of variable */
202 )
203{
204 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateVarBasic", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
205
206 SCIP_CALL( SCIPcreateVar(scip, var, name, lb, ub, obj, vartype, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
207
208 return SCIP_OKAY;
209}
210
211/** outputs the variable name to the file stream
212 *
213 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
214 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
215 *
216 * @pre This method can be called if @p scip is in one of the following stages:
217 * - \ref SCIP_STAGE_PROBLEM
218 * - \ref SCIP_STAGE_TRANSFORMING
219 * - \ref SCIP_STAGE_TRANSFORMED
220 * - \ref SCIP_STAGE_INITPRESOLVE
221 * - \ref SCIP_STAGE_PRESOLVING
222 * - \ref SCIP_STAGE_EXITPRESOLVE
223 * - \ref SCIP_STAGE_PRESOLVED
224 * - \ref SCIP_STAGE_INITSOLVE
225 * - \ref SCIP_STAGE_SOLVING
226 * - \ref SCIP_STAGE_SOLVED
227 * - \ref SCIP_STAGE_EXITSOLVE
228 * - \ref SCIP_STAGE_FREETRANS
229 */
231 SCIP* scip, /**< SCIP data structure */
232 FILE* file, /**< output file, or NULL for stdout */
233 SCIP_VAR* var, /**< variable to output */
234 SCIP_Bool type /**< should the variable type be also posted */
235 )
236{
237 assert(scip != NULL);
238 assert(var != NULL);
239
240 SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarName", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
241
242 /* print variable name */
243 if( SCIPvarIsNegated(var) )
244 {
245 SCIP_VAR* negatedvar;
246
247 SCIP_CALL( SCIPgetNegatedVar(scip, var, &negatedvar) );
248 SCIPinfoMessage(scip, file, "<~%s>", SCIPvarGetName(negatedvar));
249 }
250 else
251 {
252 SCIPinfoMessage(scip, file, "<%s>", SCIPvarGetName(var));
253 }
254
255 if( type )
256 {
257 /* print variable type */
258 SCIPinfoMessage(scip, file, "[%c]",
262 }
263
264 return SCIP_OKAY;
265}
266
267/** print the given list of variables to output stream separated by the given delimiter character;
268 *
269 * i. e. the variables x1, x2, ..., xn with given delimiter ',' are written as: <x1>, <x2>, ..., <xn>;
270 *
271 * the method SCIPparseVarsList() can parse such a string
272 *
273 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
274 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
275 *
276 * @pre This method can be called if @p scip is in one of the following stages:
277 * - \ref SCIP_STAGE_PROBLEM
278 * - \ref SCIP_STAGE_TRANSFORMING
279 * - \ref SCIP_STAGE_TRANSFORMED
280 * - \ref SCIP_STAGE_INITPRESOLVE
281 * - \ref SCIP_STAGE_PRESOLVING
282 * - \ref SCIP_STAGE_EXITPRESOLVE
283 * - \ref SCIP_STAGE_PRESOLVED
284 * - \ref SCIP_STAGE_INITSOLVE
285 * - \ref SCIP_STAGE_SOLVING
286 * - \ref SCIP_STAGE_SOLVED
287 * - \ref SCIP_STAGE_EXITSOLVE
288 * - \ref SCIP_STAGE_FREETRANS
289 *
290 * @note The printing process is done via the message handler system.
291 */
293 SCIP* scip, /**< SCIP data structure */
294 FILE* file, /**< output file, or NULL for stdout */
295 SCIP_VAR** vars, /**< variable array to output */
296 int nvars, /**< number of variables */
297 SCIP_Bool type, /**< should the variable type be also posted */
298 char delimiter /**< character which is used for delimitation */
299 )
300{
301 int v;
302
303 SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsList", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
304
305 for( v = 0; v < nvars; ++v )
306 {
307 if( v > 0 )
308 {
309 SCIPinfoMessage(scip, file, "%c", delimiter);
310 }
311
312 /* print variable name */
313 SCIP_CALL( SCIPwriteVarName(scip, file, vars[v], type) );
314 }
315
316 return SCIP_OKAY;
317}
318
319/** print the given variables and coefficients as linear sum in the following form
320 * c1 <x1> + c2 <x2> ... + cn <xn>
321 *
322 * This string can be parsed by the method SCIPparseVarsLinearsum().
323 *
324 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
325 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
326 *
327 * @pre This method can be called if @p scip is in one of the following stages:
328 * - \ref SCIP_STAGE_PROBLEM
329 * - \ref SCIP_STAGE_TRANSFORMING
330 * - \ref SCIP_STAGE_TRANSFORMED
331 * - \ref SCIP_STAGE_INITPRESOLVE
332 * - \ref SCIP_STAGE_PRESOLVING
333 * - \ref SCIP_STAGE_EXITPRESOLVE
334 * - \ref SCIP_STAGE_PRESOLVED
335 * - \ref SCIP_STAGE_INITSOLVE
336 * - \ref SCIP_STAGE_SOLVING
337 * - \ref SCIP_STAGE_SOLVED
338 * - \ref SCIP_STAGE_EXITSOLVE
339 * - \ref SCIP_STAGE_FREETRANS
340 *
341 * @note The printing process is done via the message handler system.
342 */
344 SCIP* scip, /**< SCIP data structure */
345 FILE* file, /**< output file, or NULL for stdout */
346 SCIP_VAR** vars, /**< variable array to output */
347 SCIP_Real* vals, /**< array of coefficients or NULL if all coefficients are 1.0 */
348 int nvars, /**< number of variables */
349 SCIP_Bool type /**< should the variable type be also posted */
350 )
351{
352 int v;
353
354 SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsLinearsum", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
355
356 for( v = 0; v < nvars; ++v )
357 {
358 if( vals != NULL )
359 {
360 if( vals[v] == 1.0 )
361 {
362 if( v > 0 )
363 SCIPinfoMessage(scip, file, " +");
364 }
365 else if( vals[v] == -1.0 )
366 SCIPinfoMessage(scip, file, " -");
367 else
368 SCIPinfoMessage(scip, file, " %+.15g", vals[v]);
369 }
370 else if( nvars > 0 )
371 SCIPinfoMessage(scip, file, " +");
372
373 /* print variable name */
374 SCIP_CALL( SCIPwriteVarName(scip, file, vars[v], type) );
375 }
376
377 return SCIP_OKAY;
378}
379
380/** print the given terms as signomial in the following form
381 * c1 <x11>^e11 <x12>^e12 ... <x1n>^e1n + c2 <x21>^e21 <x22>^e22 ... + ... + cn <xn1>^en1 ...
382 *
383 * This string can be parsed by the method SCIPparseVarsPolynomial().
384 *
385 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
386 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
387 *
388 * @pre This method can be called if @p scip is in one of the following stages:
389 * - \ref SCIP_STAGE_PROBLEM
390 * - \ref SCIP_STAGE_TRANSFORMING
391 * - \ref SCIP_STAGE_TRANSFORMED
392 * - \ref SCIP_STAGE_INITPRESOLVE
393 * - \ref SCIP_STAGE_PRESOLVING
394 * - \ref SCIP_STAGE_EXITPRESOLVE
395 * - \ref SCIP_STAGE_PRESOLVED
396 * - \ref SCIP_STAGE_INITSOLVE
397 * - \ref SCIP_STAGE_SOLVING
398 * - \ref SCIP_STAGE_SOLVED
399 * - \ref SCIP_STAGE_EXITSOLVE
400 * - \ref SCIP_STAGE_FREETRANS
401 *
402 * @note The printing process is done via the message handler system.
403 */
405 SCIP* scip, /**< SCIP data structure */
406 FILE* file, /**< output file, or NULL for stdout */
407 SCIP_VAR*** monomialvars, /**< arrays with variables for each monomial */
408 SCIP_Real** monomialexps, /**< arrays with variable exponents, or NULL if always 1.0 */
409 SCIP_Real* monomialcoefs, /**< array with monomial coefficients */
410 int* monomialnvars, /**< array with number of variables for each monomial */
411 int nmonomials, /**< number of monomials */
412 SCIP_Bool type /**< should the variable type be also posted */
413 )
414{
415 int i;
416 int v;
417
418 assert(scip != NULL);
419 assert(monomialvars != NULL || nmonomials == 0);
420 assert(monomialcoefs != NULL || nmonomials == 0);
421 assert(monomialnvars != NULL || nmonomials == 0);
422
423 SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsPolynomial", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
424
425 if( nmonomials == 0 )
426 {
427 SCIPinfoMessage(scip, file, " 0 ");
428 return SCIP_OKAY;
429 }
430
431 for( i = 0; i < nmonomials; ++i )
432 {
433 if( monomialcoefs[i] == 1.0 ) /*lint !e613*/
434 {
435 if( i > 0 )
436 SCIPinfoMessage(scip, file, " +");
437 }
438 else if( monomialcoefs[i] == -1.0 ) /*lint !e613*/
439 SCIPinfoMessage(scip, file, " -");
440 else
441 SCIPinfoMessage(scip, file, " %+.15g", monomialcoefs[i]); /*lint !e613*/
442
443 assert(monomialvars[i] != NULL || monomialnvars[i] == 0); /*lint !e613*/
444
445 for( v = 0; v < monomialnvars[i]; ++v ) /*lint !e613*/
446 {
447 SCIP_CALL( SCIPwriteVarName(scip, file, monomialvars[i][v], type) ); /*lint !e613*/
448 if( monomialexps != NULL && monomialexps[i] != NULL && monomialexps[i][v] != 1.0 )
449 {
450 SCIPinfoMessage(scip, file, "^%.15g", monomialexps[i][v]);
451 }
452 }
453 }
454
455 return SCIP_OKAY;
456}
457
458/** parses variable information (in cip format) out of a string; if the parsing process was successful a variable is
459 * created and captured; if variable is of integral type, fractional bounds are automatically rounded; an integer
460 * variable with bounds zero and one is automatically converted into a binary variable
461 *
462 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
463 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
464 *
465 * @pre This method can be called if @p scip is in one of the following stages:
466 * - \ref SCIP_STAGE_PROBLEM
467 * - \ref SCIP_STAGE_TRANSFORMING
468 * - \ref SCIP_STAGE_INITPRESOLVE
469 * - \ref SCIP_STAGE_PRESOLVING
470 * - \ref SCIP_STAGE_EXITPRESOLVE
471 * - \ref SCIP_STAGE_PRESOLVED
472 * - \ref SCIP_STAGE_SOLVING
473 */
475 SCIP* scip, /**< SCIP data structure */
476 SCIP_VAR** var, /**< pointer to store the problem variable */
477 const char* str, /**< string to parse */
478 SCIP_Bool initial, /**< should var's column be present in the initial root LP? */
479 SCIP_Bool removable, /**< is var's column removable from the LP (due to aging or cleanup)? */
480 SCIP_DECL_VARCOPY ((*varcopy)), /**< copies variable data if wanted to subscip, or NULL */
481 SCIP_DECL_VARDELORIG ((*vardelorig)), /**< frees user data of original variable */
482 SCIP_DECL_VARTRANS ((*vartrans)), /**< creates transformed user data by transforming original user data */
483 SCIP_DECL_VARDELTRANS ((*vardeltrans)), /**< frees user data of transformed variable */
484 SCIP_VARDATA* vardata, /**< user data for this specific variable */
485 char** endptr, /**< pointer to store the final string position if successful */
486 SCIP_Bool* success /**< pointer store if the paring process was successful */
487 )
488{
489 assert(var != NULL);
490
492
493 switch( scip->set->stage )
494 {
496 SCIP_CALL( SCIPvarParseOriginal(var, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
497 str, initial, removable, varcopy, vardelorig, vartrans, vardeltrans, vardata, endptr, success) );
498 break;
499
506 SCIP_CALL( SCIPvarParseTransformed(var, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
507 str, initial, removable, varcopy, vardelorig, vartrans, vardeltrans, vardata, endptr, success) );
508 break;
509
510 default:
511 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
512 return SCIP_INVALIDCALL;
513 } /*lint !e788*/
514
515 return SCIP_OKAY;
516}
517
518/** parses the given string for a variable name and stores the variable in the corresponding pointer if such a variable
519 * exits and returns the position where the parsing stopped
520 *
521 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
522 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
523 *
524 * @pre This method can be called if @p scip is in one of the following stages:
525 * - \ref SCIP_STAGE_PROBLEM
526 * - \ref SCIP_STAGE_TRANSFORMING
527 * - \ref SCIP_STAGE_INITPRESOLVE
528 * - \ref SCIP_STAGE_PRESOLVING
529 * - \ref SCIP_STAGE_EXITPRESOLVE
530 * - \ref SCIP_STAGE_PRESOLVED
531 * - \ref SCIP_STAGE_SOLVING
532 */
534 SCIP* scip, /**< SCIP data structure */
535 const char* str, /**< string to parse */
536 SCIP_VAR** var, /**< pointer to store the problem variable, or NULL if it does not exit */
537 char** endptr /**< pointer to store the final string position if successful */
538 )
539{
540 char varname[SCIP_MAXSTRLEN];
541
542 assert(str != NULL);
543 assert(var != NULL);
544 assert(endptr != NULL);
545
546 SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarName", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
547
548 SCIPstrCopySection(str, '<', '>', varname, SCIP_MAXSTRLEN, endptr);
549 assert(*endptr != NULL);
550
551 if( *endptr == str )
552 {
553 *var = NULL;
554 return SCIP_OKAY;
555 }
556
557 /* check if we have a negated variable */
558 if( *varname == '~' )
559 {
560 SCIPdebugMsg(scip, "parsed negated variable name <%s>\n", &varname[1]);
561
562 /* search for the variable and ignore '~' */
563 (*var) = SCIPfindVar(scip, &varname[1]);
564
565 if( *var != NULL )
566 {
568 }
569 }
570 else
571 {
572 SCIPdebugMsg(scip, "parsed variable name <%s>\n", varname);
573
574 /* search for the variable */
575 (*var) = SCIPfindVar(scip, varname);
576 }
577
578 str = *endptr;
579
580 /* skip additional variable type marker */
581 if( *str == '[' && (str[1] == SCIP_VARTYPE_BINARY_CHAR || str[1] == SCIP_VARTYPE_INTEGER_CHAR ||
582 str[1] == SCIP_VARTYPE_IMPLINT_CHAR || str[1] == SCIP_VARTYPE_CONTINUOUS_CHAR ) && str[2] == ']' )
583 (*endptr) += 3;
584
585 return SCIP_OKAY;
586}
587
588/** parse the given string as variable list (here ',' is the delimiter)) (<x1>, <x2>, ..., <xn>) (see
589 * SCIPwriteVarsList() ); if it was successful, the pointer success is set to TRUE
590 *
591 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
592 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
593 *
594 * @pre This method can be called if @p scip is in one of the following stages:
595 * - \ref SCIP_STAGE_PROBLEM
596 * - \ref SCIP_STAGE_TRANSFORMING
597 * - \ref SCIP_STAGE_INITPRESOLVE
598 * - \ref SCIP_STAGE_PRESOLVING
599 * - \ref SCIP_STAGE_EXITPRESOLVE
600 * - \ref SCIP_STAGE_PRESOLVED
601 * - \ref SCIP_STAGE_SOLVING
602 *
603 * @note The pointer success in only set to FALSE in the case that a variable with a parsed variable name does not exist.
604 *
605 * @note If the number of (parsed) variables is greater than the available slots in the variable array, nothing happens
606 * except that the required size is stored in the corresponding integer; the reason for this approach is that we
607 * cannot reallocate memory, since we do not know how the memory has been allocated (e.g., by a C++ 'new' or SCIP
608 * memory functions).
609 */
611 SCIP* scip, /**< SCIP data structure */
612 const char* str, /**< string to parse */
613 SCIP_VAR** vars, /**< array to store the parsed variable */
614 int* nvars, /**< pointer to store number of parsed variables */
615 int varssize, /**< size of the variable array */
616 int* requiredsize, /**< pointer to store the required array size for the active variables */
617 char** endptr, /**< pointer to store the final string position if successful */
618 char delimiter, /**< character which is used for delimitation */
619 SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
620 )
621{
622 SCIP_VAR** tmpvars;
623 SCIP_VAR* var;
624 int ntmpvars = 0;
625 int v;
626
627 assert( nvars != NULL );
628 assert( requiredsize != NULL );
629 assert( endptr != NULL );
630 assert( success != NULL );
631
632 SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsList", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
633
634 /* allocate buffer memory for temporary storing the parsed variables */
635 SCIP_CALL( SCIPallocBufferArray(scip, &tmpvars, varssize) );
636
637 *success = TRUE;
638
639 do
640 {
641 *endptr = (char*)str;
642
643 /* parse variable name */
644 SCIP_CALL( SCIPparseVarName(scip, str, &var, endptr) );
645
646 if( var == NULL )
647 break;
648
649 str = *endptr;
650
651 /* store the variable in the tmp array */
652 if( ntmpvars < varssize )
653 tmpvars[ntmpvars] = var;
654
655 ntmpvars++;
656
657 SCIP_CALL( SCIPskipSpace((char**)&str) );
658 }
659 while( *str == delimiter );
660
661 *endptr = (char*)str;
662
663 /* if all variable name searches were successful and the variable array has enough slots, copy the collected variables */
664 if( (*success) && ntmpvars <= varssize )
665 {
666 for( v = 0; v < ntmpvars; ++v )
667 vars[v] = tmpvars[v];
668
669 (*nvars) = ntmpvars;
670 }
671 else
672 (*nvars) = 0;
673
674 (*requiredsize) = ntmpvars;
675
676 /* free buffer arrays */
677 SCIPfreeBufferArray(scip, &tmpvars);
678
679 return SCIP_OKAY;
680}
681
682/** parse the given string as linear sum of variables and coefficients (c1 <x1> + c2 <x2> + ... + cn <xn>)
683 * (see SCIPwriteVarsLinearsum() ); if it was successful, the pointer success is set to TRUE
684 *
685 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
686 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
687 *
688 * @pre This method can be called if @p scip is in one of the following stages:
689 * - \ref SCIP_STAGE_PROBLEM
690 * - \ref SCIP_STAGE_TRANSFORMING
691 * - \ref SCIP_STAGE_INITPRESOLVE
692 * - \ref SCIP_STAGE_PRESOLVING
693 * - \ref SCIP_STAGE_EXITPRESOLVE
694 * - \ref SCIP_STAGE_PRESOLVED
695 * - \ref SCIP_STAGE_SOLVING
696 *
697 * @note The pointer success in only set to FALSE in the case that a variable with a parsed variable name does not exist.
698 *
699 * @note If the number of (parsed) variables is greater than the available slots in the variable array, nothing happens
700 * except that the required size is stored in the corresponding integer; the reason for this approach is that we
701 * cannot reallocate memory, since we do not know how the memory has been allocated (e.g., by a C++ 'new' or SCIP
702 * memory functions).
703 */
705 SCIP* scip, /**< SCIP data structure */
706 const char* str, /**< string to parse */
707 SCIP_VAR** vars, /**< array to store the parsed variables */
708 SCIP_Real* vals, /**< array to store the parsed coefficients */
709 int* nvars, /**< pointer to store number of parsed variables */
710 int varssize, /**< size of the variable array */
711 int* requiredsize, /**< pointer to store the required array size for the active variables */
712 char** endptr, /**< pointer to store the final string position if successful */
713 SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
714 )
715{
716 SCIP_VAR*** monomialvars;
717 SCIP_Real** monomialexps;
718 SCIP_Real* monomialcoefs;
719 int* monomialnvars;
720 int nmonomials;
721
722 SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsLinearsum", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
723
724 assert(scip != NULL);
725 assert(str != NULL);
726 assert(vars != NULL || varssize == 0);
727 assert(vals != NULL || varssize == 0);
728 assert(nvars != NULL);
729 assert(requiredsize != NULL);
730 assert(endptr != NULL);
731 assert(success != NULL);
732
733 *requiredsize = 0;
734
735 SCIP_CALL( SCIPparseVarsPolynomial(scip, str, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, &nmonomials, endptr, success) );
736
737 if( !*success )
738 {
739 assert(nmonomials == 0); /* SCIPparseVarsPolynomial should have freed all buffers, so no need to call free here */
740 return SCIP_OKAY;
741 }
742
743 /* check if linear sum is just "0" */
744 if( nmonomials == 1 && monomialnvars[0] == 0 && monomialcoefs[0] == 0.0 )
745 {
746 *nvars = 0;
747 *requiredsize = 0;
748
749 SCIPfreeParseVarsPolynomialData(scip, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, nmonomials);
750
751 return SCIP_OKAY;
752 }
753
754 *nvars = nmonomials;
755 *requiredsize = nmonomials;
756
757 /* if we have enough slots in the variables array, copy variables over */
758 if( varssize >= nmonomials )
759 {
760 int v;
761
762 for( v = 0; v < nmonomials; ++v )
763 {
764 if( monomialnvars[v] == 0 )
765 {
766 SCIPerrorMessage("constant in linear sum\n");
767 *success = FALSE;
768 break;
769 }
770 if( monomialnvars[v] > 1 || monomialexps[v][0] != 1.0 )
771 {
772 SCIPerrorMessage("nonlinear monomial in linear sum\n");
773 *success = FALSE;
774 break;
775 }
776 assert(monomialnvars[v] == 1);
777 assert(monomialvars[v][0] != NULL);
778 assert(monomialexps[v][0] == 1.0);
779
780 vars[v] = monomialvars[v][0]; /*lint !e613*/
781 vals[v] = monomialcoefs[v]; /*lint !e613*/
782 }
783 }
784
785 SCIPfreeParseVarsPolynomialData(scip, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, nmonomials);
786
787 return SCIP_OKAY;
788}
789
790/** parse the given string as signomial of variables and coefficients
791 * (c1 <x11>^e11 <x12>^e12 ... <x1n>^e1n + c2 <x21>^e21 <x22>^e22 ... + ... + cn <xn1>^en1 ...)
792 * (see SCIPwriteVarsPolynomial()); if it was successful, the pointer success is set to TRUE
793 *
794 * The user has to call SCIPfreeParseVarsPolynomialData(scip, monomialvars, monomialexps,
795 * monomialcoefs, monomialnvars, *nmonomials) short after SCIPparseVarsPolynomial to free all the
796 * allocated memory again.
797 *
798 * Parsing is stopped at the end of string (indicated by the \\0-character) or when no more monomials
799 * are recognized.
800 *
801 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
802 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
803 *
804 * @pre This method can be called if @p scip is in one of the following stages:
805 * - \ref SCIP_STAGE_PROBLEM
806 * - \ref SCIP_STAGE_TRANSFORMING
807 * - \ref SCIP_STAGE_INITPRESOLVE
808 * - \ref SCIP_STAGE_PRESOLVING
809 * - \ref SCIP_STAGE_EXITPRESOLVE
810 * - \ref SCIP_STAGE_PRESOLVED
811 * - \ref SCIP_STAGE_SOLVING
812 */
814 SCIP* scip, /**< SCIP data structure */
815 const char* str, /**< string to parse */
816 SCIP_VAR**** monomialvars, /**< pointer to store arrays with variables for each monomial */
817 SCIP_Real*** monomialexps, /**< pointer to store arrays with variable exponents */
818 SCIP_Real** monomialcoefs, /**< pointer to store array with monomial coefficients */
819 int** monomialnvars, /**< pointer to store array with number of variables for each monomial */
820 int* nmonomials, /**< pointer to store number of parsed monomials */
821 char** endptr, /**< pointer to store the final string position if successful */
822 SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
823 )
824{
825 typedef enum
826 {
827 SCIPPARSEPOLYNOMIAL_STATE_BEGIN, /* we are at the beginning of a monomial */
828 SCIPPARSEPOLYNOMIAL_STATE_INTERMED, /* we are in between the factors of a monomial */
829 SCIPPARSEPOLYNOMIAL_STATE_COEF, /* we parse the coefficient of a monomial */
830 SCIPPARSEPOLYNOMIAL_STATE_VARS, /* we parse monomial variables */
831 SCIPPARSEPOLYNOMIAL_STATE_EXPONENT, /* we parse the exponent of a variable */
832 SCIPPARSEPOLYNOMIAL_STATE_END, /* we are at the end the polynomial */
833 SCIPPARSEPOLYNOMIAL_STATE_ERROR /* a parsing error occured */
834 } SCIPPARSEPOLYNOMIAL_STATES;
835
836 SCIPPARSEPOLYNOMIAL_STATES state;
837 int monomialssize;
838
839 /* data of currently parsed monomial */
840 int varssize;
841 int nvars;
842 SCIP_VAR** vars;
843 SCIP_Real* exponents;
844 SCIP_Real coef;
845
846 assert(scip != NULL);
847 assert(str != NULL);
848 assert(monomialvars != NULL);
849 assert(monomialexps != NULL);
850 assert(monomialnvars != NULL);
851 assert(monomialcoefs != NULL);
852 assert(nmonomials != NULL);
853 assert(endptr != NULL);
854 assert(success != NULL);
855
856 SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsPolynomial", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
857
858 *success = FALSE;
859 *nmonomials = 0;
860 monomialssize = 0;
861 *monomialvars = NULL;
862 *monomialexps = NULL;
863 *monomialcoefs = NULL;
864 *monomialnvars = NULL;
865
866 /* initialize state machine */
867 state = SCIPPARSEPOLYNOMIAL_STATE_BEGIN;
868 varssize = 0;
869 nvars = 0;
870 vars = NULL;
871 exponents = NULL;
872 coef = SCIP_INVALID;
873
874 SCIPdebugMsg(scip, "parsing polynomial from '%s'\n", str);
875
876 while( *str && state != SCIPPARSEPOLYNOMIAL_STATE_END && state != SCIPPARSEPOLYNOMIAL_STATE_ERROR )
877 {
878 /* skip white space */
879 SCIP_CALL( SCIPskipSpace((char**)&str) );
880
881 assert(state != SCIPPARSEPOLYNOMIAL_STATE_END);
882
883 switch( state )
884 {
885 case SCIPPARSEPOLYNOMIAL_STATE_BEGIN:
886 {
887 if( coef != SCIP_INVALID ) /*lint !e777*/
888 {
889 SCIPdebugMsg(scip, "push monomial with coefficient <%g> and <%d> vars\n", coef, nvars);
890
891 /* push previous monomial */
892 if( monomialssize <= *nmonomials )
893 {
894 monomialssize = SCIPcalcMemGrowSize(scip, *nmonomials+1);
895
896 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, *nmonomials, monomialssize) );
897 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, *nmonomials, monomialssize) );
898 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, *nmonomials, monomialssize) );
899 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, *nmonomials, monomialssize) );
900 }
901
902 if( nvars > 0 )
903 {
904 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*monomialvars)[*nmonomials], vars, nvars) ); /*lint !e866*/
905 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*monomialexps)[*nmonomials], exponents, nvars) ); /*lint !e866*/
906 }
907 else
908 {
909 (*monomialvars)[*nmonomials] = NULL;
910 (*monomialexps)[*nmonomials] = NULL;
911 }
912 (*monomialcoefs)[*nmonomials] = coef;
913 (*monomialnvars)[*nmonomials] = nvars;
914 ++*nmonomials;
915
916 nvars = 0;
917 coef = SCIP_INVALID;
918 }
919
920 if( *str == '<' )
921 {
922 /* there seem to come a variable at the beginning of a monomial
923 * so assume the coefficient is 1.0
924 */
925 state = SCIPPARSEPOLYNOMIAL_STATE_VARS;
926 coef = 1.0;
927 }
928 else if( *str == '-' || *str == '+' || isdigit(*str) )
929 state = SCIPPARSEPOLYNOMIAL_STATE_COEF;
930 else
931 state = SCIPPARSEPOLYNOMIAL_STATE_END;
932
933 break;
934 }
935
936 case SCIPPARSEPOLYNOMIAL_STATE_INTERMED:
937 {
938 if( *str == '<' )
939 {
940 /* there seem to come another variable */
941 state = SCIPPARSEPOLYNOMIAL_STATE_VARS;
942 }
943 else if( *str == '-' || *str == '+' || isdigit(*str) )
944 {
945 /* there seem to come a coefficient, which means the next monomial */
946 state = SCIPPARSEPOLYNOMIAL_STATE_BEGIN;
947 }
948 else /* since we cannot detect the symbols we stop parsing the polynomial */
949 state = SCIPPARSEPOLYNOMIAL_STATE_END;
950
951 break;
952 }
953
954 case SCIPPARSEPOLYNOMIAL_STATE_COEF:
955 {
956 if( *str == '+' && !isdigit(str[1]) )
957 {
958 /* only a plus sign, without number */
959 coef = 1.0;
960 ++str;
961 }
962 else if( *str == '-' && !isdigit(str[1]) )
963 {
964 /* only a minus sign, without number */
965 coef = -1.0;
966 ++str;
967 }
968 else if( SCIPstrToRealValue(str, &coef, endptr) )
969 {
970 str = *endptr;
971 }
972 else
973 {
974 SCIPerrorMessage("could not parse number in the beginning of '%s'\n", str);
975 state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
976 break;
977 }
978
979 /* after the coefficient we go into the intermediate state, i.e., expecting next variables */
980 state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED; /*lint !e838*/
981
982 break;
983 }
984
985 case SCIPPARSEPOLYNOMIAL_STATE_VARS:
986 {
987 SCIP_VAR* var;
988
989 assert(*str == '<');
990
991 /* parse variable name */
992 SCIP_CALL( SCIPparseVarName(scip, str, &var, endptr) );
993
994 /* check if variable name was parsed */
995 if( *endptr == str )
996 {
997 state = SCIPPARSEPOLYNOMIAL_STATE_END;
998 break;
999 }
1000
1001 if( var == NULL )
1002 {
1003 SCIPerrorMessage("did not find variable in the beginning of %s\n", str);
1004 state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
1005 break;
1006 }
1007
1008 /* add variable to vars array */
1009 if( nvars + 1 > varssize )
1010 {
1011 varssize = SCIPcalcMemGrowSize(scip, nvars+1);
1013 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &exponents, nvars, varssize) );
1014 }
1015 assert(vars != NULL);
1016 assert(exponents != NULL);
1017
1018 vars[nvars] = var;
1019 exponents[nvars] = 1.0;
1020 ++nvars;
1021
1022 str = *endptr;
1023
1024 if( *str == '^' )
1025 state = SCIPPARSEPOLYNOMIAL_STATE_EXPONENT;
1026 else
1027 state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED;
1028
1029 break;
1030 }
1031
1032 case SCIPPARSEPOLYNOMIAL_STATE_EXPONENT:
1033 {
1034 assert(*str == '^');
1035 assert(nvars > 0); /* we should be in a monomial that has already a variable */
1036 assert(exponents != NULL);
1037 ++str;
1038
1039 if( !SCIPstrToRealValue(str, &exponents[nvars-1], endptr) )
1040 {
1041 SCIPerrorMessage("could not parse number in the beginning of '%s'\n", str);
1042 state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
1043 break;
1044 }
1045 str = *endptr;
1046
1047 /* after the exponent we go into the intermediate state, i.e., expecting next variables */
1048 state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED; /*lint !e838*/
1049 break;
1050 }
1051
1052 /* coverity[dead_error_line] */
1053 case SCIPPARSEPOLYNOMIAL_STATE_END:
1054 /* coverity[dead_error_line] */
1055 case SCIPPARSEPOLYNOMIAL_STATE_ERROR:
1056 default:
1057 SCIPerrorMessage("unexpected state\n");
1058 return SCIP_READERROR;
1059 }
1060 }
1061
1062 /* set end pointer */
1063 *endptr = (char*)str;
1064
1065 /* check state at end of string */
1066 switch( state )
1067 {
1068 case SCIPPARSEPOLYNOMIAL_STATE_BEGIN:
1069 case SCIPPARSEPOLYNOMIAL_STATE_END:
1070 case SCIPPARSEPOLYNOMIAL_STATE_INTERMED:
1071 {
1072 if( coef != SCIP_INVALID ) /*lint !e777*/
1073 {
1074 /* push last monomial */
1075 SCIPdebugMsg(scip, "push monomial with coefficient <%g> and <%d> vars\n", coef, nvars);
1076 if( monomialssize <= *nmonomials )
1077 {
1078 monomialssize = *nmonomials+1;
1079 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, *nmonomials, monomialssize) );
1080 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, *nmonomials, monomialssize) );
1081 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, *nmonomials, monomialssize) );
1082 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, *nmonomials, monomialssize) );
1083 }
1084
1085 if( nvars > 0 )
1086 {
1087 /* shrink vars and exponents array to needed size and take over ownership */
1089 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &exponents, varssize, nvars) );
1090 (*monomialvars)[*nmonomials] = vars;
1091 (*monomialexps)[*nmonomials] = exponents;
1092 vars = NULL;
1093 exponents = NULL;
1094 }
1095 else
1096 {
1097 (*monomialvars)[*nmonomials] = NULL;
1098 (*monomialexps)[*nmonomials] = NULL;
1099 }
1100 (*monomialcoefs)[*nmonomials] = coef;
1101 (*monomialnvars)[*nmonomials] = nvars;
1102 ++*nmonomials;
1103 }
1104
1105 *success = TRUE;
1106 break;
1107 }
1108
1109 case SCIPPARSEPOLYNOMIAL_STATE_COEF:
1110 case SCIPPARSEPOLYNOMIAL_STATE_VARS:
1111 case SCIPPARSEPOLYNOMIAL_STATE_EXPONENT:
1112 {
1113 SCIPerrorMessage("unexpected parsing state at end of polynomial string\n");
1114 }
1115 /*lint -fallthrough*/
1116 case SCIPPARSEPOLYNOMIAL_STATE_ERROR:
1117 assert(!*success);
1118 break;
1119 }
1120
1121 /* free memory to store current monomial, if still existing */
1123 SCIPfreeBlockMemoryArrayNull(scip, &exponents, varssize);
1124
1125 if( *success && *nmonomials > 0 )
1126 {
1127 /* shrink arrays to required size, so we do not need to keep monomialssize around */
1128 assert(*nmonomials <= monomialssize);
1129 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, monomialssize, *nmonomials) );
1130 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, monomialssize, *nmonomials) );
1131 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, monomialssize, *nmonomials) );
1132 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, monomialssize, *nmonomials) );
1133
1134 /* SCIPwriteVarsPolynomial(scip, NULL, *monomialvars, *monomialexps, *monomialcoefs, *monomialnvars, *nmonomials, FALSE); */
1135 }
1136 else
1137 {
1138 /* in case of error, cleanup all data here */
1139 SCIPfreeParseVarsPolynomialData(scip, monomialvars, monomialexps, monomialcoefs, monomialnvars, *nmonomials);
1140 *nmonomials = 0;
1141 }
1142
1143 return SCIP_OKAY;
1144}
1145
1146/** frees memory allocated when parsing a signomial from a string
1147 *
1148 * @pre This method can be called if @p scip is in one of the following stages:
1149 * - \ref SCIP_STAGE_PROBLEM
1150 * - \ref SCIP_STAGE_TRANSFORMING
1151 * - \ref SCIP_STAGE_INITPRESOLVE
1152 * - \ref SCIP_STAGE_PRESOLVING
1153 * - \ref SCIP_STAGE_EXITPRESOLVE
1154 * - \ref SCIP_STAGE_PRESOLVED
1155 * - \ref SCIP_STAGE_SOLVING
1156 */
1158 SCIP* scip, /**< SCIP data structure */
1159 SCIP_VAR**** monomialvars, /**< pointer to store arrays with variables for each monomial */
1160 SCIP_Real*** monomialexps, /**< pointer to store arrays with variable exponents */
1161 SCIP_Real** monomialcoefs, /**< pointer to store array with monomial coefficients */
1162 int** monomialnvars, /**< pointer to store array with number of variables for each monomial */
1163 int nmonomials /**< pointer to store number of parsed monomials */
1164 )
1165{
1166 int i;
1167
1168 assert(scip != NULL);
1169 assert(monomialvars != NULL);
1170 assert(monomialexps != NULL);
1171 assert(monomialcoefs != NULL);
1172 assert(monomialnvars != NULL);
1173 assert((*monomialvars != NULL) == (nmonomials > 0));
1174 assert((*monomialexps != NULL) == (nmonomials > 0));
1175 assert((*monomialcoefs != NULL) == (nmonomials > 0));
1176 assert((*monomialnvars != NULL) == (nmonomials > 0));
1177
1178 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPfreeParseVarsPolynomialData", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1179
1180 if( nmonomials == 0 )
1181 return;
1182
1183 for( i = nmonomials - 1; i >= 0; --i )
1184 {
1185 SCIPfreeBlockMemoryArrayNull(scip, &(*monomialexps)[i], (*monomialnvars)[i]);
1186 SCIPfreeBlockMemoryArrayNull(scip, &(*monomialvars)[i], (*monomialnvars)[i]);
1187 }
1188
1189 SCIPfreeBlockMemoryArray(scip, monomialcoefs, nmonomials);
1190 SCIPfreeBlockMemoryArray(scip, monomialnvars, nmonomials);
1191 SCIPfreeBlockMemoryArray(scip, monomialexps, nmonomials);
1192 SCIPfreeBlockMemoryArray(scip, monomialvars, nmonomials);
1193}
1194
1195/** increases usage counter of variable
1196 *
1197 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1198 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1199 *
1200 * @pre This method can be called if @p scip is in one of the following stages:
1201 * - \ref SCIP_STAGE_PROBLEM
1202 * - \ref SCIP_STAGE_TRANSFORMING
1203 * - \ref SCIP_STAGE_TRANSFORMED
1204 * - \ref SCIP_STAGE_INITPRESOLVE
1205 * - \ref SCIP_STAGE_PRESOLVING
1206 * - \ref SCIP_STAGE_EXITPRESOLVE
1207 * - \ref SCIP_STAGE_PRESOLVED
1208 * - \ref SCIP_STAGE_INITSOLVE
1209 * - \ref SCIP_STAGE_SOLVING
1210 * - \ref SCIP_STAGE_SOLVED
1211 * - \ref SCIP_STAGE_EXITSOLVE
1212 */
1214 SCIP* scip, /**< SCIP data structure */
1215 SCIP_VAR* var /**< variable to capture */
1216 )
1217{
1218 SCIP_CALL( SCIPcheckStage(scip, "SCIPcaptureVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1219 assert(var->scip == scip);
1220
1222
1223 return SCIP_OKAY;
1224}
1225
1226/** decreases usage counter of variable, if the usage pointer reaches zero the variable gets freed
1227 *
1228 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1229 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1230 *
1231 * @pre This method can be called if @p scip is in one of the following stages:
1232 * - \ref SCIP_STAGE_PROBLEM
1233 * - \ref SCIP_STAGE_TRANSFORMING
1234 * - \ref SCIP_STAGE_TRANSFORMED
1235 * - \ref SCIP_STAGE_INITPRESOLVE
1236 * - \ref SCIP_STAGE_PRESOLVING
1237 * - \ref SCIP_STAGE_EXITPRESOLVE
1238 * - \ref SCIP_STAGE_PRESOLVED
1239 * - \ref SCIP_STAGE_INITSOLVE
1240 * - \ref SCIP_STAGE_SOLVING
1241 * - \ref SCIP_STAGE_SOLVED
1242 * - \ref SCIP_STAGE_EXITSOLVE
1243 * - \ref SCIP_STAGE_FREETRANS
1244 *
1245 * @note the pointer of the variable will be NULLed
1246 */
1248 SCIP* scip, /**< SCIP data structure */
1249 SCIP_VAR** var /**< pointer to variable */
1250 )
1251{
1252 assert(var != NULL);
1253 assert(*var != NULL);
1254 assert((*var)->scip == scip);
1255
1256 SCIP_CALL( SCIPcheckStage(scip, "SCIPreleaseVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1257
1258 switch( scip->set->stage )
1259 {
1260 case SCIP_STAGE_PROBLEM:
1261 SCIP_CALL( SCIPvarRelease(var, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp) );
1262 return SCIP_OKAY;
1263
1271 case SCIP_STAGE_SOLVING:
1272 case SCIP_STAGE_SOLVED:
1275 if( !SCIPvarIsTransformed(*var) && (*var)->nuses == 1 && (*var)->data.original.transvar != NULL )
1276 {
1277 SCIPerrorMessage("cannot release last use of original variable while associated transformed variable exists\n");
1278 return SCIP_INVALIDCALL;
1279 }
1280 SCIP_CALL( SCIPvarRelease(var, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp) );
1281 return SCIP_OKAY;
1282
1283 default:
1284 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
1285 return SCIP_INVALIDCALL;
1286 } /*lint !e788*/
1287}
1288
1289/** changes the name of a variable
1290 *
1291 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1292 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1293 *
1294 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PROBLEM
1295 *
1296 * @note to get the current name of a variable, use SCIPvarGetName() from pub_var.h
1297 */
1299 SCIP* scip, /**< SCIP data structure */
1300 SCIP_VAR* var, /**< variable */
1301 const char* name /**< new name of constraint */
1302 )
1303{
1305 assert( var->scip == scip );
1306
1308 {
1309 SCIPerrorMessage("variable names can only be changed in problem creation stage\n");
1310 SCIPABORT();
1311 return SCIP_INVALIDCALL; /*lint !e527*/
1312 }
1313
1314 /* remove variable's name from the namespace if the variable was already added */
1315 if( SCIPvarGetProbindex(var) != -1 )
1316 {
1317 SCIP_CALL( SCIPprobRemoveVarName(scip->origprob, var) );
1318 }
1319
1320 /* change variable name */
1322
1323 /* add variable's name to the namespace if the variable was already added */
1324 if( SCIPvarGetProbindex(var) != -1 )
1325 {
1326 SCIP_CALL( SCIPprobAddVarName(scip->origprob, var) );
1327 }
1328
1329 return SCIP_OKAY;
1330}
1331
1332/** gets and captures transformed variable of a given variable; if the variable is not yet transformed,
1333 * a new transformed variable for this variable is created
1334 *
1335 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1336 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1337 *
1338 * @pre This method can be called if @p scip is in one of the following stages:
1339 * - \ref SCIP_STAGE_TRANSFORMING
1340 * - \ref SCIP_STAGE_TRANSFORMED
1341 * - \ref SCIP_STAGE_INITPRESOLVE
1342 * - \ref SCIP_STAGE_PRESOLVING
1343 * - \ref SCIP_STAGE_EXITPRESOLVE
1344 * - \ref SCIP_STAGE_PRESOLVED
1345 * - \ref SCIP_STAGE_INITSOLVE
1346 * - \ref SCIP_STAGE_SOLVING
1347 */
1349 SCIP* scip, /**< SCIP data structure */
1350 SCIP_VAR* var, /**< variable to get/create transformed variable for */
1351 SCIP_VAR** transvar /**< pointer to store the transformed variable */
1352 )
1353{
1354 assert(transvar != NULL);
1355
1356 SCIP_CALL( SCIPcheckStage(scip, "SCIPtransformVar", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1357
1359 {
1360 *transvar = var;
1361 SCIPvarCapture(*transvar);
1362 }
1363 else
1364 {
1365 SCIP_CALL( SCIPvarTransform(var, scip->mem->probmem, scip->set, scip->stat, scip->origprob->objsense, transvar) );
1366 }
1367
1368 return SCIP_OKAY;
1369}
1370
1371/** gets and captures transformed variables for an array of variables;
1372 * if a variable of the array is not yet transformed, a new transformed variable for this variable is created;
1373 * it is possible to call this method with vars == transvars
1374 *
1375 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1376 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1377 *
1378 * @pre This method can be called if @p scip is in one of the following stages:
1379 * - \ref SCIP_STAGE_TRANSFORMING
1380 * - \ref SCIP_STAGE_TRANSFORMED
1381 * - \ref SCIP_STAGE_INITPRESOLVE
1382 * - \ref SCIP_STAGE_PRESOLVING
1383 * - \ref SCIP_STAGE_EXITPRESOLVE
1384 * - \ref SCIP_STAGE_PRESOLVED
1385 * - \ref SCIP_STAGE_INITSOLVE
1386 * - \ref SCIP_STAGE_SOLVING
1387 */
1389 SCIP* scip, /**< SCIP data structure */
1390 int nvars, /**< number of variables to get/create transformed variables for */
1391 SCIP_VAR** vars, /**< array with variables to get/create transformed variables for */
1392 SCIP_VAR** transvars /**< array to store the transformed variables */
1393 )
1394{
1395 int v;
1396
1397 assert(nvars == 0 || vars != NULL);
1398 assert(nvars == 0 || transvars != NULL);
1399
1400 SCIP_CALL( SCIPcheckStage(scip, "SCIPtransformVars", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1401
1402 for( v = 0; v < nvars; ++v )
1403 {
1404 if( SCIPvarIsTransformed(vars[v]) )
1405 {
1406 transvars[v] = vars[v];
1407 SCIPvarCapture(transvars[v]);
1408 }
1409 else
1410 {
1411 SCIP_CALL( SCIPvarTransform(vars[v], scip->mem->probmem, scip->set, scip->stat, scip->origprob->objsense,
1412 &transvars[v]) );
1413 }
1414 }
1415
1416 return SCIP_OKAY;
1417}
1418
1419/** gets corresponding transformed variable of a given variable;
1420 * returns NULL as transvar, if transformed variable is not yet existing
1421 *
1422 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1423 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1424 *
1425 * @pre This method can be called if @p scip is in one of the following stages:
1426 * - \ref SCIP_STAGE_TRANSFORMING
1427 * - \ref SCIP_STAGE_TRANSFORMED
1428 * - \ref SCIP_STAGE_INITPRESOLVE
1429 * - \ref SCIP_STAGE_PRESOLVING
1430 * - \ref SCIP_STAGE_EXITPRESOLVE
1431 * - \ref SCIP_STAGE_PRESOLVED
1432 * - \ref SCIP_STAGE_INITSOLVE
1433 * - \ref SCIP_STAGE_SOLVING
1434 * - \ref SCIP_STAGE_SOLVED
1435 * - \ref SCIP_STAGE_EXITSOLVE
1436 * - \ref SCIP_STAGE_FREETRANS
1437 */
1439 SCIP* scip, /**< SCIP data structure */
1440 SCIP_VAR* var, /**< variable to get transformed variable for */
1441 SCIP_VAR** transvar /**< pointer to store the transformed variable */
1442 )
1443{
1444 assert(transvar != NULL);
1445
1446 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetTransformedVar", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1447
1449 *transvar = var;
1450 else
1451 {
1452 SCIP_CALL( SCIPvarGetTransformed(var, scip->mem->probmem, scip->set, scip->stat, transvar) );
1453 }
1454
1455 return SCIP_OKAY;
1456}
1457
1458/** gets corresponding transformed variables for an array of variables;
1459 * stores NULL in a transvars slot, if the transformed variable is not yet existing;
1460 * it is possible to call this method with vars == transvars, but remember that variables that are not
1461 * yet transformed will be replaced with NULL
1462 *
1463 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1464 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1465 *
1466 * @pre This method can be called if @p scip is in one of the following stages:
1467 * - \ref SCIP_STAGE_TRANSFORMING
1468 * - \ref SCIP_STAGE_TRANSFORMED
1469 * - \ref SCIP_STAGE_INITPRESOLVE
1470 * - \ref SCIP_STAGE_PRESOLVING
1471 * - \ref SCIP_STAGE_EXITPRESOLVE
1472 * - \ref SCIP_STAGE_PRESOLVED
1473 * - \ref SCIP_STAGE_INITSOLVE
1474 * - \ref SCIP_STAGE_SOLVING
1475 * - \ref SCIP_STAGE_SOLVED
1476 * - \ref SCIP_STAGE_EXITSOLVE
1477 * - \ref SCIP_STAGE_FREETRANS
1478 */
1480 SCIP* scip, /**< SCIP data structure */
1481 int nvars, /**< number of variables to get transformed variables for */
1482 SCIP_VAR** vars, /**< array with variables to get transformed variables for */
1483 SCIP_VAR** transvars /**< array to store the transformed variables */
1484 )
1485{
1486 int v;
1487
1488 assert(nvars == 0 || vars != NULL);
1489 assert(nvars == 0 || transvars != NULL);
1490
1491 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetTransformedVars", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1492
1493 for( v = 0; v < nvars; ++v )
1494 {
1495 if( SCIPvarIsTransformed(vars[v]) )
1496 transvars[v] = vars[v];
1497 else
1498 {
1499 SCIP_CALL( SCIPvarGetTransformed(vars[v], scip->mem->probmem, scip->set, scip->stat, &transvars[v]) );
1500 }
1501 }
1502
1503 return SCIP_OKAY;
1504}
1505
1506/** gets negated variable x' = lb + ub - x of variable x; negated variable is created, if not yet existing;
1507 * in difference to \ref SCIPcreateVar, the negated variable must not be released (unless captured explicitly)
1508 *
1509 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1510 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1511 *
1512 * @pre This method can be called if @p scip is in one of the following stages:
1513 * - \ref SCIP_STAGE_PROBLEM
1514 * - \ref SCIP_STAGE_TRANSFORMING
1515 * - \ref SCIP_STAGE_TRANSFORMED
1516 * - \ref SCIP_STAGE_INITPRESOLVE
1517 * - \ref SCIP_STAGE_PRESOLVING
1518 * - \ref SCIP_STAGE_EXITPRESOLVE
1519 * - \ref SCIP_STAGE_PRESOLVED
1520 * - \ref SCIP_STAGE_INITSOLVE
1521 * - \ref SCIP_STAGE_SOLVING
1522 * - \ref SCIP_STAGE_SOLVED
1523 * - \ref SCIP_STAGE_EXITSOLVE
1524 * - \ref SCIP_STAGE_FREETRANS
1525 */
1527 SCIP* scip, /**< SCIP data structure */
1528 SCIP_VAR* var, /**< variable to get negated variable for */
1529 SCIP_VAR** negvar /**< pointer to store the negated variable */
1530 )
1531{
1532 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNegatedVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1533 assert( var->scip == scip );
1534
1535 SCIP_CALL( SCIPvarNegate(var, scip->mem->probmem, scip->set, scip->stat, negvar) );
1536
1537 return SCIP_OKAY;
1538}
1539
1540/** gets negated variables x' = lb + ub - x of variables x; negated variables are created, if not yet existing
1541 *
1542 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1543 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1544 *
1545 * @pre This method can be called if @p scip is in one of the following stages:
1546 * - \ref SCIP_STAGE_PROBLEM
1547 * - \ref SCIP_STAGE_TRANSFORMING
1548 * - \ref SCIP_STAGE_TRANSFORMED
1549 * - \ref SCIP_STAGE_INITPRESOLVE
1550 * - \ref SCIP_STAGE_PRESOLVING
1551 * - \ref SCIP_STAGE_EXITPRESOLVE
1552 * - \ref SCIP_STAGE_PRESOLVED
1553 * - \ref SCIP_STAGE_INITSOLVE
1554 * - \ref SCIP_STAGE_SOLVING
1555 * - \ref SCIP_STAGE_SOLVED
1556 * - \ref SCIP_STAGE_EXITSOLVE
1557 * - \ref SCIP_STAGE_FREETRANS
1558 */
1560 SCIP* scip, /**< SCIP data structure */
1561 int nvars, /**< number of variables to get negated variables for */
1562 SCIP_VAR** vars, /**< array of variables to get negated variables for */
1563 SCIP_VAR** negvars /**< array to store the negated variables */
1564 )
1565{
1566 int v;
1567
1568 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNegatedVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1569
1570 for( v = 0; v < nvars; ++v )
1571 {
1572 SCIP_CALL( SCIPvarNegate(vars[v], scip->mem->probmem, scip->set, scip->stat, &(negvars[v])) );
1573 }
1574
1575 return SCIP_OKAY;
1576}
1577
1578/** gets a binary variable that is equal to the given binary variable, and that is either active, fixed, or
1579 * multi-aggregated, or the negated variable of an active, fixed, or multi-aggregated variable
1580 *
1581 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1582 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1583 *
1584 * @pre This method can be called if @p scip is in one of the following stages:
1585 * - \ref SCIP_STAGE_PROBLEM
1586 * - \ref SCIP_STAGE_TRANSFORMED
1587 * - \ref SCIP_STAGE_INITPRESOLVE
1588 * - \ref SCIP_STAGE_PRESOLVING
1589 * - \ref SCIP_STAGE_EXITPRESOLVE
1590 * - \ref SCIP_STAGE_PRESOLVED
1591 * - \ref SCIP_STAGE_INITSOLVE
1592 * - \ref SCIP_STAGE_SOLVING
1593 * - \ref SCIP_STAGE_SOLVED
1594 * - \ref SCIP_STAGE_EXITSOLVE
1595 */
1597 SCIP* scip, /**< SCIP data structure */
1598 SCIP_VAR* var, /**< binary variable to get binary representative for */
1599 SCIP_VAR** repvar, /**< pointer to store the binary representative */
1600 SCIP_Bool* negated /**< pointer to store whether the negation of an active variable was returned */
1601 )
1602{
1603 assert(scip != NULL);
1604 assert(var != NULL);
1605 assert(repvar != NULL);
1606 assert(negated != NULL);
1607 assert(var->scip == scip);
1608
1609 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetBinvarRepresentative", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1610
1611 /* get the active representative of the given variable */
1612 *repvar = var;
1613 *negated = FALSE;
1614 SCIP_CALL( SCIPvarGetProbvarBinary(repvar, negated) );
1615
1616 /* negate the representative, if it corresponds to the negation of the given variable */
1617 if( *negated )
1618 {
1619 SCIP_CALL( SCIPgetNegatedVar(scip, *repvar, repvar) );
1620 }
1621
1622 return SCIP_OKAY;
1623}
1624
1625/** gets binary variables that are equal to the given binary variables, and which are either active, fixed, or
1626 * multi-aggregated, or the negated variables of active, fixed, or multi-aggregated variables
1627 *
1628 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1629 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1630 *
1631 * @pre This method can be called if @p scip is in one of the following stages:
1632 * - \ref SCIP_STAGE_PROBLEM
1633 * - \ref SCIP_STAGE_TRANSFORMED
1634 * - \ref SCIP_STAGE_INITPRESOLVE
1635 * - \ref SCIP_STAGE_PRESOLVING
1636 * - \ref SCIP_STAGE_EXITPRESOLVE
1637 * - \ref SCIP_STAGE_PRESOLVED
1638 * - \ref SCIP_STAGE_INITSOLVE
1639 * - \ref SCIP_STAGE_SOLVING
1640 * - \ref SCIP_STAGE_SOLVED
1641 * - \ref SCIP_STAGE_EXITSOLVE
1642 */
1644 SCIP* scip, /**< SCIP data structure */
1645 int nvars, /**< number of binary variables to get representatives for */
1646 SCIP_VAR** vars, /**< binary variables to get binary representatives for */
1647 SCIP_VAR** repvars, /**< array to store the binary representatives */
1648 SCIP_Bool* negated /**< array to store whether the negation of an active variable was returned */
1649 )
1650{
1651 int v;
1652
1653 assert(scip != NULL);
1654 assert(vars != NULL || nvars == 0);
1655 assert(repvars != NULL || nvars == 0);
1656 assert(negated != NULL || nvars == 0);
1657
1658 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetBinvarRepresentatives", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1659
1660 if( nvars == 0 )
1661 return SCIP_OKAY;
1662
1663 /* get the active representative of the given variable */
1664 BMScopyMemoryArray(repvars, vars, nvars);
1665 BMSclearMemoryArray(negated, nvars);
1666 SCIP_CALL( SCIPvarsGetProbvarBinary(&repvars, &negated, nvars) );
1667
1668 /* negate the representatives, if they correspond to the negation of the given variables */
1669 for( v = nvars - 1; v >= 0; --v )
1670 if( negated[v] )
1671 {
1672 SCIP_CALL( SCIPgetNegatedVar(scip, repvars[v], &(repvars[v])) );
1673 }
1674
1675 return SCIP_OKAY;
1676}
1677
1678/** flattens aggregation graph of multi-aggregated variable in order to avoid exponential recursion later on
1679 *
1680 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1681 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1682 *
1683 * @pre This method can be called if @p scip is in one of the following stages:
1684 * - \ref SCIP_STAGE_INITPRESOLVE
1685 * - \ref SCIP_STAGE_PRESOLVING
1686 * - \ref SCIP_STAGE_EXITPRESOLVE
1687 * - \ref SCIP_STAGE_PRESOLVED
1688 * - \ref SCIP_STAGE_INITSOLVE
1689 * - \ref SCIP_STAGE_SOLVING
1690 * - \ref SCIP_STAGE_SOLVED
1691 */
1693 SCIP* scip, /**< SCIP data structure */
1694 SCIP_VAR* var /**< problem variable */
1695 )
1696{
1697 assert( scip != NULL );
1698 assert( var != NULL );
1699 SCIP_CALL( SCIPcheckStage(scip, "SCIPflattenVarAggregationGraph", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
1700
1701 SCIP_CALL( SCIPvarFlattenAggregationGraph(var, scip->mem->probmem, scip->set, scip->eventqueue) );
1702
1703 return SCIP_OKAY;
1704}
1705
1706/** Transforms a given linear sum of variables, that is a_1*x_1 + ... + a_n*x_n + c into a corresponding linear sum of
1707 * active variables, that is b_1*y_1 + ... + b_m*y_m + d.
1708 *
1709 * If the number of needed active variables is greater than the available slots in the variable array, nothing happens
1710 * except that the required size is stored in the corresponding variable (requiredsize). Otherwise, the active variable
1711 * representation is stored in the variable array, scalar array and constant.
1712 *
1713 * The reason for this approach is that we cannot reallocate memory, since we do not know how the memory has been
1714 * allocated (e.g., by a C++ 'new' or SCIP functions).
1715 *
1716 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1717 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1718 *
1719 * @pre This method can be called if @p scip is in one of the following stages:
1720 * - \ref SCIP_STAGE_TRANSFORMED
1721 * - \ref SCIP_STAGE_INITPRESOLVE
1722 * - \ref SCIP_STAGE_PRESOLVING
1723 * - \ref SCIP_STAGE_EXITPRESOLVE
1724 * - \ref SCIP_STAGE_PRESOLVED
1725 * - \ref SCIP_STAGE_INITSOLVE
1726 * - \ref SCIP_STAGE_SOLVING
1727 * - \ref SCIP_STAGE_SOLVED
1728 * - \ref SCIP_STAGE_EXITSOLVE
1729 * - \ref SCIP_STAGE_FREETRANS
1730 *
1731 * @note The resulting linear sum is stored into the given variable array, scalar array, and constant. That means the
1732 * given entries are overwritten.
1733 *
1734 * @note That method can be used to convert a single variables into variable space of active variables. Therefore call
1735 * the method with the linear sum 1.0*x + 0.0.
1736 */
1738 SCIP* scip, /**< SCIP data structure */
1739 SCIP_VAR** vars, /**< variable array x_1, ..., x_n in the linear sum which will be
1740 * overwritten by the variable array y_1, ..., y_m in the linear sum
1741 * w.r.t. active variables */
1742 SCIP_Real* scalars, /**< scalars a_1, ..., a_n in linear sum which will be overwritten to the
1743 * scalars b_1, ..., b_m in the linear sum of the active variables */
1744 int* nvars, /**< pointer to number of variables in the linear sum which will be
1745 * overwritten by the number of variables in the linear sum corresponding
1746 * to the active variables */
1747 int varssize, /**< available slots in vars and scalars array which is needed to check if
1748 * the array are large enough for the linear sum w.r.t. active
1749 * variables */
1750 SCIP_Real* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c which
1751 * will chnage to constant d in the linear sum b_1*y_1 + ... + b_m*y_m +
1752 * d w.r.t. the active variables */
1753 int* requiredsize, /**< pointer to store the required array size for the linear sum w.r.t. the
1754 * active variables */
1755 SCIP_Bool mergemultiples /**< should multiple occurrences of a var be replaced by a single coeff? */
1756 )
1757{
1758 assert( scip != NULL );
1759 assert( nvars != NULL );
1760 assert( vars != NULL || *nvars == 0 );
1761 assert( scalars != NULL || *nvars == 0 );
1762 assert( constant != NULL );
1763 assert( requiredsize != NULL );
1764 assert( *nvars <= varssize );
1765
1766 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetProbvarLinearSum", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1767 SCIP_CALL( SCIPvarGetActiveRepresentatives(scip->set, vars, scalars, nvars, varssize, constant, requiredsize, mergemultiples) );
1768
1769 return SCIP_OKAY;
1770}
1771
1772/** transforms given variable, scalar and constant to the corresponding active, fixed, or
1773 * multi-aggregated variable, scalar and constant; if the variable resolves to a fixed variable,
1774 * "scalar" will be 0.0 and the value of the sum will be stored in "constant"; a multi-aggregation
1775 * with only one active variable (this can happen due to fixings after the multi-aggregation),
1776 * is treated like an aggregation; if the multi-aggregation constant is infinite, "scalar" will be 0.0
1777 *
1778 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1779 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1780 *
1781 * @pre This method can be called if @p scip is in one of the following stages:
1782 * - \ref SCIP_STAGE_TRANSFORMED
1783 * - \ref SCIP_STAGE_INITPRESOLVE
1784 * - \ref SCIP_STAGE_PRESOLVING
1785 * - \ref SCIP_STAGE_EXITPRESOLVE
1786 * - \ref SCIP_STAGE_PRESOLVED
1787 * - \ref SCIP_STAGE_INITSOLVE
1788 * - \ref SCIP_STAGE_SOLVING
1789 * - \ref SCIP_STAGE_SOLVED
1790 * - \ref SCIP_STAGE_EXITSOLVE
1791 * - \ref SCIP_STAGE_FREETRANS
1792 */
1794 SCIP* scip, /**< SCIP data structure */
1795 SCIP_VAR** var, /**< pointer to problem variable x in sum a*x + c */
1796 SCIP_Real* scalar, /**< pointer to scalar a in sum a*x + c */
1797 SCIP_Real* constant /**< pointer to constant c in sum a*x + c */
1798 )
1799{
1800 assert(scip != NULL);
1801 assert(var != NULL);
1802 assert(scalar != NULL);
1803 assert(constant != NULL);
1804
1805 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetProbvarSum", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1806 SCIP_CALL( SCIPvarGetProbvarSum(var, scip->set, scalar, constant) );
1807
1808 return SCIP_OKAY;
1809}
1810
1811/** return for given variables all their active counterparts; all active variables will be pairwise different
1812 * @note It does not hold that the first output variable is the active variable for the first input variable.
1813 *
1814 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1815 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1816 *
1817 * @pre This method can be called if @p scip is in one of the following stages:
1818 * - \ref SCIP_STAGE_TRANSFORMED
1819 * - \ref SCIP_STAGE_INITPRESOLVE
1820 * - \ref SCIP_STAGE_PRESOLVING
1821 * - \ref SCIP_STAGE_EXITPRESOLVE
1822 * - \ref SCIP_STAGE_PRESOLVED
1823 * - \ref SCIP_STAGE_INITSOLVE
1824 * - \ref SCIP_STAGE_SOLVING
1825 * - \ref SCIP_STAGE_SOLVED
1826 * - \ref SCIP_STAGE_EXITSOLVE
1827 * - \ref SCIP_STAGE_FREETRANS
1828 */
1830 SCIP* scip, /**< SCIP data structure */
1831 SCIP_VAR** vars, /**< variable array with given variables and as output all active
1832 * variables, if enough slots exist
1833 */
1834 int* nvars, /**< number of given variables, and as output number of active variables,
1835 * if enough slots exist
1836 */
1837 int varssize, /**< available slots in vars array */
1838 int* requiredsize /**< pointer to store the required array size for the active variables */
1839 )
1840{
1841 assert(scip != NULL);
1842 assert(nvars != NULL);
1843 assert(vars != NULL || *nvars == 0);
1844 assert(varssize >= *nvars);
1845 assert(requiredsize != NULL);
1846
1847 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetActiveVars", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1848 SCIP_CALL( SCIPvarsGetActiveVars(scip->set, vars, nvars, varssize, requiredsize) );
1849
1850 return SCIP_OKAY;
1851}
1852
1853/** returns the reduced costs of the variable in the current node's LP relaxation;
1854 * the current node has to have a feasible LP.
1855 *
1856 * returns SCIP_INVALID if the variable is active but not in the current LP;
1857 * returns 0 if the variable has been aggregated out or fixed in presolving.
1858 *
1859 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1860 *
1861 * @note The return value of this method should be used carefully if the dual feasibility check was explictely disabled.
1862 */
1864 SCIP* scip, /**< SCIP data structure */
1865 SCIP_VAR* var /**< variable to get reduced costs, should be a column in current node LP */
1866 )
1867{
1868 assert( scip != NULL );
1869 assert( var != NULL );
1870 assert( var->scip == scip );
1871
1872 switch( SCIPvarGetStatus(var) )
1873 {
1875 if( var->data.original.transvar == NULL )
1876 return SCIP_INVALID;
1878
1881
1883 return SCIP_INVALID;
1884
1889 return 0.0;
1890
1891 default:
1892 SCIPerrorMessage("unknown variable status\n");
1893 SCIPABORT();
1894 return 0.0; /*lint !e527*/
1895 }
1896}
1897
1898/** returns the implied reduced costs of the variable in the current node's LP relaxation;
1899 * the current node has to have a feasible LP.
1900 *
1901 * returns SCIP_INVALID if the variable is active but not in the current LP;
1902 * returns 0 if the variable has been aggregated out or fixed in presolving.
1903 *
1904 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1905 *
1906 * @note The return value of this method should be used carefully if the dual feasibility check was explictely disabled.
1907 */
1909 SCIP* scip, /**< SCIP data structure */
1910 SCIP_VAR* var, /**< variable to get reduced costs, should be a column in current node LP */
1911 SCIP_Bool varfixing /**< FALSE if for x == 0, TRUE for x == 1 */
1912 )
1913{
1914 assert( scip != NULL );
1915 assert( var != NULL );
1916 assert( var->scip == scip );
1917
1918 switch( SCIPvarGetStatus(var) )
1919 {
1921 if( var->data.original.transvar == NULL )
1922 return SCIP_INVALID;
1923 return SCIPgetVarImplRedcost(scip, var->data.original.transvar, varfixing);
1924
1926 return SCIPvarGetImplRedcost(var, scip->set, varfixing, scip->stat, scip->transprob, scip->lp);
1927
1929 return SCIP_INVALID;
1930
1935 return 0.0;
1936
1937 default:
1938 SCIPerrorMessage("unknown variable status\n");
1939 SCIPABORT();
1940 return 0.0; /*lint !e527*/
1941 }
1942}
1943
1944
1945/** returns the Farkas coefficient of the variable in the current node's LP relaxation;
1946 * the current node has to have an infeasible LP.
1947 *
1948 * returns SCIP_INVALID if the variable is active but not in the current LP;
1949 * returns 0 if the variable has been aggregated out or fixed in presolving.
1950 *
1951 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1952 */
1954 SCIP* scip, /**< SCIP data structure */
1955 SCIP_VAR* var /**< variable to get reduced costs, should be a column in current node LP */
1956 )
1957{
1958 assert(scip != NULL);
1959 assert(var != NULL);
1960 assert(var->scip == scip);
1961
1962 switch( SCIPvarGetStatus(var) )
1963 {
1965 if( var->data.original.transvar == NULL )
1966 return SCIP_INVALID;
1968
1971
1973 return SCIP_INVALID;
1974
1979 return 0.0;
1980
1981 default:
1982 SCIPerrorMessage("unknown variable status\n");
1983 SCIPABORT();
1984 return 0.0; /*lint !e527*/
1985 }
1986}
1987
1988/** returns lower bound of variable directly before or after the bound change given by the bound change index
1989 * was applied
1990 */
1992 SCIP* scip, /**< SCIP data structure */
1993 SCIP_VAR* var, /**< problem variable */
1994 SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
1995 SCIP_Bool after /**< should the bound change with given index be included? */
1996 )
1997{
1998 SCIP_VARSTATUS varstatus;
1999 SCIP_BDCHGINFO* bdchginfo;
2000 assert(var != NULL);
2001
2002 varstatus = SCIPvarGetStatus(var);
2003
2004 /* get bounds of attached variables */
2005 switch( varstatus )
2006 {
2009 return SCIPgetVarLbAtIndex(scip, var->data.original.transvar, bdchgidx, after);
2010
2013 if( bdchgidx == NULL )
2014 return SCIPvarGetLbLocal(var);
2015 else
2016 {
2017 bdchginfo = SCIPvarGetLbchgInfo(var, bdchgidx, after);
2018 if( bdchginfo != NULL )
2019 return SCIPbdchginfoGetNewbound(bdchginfo);
2020 else
2021 return var->glbdom.lb;
2022 }
2023
2025 return var->glbdom.lb;
2026
2027 case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c -> y = (x-c)/a */
2029 if( var->data.aggregate.scalar > 0.0 )
2030 {
2031 SCIP_Real lb;
2032
2033 lb = SCIPgetVarLbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2034
2035 /* a > 0 -> get lower bound of y */
2036 if( SCIPisInfinity(scip, -lb) )
2037 return -SCIPinfinity(scip);
2038 else if( SCIPisInfinity(scip, lb) )
2039 return SCIPinfinity(scip);
2040 else
2042 }
2043 else if( var->data.aggregate.scalar < 0.0 )
2044 {
2045 SCIP_Real ub;
2046
2047 ub = SCIPgetVarUbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2048
2049 /* a < 0 -> get upper bound of y */
2050 if( SCIPisInfinity(scip, -ub) )
2051 return SCIPinfinity(scip);
2052 else if( SCIPisInfinity(scip, ub) )
2053 return -SCIPinfinity(scip);
2054 else
2056 }
2057 else
2058 {
2059 SCIPerrorMessage("scalar is zero in aggregation\n");
2060 SCIPABORT();
2061 return SCIP_INVALID; /*lint !e527*/
2062 }
2063
2065 /* handle multi-aggregated variables depending on one variable only (possibly caused by SCIPvarFlattenAggregationGraph()) */
2066 if ( var->data.multaggr.nvars == 1 )
2067 {
2070 assert(var->data.multaggr.vars[0] != NULL);
2071
2072 if( var->data.multaggr.scalars[0] > 0.0 )
2073 {
2074 SCIP_Real lb;
2075
2076 lb = SCIPgetVarLbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2077
2078 /* a > 0 -> get lower bound of y */
2079 if( SCIPisInfinity(scip, -lb) )
2080 return -SCIPinfinity(scip);
2081 else if( SCIPisInfinity(scip, lb) )
2082 return SCIPinfinity(scip);
2083 else
2084 return var->data.multaggr.scalars[0] * lb + var->data.multaggr.constant;
2085 }
2086 else if( var->data.multaggr.scalars[0] < 0.0 )
2087 {
2088 SCIP_Real ub;
2089
2090 ub = SCIPgetVarUbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2091
2092 /* a < 0 -> get upper bound of y */
2093 if( SCIPisInfinity(scip, -ub) )
2094 return SCIPinfinity(scip);
2095 else if( SCIPisInfinity(scip, ub) )
2096 return -SCIPinfinity(scip);
2097 else
2098 return var->data.multaggr.scalars[0] * ub + var->data.multaggr.constant;
2099 }
2100 else
2101 {
2102 SCIPerrorMessage("scalar is zero in multi-aggregation\n");
2103 SCIPABORT();
2104 return SCIP_INVALID; /*lint !e527*/
2105 }
2106 }
2107 SCIPerrorMessage("cannot get the bounds of a multi-aggregated variable.\n");
2108 SCIPABORT();
2109 return SCIP_INVALID; /*lint !e527*/
2110
2111 case SCIP_VARSTATUS_NEGATED: /* x' = offset - x -> x = offset - x' */
2115 return var->data.negate.constant - SCIPgetVarUbAtIndex(scip, var->negatedvar, bdchgidx, after);
2116
2117 default:
2118 SCIPerrorMessage("unknown variable status\n");
2119 SCIPABORT();
2120 return SCIP_INVALID; /*lint !e527*/
2121 }
2122}
2123
2124/** returns upper bound of variable directly before or after the bound change given by the bound change index
2125 * was applied
2126 */
2128 SCIP* scip, /**< SCIP data structure */
2129 SCIP_VAR* var, /**< problem variable */
2130 SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2131 SCIP_Bool after /**< should the bound change with given index be included? */
2132 )
2133{
2134 SCIP_VARSTATUS varstatus;
2135 SCIP_BDCHGINFO* bdchginfo;
2136 assert(var != NULL);
2137
2138 varstatus = SCIPvarGetStatus(var);
2139
2140 /* get bounds of attached variables */
2141 switch( varstatus )
2142 {
2145 return SCIPgetVarUbAtIndex(scip, var->data.original.transvar, bdchgidx, after);
2146
2149 if( bdchgidx == NULL )
2150 return SCIPvarGetUbLocal(var);
2151 else
2152 {
2153 bdchginfo = SCIPvarGetUbchgInfo(var, bdchgidx, after);
2154 if( bdchginfo != NULL )
2155 return SCIPbdchginfoGetNewbound(bdchginfo);
2156 else
2157 return var->glbdom.ub;
2158 }
2159
2161 return var->glbdom.ub;
2162
2163 case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c -> y = (x-c)/a */
2165 if( var->data.aggregate.scalar > 0.0 )
2166 {
2167 SCIP_Real ub;
2168
2169 ub = SCIPgetVarUbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2170
2171 /* a > 0 -> get lower bound of y */
2172 if( SCIPisInfinity(scip, -ub) )
2173 return -SCIPinfinity(scip);
2174 else if( SCIPisInfinity(scip, ub) )
2175 return SCIPinfinity(scip);
2176 else
2178 }
2179 else if( var->data.aggregate.scalar < 0.0 )
2180 {
2181 SCIP_Real lb;
2182
2183 lb = SCIPgetVarLbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2184
2185 /* a < 0 -> get upper bound of y */
2186 if ( SCIPisInfinity(scip, -lb) )
2187 return SCIPinfinity(scip);
2188 else if ( SCIPisInfinity(scip, lb) )
2189 return -SCIPinfinity(scip);
2190 else
2192 }
2193 else
2194 {
2195 SCIPerrorMessage("scalar is zero in aggregation\n");
2196 SCIPABORT();
2197 return SCIP_INVALID; /*lint !e527*/
2198 }
2199
2201 /* handle multi-aggregated variables depending on one variable only (possibly caused by SCIPvarFlattenAggregationGraph()) */
2202 if ( var->data.multaggr.nvars == 1 )
2203 {
2206 assert(var->data.multaggr.vars[0] != NULL);
2207
2208 if( var->data.multaggr.scalars[0] > 0.0 )
2209 {
2210 SCIP_Real ub;
2211
2212 ub = SCIPgetVarUbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2213
2214 /* a > 0 -> get lower bound of y */
2215 if ( SCIPisInfinity(scip, -ub) )
2216 return -SCIPinfinity(scip);
2217 else if ( SCIPisInfinity(scip, ub) )
2218 return SCIPinfinity(scip);
2219 else
2220 return var->data.multaggr.scalars[0] * ub + var->data.multaggr.constant;
2221 }
2222 else if( var->data.multaggr.scalars[0] < 0.0 )
2223 {
2224 SCIP_Real lb;
2225
2226 lb = SCIPgetVarLbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2227
2228 /* a < 0 -> get upper bound of y */
2229 if ( SCIPisInfinity(scip, -lb) )
2230 return SCIPinfinity(scip);
2231 else if ( SCIPisInfinity(scip, lb) )
2232 return -SCIPinfinity(scip);
2233 else
2234 return var->data.multaggr.scalars[0] * lb + var->data.multaggr.constant;
2235 }
2236 else
2237 {
2238 SCIPerrorMessage("scalar is zero in multi-aggregation\n");
2239 SCIPABORT();
2240 return SCIP_INVALID; /*lint !e527*/
2241 }
2242 }
2243 SCIPerrorMessage("cannot get the bounds of a multiple aggregated variable.\n");
2244 SCIPABORT();
2245 return SCIP_INVALID; /*lint !e527*/
2246
2247 case SCIP_VARSTATUS_NEGATED: /* x' = offset - x -> x = offset - x' */
2251 return var->data.negate.constant - SCIPgetVarLbAtIndex(scip, var->negatedvar, bdchgidx, after);
2252
2253 default:
2254 SCIPerrorMessage("unknown variable status\n");
2255 SCIPABORT();
2256 return SCIP_INVALID; /*lint !e527*/
2257 }
2258}
2259
2260/** returns lower or upper bound of variable directly before or after the bound change given by the bound change index
2261 * was applied
2262 */
2264 SCIP* scip, /**< SCIP data structure */
2265 SCIP_VAR* var, /**< problem variable */
2266 SCIP_BOUNDTYPE boundtype, /**< type of bound: lower or upper bound */
2267 SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2268 SCIP_Bool after /**< should the bound change with given index be included? */
2269 )
2270{
2271 if( boundtype == SCIP_BOUNDTYPE_LOWER )
2272 return SCIPgetVarLbAtIndex(scip, var, bdchgidx, after);
2273 else
2274 {
2275 assert(boundtype == SCIP_BOUNDTYPE_UPPER);
2276 return SCIPgetVarUbAtIndex(scip, var, bdchgidx, after);
2277 }
2278}
2279
2280/** returns whether the binary variable was fixed at the time given by the bound change index */
2282 SCIP* scip, /**< SCIP data structure */
2283 SCIP_VAR* var, /**< problem variable */
2284 SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2285 SCIP_Bool after /**< should the bound change with given index be included? */
2286 )
2287{
2288 assert(var != NULL);
2290
2291 /* check the current bounds first in order to decide at which bound change information we have to look
2292 * (which is expensive because we have to follow the aggregation tree to the active variable)
2293 */
2294 return ((SCIPvarGetLbLocal(var) > 0.5 && SCIPgetVarLbAtIndex(scip, var, bdchgidx, after) > 0.5)
2295 || (SCIPvarGetUbLocal(var) < 0.5 && SCIPgetVarUbAtIndex(scip, var, bdchgidx, after) < 0.5));
2296}
2297
2298/** gets solution value for variable in current node
2299 *
2300 * @return solution value for variable in current node
2301 *
2302 * @pre This method can be called if @p scip is in one of the following stages:
2303 * - \ref SCIP_STAGE_PRESOLVED
2304 * - \ref SCIP_STAGE_SOLVING
2305 */
2307 SCIP* scip, /**< SCIP data structure */
2308 SCIP_VAR* var /**< variable to get solution value for */
2309 )
2310{
2312 assert( var->scip == scip );
2313
2315}
2316
2317/** gets solution values of multiple variables in current node
2318 *
2319 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2320 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2321 *
2322 * @pre This method can be called if @p scip is in one of the following stages:
2323 * - \ref SCIP_STAGE_PRESOLVED
2324 * - \ref SCIP_STAGE_SOLVING
2325 */
2327 SCIP* scip, /**< SCIP data structure */
2328 int nvars, /**< number of variables to get solution value for */
2329 SCIP_VAR** vars, /**< array with variables to get value for */
2330 SCIP_Real* vals /**< array to store solution values of variables */
2331 )
2332{
2333 int v;
2334
2335 assert(nvars == 0 || vars != NULL);
2336 assert(nvars == 0 || vals != NULL);
2337
2339
2340 if( SCIPtreeHasCurrentNodeLP(scip->tree) )
2341 {
2342 for( v = 0; v < nvars; ++v )
2343 vals[v] = SCIPvarGetLPSol(vars[v]);
2344 }
2345 else
2346 {
2347 for( v = 0; v < nvars; ++v )
2348 vals[v] = SCIPvarGetPseudoSol(vars[v]);
2349 }
2350
2351 return SCIP_OKAY;
2352}
2353
2354/** sets the solution value of all variables in the global relaxation solution to zero
2355 *
2356 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2357 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2358 *
2359 * @pre This method can be called if @p scip is in one of the following stages:
2360 * - \ref SCIP_STAGE_PRESOLVED
2361 * - \ref SCIP_STAGE_SOLVING
2362 */
2364 SCIP* scip, /**< SCIP data structure */
2365 SCIP_RELAX* relax /**< relaxator data structure */
2366 )
2367{
2368 SCIP_VAR** vars;
2369 int nvars;
2370 int v;
2371
2372 assert(scip != NULL);
2373
2374 SCIP_CALL( SCIPcheckStage(scip, "SCIPclearRelaxSolVals", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2375
2376 /* update the responsible relax pointer */
2377 SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2378
2379 /* the relaxation solution is already cleared */
2380 if( SCIPrelaxationIsSolZero(scip->relaxation) )
2381 return SCIP_OKAY;
2382
2384
2385 for( v = 0; v < nvars; v++ )
2386 {
2387 SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, 0.0, FALSE) );
2388 }
2389
2390 SCIPrelaxationSetSolObj(scip->relaxation, 0.0);
2391 SCIPrelaxationSetSolZero(scip->relaxation, TRUE);
2392
2393 return SCIP_OKAY;
2394}
2395
2396/** sets the value of the given variable in the global relaxation solution;
2397 * this solution can be filled by the relaxation handlers and can be used by heuristics and for separation;
2398 * You can use SCIPclearRelaxSolVals() to set all values to zero, initially;
2399 * after setting all solution values, you have to call SCIPmarkRelaxSolValid()
2400 * to inform SCIP that the stored solution is valid
2401 *
2402 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2403 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2404 *
2405 * @pre This method can be called if @p scip is in one of the following stages:
2406 * - \ref SCIP_STAGE_PRESOLVED
2407 * - \ref SCIP_STAGE_SOLVING
2408 *
2409 * @note This method incrementally updates the objective value of the relaxation solution. If the whole solution
2410 * should be updated, using SCIPsetRelaxSolVals() instead or calling SCIPclearRelaxSolVals() before setting
2411 * the first value to reset the solution and the objective value to 0 may help the numerics.
2412 */
2414 SCIP* scip, /**< SCIP data structure */
2415 SCIP_RELAX* relax, /**< relaxator data structure */
2416 SCIP_VAR* var, /**< variable to set value for */
2417 SCIP_Real val /**< solution value of variable */
2418 )
2419{
2420 assert(scip != NULL);
2421
2423
2424 SCIP_CALL( SCIPvarSetRelaxSol(var, scip->set, scip->relaxation, val, TRUE) );
2425
2426 if( val != 0.0 )
2427 SCIPrelaxationSetSolZero(scip->relaxation, FALSE);
2429 SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2430
2431 return SCIP_OKAY;
2432}
2433
2434/** sets the values of the given variables in the global relaxation solution and informs SCIP about the validity
2435 * and whether the solution can be enforced via linear cuts;
2436 * this solution can be filled by the relaxation handlers and can be used by heuristics and for separation;
2437 * the solution is automatically cleared, s.t. all other variables get value 0.0
2438 *
2439 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2440 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2441 *
2442 * @pre This method can be called if @p scip is in one of the following stages:
2443 * - \ref SCIP_STAGE_PRESOLVED
2444 * - \ref SCIP_STAGE_SOLVING
2445 */
2447 SCIP* scip, /**< SCIP data structure */
2448 SCIP_RELAX* relax, /**< relaxator data structure */
2449 int nvars, /**< number of variables to set relaxation solution value for */
2450 SCIP_VAR** vars, /**< array with variables to set value for */
2451 SCIP_Real* vals, /**< array with solution values of variables */
2452 SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2453 )
2454{
2455 int v;
2456
2457 assert(scip != NULL);
2458 assert(nvars == 0 || vars != NULL);
2459 assert(nvars == 0 || vals != NULL);
2460
2461 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolVals", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2462
2464
2465 for( v = 0; v < nvars; v++ )
2466 {
2467 SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, vals[v], TRUE) );
2468 }
2469
2470 SCIPrelaxationSetSolZero(scip->relaxation, FALSE);
2471 SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2472 SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2473
2474 return SCIP_OKAY;
2475}
2476
2477/** sets the values of the variables in the global relaxation solution to the values in the given primal solution
2478 * and informs SCIP about the validity and whether the solution can be enforced via linear cuts;
2479 * the relaxation solution can be filled by the relaxation handlers and might be used by heuristics and for separation
2480 *
2481 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2482 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2483 *
2484 * @pre This method can be called if @p scip is in one of the following stages:
2485 * - \ref SCIP_STAGE_PRESOLVED
2486 * - \ref SCIP_STAGE_SOLVING
2487 */
2489 SCIP* scip, /**< SCIP data structure */
2490 SCIP_RELAX* relax, /**< relaxator data structure */
2491 SCIP_SOL* sol, /**< primal relaxation solution */
2492 SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2493 )
2494{
2495 SCIP_VAR** vars;
2496 SCIP_Real* vals;
2497 int nvars;
2498 int v;
2499
2500 assert(scip != NULL);
2501
2502 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolValsSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2503
2505
2506 /* alloc buffer array for solution values of the variables and get the values */
2509
2511
2512 for( v = 0; v < nvars; v++ )
2513 {
2514 SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, vals[v], FALSE) );
2515 }
2516
2517 SCIPrelaxationSetSolObj(scip->relaxation, SCIPsolGetObj(sol, scip->set, scip->transprob, scip->origprob));
2518
2519 SCIPrelaxationSetSolZero(scip->relaxation, FALSE);
2520 SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2521 SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2522
2523 SCIPfreeBufferArray(scip, &vals);
2524
2525 return SCIP_OKAY;
2526}
2527
2528/** returns whether the relaxation solution is valid
2529 *
2530 * @return TRUE, if the relaxation solution is valid; FALSE, otherwise
2531 *
2532 * @pre This method can be called if @p scip is in one of the following stages:
2533 * - \ref SCIP_STAGE_PRESOLVED
2534 * - \ref SCIP_STAGE_SOLVING
2535 */
2537 SCIP* scip /**< SCIP data structure */
2538 )
2539{
2540 assert(scip != NULL);
2541
2543
2544 return SCIPrelaxationIsSolValid(scip->relaxation);
2545}
2546
2547/** informs SCIP that the relaxation solution is valid and whether the relaxation can be enforced through linear cuts
2548 *
2549 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2550 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2551 *
2552 * @pre This method can be called if @p scip is in one of the following stages:
2553 * - \ref SCIP_STAGE_PRESOLVED
2554 * - \ref SCIP_STAGE_SOLVING
2555 */
2557 SCIP* scip, /**< SCIP data structure */
2558 SCIP_RELAX* relax, /**< relaxator data structure that set the current relaxation solution */
2559 SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2560 )
2561{
2562 assert(scip != NULL);
2563
2564 SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkRelaxSolValid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2565
2566 SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2567 SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2568
2569 return SCIP_OKAY;
2570}
2571
2572/** informs SCIP, that the relaxation solution is invalid
2573 *
2574 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2575 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2576 *
2577 * @pre This method can be called if @p scip is in one of the following stages:
2578 * - \ref SCIP_STAGE_PRESOLVED
2579 * - \ref SCIP_STAGE_SOLVING
2580 */
2582 SCIP* scip /**< SCIP data structure */
2583 )
2584{
2585 assert(scip != NULL);
2586
2587 SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkRelaxSolInvalid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2588
2590
2591 return SCIP_OKAY;
2592}
2593
2594/** gets the relaxation solution value of the given variable
2595 *
2596 * @return the relaxation solution value of the given variable
2597 *
2598 * @pre This method can be called if @p scip is in one of the following stages:
2599 * - \ref SCIP_STAGE_PRESOLVED
2600 * - \ref SCIP_STAGE_SOLVING
2601 */
2603 SCIP* scip, /**< SCIP data structure */
2604 SCIP_VAR* var /**< variable to get value for */
2605 )
2606{
2607 assert(scip != NULL);
2608 assert(var != NULL);
2609 assert(var->scip == scip);
2610
2612
2613 if( !SCIPrelaxationIsSolValid(scip->relaxation) )
2614 {
2615 SCIPerrorMessage("Relaxation Solution is not valid!\n");
2616 SCIPABORT();
2617 return SCIP_INVALID; /*lint !e527*/
2618 }
2619
2620 return SCIPvarGetRelaxSol(var, scip->set);
2621}
2622
2623/** gets the relaxation solution objective value
2624 *
2625 * @return the objective value of the relaxation solution
2626 *
2627 * @pre This method can be called if @p scip is in one of the following stages:
2628 * - \ref SCIP_STAGE_PRESOLVED
2629 * - \ref SCIP_STAGE_SOLVING
2630 */
2632 SCIP* scip /**< SCIP data structure */
2633 )
2634{
2635 assert(scip != NULL);
2636
2638
2639 if( !SCIPrelaxationIsSolValid(scip->relaxation) )
2640 {
2641 SCIPerrorMessage("Relaxation Solution is not valid!\n");
2642 SCIPABORT();
2643 return SCIP_INVALID; /*lint !e527*/
2644 }
2645
2646 return SCIPrelaxationGetSolObj(scip->relaxation);
2647}
2648
2649/** determine which branching direction should be evaluated first by strong branching
2650 *
2651 * @return TRUE iff strong branching should first evaluate the down child
2652 *
2653 */
2655 SCIP* scip, /**< SCIP data structure */
2656 SCIP_VAR* var /**< variable to determine the branching direction on */
2657 )
2658{
2659 switch( scip->set->branch_firstsbchild )
2660 {
2661 case 'u':
2662 return FALSE;
2663 case 'd':
2664 return TRUE;
2665 case 'a':
2667 default:
2668 assert(scip->set->branch_firstsbchild == 'h');
2670 }
2671}
2672
2673/** start strong branching - call before any strong branching
2674 *
2675 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2676 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2677 *
2678 * @pre This method can be called if @p scip is in one of the following stages:
2679 * - \ref SCIP_STAGE_PRESOLVED
2680 * - \ref SCIP_STAGE_SOLVING
2681 *
2682 * @note if propagation is enabled, strong branching is not done directly on the LP, but probing nodes are created
2683 * which allow to perform propagation but also creates some overhead
2684 */
2686 SCIP* scip, /**< SCIP data structure */
2687 SCIP_Bool enablepropagation /**< should propagation be done before solving the strong branching LP? */
2688 )
2689{
2690 assert( scip != NULL );
2691 SCIP_CALL( SCIPcheckStage(scip, "SCIPstartStrongbranch", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2692
2694
2695 SCIPdebugMsg(scip, "starting strong branching mode%s: lpcount=%" SCIP_LONGINT_FORMAT "\n", enablepropagation ? " with propagation" : "", scip->stat->lpcount - scip->stat->nsbdivinglps);
2696
2697 /* start probing mode to allow propagation before solving the strong branching LPs; if no propagation should be done,
2698 * start the strong branching mode in the LP interface
2699 */
2700 if( enablepropagation )
2701 {
2702 if( SCIPtreeProbing(scip->tree) )
2703 {
2704 SCIPerrorMessage("cannot start strong branching with propagation while in probing mode\n");
2705 return SCIP_INVALIDCALL;
2706 }
2707
2708 if( scip->lp != NULL && SCIPlpDiving(scip->lp) )
2709 {
2710 SCIPerrorMessage("cannot start strong branching with propagation while in diving mode\n");
2711 return SCIP_INVALIDCALL;
2712 }
2713
2714 /* other then in SCIPstartProbing(), we do not disable collecting variable statistics during strong branching;
2715 * we cannot disable it, because the pseudo costs would not be updated, otherwise,
2716 * and reliability branching would end up doing strong branching all the time
2717 */
2718 SCIP_CALL( SCIPtreeStartProbing(scip->tree, scip->mem->probmem, scip->set, scip->lp, scip->relaxation, scip->transprob, TRUE) );
2719
2720 /* inform the LP that the current probing mode is used for strong branching */
2722 }
2723 else
2724 {
2726 }
2727
2728 /* reset local strong branching info */
2729 scip->stat->lastsblpsolstats[0] = scip->stat->lastsblpsolstats[1] = SCIP_LPSOLSTAT_NOTSOLVED;
2730
2731 return SCIP_OKAY;
2732}
2733
2734/** end strong branching - call after any strong branching
2735 *
2736 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2737 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2738 *
2739 * @pre This method can be called if @p scip is in one of the following stages:
2740 * - \ref SCIP_STAGE_PRESOLVED
2741 * - \ref SCIP_STAGE_SOLVING
2742 */
2744 SCIP* scip /**< SCIP data structure */
2745 )
2746{
2747 assert( scip != NULL );
2748
2749 SCIP_CALL( SCIPcheckStage(scip, "SCIPendStrongbranch", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2750
2751 /* depending on whether the strong branching mode was started with propagation enabled or not, we end the strong
2752 * branching probing mode or the LP strong branching mode
2753 */
2754 if( SCIPtreeProbing(scip->tree) )
2755 {
2756 SCIP_NODE* node;
2757 SCIP_DOMCHG* domchg;
2758 SCIP_VAR** boundchgvars;
2759 SCIP_Real* bounds;
2760 SCIP_BOUNDTYPE* boundtypes;
2761 int nboundchgs;
2762 int nbnds;
2763 int i;
2764
2765 /* collect all bound changes deducted during probing, which were applied at the probing root and apply them to the
2766 * focusnode
2767 */
2768 node = SCIPgetCurrentNode(scip);
2771
2772 domchg = SCIPnodeGetDomchg(node);
2773 nboundchgs = SCIPdomchgGetNBoundchgs(domchg);
2774
2775 SCIP_CALL( SCIPallocBufferArray(scip, &boundchgvars, nboundchgs) );
2776 SCIP_CALL( SCIPallocBufferArray(scip, &bounds, nboundchgs) );
2777 SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, nboundchgs) );
2778
2779 for( i = 0, nbnds = 0; i < nboundchgs; ++i )
2780 {
2781 SCIP_BOUNDCHG* boundchg;
2782
2783 boundchg = SCIPdomchgGetBoundchg(domchg, i);
2784
2785 /* ignore redundant bound changes */
2786 if( SCIPboundchgIsRedundant(boundchg) )
2787 continue;
2788
2789 boundchgvars[nbnds] = SCIPboundchgGetVar(boundchg);
2790 bounds[nbnds] = SCIPboundchgGetNewbound(boundchg);
2791 boundtypes[nbnds] = SCIPboundchgGetBoundtype(boundchg);
2792 ++nbnds;
2793 }
2794
2795 SCIPdebugMsg(scip, "ending strong branching with probing: %d bound changes collected\n", nbnds);
2796
2797 /* inform the LP that the probing mode is not used for strong branching anymore */
2799
2800 /* switch back from probing to normal operation mode and restore variables and constraints to focus node */
2801 SCIP_CALL( SCIPtreeEndProbing(scip->tree, scip->reopt, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
2802 scip->transprob, scip->origprob, scip->lp, scip->relaxation, scip->primal,
2803 scip->branchcand, scip->eventqueue, scip->eventfilter, scip->cliquetable) );
2804
2805 /* apply the collected bound changes */
2806 for( i = 0; i < nbnds; ++i )
2807 {
2808 if( boundtypes[i] == SCIP_BOUNDTYPE_LOWER )
2809 {
2810 SCIPdebugMsg(scip, "apply probing lower bound change <%s> >= %.9g\n", SCIPvarGetName(boundchgvars[i]), bounds[i]);
2811 SCIP_CALL( SCIPchgVarLb(scip, boundchgvars[i], bounds[i]) );
2812 }
2813 else
2814 {
2815 SCIPdebugMsg(scip, "apply probing upper bound change <%s> <= %.9g\n", SCIPvarGetName(boundchgvars[i]), bounds[i]);
2816 SCIP_CALL( SCIPchgVarUb(scip, boundchgvars[i], bounds[i]) );
2817 }
2818 }
2819
2820 SCIPfreeBufferArray(scip, &boundtypes);
2821 SCIPfreeBufferArray(scip, &bounds);
2822 SCIPfreeBufferArray(scip, &boundchgvars);
2823 }
2824 else
2825 {
2826 SCIPdebugMsg(scip, "ending strong branching\n");
2827
2829 }
2830
2831 return SCIP_OKAY;
2832}
2833
2834/** analyze the strong branching for the given variable; that includes conflict analysis for infeasible branches and
2835 * storing of root reduced cost information
2836 */
2837static
2839 SCIP* scip, /**< SCIP data structure */
2840 SCIP_VAR* var, /**< variable to analyze */
2841 SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
2842 SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
2843 SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
2844 * infeasible downwards branch, or NULL */
2845 SCIP_Bool* upconflict /**< pointer to store whether a conflict constraint was created for an
2846 * infeasible upwards branch, or NULL */
2847 )
2848{
2849 SCIP_COL* col;
2850 SCIP_Bool downcutoff;
2851 SCIP_Bool upcutoff;
2852
2853 col = SCIPvarGetCol(var);
2854 assert(col != NULL);
2855
2856 downcutoff = col->sbdownvalid && SCIPsetIsGE(scip->set, col->sbdown, scip->lp->cutoffbound);
2857 upcutoff = col->sbupvalid && SCIPsetIsGE(scip->set, col->sbup, scip->lp->cutoffbound);
2858
2859 if( downinf != NULL )
2860 *downinf = downcutoff;
2861 if( upinf != NULL )
2862 *upinf = upcutoff;
2863
2864 /* analyze infeasible strong branching sub problems:
2865 * because the strong branching's bound change is necessary for infeasibility, it cannot be undone;
2866 * therefore, infeasible strong branchings on non-binary variables will not produce a valid conflict constraint
2867 */
2868 if( scip->set->conf_enable && scip->set->conf_usesb && scip->set->nconflicthdlrs > 0
2870 {
2871 if( (downcutoff && SCIPsetFeasCeil(scip->set, col->primsol-1.0) >= col->lb - 0.5)
2872 || (upcutoff && SCIPsetFeasFloor(scip->set, col->primsol+1.0) <= col->ub + 0.5) )
2873 {
2874 assert(downconflict != NULL);
2875 assert(upconflict != NULL);
2876 SCIP_CALL( SCIPconflictAnalyzeStrongbranch(scip->conflict, scip->conflictstore, scip->mem->probmem, scip->set, scip->stat,
2877 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, col, downconflict, upconflict) );
2878 }
2879 }
2880
2881 /* the strong branching results can be used to strengthen the root reduced cost information which is used for example
2882 * to propagate against the cutoff bound
2883 *
2884 * @note Ignore the results if the LP solution of the down (up) branch LP is smaller which should not happened by
2885 * theory but can arise due to numerical issues.
2886 */
2888 {
2889 SCIP_Real lpobjval;
2890
2892
2893 lpobjval = SCIPlpGetObjval(scip->lp, scip->set, scip->transprob);
2894
2895 if( col->sbdownvalid && SCIPsetFeasCeil(scip->set, col->primsol-1.0) >= col->lb - 0.5 && lpobjval < col->sbdown )
2896 SCIPvarUpdateBestRootSol(var, scip->set, SCIPvarGetUbGlobal(var), -(col->sbdown - lpobjval), lpobjval);
2897 if( col->sbupvalid && SCIPsetFeasFloor(scip->set, col->primsol+1.0) <= col->ub + 0.5 && lpobjval < col->sbup )
2898 SCIPvarUpdateBestRootSol(var, scip->set, SCIPvarGetLbGlobal(var), col->sbup - lpobjval, lpobjval);
2899 }
2900
2901 return SCIP_OKAY;
2902}
2903
2904/** gets strong branching information on column variable with fractional value
2905 *
2906 * Before calling this method, the strong branching mode must have been activated by calling SCIPstartStrongbranch();
2907 * after strong branching was done for all candidate variables, the strong branching mode must be ended by
2908 * SCIPendStrongbranch(). Since this method does not apply domain propagation before strongbranching,
2909 * propagation should not be enabled in the SCIPstartStrongbranch() call.
2910 *
2911 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2912 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2913 *
2914 * @pre This method can be called if @p scip is in one of the following stages:
2915 * - \ref SCIP_STAGE_PRESOLVED
2916 * - \ref SCIP_STAGE_SOLVING
2917 */
2919 SCIP* scip, /**< SCIP data structure */
2920 SCIP_VAR* var, /**< variable to get strong branching values for */
2921 int itlim, /**< iteration limit for strong branchings */
2922 SCIP_Bool idempotent, /**< should scip's state remain the same after the call (statistics, column states...), or should it be updated ? */
2923 SCIP_Real* down, /**< stores dual bound after branching column down */
2924 SCIP_Real* up, /**< stores dual bound after branching column up */
2925 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
2926 * otherwise, it can only be used as an estimate value */
2927 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
2928 * otherwise, it can only be used as an estimate value */
2929 SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
2930 SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
2931 SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
2932 * infeasible downwards branch, or NULL */
2933 SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
2934 * infeasible upwards branch, or NULL */
2935 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
2936 * solving process should be stopped (e.g., due to a time limit) */
2937 )
2938{
2939 SCIP_COL* col;
2940 SCIP_Real localdown;
2941 SCIP_Real localup;
2942 SCIP_Bool localdownvalid;
2943 SCIP_Bool localupvalid;
2944
2945 assert(scip != NULL);
2946 assert(var != NULL);
2947 assert(lperror != NULL);
2948 assert(!SCIPtreeProbing(scip->tree)); /* we should not be in strong branching with propagation mode */
2949 assert(var->scip == scip);
2950
2951 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchFrac", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2952
2953 if( downvalid != NULL )
2954 *downvalid = FALSE;
2955 if( upvalid != NULL )
2956 *upvalid = FALSE;
2957 if( downinf != NULL )
2958 *downinf = FALSE;
2959 if( upinf != NULL )
2960 *upinf = FALSE;
2961 if( downconflict != NULL )
2962 *downconflict = FALSE;
2963 if( upconflict != NULL )
2964 *upconflict = FALSE;
2965
2967 {
2968 SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
2969 return SCIP_INVALIDDATA;
2970 }
2971
2972 col = SCIPvarGetCol(var);
2973 assert(col != NULL);
2974
2975 if( !SCIPcolIsInLP(col) )
2976 {
2977 SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
2978 return SCIP_INVALIDDATA;
2979 }
2980
2981 /* check if the solving process should be aborted */
2982 if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
2983 {
2984 /* mark this as if the LP failed */
2985 *lperror = TRUE;
2986 return SCIP_OKAY;
2987 }
2988
2989 /* call strong branching for column with fractional value */
2990 SCIP_CALL( SCIPcolGetStrongbranch(col, FALSE, scip->set, scip->stat, scip->transprob, scip->lp, itlim, !idempotent, !idempotent,
2991 &localdown, &localup, &localdownvalid, &localupvalid, lperror) );
2992
2993 /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
2994 * declare the sub nodes infeasible
2995 */
2996 if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
2997 {
2998 if( !idempotent ) /*lint !e774*/
2999 {
3000 SCIP_CALL( analyzeStrongbranch(scip, var, downinf, upinf, downconflict, upconflict) );
3001 }
3002 else
3003 {
3004 if( downinf != NULL )
3005 *downinf = localdownvalid && SCIPsetIsGE(scip->set, localdown, scip->lp->cutoffbound);
3006 if( upinf != NULL )
3007 *upinf = localupvalid && SCIPsetIsGE(scip->set, localup, scip->lp->cutoffbound);
3008 }
3009 }
3010
3011 if( down != NULL )
3012 *down = localdown;
3013 if( up != NULL )
3014 *up = localup;
3015 if( downvalid != NULL )
3016 *downvalid = localdownvalid;
3017 if( upvalid != NULL )
3018 *upvalid = localupvalid;
3019
3020 return SCIP_OKAY;
3021}
3022
3023/** create, solve, and evaluate a single strong branching child (for strong branching with propagation) */
3024static
3026 SCIP* scip, /**< SCIP data structure */
3027 SCIP_VAR* var, /**< variable to get strong branching values for */
3028 SCIP_Bool down, /**< do we regard the down child? */
3029 SCIP_Bool firstchild, /**< is this the first of the two strong branching children? */
3030 SCIP_Bool propagate, /**< should domain propagation be performed? */
3031 SCIP_Real newbound, /**< new bound to apply at the strong branching child */
3032 int itlim, /**< iteration limit for strong branchings */
3033 int maxproprounds, /**< maximum number of propagation rounds (-1: no limit, -2: parameter
3034 * settings) */
3035 SCIP_Real* value, /**< stores dual bound for strong branching child */
3036 SCIP_Bool* valid, /**< stores whether the returned value is a valid dual bound, or NULL;
3037 * otherwise, it can only be used as an estimate value */
3038 SCIP_Longint* ndomreductions, /**< pointer to store the number of domain reductions found, or NULL */
3039 SCIP_Bool* conflict, /**< pointer to store whether a conflict constraint was created for an
3040 * infeasible strong branching child, or NULL */
3041 SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred or the
3042 * solving process should be stopped (e.g., due to a time limit) */
3043 SCIP_VAR** vars, /**< active problem variables */
3044 int nvars, /**< number of active problem variables */
3045 SCIP_Real* newlbs, /**< array to store valid lower bounds for all active variables, or NULL */
3046 SCIP_Real* newubs, /**< array to store valid upper bounds for all active variables, or NULL */
3047 SCIP_Bool* foundsol, /**< pointer to store whether a primal solution was found during strong branching */
3048 SCIP_Bool* cutoff /**< pointer to store whether the strong branching child is infeasible */
3049 )
3050{
3051 SCIP_Longint ndomreds;
3052
3053 assert(value != NULL);
3054 assert(foundsol != NULL);
3055 assert(cutoff != NULL);
3056 assert(lperror != NULL);
3057 assert(valid != NULL ? !(*valid) : TRUE);
3058
3059 *foundsol = FALSE;
3060 *cutoff = FALSE;
3061 *lperror = FALSE;
3062
3063 /* check whether the strong branching child is already infeasible due to the bound change */
3064 if( down )
3065 {
3066 /* the down branch is infeasible due to the branching bound change; since this means that solval is not within the
3067 * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3068 * are valid for and were already applied at the probing root
3069 */
3070 if( newbound < SCIPvarGetLbLocal(var) - 0.5 )
3071 {
3072 *value = SCIPinfinity(scip);
3073
3074 if( valid != NULL )
3075 *valid = TRUE;
3076
3077 /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3078 if( conflict != NULL )
3079 *conflict = TRUE;
3080
3081 *cutoff = TRUE;
3082
3083 return SCIP_OKAY;
3084 }
3085 }
3086 else
3087 {
3088 /* the up branch is infeasible due to the branching bound change; since this means that solval is not within the
3089 * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3090 * are valid for and were already applied at the probing root
3091 */
3092 if( newbound > SCIPvarGetUbLocal(var) + 0.5 )
3093 {
3094 *value = SCIPinfinity(scip);
3095
3096 if( valid != NULL )
3097 *valid = TRUE;
3098
3099 /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3100 if( conflict != NULL )
3101 *conflict = TRUE;
3102
3103 *cutoff = TRUE;
3104
3105 return SCIP_OKAY;
3106 }
3107 }
3108
3109 /* we need to ensure that we can create at least one new probing node without exceeding the maximal tree depth */
3111 {
3112 /* create a new probing node for the strong branching child and apply the new bound for the variable */
3114
3115 if( down )
3116 {
3118 if( SCIPisLT(scip, newbound, SCIPvarGetUbLocal(var)) )
3119 {
3120 SCIP_CALL( SCIPchgVarUbProbing(scip, var, newbound) );
3121 }
3122 }
3123 else
3124 {
3126 if( SCIPisGT(scip, newbound, SCIPvarGetLbLocal(var)) )
3127 {
3128 SCIP_CALL( SCIPchgVarLbProbing(scip, var, newbound) );
3129 }
3130 }
3131 }
3132 else
3133 {
3134 if( valid != NULL )
3135 *valid = FALSE;
3136
3137 *cutoff = FALSE;
3138
3139 if( conflict != NULL )
3140 *conflict = FALSE;
3141
3142 return SCIP_OKAY;
3143 }
3144
3145 /* propagate domains at the probing node */
3146 if( propagate )
3147 {
3148 /* start time measuring */
3149 SCIPclockStart(scip->stat->strongpropclock, scip->set);
3150
3151 ndomreds = 0;
3152 SCIP_CALL( SCIPpropagateProbing(scip, maxproprounds, cutoff, &ndomreds) );
3153
3154 /* store number of domain reductions in strong branching */
3155 if( down )
3156 SCIPstatAdd(scip->stat, scip->set, nsbdowndomchgs, ndomreds);
3157 else
3158 SCIPstatAdd(scip->stat, scip->set, nsbupdomchgs, ndomreds);
3159
3160 if( ndomreductions != NULL )
3161 *ndomreductions = ndomreds;
3162
3163 /* stop time measuring */
3164 SCIPclockStop(scip->stat->strongpropclock, scip->set);
3165
3166 if( *cutoff )
3167 {
3168 *value = SCIPinfinity(scip);
3169
3170 if( valid != NULL )
3171 *valid = TRUE;
3172
3173 SCIPdebugMsg(scip, "%s branch of var <%s> detected infeasible during propagation\n",
3174 down ? "down" : "up", SCIPvarGetName(var));
3175 }
3176 }
3177
3178 /* if propagation did not already detect infeasibility, solve the probing LP */
3179 if( !(*cutoff) )
3180 {
3183
3184 if( *cutoff )
3185 {
3186 assert(!(*lperror));
3187
3188 *value = SCIPinfinity(scip);
3189
3190 if( valid != NULL )
3191 *valid = TRUE;
3192
3193 SCIPdebugMsg(scip, "%s branch of var <%s> detected infeasible in LP solving: status=%d\n",
3194 down ? "down" : "up", SCIPvarGetName(var), SCIPgetLPSolstat(scip));
3195 }
3196 else if( !(*lperror) )
3197 {
3198 /* save the lp solution status */
3199 scip->stat->lastsblpsolstats[down ? 0 : 1] = SCIPgetLPSolstat(scip);
3200
3201 switch( SCIPgetLPSolstat(scip) )
3202 {
3204 {
3205 *value = SCIPgetLPObjval(scip);
3207
3208 SCIPdebugMsg(scip, "probing LP solved to optimality, objective value: %16.9g\n", *value);
3209
3210 if( valid != NULL )
3211 *valid = TRUE;
3212
3213 /* check the strong branching LP solution for feasibility */
3215 break;
3216 }
3218 ++scip->stat->nsbtimesiterlimhit;
3219 /*lint -fallthrough*/
3221 {
3222 /* use LP value as estimate */
3223 SCIP_LPI* lpi;
3224 SCIP_Real objval;
3225 SCIP_Real looseobjval;
3226
3227 SCIPdebugMsg(scip, "probing LP hit %s limit\n", SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_ITERLIMIT ? "iteration" : "time");
3228
3229 /* we access the LPI directly, because when a time limit was hit, we cannot access objective value and dual
3230 * feasibility using the SCIPlp... methods; we should try to avoid direct calls to the LPI, but this is rather
3231 * uncritical here, because we are immediately after the SCIPsolveProbingLP() call, because we access the LPI
3232 * read-only, and we check SCIPlpiWasSolved() first
3233 */
3234 SCIP_CALL( SCIPgetLPI(scip, &lpi) );
3235
3236 if( SCIPlpiWasSolved(lpi) )
3237 {
3239 looseobjval = SCIPlpGetLooseObjval(scip->lp, scip->set, scip->transprob);
3240
3241 /* the infinity value in the LPI should not be smaller than SCIP's infinity value */
3243
3244 /* we use SCIP's infinity value here because a value larger than this is counted as infeasible by SCIP */
3245 if( SCIPisInfinity(scip, objval) )
3246 *value = SCIPinfinity(scip);
3247 else if( SCIPisInfinity(scip, -looseobjval) )
3248 *value = -SCIPinfinity(scip);
3249 else
3250 *value = objval + looseobjval;
3251
3252 if( SCIPlpiIsDualFeasible(lpi) )
3253 {
3254 if( valid != NULL )
3255 *valid = TRUE;
3256
3257 if( SCIPisGE(scip, *value, SCIPgetCutoffbound(scip)) )
3258 *cutoff = TRUE;
3259 }
3260 }
3261 break;
3262 }
3265 *lperror = TRUE;
3266 break;
3267 case SCIP_LPSOLSTAT_NOTSOLVED: /* should only be the case for *cutoff = TRUE or *lperror = TRUE */
3268 case SCIP_LPSOLSTAT_OBJLIMIT: /* in this case, *cutoff should be TRUE and we should not get here */
3269 case SCIP_LPSOLSTAT_INFEASIBLE: /* in this case, *cutoff should be TRUE and we should not get here */
3270 default:
3271 SCIPerrorMessage("invalid LP solution status <%d>\n", SCIPgetLPSolstat(scip));
3272 return SCIP_INVALIDDATA;
3273 } /*lint !e788*/
3274 }
3275
3276 /* If columns are missing in the LP, the cutoff flag may be wrong. Therefore, we need to set it and the valid pointer
3277 * to false here.
3278 */
3279 if( (*cutoff) && !SCIPallColsInLP(scip) )
3280 {
3281 *cutoff = FALSE;
3282 }
3283
3284#ifndef NDEBUG
3285 if( *lperror )
3286 {
3287 SCIPdebugMsg(scip, "error during strong branching probing LP solving: status=%d\n", SCIPgetLPSolstat(scip));
3288 }
3289#endif
3290 }
3291
3292 /* if the subproblem was feasible, we store the local bounds of the variables after propagation and (possibly)
3293 * conflict analysis
3294 * @todo do this after propagation? should be able to get valid bounds more often, but they might be weaker
3295 */
3296 if( !(*cutoff) && newlbs != NULL)
3297 {
3298 int v;
3299
3300 assert(newubs != NULL);
3301
3302 /* initialize the newlbs and newubs to the current local bounds */
3303 if( firstchild )
3304 {
3305 for( v = 0; v < nvars; ++v )
3306 {
3307 newlbs[v] = SCIPvarGetLbLocal(vars[v]);
3308 newubs[v] = SCIPvarGetUbLocal(vars[v]);
3309 }
3310 }
3311 /* update newlbs and newubs: take the weaker of the already stored bounds and the current local bounds */
3312 else
3313 {
3314 for( v = 0; v < nvars; ++v )
3315 {
3316 SCIP_Real lb = SCIPvarGetLbLocal(vars[v]);
3317 SCIP_Real ub = SCIPvarGetUbLocal(vars[v]);
3318
3319 newlbs[v] = MIN(newlbs[v], lb);
3320 newubs[v] = MAX(newubs[v], ub);
3321 }
3322 }
3323 }
3324
3325 /* revert all changes at the probing node */
3327
3328 return SCIP_OKAY;
3329}
3330
3331/** gets strong branching information with previous domain propagation on column variable
3332 *
3333 * Before calling this method, the strong branching mode must have been activated by calling SCIPstartStrongbranch();
3334 * after strong branching was done for all candidate variables, the strong branching mode must be ended by
3335 * SCIPendStrongbranch(). Since this method applies domain propagation before strongbranching, propagation has to be be
3336 * enabled in the SCIPstartStrongbranch() call.
3337 *
3338 * Before solving the strong branching LP, domain propagation can be performed. The number of propagation rounds
3339 * can be specified by the parameter @p maxproprounds.
3340 *
3341 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3342 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3343 *
3344 * @pre This method can be called if @p scip is in one of the following stages:
3345 * - \ref SCIP_STAGE_PRESOLVED
3346 * - \ref SCIP_STAGE_SOLVING
3347 *
3348 * @warning When using this method, LP banching candidates and solution values must be copied beforehand, because
3349 * they are updated w.r.t. the strong branching LP solution.
3350 */
3352 SCIP* scip, /**< SCIP data structure */
3353 SCIP_VAR* var, /**< variable to get strong branching values for */
3354 SCIP_Real solval, /**< value of the variable in the current LP solution */
3355 SCIP_Real lpobjval, /**< LP objective value of the current LP solution */
3356 int itlim, /**< iteration limit for strong branchings */
3357 int maxproprounds, /**< maximum number of propagation rounds (-1: no limit, -2: parameter
3358 * settings) */
3359 SCIP_Real* down, /**< stores dual bound after branching column down */
3360 SCIP_Real* up, /**< stores dual bound after branching column up */
3361 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
3362 * otherwise, it can only be used as an estimate value */
3363 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
3364 * otherwise, it can only be used as an estimate value */
3365 SCIP_Longint* ndomredsdown, /**< pointer to store the number of domain reductions down, or NULL */
3366 SCIP_Longint* ndomredsup, /**< pointer to store the number of domain reductions up, or NULL */
3367 SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
3368 SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
3369 SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
3370 * infeasible downwards branch, or NULL */
3371 SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
3372 * infeasible upwards branch, or NULL */
3373 SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred or the
3374 * solving process should be stopped (e.g., due to a time limit) */
3375 SCIP_Real* newlbs, /**< array to store valid lower bounds for all active variables, or NULL */
3376 SCIP_Real* newubs /**< array to store valid upper bounds for all active variables, or NULL */
3377 )
3378{
3379 SCIP_COL* col;
3380 SCIP_VAR** vars;
3381 SCIP_Longint oldniters;
3382 SCIP_Real newub;
3383 SCIP_Real newlb;
3384 SCIP_Bool propagate;
3385 SCIP_Bool cutoff;
3386 SCIP_Bool downchild;
3387 SCIP_Bool firstchild;
3388 SCIP_Bool foundsol;
3389 SCIP_Bool downvalidlocal;
3390 SCIP_Bool upvalidlocal;
3391 SCIP_Bool allcolsinlp;
3392 SCIP_Bool enabledconflict;
3393 int oldnconflicts;
3394 int nvars;
3395
3396 assert(scip != NULL);
3397 assert(var != NULL);
3399 assert(down != NULL);
3400 assert(up != NULL);
3401 assert(lperror != NULL);
3402 assert((newlbs != NULL) == (newubs != NULL));
3404 assert(var->scip == scip);
3405
3406 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchWithPropagation", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3407
3408 /* check whether propagation should be performed */
3409 propagate = (maxproprounds != 0 && maxproprounds != -3);
3410
3411 /* Check, if all existing columns are in LP.
3412 * If this is not the case, we may still return that the up and down dual bounds are valid, because the branching
3413 * rule should not apply them otherwise.
3414 * However, we must not set the downinf or upinf pointers to TRUE based on the dual bound, because we cannot
3415 * guarantee that this node can be cut off.
3416 */
3417 allcolsinlp = SCIPallColsInLP(scip);
3418
3419 /* if maxproprounds is -2, change it to 0, which for the following calls means using the parameter settings */
3420 if( maxproprounds == -2 )
3421 maxproprounds = 0;
3422
3423 *down = lpobjval;
3424 *up = lpobjval;
3425 if( downvalid != NULL )
3426 *downvalid = FALSE;
3427 if( upvalid != NULL )
3428 *upvalid = FALSE;
3429 if( downinf != NULL )
3430 *downinf = FALSE;
3431 if( upinf != NULL )
3432 *upinf = FALSE;
3433 if( downconflict != NULL )
3434 *downconflict = FALSE;
3435 if( upconflict != NULL )
3436 *upconflict = FALSE;
3437 if( ndomredsdown != NULL )
3438 *ndomredsdown = 0;
3439 if( ndomredsup != NULL )
3440 *ndomredsup = 0;
3441
3442 *lperror = FALSE;
3443
3446
3447 scip->stat->lastsblpsolstats[0] = scip->stat->lastsblpsolstats[1] = SCIP_LPSOLSTAT_NOTSOLVED;
3448
3449 /* check if the solving process should be aborted */
3450 if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3451 {
3452 /* mark this as if the LP failed */
3453 *lperror = TRUE;
3454 return SCIP_OKAY;
3455 }
3456
3458 {
3459 SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3460 return SCIP_INVALIDDATA;
3461 }
3462
3463 col = SCIPvarGetCol(var);
3464 assert(col != NULL);
3465
3466 if( !SCIPcolIsInLP(col) )
3467 {
3468 SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3469 return SCIP_INVALIDDATA;
3470 }
3471
3472 newlb = SCIPfeasFloor(scip, solval + 1.0);
3473 newub = SCIPfeasCeil(scip, solval - 1.0);
3474
3475 SCIPdebugMsg(scip, "strong branching on var <%s>: solval=%g, lb=%g, ub=%g\n", SCIPvarGetName(var), solval,
3477
3478 /* the up branch is infeasible due to the branching bound change; since this means that solval is not within the
3479 * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3480 * are valid for and were already applied at the probing root
3481 */
3482 if( newlb > SCIPvarGetUbLocal(var) + 0.5 )
3483 {
3484 *up = SCIPinfinity(scip);
3485
3486 if( upinf != NULL )
3487 *upinf = TRUE;
3488
3489 if( upvalid != NULL )
3490 *upvalid = TRUE;
3491
3492 /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3493 if( upconflict != NULL )
3494 *upconflict = TRUE;
3495
3496 SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3497 *down, *up, FALSE, TRUE, 0LL, INT_MAX);
3498
3499 /* we do not regard the down branch; its valid pointer stays set to FALSE */
3500 return SCIP_OKAY;
3501 }
3502
3503 /* the down branch is infeasible due to the branching bound change; since this means that solval is not within the
3504 * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3505 * are valid for and were already applied at the probing root
3506 */
3507 if( newub < SCIPvarGetLbLocal(var) - 0.5 )
3508 {
3509 *down = SCIPinfinity(scip);
3510
3511 if( downinf != NULL )
3512 *downinf = TRUE;
3513
3514 if( downvalid != NULL )
3515 *downvalid = TRUE;
3516
3517 /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3518 if( downconflict != NULL )
3519 *downconflict = TRUE;
3520
3521 SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3522 *down, *up, TRUE, FALSE, 0LL, INT_MAX);
3523
3524 /* we do not regard the up branch; its valid pointer stays set to FALSE */
3525 return SCIP_OKAY;
3526 }
3527
3528 /* We now do strong branching by creating the two potential child nodes as probing nodes and solving them one after
3529 * the other. We will stop when the first child is detected infeasible, saving the effort we would need for the
3530 * second child. Since empirically, the up child tends to be infeasible more often, we do strongbranching first on
3531 * the up branch.
3532 */
3533 oldniters = scip->stat->nsbdivinglpiterations;
3534 firstchild = TRUE;
3535 cutoff = FALSE;
3536
3537 /* switch conflict analysis according to usesb parameter */
3538 enabledconflict = scip->set->conf_enable;
3539 scip->set->conf_enable = (scip->set->conf_enable && scip->set->conf_usesb);
3540
3541 /* @todo: decide the branch to look at first based on the cutoffs in previous calls? */
3542 downchild = SCIPisStrongbranchDownFirst(scip, var);
3543
3544 downvalidlocal = FALSE;
3545 upvalidlocal = FALSE;
3546
3547 do
3548 {
3549 oldnconflicts = SCIPconflictGetNConflicts(scip->conflict);
3550
3551 if( downchild )
3552 {
3553 SCIP_CALL( performStrongbranchWithPropagation(scip, var, downchild, firstchild, propagate, newub, itlim, maxproprounds,
3554 down, &downvalidlocal, ndomredsdown, downconflict, lperror, vars, nvars, newlbs, newubs, &foundsol, &cutoff) );
3555
3556 /* check whether a new solutions rendered the previous child infeasible */
3557 if( foundsol && !firstchild && allcolsinlp )
3558 {
3559 if( SCIPisGE(scip, *up, SCIPgetCutoffbound(scip)) )
3560 {
3561 if( upinf != NULL )
3562 *upinf = TRUE;
3563 }
3564 }
3565
3566 /* check for infeasibility */
3567 if( cutoff )
3568 {
3569 if( downinf != NULL )
3570 *downinf = TRUE;
3571
3572 if( downconflict != NULL &&
3573 (SCIPvarGetLbLocal(var) > newub + 0.5 || SCIPconflictGetNConflicts(scip->conflict) > oldnconflicts) )
3574 {
3575 *downconflict = TRUE;
3576 }
3577
3578 if( !scip->set->branch_forceall )
3579 {
3580 /* if this is the first call, we do not regard the up branch, its valid pointer is initially set to FALSE */
3581 break;
3582 }
3583 }
3584 }
3585 else
3586 {
3587 SCIP_CALL( performStrongbranchWithPropagation(scip, var, downchild, firstchild, propagate, newlb, itlim, maxproprounds,
3588 up, &upvalidlocal, ndomredsup, upconflict, lperror, vars, nvars, newlbs, newubs, &foundsol, &cutoff) );
3589
3590 /* check whether a new solutions rendered the previous child infeasible */
3591 if( foundsol && !firstchild && allcolsinlp )
3592 {
3593 if( SCIPisGE(scip, *down, SCIPgetCutoffbound(scip)) )
3594 {
3595 if( downinf != NULL )
3596 *downinf = TRUE;
3597 }
3598 }
3599
3600 /* check for infeasibility */
3601 if( cutoff )
3602 {
3603 if( upinf != NULL )
3604 *upinf = TRUE;
3605
3606 assert(upinf == NULL || (*upinf) == TRUE);
3607
3608 if( upconflict != NULL &&
3609 (SCIPvarGetUbLocal(var) < newlb - 0.5 || SCIPconflictGetNConflicts(scip->conflict) > oldnconflicts) )
3610 {
3611 *upconflict = TRUE;
3612 }
3613
3614 if( !scip->set->branch_forceall )
3615 {
3616 /* if this is the first call, we do not regard the down branch, its valid pointer is initially set to FALSE */
3617 break;
3618 }
3619 }
3620 }
3621
3622 downchild = !downchild;
3623 firstchild = !firstchild;
3624 }
3625 while( !firstchild );
3626
3627 /* set strong branching information in column */
3628 if( *lperror )
3629 {
3630 SCIPcolInvalidateStrongbranchData(col, scip->set, scip->stat, scip->lp);
3631 }
3632 else
3633 {
3634 SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3635 *down, *up, downvalidlocal, upvalidlocal, scip->stat->nsbdivinglpiterations - oldniters, itlim);
3636 }
3637
3638 if( downvalid != NULL )
3639 *downvalid = downvalidlocal;
3640 if( upvalid != NULL )
3641 *upvalid = upvalidlocal;
3642
3643 scip->set->conf_enable = enabledconflict;
3644
3645 return SCIP_OKAY; /*lint !e438*/
3646}
3647
3648/** gets strong branching information on column variable x with integral LP solution value (val); that is, the down branch
3649 * is (val -1.0) and the up brach ins (val +1.0)
3650 *
3651 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3652 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3653 *
3654 * @pre This method can be called if @p scip is in one of the following stages:
3655 * - \ref SCIP_STAGE_PRESOLVED
3656 * - \ref SCIP_STAGE_SOLVING
3657 *
3658 * @note If the integral LP solution value is the lower or upper bound of the variable, the corresponding branch will be
3659 * marked as infeasible. That is, the valid pointer and the infeasible pointer are set to TRUE.
3660 */
3662 SCIP* scip, /**< SCIP data structure */
3663 SCIP_VAR* var, /**< variable to get strong branching values for */
3664 int itlim, /**< iteration limit for strong branchings */
3665 SCIP_Bool idempotent, /**< should scip's state remain the same after the call (statistics, column states...), or should it be updated ? */
3666 SCIP_Real* down, /**< stores dual bound after branching column down */
3667 SCIP_Real* up, /**< stores dual bound after branching column up */
3668 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
3669 * otherwise, it can only be used as an estimate value */
3670 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
3671 * otherwise, it can only be used as an estimate value */
3672 SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
3673 SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
3674 SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
3675 * infeasible downwards branch, or NULL */
3676 SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
3677 * infeasible upwards branch, or NULL */
3678 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3679 * solving process should be stopped (e.g., due to a time limit) */
3680 )
3681{
3682 SCIP_COL* col;
3683 SCIP_Real localdown;
3684 SCIP_Real localup;
3685 SCIP_Bool localdownvalid;
3686 SCIP_Bool localupvalid;
3687
3688 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchInt", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3689
3690 assert(lperror != NULL);
3691 assert(var->scip == scip);
3692
3693 if( downvalid != NULL )
3694 *downvalid = FALSE;
3695 if( upvalid != NULL )
3696 *upvalid = FALSE;
3697 if( downinf != NULL )
3698 *downinf = FALSE;
3699 if( upinf != NULL )
3700 *upinf = FALSE;
3701 if( downconflict != NULL )
3702 *downconflict = FALSE;
3703 if( upconflict != NULL )
3704 *upconflict = FALSE;
3705
3707 {
3708 SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3709 return SCIP_INVALIDDATA;
3710 }
3711
3712 col = SCIPvarGetCol(var);
3713 assert(col != NULL);
3714
3715 if( !SCIPcolIsInLP(col) )
3716 {
3717 SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3718 return SCIP_INVALIDDATA;
3719 }
3720
3721 /* check if the solving process should be aborted */
3722 if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3723 {
3724 /* mark this as if the LP failed */
3725 *lperror = TRUE;
3726 return SCIP_OKAY;
3727 }
3728
3729 /* call strong branching for column */
3730 SCIP_CALL( SCIPcolGetStrongbranch(col, TRUE, scip->set, scip->stat, scip->transprob, scip->lp, itlim, !idempotent, !idempotent,
3731 &localdown, &localup, &localdownvalid, &localupvalid, lperror) );
3732
3733 /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3734 * declare the sub nodes infeasible
3735 */
3736 if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3737 {
3738 if( !idempotent ) /*lint !e774*/
3739 {
3740 SCIP_CALL( analyzeStrongbranch(scip, var, downinf, upinf, downconflict, upconflict) );
3741 }
3742 else
3743 {
3744 if( downinf != NULL )
3745 *downinf = localdownvalid && SCIPsetIsGE(scip->set, localdown, scip->lp->cutoffbound);
3746 if( upinf != NULL )
3747 *upinf = localupvalid && SCIPsetIsGE(scip->set, localup, scip->lp->cutoffbound);
3748 }
3749 }
3750
3751 if( down != NULL )
3752 *down = localdown;
3753 if( up != NULL )
3754 *up = localup;
3755 if( downvalid != NULL )
3756 *downvalid = localdownvalid;
3757 if( upvalid != NULL )
3758 *upvalid = localupvalid;
3759
3760 return SCIP_OKAY;
3761}
3762
3763/** gets strong branching information on column variables with fractional values
3764 *
3765 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3766 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3767 *
3768 * @pre This method can be called if @p scip is in one of the following stages:
3769 * - \ref SCIP_STAGE_PRESOLVED
3770 * - \ref SCIP_STAGE_SOLVING
3771 */
3773 SCIP* scip, /**< SCIP data structure */
3774 SCIP_VAR** vars, /**< variables to get strong branching values for */
3775 int nvars, /**< number of variables */
3776 int itlim, /**< iteration limit for strong branchings */
3777 SCIP_Real* down, /**< stores dual bounds after branching variables down */
3778 SCIP_Real* up, /**< stores dual bounds after branching variables up */
3779 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
3780 * otherwise, they can only be used as an estimate value */
3781 SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
3782 * otherwise, they can only be used as an estimate value */
3783 SCIP_Bool* downinf, /**< array to store whether the downward branches are infeasible, or NULL */
3784 SCIP_Bool* upinf, /**< array to store whether the upward branches are infeasible, or NULL */
3785 SCIP_Bool* downconflict, /**< array to store whether conflict constraints were created for
3786 * infeasible downward branches, or NULL */
3787 SCIP_Bool* upconflict, /**< array to store whether conflict constraints were created for
3788 * infeasible upward branches, or NULL */
3789 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3790 * solving process should be stopped (e.g., due to a time limit) */
3791 )
3792{
3793 SCIP_COL** cols;
3794 int j;
3795
3796 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarsStrongbranchesFrac", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3797
3798 assert( lperror != NULL );
3799 assert( vars != NULL );
3800
3801 /* set up data */
3802 cols = NULL;
3804 assert(cols != NULL);
3805 for( j = 0; j < nvars; ++j )
3806 {
3807 SCIP_VAR* var;
3808 SCIP_COL* col;
3809
3810 if( downvalid != NULL )
3811 downvalid[j] = FALSE;
3812 if( upvalid != NULL )
3813 upvalid[j] = FALSE;
3814 if( downinf != NULL )
3815 downinf[j] = FALSE;
3816 if( upinf != NULL )
3817 upinf[j] = FALSE;
3818 if( downconflict != NULL )
3819 downconflict[j] = FALSE;
3820 if( upconflict != NULL )
3821 upconflict[j] = FALSE;
3822
3823 var = vars[j];
3824 assert( var != NULL );
3826 {
3827 SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3828 SCIPfreeBufferArray(scip, &cols);
3829 return SCIP_INVALIDDATA;
3830 }
3831
3832 col = SCIPvarGetCol(var);
3833 assert(col != NULL);
3834 cols[j] = col;
3835
3836 if( !SCIPcolIsInLP(col) )
3837 {
3838 SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3839 SCIPfreeBufferArray(scip, &cols);
3840 return SCIP_INVALIDDATA;
3841 }
3842 }
3843
3844 /* check if the solving process should be aborted */
3845 if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3846 {
3847 /* mark this as if the LP failed */
3848 *lperror = TRUE;
3849 }
3850 else
3851 {
3852 /* call strong branching for columns with fractional value */
3853 SCIP_CALL( SCIPcolGetStrongbranches(cols, nvars, FALSE, scip->set, scip->stat, scip->transprob, scip->lp, itlim,
3854 down, up, downvalid, upvalid, lperror) );
3855
3856 /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3857 * declare the sub nodes infeasible
3858 */
3859 if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3860 {
3861 for( j = 0; j < nvars; ++j )
3862 {
3863 SCIP_CALL( analyzeStrongbranch(scip, vars[j], (downinf != NULL) ? (&(downinf[j])) : NULL,
3864 (upinf != NULL) ? (&(upinf[j])) : NULL, (downconflict != NULL) ? (&(downconflict[j])) : NULL,
3865 (upconflict != NULL) ? (&(upconflict[j])) : NULL) );
3866 }
3867 }
3868 }
3869 SCIPfreeBufferArray(scip, &cols);
3870
3871 return SCIP_OKAY;
3872}
3873
3874/** gets strong branching information on column variables with integral values
3875 *
3876 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3877 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3878 *
3879 * @pre This method can be called if @p scip is in one of the following stages:
3880 * - \ref SCIP_STAGE_PRESOLVED
3881 * - \ref SCIP_STAGE_SOLVING
3882 */
3884 SCIP* scip, /**< SCIP data structure */
3885 SCIP_VAR** vars, /**< variables to get strong branching values for */
3886 int nvars, /**< number of variables */
3887 int itlim, /**< iteration limit for strong branchings */
3888 SCIP_Real* down, /**< stores dual bounds after branching variables down */
3889 SCIP_Real* up, /**< stores dual bounds after branching variables up */
3890 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
3891 * otherwise, they can only be used as an estimate value */
3892 SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
3893 * otherwise, they can only be used as an estimate value */
3894 SCIP_Bool* downinf, /**< array to store whether the downward branches are infeasible, or NULL */
3895 SCIP_Bool* upinf, /**< array to store whether the upward branches are infeasible, or NULL */
3896 SCIP_Bool* downconflict, /**< array to store whether conflict constraints were created for
3897 * infeasible downward branches, or NULL */
3898 SCIP_Bool* upconflict, /**< array to store whether conflict constraints were created for
3899 * infeasible upward branches, or NULL */
3900 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3901 * solving process should be stopped (e.g., due to a time limit) */
3902 )
3903{
3904 SCIP_COL** cols;
3905 int j;
3906
3907 assert(lperror != NULL);
3908
3909 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarsStrongbranchesInt", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3910
3911 assert( vars != NULL );
3912
3913 /* set up data */
3914 cols = NULL;
3916 assert(cols != NULL);
3917 for( j = 0; j < nvars; ++j )
3918 {
3919 SCIP_VAR* var;
3920 SCIP_COL* col;
3921
3922 if( downvalid != NULL )
3923 downvalid[j] = FALSE;
3924 if( upvalid != NULL )
3925 upvalid[j] = FALSE;
3926 if( downinf != NULL )
3927 downinf[j] = FALSE;
3928 if( upinf != NULL )
3929 upinf[j] = FALSE;
3930 if( downconflict != NULL )
3931 downconflict[j] = FALSE;
3932 if( upconflict != NULL )
3933 upconflict[j] = FALSE;
3934
3935 var = vars[j];
3936 assert( var != NULL );
3938 {
3939 SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3940 SCIPfreeBufferArray(scip, &cols);
3941 return SCIP_INVALIDDATA;
3942 }
3943
3944 col = SCIPvarGetCol(var);
3945 assert(col != NULL);
3946 cols[j] = col;
3947
3948 if( !SCIPcolIsInLP(col) )
3949 {
3950 SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3951 SCIPfreeBufferArray(scip, &cols);
3952 return SCIP_INVALIDDATA;
3953 }
3954 }
3955
3956 /* check if the solving process should be aborted */
3957 if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3958 {
3959 /* mark this as if the LP failed */
3960 *lperror = TRUE;
3961 }
3962 else
3963 {
3964 /* call strong branching for columns */
3965 SCIP_CALL( SCIPcolGetStrongbranches(cols, nvars, TRUE, scip->set, scip->stat, scip->transprob, scip->lp, itlim,
3966 down, up, downvalid, upvalid, lperror) );
3967
3968 /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3969 * declare the sub nodes infeasible
3970 */
3971 if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3972 {
3973 for( j = 0; j < nvars; ++j )
3974 {
3975 SCIP_CALL( analyzeStrongbranch(scip, vars[j], (downinf != NULL) ? (&(downinf[j])) : NULL,
3976 (upinf != NULL) ? (&(upinf[j])) : NULL, (downconflict != NULL) ? (&(downconflict[j])) : NULL,
3977 (upconflict != NULL) ? (&(upconflict[j])) : NULL) );
3978 }
3979 }
3980 }
3981 SCIPfreeBufferArray(scip, &cols);
3982
3983 return SCIP_OKAY;
3984}
3985
3986/** get LP solution status of last strong branching call (currently only works for strong branching with propagation) */
3988 SCIP* scip, /**< SCIP data structure */
3989 SCIP_BRANCHDIR branchdir /**< branching direction for which LP solution status is requested */
3990 )
3991{
3992 assert(NULL != scip);
3993 assert(branchdir == SCIP_BRANCHDIR_DOWNWARDS || branchdir == SCIP_BRANCHDIR_UPWARDS);
3994
3995 return scip->stat->lastsblpsolstats[branchdir == SCIP_BRANCHDIR_DOWNWARDS ? 0 : 1];
3996}
3997
3998/** gets strong branching information on COLUMN variable of the last SCIPgetVarStrongbranch() call;
3999 * returns values of SCIP_INVALID, if strong branching was not yet called on the given variable;
4000 * keep in mind, that the returned old values may have nothing to do with the current LP solution
4001 *
4002 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4003 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4004 *
4005 * @pre This method can be called if @p scip is in one of the following stages:
4006 * - \ref SCIP_STAGE_SOLVING
4007 * - \ref SCIP_STAGE_SOLVED
4008 */
4010 SCIP* scip, /**< SCIP data structure */
4011 SCIP_VAR* var, /**< variable to get last strong branching values for */
4012 SCIP_Real* down, /**< stores dual bound after branching column down */
4013 SCIP_Real* up, /**< stores dual bound after branching column up */
4014 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4015 * otherwise, it can only be used as an estimate value */
4016 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4017 * otherwise, it can only be used as an estimate value */
4018 SCIP_Real* solval, /**< stores LP solution value of variable at the last strong branching call, or NULL */
4019 SCIP_Real* lpobjval /**< stores LP objective value at last strong branching call, or NULL */
4020 )
4021{
4022 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchLast", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
4023
4025 {
4026 SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable\n");
4027 return SCIP_INVALIDDATA;
4028 }
4029
4030 SCIPcolGetStrongbranchLast(SCIPvarGetCol(var), down, up, downvalid, upvalid, solval, lpobjval);
4031
4032 return SCIP_OKAY;
4033}
4034
4035/** sets strong branching information for a column variable
4036 *
4037 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4038 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4039 *
4040 * @pre This method can be called if @p scip is in one of the following stages:
4041 * - \ref SCIP_STAGE_SOLVING
4042 */
4044 SCIP* scip, /**< SCIP data structure */
4045 SCIP_VAR* var, /**< variable to set last strong branching values for */
4046 SCIP_Real lpobjval, /**< objective value of the current LP */
4047 SCIP_Real primsol, /**< primal solution value of the column in the current LP */
4048 SCIP_Real down, /**< dual bound after branching column down */
4049 SCIP_Real up, /**< dual bound after branching column up */
4050 SCIP_Bool downvalid, /**< is the returned down value a valid dual bound? */
4051 SCIP_Bool upvalid, /**< is the returned up value a valid dual bound? */
4052 SCIP_Longint iter, /**< total number of strong branching iterations */
4053 int itlim /**< iteration limit applied to the strong branching call */
4054 )
4055{
4056 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetVarStrongbranchData", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4057
4059 {
4060 SCIPerrorMessage("cannot set strong branching information on non-COLUMN variable\n");
4061 return SCIP_INVALIDDATA;
4062 }
4063
4064 SCIPcolSetStrongbranchData(SCIPvarGetCol(var), scip->set, scip->stat, scip->lp, lpobjval, primsol,
4065 down, up, downvalid, upvalid, iter, itlim);
4066
4067 return SCIP_OKAY;
4068}
4069
4070/** rounds the current solution and tries it afterwards; if feasible, adds it to storage
4071 *
4072 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4073 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4074 *
4075 * @pre This method can be called if @p scip is in one of the following stages:
4076 * - \ref SCIP_STAGE_SOLVING
4077 */
4079 SCIP* scip, /**< SCIP data structure */
4080 SCIP_Bool* foundsol, /**< stores whether solution was feasible and good enough to keep */
4081 SCIP_Bool* cutoff /**< stores whether solution was cutoff due to exceeding the cutoffbound */
4082 )
4083{
4084 assert(scip != NULL);
4085 assert(foundsol != NULL);
4086 assert(cutoff != NULL);
4087
4088 SCIP_CALL( SCIPcheckStage(scip, "SCIPtryStrongbranchLPSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4089
4090 if( scip->set->branch_checksbsol )
4091 {
4092 SCIP_SOL* sol;
4093 SCIP_Bool rounded = TRUE;
4094 SCIP_Real value = SCIPgetLPObjval(scip);
4095 SCIP_Longint oldnbestsolsfound = scip->primal->nbestsolsfound;
4096
4097 /* start clock for strong branching solutions */
4098 SCIPclockStart(scip->stat->sbsoltime, scip->set);
4099
4102
4103 /* try to round the strong branching solution */
4104 if( scip->set->branch_roundsbsol )
4105 {
4106 SCIP_CALL( SCIProundSol(scip, sol, &rounded) );
4107 }
4108
4109 /* check the solution for feasibility if rounding worked well (or was not tried) */
4110 if( rounded )
4111 {
4112 SCIP_CALL( SCIPtrySolFree(scip, &sol, FALSE, FALSE, FALSE, TRUE, FALSE, foundsol) );
4113 }
4114 else
4115 {
4117 }
4118
4119 if( *foundsol )
4120 {
4121 SCIPdebugMsg(scip, "found new solution in strong branching\n");
4122
4123 scip->stat->nsbsolsfound++;
4124
4125 if( scip->primal->nbestsolsfound != oldnbestsolsfound )
4126 {
4127 scip->stat->nsbbestsolsfound++;
4128 }
4129
4130 if( SCIPisGE(scip, value, SCIPgetCutoffbound(scip)) )
4131 *cutoff = TRUE;
4132 }
4133
4134 /* stop clock for strong branching solutions */
4135 SCIPclockStop(scip->stat->sbsoltime, scip->set);
4136 }
4137 return SCIP_OKAY;
4138}
4139
4140
4141/** gets node number of the last node in current branch and bound run, where strong branching was used on the
4142 * given variable, or -1 if strong branching was never applied to the variable in current run
4143 *
4144 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4145 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4146 *
4147 * @pre This method can be called if @p scip is in one of the following stages:
4148 * - \ref SCIP_STAGE_TRANSFORMING
4149 * - \ref SCIP_STAGE_TRANSFORMED
4150 * - \ref SCIP_STAGE_INITPRESOLVE
4151 * - \ref SCIP_STAGE_PRESOLVING
4152 * - \ref SCIP_STAGE_EXITPRESOLVE
4153 * - \ref SCIP_STAGE_PRESOLVED
4154 * - \ref SCIP_STAGE_INITSOLVE
4155 * - \ref SCIP_STAGE_SOLVING
4156 * - \ref SCIP_STAGE_SOLVED
4157 * - \ref SCIP_STAGE_EXITSOLVE
4158 */
4160 SCIP* scip, /**< SCIP data structure */
4161 SCIP_VAR* var /**< variable to get last strong branching node for */
4162 )
4163{
4164 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarStrongbranchNode", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4165
4166 assert( var->scip == scip );
4167
4169 return -1;
4170
4172}
4173
4174/** if strong branching was already applied on the variable at the current node, returns the number of LPs solved after
4175 * the LP where the strong branching on this variable was applied;
4176 * if strong branching was not yet applied on the variable at the current node, returns INT_MAX
4177 *
4178 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4179 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4180 *
4181 * @pre This method can be called if @p scip is in one of the following stages:
4182 * - \ref SCIP_STAGE_TRANSFORMING
4183 * - \ref SCIP_STAGE_TRANSFORMED
4184 * - \ref SCIP_STAGE_INITPRESOLVE
4185 * - \ref SCIP_STAGE_PRESOLVING
4186 * - \ref SCIP_STAGE_EXITPRESOLVE
4187 * - \ref SCIP_STAGE_PRESOLVED
4188 * - \ref SCIP_STAGE_INITSOLVE
4189 * - \ref SCIP_STAGE_SOLVING
4190 * - \ref SCIP_STAGE_SOLVED
4191 * - \ref SCIP_STAGE_EXITSOLVE
4192 */
4194 SCIP* scip, /**< SCIP data structure */
4195 SCIP_VAR* var /**< variable to get strong branching LP age for */
4196 )
4197{
4198 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarStrongbranchLPAge", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4199
4200 assert( var->scip == scip );
4201
4203 return SCIP_LONGINT_MAX;
4204
4206}
4207
4208/** gets number of times, strong branching was applied in current run on the given variable
4209 *
4210 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4211 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4212 *
4213 * @pre This method can be called if @p scip is in one of the following stages:
4214 * - \ref SCIP_STAGE_TRANSFORMING
4215 * - \ref SCIP_STAGE_TRANSFORMED
4216 * - \ref SCIP_STAGE_INITPRESOLVE
4217 * - \ref SCIP_STAGE_PRESOLVING
4218 * - \ref SCIP_STAGE_EXITPRESOLVE
4219 * - \ref SCIP_STAGE_PRESOLVED
4220 * - \ref SCIP_STAGE_INITSOLVE
4221 * - \ref SCIP_STAGE_SOLVING
4222 * - \ref SCIP_STAGE_SOLVED
4223 * - \ref SCIP_STAGE_EXITSOLVE
4224 */
4226 SCIP* scip, /**< SCIP data structure */
4227 SCIP_VAR* var /**< variable to get last strong branching node for */
4228 )
4229{
4230 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarNStrongbranchs", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4231
4232 assert( var->scip == scip );
4233
4235 return 0;
4236
4238}
4239
4240/** adds given values to lock numbers of type @p locktype of variable for rounding
4241 *
4242 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4243 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4244 *
4245 * @pre This method can be called if @p scip is in one of the following stages:
4246 * - \ref SCIP_STAGE_PROBLEM
4247 * - \ref SCIP_STAGE_TRANSFORMING
4248 * - \ref SCIP_STAGE_TRANSFORMED
4249 * - \ref SCIP_STAGE_INITPRESOLVE
4250 * - \ref SCIP_STAGE_PRESOLVING
4251 * - \ref SCIP_STAGE_EXITPRESOLVE
4252 * - \ref SCIP_STAGE_PRESOLVED
4253 * - \ref SCIP_STAGE_INITSOLVE
4254 * - \ref SCIP_STAGE_SOLVING
4255 * - \ref SCIP_STAGE_EXITSOLVE
4256 * - \ref SCIP_STAGE_FREETRANS
4257 */
4259 SCIP* scip, /**< SCIP data structure */
4260 SCIP_VAR* var, /**< problem variable */
4261 SCIP_LOCKTYPE locktype, /**< type of the variable locks */
4262 int nlocksdown, /**< modification in number of rounding down locks */
4263 int nlocksup /**< modification in number of rounding up locks */
4264 )
4265{
4266 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarLocksType", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4267
4268 assert( var->scip == scip );
4269
4270 switch( scip->set->stage )
4271 {
4272 case SCIP_STAGE_PROBLEM:
4274 /*lint -fallthrough*/
4282 case SCIP_STAGE_SOLVING:
4285 SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, locktype, nlocksdown, nlocksup) );
4286 return SCIP_OKAY;
4287
4288 default:
4289 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4290 return SCIP_INVALIDCALL;
4291 } /*lint !e788*/
4292}
4293
4294/** adds given values to lock numbers of variable for rounding
4295 *
4296 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4297 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4298 *
4299 * @pre This method can be called if @p scip is in one of the following stages:
4300 * - \ref SCIP_STAGE_PROBLEM
4301 * - \ref SCIP_STAGE_TRANSFORMING
4302 * - \ref SCIP_STAGE_TRANSFORMED
4303 * - \ref SCIP_STAGE_INITPRESOLVE
4304 * - \ref SCIP_STAGE_PRESOLVING
4305 * - \ref SCIP_STAGE_EXITPRESOLVE
4306 * - \ref SCIP_STAGE_PRESOLVED
4307 * - \ref SCIP_STAGE_INITSOLVE
4308 * - \ref SCIP_STAGE_SOLVING
4309 * - \ref SCIP_STAGE_EXITSOLVE
4310 * - \ref SCIP_STAGE_FREETRANS
4311 *
4312 * @note This method will always add variable locks of type model
4313 *
4314 * @note It is recommented to use SCIPaddVarLocksType()
4315 */
4317 SCIP* scip, /**< SCIP data structure */
4318 SCIP_VAR* var, /**< problem variable */
4319 int nlocksdown, /**< modification in number of rounding down locks */
4320 int nlocksup /**< modification in number of rounding up locks */
4321 )
4322{
4323 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarLocks", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4324
4325 SCIP_CALL( SCIPaddVarLocksType(scip, var, SCIP_LOCKTYPE_MODEL, nlocksdown, nlocksup) );
4326
4327 return SCIP_OKAY;
4328}
4329
4330/** add locks of variable with respect to the lock status of the constraint and its negation;
4331 * this method should be called whenever the lock status of a variable in a constraint changes, for example if
4332 * the coefficient of the variable changed its sign or if the left or right hand sides of the constraint were
4333 * added or removed
4334 *
4335 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4336 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4337 *
4338 * @pre This method can be called if @p scip is in one of the following stages:
4339 * - \ref SCIP_STAGE_PROBLEM
4340 * - \ref SCIP_STAGE_TRANSFORMING
4341 * - \ref SCIP_STAGE_TRANSFORMED
4342 * - \ref SCIP_STAGE_INITPRESOLVE
4343 * - \ref SCIP_STAGE_PRESOLVING
4344 * - \ref SCIP_STAGE_EXITPRESOLVE
4345 * - \ref SCIP_STAGE_INITSOLVE
4346 * - \ref SCIP_STAGE_SOLVING
4347 * - \ref SCIP_STAGE_EXITSOLVE
4348 * - \ref SCIP_STAGE_FREETRANS
4349 */
4351 SCIP* scip, /**< SCIP data structure */
4352 SCIP_VAR* var, /**< problem variable */
4353 SCIP_CONS* cons, /**< constraint */
4354 SCIP_Bool lockdown, /**< should the rounding be locked in downwards direction? */
4355 SCIP_Bool lockup /**< should the rounding be locked in upwards direction? */
4356 )
4357{
4358 int nlocksdown[NLOCKTYPES];
4359 int nlocksup[NLOCKTYPES];
4360 int i;
4361
4362 SCIP_CALL( SCIPcheckStage(scip, "SCIPlockVarCons", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4363
4364 assert( var->scip == scip );
4365
4366 for( i = 0; i < NLOCKTYPES; i++ )
4367 {
4368 nlocksdown[i] = 0;
4369 nlocksup[i] = 0;
4370
4372 {
4373 if( lockdown )
4374 ++nlocksdown[i];
4375 if( lockup )
4376 ++nlocksup[i];
4377 }
4379 {
4380 if( lockdown )
4381 ++nlocksup[i];
4382 if( lockup )
4383 ++nlocksdown[i];
4384 }
4385 }
4386
4387 switch( scip->set->stage )
4388 {
4389 case SCIP_STAGE_PROBLEM:
4391 /*lint -fallthrough*/
4398 case SCIP_STAGE_SOLVING:
4401 for( i = 0; i < NLOCKTYPES; i++ )
4402 {
4403 if( nlocksdown[i] == 0 && nlocksup[i] == 0 )
4404 continue;
4405
4406 SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, (SCIP_LOCKTYPE) i, nlocksdown[i], nlocksup[i]) );
4407 }
4408 return SCIP_OKAY;
4409
4410 default:
4411 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4412 return SCIP_INVALIDCALL;
4413 } /*lint !e788*/
4414}
4415
4416/** remove locks of type @p locktype of variable with respect to the lock status of the constraint and its negation;
4417 * this method should be called whenever the lock status of a variable in a constraint changes, for example if
4418 * the coefficient of the variable changed its sign or if the left or right hand sides of the constraint were
4419 * added or removed
4420 *
4421 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4422 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4423 *
4424 * @pre This method can be called if @p scip is in one of the following stages:
4425 * - \ref SCIP_STAGE_PROBLEM
4426 * - \ref SCIP_STAGE_TRANSFORMING
4427 * - \ref SCIP_STAGE_TRANSFORMED
4428 * - \ref SCIP_STAGE_INITPRESOLVE
4429 * - \ref SCIP_STAGE_PRESOLVING
4430 * - \ref SCIP_STAGE_EXITPRESOLVE
4431 * - \ref SCIP_STAGE_INITSOLVE
4432 * - \ref SCIP_STAGE_SOLVING
4433 * - \ref SCIP_STAGE_EXITSOLVE
4434 * - \ref SCIP_STAGE_FREETRANS
4435 */
4437 SCIP* scip, /**< SCIP data structure */
4438 SCIP_VAR* var, /**< problem variable */
4439 SCIP_CONS* cons, /**< constraint */
4440 SCIP_Bool lockdown, /**< should the rounding be unlocked in downwards direction? */
4441 SCIP_Bool lockup /**< should the rounding be unlocked in upwards direction? */
4442 )
4443{
4444 int nlocksdown[NLOCKTYPES];
4445 int nlocksup[NLOCKTYPES];
4446 int i;
4447
4448 SCIP_CALL( SCIPcheckStage(scip, "SCIPunlockVarCons", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4449
4450 assert( var->scip == scip );
4451
4452 for( i = 0; i < NLOCKTYPES; i++ )
4453 {
4454 nlocksdown[i] = 0;
4455 nlocksup[i] = 0;
4456
4458 {
4459 if( lockdown )
4460 ++nlocksdown[i];
4461 if( lockup )
4462 ++nlocksup[i];
4463 }
4465 {
4466 if( lockdown )
4467 ++nlocksup[i];
4468 if( lockup )
4469 ++nlocksdown[i];
4470 }
4471 }
4472 switch( scip->set->stage )
4473 {
4474 case SCIP_STAGE_PROBLEM:
4476 /*lint -fallthrough*/
4483 case SCIP_STAGE_SOLVING:
4486 for( i = 0; i < NLOCKTYPES; i++ )
4487 {
4488 if( nlocksdown[i] == 0 && nlocksup[i] == 0 )
4489 continue;
4490
4491 SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, (SCIP_LOCKTYPE) i, -nlocksdown[i], -nlocksup[i]) );
4492 }
4493 return SCIP_OKAY;
4494
4495 default:
4496 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4497 return SCIP_INVALIDCALL;
4498 } /*lint !e788*/
4499}
4500
4501/** changes variable's objective value
4502 *
4503 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4504 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4505 *
4506 * @pre This method can be called if @p scip is in one of the following stages:
4507 * - \ref SCIP_STAGE_PROBLEM
4508 * - \ref SCIP_STAGE_TRANSFORMING
4509 * - \ref SCIP_STAGE_PRESOLVING
4510 * - \ref SCIP_STAGE_PRESOLVED
4511 */
4513 SCIP* scip, /**< SCIP data structure */
4514 SCIP_VAR* var, /**< variable to change the objective value for */
4515 SCIP_Real newobj /**< new objective value */
4516 )
4517{
4519
4520 assert( var->scip == scip );
4521
4522 /* forbid infinite objective values */
4524 {
4525 SCIPerrorMessage("invalid objective value: objective value is infinite\n");
4526 return SCIP_INVALIDDATA;
4527 }
4528
4529 switch( scip->set->stage )
4530 {
4531 case SCIP_STAGE_PROBLEM:
4533 SCIP_CALL( SCIPvarChgObj(var, scip->mem->probmem, scip->set, scip->origprob, scip->primal, scip->lp, scip->eventqueue, newobj) );
4534 return SCIP_OKAY;
4535
4540 SCIP_CALL( SCIPvarChgObj(var, scip->mem->probmem, scip->set, scip->transprob, scip->primal, scip->lp, scip->eventqueue, newobj) );
4541 return SCIP_OKAY;
4542
4543 default:
4544 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4545 return SCIP_INVALIDCALL;
4546 } /*lint !e788*/
4547}
4548
4549/** adds value to variable's objective value
4550 *
4551 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4552 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4553 *
4554 * @pre This method can be called if @p scip is in one of the following stages:
4555 * - \ref SCIP_STAGE_PROBLEM
4556 * - \ref SCIP_STAGE_TRANSFORMING
4557 * - \ref SCIP_STAGE_PRESOLVING
4558 * - \ref SCIP_STAGE_EXITPRESOLVE
4559 * - \ref SCIP_STAGE_PRESOLVED
4560 */
4562 SCIP* scip, /**< SCIP data structure */
4563 SCIP_VAR* var, /**< variable to change the objective value for */
4564 SCIP_Real addobj /**< additional objective value */
4565 )
4566{
4568
4569 assert( var->scip == scip );
4570
4571 switch( scip->set->stage )
4572 {
4573 case SCIP_STAGE_PROBLEM:
4575 SCIP_CALL( SCIPvarAddObj(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->primal,
4576 scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue, addobj) );
4577 return SCIP_OKAY;
4578
4583 SCIP_CALL( SCIPvarAddObj(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->primal,
4584 scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue, addobj) );
4585 return SCIP_OKAY;
4586
4587 default:
4588 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4589 return SCIP_INVALIDCALL;
4590 } /*lint !e788*/
4591}
4592
4593/** returns the adjusted (i.e. rounded, if the given variable is of integral type) lower bound value;
4594 * does not change the bounds of the variable
4595 *
4596 * @return adjusted lower bound for the given variable; the bound of the variable is not changed
4597 *
4598 * @pre This method can be called if @p scip is in one of the following stages:
4599 * - \ref SCIP_STAGE_PROBLEM
4600 * - \ref SCIP_STAGE_TRANSFORMING
4601 * - \ref SCIP_STAGE_TRANSFORMED
4602 * - \ref SCIP_STAGE_INITPRESOLVE
4603 * - \ref SCIP_STAGE_PRESOLVING
4604 * - \ref SCIP_STAGE_EXITPRESOLVE
4605 * - \ref SCIP_STAGE_PRESOLVED
4606 * - \ref SCIP_STAGE_INITSOLVE
4607 * - \ref SCIP_STAGE_SOLVING
4608 * - \ref SCIP_STAGE_SOLVED
4609 * - \ref SCIP_STAGE_EXITSOLVE
4610 * - \ref SCIP_STAGE_FREETRANS
4611 */
4613 SCIP* scip, /**< SCIP data structure */
4614 SCIP_VAR* var, /**< variable to adjust the bound for */
4615 SCIP_Real lb /**< lower bound value to adjust */
4616 )
4617{
4618 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPadjustedVarLb", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
4619
4620 SCIPvarAdjustLb(var, scip->set, &lb);
4621
4622 return lb;
4623}
4624
4625/** returns the adjusted (i.e. rounded, if the given variable is of integral type) upper bound value;
4626 * does not change the bounds of the variable
4627 *
4628 * @return adjusted upper bound for the given variable; the bound of the variable is not changed
4629 *
4630 * @pre This method can be called if @p scip is in one of the following stages:
4631 * - \ref SCIP_STAGE_PROBLEM
4632 * - \ref SCIP_STAGE_TRANSFORMING
4633 * - \ref SCIP_STAGE_TRANSFORMED
4634 * - \ref SCIP_STAGE_INITPRESOLVE
4635 * - \ref SCIP_STAGE_PRESOLVING
4636 * - \ref SCIP_STAGE_EXITPRESOLVE
4637 * - \ref SCIP_STAGE_PRESOLVED
4638 * - \ref SCIP_STAGE_INITSOLVE
4639 * - \ref SCIP_STAGE_SOLVING
4640 * - \ref SCIP_STAGE_SOLVED
4641 * - \ref SCIP_STAGE_EXITSOLVE
4642 * - \ref SCIP_STAGE_FREETRANS
4643 */
4645 SCIP* scip, /**< SCIP data structure */
4646 SCIP_VAR* var, /**< variable to adjust the bound for */
4647 SCIP_Real ub /**< upper bound value to adjust */
4648 )
4649{
4650 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPadjustedVarUb", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
4651
4652 SCIPvarAdjustUb(var, scip->set, &ub);
4653
4654 return ub;
4655}
4656
4657/** depending on SCIP's stage, changes lower bound of variable in the problem, in preprocessing, or in current node;
4658 * if possible, adjusts bound to integral value; doesn't store any inference information in the bound change, such
4659 * that in conflict analysis, this change is treated like a branching decision
4660 *
4661 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4662 * SCIPgetVars()) gets resorted.
4663 *
4664 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4665 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4666 *
4667 * @pre This method can be called if @p scip is in one of the following stages:
4668 * - \ref SCIP_STAGE_PROBLEM
4669 * - \ref SCIP_STAGE_TRANSFORMING
4670 * - \ref SCIP_STAGE_PRESOLVING
4671 * - \ref SCIP_STAGE_SOLVING
4672 *
4673 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4674 */
4676 SCIP* scip, /**< SCIP data structure */
4677 SCIP_VAR* var, /**< variable to change the bound for */
4678 SCIP_Real newbound /**< new value for bound */
4679 )
4680{
4682
4683 SCIPvarAdjustLb(var, scip->set, &newbound);
4684
4685 /* ignore tightenings of lower bounds to +infinity during solving process */
4687 {
4688#ifndef NDEBUG
4689 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4691#endif
4692 return SCIP_OKAY;
4693 }
4694
4695 switch( scip->set->stage )
4696 {
4697 case SCIP_STAGE_PROBLEM:
4699 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4700 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4701 SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4702 scip->branchcand, scip->eventqueue, newbound) );
4703 SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
4704 break;
4705
4708 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4709 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4710 break;
4711
4713 if( !SCIPinProbing(scip) )
4714 {
4715 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4716 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4717
4718 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4719 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable,
4720 var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
4721
4723 {
4724 SCIP_Bool infeasible;
4725
4727 assert(!infeasible);
4728 }
4729 break;
4730 }
4731 /*lint -fallthrough*/
4732 case SCIP_STAGE_SOLVING:
4733 SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
4734 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4735 scip->cliquetable, var, newbound,
4737 break;
4738
4739 default:
4740 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4741 return SCIP_INVALIDCALL;
4742 } /*lint !e788*/
4743
4744 return SCIP_OKAY;
4745}
4746
4747/** depending on SCIP's stage, changes upper bound of variable in the problem, in preprocessing, or in current node;
4748 * if possible, adjusts bound to integral value; doesn't store any inference information in the bound change, such
4749 * that in conflict analysis, this change is treated like a branching decision
4750 *
4751 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4752 * SCIPgetVars()) gets resorted.
4753 *
4754 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4755 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4756 *
4757 * @pre This method can be called if @p scip is in one of the following stages:
4758 * - \ref SCIP_STAGE_PROBLEM
4759 * - \ref SCIP_STAGE_TRANSFORMING
4760 * - \ref SCIP_STAGE_PRESOLVING
4761 * - \ref SCIP_STAGE_SOLVING
4762 *
4763 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4764 */
4766 SCIP* scip, /**< SCIP data structure */
4767 SCIP_VAR* var, /**< variable to change the bound for */
4768 SCIP_Real newbound /**< new value for bound */
4769 )
4770{
4772
4773 SCIPvarAdjustUb(var, scip->set, &newbound);
4774
4775 /* ignore tightenings of upper bounds to -infinity during solving process */
4776 if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4777 {
4778#ifndef NDEBUG
4779 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
4781#endif
4782 return SCIP_OKAY;
4783 }
4784
4785 switch( scip->set->stage )
4786 {
4787 case SCIP_STAGE_PROBLEM:
4789 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4790 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4791 SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4792 scip->branchcand, scip->eventqueue, newbound) );
4793 SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
4794 break;
4795
4798 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4799 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4800 break;
4801
4803 if( !SCIPinProbing(scip) )
4804 {
4805 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4806 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4807
4808 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4809 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4810 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
4811
4813 {
4814 SCIP_Bool infeasible;
4815
4817 assert(!infeasible);
4818 }
4819 break;
4820 }
4821 /*lint -fallthrough*/
4822 case SCIP_STAGE_SOLVING:
4823 SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
4824 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4825 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
4826 break;
4827
4828 default:
4829 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4830 return SCIP_INVALIDCALL;
4831 } /*lint !e788*/
4832
4833 return SCIP_OKAY;
4834}
4835
4836/** changes lower bound of variable in the given node; if possible, adjust bound to integral value; doesn't store any
4837 * inference information in the bound change, such that in conflict analysis, this change is treated like a branching
4838 * decision
4839 *
4840 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4841 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4842 *
4843 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
4844 */
4846 SCIP* scip, /**< SCIP data structure */
4847 SCIP_NODE* node, /**< node to change bound at, or NULL for current node */
4848 SCIP_VAR* var, /**< variable to change the bound for */
4849 SCIP_Real newbound /**< new value for bound */
4850 )
4851{
4853
4854 if( node == NULL )
4855 {
4856 SCIP_CALL( SCIPchgVarLb(scip, var, newbound) );
4857 }
4858 else
4859 {
4860 SCIPvarAdjustLb(var, scip->set, &newbound);
4861
4862 /* ignore tightenings of lower bounds to +infinity during solving process */
4864 {
4865#ifndef NDEBUG
4866 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4868#endif
4869 return SCIP_OKAY;
4870 }
4871
4872 SCIP_CALL( SCIPnodeAddBoundchg(node, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
4873 scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4875 }
4876
4877 return SCIP_OKAY;
4878}
4879
4880/** changes upper bound of variable in the given node; if possible, adjust bound to integral value; doesn't store any
4881 * inference information in the bound change, such that in conflict analysis, this change is treated like a branching
4882 * decision
4883 *
4884 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4885 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4886 *
4887 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
4888 */
4890 SCIP* scip, /**< SCIP data structure */
4891 SCIP_NODE* node, /**< node to change bound at, or NULL for current node */
4892 SCIP_VAR* var, /**< variable to change the bound for */
4893 SCIP_Real newbound /**< new value for bound */
4894 )
4895{
4897
4898 if( node == NULL )
4899 {
4900 SCIP_CALL( SCIPchgVarUb(scip, var, newbound) );
4901 }
4902 else
4903 {
4904 SCIPvarAdjustUb(var, scip->set, &newbound);
4905
4906 /* ignore tightenings of upper bounds to -infinity during solving process */
4907 if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4908 {
4909#ifndef NDEBUG
4910 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
4912#endif
4913 return SCIP_OKAY;
4914 }
4915
4916 SCIP_CALL( SCIPnodeAddBoundchg(node, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
4917 scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4919 }
4920
4921 return SCIP_OKAY;
4922}
4923
4924/** changes global lower bound of variable; if possible, adjust bound to integral value; also tightens the local bound,
4925 * if the global bound is better than the local bound
4926 *
4927 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4928 * SCIPgetVars()) gets resorted.
4929 *
4930 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4931 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4932 *
4933 * @pre This method can be called if @p scip is in one of the following stages:
4934 * - \ref SCIP_STAGE_PROBLEM
4935 * - \ref SCIP_STAGE_TRANSFORMING
4936 * - \ref SCIP_STAGE_TRANSFORMED
4937 * - \ref SCIP_STAGE_PRESOLVING
4938 * - \ref SCIP_STAGE_SOLVING
4939 *
4940 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4941 */
4943 SCIP* scip, /**< SCIP data structure */
4944 SCIP_VAR* var, /**< variable to change the bound for */
4945 SCIP_Real newbound /**< new value for bound */
4946 )
4947{
4948 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbGlobal", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4949
4950 SCIPvarAdjustLb(var, scip->set, &newbound);
4951
4952 /* ignore tightenings of lower bounds to +infinity during solving process */
4954 {
4955#ifndef NDEBUG
4956 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4958#endif
4959 return SCIP_OKAY;
4960 }
4961
4962 switch( scip->set->stage )
4963 {
4964 case SCIP_STAGE_PROBLEM:
4966 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4967 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4968 SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4969 scip->branchcand, scip->eventqueue, newbound) );
4970 SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
4971 break;
4972
4975 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4976 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4977 break;
4978
4980 if( !SCIPinProbing(scip) )
4981 {
4982 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4983 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4984
4985 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4986 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4988
4990 {
4991 SCIP_Bool infeasible;
4992
4994 assert(!infeasible);
4995 }
4996 break;
4997 }
4998 /*lint -fallthrough*/
4999 case SCIP_STAGE_SOLVING:
5000 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5001 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5003 break;
5004
5005 default:
5006 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5007 return SCIP_INVALIDCALL;
5008 } /*lint !e788*/
5009
5010 return SCIP_OKAY;
5011}
5012
5013/** changes global upper bound of variable; if possible, adjust bound to integral value; also tightens the local bound,
5014 * if the global bound is better than the local bound
5015 *
5016 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5017 * SCIPgetVars()) gets resorted.
5018 *
5019 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5020 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5021 *
5022 * @pre This method can be called if @p scip is in one of the following stages:
5023 * - \ref SCIP_STAGE_PROBLEM
5024 * - \ref SCIP_STAGE_TRANSFORMING
5025 * - \ref SCIP_STAGE_TRANSFORMED
5026 * - \ref SCIP_STAGE_PRESOLVING
5027 * - \ref SCIP_STAGE_SOLVING
5028 *
5029 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5030 */
5032 SCIP* scip, /**< SCIP data structure */
5033 SCIP_VAR* var, /**< variable to change the bound for */
5034 SCIP_Real newbound /**< new value for bound */
5035 )
5036{
5037 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbGlobal", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5038
5039 SCIPvarAdjustUb(var, scip->set, &newbound);
5040
5041 /* ignore tightenings of upper bounds to -infinity during solving process */
5042 if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5043 {
5044#ifndef NDEBUG
5045 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5047#endif
5048 return SCIP_OKAY;
5049 }
5050
5051 switch( scip->set->stage )
5052 {
5053 case SCIP_STAGE_PROBLEM:
5055 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5056 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5057 SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5058 scip->branchcand, scip->eventqueue, newbound) );
5059 SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
5060 break;
5061
5064 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5065 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5066 break;
5067
5069 if( !SCIPinProbing(scip) )
5070 {
5071 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5072 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5073
5074 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5075 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5077
5079 {
5080 SCIP_Bool infeasible;
5081
5083 assert(!infeasible);
5084 }
5085 break;
5086 }
5087 /*lint -fallthrough*/
5088 case SCIP_STAGE_SOLVING:
5089 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5090 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5092 break;
5093
5094 default:
5095 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5096 return SCIP_INVALIDCALL;
5097 } /*lint !e788*/
5098
5099 return SCIP_OKAY;
5100}
5101
5102/** changes lazy lower bound of the variable, this is only possible if the variable is not in the LP yet
5103 *
5104 * Lazy bounds are bounds that are already enforced by constraints and the objective function.
5105 * Setting a lazy lower bound has the consequence that for variables which lower bound equals the lazy lower bound,
5106 * the lower bound does not need to be passed on to the LP solver.
5107 * This is especially useful in a column generation (branch-and-price) setting.
5108 *
5109 * @attention If the variable has a global lower bound below lazylb, then the global lower bound is tightened to
5110 * lazylb by a call to SCIPchgVarLbGlobal().
5111 *
5112 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5113 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5114 *
5115 * @pre This method can be called if @p scip is in one of the following stages:
5116 * - \ref SCIP_STAGE_PROBLEM
5117 * - \ref SCIP_STAGE_TRANSFORMING
5118 * - \ref SCIP_STAGE_TRANSFORMED
5119 * - \ref SCIP_STAGE_PRESOLVING
5120 * - \ref SCIP_STAGE_SOLVING
5121 */
5123 SCIP* scip, /**< SCIP data structure */
5124 SCIP_VAR* var, /**< problem variable */
5125 SCIP_Real lazylb /**< the lazy lower bound to be set */
5126 )
5127{
5128 assert(scip != NULL);
5129 assert(var != NULL);
5130
5132
5133 if( SCIPisGT(scip, lazylb, SCIPvarGetLbGlobal(var)) )
5134 {
5135 SCIP_CALL( SCIPchgVarLbGlobal(scip, var, lazylb) );
5136 }
5137
5138 SCIP_CALL( SCIPvarChgLbLazy(var, scip->set, lazylb) );
5139
5140 return SCIP_OKAY;
5141}
5142
5143/** changes lazy upper bound of the variable, this is only possible if the variable is not in the LP yet
5144 *
5145 * Lazy bounds are bounds that are already enforced by constraints and the objective function.
5146 * Setting a lazy upper bound has the consequence that for variables which upper bound equals the lazy upper bound,
5147 * the upper bound does not need to be passed on to the LP solver.
5148 * This is especially useful in a column generation (branch-and-price) setting.
5149 *
5150 * @attention If the variable has a global upper bound above lazyub, then the global upper bound is tightened to
5151 * lazyub by a call to SCIPchgVarUbGlobal().
5152 *
5153 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5154 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5155 *
5156 * @pre This method can be called if @p scip is in one of the following stages:
5157 * - \ref SCIP_STAGE_PROBLEM
5158 * - \ref SCIP_STAGE_TRANSFORMING
5159 * - \ref SCIP_STAGE_TRANSFORMED
5160 * - \ref SCIP_STAGE_PRESOLVING
5161 * - \ref SCIP_STAGE_SOLVING
5162 */
5164 SCIP* scip, /**< SCIP data structure */
5165 SCIP_VAR* var, /**< problem variable */
5166 SCIP_Real lazyub /**< the lazy lower bound to be set */
5167 )
5168{
5169 assert(scip != NULL);
5170 assert(var != NULL);
5171
5173
5174 if( SCIPisLT(scip, lazyub, SCIPvarGetUbGlobal(var)) )
5175 {
5176 SCIP_CALL( SCIPchgVarUbGlobal(scip, var, lazyub) );
5177 }
5178
5179 SCIP_CALL( SCIPvarChgUbLazy(var, scip->set, lazyub) );
5180
5181 return SCIP_OKAY;
5182}
5183
5184/** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
5185 * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5186 * doesn't store any inference information in the bound change, such that in conflict analysis, this change
5187 * is treated like a branching decision
5188 *
5189 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5190 * SCIPgetVars()) gets resorted.
5191 *
5192 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5193 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5194 *
5195 * @pre This method can be called if @p scip is in one of the following stages:
5196 * - \ref SCIP_STAGE_PROBLEM
5197 * - \ref SCIP_STAGE_PRESOLVING
5198 * - \ref SCIP_STAGE_SOLVING
5199 *
5200 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5201 */
5203 SCIP* scip, /**< SCIP data structure */
5204 SCIP_VAR* var, /**< variable to change the bound for */
5205 SCIP_Real newbound, /**< new value for bound */
5206 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5207 SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
5208 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5209 )
5210{
5211 SCIP_Real lb;
5212 SCIP_Real ub;
5213
5214 assert(infeasible != NULL);
5215
5217 /** @todo if needed provide pending local/global bound changes that will be flushed after leaving diving mode (as in struct_tree.h) */
5219
5220 *infeasible = FALSE;
5221 if( tightened != NULL )
5222 *tightened = FALSE;
5223
5224 SCIPvarAdjustLb(var, scip->set, &newbound);
5225
5226 /* ignore tightenings of lower bounds to +infinity during solving process */
5228 {
5229#ifndef NDEBUG
5230 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
5232#endif
5233 return SCIP_OKAY;
5234 }
5235
5236 /* get current bounds */
5239 assert(SCIPsetIsLE(scip->set, lb, ub));
5240
5241 if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
5242 {
5243 *infeasible = TRUE;
5244 return SCIP_OKAY;
5245 }
5246 newbound = MIN(newbound, ub);
5247
5248 if( (force && SCIPsetIsLE(scip->set, newbound, lb)) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
5249 return SCIP_OKAY;
5250
5251 switch( scip->set->stage )
5252 {
5253 case SCIP_STAGE_PROBLEM:
5255 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5256 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5257 SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5258 scip->branchcand, scip->eventqueue, newbound) );
5259 SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
5260 break;
5262 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5263 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5264 break;
5266 if( !SCIPinProbing(scip) )
5267 {
5268 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5269 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5270
5271 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5272 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5274
5276 {
5278 assert(!(*infeasible));
5279 }
5280 break;
5281 }
5282 /*lint -fallthrough*/
5283 case SCIP_STAGE_SOLVING:
5284 SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
5285 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable,
5286 var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
5287 break;
5288
5289 default:
5290 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5291 return SCIP_INVALIDCALL;
5292 } /*lint !e788*/
5293
5294 /* check whether the lower bound improved */
5295 if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
5296 *tightened = TRUE;
5297
5298 return SCIP_OKAY;
5299}
5300
5301/** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
5302 * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5303 * doesn't store any inference information in the bound change, such that in conflict analysis, this change
5304 * is treated like a branching decision
5305 *
5306 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5307 * SCIPgetVars()) gets resorted.
5308 *
5309 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5310 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5311 *
5312 * @pre This method can be called if @p scip is in one of the following stages:
5313 * - \ref SCIP_STAGE_PROBLEM
5314 * - \ref SCIP_STAGE_PRESOLVING
5315 * - \ref SCIP_STAGE_SOLVING
5316 *
5317 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5318 */
5320 SCIP* scip, /**< SCIP data structure */
5321 SCIP_VAR* var, /**< variable to change the bound for */
5322 SCIP_Real newbound, /**< new value for bound */
5323 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5324 SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
5325 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5326 )
5327{
5328 SCIP_Real lb;
5329 SCIP_Real ub;
5330
5331 assert(infeasible != NULL);
5333
5334 /** @todo if needed provide pending local/global bound changes that will be flushed after leaving diving mode (as in struct_tree.h) */
5336
5337 *infeasible = FALSE;
5338 if( tightened != NULL )
5339 *tightened = FALSE;
5340
5341 SCIPvarAdjustUb(var, scip->set, &newbound);
5342
5343 /* ignore tightenings of upper bounds to -infinity during solving process */
5344 if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5345 {
5346#ifndef NDEBUG
5347 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5349#endif
5350 return SCIP_OKAY;
5351 }
5352
5353 /* get current bounds */
5356 assert(SCIPsetIsLE(scip->set, lb, ub));
5357
5358 if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
5359 {
5360 *infeasible = TRUE;
5361 return SCIP_OKAY;
5362 }
5363 newbound = MAX(newbound, lb);
5364
5365 if( (force && SCIPsetIsGE(scip->set, newbound, ub)) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
5366 return SCIP_OKAY;
5367
5368 switch( scip->set->stage )
5369 {
5370 case SCIP_STAGE_PROBLEM:
5372 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5373 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5374 SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5375 scip->branchcand, scip->eventqueue, newbound) );
5376 SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
5377 break;
5379 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5380 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5381 break;
5383 if( !SCIPinProbing(scip) )
5384 {
5385 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5386 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5387
5388 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5389 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5391
5393 {
5395 assert(!(*infeasible));
5396 }
5397 break;
5398 }
5399 /*lint -fallthrough*/
5400 case SCIP_STAGE_SOLVING:
5401 SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
5402 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5403 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
5404 break;
5405
5406 default:
5407 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5408 return SCIP_INVALIDCALL;
5409 } /*lint !e788*/
5410
5411 /* check whether the upper bound improved */
5412 if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
5413 *tightened = TRUE;
5414
5415 return SCIP_OKAY;
5416}
5417
5418/** fixes variable in preprocessing or in the current node, if the new bound is tighter (w.r.t. bound strengthening
5419 * epsilon) than the current bound; if possible, adjusts bound to integral value; the given inference constraint is
5420 * stored, such that the conflict analysis is able to find out the reason for the deduction of the bound change
5421 *
5422 * @note In presolving stage when not in probing mode the variable will be fixed directly, otherwise this method
5423 * changes first the lowerbound by calling SCIPinferVarLbCons and second the upperbound by calling
5424 * SCIPinferVarUbCons
5425 *
5426 * @note If SCIP is in presolving stage, it can happen that the internal variable array (which get be accessed via
5427 * SCIPgetVars()) gets resorted.
5428 *
5429 * @note During presolving, an integer variable which bound changes to {0,1} is upgraded to a binary variable.
5430 */
5432 SCIP* scip, /**< SCIP data structure */
5433 SCIP_VAR* var, /**< variable to change the bound for */
5434 SCIP_Real fixedval, /**< new value for fixation */
5435 SCIP_CONS* infercons, /**< constraint that deduced the bound change */
5436 int inferinfo, /**< user information for inference to help resolving the conflict */
5437 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5438 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5439 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5440 )
5441{
5442 assert(scip != NULL);
5443 assert(var != NULL);
5444 assert(infeasible != NULL);
5445
5446 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarFixCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5447
5448 if( tightened != NULL )
5449 *tightened = FALSE;
5450
5451 /* in presolving case we take the shortcut to directly fix the variables */
5453 {
5454 SCIP_Bool fixed;
5455
5456 SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5457 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter,
5458 scip->eventqueue, scip->cliquetable, fixedval, infeasible, &fixed) );
5459
5460 if( tightened != NULL )
5461 *tightened = fixed;
5462 }
5463 /* otherwise we use the lb and ub methods */
5464 else
5465 {
5466 SCIP_Bool lbtightened;
5467
5468 SCIP_CALL( SCIPinferVarLbCons(scip, var, fixedval, infercons, inferinfo, force, infeasible, &lbtightened) );
5469
5470 if( ! (*infeasible) )
5471 {
5472 SCIP_CALL( SCIPinferVarUbCons(scip, var, fixedval, infercons, inferinfo, force, infeasible, tightened) );
5473
5474 if( tightened != NULL )
5475 *tightened |= lbtightened;
5476 }
5477 }
5478
5479 return SCIP_OKAY;
5480}
5481
5482/** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
5483 * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5484 * the given inference constraint is stored, such that the conflict analysis is able to find out the reason
5485 * for the deduction of the bound change
5486 *
5487 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5488 * SCIPgetVars()) gets resorted.
5489 *
5490 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5491 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5492 *
5493 * @pre This method can be called if @p scip is in one of the following stages:
5494 * - \ref SCIP_STAGE_PROBLEM
5495 * - \ref SCIP_STAGE_PRESOLVING
5496 * - \ref SCIP_STAGE_SOLVING
5497 *
5498 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5499 */
5501 SCIP* scip, /**< SCIP data structure */
5502 SCIP_VAR* var, /**< variable to change the bound for */
5503 SCIP_Real newbound, /**< new value for bound */
5504 SCIP_CONS* infercons, /**< constraint that deduced the bound change */
5505 int inferinfo, /**< user information for inference to help resolving the conflict */
5506 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5507 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5508 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5509 )
5510{
5511 SCIP_Real lb;
5512 SCIP_Real ub;
5513
5514 assert(infeasible != NULL);
5515
5516 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarLbCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5517
5518 *infeasible = FALSE;
5519 if( tightened != NULL )
5520 *tightened = FALSE;
5521
5522 SCIPvarAdjustLb(var, scip->set, &newbound);
5523
5524 /* ignore tightenings of lower bounds to +infinity during solving process */
5526 {
5527#ifndef NDEBUG
5528 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
5530#endif
5531 return SCIP_OKAY;
5532 }
5533
5534 /* get current bounds */
5535 lb = SCIPvarGetLbLocal(var);
5536 ub = SCIPvarGetUbLocal(var);
5537 assert(SCIPsetIsLE(scip->set, lb, ub));
5538
5539 if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
5540 {
5541 *infeasible = TRUE;
5542 return SCIP_OKAY;
5543 }
5544 newbound = MIN(newbound, ub);
5545
5546 if( (force && SCIPsetIsLE(scip->set, newbound, lb)) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
5547 return SCIP_OKAY;
5548
5549 switch( scip->set->stage )
5550 {
5551 case SCIP_STAGE_PROBLEM:
5553 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5554 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5555 SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5556 scip->branchcand, scip->eventqueue, newbound) );
5557 SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
5558 break;
5559
5561 if( !SCIPinProbing(scip) )
5562 {
5563 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5564 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5565
5566 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5567 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5569
5571 {
5573 assert(!(*infeasible));
5574 }
5575 break;
5576 }
5577 /*lint -fallthrough*/
5578 case SCIP_STAGE_SOLVING:
5579 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
5580 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5581 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, infercons, NULL, inferinfo, FALSE) );
5582 break;
5583
5584 default:
5585 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5586 return SCIP_INVALIDCALL;
5587 } /*lint !e788*/
5588
5589 /* check whether the lower bound improved */
5590 if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
5591 *tightened = TRUE;
5592
5593 return SCIP_OKAY;
5594}
5595
5596/** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
5597 * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5598 * the given inference constraint is stored, such that the conflict analysis is able to find out the reason
5599 * for the deduction of the bound change
5600 *
5601 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5602 * SCIPgetVars()) gets resorted.
5603 *
5604 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5605 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5606 *
5607 * @pre This method can be called if @p scip is in one of the following stages:
5608 * - \ref SCIP_STAGE_PROBLEM
5609 * - \ref SCIP_STAGE_PRESOLVING
5610 * - \ref SCIP_STAGE_SOLVING
5611 *
5612 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5613 */
5615 SCIP* scip, /**< SCIP data structure */
5616 SCIP_VAR* var, /**< variable to change the bound for */
5617 SCIP_Real newbound, /**< new value for bound */
5618 SCIP_CONS* infercons, /**< constraint that deduced the bound change */
5619 int inferinfo, /**< user information for inference to help resolving the conflict */
5620 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5621 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5622 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5623 )
5624{
5625 SCIP_Real lb;
5626 SCIP_Real ub;
5627
5628 assert(infeasible != NULL);
5629
5630 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarUbCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5631
5632 *infeasible = FALSE;
5633 if( tightened != NULL )
5634 *tightened = FALSE;
5635
5636 SCIPvarAdjustUb(var, scip->set, &newbound);
5637
5638 /* ignore tightenings of upper bounds to -infinity during solving process */
5639 if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5640 {
5641#ifndef NDEBUG
5642 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5644#endif
5645 return SCIP_OKAY;
5646 }
5647
5648 /* get current bounds */
5649 lb = SCIPvarGetLbLocal(var);
5650 ub = SCIPvarGetUbLocal(var);
5651 assert(SCIPsetIsLE(scip->set, lb, ub));
5652
5653 if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
5654 {
5655 *infeasible = TRUE;
5656 return SCIP_OKAY;
5657 }
5658 newbound = MAX(newbound, lb);
5659
5660 if( (force && SCIPsetIsGE(scip->set, newbound, ub)) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
5661 return SCIP_OKAY;
5662
5663 switch( scip->set->stage )
5664 {
5665 case SCIP_STAGE_PROBLEM:
5667 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5668 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5669 SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5670 scip->branchcand, scip->eventqueue, newbound) );
5671 SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
5672 break;
5673
5675 if( !SCIPinProbing(scip) )
5676 {
5677 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5678 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5679
5680 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5681 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5683
5685 {
5687 assert(!(*infeasible));
5688 }
5689 break;
5690 }
5691 /*lint -fallthrough*/
5692 case SCIP_STAGE_SOLVING:
5693 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
5694 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5695 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, infercons, NULL, inferinfo, FALSE) );
5696 break;
5697
5698 default:
5699 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5700 return SCIP_INVALIDCALL;
5701 } /*lint !e788*/
5702
5703 /* check whether the upper bound improved */
5704 if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
5705 *tightened = TRUE;
5706
5707 return SCIP_OKAY;
5708}
5709
5710/** depending on SCIP's stage, fixes binary variable in the problem, in preprocessing, or in current node;
5711 * the given inference constraint is stored, such that the conflict analysis is able to find out the reason for the
5712 * deduction of the fixing
5713 *
5714 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5715 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5716 *
5717 * @pre This method can be called if @p scip is in one of the following stages:
5718 * - \ref SCIP_STAGE_PROBLEM
5719 * - \ref SCIP_STAGE_PRESOLVING
5720 * - \ref SCIP_STAGE_SOLVING
5721 */
5723 SCIP* scip, /**< SCIP data structure */
5724 SCIP_VAR* var, /**< binary variable to fix */
5725 SCIP_Bool fixedval, /**< value to fix binary variable to */
5726 SCIP_CONS* infercons, /**< constraint that deduced the fixing */
5727 int inferinfo, /**< user information for inference to help resolving the conflict */
5728 SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
5729 SCIP_Bool* tightened /**< pointer to store whether the fixing tightened the local bounds, or NULL */
5730 )
5731{
5732 SCIP_Real lb;
5733 SCIP_Real ub;
5734
5736 assert(fixedval == TRUE || fixedval == FALSE);
5737 assert(infeasible != NULL);
5738
5739 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferBinvarCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5740
5741 *infeasible = FALSE;
5742 if( tightened != NULL )
5743 *tightened = FALSE;
5744
5745 /* get current bounds */
5746 lb = SCIPvarGetLbLocal(var);
5747 ub = SCIPvarGetUbLocal(var);
5748 assert(SCIPsetIsEQ(scip->set, lb, 0.0) || SCIPsetIsEQ(scip->set, lb, 1.0));
5749 assert(SCIPsetIsEQ(scip->set, ub, 0.0) || SCIPsetIsEQ(scip->set, ub, 1.0));
5750 assert(SCIPsetIsLE(scip->set, lb, ub));
5751
5752 /* check, if variable is already fixed */
5753 if( (lb > 0.5) || (ub < 0.5) )
5754 {
5755 *infeasible = (fixedval == (lb < 0.5));
5756
5757 return SCIP_OKAY;
5758 }
5759
5760 /* apply the fixing */
5761 switch( scip->set->stage )
5762 {
5763 case SCIP_STAGE_PROBLEM:
5765 if( fixedval == TRUE )
5766 {
5767 SCIP_CALL( SCIPchgVarLb(scip, var, 1.0) );
5768 }
5769 else
5770 {
5771 SCIP_CALL( SCIPchgVarUb(scip, var, 0.0) );
5772 }
5773 break;
5774
5776 if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
5777 {
5778 SCIP_Bool fixed;
5779
5780 SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5781 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
5782 scip->cliquetable, (SCIP_Real)fixedval, infeasible, &fixed) );
5783 break;
5784 }
5785 /*lint -fallthrough*/
5786 case SCIP_STAGE_SOLVING:
5787 if( fixedval == TRUE )
5788 {
5789 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
5790 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5791 scip->cliquetable, var, 1.0, SCIP_BOUNDTYPE_LOWER, infercons, NULL, inferinfo, FALSE) );
5792 }
5793 else
5794 {
5795 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
5796 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5797 scip->cliquetable, var, 0.0, SCIP_BOUNDTYPE_UPPER, infercons, NULL, inferinfo, FALSE) );
5798 }
5799 break;
5800
5801 default:
5802 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5803 return SCIP_INVALIDCALL;
5804 } /*lint !e788*/
5805
5806 if( tightened != NULL )
5807 *tightened = TRUE;
5808
5809 return SCIP_OKAY;
5810}
5811
5812/** fixes variable in preprocessing or in the current node, if the new bound is tighter (w.r.t. bound strengthening
5813 * epsilon) than the current bound; if possible, adjusts bound to integral value; the given inference constraint is
5814 * stored, such that the conflict analysis is able to find out the reason for the deduction of the bound change
5815 *
5816 * @note In presolving stage when not in probing mode the variable will be fixed directly, otherwise this method
5817 * changes first the lowerbound by calling SCIPinferVarLbProp and second the upperbound by calling
5818 * SCIPinferVarUbProp
5819 *
5820 * @note If SCIP is in presolving stage, it can happen that the internal variable array (which get be accessed via
5821 * SCIPgetVars()) gets resorted.
5822 *
5823 * @note During presolving, an integer variable which bound changes to {0,1} is upgraded to a binary variable.
5824 */
5826 SCIP* scip, /**< SCIP data structure */
5827 SCIP_VAR* var, /**< variable to change the bound for */
5828 SCIP_Real fixedval, /**< new value for fixation */
5829 SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
5830 int inferinfo, /**< user information for inference to help resolving the conflict */
5831 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5832 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5833 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5834 )
5835{
5836 assert(scip != NULL);
5837 assert(var != NULL);
5838 assert(infeasible != NULL);
5839
5840 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarFixProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5841
5842 if( tightened != NULL )
5843 *tightened = FALSE;
5844
5845 /* in presolving case we take the shortcut to directly fix the variables */
5847 {
5848 SCIP_Bool fixed;
5849
5850 SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5851 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
5852 scip->cliquetable, fixedval, infeasible, &fixed) );
5853
5854 if( tightened != NULL )
5855 *tightened = fixed;
5856 }
5857 /* otherwise we use the lb and ub methods */
5858 else
5859 {
5860 SCIP_Bool lbtightened;
5861
5862 SCIP_CALL( SCIPinferVarLbProp(scip, var, fixedval, inferprop, inferinfo, force, infeasible, &lbtightened) );
5863
5864 if( ! (*infeasible) )
5865 {
5866 SCIP_CALL( SCIPinferVarUbProp(scip, var, fixedval, inferprop, inferinfo, force, infeasible, tightened) );
5867
5868 if( tightened != NULL )
5869 *tightened |= lbtightened;
5870 }
5871 }
5872
5873 return SCIP_OKAY;
5874}
5875
5876/** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
5877 * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5878 * the given inference propagator is stored, such that the conflict analysis is able to find out the reason
5879 * for the deduction of the bound change
5880 *
5881 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5882 * SCIPgetVars()) gets resorted.
5883 *
5884 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5885 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5886 *
5887 * @pre This method can be called if @p scip is in one of the following stages:
5888 * - \ref SCIP_STAGE_PROBLEM
5889 * - \ref SCIP_STAGE_PRESOLVING
5890 * - \ref SCIP_STAGE_SOLVING
5891 *
5892 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5893 */
5895 SCIP* scip, /**< SCIP data structure */
5896 SCIP_VAR* var, /**< variable to change the bound for */
5897 SCIP_Real newbound, /**< new value for bound */
5898 SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
5899 int inferinfo, /**< user information for inference to help resolving the conflict */
5900 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5901 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5902 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5903 )
5904{
5905 SCIP_Real lb;
5906 SCIP_Real ub;
5907
5908 assert(infeasible != NULL);
5909
5910 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarLbProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5911
5912 *infeasible = FALSE;
5913 if( tightened != NULL )
5914 *tightened = FALSE;
5915
5916 SCIPvarAdjustLb(var, scip->set, &newbound);
5917
5918 /* ignore tightenings of lower bounds to +infinity during solving process */
5920 {
5921#ifndef NDEBUG
5922 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
5924#endif
5925 return SCIP_OKAY;
5926 }
5927
5928 /* get current bounds */
5929 lb = SCIPvarGetLbLocal(var);
5930 ub = SCIPvarGetUbLocal(var);
5931 assert(SCIPsetIsLE(scip->set, lb, ub));
5932
5933 if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
5934 {
5935 *infeasible = TRUE;
5936 return SCIP_OKAY;
5937 }
5938 newbound = MIN(newbound, ub);
5939
5940 if( (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub))
5941 || SCIPsetIsLE(scip->set, newbound, lb) )
5942 return SCIP_OKAY;
5943
5944 switch( scip->set->stage )
5945 {
5946 case SCIP_STAGE_PROBLEM:
5948 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5949 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5950 SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5951 scip->branchcand, scip->eventqueue, newbound) );
5952 SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
5953 break;
5954
5956 if( !SCIPinProbing(scip) )
5957 {
5958 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5959 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5960
5961 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5962 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5964
5966 {
5968 assert(!(*infeasible));
5969 }
5970 break;
5971 }
5972 /*lint -fallthrough*/
5973 case SCIP_STAGE_SOLVING:
5974 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
5975 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5976 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, NULL, inferprop, inferinfo, FALSE) );
5977 break;
5978
5979 default:
5980 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5981 return SCIP_INVALIDCALL;
5982 } /*lint !e788*/
5983
5984 /* check whether the lower bound improved */
5985 if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
5986 *tightened = TRUE;
5987
5988 return SCIP_OKAY;
5989}
5990
5991/** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
5992 * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5993 * the given inference propagator is stored, such that the conflict analysis is able to find out the reason
5994 * for the deduction of the bound change
5995 *
5996 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5997 * SCIPgetVars()) gets resorted.
5998 *
5999 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6000 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6001 *
6002 * @pre This method can be called if @p scip is in one of the following stages:
6003 * - \ref SCIP_STAGE_PROBLEM
6004 * - \ref SCIP_STAGE_PRESOLVING
6005 * - \ref SCIP_STAGE_SOLVING
6006 *
6007 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6008 */
6010 SCIP* scip, /**< SCIP data structure */
6011 SCIP_VAR* var, /**< variable to change the bound for */
6012 SCIP_Real newbound, /**< new value for bound */
6013 SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
6014 int inferinfo, /**< user information for inference to help resolving the conflict */
6015 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6016 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
6017 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6018 )
6019{
6020 SCIP_Real lb;
6021 SCIP_Real ub;
6022
6023 assert(infeasible != NULL);
6024
6025 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarUbProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6026
6027 *infeasible = FALSE;
6028 if( tightened != NULL )
6029 *tightened = FALSE;
6030
6031 SCIPvarAdjustUb(var, scip->set, &newbound);
6032
6033 /* ignore tightenings of upper bounds to -infinity during solving process */
6034 if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6035 {
6036#ifndef NDEBUG
6037 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
6039#endif
6040 return SCIP_OKAY;
6041 }
6042
6043 /* get current bounds */
6044 lb = SCIPvarGetLbLocal(var);
6045 ub = SCIPvarGetUbLocal(var);
6046 assert(SCIPsetIsLE(scip->set, lb, ub));
6047
6048 if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
6049 {
6050 *infeasible = TRUE;
6051 return SCIP_OKAY;
6052 }
6053 newbound = MAX(newbound, lb);
6054
6055 if( (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub))
6056 || SCIPsetIsGE(scip->set, newbound, ub) )
6057 return SCIP_OKAY;
6058
6059 switch( scip->set->stage )
6060 {
6061 case SCIP_STAGE_PROBLEM:
6063 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6064 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6065 SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6066 scip->branchcand, scip->eventqueue, newbound) );
6067 SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
6068 break;
6069
6071 if( !SCIPinProbing(scip) )
6072 {
6073 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6074 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6075
6076 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6077 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6079
6081 {
6083 assert(!(*infeasible));
6084 }
6085 break;
6086 }
6087 /*lint -fallthrough*/
6088 case SCIP_STAGE_SOLVING:
6089 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
6090 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
6091 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, NULL, inferprop, inferinfo, FALSE) );
6092 break;
6093
6094 default:
6095 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6096 return SCIP_INVALIDCALL;
6097 } /*lint !e788*/
6098
6099 /* check whether the upper bound improved */
6100 if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
6101 *tightened = TRUE;
6102
6103 return SCIP_OKAY;
6104}
6105
6106/** depending on SCIP's stage, fixes binary variable in the problem, in preprocessing, or in current node;
6107 * the given inference propagator is stored, such that the conflict analysis is able to find out the reason for the
6108 * deduction of the fixing
6109 *
6110 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6111 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6112 *
6113 * @pre This method can be called if @p scip is in one of the following stages:
6114 * - \ref SCIP_STAGE_PROBLEM
6115 * - \ref SCIP_STAGE_PRESOLVING
6116 * - \ref SCIP_STAGE_PRESOLVED
6117 * - \ref SCIP_STAGE_SOLVING
6118 */
6120 SCIP* scip, /**< SCIP data structure */
6121 SCIP_VAR* var, /**< binary variable to fix */
6122 SCIP_Bool fixedval, /**< value to fix binary variable to */
6123 SCIP_PROP* inferprop, /**< propagator that deduced the fixing */
6124 int inferinfo, /**< user information for inference to help resolving the conflict */
6125 SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
6126 SCIP_Bool* tightened /**< pointer to store whether the fixing tightened the local bounds, or NULL */
6127 )
6128{
6129 SCIP_Real lb;
6130 SCIP_Real ub;
6131
6133 assert(fixedval == TRUE || fixedval == FALSE);
6134 assert(infeasible != NULL);
6135
6136 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferBinvarProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6137
6138 *infeasible = FALSE;
6139 if( tightened != NULL )
6140 *tightened = FALSE;
6141
6142 /* get current bounds */
6143 lb = SCIPvarGetLbLocal(var);
6144 ub = SCIPvarGetUbLocal(var);
6145 assert(SCIPsetIsEQ(scip->set, lb, 0.0) || SCIPsetIsEQ(scip->set, lb, 1.0));
6146 assert(SCIPsetIsEQ(scip->set, ub, 0.0) || SCIPsetIsEQ(scip->set, ub, 1.0));
6147 assert(SCIPsetIsLE(scip->set, lb, ub));
6148
6149 /* check, if variable is already fixed */
6150 if( (lb > 0.5) || (ub < 0.5) )
6151 {
6152 *infeasible = (fixedval == (lb < 0.5));
6153
6154 return SCIP_OKAY;
6155 }
6156
6157 /* apply the fixing */
6158 switch( scip->set->stage )
6159 {
6160 case SCIP_STAGE_PROBLEM:
6162 if( fixedval == TRUE )
6163 {
6164 SCIP_CALL( SCIPchgVarLb(scip, var, 1.0) );
6165 }
6166 else
6167 {
6168 SCIP_CALL( SCIPchgVarUb(scip, var, 0.0) );
6169 }
6170 break;
6171
6173 if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
6174 {
6175 SCIP_Bool fixed;
6176
6177 SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6178 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
6179 scip->cliquetable, (SCIP_Real)fixedval, infeasible, &fixed) );
6180 break;
6181 }
6182 /*lint -fallthrough*/
6183 case SCIP_STAGE_SOLVING:
6184 if( fixedval == TRUE )
6185 {
6186 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
6187 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, 1.0,
6188 SCIP_BOUNDTYPE_LOWER, NULL, inferprop, inferinfo, FALSE) );
6189 }
6190 else
6191 {
6192 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
6193 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, 0.0,
6194 SCIP_BOUNDTYPE_UPPER, NULL, inferprop, inferinfo, FALSE) );
6195 }
6196 break;
6197
6198 default:
6199 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6200 return SCIP_INVALIDCALL;
6201 } /*lint !e788*/
6202
6203 if( tightened != NULL )
6204 *tightened = TRUE;
6205
6206 return SCIP_OKAY;
6207}
6208
6209/** changes global lower bound of variable in preprocessing or in the current node, if the new bound is tighter
6210 * (w.r.t. bound strengthening epsilon) than the current global bound; if possible, adjusts bound to integral value;
6211 * also tightens the local bound, if the global bound is better than the local bound
6212 *
6213 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6214 * SCIPgetVars()) gets resorted.
6215 *
6216 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6217 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6218 *
6219 * @pre This method can be called if @p scip is in one of the following stages:
6220 * - \ref SCIP_STAGE_PROBLEM
6221 * - \ref SCIP_STAGE_TRANSFORMING
6222 * - \ref SCIP_STAGE_PRESOLVING
6223 * - \ref SCIP_STAGE_SOLVING
6224 *
6225 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6226 */
6228 SCIP* scip, /**< SCIP data structure */
6229 SCIP_VAR* var, /**< variable to change the bound for */
6230 SCIP_Real newbound, /**< new value for bound */
6231 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6232 SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
6233 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6234 )
6235{
6236 SCIP_Real lb;
6237 SCIP_Real ub;
6238
6239 assert(infeasible != NULL);
6240
6241 SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarLbGlobal", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6242
6243 *infeasible = FALSE;
6244 if( tightened != NULL )
6245 *tightened = FALSE;
6246
6247 SCIPvarAdjustLb(var, scip->set, &newbound);
6248
6249 /* ignore tightenings of lower bounds to +infinity during solving process */
6251 {
6252#ifndef NDEBUG
6253 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
6255#endif
6256 return SCIP_OKAY;
6257 }
6258
6259 /* get current bounds */
6260 lb = SCIPvarGetLbGlobal(var);
6261 ub = SCIPvarGetUbGlobal(var);
6262 assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPsetIsLE(scip->set, lb, ub));
6263
6264 if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
6265 {
6266 *infeasible = TRUE;
6267 return SCIP_OKAY;
6268 }
6269 newbound = MIN(newbound, ub);
6270
6271 /* bound changes of less than epsilon are ignored by SCIPvarChgLb or raise an assert in SCIPnodeAddBoundinfer,
6272 * so don't apply them even if force is set
6273 */
6274 if( SCIPsetIsEQ(scip->set, lb, newbound) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
6275 return SCIP_OKAY;
6276
6277 switch( scip->set->stage )
6278 {
6279 case SCIP_STAGE_PROBLEM:
6281 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6282 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6283 SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6284 scip->branchcand, scip->eventqueue, newbound) );
6285 SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
6286 break;
6287
6289 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6290 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6291 break;
6292
6294 if( !SCIPinProbing(scip) )
6295 {
6296 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6297 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6298
6299 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6300 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6302
6304 {
6306 assert(!(*infeasible));
6307 }
6308 break;
6309 }
6310 /*lint -fallthrough*/
6311 case SCIP_STAGE_SOLVING:
6312 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6313 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6315 break;
6316
6317 default:
6318 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6319 return SCIP_INVALIDCALL;
6320 } /*lint !e788*/
6321
6322 /* coverity: unreachable code */
6323 if( tightened != NULL && lb < SCIPcomputeVarLbGlobal(scip, var) )
6324 *tightened = TRUE;
6325
6326 return SCIP_OKAY;
6327}
6328
6329/** changes global upper bound of variable in preprocessing or in the current node, if the new bound is tighter
6330 * (w.r.t. bound strengthening epsilon) than the current global bound; if possible, adjusts bound to integral value;
6331 * also tightens the local bound, if the global bound is better than the local bound
6332 *
6333 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6334 * SCIPgetVars()) gets resorted.
6335 *
6336 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6337 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6338 *
6339 * @pre This method can be called if @p scip is in one of the following stages:
6340 * - \ref SCIP_STAGE_PROBLEM
6341 * - \ref SCIP_STAGE_TRANSFORMING
6342 * - \ref SCIP_STAGE_PRESOLVING
6343 * - \ref SCIP_STAGE_SOLVING
6344 *
6345 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6346 */
6348 SCIP* scip, /**< SCIP data structure */
6349 SCIP_VAR* var, /**< variable to change the bound for */
6350 SCIP_Real newbound, /**< new value for bound */
6351 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6352 SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
6353 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6354 )
6355{
6356 SCIP_Real lb;
6357 SCIP_Real ub;
6358
6359 assert(infeasible != NULL);
6360
6361 SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarUbGlobal", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6362
6363 *infeasible = FALSE;
6364 if( tightened != NULL )
6365 *tightened = FALSE;
6366
6367 SCIPvarAdjustUb(var, scip->set, &newbound);
6368
6369 /* ignore tightenings of upper bounds to -infinity during solving process */
6370 if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6371 {
6372#ifndef NDEBUG
6373 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
6375#endif
6376 return SCIP_OKAY;
6377 }
6378
6379 /* get current bounds */
6380 lb = SCIPvarGetLbGlobal(var);
6381 ub = SCIPvarGetUbGlobal(var);
6382 assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPsetIsLE(scip->set, lb, ub));
6383
6384 if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
6385 {
6386 *infeasible = TRUE;
6387 return SCIP_OKAY;
6388 }
6389 newbound = MAX(newbound, lb);
6390
6391 /* bound changes of less than epsilon are ignored by SCIPvarChgUb or raise an assert in SCIPnodeAddBoundinfer,
6392 * so don't apply them even if force is set
6393 */
6394 if( SCIPsetIsEQ(scip->set, ub, newbound) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
6395 return SCIP_OKAY;
6396
6397 switch( scip->set->stage )
6398 {
6399 case SCIP_STAGE_PROBLEM:
6401 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6402 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6403 SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6404 scip->branchcand, scip->eventqueue, newbound) );
6405 SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
6406 break;
6407
6409 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6410 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6411 break;
6412
6414 if( !SCIPinProbing(scip) )
6415 {
6416 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6417 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6418
6419 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6420 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6422
6424 {
6426 assert(!(*infeasible));
6427 }
6428 break;
6429 }
6430 /*lint -fallthrough*/
6431 case SCIP_STAGE_SOLVING:
6432 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6433 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6435 break;
6436
6437 default:
6438 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6439 return SCIP_INVALIDCALL;
6440 } /*lint !e788*/
6441
6442 /* coverity: unreachable code */
6443 if( tightened != NULL && ub > SCIPcomputeVarUbGlobal(scip, var) )
6444 *tightened = TRUE;
6445
6446 return SCIP_OKAY;
6447}
6448
6449/* some simple variable functions implemented as defines */
6450#undef SCIPcomputeVarLbGlobal
6451#undef SCIPcomputeVarUbGlobal
6452#undef SCIPcomputeVarLbLocal
6453#undef SCIPcomputeVarUbLocal
6454
6455/** for a multi-aggregated variable, returns the global lower bound computed by adding the global bounds from all aggregation variables
6456 *
6457 * 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
6458 * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetLbGlobal.
6459 *
6460 * @return the global lower bound computed by adding the global bounds from all aggregation variables
6461 */
6463 SCIP* scip, /**< SCIP data structure */
6464 SCIP_VAR* var /**< variable to compute the bound for */
6465 )
6466{
6467 assert(scip != NULL);
6468 assert(var != NULL);
6469
6471 return SCIPvarGetMultaggrLbGlobal(var, scip->set);
6472 else
6473 return SCIPvarGetLbGlobal(var);
6474}
6475
6476/** for a multi-aggregated variable, returns the global upper bound computed by adding the global bounds from all aggregation variables
6477 *
6478 * 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
6479 * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetUbGlobal
6480 *
6481 * @return the global upper bound computed by adding the global bounds from all aggregation variables
6482 */
6484 SCIP* scip, /**< SCIP data structure */
6485 SCIP_VAR* var /**< variable to compute the bound for */
6486 )
6487{
6488 assert(scip != NULL);
6489 assert(var != NULL);
6490
6492 return SCIPvarGetMultaggrUbGlobal(var, scip->set);
6493 else
6494 return SCIPvarGetUbGlobal(var);
6495}
6496
6497/** for a multi-aggregated variable, returns the local lower bound computed by adding the local bounds from all aggregation variables
6498 *
6499 * 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
6500 * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetLbLocal.
6501 *
6502 * @return the local lower bound computed by adding the global bounds from all aggregation variables
6503 */
6505 SCIP* scip, /**< SCIP data structure */
6506 SCIP_VAR* var /**< variable to compute the bound for */
6507 )
6508{
6509 assert(scip != NULL);
6510 assert(var != NULL);
6511
6513 return SCIPvarGetMultaggrLbLocal(var, scip->set);
6514 else
6515 return SCIPvarGetLbLocal(var);
6516}
6517
6518/** for a multi-aggregated variable, returns the local upper bound computed by adding the local bounds from all aggregation variables
6519 *
6520 * 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
6521 * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetUbLocal.
6522 *
6523 * @return the local upper bound computed by adding the global bounds from all aggregation variables
6524 */
6526 SCIP* scip, /**< SCIP data structure */
6527 SCIP_VAR* var /**< variable to compute the bound for */
6528 )
6529{
6530 assert(scip != NULL);
6531 assert(var != NULL);
6532
6534 return SCIPvarGetMultaggrUbLocal(var, scip->set);
6535 else
6536 return SCIPvarGetUbLocal(var);
6537}
6538
6539/** for a multi-aggregated variable, gives the global lower bound computed by adding the global bounds from all
6540 * aggregation variables, this global bound may be tighter than the one given by SCIPvarGetLbGlobal, since the latter is
6541 * not updated if bounds of aggregation variables are changing
6542 *
6543 * calling this function for a non-multi-aggregated variable is not allowed
6544 */
6546 SCIP* scip, /**< SCIP data structure */
6547 SCIP_VAR* var /**< variable to compute the bound for */
6548 )
6549{
6551 return SCIPvarGetMultaggrLbGlobal(var, scip->set);
6552}
6553
6554/** for a multi-aggregated variable, gives the global upper bound computed by adding the global bounds from all
6555 * aggregation variables, this upper bound may be tighter than the one given by SCIPvarGetUbGlobal, since the latter is
6556 * not updated if bounds of aggregation variables are changing
6557 *
6558 * calling this function for a non-multi-aggregated variable is not allowed
6559 */
6561 SCIP* scip, /**< SCIP data structure */
6562 SCIP_VAR* var /**< variable to compute the bound for */
6563 )
6564{
6566 return SCIPvarGetMultaggrUbGlobal(var, scip->set);
6567}
6568
6569/** for a multi-aggregated variable, gives the local lower bound computed by adding the local bounds from all
6570 * aggregation variables, this lower bound may be tighter than the one given by SCIPvarGetLbLocal, since the latter is
6571 * not updated if bounds of aggregation variables are changing
6572 *
6573 * calling this function for a non-multi-aggregated variable is not allowed
6574 */
6576 SCIP* scip, /**< SCIP data structure */
6577 SCIP_VAR* var /**< variable to compute the bound for */
6578 )
6579{
6581 return SCIPvarGetMultaggrLbLocal(var, scip->set);
6582}
6583
6584/** for a multi-aggregated variable, gives the local upper bound computed by adding the local bounds from all
6585 * aggregation variables, this upper bound may be tighter than the one given by SCIPvarGetUbLocal, since the latter is
6586 * not updated if bounds of aggregation variables are changing
6587 *
6588 * calling this function for a non-multi-aggregated variable is not allowed
6589 */
6591 SCIP* scip, /**< SCIP data structure */
6592 SCIP_VAR* var /**< variable to compute the bound for */
6593 )
6594{
6596 return SCIPvarGetMultaggrUbLocal(var, scip->set);
6597}
6598
6599/** returns solution value and index of variable lower bound that is closest to the variable's value in the given primal
6600 * solution or current LP solution if no primal solution is given; returns an index of -1 if no variable lower bound is
6601 * available
6602 *
6603 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6604 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6605 *
6606 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
6607 */
6609 SCIP* scip, /**< SCIP data structure */
6610 SCIP_VAR* var, /**< active problem variable */
6611 SCIP_SOL* sol, /**< primal solution, or NULL for LP solution */
6612 SCIP_Real* closestvlb, /**< pointer to store the value of the closest variable lower bound */
6613 int* closestvlbidx /**< pointer to store the index of the closest variable lower bound */
6614 )
6615{
6616 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarClosestVlb", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6617
6618 SCIPvarGetClosestVlb(var, sol, scip->set, scip->stat, closestvlb, closestvlbidx);
6619
6620 return SCIP_OKAY;
6621}
6622
6623/** returns solution value and index of variable upper bound that is closest to the variable's value in the given primal solution;
6624 * or current LP solution if no primal solution is given; returns an index of -1 if no variable upper bound is available
6625 *
6626 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6627 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6628 *
6629 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
6630 */
6632 SCIP* scip, /**< SCIP data structure */
6633 SCIP_VAR* var, /**< active problem variable */
6634 SCIP_SOL* sol, /**< primal solution, or NULL for LP solution */
6635 SCIP_Real* closestvub, /**< pointer to store the value of the closest variable lower bound */
6636 int* closestvubidx /**< pointer to store the index of the closest variable lower bound */
6637 )
6638{
6639 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarClosestVub", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6640
6641 SCIPvarGetClosestVub(var, sol, scip->set, scip->stat, closestvub, closestvubidx);
6642
6643 return SCIP_OKAY;
6644}
6645
6646/** informs variable x about a globally valid variable lower bound x >= b*z + d with integer variable z;
6647 * if z is binary, the corresponding valid implication for z is also added;
6648 * if z is non-continuous and 1/b not too small, the corresponding valid upper/lower bound
6649 * z <= (x-d)/b or z >= (x-d)/b (depending on the sign of of b) is added, too;
6650 * improves the global bounds of the variable and the vlb variable if possible
6651 *
6652 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6653 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6654 *
6655 * @pre This method can be called if @p scip is in one of the following stages:
6656 * - \ref SCIP_STAGE_PRESOLVING
6657 * - \ref SCIP_STAGE_PRESOLVED
6658 * - \ref SCIP_STAGE_SOLVING
6659 */
6661 SCIP* scip, /**< SCIP data structure */
6662 SCIP_VAR* var, /**< problem variable */
6663 SCIP_VAR* vlbvar, /**< variable z in x >= b*z + d */
6664 SCIP_Real vlbcoef, /**< coefficient b in x >= b*z + d */
6665 SCIP_Real vlbconstant, /**< constant d in x >= b*z + d */
6666 SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6667 int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6668 )
6669{
6670 int nlocalbdchgs;
6671
6673
6674 SCIP_CALL( SCIPvarAddVlb(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->tree,
6675 scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, vlbvar, vlbcoef, vlbconstant,
6676 TRUE, infeasible, &nlocalbdchgs) );
6677
6678 *nbdchgs = nlocalbdchgs;
6679
6680 /* 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
6681 * detected infeasibility
6682 */
6683 if( !(*infeasible) && SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisZero(scip, 1.0/vlbcoef) )
6684 {
6685 if( vlbcoef > 0.0 )
6686 {
6687 /* if b > 0, we have a variable upper bound: x >= b*z + d => z <= (x-d)/b */
6688 SCIP_CALL( SCIPvarAddVub(vlbvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6689 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vlbcoef,
6690 -vlbconstant/vlbcoef, TRUE, infeasible, &nlocalbdchgs) );
6691 }
6692 else
6693 {
6694 /* if b < 0, we have a variable lower bound: x >= b*z + d => z >= (x-d)/b */
6695 SCIP_CALL( SCIPvarAddVlb(vlbvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6696 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vlbcoef,
6697 -vlbconstant/vlbcoef, TRUE, infeasible, &nlocalbdchgs) );
6698 }
6699 *nbdchgs += nlocalbdchgs;
6700 }
6701
6702 return SCIP_OKAY;
6703}
6704
6705/** informs variable x about a globally valid variable upper bound x <= b*z + d with integer variable z;
6706 * if z is binary, the corresponding valid implication for z is also added;
6707 * if z is non-continuous and 1/b not too small, the corresponding valid lower/upper bound
6708 * z >= (x-d)/b or z <= (x-d)/b (depending on the sign of of b) is added, too;
6709 * improves the global bounds of the variable and the vlb variable if possible
6710 *
6711 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6712 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6713 *
6714 * @pre This method can be called if @p scip is in one of the following stages:
6715 * - \ref SCIP_STAGE_PRESOLVING
6716 * - \ref SCIP_STAGE_PRESOLVED
6717 * - \ref SCIP_STAGE_SOLVING
6718 */
6720 SCIP* scip, /**< SCIP data structure */
6721 SCIP_VAR* var, /**< problem variable */
6722 SCIP_VAR* vubvar, /**< variable z in x <= b*z + d */
6723 SCIP_Real vubcoef, /**< coefficient b in x <= b*z + d */
6724 SCIP_Real vubconstant, /**< constant d in x <= b*z + d */
6725 SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6726 int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6727 )
6728{
6729 int nlocalbdchgs;
6730
6732
6733 SCIP_CALL( SCIPvarAddVub(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->tree,
6734 scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, vubvar, vubcoef, vubconstant, TRUE,
6735 infeasible, &nlocalbdchgs) );
6736
6737 *nbdchgs = nlocalbdchgs;
6738
6739 /* 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
6740 * detected infeasibility
6741 */
6742 if( !(*infeasible) && SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisZero(scip, 1.0/vubcoef) )
6743 {
6744 if( vubcoef > 0.0 )
6745 {
6746 /* if b < 0, we have a variable lower bound: x >= b*z + d => z >= (x-d)/b */
6747 SCIP_CALL( SCIPvarAddVlb(vubvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6748 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vubcoef,
6749 -vubconstant/vubcoef, TRUE, infeasible, &nlocalbdchgs) );
6750 }
6751 else
6752 {
6753 /* if b > 0, we have a variable upper bound: x >= b*z + d => z <= (x-d)/b */
6754 SCIP_CALL( SCIPvarAddVub(vubvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6755 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vubcoef,
6756 -vubconstant/vubcoef, TRUE, infeasible, &nlocalbdchgs) );
6757 }
6758 *nbdchgs += nlocalbdchgs;
6759 }
6760
6761 return SCIP_OKAY;
6762}
6763
6764/** informs binary variable x about a globally valid implication: x == 0 or x == 1 ==> y <= b or y >= b;
6765 * also adds the corresponding implication or variable bound to the implied variable;
6766 * if the implication is conflicting, the variable is fixed to the opposite value;
6767 * if the variable is already fixed to the given value, the implication is performed immediately;
6768 * if the implication is redundant with respect to the variables' global bounds, it is ignored
6769 *
6770 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6771 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6772 *
6773 * @pre This method can be called if @p scip is in one of the following stages:
6774 * - \ref SCIP_STAGE_TRANSFORMED
6775 * - \ref SCIP_STAGE_PRESOLVING
6776 * - \ref SCIP_STAGE_PRESOLVED
6777 * - \ref SCIP_STAGE_SOLVING
6778 */
6780 SCIP* scip, /**< SCIP data structure */
6781 SCIP_VAR* var, /**< problem variable */
6782 SCIP_Bool varfixing, /**< FALSE if y should be added in implications for x == 0, TRUE for x == 1 */
6783 SCIP_VAR* implvar, /**< variable y in implication y <= b or y >= b */
6784 SCIP_BOUNDTYPE impltype, /**< type of implication y <= b (SCIP_BOUNDTYPE_UPPER)
6785 * or y >= b (SCIP_BOUNDTYPE_LOWER) */
6786 SCIP_Real implbound, /**< bound b in implication y <= b or y >= b */
6787 SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6788 int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6789 )
6790{
6791 SCIP_VAR* implprobvar;
6792
6793 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarImplication", FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6794
6795 assert(infeasible != NULL);
6796 *infeasible = FALSE;
6797
6798 if ( nbdchgs != NULL )
6799 *nbdchgs = 0;
6800
6801 if( !SCIPvarIsBinary(var) )
6802 {
6803 SCIPerrorMessage("can't add implication for nonbinary variable\n");
6804 return SCIP_INVALIDDATA;
6805 }
6806
6807 implprobvar = SCIPvarGetProbvar(implvar);
6808 /* transform implication containing two binary variables to a clique; the condition ensures that the active representative
6809 * of implvar is actually binary
6810 */
6811 if( SCIPvarIsBinary(implvar) && (SCIPvarIsActive(implvar) || (implprobvar != NULL && SCIPvarIsBinary(implprobvar))) )
6812 {
6813 assert(SCIPisFeasEQ(scip, implbound, 1.0) || SCIPisFeasZero(scip, implbound));
6814 assert((impltype == SCIP_BOUNDTYPE_UPPER) == SCIPisFeasZero(scip, implbound));
6815
6816 /* only add clique if implication is not redundant with respect to global bounds of the implication variable */
6817 if( (impltype == SCIP_BOUNDTYPE_LOWER && SCIPvarGetLbGlobal(implvar) < 0.5) ||
6818 (impltype == SCIP_BOUNDTYPE_UPPER && SCIPvarGetUbGlobal(implvar) > 0.5) )
6819 {
6820 SCIP_VAR* vars[2];
6821 SCIP_Bool vals[2];
6822
6823 vars[0] = var;
6824 vars[1] = implvar;
6825 vals[0] = varfixing;
6826 vals[1] = (impltype == SCIP_BOUNDTYPE_UPPER);
6827
6828 SCIP_CALL( SCIPaddClique(scip, vars, vals, 2, FALSE, infeasible, nbdchgs) );
6829 }
6830
6831 return SCIP_OKAY;
6832 }
6833
6834 /* the implication graph can only handle 'real' binary (SCIP_VARTYPE_BINARY) variables, therefore we transform the
6835 * implication in variable bounds, (lowerbound of y will be abbreviated by lby, upperbound equivlaent) the follwing
6836 * four cases are:
6837 *
6838 * 1. (x >= 1 => y >= b) => y >= (b - lby) * x + lby
6839 * 2. (x >= 1 => y <= b) => y <= (b - uby) * x + uby
6840 * 3. (x <= 0 => y >= b) => y >= (lby - b) * x + b
6841 * 4. (x <= 0 => y <= b) => y <= (uby - b) * x + b
6842 */
6844 {
6845 SCIP_Real lby;
6846 SCIP_Real uby;
6847
6848 lby = SCIPvarGetLbGlobal(implvar);
6849 uby = SCIPvarGetUbGlobal(implvar);
6850
6851 if( varfixing == TRUE )
6852 {
6853 if( impltype == SCIP_BOUNDTYPE_LOWER )
6854 {
6855 /* we return if the lower bound is infinity */
6856 if( SCIPisInfinity(scip, -lby) )
6857 return SCIP_OKAY;
6858
6859 SCIP_CALL( SCIPvarAddVlb(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6860 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6861 implbound - lby, lby, TRUE, infeasible, nbdchgs) );
6862 }
6863 else
6864 {
6865 /* we return if the upper bound is infinity */
6866 if( SCIPisInfinity(scip, uby) )
6867 return SCIP_OKAY;
6868
6869 SCIP_CALL( SCIPvarAddVub(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6870 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6871 implbound - uby, uby, TRUE, infeasible, nbdchgs) );
6872 }
6873 }
6874 else
6875 {
6876 if( impltype == SCIP_BOUNDTYPE_LOWER )
6877 {
6878 /* we return if the lower bound is infinity */
6879 if( SCIPisInfinity(scip, -lby) )
6880 return SCIP_OKAY;
6881
6882 SCIP_CALL( SCIPvarAddVlb(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6883 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6884 lby - implbound, implbound, TRUE, infeasible, nbdchgs) );
6885 }
6886 else
6887 {
6888 /* we return if the upper bound is infinity */
6889 if( SCIPisInfinity(scip, uby) )
6890 return SCIP_OKAY;
6891
6892 SCIP_CALL( SCIPvarAddVub(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6893 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6894 uby - implbound, implbound, TRUE, infeasible, nbdchgs) );
6895 }
6896 }
6897 }
6898 else
6899 {
6900 SCIP_CALL( SCIPvarAddImplic(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6901 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, varfixing, implvar, impltype,
6902 implbound, TRUE, infeasible, nbdchgs) );
6903 }
6904
6905 return SCIP_OKAY;
6906}
6907
6908/** adds a clique information to SCIP, stating that at most one of the given binary variables can be set to 1;
6909 * if a variable appears twice in the same clique, the corresponding implications are performed
6910 *
6911 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6912 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6913 *
6914 * @pre This method can be called if @p scip is in one of the following stages:
6915 * - \ref SCIP_STAGE_TRANSFORMED
6916 * - \ref SCIP_STAGE_PRESOLVING
6917 * - \ref SCIP_STAGE_PRESOLVED
6918 * - \ref SCIP_STAGE_SOLVING
6919 */
6921 SCIP* scip, /**< SCIP data structure */
6922 SCIP_VAR** vars, /**< binary variables in the clique from which at most one can be set to 1 */
6923 SCIP_Bool* values, /**< values of the variables in the clique; NULL to use TRUE for all vars */
6924 int nvars, /**< number of variables in the clique */
6925 SCIP_Bool isequation, /**< is the clique an equation or an inequality? */
6926 SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6927 int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6928 )
6929{
6931
6932 *infeasible = FALSE;
6933 if( nbdchgs != NULL )
6934 *nbdchgs = 0;
6935
6936 if( nvars > 1 )
6937 {
6938 /* add the clique to the clique table */
6939 SCIP_CALL( SCIPcliquetableAdd(scip->cliquetable, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6940 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, vars, values, nvars, isequation,
6941 infeasible, nbdchgs) );
6942 }
6943
6944 return SCIP_OKAY;
6945}
6946
6947/** relabels the given labels in-place in an increasing fashion: the first seen label is 0, the next label 1, etc...
6948 *
6949 * @note every label equal to -1 is treated as a previously unseen, unique label and gets a new ordered label.
6950 */
6951static
6953 SCIP*const scip, /**< SCIP data structure */
6954 int* labels, /**< current labels that will be overwritten */
6955 int const nlabels, /**< number of variables in the clique */
6956 int* nclasses /**< pointer to store the total number of distinct labels */
6957 )
6958{
6959 SCIP_HASHMAP* classidx2newlabel;
6960
6961 int classidx;
6962 int i;
6963
6964 SCIP_CALL( SCIPhashmapCreate(&classidx2newlabel, SCIPblkmem(scip), nlabels) );
6965
6966 classidx = 0;
6967
6968 /* loop over labels to create local class indices that obey the variable order */
6969 for( i = 0; i < nlabels; ++i )
6970 {
6971 int currentlabel = labels[i];
6972 int localclassidx;
6973
6974 /* labels equal to -1 are stored as singleton classes */
6975 if( currentlabel == -1 )
6976 {
6977 ++classidx;
6978 localclassidx = classidx;
6979 }
6980 else
6981 {
6982 assert(currentlabel >= 0);
6983 /* look up the class index image in the hash map; if it is not stored yet, new class index is created and stored */
6984 if( !SCIPhashmapExists(classidx2newlabel, (void*)(size_t)currentlabel) )
6985 {
6986 ++classidx;
6987 localclassidx = classidx;
6988 SCIP_CALL( SCIPhashmapInsertInt(classidx2newlabel, (void*)(size_t)currentlabel, classidx) ); /*lint !e571*/
6989 }
6990 else
6991 {
6992 localclassidx = SCIPhashmapGetImageInt(classidx2newlabel, (void*)(size_t)currentlabel); /*lint !e571*/
6993 }
6994 }
6995 assert(localclassidx - 1 >= 0);
6996 assert(localclassidx - 1 <= i);
6997
6998 /* indices start with zero, but we have an offset of 1 because we cannot store 0 in a hashmap */
6999 labels[i] = localclassidx - 1;
7000 }
7001
7002 assert(classidx > 0);
7003 assert(classidx <= nlabels);
7004 *nclasses = classidx;
7005
7006 SCIPhashmapFree(&classidx2newlabel);
7007
7008 return SCIP_OKAY;
7009}
7010
7011/** sort the variables w.r.t. the given labels; thereby ensure the current order of the variables with the same label. */
7012static
7014 SCIP* scip, /**< SCIP data structure */
7015 SCIP_VAR** vars, /**< variable array */
7016 int* classlabels, /**< array that contains a class label for every variable */
7017 SCIP_VAR** sortedvars, /**< array to store variables after stable sorting */
7018 int* sortedindices, /**< array to store indices of sorted variables in the original vars array */
7019 int* classesstartposs, /**< starting position array for each label class (must have size nclasses + 1) */
7020 int nvars, /**< size of the vars arrays */
7021 int nclasses /**< number of label classes */
7022 )
7023{
7024 SCIP_VAR*** varpointers;
7025 int** indexpointers;
7026 int* classcount;
7027
7028 int nextpos;
7029 int c;
7030 int v;
7031
7032 assert(scip != NULL);
7033 assert(vars != NULL);
7034 assert(sortedindices != NULL);
7035 assert(classesstartposs != NULL);
7036
7037 assert(nvars == 0 || vars != NULL);
7038
7039 if( nvars == 0 )
7040 return SCIP_OKAY;
7041
7042 assert(classlabels != NULL);
7043 assert(nclasses > 0);
7044
7045 /* we first count all class cardinalities and allocate temporary memory for a bucket sort */
7046 SCIP_CALL( SCIPallocBufferArray(scip, &classcount, nclasses) );
7047 BMSclearMemoryArray(classcount, nclasses);
7048
7049 /* first we count for each class the number of elements */
7050 for( v = nvars - 1; v >= 0; --v )
7051 {
7052 assert(0 <= classlabels[v] && classlabels[v] < nclasses);
7053 ++(classcount[classlabels[v]]);
7054 }
7055
7056#ifndef NDEBUG
7057 BMSclearMemoryArray(sortedvars, nvars);
7058 BMSclearMemoryArray(sortedindices, nvars);
7059#endif
7060 SCIP_CALL( SCIPallocBufferArray(scip, &varpointers, nclasses) );
7061 SCIP_CALL( SCIPallocBufferArray(scip, &indexpointers, nclasses) );
7062
7063 nextpos = 0;
7064 /* now we initialize all start pointers for each class, so they will be ordered */
7065 for( c = 0; c < nclasses; ++c )
7066 {
7067 /* to reach the goal that all variables of each class will be standing next to each other we will initialize the
7068 * starting pointers for each class by adding the cardinality of each class to the last class starting pointer
7069 * e.g. class1 has 4 elements and class2 has 3 elements then the starting pointer for class1 will be the pointer
7070 * to sortedvars[0], the starting pointer to class2 will be the pointer to sortedvars[4] and to class3 it will be
7071 * the pointer to sortedvars[7]
7072 */
7073 varpointers[c] = (SCIP_VAR**) (sortedvars + nextpos);
7074 indexpointers[c] = (int*) (sortedindices + nextpos);
7075 classesstartposs[c] = nextpos;
7076 assert(classcount[c] > 0);
7077 nextpos += classcount[c];
7078 assert(nextpos > 0);
7079 }
7080 assert(nextpos == nvars);
7081 classesstartposs[c] = nextpos;
7082
7083 /* now we copy all variables to the right order */
7084 for( v = 0; v < nvars; ++v )
7085 {
7086 /* copy variable itself to the right position */
7087 *(varpointers[classlabels[v]]) = vars[v]; /*lint !e613*/
7088 ++(varpointers[classlabels[v]]);
7089
7090 /* copy index */
7091 *(indexpointers[classlabels[v]]) = v;
7092 ++(indexpointers[classlabels[v]]);
7093 }
7094
7095/* in debug mode, we ensure the correctness of the mapping */
7096#ifndef NDEBUG
7097 for( v = 0; v < nvars; ++v )
7098 {
7099 assert(sortedvars[v] != NULL);
7100 assert(sortedindices[v] >= 0);
7101
7102 /* assert that the sorted indices map back to the correct variable in the original order */
7103 assert(vars[sortedindices[v]] == sortedvars[v]);
7104 }
7105#endif
7106
7107 /* free temporary memory */
7108 SCIPfreeBufferArray(scip, &indexpointers);
7109 SCIPfreeBufferArray(scip, &varpointers);
7110 SCIPfreeBufferArray(scip, &classcount);
7111
7112 return SCIP_OKAY;
7113}
7114
7115
7116/* calculate clique partition for a maximal amount of comparisons on variables due to expensive algorithm
7117 * @todo: check for a good value, maybe it's better to check parts of variables
7118 */
7119#define MAXNCLIQUEVARSCOMP 1000000
7120
7121/** calculates a partition of the given set of binary variables into cliques;
7122 * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7123 * were assigned to the same clique;
7124 * the first variable is always assigned to clique 0, and a variable can only be assigned to clique i if at least one of
7125 * the preceding variables was assigned to clique i-1;
7126 * for each clique at most 1 variables can be set to TRUE in a feasible solution;
7127 *
7128 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7129 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7130 *
7131 * @pre This method can be called if @p scip is in one of the following stages:
7132 * - \ref SCIP_STAGE_INITPRESOLVE
7133 * - \ref SCIP_STAGE_PRESOLVING
7134 * - \ref SCIP_STAGE_EXITPRESOLVE
7135 * - \ref SCIP_STAGE_PRESOLVED
7136 * - \ref SCIP_STAGE_SOLVING
7137 */
7138static
7140 SCIP*const scip, /**< SCIP data structure */
7141 SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7142 SCIP_Bool*const values, /**< clique value (TRUE or FALSE) for each variable in the clique */
7143 int const nvars, /**< number of variables in the array */
7144 int*const cliquepartition, /**< array of length nvars to store the clique partition */
7145 int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7146 )
7147{
7148 SCIP_VAR** cliquevars;
7149 SCIP_Bool* cliquevalues;
7150 int i;
7151 int maxncliquevarscomp;
7152 int ncliquevars;
7153
7154 /* allocate temporary memory for storing the variables of the current clique */
7155 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &cliquevars, nvars) );
7156 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &cliquevalues, nvars) );
7157
7158 /* initialize the cliquepartition array with -1 */
7159 for( i = nvars - 1; i >= 0; --i )
7160 cliquepartition[i] = -1;
7161
7162 maxncliquevarscomp = (int) MIN(nvars * (SCIP_Longint)nvars, MAXNCLIQUEVARSCOMP);
7163 /* calculate the clique partition */
7164 *ncliques = 0;
7165 for( i = 0; i < nvars; ++i )
7166 {
7167 if( cliquepartition[i] == -1 )
7168 {
7169 int j;
7170
7171 /* variable starts a new clique */
7172 cliquepartition[i] = *ncliques;
7173 cliquevars[0] = vars[i];
7174 cliquevalues[0] = values[i];
7175 ncliquevars = 1;
7176
7177 /* if variable is not active (multi-aggregated or fixed), it cannot be in any clique */
7178 if( SCIPvarIsActive(vars[i]) && SCIPvarGetNCliques(vars[i], values[i]) > 0 )
7179 {
7180 /* greedily fill up the clique */
7181 for( j = i+1; j < nvars; ++j )
7182 {
7183 /* if variable is not active (multi-aggregated or fixed), it cannot be in any clique */
7184 if( cliquepartition[j] == -1 && SCIPvarIsActive(vars[j]) )
7185 {
7186 int k;
7187
7188 /* check if every variable in the current clique can be extended by tmpvars[j] */
7189 for( k = ncliquevars - 1; k >= 0; --k )
7190 {
7191 if( !SCIPvarsHaveCommonClique(vars[j], values[j], cliquevars[k], cliquevalues[k], FALSE) )
7192 break;
7193 }
7194
7195 if( k == -1 )
7196 {
7197 /* put the variable into the same clique */
7198 cliquepartition[j] = cliquepartition[i];
7199 cliquevars[ncliquevars] = vars[j];
7200 cliquevalues[ncliquevars] = values[j];
7201 ++ncliquevars;
7202 }
7203 }
7204 }
7205 }
7206
7207 /* this clique is finished */
7208 ++(*ncliques);
7209 }
7210 assert(cliquepartition[i] >= 0 && cliquepartition[i] < i+1);
7211
7212 /* break if we reached the maximal number of comparisons */
7213 if( i * nvars > maxncliquevarscomp )
7214 break;
7215 }
7216 /* if we had to many variables fill up the cliquepartition and put each variable in a separate clique */
7217 for( ; i < nvars; ++i )
7218 {
7219 if( cliquepartition[i] == -1 )
7220 {
7221 cliquepartition[i] = *ncliques;
7222 ++(*ncliques);
7223 }
7224 }
7225
7226 SCIPsetFreeBufferArray(scip->set, &cliquevalues);
7227 SCIPsetFreeBufferArray(scip->set, &cliquevars);
7228
7229 return SCIP_OKAY;
7230}
7231
7232/** calculates a partition of the given set of binary variables into cliques; takes into account independent clique components
7233 *
7234 * The algorithm performs the following steps:
7235 * - recomputes connected components of the clique table, if necessary
7236 * - computes a clique partition for every connected component greedily.
7237 * - relabels the resulting clique partition such that it satisfies the description below
7238 *
7239 * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7240 * were assigned to the same clique;
7241 * the first variable is always assigned to clique 0, and a variable can only be assigned to clique i if at least one of
7242 * the preceding variables was assigned to clique i-1;
7243 * for each clique at most 1 variables can be set to TRUE in a feasible solution;
7244 *
7245 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7246 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7247 *
7248 * @pre This method can be called if @p scip is in one of the following stages:
7249 * - \ref SCIP_STAGE_INITPRESOLVE
7250 * - \ref SCIP_STAGE_PRESOLVING
7251 * - \ref SCIP_STAGE_EXITPRESOLVE
7252 * - \ref SCIP_STAGE_PRESOLVED
7253 * - \ref SCIP_STAGE_SOLVING
7254 */
7256 SCIP*const scip, /**< SCIP data structure */
7257 SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7258 int const nvars, /**< number of variables in the clique */
7259 int*const cliquepartition, /**< array of length nvars to store the clique partition */
7260 int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7261 )
7262{
7263 SCIP_VAR** tmpvars;
7264
7265 SCIP_VAR** sortedtmpvars;
7266 SCIP_Bool* tmpvalues;
7267 SCIP_Bool* sortedtmpvalues;
7268 int* componentlabels;
7269 int* sortedindices;
7270 int* componentstartposs;
7271 int i;
7272 int c;
7273
7274 int ncomponents;
7275
7276 assert(scip != NULL);
7277 assert(nvars == 0 || vars != NULL);
7278 assert(nvars == 0 || cliquepartition != NULL);
7279 assert(ncliques != NULL);
7280
7281 SCIP_CALL( SCIPcheckStage(scip, "SCIPcalcCliquePartition", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7282
7283 if( nvars == 0 )
7284 {
7285 *ncliques = 0;
7286 return SCIP_OKAY;
7287 }
7288
7289 /* early abort if no cliques are present */
7290 if( SCIPgetNCliques(scip) == 0 )
7291 {
7292 for( i = 0; i < nvars; ++i )
7293 cliquepartition[i] = i;
7294
7295 *ncliques = nvars;
7296
7297 return SCIP_OKAY;
7298 }
7299
7300 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &tmpvalues, nvars) );
7302 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &componentlabels, nvars) );
7303 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedindices, nvars) );
7304
7305 /* initialize the tmpvalues array */
7306 for( i = nvars - 1; i >= 0; --i )
7307 {
7308 tmpvalues[i] = TRUE;
7309 cliquepartition[i] = -1;
7310 }
7311
7312 /* get corresponding active problem variables */
7313 SCIP_CALL( SCIPvarsGetProbvarBinary(&tmpvars, &tmpvalues, nvars) );
7314
7315 ncomponents = -1;
7316
7317 /* update clique components if necessary */
7318 if( SCIPcliquetableNeedsComponentUpdate(scip->cliquetable) )
7319 {
7320 SCIP_VAR** allvars;
7321 int nallbinvars;
7322 int nallintvars;
7323 int nallimplvars;
7324
7325 SCIP_CALL( SCIPgetVarsData(scip, &allvars, NULL, &nallbinvars, &nallintvars, &nallimplvars, NULL) );
7326
7327 SCIP_CALL( SCIPcliquetableComputeCliqueComponents(scip->cliquetable, scip->set, SCIPblkmem(scip), allvars, nallbinvars, nallintvars, nallimplvars) );
7328 }
7329
7331
7332 /* store the global clique component labels */
7333 for( i = 0; i < nvars; ++i )
7334 {
7335 if( SCIPvarIsActive(tmpvars[i]) )
7336 componentlabels[i] = SCIPcliquetableGetVarComponentIdx(scip->cliquetable, tmpvars[i]);
7337 else
7338 componentlabels[i] = -1;
7339 }
7340
7341 /* relabel component labels order consistent as prerequisite for a stable sort */
7342 SCIP_CALL( relabelOrderConsistent(scip, componentlabels, nvars, &ncomponents) );
7343 assert(ncomponents >= 1);
7344 assert(ncomponents <= nvars);
7345
7346 /* allocate storage array for the starting positions of the components */
7347 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &componentstartposs, ncomponents + 1) );
7348
7349 /* stable sort the variables w.r.t. the component labels so that we can restrict the quadratic algorithm to the components */
7350 if( ncomponents > 1 )
7351 {
7352 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedtmpvars, nvars) );
7353 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedtmpvalues, nvars) );
7354 SCIP_CALL( labelSortStable(scip, tmpvars, componentlabels, sortedtmpvars, sortedindices, componentstartposs, nvars, ncomponents) );
7355
7356 /* reassign the tmpvalues with respect to the sorting */
7357 for( i = 0; i < nvars; ++i )
7358 {
7359 assert(tmpvars[sortedindices[i]] == sortedtmpvars[i]);
7360 sortedtmpvalues[i] = tmpvalues[sortedindices[i]];
7361 }
7362 }
7363 else
7364 {
7365 /* if we have only one large connected component, skip the stable sorting and prepare the data differently */
7366 sortedtmpvars = tmpvars;
7367 sortedtmpvalues = tmpvalues;
7368 componentstartposs[0] = 0;
7369 componentstartposs[1] = nvars;
7370
7371 /* sorted indices are the identity */
7372 for( i = 0; i < nvars; ++i )
7373 sortedindices[i] = i;
7374 }
7375
7376 *ncliques = 0;
7377 /* calculate a greedy clique partition for each connected component */
7378 for( c = 0; c < ncomponents; ++c )
7379 {
7380 int* localcliquepartition;
7381 int nlocalcliques;
7382 int ncomponentvars;
7383 int l;
7384
7385 /* extract the number of variables in this connected component */
7386 ncomponentvars = componentstartposs[c + 1] - componentstartposs[c];
7387 nlocalcliques = 0;
7388
7389 /* allocate necessary memory to hold the intermediate component clique partition */
7390 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &localcliquepartition, ncomponentvars) );
7391
7392 /* call greedy clique algorithm for all component variables */
7393 SCIP_CALL( calcCliquePartitionGreedy(scip, &(sortedtmpvars[componentstartposs[c]]), &(sortedtmpvalues[componentstartposs[c]]),
7394 ncomponentvars, localcliquepartition, &nlocalcliques) );
7395
7396 assert(nlocalcliques >= 1);
7397 assert(nlocalcliques <= ncomponentvars);
7398
7399 /* store the obtained clique partition with an offset of ncliques for the original variables */
7400 for( l = componentstartposs[c]; l < componentstartposs[c + 1]; ++l )
7401 {
7402 int origvaridx = sortedindices[l];
7403 assert(cliquepartition[origvaridx] == -1);
7404 assert(localcliquepartition[l - componentstartposs[c]] <= l - componentstartposs[c]);
7405 cliquepartition[origvaridx] = localcliquepartition[l - componentstartposs[c]] + (*ncliques);
7406 }
7407 *ncliques += nlocalcliques;
7408
7409 /* free the local clique partition */
7410 SCIPsetFreeBufferArray(scip->set, &localcliquepartition);
7411 }
7412
7413 /* except in the two trivial cases, we have to ensure the order consistency of the partition indices */
7414 if( ncomponents > 1 && ncomponents < nvars )
7415 {
7416 int partitionsize;
7417 SCIP_CALL( relabelOrderConsistent(scip, cliquepartition, nvars, &partitionsize) );
7418
7419 assert(partitionsize == *ncliques);
7420 }
7421
7422 if( ncomponents > 1 )
7423 {
7424 SCIPsetFreeBufferArray(scip->set, &sortedtmpvalues);
7425 SCIPsetFreeBufferArray(scip->set, &sortedtmpvars);
7426 }
7427
7428 /* use the greedy algorithm as a whole to verify the result on small number of variables */
7429#ifdef SCIP_DISABLED_CODE
7430 {
7431 int* debugcliquepartition;
7432 int ndebugcliques;
7433
7434 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &debugcliquepartition, nvars) );
7435
7436 /* call greedy clique algorithm for all component variables */
7437 SCIP_CALL( calcCliquePartitionGreedy(scip, tmpvars, tmpvalues, nvars, debugcliquepartition, &ndebugcliques) );
7438
7439 /* loop and compare the traditional greedy clique with */
7440 for( i = 0; i < nvars; ++i )
7441 assert(i * nvars > MAXNCLIQUEVARSCOMP || cliquepartition[i] == debugcliquepartition[i]);
7442
7443 SCIPsetFreeBufferArray(scip->set, &debugcliquepartition);
7444 }
7445#endif
7446
7447 /* free temporary memory */
7448 SCIPsetFreeBufferArray(scip->set, &componentstartposs);
7449 SCIPsetFreeBufferArray(scip->set, &sortedindices);
7450 SCIPsetFreeBufferArray(scip->set, &componentlabels);
7451 SCIPsetFreeBufferArray(scip->set, &tmpvars);
7452 SCIPsetFreeBufferArray(scip->set, &tmpvalues);
7453
7454 return SCIP_OKAY;
7455}
7456
7457/** calculates a partition of the given set of binary variables into negated cliques;
7458 * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7459 * were assigned to the same negated clique;
7460 * the first variable is always assigned to clique 0 and a variable can only be assigned to clique i if at least one of
7461 * the preceding variables was assigned to clique i-1;
7462 * for each clique with n_c variables at least n_c-1 variables can be set to TRUE in a feasible solution;
7463 *
7464 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7465 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7466 *
7467 * @pre This method can be called if @p scip is in one of the following stages:
7468 * - \ref SCIP_STAGE_INITPRESOLVE
7469 * - \ref SCIP_STAGE_PRESOLVING
7470 * - \ref SCIP_STAGE_EXITPRESOLVE
7471 * - \ref SCIP_STAGE_PRESOLVED
7472 * - \ref SCIP_STAGE_SOLVING
7473 */
7475 SCIP*const scip, /**< SCIP data structure */
7476 SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7477 int const nvars, /**< number of variables in the clique */
7478 int*const cliquepartition, /**< array of length nvars to store the clique partition */
7479 int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7480 )
7481{
7482 SCIP_VAR** negvars;
7483 int v;
7484
7485 assert(scip != NULL);
7486 assert(cliquepartition != NULL || nvars == 0);
7487 assert(ncliques != NULL);
7488
7489 if( nvars == 0 )
7490 {
7491 *ncliques = 0;
7492 return SCIP_OKAY;
7493 }
7494 assert(vars != NULL);
7495
7496 /* allocate temporary memory */
7497 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &negvars, nvars) );
7498
7499 /* get all negated variables */
7500 for( v = nvars - 1; v >= 0; --v )
7501 {
7502 SCIP_CALL( SCIPgetNegatedVar(scip, vars[v], &(negvars[v])) );
7503 }
7504
7505 /* calculate cliques on negated variables, which are "negated" cliques on normal variables array */
7506 SCIP_CALL( SCIPcalcCliquePartition( scip, negvars, nvars, cliquepartition, ncliques) );
7507
7508 /* free temporary memory */
7509 SCIPsetFreeBufferArray(scip->set, &negvars);
7510
7511 return SCIP_OKAY;
7512}
7513
7514
7515/** force SCIP to clean up all cliques; cliques do not get automatically cleaned up after presolving. Use
7516 * this method to prevent inactive variables in cliques when retrieved via SCIPgetCliques()
7517 *
7518 * @return SCIP_OKAY if everything worked, otherwise a suitable error code is passed
7519 *
7520 * @pre This method can be called if @p scip is in one of the following stages:
7521 * - \ref SCIP_STAGE_TRANSFORMED
7522 * - \ref SCIP_STAGE_INITPRESOLVE
7523 * - \ref SCIP_STAGE_PRESOLVING
7524 * - \ref SCIP_STAGE_EXITPRESOLVE
7525 * - \ref SCIP_STAGE_PRESOLVED
7526 * - \ref SCIP_STAGE_INITSOLVE
7527 * - \ref SCIP_STAGE_SOLVING
7528 * - \ref SCIP_STAGE_SOLVED
7529 * - \ref SCIP_STAGE_EXITSOLVE
7530 */
7532 SCIP* scip, /**< SCIP data structure */
7533 SCIP_Bool* infeasible /**< pointer to store if cleanup detected infeasibility */
7534 )
7535{
7536 int nlocalbdchgs;
7537 SCIP_Bool globalinfeasibility;
7538
7539 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPcleanupCliques", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7540
7541 globalinfeasibility = FALSE;
7542 nlocalbdchgs = 0;
7543 SCIP_CALL( SCIPcliquetableCleanup(scip->cliquetable, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
7544 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, &nlocalbdchgs,
7545 &globalinfeasibility) );
7546
7547 if( infeasible != NULL )
7548 *infeasible = globalinfeasibility;
7549
7550 if( globalinfeasibility )
7551 scip->stat->status = SCIP_STATUS_INFEASIBLE;
7552
7553 return SCIP_OKAY;
7554}
7555
7556/** gets the number of cliques in the clique table
7557 *
7558 * @return number of cliques in the clique table
7559 *
7560 * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7561 * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
7562 *
7563 * @pre This method can be called if @p scip is in one of the following stages:
7564 * - \ref SCIP_STAGE_TRANSFORMED
7565 * - \ref SCIP_STAGE_INITPRESOLVE
7566 * - \ref SCIP_STAGE_PRESOLVING
7567 * - \ref SCIP_STAGE_EXITPRESOLVE
7568 * - \ref SCIP_STAGE_PRESOLVED
7569 * - \ref SCIP_STAGE_INITSOLVE
7570 * - \ref SCIP_STAGE_SOLVING
7571 * - \ref SCIP_STAGE_SOLVED
7572 * - \ref SCIP_STAGE_EXITSOLVE
7573 */
7575 SCIP* scip /**< SCIP data structure */
7576 )
7577{
7579
7580 return SCIPcliquetableGetNCliques(scip->cliquetable);
7581}
7582
7583/** gets the number of cliques created so far by the cliquetable
7584 *
7585 * @return number of cliques created so far by the cliquetable
7586 *
7587 * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7588 * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
7589 *
7590 * @pre This method can be called if @p scip is in one of the following stages:
7591 * - \ref SCIP_STAGE_TRANSFORMED
7592 * - \ref SCIP_STAGE_INITPRESOLVE
7593 * - \ref SCIP_STAGE_PRESOLVING
7594 * - \ref SCIP_STAGE_EXITPRESOLVE
7595 * - \ref SCIP_STAGE_PRESOLVED
7596 * - \ref SCIP_STAGE_INITSOLVE
7597 * - \ref SCIP_STAGE_SOLVING
7598 * - \ref SCIP_STAGE_SOLVED
7599 * - \ref SCIP_STAGE_EXITSOLVE
7600 */
7602 SCIP* scip /**< SCIP data structure */
7603 )
7604{
7605 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNCliquesCreated", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7606
7607 return SCIPcliquetableGetNCliquesCreated(scip->cliquetable);
7608}
7609
7610/** gets the array of cliques in the clique table
7611 *
7612 * @return array of cliques in the clique table
7613 *
7614 * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7615 * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
7616 *
7617 * @pre This method can be called if @p scip is in one of the following stages:
7618 * - \ref SCIP_STAGE_TRANSFORMED
7619 * - \ref SCIP_STAGE_INITPRESOLVE
7620 * - \ref SCIP_STAGE_PRESOLVING
7621 * - \ref SCIP_STAGE_EXITPRESOLVE
7622 * - \ref SCIP_STAGE_PRESOLVED
7623 * - \ref SCIP_STAGE_INITSOLVE
7624 * - \ref SCIP_STAGE_SOLVING
7625 * - \ref SCIP_STAGE_SOLVED
7626 * - \ref SCIP_STAGE_EXITSOLVE
7627 */
7629 SCIP* scip /**< SCIP data structure */
7630 )
7631{
7633
7634 return SCIPcliquetableGetCliques(scip->cliquetable);
7635}
7636
7637/** returns whether there is a clique that contains both given variable/value pairs;
7638 * the variables must be active binary variables;
7639 * if regardimplics is FALSE, only the cliques in the clique table are looked at;
7640 * if regardimplics is TRUE, both the cliques and the implications of the implication graph are regarded
7641 *
7642 * @return TRUE, if there is a clique that contains both variable/clique pairs; FALSE, otherwise
7643 *
7644 * @pre This method can be called if @p scip is in one of the following stages:
7645 * - \ref SCIP_STAGE_TRANSFORMED
7646 * - \ref SCIP_STAGE_INITPRESOLVE
7647 * - \ref SCIP_STAGE_PRESOLVING
7648 * - \ref SCIP_STAGE_EXITPRESOLVE
7649 * - \ref SCIP_STAGE_PRESOLVED
7650 * - \ref SCIP_STAGE_INITSOLVE
7651 * - \ref SCIP_STAGE_SOLVING
7652 * - \ref SCIP_STAGE_SOLVED
7653 * - \ref SCIP_STAGE_EXITSOLVE
7654 *
7655 * @note a variable with it's negated variable are NOT! in a clique
7656 * @note a variable with itself are in a clique
7657 */
7659 SCIP* scip, /**< SCIP data structure */
7660 SCIP_VAR* var1, /**< first variable */
7661 SCIP_Bool value1, /**< value of first variable */
7662 SCIP_VAR* var2, /**< second variable */
7663 SCIP_Bool value2, /**< value of second variable */
7664 SCIP_Bool regardimplics /**< should the implication graph also be searched for a clique? */
7665 )
7666{
7667 assert(scip != NULL);
7668 assert(var1 != NULL);
7669 assert(var2 != NULL);
7670 assert(SCIPvarIsActive(var1));
7671 assert(SCIPvarIsActive(var2));
7672 assert(SCIPvarIsBinary(var1));
7673 assert(SCIPvarIsBinary(var2));
7674
7675 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPhaveVarsCommonClique", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7676
7677 /* if both variables together have more cliques then actual cliques exist, then they have a common clique (in debug
7678 * mode we check this for correctness), otherwise we need to call the pairwise comparison method for these variables
7679 */
7680#ifndef NDEBUG
7681 assert((SCIPvarGetNCliques(var1, value1) + SCIPvarGetNCliques(var2, value2) > SCIPcliquetableGetNCliques(scip->cliquetable)) ? SCIPvarsHaveCommonClique(var1, value1, var2, value2, FALSE) : TRUE);
7682#endif
7683
7684 return (SCIPvarGetNCliques(var1, value1) + SCIPvarGetNCliques(var2, value2) > SCIPcliquetableGetNCliques(scip->cliquetable)
7685 || SCIPvarsHaveCommonClique(var1, value1, var2, value2, regardimplics));
7686}
7687
7688/** writes the clique graph to a gml file
7689 *
7690 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7691 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7692 *
7693 * @pre This method can be called if @p scip is in one of the following stages:
7694 * - \ref SCIP_STAGE_TRANSFORMED
7695 * - \ref SCIP_STAGE_INITPRESOLVE
7696 * - \ref SCIP_STAGE_PRESOLVING
7697 * - \ref SCIP_STAGE_EXITPRESOLVE
7698 * - \ref SCIP_STAGE_PRESOLVED
7699 * - \ref SCIP_STAGE_INITSOLVE
7700 * - \ref SCIP_STAGE_SOLVING
7701 * - \ref SCIP_STAGE_SOLVED
7702 * - \ref SCIP_STAGE_EXITSOLVE
7703 *
7704 * @note there can be duplicated arcs in the output file
7705 *
7706 * If @p writenodeweights is true, only nodes corresponding to variables that have a fractional value and only edges
7707 * between such nodes are written.
7708 */
7710 SCIP* scip, /**< SCIP data structure */
7711 const char* fname, /**< name of file */
7712 SCIP_Bool writenodeweights /**< should we write weights of nodes? */
7713 )
7714{
7715 FILE* gmlfile;
7716 SCIP_HASHMAP* nodehashmap;
7717 SCIP_CLIQUE** cliques;
7718 SCIP_VAR** clqvars;
7719 SCIP_VAR** allvars;
7720 SCIP_Bool* clqvalues;
7721 char nodename[SCIP_MAXSTRLEN];
7722 int nallvars;
7723 int nbinvars;
7724 int nintvars;
7725 int nimplvars;
7726 int ncliques;
7727 int c;
7728 int v1;
7729 int v2;
7730 int id1;
7731 int id2;
7732
7733 assert(scip != NULL);
7734 assert(fname != NULL);
7735
7736 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPwriteCliqueGraph", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7737
7738 /* get all active variables */
7739 SCIP_CALL( SCIPgetVarsData(scip, &allvars, &nallvars, &nbinvars, &nintvars, &nimplvars, NULL) );
7740
7741 /* no possible variables for cliques exist */
7742 if( nbinvars + nimplvars == 0 )
7743 return SCIP_OKAY;
7744
7745 ncliques = SCIPgetNCliques(scip);
7746
7747 /* no cliques and do not wont to check for binary implications */
7748 if( ncliques == 0 )
7749 return SCIP_OKAY;
7750
7751 /* open gml file */
7752 gmlfile = fopen(fname, "w");
7753
7754 if( gmlfile == NULL )
7755 {
7756 SCIPerrorMessage("cannot open graph file <%s>\n", fname);
7757 SCIPABORT();
7758 return SCIP_INVALIDDATA; /*lint !e527*/
7759 }
7760
7761 /* create the hash map */
7762 SCIP_CALL_FINALLY( SCIPhashmapCreate(&nodehashmap, SCIPblkmem(scip), nbinvars+nimplvars), fclose(gmlfile) );
7763
7764 /* write starting of gml file */
7765 SCIPgmlWriteOpening(gmlfile, TRUE);
7766
7767 cliques = SCIPgetCliques(scip);
7768
7769 /* write nodes and arcs for all cliques */
7770 for( c = ncliques - 1; c >= 0; --c )
7771 {
7772 clqvalues = SCIPcliqueGetValues(cliques[c]);
7773 clqvars = SCIPcliqueGetVars(cliques[c]);
7774
7775 for( v1 = SCIPcliqueGetNVars(cliques[c]) - 1; v1 >= 0; --v1 )
7776 {
7777 id1 = clqvalues[v1] ? SCIPvarGetProbindex(clqvars[v1]) : (nallvars + SCIPvarGetProbindex(clqvars[v1]));
7778
7779 /* if corresponding node was not added yet, add it */
7780 if( !SCIPhashmapExists(nodehashmap, (void*)(size_t)id1) )
7781 {
7782 assert(id1 >= 0);
7783 SCIP_CALL_FINALLY( SCIPhashmapInsertInt(nodehashmap, (void*)(size_t)id1, 1), fclose(gmlfile) ); /*lint !e571*/
7784
7785 (void) SCIPsnprintf(nodename, SCIP_MAXSTRLEN, "%s%s", (id1 >= nallvars ? "~" : ""), SCIPvarGetName(clqvars[v1]));
7786
7787 /* write new gml node for new variable */
7788 if ( writenodeweights )
7789 {
7790 if ( ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v1])) )
7791 SCIPgmlWriteNodeWeight(gmlfile, (unsigned int)id1, nodename, NULL, NULL, NULL, SCIPgetSolVal(scip, NULL, clqvars[v1]));
7792 }
7793 else
7794 {
7795 SCIPgmlWriteNode(gmlfile, (unsigned int)id1, nodename, NULL, NULL, NULL);
7796 }
7797 }
7798
7799 for( v2 = SCIPcliqueGetNVars(cliques[c]) - 1; v2 >= 0; --v2 )
7800 {
7801 if( v1 == v2 )
7802 continue;
7803
7804 id2 = clqvalues[v2] ? SCIPvarGetProbindex(clqvars[v2]) : (nallvars + SCIPvarGetProbindex(clqvars[v2]));
7805
7806 /* if corresponding node was not added yet, add it */
7807 if( !SCIPhashmapExists(nodehashmap, (void*)(size_t)id2) )
7808 {
7809 assert(id2 >= 0);
7810 SCIP_CALL_FINALLY( SCIPhashmapInsertInt(nodehashmap, (void*)(size_t)id2, 1), fclose(gmlfile) ); /*lint !e571*/
7811
7812 (void) SCIPsnprintf(nodename, SCIP_MAXSTRLEN, "%s%s", (id2 >= nallvars ? "~" : ""), SCIPvarGetName(clqvars[v2]));
7813
7814 /* write new gml node for new variable */
7815 if ( writenodeweights )
7816 {
7817 if ( ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v2])) )
7818 SCIPgmlWriteNodeWeight(gmlfile, (unsigned int)id2, nodename, NULL, NULL, NULL, SCIPgetSolVal(scip, NULL, clqvars[v2]));
7819 }
7820 else
7821 {
7822 SCIPgmlWriteNode(gmlfile, (unsigned int)id2, nodename, NULL, NULL, NULL);
7823 }
7824 }
7825
7826 /* write gml arc between resultant and operand */
7827 if ( ! writenodeweights || ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v2])) )
7828 SCIPgmlWriteArc(gmlfile, (unsigned int)id1, (unsigned int)id2, NULL, NULL);
7829 }
7830 }
7831 }
7832
7833 /* free the hash map */
7834 SCIPhashmapFree(&nodehashmap);
7835
7836 SCIPgmlWriteClosing(gmlfile);
7837 fclose(gmlfile);
7838
7839 return SCIP_OKAY;
7840}
7841
7842/** Removes (irrelevant) variable from all its global structures, i.e. cliques, implications and variable bounds.
7843 * This is an advanced method which should be used with care.
7844 *
7845 * @return SCIP_OKAY if everything worked, otherwise a suitable error code is passed
7846 *
7847 * @pre This method can be called if @p scip is in one of the following stages:
7848 * - \ref SCIP_STAGE_TRANSFORMED
7849 * - \ref SCIP_STAGE_INITPRESOLVE
7850 * - \ref SCIP_STAGE_PRESOLVING
7851 * - \ref SCIP_STAGE_EXITPRESOLVE
7852 * - \ref SCIP_STAGE_PRESOLVED
7853 * - \ref SCIP_STAGE_INITSOLVE
7854 * - \ref SCIP_STAGE_SOLVING
7855 * - \ref SCIP_STAGE_SOLVED
7856 * - \ref SCIP_STAGE_EXITSOLVE
7857 */
7859 SCIP* scip, /**< SCIP data structure */
7860 SCIP_VAR* var /**< variable to remove from global structures */
7861 )
7862{
7863 assert(scip != NULL);
7864
7865 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPremoveVarFromGlobalStructures", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7866
7867 /* mark the variable as deletable from global structures - This is necessary for the delayed clean up of cliques */
7869
7870 /* remove variable from all its cliques, implications, and variable bounds */
7872
7873 return SCIP_OKAY;
7874}
7875
7876/** sets the branch factor of the variable; this value can be used in the branching methods to scale the score
7877 * values of the variables; higher factor leads to a higher probability that this variable is chosen for branching
7878 *
7879 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7880 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7881 *
7882 * @pre This method can be called if @p scip is in one of the following stages:
7883 * - \ref SCIP_STAGE_PROBLEM
7884 * - \ref SCIP_STAGE_TRANSFORMING
7885 * - \ref SCIP_STAGE_TRANSFORMED
7886 * - \ref SCIP_STAGE_INITPRESOLVE
7887 * - \ref SCIP_STAGE_PRESOLVING
7888 * - \ref SCIP_STAGE_EXITPRESOLVE
7889 * - \ref SCIP_STAGE_PRESOLVED
7890 * - \ref SCIP_STAGE_SOLVING
7891 */
7893 SCIP* scip, /**< SCIP data structure */
7894 SCIP_VAR* var, /**< problem variable */
7895 SCIP_Real branchfactor /**< factor to weigh variable's branching score with */
7896 )
7897{
7898 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7899
7900 SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, branchfactor) );
7901
7902 return SCIP_OKAY;
7903}
7904
7905/** scales the branch factor of the variable with the given value
7906 *
7907 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7908 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7909 *
7910 * @pre This method can be called if @p scip is in one of the following stages:
7911 * - \ref SCIP_STAGE_PROBLEM
7912 * - \ref SCIP_STAGE_TRANSFORMING
7913 * - \ref SCIP_STAGE_TRANSFORMED
7914 * - \ref SCIP_STAGE_INITPRESOLVE
7915 * - \ref SCIP_STAGE_PRESOLVING
7916 * - \ref SCIP_STAGE_EXITPRESOLVE
7917 * - \ref SCIP_STAGE_PRESOLVED
7918 * - \ref SCIP_STAGE_SOLVING
7919 */
7921 SCIP* scip, /**< SCIP data structure */
7922 SCIP_VAR* var, /**< problem variable */
7923 SCIP_Real scale /**< factor to scale variable's branching factor with */
7924 )
7925{
7926 SCIP_CALL( SCIPcheckStage(scip, "SCIPscaleVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7927
7929
7930 return SCIP_OKAY;
7931}
7932
7933/** adds the given value to the branch factor of the variable
7934 *
7935 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7936 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7937 *
7938 * @pre This method can be called if @p scip is in one of the following stages:
7939 * - \ref SCIP_STAGE_PROBLEM
7940 * - \ref SCIP_STAGE_TRANSFORMING
7941 * - \ref SCIP_STAGE_TRANSFORMED
7942 * - \ref SCIP_STAGE_INITPRESOLVE
7943 * - \ref SCIP_STAGE_PRESOLVING
7944 * - \ref SCIP_STAGE_EXITPRESOLVE
7945 * - \ref SCIP_STAGE_PRESOLVED
7946 * - \ref SCIP_STAGE_SOLVING
7947 */
7949 SCIP* scip, /**< SCIP data structure */
7950 SCIP_VAR* var, /**< problem variable */
7951 SCIP_Real addfactor /**< value to add to the branch factor of the variable */
7952 )
7953{
7954 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7955
7957
7958 return SCIP_OKAY;
7959}
7960
7961/** sets the branch priority of the variable; variables with higher branch priority are always preferred to variables
7962 * with lower priority in selection of branching variable
7963 *
7964 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7965 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7966 *
7967 * @pre This method can be called if @p scip is in one of the following stages:
7968 * - \ref SCIP_STAGE_PROBLEM
7969 * - \ref SCIP_STAGE_TRANSFORMING
7970 * - \ref SCIP_STAGE_TRANSFORMED
7971 * - \ref SCIP_STAGE_INITPRESOLVE
7972 * - \ref SCIP_STAGE_PRESOLVING
7973 * - \ref SCIP_STAGE_EXITPRESOLVE
7974 * - \ref SCIP_STAGE_PRESOLVED
7975 * - \ref SCIP_STAGE_SOLVING
7976 *
7977 * @note the default branching priority is 0
7978 */
7980 SCIP* scip, /**< SCIP data structure */
7981 SCIP_VAR* var, /**< problem variable */
7982 int branchpriority /**< branch priority of the variable */
7983 )
7984{
7985 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7986
7987 assert( var->scip == scip );
7988
7989 if( SCIPisTransformed(scip) )
7990 {
7991 assert(scip->branchcand != NULL);
7992
7993 /* inform the pseudo branch candidates that the branch priority changes and change the branch priority */
7994 SCIP_CALL( SCIPbranchcandUpdateVarBranchPriority(scip->branchcand, scip->set, var, branchpriority) );
7995 }
7996 else
7997 {
7998 /* change the branching priority of the variable */
7999 SCIP_CALL( SCIPvarChgBranchPriority(var, branchpriority) );
8000 }
8001
8002 return SCIP_OKAY;
8003}
8004
8005/** changes the branch priority of the variable to the given value, if it is larger than the current priority
8006 *
8007 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8008 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8009 *
8010 * @pre This method can be called if @p scip is in one of the following stages:
8011 * - \ref SCIP_STAGE_PROBLEM
8012 * - \ref SCIP_STAGE_TRANSFORMING
8013 * - \ref SCIP_STAGE_TRANSFORMED
8014 * - \ref SCIP_STAGE_INITPRESOLVE
8015 * - \ref SCIP_STAGE_PRESOLVING
8016 * - \ref SCIP_STAGE_EXITPRESOLVE
8017 * - \ref SCIP_STAGE_PRESOLVED
8018 * - \ref SCIP_STAGE_SOLVING
8019 */
8021 SCIP* scip, /**< SCIP data structure */
8022 SCIP_VAR* var, /**< problem variable */
8023 int branchpriority /**< new branch priority of the variable, if it is larger than current priority */
8024 )
8025{
8026 SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8027
8028 assert( var->scip == scip );
8029
8030 if( branchpriority > SCIPvarGetBranchPriority(var) )
8031 {
8032 SCIP_CALL( SCIPvarChgBranchPriority(var, branchpriority) );
8033 }
8034
8035 return SCIP_OKAY;
8036}
8037
8038/** adds the given value to the branch priority of the variable
8039 *
8040 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8041 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8042 *
8043 * @pre This method can be called if @p scip is in one of the following stages:
8044 * - \ref SCIP_STAGE_PROBLEM
8045 * - \ref SCIP_STAGE_TRANSFORMING
8046 * - \ref SCIP_STAGE_TRANSFORMED
8047 * - \ref SCIP_STAGE_INITPRESOLVE
8048 * - \ref SCIP_STAGE_PRESOLVING
8049 * - \ref SCIP_STAGE_EXITPRESOLVE
8050 * - \ref SCIP_STAGE_PRESOLVED
8051 * - \ref SCIP_STAGE_SOLVING
8052 */
8054 SCIP* scip, /**< SCIP data structure */
8055 SCIP_VAR* var, /**< problem variable */
8056 int addpriority /**< value to add to the branch priority of the variable */
8057 )
8058{
8059 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8060
8061 assert( var->scip == scip );
8062
8064
8065 return SCIP_OKAY;
8066}
8067
8068/** sets the branch direction of the variable (-1: prefer downwards branch, 0: automatic selection, +1: prefer upwards
8069 * branch)
8070 *
8071 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8072 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8073 *
8074 * @pre This method can be called if @p scip is in one of the following stages:
8075 * - \ref SCIP_STAGE_PROBLEM
8076 * - \ref SCIP_STAGE_TRANSFORMING
8077 * - \ref SCIP_STAGE_TRANSFORMED
8078 * - \ref SCIP_STAGE_INITPRESOLVE
8079 * - \ref SCIP_STAGE_PRESOLVING
8080 * - \ref SCIP_STAGE_EXITPRESOLVE
8081 * - \ref SCIP_STAGE_PRESOLVED
8082 * - \ref SCIP_STAGE_SOLVING
8083 */
8085 SCIP* scip, /**< SCIP data structure */
8086 SCIP_VAR* var, /**< problem variable */
8087 SCIP_BRANCHDIR branchdirection /**< preferred branch direction of the variable (downwards, upwards, auto) */
8088 )
8089{
8090 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchDirection", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8091
8092 assert( var->scip == scip );
8093
8094 SCIP_CALL( SCIPvarChgBranchDirection(var, branchdirection) );
8095
8096 return SCIP_OKAY;
8097}
8098
8099/** tightens the variable bounds due to a new variable type */
8100static
8102 SCIP* scip, /**< SCIP data structure */
8103 SCIP_VAR* var, /**< variable to change the bound for */
8104 SCIP_VARTYPE vartype, /**< new type of variable */
8105 SCIP_Bool* infeasible /**< pointer to store whether an infeasibility was detected (, due to
8106 * integrality condition of the new variable type) */
8107 )
8108{
8109 assert(scip != NULL);
8112 assert(var->scip == scip);
8113
8114 *infeasible = FALSE;
8115
8116 /* adjusts bounds if the variable type changed form continuous to non-continuous (integral) */
8118 {
8119 SCIP_Bool tightened;
8120
8121 /* we adjust variable bounds to integers first, since otherwise a later bound tightening with a fractional old
8122 * bound may give an assert because SCIP expects non-continuous variables to have non-fractional bounds
8123 *
8124 * we adjust bounds with a fractionality within [eps,feastol] only if the resulting bound change is a bound
8125 * tightening, because relaxing bounds may not be allowed
8126 */
8131 )
8132 {
8134 if( *infeasible )
8135 return SCIP_OKAY;
8136
8137 /* 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
8138 * 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
8139 */
8141 }
8144 )
8145 {
8147 if( *infeasible )
8148 return SCIP_OKAY;
8149
8151 }
8152 }
8153
8154 return SCIP_OKAY;
8155}
8156
8157/** changes type of variable in the problem;
8158 *
8159 * @warning This type change might change the variable array returned from SCIPgetVars() and SCIPgetVarsData();
8160 *
8161 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8162 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8163 *
8164 * @pre This method can be called if @p scip is in one of the following stages:
8165 * - \ref SCIP_STAGE_PROBLEM
8166 * - \ref SCIP_STAGE_TRANSFORMING
8167 * - \ref SCIP_STAGE_PRESOLVING
8168 *
8169 * @note If SCIP is already beyond the SCIP_STAGE_PROBLEM and a original variable is passed, the variable type of the
8170 * corresponding transformed variable is changed; the type of the original variable does not change
8171 *
8172 * @note If the type changes from a continuous variable to a non-continuous variable the bounds of the variable get
8173 * adjusted w.r.t. to integrality information
8174 */
8176 SCIP* scip, /**< SCIP data structure */
8177 SCIP_VAR* var, /**< variable to change the bound for */
8178 SCIP_VARTYPE vartype, /**< new type of variable */
8179 SCIP_Bool* infeasible /**< pointer to store whether an infeasibility was detected (, due to
8180 * integrality condition of the new variable type) */
8181 )
8182{
8184
8185 assert(var != NULL);
8186 assert(var->scip == scip);
8187
8188 if( SCIPvarIsNegated(var) )
8189 {
8190 SCIPdebugMsg(scip, "upgrading type of negated variable <%s> from %d to %d\n", SCIPvarGetName(var), SCIPvarGetType(var), vartype);
8192 }
8193#ifndef NDEBUG
8194 else
8195 {
8197 {
8198 SCIPdebugMsg(scip, "upgrading type of variable <%s> from %d to %d\n", SCIPvarGetName(var), SCIPvarGetType(var), vartype);
8199 }
8200 }
8201#endif
8202
8203 /* change variable type */
8204 switch( scip->set->stage )
8205 {
8206 case SCIP_STAGE_PROBLEM:
8208
8209 /* first adjust the variable due to new integrality information */
8210 SCIP_CALL( tightenBounds(scip, var, vartype, infeasible) );
8211
8212 /* second change variable type */
8213 if( SCIPvarGetProbindex(var) >= 0 )
8214 {
8215 SCIP_CALL( SCIPprobChgVarType(scip->origprob, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8216 scip->branchcand, scip->eventqueue, scip->cliquetable, var, vartype) );
8217 }
8218 else
8219 {
8220 SCIP_CALL( SCIPvarChgType(var, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8221 scip->eventqueue, vartype) );
8222 }
8223 break;
8224
8227 {
8228 SCIP_VAR* transvar;
8229
8230 SCIP_CALL( SCIPgetTransformedVar(scip, var, &transvar) );
8231 assert(transvar != NULL);
8232
8233 /* recall method with transformed variable */
8234 SCIP_CALL( SCIPchgVarType(scip, transvar, vartype, infeasible) );
8235 return SCIP_OKAY;
8236 }
8237
8238 /* first adjust the variable due to new integrality information */
8239 SCIP_CALL( tightenBounds(scip, var, vartype, infeasible) );
8240
8241 /* second change variable type */
8242 if( SCIPvarGetProbindex(var) >= 0 )
8243 {
8244 SCIP_CALL( SCIPprobChgVarType(scip->transprob, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8245 scip->branchcand, scip->eventqueue, scip->cliquetable, var, vartype) );
8246 }
8247 else
8248 {
8249 SCIP_CALL( SCIPvarChgType(var, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8250 scip->eventqueue, vartype) );
8251 }
8252 break;
8253
8254 default:
8255 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
8256 return SCIP_INVALIDCALL;
8257 } /*lint !e788*/
8258
8259 return SCIP_OKAY;
8260}
8261
8262/** in problem creation and solving stage, both bounds of the variable are set to the given value;
8263 * in presolving stage, the variable is converted into a fixed variable, and bounds are changed respectively;
8264 * conversion into a fixed variable changes the vars array returned from SCIPgetVars() and SCIPgetVarsData(),
8265 * and also renders arrays returned from the SCIPvarGetImpl...() methods invalid
8266 *
8267 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8268 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8269 *
8270 * @pre This method can be called if @p scip is in one of the following stages:
8271 * - \ref SCIP_STAGE_PROBLEM
8272 * - \ref SCIP_STAGE_PRESOLVING
8273 * - \ref SCIP_STAGE_SOLVING
8274 */
8276 SCIP* scip, /**< SCIP data structure */
8277 SCIP_VAR* var, /**< variable to fix */
8278 SCIP_Real fixedval, /**< value to fix variable to */
8279 SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
8280 SCIP_Bool* fixed /**< pointer to store whether the fixing was performed (variable was unfixed) */
8281 )
8282{
8283 assert(var != NULL);
8284 assert(infeasible != NULL);
8285 assert(fixed != NULL);
8286
8288
8289 *infeasible = FALSE;
8290 *fixed = FALSE;
8291
8292 /* in the problem creation stage, modify the bounds as requested, independently from the current bounds */
8293 if( scip->set->stage != SCIP_STAGE_PROBLEM )
8294 {
8296 || SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetLbLocal(var))
8297 || SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8298 {
8299 *infeasible = TRUE;
8300 return SCIP_OKAY;
8301 }
8303 {
8304 *infeasible = !SCIPsetIsFeasEQ(scip->set, fixedval, SCIPvarGetLbLocal(var));
8305 return SCIP_OKAY;
8306 }
8307 }
8308 else
8310
8311 switch( scip->set->stage )
8312 {
8313 case SCIP_STAGE_PROBLEM:
8314 /* in the problem creation stage, modify the bounds as requested, independently from the current bounds;
8315 * we have to make sure, that the order of the bound changes does not intermediately produce an invalid
8316 * interval lb > ub
8317 */
8318 if( fixedval <= SCIPvarGetLbLocal(var) )
8319 {
8320 SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
8321 SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
8322 *fixed = TRUE;
8323 }
8324 else
8325 {
8326 SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
8327 SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
8328 *fixed = TRUE;
8329 }
8330 return SCIP_OKAY;
8331
8333 if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
8334 {
8335 SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8336 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8337 scip->cliquetable, fixedval, infeasible, fixed) );
8338 return SCIP_OKAY;
8339 }
8340 /*lint -fallthrough*/
8341 case SCIP_STAGE_SOLVING:
8342 if( SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetLbLocal(var)) )
8343 {
8344 if( SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8345 {
8346 *infeasible = TRUE;
8347 return SCIP_OKAY;
8348 }
8349 else
8350 {
8351 SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
8352 *fixed = TRUE;
8353 }
8354 }
8355 if( SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8356 {
8357 if( SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetLbLocal(var)) )
8358 {
8359 *infeasible = TRUE;
8360 return SCIP_OKAY;
8361 }
8362 else
8363 {
8364 SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
8365 *fixed = TRUE;
8366 }
8367 }
8368 return SCIP_OKAY;
8369
8370 default:
8371 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
8372 return SCIP_INVALIDCALL;
8373 } /*lint !e788*/
8374}
8375
8376/** From a given equality a*x + b*y == c, aggregates one of the variables and removes it from the set of
8377 * active problem variables. This changes the vars array returned from SCIPgetVars() and SCIPgetVarsData(),
8378 * and also renders the arrays returned from the SCIPvarGetImpl...() methods for the two variables invalid.
8379 * In the first step, the equality is transformed into an equality with active problem variables
8380 * a'*x' + b'*y' == c'. If x' == y', this leads to the detection of redundancy if a' == -b' and c' == 0,
8381 * of infeasibility, if a' == -b' and c' != 0, or to a variable fixing x' == c'/(a'+b') (and possible
8382 * infeasibility) otherwise.
8383 * In the second step, the variable to be aggregated is chosen among x' and y', prefering a less strict variable
8384 * type as aggregation variable (i.e. continuous variables are preferred over implicit integers, implicit integers
8385 * over integers, and integers over binaries). If none of the variables is continuous, it is tried to find an integer
8386 * aggregation (i.e. integral coefficients a'' and b'', such that a''*x' + b''*y' == c''). This can lead to
8387 * the detection of infeasibility (e.g. if c'' is fractional), or to a rejection of the aggregation (denoted by
8388 * aggregated == FALSE), if the resulting integer coefficients are too large and thus numerically instable.
8389 *
8390 * The output flags have the following meaning:
8391 * - infeasible: the problem is infeasible
8392 * - redundant: the equality can be deleted from the constraint set
8393 * - aggregated: the aggregation was successfully performed (the variables were not aggregated before)
8394 *
8395 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8396 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8397 *
8398 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PRESOLVING
8399 */
8401 SCIP* scip, /**< SCIP data structure */
8402 SCIP_VAR* varx, /**< variable x in equality a*x + b*y == c */
8403 SCIP_VAR* vary, /**< variable y in equality a*x + b*y == c */
8404 SCIP_Real scalarx, /**< multiplier a in equality a*x + b*y == c */
8405 SCIP_Real scalary, /**< multiplier b in equality a*x + b*y == c */
8406 SCIP_Real rhs, /**< right hand side c in equality a*x + b*y == c */
8407 SCIP_Bool* infeasible, /**< pointer to store whether the aggregation is infeasible */
8408 SCIP_Bool* redundant, /**< pointer to store whether the equality is (now) redundant */
8409 SCIP_Bool* aggregated /**< pointer to store whether the aggregation was successful */
8410 )
8411{
8412 SCIP_Real constantx;
8413 SCIP_Real constanty;
8414
8415 assert(infeasible != NULL);
8416 assert(redundant != NULL);
8417 assert(aggregated != NULL);
8418
8420
8421 *infeasible = FALSE;
8422 *redundant = FALSE;
8423 *aggregated = FALSE;
8424
8425 if( SCIPtreeProbing(scip->tree) )
8426 {
8427 SCIPerrorMessage("cannot aggregate variables during probing\n");
8428 return SCIP_INVALIDCALL;
8429 }
8430 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
8431
8432 /* do not perform aggregation if it is globally deactivated */
8433 if( scip->set->presol_donotaggr )
8434 return SCIP_OKAY;
8435
8436 /* get the corresponding equality in active problem variable space:
8437 * transform both expressions "a*x + 0" and "b*y + 0" into problem variable space
8438 */
8439 constantx = 0.0;
8440 constanty = 0.0;
8441 SCIP_CALL( SCIPvarGetProbvarSum(&varx, scip->set, &scalarx, &constantx) );
8442 SCIP_CALL( SCIPvarGetProbvarSum(&vary, scip->set, &scalary, &constanty) );
8443
8444 /* we cannot aggregate multi-aggregated variables */
8446 return SCIP_OKAY;
8447
8448 /* move the constant to the right hand side to acquire the form "a'*x' + b'*y' == c'" */
8449 rhs -= (constantx + constanty);
8450
8451 /* if a scalar is zero, treat the variable as fixed-to-zero variable */
8452 if( SCIPsetIsZero(scip->set, scalarx) )
8453 varx = NULL;
8454 if( SCIPsetIsZero(scip->set, scalary) )
8455 vary = NULL;
8456
8457 /* capture the special cases that less than two variables are left, due to resolutions to a fixed variable or
8458 * to the same active variable
8459 */
8460 if( varx == NULL && vary == NULL )
8461 {
8462 /* both variables were resolved to fixed variables */
8463 *infeasible = !SCIPsetIsZero(scip->set, rhs);
8464 *redundant = TRUE;
8465 }
8466 else if( varx == NULL )
8467 {
8468 assert(SCIPsetIsZero(scip->set, scalarx));
8469 assert(!SCIPsetIsZero(scip->set, scalary));
8470
8471 /* variable x was resolved to fixed variable: variable y can be fixed to c'/b' */
8472 SCIP_CALL( SCIPvarFix(vary, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8473 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8474 scip->cliquetable, rhs/scalary, infeasible, aggregated) );
8475 *redundant = TRUE;
8476 }
8477 else if( vary == NULL )
8478 {
8479 assert(SCIPsetIsZero(scip->set, scalary));
8480 assert(!SCIPsetIsZero(scip->set, scalarx));
8481
8482 /* variable y was resolved to fixed variable: variable x can be fixed to c'/a' */
8483 SCIP_CALL( SCIPvarFix(varx, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8484 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8485 scip->cliquetable, rhs/scalarx, infeasible, aggregated) );
8486 *redundant = TRUE;
8487 }
8488 else if( varx == vary )
8489 {
8490 /* both variables were resolved to the same active problem variable: this variable can be fixed */
8491 scalarx += scalary;
8492 if( SCIPsetIsZero(scip->set, scalarx) )
8493 {
8494 /* left hand side of equality is zero: equality is potentially infeasible */
8495 *infeasible = !SCIPsetIsZero(scip->set, rhs);
8496 }
8497 else
8498 {
8499 /* sum of scalars is not zero: fix variable x' == y' to c'/(a'+b') */
8500 SCIP_CALL( SCIPvarFix(varx, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8501 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8502 scip->cliquetable, rhs/scalarx, infeasible, aggregated) );
8503 }
8504 *redundant = TRUE;
8505 }
8506 else
8507 {
8508 /* both variables are different active problem variables, and both scalars are non-zero: try to aggregate them */
8509 SCIP_CALL( SCIPvarTryAggregateVars(scip->set, scip->mem->probmem, scip->stat, scip->transprob, scip->origprob,
8510 scip->primal, scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventfilter,
8511 scip->eventqueue, varx, vary, scalarx, scalary, rhs, infeasible, aggregated) );
8512 *redundant = *aggregated;
8513 }
8514
8515 return SCIP_OKAY;
8516}
8517
8518/** converts variable into multi-aggregated variable; this changes the variable array returned from
8519 * SCIPgetVars() and SCIPgetVarsData();
8520 *
8521 * @warning The integrality condition is not checked anymore on the multi-aggregated variable. You must not
8522 * multi-aggregate an integer variable without being sure, that integrality on the aggregation variables
8523 * implies integrality on the aggregated variable.
8524 *
8525 * The output flags have the following meaning:
8526 * - infeasible: the problem is infeasible
8527 * - aggregated: the aggregation was successfully performed (the variables were not aggregated before)
8528 *
8529 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8530 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8531 *
8532 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PRESOLVING
8533 */
8535 SCIP* scip, /**< SCIP data structure */
8536 SCIP_VAR* var, /**< variable x to aggregate */
8537 int naggvars, /**< number n of variables in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8538 SCIP_VAR** aggvars, /**< variables y_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8539 SCIP_Real* scalars, /**< multipliers a_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8540 SCIP_Real constant, /**< constant shift c in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8541 SCIP_Bool* infeasible, /**< pointer to store whether the aggregation is infeasible */
8542 SCIP_Bool* aggregated /**< pointer to store whether the aggregation was successful */
8543 )
8544{
8545 SCIP_CALL( SCIPcheckStage(scip, "SCIPmultiaggregateVar", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
8546
8547 assert(var->scip == scip);
8548
8549 if( SCIPtreeProbing(scip->tree) )
8550 {
8551 SCIPerrorMessage("cannot multi-aggregate variables during probing\n");
8552 return SCIP_INVALIDCALL;
8553 }
8554 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
8555
8556 SCIP_CALL( SCIPvarMultiaggregate(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8557 scip->primal, scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventfilter,
8558 scip->eventqueue, naggvars, aggvars, scalars, constant, infeasible, aggregated) );
8559
8560 return SCIP_OKAY;
8561}
8562
8563/** returns whether aggregation of variables is not allowed */
8565 SCIP* scip /**< SCIP data structure */
8566 )
8567{
8568 assert(scip != NULL);
8569
8570 return scip->set->presol_donotaggr;
8571}
8572
8573/** returns whether multi-aggregation is disabled */
8575 SCIP* scip /**< SCIP data structure */
8576 )
8577{
8578 assert(scip != NULL);
8579
8580 return scip->set->presol_donotmultaggr;
8581}
8582
8583/** returns whether variable is not allowed to be aggregated */
8585 SCIP* scip, /**< SCIP data structure */
8586 SCIP_VAR* var /**< variable x to aggregate */
8587 )
8588{
8589 assert(scip != NULL);
8590 assert(var != NULL);
8591 assert(var->scip == scip);
8592
8593 return scip->set->presol_donotaggr || SCIPvarDoNotAggr(var);
8594}
8595
8596/** returns whether variable is not allowed to be multi-aggregated */
8598 SCIP* scip, /**< SCIP data structure */
8599 SCIP_VAR* var /**< variable x to aggregate */
8600 )
8601{
8602 assert(scip != NULL);
8603 assert(var != NULL);
8604 assert(var->scip == scip);
8605
8606 return scip->set->presol_donotmultaggr || SCIPvarDoNotMultaggr(var);
8607}
8608
8609/** returns whether dual reductions are allowed during propagation and presolving
8610 *
8611 * @deprecated Please use SCIPallowStrongDualReds()
8612 */
8614 SCIP* scip /**< SCIP data structure */
8615 )
8616{
8617 assert(scip != NULL);
8618
8619 return !scip->set->reopt_enable && scip->set->misc_allowstrongdualreds;
8620}
8621
8622/** returns whether strong dual reductions are allowed during propagation and presolving
8623 *
8624 * @note A reduction is called strong dual, if it may discard feasible/optimal solutions, but leaves at least one
8625 * optimal solution intact. Often such reductions are based on analyzing the objective function and variable
8626 * locks.
8627 */
8629 SCIP* scip /**< SCIP data structure */
8630 )
8631{
8632 assert(scip != NULL);
8633
8634 return !scip->set->reopt_enable && scip->set->misc_allowstrongdualreds;
8635}
8636
8637/** returns whether propagation w.r.t. current objective is allowed
8638 *
8639 * @deprecated Please use SCIPallowWeakDualReds()
8640 */
8642 SCIP* scip /**< SCIP data structure */
8643 )
8644{
8645 assert(scip != NULL);
8646
8647 return !scip->set->reopt_enable && scip->set->misc_allowweakdualreds;
8648}
8649
8650/** returns whether weak dual reductions are allowed during propagation and presolving
8651 *
8652 * @note A reduction is called weak dual, if it may discard feasible solutions, but leaves at all optimal solutions
8653 * intact. Often such reductions are based on analyzing the objective function, reduced costs, and/or dual LPs.
8654 */
8656 SCIP* scip /**< SCIP data structure */
8657 )
8658{
8659 assert(scip != NULL);
8660
8661 return !scip->set->reopt_enable && scip->set->misc_allowweakdualreds;
8662}
8663
8664/** marks the variable that it must not be aggregated
8665 *
8666 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8667 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8668 *
8669 * @pre This method can be called if @p scip is in one of the following stages:
8670 * - \ref SCIP_STAGE_INIT
8671 * - \ref SCIP_STAGE_PROBLEM
8672 * - \ref SCIP_STAGE_TRANSFORMING
8673 * - \ref SCIP_STAGE_TRANSFORMED
8674 * - \ref SCIP_STAGE_INITPRESOLVE
8675 * - \ref SCIP_STAGE_PRESOLVING
8676 * - \ref SCIP_STAGE_EXITPRESOLVE
8677 *
8678 * @note There exists no "unmark" method since it has to be ensured that if a plugin requires that a variable is not
8679 * aggregated that this is will be the case.
8680 */
8682 SCIP* scip, /**< SCIP data structure */
8683 SCIP_VAR* var /**< variable to delete */
8684 )
8685{
8686 assert(scip != NULL);
8687 assert(var != NULL);
8688 assert(var->scip == scip);
8689
8690 SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkDoNotAggrVar", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE) );
8691
8693
8694 return SCIP_OKAY;
8695}
8696
8697/** marks the variable that it must not be multi-aggregated
8698 *
8699 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8700 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8701 *
8702 * @pre This method can be called if @p scip is in one of the following stages:
8703 * - \ref SCIP_STAGE_INIT
8704 * - \ref SCIP_STAGE_PROBLEM
8705 * - \ref SCIP_STAGE_TRANSFORMING
8706 * - \ref SCIP_STAGE_TRANSFORMED
8707 * - \ref SCIP_STAGE_INITPRESOLVE
8708 * - \ref SCIP_STAGE_PRESOLVING
8709 * - \ref SCIP_STAGE_EXITPRESOLVE
8710 *
8711 * @note There exists no "unmark" method since it has to be ensured that if a plugin requires that a variable is not
8712 * multi-aggregated that this is will be the case.
8713 */
8715 SCIP* scip, /**< SCIP data structure */
8716 SCIP_VAR* var /**< variable to delete */
8717 )
8718{
8719 assert(scip != NULL);
8720 assert(var != NULL);
8721 assert(var->scip == scip);
8722
8723 SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkDoNotMultaggrVar", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE) );
8724
8726
8727 return SCIP_OKAY;
8728}
8729
8730/** enables the collection of statistics for a variable
8731 *
8732 * @pre This method can be called if @p scip is in one of the following stages:
8733 * - \ref SCIP_STAGE_PROBLEM
8734 * - \ref SCIP_STAGE_INITPRESOLVE
8735 * - \ref SCIP_STAGE_PRESOLVING
8736 * - \ref SCIP_STAGE_EXITPRESOLVE
8737 * - \ref SCIP_STAGE_SOLVING
8738 * - \ref SCIP_STAGE_SOLVED
8739 */
8741 SCIP* scip /**< SCIP data structure */
8742 )
8743{
8744 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPenableVarHistory", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8745
8747}
8748
8749/** disables the collection of any statistic for a variable
8750 *
8751 * @pre This method can be called if @p scip is in one of the following stages:
8752 * - \ref SCIP_STAGE_PROBLEM
8753 * - \ref SCIP_STAGE_INITPRESOLVE
8754 * - \ref SCIP_STAGE_PRESOLVING
8755 * - \ref SCIP_STAGE_EXITPRESOLVE
8756 * - \ref SCIP_STAGE_SOLVING
8757 * - \ref SCIP_STAGE_SOLVED
8758 */
8760 SCIP* scip /**< SCIP data structure */
8761 )
8762{
8763 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPdisableVarHistory", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8764
8766}
8767
8768/** updates the pseudo costs of the given variable and the global pseudo costs after a change of "solvaldelta" in the
8769 * variable's solution value and resulting change of "objdelta" in the in the LP's objective value;
8770 * the update is ignored, if the objective value difference is infinite
8771 *
8772 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8773 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8774 *
8775 * @pre This method can be called if @p scip is in one of the following stages:
8776 * - \ref SCIP_STAGE_SOLVING
8777 * - \ref SCIP_STAGE_SOLVED
8778 */
8780 SCIP* scip, /**< SCIP data structure */
8781 SCIP_VAR* var, /**< problem variable */
8782 SCIP_Real solvaldelta, /**< difference of variable's new LP value - old LP value */
8783 SCIP_Real objdelta, /**< difference of new LP's objective value - old LP's objective value */
8784 SCIP_Real weight /**< weight in (0,1] of this update in pseudo cost sum */
8785 )
8786{
8787 SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateVarPseudocost", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8788
8789 if( !SCIPsetIsInfinity(scip->set, 2*objdelta) ) /* differences infinity - eps should also be treated as infinity */
8790 {
8791 if( scip->set->branch_divingpscost || (!scip->lp->diving && !SCIPtreeProbing(scip->tree)) )
8792 {
8793 SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, solvaldelta, objdelta, weight) );
8794 }
8795 }
8796
8797 return SCIP_OKAY;
8798}
8799
8800/** gets the variable's pseudo cost value for the given change of the variable's LP value
8801 *
8802 * @return the variable's pseudo cost value for the given change of the variable's LP value
8803 *
8804 * @pre This method can be called if @p scip is in one of the following stages:
8805 * - \ref SCIP_STAGE_INITPRESOLVE
8806 * - \ref SCIP_STAGE_PRESOLVING
8807 * - \ref SCIP_STAGE_EXITPRESOLVE
8808 * - \ref SCIP_STAGE_PRESOLVED
8809 * - \ref SCIP_STAGE_INITSOLVE
8810 * - \ref SCIP_STAGE_SOLVING
8811 * - \ref SCIP_STAGE_SOLVED
8812 */
8814 SCIP* scip, /**< SCIP data structure */
8815 SCIP_VAR* var, /**< problem variable */
8816 SCIP_Real solvaldelta /**< difference of variable's new LP value - old LP value */
8817 )
8818{
8819 assert( var->scip == scip );
8820
8821 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostVal", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8822
8823 return SCIPvarGetPseudocost(var, scip->stat, solvaldelta);
8824}
8825
8826/** gets the variable's pseudo cost value for the given change of the variable's LP value,
8827 * only using the pseudo cost information of the current run
8828 *
8829 * @return the variable's pseudo cost value for the given change of the variable's LP value,
8830 * only using the pseudo cost information of the current run
8831 *
8832 * @pre This method can be called if @p scip is in one of the following stages:
8833 * - \ref SCIP_STAGE_INITPRESOLVE
8834 * - \ref SCIP_STAGE_PRESOLVING
8835 * - \ref SCIP_STAGE_EXITPRESOLVE
8836 * - \ref SCIP_STAGE_PRESOLVED
8837 * - \ref SCIP_STAGE_INITSOLVE
8838 * - \ref SCIP_STAGE_SOLVING
8839 * - \ref SCIP_STAGE_SOLVED
8840 */
8842 SCIP* scip, /**< SCIP data structure */
8843 SCIP_VAR* var, /**< problem variable */
8844 SCIP_Real solvaldelta /**< difference of variable's new LP value - old LP value */
8845 )
8846{
8847 assert( var->scip == scip );
8848
8849 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostValCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8850
8851 return SCIPvarGetPseudocostCurrentRun(var, scip->stat, solvaldelta);
8852}
8853
8854/** gets the variable's pseudo cost value for the given direction
8855 *
8856 * @return the variable's pseudo cost value for the given direction
8857 *
8858 * @pre This method can be called if @p scip is in one of the following stages:
8859 * - \ref SCIP_STAGE_INITPRESOLVE
8860 * - \ref SCIP_STAGE_PRESOLVING
8861 * - \ref SCIP_STAGE_EXITPRESOLVE
8862 * - \ref SCIP_STAGE_PRESOLVED
8863 * - \ref SCIP_STAGE_INITSOLVE
8864 * - \ref SCIP_STAGE_SOLVING
8865 * - \ref SCIP_STAGE_SOLVED
8866 */
8868 SCIP* scip, /**< SCIP data structure */
8869 SCIP_VAR* var, /**< problem variable */
8870 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8871 )
8872{
8873 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocost", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8875 assert(var->scip == scip);
8876
8877 return SCIPvarGetPseudocost(var, scip->stat, dir == SCIP_BRANCHDIR_DOWNWARDS ? -1.0 : 1.0);
8878}
8879
8880/** gets the variable's pseudo cost value for the given direction,
8881 * only using the pseudo cost information of the current run
8882 *
8883 * @return the variable's pseudo cost value for the given direction,
8884 * only using the pseudo cost information of the current run
8885 *
8886 * @pre This method can be called if @p scip is in one of the following stages:
8887 * - \ref SCIP_STAGE_INITPRESOLVE
8888 * - \ref SCIP_STAGE_PRESOLVING
8889 * - \ref SCIP_STAGE_EXITPRESOLVE
8890 * - \ref SCIP_STAGE_PRESOLVED
8891 * - \ref SCIP_STAGE_INITSOLVE
8892 * - \ref SCIP_STAGE_SOLVING
8893 * - \ref SCIP_STAGE_SOLVED
8894 */
8896 SCIP* scip, /**< SCIP data structure */
8897 SCIP_VAR* var, /**< problem variable */
8898 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8899 )
8900{
8901 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8903 assert(var->scip == scip);
8904
8905 return SCIPvarGetPseudocostCurrentRun(var, scip->stat, dir == SCIP_BRANCHDIR_DOWNWARDS ? -1.0 : 1.0);
8906}
8907
8908/** gets the variable's (possible fractional) number of pseudo cost updates for the given direction
8909 *
8910 * @return the variable's (possible fractional) number of pseudo cost updates for the given direction
8911 *
8912 * @pre This method can be called if @p scip is in one of the following stages:
8913 * - \ref SCIP_STAGE_INITPRESOLVE
8914 * - \ref SCIP_STAGE_PRESOLVING
8915 * - \ref SCIP_STAGE_EXITPRESOLVE
8916 * - \ref SCIP_STAGE_PRESOLVED
8917 * - \ref SCIP_STAGE_INITSOLVE
8918 * - \ref SCIP_STAGE_SOLVING
8919 * - \ref SCIP_STAGE_SOLVED
8920 */
8922 SCIP* scip, /**< SCIP data structure */
8923 SCIP_VAR* var, /**< problem variable */
8924 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8925 )
8926{
8927 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCount", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8929 assert(var->scip == scip);
8930
8931 return SCIPvarGetPseudocostCount(var, dir);
8932}
8933
8934/** gets the variable's (possible fractional) number of pseudo cost updates for the given direction,
8935 * only using the pseudo cost information of the current run
8936 *
8937 * @return the variable's (possible fractional) number of pseudo cost updates for the given direction,
8938 * only using the pseudo cost information of the current run
8939 *
8940 * @pre This method can be called if @p scip is in one of the following stages:
8941 * - \ref SCIP_STAGE_INITPRESOLVE
8942 * - \ref SCIP_STAGE_PRESOLVING
8943 * - \ref SCIP_STAGE_EXITPRESOLVE
8944 * - \ref SCIP_STAGE_PRESOLVED
8945 * - \ref SCIP_STAGE_INITSOLVE
8946 * - \ref SCIP_STAGE_SOLVING
8947 * - \ref SCIP_STAGE_SOLVED
8948 */
8950 SCIP* scip, /**< SCIP data structure */
8951 SCIP_VAR* var, /**< problem variable */
8952 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8953 )
8954{
8955 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCountCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8957 assert(var->scip == scip);
8958
8960}
8961
8962/** get pseudo cost variance of the variable, either for entire solve or only for current branch and bound run
8963 *
8964 * @return returns the (corrected) variance of pseudo code information collected so far.
8965 *
8966 * @pre This method can be called if @p scip is in one of the following stages:
8967 * - \ref SCIP_STAGE_INITPRESOLVE
8968 * - \ref SCIP_STAGE_PRESOLVING
8969 * - \ref SCIP_STAGE_EXITPRESOLVE
8970 * - \ref SCIP_STAGE_PRESOLVED
8971 * - \ref SCIP_STAGE_INITSOLVE
8972 * - \ref SCIP_STAGE_SOLVING
8973 * - \ref SCIP_STAGE_SOLVED
8974 */
8976 SCIP* scip, /**< SCIP data structure */
8977 SCIP_VAR* var, /**< problem variable */
8978 SCIP_BRANCHDIR dir, /**< branching direction (downwards, or upwards) */
8979 SCIP_Bool onlycurrentrun /**< only for pseudo costs of current branch and bound run */
8980 )
8981{
8982 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostVariance", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8984 assert(var->scip == scip);
8985
8986 return SCIPvarGetPseudocostVariance(var, dir, onlycurrentrun);
8987}
8988
8989/** calculates a confidence bound for this variable under the assumption of normally distributed pseudo costs
8990 *
8991 * The confidence bound \f$ \theta \geq 0\f$ denotes the interval borders \f$ [X - \theta, \ X + \theta]\f$, which contains
8992 * the true pseudo costs of the variable, i.e., the expected value of the normal distribution, with a probability
8993 * of 2 * clevel - 1.
8994 *
8995 * @return value of confidence bound for this variable
8996 */
8998 SCIP* scip, /**< SCIP data structure */
8999 SCIP_VAR* var, /**< variable in question */
9000 SCIP_BRANCHDIR dir, /**< the branching direction for the confidence bound */
9001 SCIP_Bool onlycurrentrun, /**< should only the current run be taken into account */
9002 SCIP_CONFIDENCELEVEL clevel /**< confidence level for the interval */
9003 )
9004{
9005 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPcalculatePscostConfidenceBound", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9006
9007 return SCIPvarCalcPscostConfidenceBound(var, scip->set, dir, onlycurrentrun, clevel);
9008}
9009
9010/** check if variable pseudo-costs have a significant difference in location. The significance depends on
9011 * the choice of \p clevel and on the kind of tested hypothesis. The one-sided hypothesis, which
9012 * should be rejected, is that fracy * mu_y >= fracx * mu_x, where mu_y and mu_x denote the
9013 * unknown location means of the underlying pseudo-cost distributions of x and y.
9014 *
9015 * This method is applied best if variable x has a better pseudo-cost score than y. The method hypothesizes that y were actually
9016 * better than x (despite the current information), meaning that y can be expected to yield branching
9017 * decisions as least as good as x in the long run. If the method returns TRUE, the current history information is
9018 * sufficient to safely rely on the alternative hypothesis that x yields indeed a better branching score (on average)
9019 * than y.
9020 *
9021 * @note The order of x and y matters for the one-sided hypothesis
9022 *
9023 * @note set \p onesided to FALSE if you are not sure which variable is better. The hypothesis tested then reads
9024 * fracy * mu_y == fracx * mu_x vs the alternative hypothesis fracy * mu_y != fracx * mu_x.
9025 *
9026 * @return TRUE if the hypothesis can be safely rejected at the given confidence level
9027 */
9029 SCIP* scip, /**< SCIP data structure */
9030 SCIP_VAR* varx, /**< variable x */
9031 SCIP_Real fracx, /**< the fractionality of variable x */
9032 SCIP_VAR* vary, /**< variable y */
9033 SCIP_Real fracy, /**< the fractionality of variable y */
9034 SCIP_BRANCHDIR dir, /**< branching direction */
9035 SCIP_CONFIDENCELEVEL clevel, /**< confidence level for rejecting hypothesis */
9036 SCIP_Bool onesided /**< should a one-sided hypothesis y >= x be tested? */
9037 )
9038{
9039 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPsignificantVarPscostDifference", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9040
9041 return SCIPvarSignificantPscostDifference(scip->set, scip->stat, varx, fracx, vary, fracy, dir, clevel, onesided);
9042}
9043
9044/** tests at a given confidence level whether the variable pseudo-costs only have a small probability to
9045 * exceed a \p threshold. This is useful to determine if past observations provide enough evidence
9046 * to skip an expensive strong-branching step if there is already a candidate that has been proven to yield an improvement
9047 * of at least \p threshold.
9048 *
9049 * @note use \p clevel to adjust the level of confidence. For SCIP_CONFIDENCELEVEL_MIN, the method returns TRUE if
9050 * the estimated probability to exceed \p threshold is less than 25 %.
9051 *
9052 * @see SCIP_Confidencelevel for a list of available levels. The used probability limits refer to the one-sided levels
9053 * of confidence.
9054 *
9055 * @return TRUE if the variable pseudo-cost probabilistic model is likely to be smaller than \p threshold
9056 * at the given confidence level \p clevel.
9057 */
9059 SCIP* scip, /**< SCIP data structure */
9060 SCIP_VAR* var, /**< variable x */
9061 SCIP_Real frac, /**< the fractionality of variable x */
9062 SCIP_Real threshold, /**< the threshold to test against */
9063 SCIP_BRANCHDIR dir, /**< branching direction */
9064 SCIP_CONFIDENCELEVEL clevel /**< confidence level for rejecting hypothesis */
9065 )
9066{
9067 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPpscostThresholdProbabilityTest", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9068
9069 return SCIPvarPscostThresholdProbabilityTest(scip->set, scip->stat, var, frac, threshold, dir, clevel);
9070}
9071
9072/** check if the current pseudo cost relative error in a direction violates the given threshold. The Relative
9073 * Error is calculated at a specific confidence level
9074 *
9075 * @return TRUE if relative error in variable pseudo costs is smaller than \p threshold
9076 */
9078 SCIP* scip, /**< SCIP data structure */
9079 SCIP_VAR* var, /**< variable in question */
9080 SCIP_Real threshold, /**< threshold for relative errors to be considered reliable (enough) */
9081 SCIP_CONFIDENCELEVEL clevel /**< a given confidence level */
9082 )
9083{
9084 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisVarPscostRelerrorReliable", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9085
9086 return SCIPvarIsPscostRelerrorReliable(var, scip->set, scip->stat, threshold, clevel);
9087}
9088
9089/** gets the variable's pseudo cost score value for the given LP solution value
9090 *
9091 * @return the variable's pseudo cost score value for the given LP solution value
9092 *
9093 * @pre This method can be called if @p scip is in one of the following stages:
9094 * - \ref SCIP_STAGE_INITPRESOLVE
9095 * - \ref SCIP_STAGE_PRESOLVING
9096 * - \ref SCIP_STAGE_EXITPRESOLVE
9097 * - \ref SCIP_STAGE_PRESOLVED
9098 * - \ref SCIP_STAGE_INITSOLVE
9099 * - \ref SCIP_STAGE_SOLVING
9100 * - \ref SCIP_STAGE_SOLVED
9101 */
9103 SCIP* scip, /**< SCIP data structure */
9104 SCIP_VAR* var, /**< problem variable */
9105 SCIP_Real solval /**< variable's LP solution value */
9106 )
9107{
9108 SCIP_Real downsol;
9109 SCIP_Real upsol;
9110 SCIP_Real pscostdown;
9111 SCIP_Real pscostup;
9112
9113 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9114
9115 assert( var->scip == scip );
9116
9117 downsol = SCIPsetFeasCeil(scip->set, solval-1.0);
9118 upsol = SCIPsetFeasFloor(scip->set, solval+1.0);
9119 pscostdown = SCIPvarGetPseudocost(var, scip->stat, downsol-solval);
9120 pscostup = SCIPvarGetPseudocost(var, scip->stat, upsol-solval);
9121
9122 return SCIPbranchGetScore(scip->set, var, pscostdown, pscostup);
9123}
9124
9125/** gets the variable's pseudo cost score value for the given LP solution value,
9126 * only using the pseudo cost information of the current run
9127 *
9128 * @return the variable's pseudo cost score value for the given LP solution value,
9129 * only using the pseudo cost information of the current run
9130 *
9131 * @pre This method can be called if @p scip is in one of the following stages:
9132 * - \ref SCIP_STAGE_INITPRESOLVE
9133 * - \ref SCIP_STAGE_PRESOLVING
9134 * - \ref SCIP_STAGE_EXITPRESOLVE
9135 * - \ref SCIP_STAGE_PRESOLVED
9136 * - \ref SCIP_STAGE_INITSOLVE
9137 * - \ref SCIP_STAGE_SOLVING
9138 * - \ref SCIP_STAGE_SOLVED
9139 */
9141 SCIP* scip, /**< SCIP data structure */
9142 SCIP_VAR* var, /**< problem variable */
9143 SCIP_Real solval /**< variable's LP solution value */
9144 )
9145{
9146 SCIP_Real downsol;
9147 SCIP_Real upsol;
9148 SCIP_Real pscostdown;
9149 SCIP_Real pscostup;
9150
9151 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9152
9153 assert( var->scip == scip );
9154
9155 downsol = SCIPsetFeasCeil(scip->set, solval-1.0);
9156 upsol = SCIPsetFeasFloor(scip->set, solval+1.0);
9157 pscostdown = SCIPvarGetPseudocostCurrentRun(var, scip->stat, downsol-solval);
9158 pscostup = SCIPvarGetPseudocostCurrentRun(var, scip->stat, upsol-solval);
9159
9160 return SCIPbranchGetScore(scip->set, var, pscostdown, pscostup);
9161}
9162
9163/** returns the variable's VSIDS value
9164 *
9165 * @return the variable's VSIDS value
9166 *
9167 * @pre This method can be called if @p scip is in one of the following stages:
9168 * - \ref SCIP_STAGE_INITPRESOLVE
9169 * - \ref SCIP_STAGE_PRESOLVING
9170 * - \ref SCIP_STAGE_EXITPRESOLVE
9171 * - \ref SCIP_STAGE_PRESOLVED
9172 * - \ref SCIP_STAGE_INITSOLVE
9173 * - \ref SCIP_STAGE_SOLVING
9174 * - \ref SCIP_STAGE_SOLVED
9175 */
9177 SCIP* scip, /**< SCIP data structure */
9178 SCIP_VAR* var, /**< problem variable */
9179 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9180 )
9181{
9183
9184 assert( var->scip == scip );
9185
9187 {
9188 SCIPerrorMessage("invalid branching direction %d when asking for VSIDS value\n", dir);
9189 return SCIP_INVALID;
9190 }
9191
9192 return SCIPvarGetVSIDS(var, scip->stat, dir);
9193}
9194
9195/** returns the variable's VSIDS value only using conflicts of the current run
9196 *
9197 * @return the variable's VSIDS value only using conflicts of the current run
9198 *
9199 * @pre This method can be called if @p scip is in one of the following stages:
9200 * - \ref SCIP_STAGE_INITPRESOLVE
9201 * - \ref SCIP_STAGE_PRESOLVING
9202 * - \ref SCIP_STAGE_EXITPRESOLVE
9203 * - \ref SCIP_STAGE_PRESOLVED
9204 * - \ref SCIP_STAGE_INITSOLVE
9205 * - \ref SCIP_STAGE_SOLVING
9206 * - \ref SCIP_STAGE_SOLVED
9207 */
9209 SCIP* scip, /**< SCIP data structure */
9210 SCIP_VAR* var, /**< problem variable */
9211 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9212 )
9213{
9214 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarVSIDSCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9215
9216 assert( var->scip == scip );
9217
9219 {
9220 SCIPerrorMessage("invalid branching direction %d when asking for VSIDS value\n", dir);
9221 return SCIP_INVALID;
9222 }
9223
9224 return SCIPvarGetVSIDSCurrentRun(var, scip->stat, dir);
9225}
9226
9227/** returns the variable's conflict score value
9228 *
9229 * @return the variable's conflict score value
9230 *
9231 * @pre This method can be called if @p scip is in one of the following stages:
9232 * - \ref SCIP_STAGE_INITPRESOLVE
9233 * - \ref SCIP_STAGE_PRESOLVING
9234 * - \ref SCIP_STAGE_EXITPRESOLVE
9235 * - \ref SCIP_STAGE_PRESOLVED
9236 * - \ref SCIP_STAGE_INITSOLVE
9237 * - \ref SCIP_STAGE_SOLVING
9238 * - \ref SCIP_STAGE_SOLVED
9239 */
9241 SCIP* scip, /**< SCIP data structure */
9242 SCIP_VAR* var /**< problem variable */
9243 )
9244{
9245 SCIP_Real downscore;
9246 SCIP_Real upscore;
9247
9248 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9249
9250 assert( var->scip == scip );
9251
9252 downscore = SCIPvarGetVSIDS(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9254
9255 return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9256}
9257
9258/** returns the variable's conflict score value only using conflicts of the current run
9259 *
9260 * @return the variable's conflict score value only using conflicts of the current run
9261 *
9262 * @pre This method can be called if @p scip is in one of the following stages:
9263 * - \ref SCIP_STAGE_INITPRESOLVE
9264 * - \ref SCIP_STAGE_PRESOLVING
9265 * - \ref SCIP_STAGE_EXITPRESOLVE
9266 * - \ref SCIP_STAGE_PRESOLVED
9267 * - \ref SCIP_STAGE_INITSOLVE
9268 * - \ref SCIP_STAGE_SOLVING
9269 * - \ref SCIP_STAGE_SOLVED
9270 */
9272 SCIP* scip, /**< SCIP data structure */
9273 SCIP_VAR* var /**< problem variable */
9274 )
9275{
9276 SCIP_Real downscore;
9277 SCIP_Real upscore;
9278
9279 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9280
9281 assert( var->scip == scip );
9282
9285
9286 return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9287}
9288
9289/** returns the variable's conflict length score
9290 *
9291 * @return the variable's conflict length score
9292 *
9293 * @pre This method can be called if @p scip is in one of the following stages:
9294 * - \ref SCIP_STAGE_INITPRESOLVE
9295 * - \ref SCIP_STAGE_PRESOLVING
9296 * - \ref SCIP_STAGE_EXITPRESOLVE
9297 * - \ref SCIP_STAGE_PRESOLVED
9298 * - \ref SCIP_STAGE_INITSOLVE
9299 * - \ref SCIP_STAGE_SOLVING
9300 * - \ref SCIP_STAGE_SOLVED
9301 */
9303 SCIP* scip, /**< SCIP data structure */
9304 SCIP_VAR* var /**< problem variable */
9305 )
9306{
9307 SCIP_Real downscore;
9308 SCIP_Real upscore;
9309
9310 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictlengthScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9311
9312 assert( var->scip == scip );
9313
9316
9317 return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9318}
9319
9320/** returns the variable's conflict length score only using conflicts of the current run
9321 *
9322 * @return the variable's conflict length score only using conflicts of the current run
9323 *
9324 * @pre This method can be called if @p scip is in one of the following stages:
9325 * - \ref SCIP_STAGE_INITPRESOLVE
9326 * - \ref SCIP_STAGE_PRESOLVING
9327 * - \ref SCIP_STAGE_EXITPRESOLVE
9328 * - \ref SCIP_STAGE_PRESOLVED
9329 * - \ref SCIP_STAGE_INITSOLVE
9330 * - \ref SCIP_STAGE_SOLVING
9331 * - \ref SCIP_STAGE_SOLVED
9332 */
9334 SCIP* scip, /**< SCIP data structure */
9335 SCIP_VAR* var /**< problem variable */
9336 )
9337{
9338 SCIP_Real downscore;
9339 SCIP_Real upscore;
9340
9341 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictlengthScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9342
9343 assert( var->scip == scip );
9344
9347
9348 return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9349}
9350
9351/** returns the variable's average conflict length
9352 *
9353 * @return the variable's average conflict length
9354 *
9355 * @pre This method can be called if @p scip is in one of the following stages:
9356 * - \ref SCIP_STAGE_INITPRESOLVE
9357 * - \ref SCIP_STAGE_PRESOLVING
9358 * - \ref SCIP_STAGE_EXITPRESOLVE
9359 * - \ref SCIP_STAGE_PRESOLVED
9360 * - \ref SCIP_STAGE_INITSOLVE
9361 * - \ref SCIP_STAGE_SOLVING
9362 * - \ref SCIP_STAGE_SOLVED
9363 */
9365 SCIP* scip, /**< SCIP data structure */
9366 SCIP_VAR* var, /**< problem variable */
9367 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9368 )
9369{
9370 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgConflictlength", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9371
9372 assert( var->scip == scip );
9373
9374 return SCIPvarGetAvgConflictlength(var, dir);
9375}
9376
9377/** returns the variable's average conflict length only using conflicts of the current run
9378 *
9379 * @return the variable's average conflict length only using conflicts of the current run
9380 *
9381 * @pre This method can be called if @p scip is in one of the following stages:
9382 * - \ref SCIP_STAGE_INITPRESOLVE
9383 * - \ref SCIP_STAGE_PRESOLVING
9384 * - \ref SCIP_STAGE_EXITPRESOLVE
9385 * - \ref SCIP_STAGE_PRESOLVED
9386 * - \ref SCIP_STAGE_INITSOLVE
9387 * - \ref SCIP_STAGE_SOLVING
9388 * - \ref SCIP_STAGE_SOLVED
9389 */
9391 SCIP* scip, /**< SCIP data structure */
9392 SCIP_VAR* var, /**< problem variable */
9393 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9394 )
9395{
9396 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgConflictlengthCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9397
9398 assert( var->scip == scip );
9399
9401}
9402
9403/** returns the average number of inferences found after branching on the variable in given direction;
9404 * if branching on the variable in the given direction was yet evaluated, the average number of inferences
9405 * over all variables for branching in the given direction is returned
9406 *
9407 * @return the average number of inferences found after branching on the variable in given direction
9408 *
9409 * @pre This method can be called if @p scip is in one of the following stages:
9410 * - \ref SCIP_STAGE_INITPRESOLVE
9411 * - \ref SCIP_STAGE_PRESOLVING
9412 * - \ref SCIP_STAGE_EXITPRESOLVE
9413 * - \ref SCIP_STAGE_PRESOLVED
9414 * - \ref SCIP_STAGE_INITSOLVE
9415 * - \ref SCIP_STAGE_SOLVING
9416 * - \ref SCIP_STAGE_SOLVED
9417 */
9419 SCIP* scip, /**< SCIP data structure */
9420 SCIP_VAR* var, /**< problem variable */
9421 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9422 )
9423{
9424 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferences", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9425
9426 assert( var->scip == scip );
9427
9428 return SCIPvarGetAvgInferences(var, scip->stat, dir);
9429}
9430
9431/** returns the average number of inferences found after branching on the variable in given direction in the current run;
9432 * if branching on the variable in the given direction was yet evaluated, the average number of inferences
9433 * over all variables for branching in the given direction is returned
9434 *
9435 * @return the average number of inferences found after branching on the variable in given direction in the current run
9436 *
9437 * @pre This method can be called if @p scip is in one of the following stages:
9438 * - \ref SCIP_STAGE_INITPRESOLVE
9439 * - \ref SCIP_STAGE_PRESOLVING
9440 * - \ref SCIP_STAGE_EXITPRESOLVE
9441 * - \ref SCIP_STAGE_PRESOLVED
9442 * - \ref SCIP_STAGE_INITSOLVE
9443 * - \ref SCIP_STAGE_SOLVING
9444 * - \ref SCIP_STAGE_SOLVED
9445 */
9447 SCIP* scip, /**< SCIP data structure */
9448 SCIP_VAR* var, /**< problem variable */
9449 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9450 )
9451{
9452 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferencesCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9453
9454 assert( var->scip == scip );
9455
9456 return SCIPvarGetAvgInferencesCurrentRun(var, scip->stat, dir);
9457}
9458
9459/** returns the variable's average inference score value
9460 *
9461 * @return the variable's average inference score value
9462 *
9463 * @pre This method can be called if @p scip is in one of the following stages:
9464 * - \ref SCIP_STAGE_INITPRESOLVE
9465 * - \ref SCIP_STAGE_PRESOLVING
9466 * - \ref SCIP_STAGE_EXITPRESOLVE
9467 * - \ref SCIP_STAGE_PRESOLVED
9468 * - \ref SCIP_STAGE_INITSOLVE
9469 * - \ref SCIP_STAGE_SOLVING
9470 * - \ref SCIP_STAGE_SOLVED
9471 */
9473 SCIP* scip, /**< SCIP data structure */
9474 SCIP_VAR* var /**< problem variable */
9475 )
9476{
9477 SCIP_Real inferdown;
9478 SCIP_Real inferup;
9479
9480 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9481
9482 assert( var->scip == scip );
9483
9486
9487 return SCIPbranchGetScore(scip->set, var, inferdown, inferup);
9488}
9489
9490/** returns the variable's average inference score value only using inferences of the current run
9491 *
9492 * @return the variable's average inference score value only using inferences of the current run
9493 *
9494 * @pre This method can be called if @p scip is in one of the following stages:
9495 * - \ref SCIP_STAGE_INITPRESOLVE
9496 * - \ref SCIP_STAGE_PRESOLVING
9497 * - \ref SCIP_STAGE_EXITPRESOLVE
9498 * - \ref SCIP_STAGE_PRESOLVED
9499 * - \ref SCIP_STAGE_INITSOLVE
9500 * - \ref SCIP_STAGE_SOLVING
9501 * - \ref SCIP_STAGE_SOLVED
9502 */
9504 SCIP* scip, /**< SCIP data structure */
9505 SCIP_VAR* var /**< problem variable */
9506 )
9507{
9508 SCIP_Real inferdown;
9509 SCIP_Real inferup;
9510
9511 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9512
9513 assert( var->scip == scip );
9514
9517
9518 return SCIPbranchGetScore(scip->set, var, inferdown, inferup);
9519}
9520
9521/** initializes the upwards and downwards pseudocosts, conflict scores, conflict lengths, inference scores, cutoff scores
9522 * of a variable to the given values
9523 *
9524 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9525 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9526 *
9527 * @pre This method can be called if @p scip is in one of the following stages:
9528 * - \ref SCIP_STAGE_TRANSFORMED
9529 * - \ref SCIP_STAGE_INITPRESOLVE
9530 * - \ref SCIP_STAGE_PRESOLVING
9531 * - \ref SCIP_STAGE_EXITPRESOLVE
9532 * - \ref SCIP_STAGE_PRESOLVED
9533 * - \ref SCIP_STAGE_INITSOLVE
9534 * - \ref SCIP_STAGE_SOLVING
9535 */
9537 SCIP* scip, /**< SCIP data structure */
9538 SCIP_VAR* var, /**< variable which should be initialized */
9539 SCIP_Real downpscost, /**< value to which pseudocosts for downwards branching should be initialized */
9540 SCIP_Real uppscost, /**< value to which pseudocosts for upwards branching should be initialized */
9541 SCIP_Real downvsids, /**< value to which VSIDS score for downwards branching should be initialized */
9542 SCIP_Real upvsids, /**< value to which VSIDS score for upwards branching should be initialized */
9543 SCIP_Real downconflen, /**< value to which conflict length score for downwards branching should be initialized */
9544 SCIP_Real upconflen, /**< value to which conflict length score for upwards branching should be initialized */
9545 SCIP_Real downinfer, /**< value to which inference counter for downwards branching should be initialized */
9546 SCIP_Real upinfer, /**< value to which inference counter for upwards branching should be initialized */
9547 SCIP_Real downcutoff, /**< value to which cutoff counter for downwards branching should be initialized */
9548 SCIP_Real upcutoff /**< value to which cutoff counter for upwards branching should be initialized */
9549 )
9550{
9551 SCIP_CALL( SCIPcheckStage(scip, "SCIPinitVarBranchStats", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
9552
9553 assert(downpscost >= 0.0 && uppscost >= 0.0);
9554 assert(downvsids >= 0.0 && upvsids >= 0.0);
9555 assert(downconflen >= 0.0 && upconflen >= 0.0);
9556 assert(downinfer >= 0.0 && upinfer >= 0.0);
9557 assert(downcutoff >= 0.0 && upcutoff >= 0.0);
9558
9559 if( !SCIPisFeasZero(scip, downpscost) || !SCIPisFeasZero(scip, downvsids)
9560 || !SCIPisFeasZero(scip, downinfer) || !SCIPisFeasZero(scip, downcutoff) )
9561 {
9563 SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, -1.0, downpscost, 1.0) );
9567 }
9568
9569 if( !SCIPisFeasZero(scip, downconflen) )
9570 {
9572 }
9573
9574 if( !SCIPisFeasZero(scip, uppscost) || !SCIPisFeasZero(scip, upvsids)
9575 || !SCIPisFeasZero(scip, upinfer) || !SCIPisFeasZero(scip, upcutoff) )
9576 {
9578 SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, 1.0, uppscost, 1.0) );
9582 }
9583
9584 if( !SCIPisFeasZero(scip, upconflen) )
9585 {
9587 }
9588
9589 return SCIP_OKAY;
9590}
9591
9592/** initializes the upwards and downwards conflict scores, conflict lengths, inference scores, cutoff scores of a
9593 * variable w.r.t. a value by the given values (SCIP_VALUEHISTORY)
9594 *
9595 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9596 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9597 *
9598 * @pre This method can be called if @p scip is in one of the following stages:
9599 * - \ref SCIP_STAGE_TRANSFORMED
9600 * - \ref SCIP_STAGE_INITPRESOLVE
9601 * - \ref SCIP_STAGE_PRESOLVING
9602 * - \ref SCIP_STAGE_EXITPRESOLVE
9603 * - \ref SCIP_STAGE_PRESOLVED
9604 * - \ref SCIP_STAGE_INITSOLVE
9605 * - \ref SCIP_STAGE_SOLVING
9606 */
9608 SCIP* scip, /**< SCIP data structure */
9609 SCIP_VAR* var, /**< variable which should be initialized */
9610 SCIP_Real value, /**< domain value, or SCIP_UNKNOWN */
9611 SCIP_Real downvsids, /**< value to which VSIDS score for downwards branching should be initialized */
9612 SCIP_Real upvsids, /**< value to which VSIDS score for upwards branching should be initialized */
9613 SCIP_Real downconflen, /**< value to which conflict length score for downwards branching should be initialized */
9614 SCIP_Real upconflen, /**< value to which conflict length score for upwards branching should be initialized */
9615 SCIP_Real downinfer, /**< value to which inference counter for downwards branching should be initialized */
9616 SCIP_Real upinfer, /**< value to which inference counter for upwards branching should be initialized */
9617 SCIP_Real downcutoff, /**< value to which cutoff counter for downwards branching should be initialized */
9618 SCIP_Real upcutoff /**< value to which cutoff counter for upwards branching should be initialized */
9619 )
9620{
9621 SCIP_CALL( SCIPcheckStage(scip, "SCIPinitVarValueBranchStats", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
9622
9623 assert(downvsids >= 0.0 && upvsids >= 0.0);
9624 assert(downconflen >= 0.0 && upconflen >= 0.0);
9625 assert(downinfer >= 0.0 && upinfer >= 0.0);
9626 assert(downcutoff >= 0.0 && upcutoff >= 0.0);
9627
9628 if( !SCIPisFeasZero(scip, downvsids) || !SCIPisFeasZero(scip, downinfer) || !SCIPisFeasZero(scip, downcutoff) )
9629 {
9632 SCIP_CALL( SCIPvarIncVSIDS(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downvsids) );
9633 SCIP_CALL( SCIPvarIncCutoffSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downcutoff) );
9634 }
9635
9636 if( !SCIPisFeasZero(scip, downconflen) )
9637 {
9639 }
9640
9641 if( !SCIPisFeasZero(scip, upvsids) || !SCIPisFeasZero(scip, upinfer) || !SCIPisFeasZero(scip, upcutoff) )
9642 {
9645 SCIP_CALL( SCIPvarIncVSIDS(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upvsids) );
9646 SCIP_CALL( SCIPvarIncCutoffSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upcutoff) );
9647 }
9648
9649 if( !SCIPisFeasZero(scip, upconflen) )
9650 {
9652 }
9653
9654 return SCIP_OKAY;
9655}
9656
9657/** returns the average number of cutoffs found after branching on the variable in given direction;
9658 * if branching on the variable in the given direction was yet evaluated, the average number of cutoffs
9659 * over all variables for branching in the given direction is returned
9660 *
9661 * @return the average number of cutoffs found after branching on the variable in given direction
9662 *
9663 * @pre This method can be called if @p scip is in one of the following stages:
9664 * - \ref SCIP_STAGE_INITPRESOLVE
9665 * - \ref SCIP_STAGE_PRESOLVING
9666 * - \ref SCIP_STAGE_EXITPRESOLVE
9667 * - \ref SCIP_STAGE_PRESOLVED
9668 * - \ref SCIP_STAGE_INITSOLVE
9669 * - \ref SCIP_STAGE_SOLVING
9670 * - \ref SCIP_STAGE_SOLVED
9671 */
9673 SCIP* scip, /**< SCIP data structure */
9674 SCIP_VAR* var, /**< problem variable */
9675 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9676 )
9677{
9678 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffs", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9679
9680 assert( var->scip == scip );
9681
9682 return SCIPvarGetAvgCutoffs(var, scip->stat, dir);
9683}
9684
9685/** returns the average number of cutoffs found after branching on the variable in given direction in the current run;
9686 * if branching on the variable in the given direction was yet evaluated, the average number of cutoffs
9687 * over all variables for branching in the given direction is returned
9688 *
9689 * @return the average number of cutoffs found after branching on the variable in given direction in the current run
9690 *
9691 * @pre This method can be called if @p scip is in one of the following stages:
9692 * - \ref SCIP_STAGE_INITPRESOLVE
9693 * - \ref SCIP_STAGE_PRESOLVING
9694 * - \ref SCIP_STAGE_EXITPRESOLVE
9695 * - \ref SCIP_STAGE_PRESOLVED
9696 * - \ref SCIP_STAGE_INITSOLVE
9697 * - \ref SCIP_STAGE_SOLVING
9698 * - \ref SCIP_STAGE_SOLVED
9699 */
9701 SCIP* scip, /**< SCIP data structure */
9702 SCIP_VAR* var, /**< problem variable */
9703 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9704 )
9705{
9706 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffsCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9707
9708 assert( var->scip == scip );
9709
9710 return SCIPvarGetAvgCutoffsCurrentRun(var, scip->stat, dir);
9711}
9712
9713/** returns the variable's average cutoff score value
9714 *
9715 * @return the variable's average cutoff score value
9716 *
9717 * @pre This method can be called if @p scip is in one of the following stages:
9718 * - \ref SCIP_STAGE_INITPRESOLVE
9719 * - \ref SCIP_STAGE_PRESOLVING
9720 * - \ref SCIP_STAGE_EXITPRESOLVE
9721 * - \ref SCIP_STAGE_PRESOLVED
9722 * - \ref SCIP_STAGE_INITSOLVE
9723 * - \ref SCIP_STAGE_SOLVING
9724 * - \ref SCIP_STAGE_SOLVED
9725 */
9727 SCIP* scip, /**< SCIP data structure */
9728 SCIP_VAR* var /**< problem variable */
9729 )
9730{
9731 SCIP_Real cutoffdown;
9732 SCIP_Real cutoffup;
9733
9734 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9735
9736 assert( var->scip == scip );
9737
9740
9741 return SCIPbranchGetScore(scip->set, var, cutoffdown, cutoffup);
9742}
9743
9744/** returns the variable's average cutoff score value, only using cutoffs of the current run
9745 *
9746 * @return the variable's average cutoff score value, only using cutoffs of the current run
9747 *
9748 * @pre This method can be called if @p scip is in one of the following stages:
9749 * - \ref SCIP_STAGE_INITPRESOLVE
9750 * - \ref SCIP_STAGE_PRESOLVING
9751 * - \ref SCIP_STAGE_EXITPRESOLVE
9752 * - \ref SCIP_STAGE_PRESOLVED
9753 * - \ref SCIP_STAGE_INITSOLVE
9754 * - \ref SCIP_STAGE_SOLVING
9755 * - \ref SCIP_STAGE_SOLVED
9756 */
9758 SCIP* scip, /**< SCIP data structure */
9759 SCIP_VAR* var /**< problem variable */
9760 )
9761{
9762 SCIP_Real cutoffdown;
9763 SCIP_Real cutoffup;
9764
9765 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9766
9767 assert( var->scip == scip );
9768
9771
9772 return SCIPbranchGetScore(scip->set, var, cutoffdown, cutoffup);
9773}
9774
9775/** returns the variable's average inference/cutoff score value, weighting the cutoffs of the variable with the given
9776 * factor
9777 *
9778 * @return the variable's average inference/cutoff score value
9779 *
9780 * @pre This method can be called if @p scip is in one of the following stages:
9781 * - \ref SCIP_STAGE_INITPRESOLVE
9782 * - \ref SCIP_STAGE_PRESOLVING
9783 * - \ref SCIP_STAGE_EXITPRESOLVE
9784 * - \ref SCIP_STAGE_PRESOLVED
9785 * - \ref SCIP_STAGE_INITSOLVE
9786 * - \ref SCIP_STAGE_SOLVING
9787 * - \ref SCIP_STAGE_SOLVED
9788 */
9790 SCIP* scip, /**< SCIP data structure */
9791 SCIP_VAR* var, /**< problem variable */
9792 SCIP_Real cutoffweight /**< factor to weigh average number of cutoffs in branching score */
9793 )
9794{
9795 SCIP_Real avginferdown;
9796 SCIP_Real avginferup;
9797 SCIP_Real avginfer;
9798 SCIP_Real inferdown;
9799 SCIP_Real inferup;
9800 SCIP_Real cutoffdown;
9801 SCIP_Real cutoffup;
9802
9803 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceCutoffScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9804
9805 assert( var->scip == scip );
9806
9807 avginferdown = SCIPhistoryGetAvgInferences(scip->stat->glbhistory, SCIP_BRANCHDIR_DOWNWARDS);
9808 avginferup = SCIPhistoryGetAvgInferences(scip->stat->glbhistory, SCIP_BRANCHDIR_UPWARDS);
9809 avginfer = (avginferdown + avginferup)/2.0;
9814
9815 return SCIPbranchGetScore(scip->set, var,
9816 inferdown + cutoffweight * avginfer * cutoffdown, inferup + cutoffweight * avginfer * cutoffup);
9817}
9818
9819/** returns the variable's average inference/cutoff score value, weighting the cutoffs of the variable with the given
9820 * factor, only using inferences and cutoffs of the current run
9821 *
9822 * @return the variable's average inference/cutoff score value, only using inferences and cutoffs of the current run
9823 *
9824 * @pre This method can be called if @p scip is in one of the following stages:
9825 * - \ref SCIP_STAGE_INITPRESOLVE
9826 * - \ref SCIP_STAGE_PRESOLVING
9827 * - \ref SCIP_STAGE_EXITPRESOLVE
9828 * - \ref SCIP_STAGE_PRESOLVED
9829 * - \ref SCIP_STAGE_INITSOLVE
9830 * - \ref SCIP_STAGE_SOLVING
9831 * - \ref SCIP_STAGE_SOLVED
9832 */
9834 SCIP* scip, /**< SCIP data structure */
9835 SCIP_VAR* var, /**< problem variable */
9836 SCIP_Real cutoffweight /**< factor to weigh average number of cutoffs in branching score */
9837 )
9838{
9839 SCIP_Real avginferdown;
9840 SCIP_Real avginferup;
9841 SCIP_Real avginfer;
9842 SCIP_Real inferdown;
9843 SCIP_Real inferup;
9844 SCIP_Real cutoffdown;
9845 SCIP_Real cutoffup;
9846
9847 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceCutoffScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9848
9849 assert( var->scip == scip );
9850
9851 avginferdown = SCIPhistoryGetAvgInferences(scip->stat->glbhistorycrun, SCIP_BRANCHDIR_DOWNWARDS);
9852 avginferup = SCIPhistoryGetAvgInferences(scip->stat->glbhistorycrun, SCIP_BRANCHDIR_UPWARDS);
9853 avginfer = (avginferdown + avginferup)/2.0;
9858
9859 return SCIPbranchGetScore(scip->set, var,
9860 inferdown + cutoffweight * avginfer * cutoffdown, inferup + cutoffweight * avginfer * cutoffup);
9861}
9862
9863/** returns the variable's average GMI efficacy score value
9864 *
9865 * @return the variable's average GMI efficacy score value
9866 *
9867 * @pre This method can be called if @p scip is in one of the following stages:
9868 * - \ref SCIP_STAGE_INITPRESOLVE
9869 * - \ref SCIP_STAGE_PRESOLVING
9870 * - \ref SCIP_STAGE_EXITPRESOLVE
9871 * - \ref SCIP_STAGE_PRESOLVED
9872 * - \ref SCIP_STAGE_INITSOLVE
9873 * - \ref SCIP_STAGE_SOLVING
9874 * - \ref SCIP_STAGE_SOLVED
9875 */
9877 SCIP* scip, /**< SCIP data structure */
9878 SCIP_VAR* var /**< problem variable */
9879 )
9880{
9881 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgGMIScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9882
9883 assert( var->scip == scip );
9884
9885 return SCIPvarGetAvgGMIScore(var, scip->stat);
9886}
9887
9888/** sets the variable's average GMI efficacy score value
9889 *
9890 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9891 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9892 *
9893 * @pre This method can be called if @p scip is in one of the following stages:
9894 * - \ref SCIP_STAGE_INITPRESOLVE
9895 * - \ref SCIP_STAGE_PRESOLVING
9896 * - \ref SCIP_STAGE_EXITPRESOLVE
9897 * - \ref SCIP_STAGE_PRESOLVED
9898 * - \ref SCIP_STAGE_INITSOLVE
9899 * - \ref SCIP_STAGE_SOLVING
9900 * - \ref SCIP_STAGE_SOLVED
9901 */
9902SCIP_EXPORT
9904 SCIP* scip, /**< SCIP data structure */
9905 SCIP_VAR* var, /**< problem variable */
9906 SCIP_Real gmieff /**< Efficacy of last GMI cut generated from when var was basic /frac */
9907 )
9908{
9909 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPincVarGMISumScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9910
9911 assert( var->scip == scip );
9912
9913 SCIP_CALL( SCIPvarIncGMIeffSum(var, scip->stat, gmieff) );
9914
9915 return SCIP_OKAY;
9916}
9917
9918/** returns the variable's last GMI efficacy score value
9919 *
9920 * @return the variable's last GMI efficacy score value
9921 *
9922 * @pre This method can be called if @p scip is in one of the following stages:
9923 * - \ref SCIP_STAGE_INITPRESOLVE
9924 * - \ref SCIP_STAGE_PRESOLVING
9925 * - \ref SCIP_STAGE_EXITPRESOLVE
9926 * - \ref SCIP_STAGE_PRESOLVED
9927 * - \ref SCIP_STAGE_INITSOLVE
9928 * - \ref SCIP_STAGE_SOLVING
9929 * - \ref SCIP_STAGE_SOLVED
9930 */
9932 SCIP* scip, /**< SCIP data structure */
9933 SCIP_VAR* var /**< problem variable */
9934 )
9935{
9936 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarLastGMIScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9937
9938 assert( var->scip == scip );
9939
9940 return SCIPvarGetLastGMIScore(var, scip->stat);
9941}
9942
9943/** sets the variable's last GMI efficacy score value
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_INITPRESOLVE
9950 * - \ref SCIP_STAGE_PRESOLVING
9951 * - \ref SCIP_STAGE_EXITPRESOLVE
9952 * - \ref SCIP_STAGE_PRESOLVED
9953 * - \ref SCIP_STAGE_INITSOLVE
9954 * - \ref SCIP_STAGE_SOLVING
9955 * - \ref SCIP_STAGE_SOLVED
9956 */
9958 SCIP* scip, /**< SCIP data structure */
9959 SCIP_VAR* var, /**< problem variable */
9960 SCIP_Real gmieff /**< efficacy of GMI cut from tableau row when variable is basic / frac */
9961 )
9962{
9963 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPsetVarLastGMIScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9964
9965 assert( var->scip == scip );
9966
9967 SCIP_CALL( SCIPvarSetLastGMIScore(var, scip->stat, gmieff) );
9968
9969 return SCIP_OKAY;
9970}
9971
9972/** outputs variable information to file stream via the message system
9973 *
9974 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9975 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9976 *
9977 * @pre This method can be called if @p scip is in one of the following stages:
9978 * - \ref SCIP_STAGE_PROBLEM
9979 * - \ref SCIP_STAGE_TRANSFORMING
9980 * - \ref SCIP_STAGE_TRANSFORMED
9981 * - \ref SCIP_STAGE_INITPRESOLVE
9982 * - \ref SCIP_STAGE_PRESOLVING
9983 * - \ref SCIP_STAGE_EXITPRESOLVE
9984 * - \ref SCIP_STAGE_PRESOLVED
9985 * - \ref SCIP_STAGE_INITSOLVE
9986 * - \ref SCIP_STAGE_SOLVING
9987 * - \ref SCIP_STAGE_SOLVED
9988 * - \ref SCIP_STAGE_EXITSOLVE
9989 * - \ref SCIP_STAGE_FREETRANS
9990 *
9991 * @note If the message handler is set to a NULL pointer nothing will be printed
9992 */
9994 SCIP* scip, /**< SCIP data structure */
9995 SCIP_VAR* var, /**< problem variable */
9996 FILE* file /**< output file (or NULL for standard output) */
9997 )
9998{
9999 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
10000
10001 SCIP_CALL( SCIPvarPrint(var, scip->set, scip->messagehdlr, file) );
10002
10003 return SCIP_OKAY;
10004}
SCIP_RETCODE SCIPbranchcandUpdateVarBranchPriority(SCIP_BRANCHCAND *branchcand, SCIP_SET *set, SCIP_VAR *var, int branchpriority)
Definition branch.c:1176
SCIP_Real SCIPbranchGetScore(SCIP_SET *set, SCIP_VAR *var, SCIP_Real downgain, SCIP_Real upgain)
Definition branch.c:2190
internal methods for branching rules and branching candidate storage
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_CLIQUETABLE *cliquetable, SCIP_COL *col, SCIP_Bool *downconflict, SCIP_Bool *upconflict)
SCIP_RETCODE SCIPcheckStage(SCIP *scip, const char *method, SCIP_Bool init, SCIP_Bool problem, SCIP_Bool transforming, SCIP_Bool transformed, SCIP_Bool initpresolve, SCIP_Bool presolving, SCIP_Bool exitpresolve, SCIP_Bool presolved, SCIP_Bool initsolve, SCIP_Bool solving, SCIP_Bool solved, SCIP_Bool exitsolve, SCIP_Bool freetrans, SCIP_Bool freescip)
Definition debug.c:2208
methods for debugging
#define NULL
Definition def.h:267
#define SCIP_MAXSTRLEN
Definition def.h:288
#define SCIP_MAXTREEDEPTH
Definition def.h:316
#define SCIP_VARTYPE_INTEGER_CHAR
Definition def.h:145
#define SCIP_VARTYPE_IMPLINT_CHAR
Definition def.h:146
#define SCIP_INVALID
Definition def.h:193
#define MIN(x, y)
Definition def.h:243
#define SCIP_UNKNOWN
Definition def.h:194
#define TRUE
Definition def.h:93
#define FALSE
Definition def.h:94
#define MAX(x, y)
Definition def.h:239
#define SCIP_CALL_ABORT(x)
Definition def.h:353
#define SCIP_VARTYPE_BINARY_CHAR
Definition def.h:144
#define SCIP_LONGINT_FORMAT
Definition def.h:165
#define SCIP_VARTYPE_CONTINUOUS_CHAR
Definition def.h:147
#define SCIPABORT()
Definition def.h:346
#define REALABS(x)
Definition def.h:197
#define SCIP_LONGINT_MAX
Definition def.h:159
#define SCIP_CALL(x)
Definition def.h:374
#define SCIP_CALL_FINALLY(x, y)
Definition def.h:416
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:545
void SCIPgmlWriteNode(FILE *file, unsigned int id, const char *label, const char *nodetype, const char *fillcolor, const char *bordercolor)
Definition misc.c:497
void SCIPgmlWriteClosing(FILE *file)
Definition misc.c:699
void SCIPgmlWriteOpening(FILE *file, SCIP_Bool directed)
Definition misc.c:683
void SCIPgmlWriteArc(FILE *file, unsigned int source, unsigned int target, const char *label, const char *color)
Definition misc.c:639
SCIP_Bool SCIPisTransformed(SCIP *scip)
SCIP_STAGE SCIPgetStage(SCIP *scip)
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition scip_prob.c:1866
int SCIPgetNVars(SCIP *scip)
Definition scip_prob.c:1992
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition scip_prob.c:1947
SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
Definition scip_prob.c:2685
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition misc.c:3108
int SCIPhashmapGetImageInt(SCIP_HASHMAP *hashmap, void *origin)
Definition misc.c:3281
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition misc.c:3074
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition misc.c:3423
SCIP_RETCODE SCIPhashmapInsertInt(SCIP_HASHMAP *hashmap, void *origin, int image)
Definition misc.c:3192
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
Definition lpi_clp.cpp:3931
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition lpi_clp.cpp:2766
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition lpi_clp.cpp:2609
SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition lpi_clp.cpp:2386
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
#define SCIPdebugMsg
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
SCIP_Real SCIPgetColRedcost(SCIP *scip, SCIP_COL *col)
Definition scip_lp.c:1154
SCIP_Longint SCIPcolGetStrongbranchNode(SCIP_COL *col)
Definition lp.c:17173
int SCIPcolGetNStrongbranchs(SCIP_COL *col)
Definition lp.c:17183
SCIP_Bool SCIPcolIsInLP(SCIP_COL *col)
Definition lp.c:17115
SCIP_Real SCIPgetColFarkasCoef(SCIP *scip, SCIP_COL *col)
Definition scip_lp.c:1180
SCIP_Bool SCIPconsIsLockedTypePos(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
Definition cons.c:8583
SCIP_Bool SCIPconsIsLockedTypeNeg(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
Definition cons.c:8595
SCIP_Bool SCIPinDive(SCIP *scip)
Definition scip_lp.c:2775
SCIP_Bool SCIPisLPRelax(SCIP *scip)
Definition scip_lp.c:225
SCIP_RETCODE SCIPgetLPI(SCIP *scip, SCIP_LPI **lpi)
Definition scip_lp.c:985
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition scip_lp.c:168
SCIP_Bool SCIPallColsInLP(SCIP *scip)
Definition scip_lp.c:649
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition scip_lp.c:247
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition scip_mem.h:110
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 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:7480
SCIP_DOMCHG * SCIPnodeGetDomchg(SCIP_NODE *node)
Definition tree.c:7585
int SCIPgetProbingDepth(SCIP *scip)
SCIP_RETCODE SCIPchgVarUbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
SCIP_RETCODE SCIPchgVarLbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
SCIP_RETCODE SCIPpropagateProbing(SCIP *scip, int maxproprounds, SCIP_Bool *cutoff, SCIP_Longint *ndomredsfound)
SCIP_RETCODE SCIPbacktrackProbing(SCIP *scip, int probingdepth)
SCIP_Bool SCIPinProbing(SCIP *scip)
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
SCIP_RETCODE SCIPsolveProbingLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
void SCIPsolSetStrongbranching(SCIP_SOL *sol)
Definition sol.c:2909
SCIP_RETCODE SCIPcreateLPSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition scip_sol.c:226
SCIP_RETCODE SCIPgetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition scip_sol.c:1254
SCIP_RETCODE SCIProundSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
Definition scip_sol.c:2311
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:3050
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition scip_sol.c:1217
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 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 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:2918
SCIP_Real SCIPgetRelaxSolObj(SCIP *scip)
Definition scip_var.c:2631
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:9536
SCIP_RETCODE SCIPgetProbvarLinearSum(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize, SCIP_Bool mergemultiples)
Definition scip_var.c:1737
SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition scip_var.c:5202
SCIP_Real SCIPgetVarBdAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition scip_var.c:2263
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:9607
SCIP_RETCODE SCIPaddVarLocks(SCIP *scip, SCIP_VAR *var, int nlocksdown, int nlocksup)
Definition scip_var.c:4316
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition var.c:17789
SCIP_Real SCIPgetVarMultaggrLbGlobal(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:6545
SCIP_Bool SCIPpscostThresholdProbabilityTest(SCIP *scip, SCIP_VAR *var, SCIP_Real frac, SCIP_Real threshold, SCIP_BRANCHDIR dir, SCIP_CONFIDENCELEVEL clevel)
Definition scip_var.c:9058
SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition scip_var.c:4350
SCIP_RETCODE SCIPremoveVarFromGlobalStructures(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:7858
SCIP_Real SCIPvarGetSol(SCIP_VAR *var, SCIP_Bool getlpval)
Definition var.c:13257
SCIP_Bool SCIPdoNotAggrVar(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:8584
void SCIPdisableVarHistory(SCIP *scip)
Definition scip_var.c:8759
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition var.c:17748
SCIP_Bool SCIPgetVarWasFixedAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition scip_var.c:2281
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition var.c:17599
SCIP_RETCODE SCIPincVarGMISumScore(SCIP *scip, SCIP_VAR *var, SCIP_Real gmieff)
Definition scip_var.c:9903
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:5825
SCIP_BOUNDTYPE SCIPboundchgGetBoundtype(SCIP_BOUNDCHG *boundchg)
Definition var.c:17346
SCIP_Real SCIPgetVarMultaggrLbLocal(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:6575
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:6009
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:6920
SCIP_RETCODE SCIPcalcCliquePartition(SCIP *const scip, SCIP_VAR **const vars, int const nvars, int *const cliquepartition, int *const ncliques)
Definition scip_var.c:7255
SCIP_RETCODE SCIPsetRelaxSolVal(SCIP *scip, SCIP_RELAX *relax, SCIP_VAR *var, SCIP_Real val)
Definition scip_var.c:2413
SCIP_RETCODE SCIPtightenVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition scip_var.c:6347
SCIP_Real SCIPgetVarAvgInferenceScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:9503
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:3661
SCIP_VAR * SCIPboundchgGetVar(SCIP_BOUNDCHG *boundchg)
Definition var.c:17326
SCIP_Real SCIPgetVarPseudocostCountCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition scip_var.c:8949
SCIP_Real SCIPgetVarAvgInferenceScore(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:9472
SCIP_RETCODE SCIPscaleVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real scale)
Definition scip_var.c:7920
SCIP_RETCODE SCIPendStrongbranch(SCIP *scip)
Definition scip_var.c:2743
SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition scip_var.c:4675
SCIP_Real SCIPgetVarMultaggrUbGlobal(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:6560
SCIP_BOUNDCHG * SCIPdomchgGetBoundchg(SCIP_DOMCHG *domchg, int pos)
Definition var.c:17374
SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition scip_var.c:1479
SCIP_Real SCIPgetVarPseudocostCount(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition scip_var.c:8921
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition var.c:17538
SCIP_RETCODE SCIPcalcNegatedCliquePartition(SCIP *const scip, SCIP_VAR **const vars, int const nvars, int *const cliquepartition, int *const ncliques)
Definition scip_var.c:7474
SCIP_Real SCIPgetVarPseudocostCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition scip_var.c:8895
SCIP_RETCODE SCIPwriteCliqueGraph(SCIP *scip, const char *fname, SCIP_Bool writenodeweights)
Definition scip_var.c:7709
SCIP_RETCODE SCIPchgVarName(SCIP *scip, SCIP_VAR *var, const char *name)
Definition scip_var.c:1298
SCIP_Bool SCIPdoNotAggr(SCIP *scip)
Definition scip_var.c:8564
SCIP_Real SCIPgetVarMultaggrUbLocal(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:6590
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition var.c:18144
int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition var.c:3416
SCIP_RETCODE SCIPupdateVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition scip_var.c:8020
SCIP_Real SCIPgetVarAvgConflictlength(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition scip_var.c:9364
SCIP_Bool SCIPisVarPscostRelerrorReliable(SCIP *scip, SCIP_VAR *var, SCIP_Real threshold, SCIP_CONFIDENCELEVEL clevel)
Definition scip_var.c:9077
SCIP_RETCODE SCIPgetBinvarRepresentatives(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **repvars, SCIP_Bool *negated)
Definition scip_var.c:1643
SCIP_BDCHGINFO * SCIPvarGetLbchgInfo(SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition var.c:16577
SCIP_Bool SCIPdoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:8597
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition var.c:17561
SCIP_Real SCIPgetVarPseudocost(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition scip_var.c:8867
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:610
SCIP_Real SCIPgetVarAvgCutoffScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:9757
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:8400
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:5614
SCIP_Bool SCIPallowObjProp(SCIP *scip)
Definition scip_var.c:8641
SCIP_Real SCIPboundchgGetNewbound(SCIP_BOUNDCHG *boundchg)
Definition var.c:17316
SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition scip_var.c:4765
SCIP_RETCODE SCIPchgVarUbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
Definition scip_var.c:4889
SCIP_Real SCIPgetVarAvgInferencesCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition scip_var.c:9446
SCIP_VAR * SCIPvarGetProbvar(SCIP_VAR *var)
Definition var.c:12218
SCIP_CLIQUE ** SCIPgetCliques(SCIP *scip)
Definition scip_var.c:7628
SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition scip_var.c:5319
SCIP_RETCODE SCIPparseVarName(SCIP *scip, const char *str, SCIP_VAR **var, char **endptr)
Definition scip_var.c:533
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:474
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition var.c:17584
SCIP_RETCODE SCIPgetProbvarSum(SCIP *scip, SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition scip_var.c:1793
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition var.c:18088
SCIP_RETCODE SCIPchgVarBranchDirection(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR branchdirection)
Definition scip_var.c:8084
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:6719
SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
Definition scip_var.c:4258
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:6660
SCIP_RETCODE SCIPchgVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition scip_var.c:7979
SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition scip_var.c:4436
SCIP_Real SCIPgetVarFarkasCoef(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:1953
SCIP_RETCODE SCIPgetVarClosestVub(SCIP *scip, SCIP_VAR *var, SCIP_SOL *sol, SCIP_Real *closestvub, int *closestvubidx)
Definition scip_var.c:6631
SCIP_Real SCIPgetVarAvgCutoffsCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition scip_var.c:9700
SCIP_RETCODE SCIPchgVarLbLazy(SCIP *scip, SCIP_VAR *var, SCIP_Real lazylb)
Definition scip_var.c:5122
SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition scip_var.c:2127
int SCIPdomchgGetNBoundchgs(SCIP_DOMCHG *domchg)
Definition var.c:17366
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition var.c:17768
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:17419
SCIP_Longint SCIPgetVarStrongbranchNode(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:4159
SCIP_RETCODE SCIPtransformVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition scip_var.c:1388
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:8534
void SCIPfreeParseVarsPolynomialData(SCIP *scip, SCIP_VAR ****monomialvars, SCIP_Real ***monomialexps, SCIP_Real **monomialcoefs, int **monomialnvars, int nmonomials)
Definition scip_var.c:1157
SCIP_LPSOLSTAT SCIPgetLastStrongbranchLPSolStat(SCIP *scip, SCIP_BRANCHDIR branchdir)
Definition scip_var.c:3987
SCIP_RETCODE SCIPaddVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real addfactor)
Definition scip_var.c:7948
int SCIPgetNCliquesCreated(SCIP *scip)
Definition scip_var.c:7601
SCIP_RETCODE SCIPcleanupCliques(SCIP *scip, SCIP_Bool *infeasible)
Definition scip_var.c:7531
void SCIPvarMarkDeleteGlobalStructures(SCIP_VAR *var)
Definition var.c:17676
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition scip_var.c:1247
SCIP_Real SCIPadjustedVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real ub)
Definition scip_var.c:4644
SCIP_Longint SCIPgetVarStrongbranchLPAge(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:4193
SCIP_RETCODE SCIPchgVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition scip_var.c:4942
SCIP_RETCODE SCIPmarkRelaxSolValid(SCIP *scip, SCIP_RELAX *relax, SCIP_Bool includeslp)
Definition scip_var.c:2556
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:3772
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:4043
SCIP_Real SCIPvarGetBranchFactor(SCIP_VAR *var)
Definition var.c:18238
SCIP_Bool SCIPdoNotMultaggr(SCIP *scip)
Definition scip_var.c:8574
SCIP_Real SCIPgetVarPseudocostVal(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta)
Definition scip_var.c:8813
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:704
SCIP_Real SCIPgetVarConflictlengthScore(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:9302
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:9028
SCIP_Real SCIPgetRelaxSolVal(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:2602
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:3351
SCIP_Real SCIPadjustedVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real lb)
Definition scip_var.c:4612
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition var.c:17610
SCIP_Real SCIPgetVarAvgCutoffs(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition scip_var.c:9672
SCIP_Real SCIPvarGetPseudoSol(SCIP_VAR *var)
Definition var.c:18530
SCIP_Bool SCIPisRelaxSolValid(SCIP *scip)
Definition scip_var.c:2536
SCIP_RETCODE SCIPgetVarClosestVlb(SCIP *scip, SCIP_VAR *var, SCIP_SOL *sol, SCIP_Real *closestvlb, int *closestvlbidx)
Definition scip_var.c:6608
SCIP_Bool SCIPallowDualReds(SCIP *scip)
Definition scip_var.c:8613
SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition scip_var.c:8175
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
Definition var.c:18452
SCIP_RETCODE SCIPflattenVarAggregationGraph(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:1692
SCIP_Real SCIPcomputeVarLbGlobal(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:6462
SCIP_Real SCIPgetVarSol(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:2306
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition scip_var.c:1526
SCIP_Real SCIPgetVarPseudocostScoreCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real solval)
Definition scip_var.c:9140
SCIP_Bool SCIPhaveVarsCommonClique(SCIP *scip, SCIP_VAR *var1, SCIP_Bool value1, SCIP_VAR *var2, SCIP_Bool value2, SCIP_Bool regardimplics)
Definition scip_var.c:7658
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:6779
SCIP_RETCODE SCIPsetRelaxSolVals(SCIP *scip, SCIP_RELAX *relax, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Bool includeslp)
Definition scip_var.c:2446
SCIP_Real SCIPcalculatePscostConfidenceBound(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun, SCIP_CONFIDENCELEVEL clevel)
Definition scip_var.c:8997
int SCIPvarGetNCliques(SCIP_VAR *var, SCIP_Bool varfixing)
Definition var.c:18430
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition var.c:18134
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition var.c:17574
SCIP_RETCODE SCIPchgVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition scip_var.c:5031
SCIP_Real SCIPcomputeVarLbLocal(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:6504
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:404
SCIP_Bool SCIPboundchgIsRedundant(SCIP_BOUNDCHG *boundchg)
Definition var.c:17356
SCIP_Real SCIPgetVarPseudocostValCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta)
Definition scip_var.c:8841
SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
Definition var.c:17904
SCIP_RETCODE SCIPupdateVarPseudocost(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
Definition scip_var.c:8779
int SCIPgetNCliques(SCIP *scip)
Definition scip_var.c:7574
SCIP_BDCHGINFO * SCIPvarGetUbchgInfo(SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition var.c:16633
SCIP_Real SCIPgetVarAvgGMIScore(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:9876
int SCIPvarGetBranchPriority(SCIP_VAR *var)
Definition var.c:18250
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:114
SCIP_RETCODE SCIPaddVarBranchPriority(SCIP *scip, SCIP_VAR *var, int addpriority)
Definition scip_var.c:8053
SCIP_RETCODE SCIPtransformVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition scip_var.c:1348
SCIP_Real SCIPgetVarRedcost(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:1863
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition var.c:18078
SCIP_RETCODE SCIPmarkDoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:8714
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition scip_var.c:8275
SCIP_RETCODE SCIPmarkRelaxSolInvalid(SCIP *scip)
Definition scip_var.c:2581
SCIP_Real SCIPgetVarAvgInferenceCutoffScoreCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real cutoffweight)
Definition scip_var.c:9833
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:5500
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:3883
SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition scip_var.c:1991
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:813
SCIP_Real SCIPgetVarLastGMIScore(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:9931
SCIP_Real SCIPgetVarConflictScore(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:9240
SCIP_RETCODE SCIPprintVar(SCIP *scip, SCIP_VAR *var, FILE *file)
Definition scip_var.c:9993
SCIP_Real SCIPgetVarAvgCutoffScore(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:9726
SCIP_RETCODE SCIPchgVarLbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
Definition scip_var.c:4845
SCIP_RETCODE SCIPvarGetProbvarBinary(SCIP_VAR **var, SCIP_Bool *negated)
Definition var.c:12310
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:194
SCIP_RETCODE SCIPsetVarLastGMIScore(SCIP *scip, SCIP_VAR *var, SCIP_Real gmieff)
Definition scip_var.c:9957
SCIP_RETCODE SCIPchgVarUbLazy(SCIP *scip, SCIP_VAR *var, SCIP_Real lazyub)
Definition scip_var.c:5163
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:5722
int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition var.c:3429
SCIP_RETCODE SCIPtryStrongbranchLPSol(SCIP *scip, SCIP_Bool *foundsol, SCIP_Bool *cutoff)
Definition scip_var.c:4078
SCIP_RETCODE SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
Definition scip_var.c:230
SCIP_RETCODE SCIPgetVarSols(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition scip_var.c:2326
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition scip_var.c:4512
SCIP_RETCODE SCIPgetBinvarRepresentative(SCIP *scip, SCIP_VAR *var, SCIP_VAR **repvar, SCIP_Bool *negated)
Definition scip_var.c:1596
SCIP_Real SCIPgetVarAvgInferenceCutoffScore(SCIP *scip, SCIP_VAR *var, SCIP_Real cutoffweight)
Definition scip_var.c:9789
SCIP_RETCODE SCIPwriteVarsList(SCIP *scip, FILE *file, SCIP_VAR **vars, int nvars, SCIP_Bool type, char delimiter)
Definition scip_var.c:292
SCIP_Real SCIPcomputeVarUbGlobal(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:6483
SCIP_Real SCIPcomputeVarUbLocal(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:6525
SCIP_RETCODE SCIPgetActiveVars(SCIP *scip, SCIP_VAR **vars, int *nvars, int varssize, int *requiredsize)
Definition scip_var.c:1829
int SCIPgetVarNStrongbranchs(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:4225
SCIP_RETCODE SCIPwriteVarsLinearsum(SCIP *scip, FILE *file, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Bool type)
Definition scip_var.c:343
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:4009
SCIP_Real SCIPgetVarVSIDS(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition scip_var.c:9176
SCIP_Bool SCIPvarsHaveCommonClique(SCIP_VAR *var1, SCIP_Bool value1, SCIP_VAR *var2, SCIP_Bool value2, SCIP_Bool regardimplics)
Definition var.c:11475
SCIP_Real SCIPgetVarConflictlengthScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:9333
SCIP_Real SCIPgetVarVSIDSCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition scip_var.c:9208
SCIP_Bool SCIPisStrongbranchDownFirst(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:2654
SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
Definition var.c:18670
void SCIPenableVarHistory(SCIP *scip)
Definition scip_var.c:8740
SCIP_Real SCIPgetVarImplRedcost(SCIP *scip, SCIP_VAR *var, SCIP_Bool varfixing)
Definition scip_var.c:1908
SCIP_Bool SCIPallowWeakDualReds(SCIP *scip)
Definition scip_var.c:8655
SCIP_Real SCIPgetVarPseudocostVariance(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun)
Definition scip_var.c:8975
SCIP_RETCODE SCIPgetNegatedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **negvars)
Definition scip_var.c:1559
SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition scip_var.c:1438
SCIP_Real SCIPgetVarConflictScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:9271
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:1213
SCIP_Real SCIPgetVarPseudocostScore(SCIP *scip, SCIP_VAR *var, SCIP_Real solval)
Definition scip_var.c:9102
SCIP_RETCODE SCIPstartStrongbranch(SCIP *scip, SCIP_Bool enablepropagation)
Definition scip_var.c:2685
SCIP_RETCODE SCIPclearRelaxSolVals(SCIP *scip, SCIP_RELAX *relax)
Definition scip_var.c:2363
SCIP_RETCODE SCIPmarkDoNotAggrVar(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:8681
SCIP_Real SCIPgetVarAvgInferences(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition scip_var.c:9418
SCIP_Bool SCIPallowStrongDualReds(SCIP *scip)
Definition scip_var.c:8628
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:6119
SCIP_RETCODE SCIPvarsGetProbvarBinary(SCIP_VAR ***vars, SCIP_Bool **negatedarr, int nvars)
Definition var.c:12278
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:5431
SCIP_Real SCIPgetVarAvgConflictlengthCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition scip_var.c:9390
SCIP_RETCODE SCIPsetRelaxSolValsSol(SCIP *scip, SCIP_RELAX *relax, SCIP_SOL *sol, SCIP_Bool includeslp)
Definition scip_var.c:2488
SCIP_RETCODE SCIPchgVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real branchfactor)
Definition scip_var.c:7892
SCIP_RETCODE SCIPtightenVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition scip_var.c:6227
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:5894
SCIP_RETCODE SCIPaddVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real addobj)
Definition scip_var.c:4561
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition misc.c:10877
SCIP_Bool SCIPstrToRealValue(const char *str, SCIP_Real *value, char **endptr)
Definition misc.c:10977
void SCIPstrCopySection(const char *str, char startchar, char endchar, char *token, int size, char **endptr)
Definition misc.c:11007
SCIP_RETCODE SCIPskipSpace(char **s)
Definition misc.c:10866
return SCIP_OKAY
SCIPfreeSol(scip, &heurdata->sol))
SCIP_Bool lperror
int c
SCIP_Bool cutoff
SCIP_Real objval
static SCIP_SOL * sol
SCIP_Real obj
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
SCIP_VAR * var
SCIP_Real primsol
SCIP_Real frac
SCIP_Real newobj
static SCIP_Bool propagate
static SCIP_VAR ** vars
int nbinvars
int nintvars
SCIP_Real SCIPhistoryGetAvgInferences(SCIP_HISTORY *history, SCIP_BRANCHDIR dir)
Definition history.c:665
internal methods for branching and inference history
int SCIPcliquetableGetNCliquesCreated(SCIP_CLIQUETABLE *cliquetable)
Definition implics.c:3516
SCIP_Bool SCIPcliquetableNeedsComponentUpdate(SCIP_CLIQUETABLE *cliquetable)
Definition implics.c:3554
SCIP_VAR ** SCIPcliqueGetVars(SCIP_CLIQUE *clique)
Definition implics.c:3380
int SCIPcliqueGetNVars(SCIP_CLIQUE *clique)
Definition implics.c:3370
SCIP_Bool * SCIPcliqueGetValues(SCIP_CLIQUE *clique)
Definition implics.c:3392
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_VAR **vars, SCIP_Bool *values, int nvars, SCIP_Bool isequation, SCIP_Bool *infeasible, int *nbdchgs)
Definition implics.c:2376
int SCIPcliquetableGetNCliques(SCIP_CLIQUETABLE *cliquetable)
Definition implics.c:3506
int SCIPcliquetableGetVarComponentIdx(SCIP_CLIQUETABLE *cliquetable, SCIP_VAR *var)
Definition implics.c:2348
SCIP_RETCODE SCIPcliquetableComputeCliqueComponents(SCIP_CLIQUETABLE *cliquetable, SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_VAR **vars, int nbinvars, int nintvars, int nimplvars)
Definition implics.c:3131
SCIP_CLIQUE ** SCIPcliquetableGetCliques(SCIP_CLIQUETABLE *cliquetable)
Definition implics.c:3526
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, int *nchgbds, SCIP_Bool *infeasible)
Definition implics.c:2920
methods for implications, variable bounds, and cliques
SCIP_Real SCIPlpGetLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition lp.c:13158
SCIP_RETCODE SCIPlpStartStrongbranch(SCIP_LP *lp)
Definition lp.c:4180
void SCIPcolInvalidateStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition lp.c:4264
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:4299
SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition lp.c:13119
SCIP_RETCODE SCIPlpEndStrongbranch(SCIP_LP *lp)
Definition lp.c:4195
SCIP_Longint SCIPcolGetStrongbranchLPAge(SCIP_COL *col, SCIP_STAT *stat)
Definition lp.c:4739
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition lp.c:17847
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:4707
void SCIPlpStartStrongbranchProbing(SCIP_LP *lp)
Definition lp.c:16345
void SCIPlpEndStrongbranchProbing(SCIP_LP *lp)
Definition lp.c:16358
SCIP_Bool SCIPlpIsDualReliable(SCIP_LP *lp)
Definition lp.c:17827
static const SCIP_Real scalars[]
Definition lp.c:5743
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:4210
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:4484
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
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition scip_mem.c:57
SCIP_RETCODE SCIPprobAddVarName(SCIP_PROB *prob, SCIP_VAR *var)
Definition prob.c:939
SCIP_RETCODE SCIPprobRemoveVarName(SCIP_PROB *prob, SCIP_VAR *var)
Definition prob.c:955
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:1175
SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
Definition prob.c:2350
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
SCIP_Bool SCIPrelaxationIsSolZero(SCIP_RELAXATION *relaxation)
Definition relax.c:785
void SCIPrelaxationSetSolZero(SCIP_RELAXATION *relaxation, SCIP_Bool iszero)
Definition relax.c:774
void SCIPrelaxationSetSolValid(SCIP_RELAXATION *relaxation, SCIP_Bool isvalid, SCIP_Bool includeslp)
Definition relax.c:795
void SCIPrelaxationSetSolObj(SCIP_RELAXATION *relaxation, SCIP_Real obj)
Definition relax.c:828
SCIP_Real SCIPrelaxationGetSolObj(SCIP_RELAXATION *relaxation)
Definition relax.c:839
void SCIPrelaxationSetSolRelax(SCIP_RELAXATION *relaxation, SCIP_RELAX *relax)
Definition relax.c:880
SCIP_Bool SCIPrelaxationIsSolValid(SCIP_RELAXATION *relaxation)
Definition relax.c:808
internal methods for relaxators
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:2838
static SCIP_RETCODE calcCliquePartitionGreedy(SCIP *const scip, SCIP_VAR **const vars, SCIP_Bool *const values, int const nvars, int *const cliquepartition, int *const ncliques)
Definition scip_var.c:7139
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:3025
static SCIP_RETCODE labelSortStable(SCIP *scip, SCIP_VAR **vars, int *classlabels, SCIP_VAR **sortedvars, int *sortedindices, int *classesstartposs, int nvars, int nclasses)
Definition scip_var.c:7013
static SCIP_RETCODE relabelOrderConsistent(SCIP *const scip, int *labels, int const nlabels, int *nclasses)
Definition scip_var.c:6952
#define MAXNCLIQUEVARSCOMP
Definition scip_var.c:7119
static SCIP_RETCODE tightenBounds(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition scip_var.c:8101
public methods for SCIP variables
SCIP_Bool SCIPsetIsLbBetter(SCIP_SET *set, SCIP_Real newlb, SCIP_Real oldlb, SCIP_Real oldub)
Definition set.c:7022
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6293
SCIP_Real SCIPsetFeasCeil(SCIP_SET *set, SCIP_Real val)
Definition set.c:6775
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6663
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6597
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6257
SCIP_Real SCIPsetFeasFloor(SCIP_SET *set, SCIP_Real val)
Definition set.c:6764
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6221
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6619
SCIP_Bool SCIPsetIsUbBetter(SCIP_SET *set, SCIP_Real newub, SCIP_Real oldlb, SCIP_Real oldub)
Definition set.c:7043
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition set.c:6199
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition set.c:6311
SCIP_Bool SCIPsetIsFeasIntegral(SCIP_SET *set, SCIP_Real val)
Definition set.c:6740
internal methods for global SCIP settings
#define SCIPsetFreeBufferArray(set, ptr)
Definition set.h:1755
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition set.h:1748
#define SCIPsetDuplicateBufferArray(set, ptr, source, num)
Definition set.h:1750
SCIP_Real SCIPsolGetObj(SCIP_SOL *sol, SCIP_SET *set, SCIP_PROB *transprob, SCIP_PROB *origprob)
Definition sol.c:1571
internal methods for storing primal CIP solutions
SCIP_Bool SCIPsolveIsStopped(SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool checknodelimits)
Definition solve.c:102
internal methods for main solving loop and node processing
void SCIPstatEnableVarHistory(SCIP_STAT *stat)
Definition stat.c:166
void SCIPstatDisableVarHistory(SCIP_STAT *stat)
Definition stat.c:156
internal methods for problem statistics
#define SCIPstatAdd(stat, set, field, val)
Definition stat.h:280
SCIP_VAR * var
Definition struct_var.h:187
SCIP_Real scalar
Definition struct_var.h:185
SCIP_Real constant
Definition struct_var.h:186
SCIP_Real lb
Definition struct_lp.h:138
SCIP_Real ub
Definition struct_lp.h:139
SCIP_Real sbdown
Definition struct_lp.h:153
SCIP_Real sbup
Definition struct_lp.h:154
unsigned int sbupvalid
Definition struct_lp.h:190
SCIP_Real primsol
Definition struct_lp.h:148
unsigned int sbdownvalid
Definition struct_lp.h:188
SCIP_Real lb
Definition struct_var.h:170
SCIP_Real ub
Definition struct_var.h:171
SCIP_VAR ** vars
Definition struct_var.h:195
SCIP_Real constant
Definition struct_var.h:193
SCIP_Real * scalars
Definition struct_var.h:194
SCIP_Real constant
Definition struct_var.h:203
SCIP_VAR * transvar
Definition struct_var.h:179
SCIP_ORIGINAL original
Definition struct_var.h:229
SCIP_AGGREGATE aggregate
Definition struct_var.h:231
SCIP_VAR * negatedvar
Definition struct_var.h:242
SCIP * scip
Definition struct_var.h:288
union SCIP_Var::@22 data
SCIP_DOM glbdom
Definition struct_var.h:225
unsigned int vartype
Definition struct_var.h:280
SCIP_MULTAGGR multaggr
Definition struct_var.h:232
SCIP_NEGATE negate
Definition struct_var.h:233
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_Bool SCIPtreeProbing(SCIP_TREE *tree)
Definition tree.c:8332
int SCIPtreeGetProbingDepth(SCIP_TREE *tree)
Definition tree.c:8478
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:6481
SCIP_NODE * SCIPtreeGetCurrentNode(SCIP_TREE *tree)
Definition tree.c:8433
SCIP_Bool SCIPtreeHasCurrentNodeLP(SCIP_TREE *tree)
Definition tree.c:8467
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_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:1858
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_CLIQUETABLE *cliquetable, SCIP_VAR *var, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype, SCIP_Bool probingchange)
Definition tree.c:2133
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:6915
int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
Definition tree.c:8450
internal methods for branch and bound tree
@ SCIP_BRANCHDIR_DOWNWARDS
@ SCIP_BRANCHDIR_UPWARDS
enum SCIP_BranchDir SCIP_BRANCHDIR
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition type_lp.h:51
@ SCIP_BOUNDTYPE_UPPER
Definition type_lp.h:57
@ SCIP_BOUNDTYPE_LOWER
Definition type_lp.h:56
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition type_lp.h:59
@ SCIP_LPSOLSTAT_ERROR
Definition type_lp.h:49
@ SCIP_LPSOLSTAT_NOTSOLVED
Definition type_lp.h:42
@ SCIP_LPSOLSTAT_OPTIMAL
Definition type_lp.h:43
@ SCIP_LPSOLSTAT_TIMELIMIT
Definition type_lp.h:48
@ SCIP_LPSOLSTAT_UNBOUNDEDRAY
Definition type_lp.h:45
@ SCIP_LPSOLSTAT_INFEASIBLE
Definition type_lp.h:44
@ SCIP_LPSOLSTAT_OBJLIMIT
Definition type_lp.h:46
@ SCIP_LPSOLSTAT_ITERLIMIT
Definition type_lp.h:47
enum SCIP_Confidencelevel SCIP_CONFIDENCELEVEL
Definition type_misc.h:53
@ SCIP_READERROR
@ SCIP_INVALIDDATA
@ SCIP_INVALIDCALL
enum SCIP_Retcode SCIP_RETCODE
@ 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:62
@ SCIP_NODETYPE_PROBINGNODE
Definition type_tree.h:42
struct SCIP_VarData SCIP_VARDATA
Definition type_var.h:120
#define NLOCKTYPES
Definition type_var.h:94
#define SCIP_DECL_VARDELORIG(x)
Definition type_var.h:131
#define SCIP_DECL_VARTRANS(x)
Definition type_var.h:151
@ SCIP_VARTYPE_INTEGER
Definition type_var.h:63
@ SCIP_VARTYPE_CONTINUOUS
Definition type_var.h:71
@ SCIP_VARTYPE_IMPLINT
Definition type_var.h:64
@ SCIP_VARTYPE_BINARY
Definition type_var.h:62
@ SCIP_VARSTATUS_ORIGINAL
Definition type_var.h:49
@ SCIP_VARSTATUS_FIXED
Definition type_var.h:52
@ SCIP_VARSTATUS_COLUMN
Definition type_var.h:51
@ SCIP_VARSTATUS_MULTAGGR
Definition type_var.h:54
@ SCIP_VARSTATUS_NEGATED
Definition type_var.h:55
@ SCIP_VARSTATUS_AGGREGATED
Definition type_var.h:53
@ SCIP_VARSTATUS_LOOSE
Definition type_var.h:50
#define SCIP_DECL_VARCOPY(x)
Definition type_var.h:194
#define SCIP_DECL_VARDELTRANS(x)
Definition type_var.h:164
enum SCIP_LockType SCIP_LOCKTYPE
Definition type_var.h:100
@ SCIP_LOCKTYPE_MODEL
Definition type_var.h:97
enum SCIP_Vartype SCIP_VARTYPE
Definition type_var.h:73
enum SCIP_Varstatus SCIP_VARSTATUS
Definition type_var.h:57
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_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_Real addobj)
Definition var.c:6339
SCIP_Real SCIPvarGetPseudocost(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real solvaldelta)
Definition var.c:14477
SCIP_RETCODE SCIPvarsGetActiveVars(SCIP_SET *set, SCIP_VAR **vars, int *nvars, int varssize, int *requiredsize)
Definition var.c:12006
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:15447
SCIP_RETCODE SCIPvarChgLbLazy(SCIP_VAR *var, SCIP_SET *set, SCIP_Real lazylb)
Definition var.c:7469
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_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:2117
SCIP_Real SCIPvarGetPseudocostCount(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition var.c:14573
SCIP_RETCODE SCIPvarGetTransformed(SCIP_VAR *origvar, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR **transvar)
Definition var.c:3548
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:6264
SCIP_Real SCIPvarGetPseudocostVariance(SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun)
Definition var.c:14692
SCIP_Real SCIPvarGetImplRedcost(SCIP_VAR *var, SCIP_SET *set, SCIP_Bool varfixing, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp)
Definition var.c:13468
SCIP_RETCODE SCIPvarSetLastGMIScore(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real gmieff)
Definition var.c:16483
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_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition var.c:3749
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:15531
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:15051
SCIP_Real SCIPvarGetAvgCutoffs(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition var.c:16265
SCIP_RETCODE SCIPvarUpdatePseudocost(SCIP_VAR *var, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
Definition var.c:14379
SCIP_RETCODE SCIPvarTransform(SCIP_VAR *origvar, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_OBJSENSE objsense, SCIP_VAR **transvar)
Definition var.c:3461
SCIP_Real SCIPvarGetAvgInferencesCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition var.c:16124
SCIP_RETCODE SCIPvarRelease(SCIP_VAR **var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition var.c:2872
void SCIPvarGetClosestVub(SCIP_VAR *var, SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real *closestvub, int *closestvubidx)
Definition var.c:14198
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:15187
void SCIPvarAdjustLb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *lb)
Definition var.c:6517
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:7185
SCIP_Real SCIPvarCalcPscostConfidenceBound(SCIP_VAR *var, SCIP_SET *set, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun, SCIP_CONFIDENCELEVEL clevel)
Definition var.c:14746
SCIP_Bool SCIPvarIsPscostRelerrorReliable(SCIP_VAR *var, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real threshold, SCIP_CONFIDENCELEVEL clevel)
Definition var.c:14784
SCIP_RETCODE SCIPvarChgLbOriginal(SCIP_VAR *var, SCIP_SET *set, SCIP_Real newbound)
Definition var.c:6567
SCIP_RETCODE SCIPvarPrint(SCIP_VAR *var, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition var.c:3006
SCIP_Real SCIPvarGetAvgGMIScore(SCIP_VAR *var, SCIP_STAT *stat)
Definition var.c:16359
SCIP_Real SCIPvarGetVSIDS(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition var.c:18543
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:15615
SCIP_Real SCIPvarGetMultaggrLbLocal(SCIP_VAR *var, SCIP_SET *set)
Definition var.c:8434
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:14861
void SCIPvarCapture(SCIP_VAR *var)
Definition var.c:2847
SCIP_RETCODE SCIPvarChgBranchDirection(SCIP_VAR *var, SCIP_BRANCHDIR branchdirection)
Definition var.c:11818
SCIP_Real SCIPvarGetPseudocostCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real solvaldelta)
Definition var.c:14526
SCIP_Bool SCIPvarDoNotAggr(SCIP_VAR *var)
Definition var.c:5848
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:6178
SCIP_RETCODE SCIPvarFlattenAggregationGraph(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition var.c:4424
void SCIPvarUpdateBestRootSol(SCIP_VAR *var, SCIP_SET *set, SCIP_Real rootsol, SCIP_Real rootredcost, SCIP_Real rootlpobjval)
Definition var.c:13280
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_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:2074
SCIP_Real SCIPvarGetAvgConflictlength(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition var.c:15360
SCIP_Real SCIPvarGetPseudocostCountCurrentRun(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition var.c:14618
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:7328
SCIP_RETCODE SCIPvarGetActiveRepresentatives(SCIP_SET *set, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize, SCIP_Bool mergemultiples)
Definition var.c:3929
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:2560
SCIP_RETCODE SCIPvarChgUbOriginal(SCIP_VAR *var, SCIP_SET *set, SCIP_Real newbound)
Definition var.c:6626
SCIP_Real SCIPvarGetAvgInferences(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition var.c:16067
SCIP_Real SCIPvarGetMultaggrUbGlobal(SCIP_VAR *var, SCIP_SET *set)
Definition var.c:8632
void SCIPvarGetClosestVlb(SCIP_VAR *var, SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real *closestvlb, int *closestvlbidx)
Definition var.c:14123
SCIP_RETCODE SCIPvarChgUbLazy(SCIP_VAR *var, SCIP_SET *set, SCIP_Real lazyub)
Definition var.c:7492
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:14927
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_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_VAR *varx, SCIP_VAR *vary, SCIP_Real scalarx, SCIP_Real scalary, SCIP_Real rhs, SCIP_Bool *infeasible, SCIP_Bool *aggregated)
Definition var.c:5292
SCIP_Real SCIPvarGetRelaxSol(SCIP_VAR *var, SCIP_SET *set)
Definition var.c:13923
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_Bool varfixing, SCIP_VAR *implvar, SCIP_BOUNDTYPE impltype, SCIP_Real implbound, SCIP_Bool transitive, SCIP_Bool *infeasible, int *nbdchgs)
Definition var.c:10912
SCIP_RETCODE SCIPvarMarkDoNotAggr(SCIP_VAR *var)
Definition var.c:6106
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:7970
SCIP_RETCODE SCIPvarChgBranchPriority(SCIP_VAR *var, int branchpriority)
Definition var.c:11687
SCIP_RETCODE SCIPvarMarkDoNotMultaggr(SCIP_VAR *var)
Definition var.c:6142
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:3167
SCIP_RETCODE SCIPvarNegate(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR **negvar)
Definition var.c:5917
SCIP_Real SCIPvarGetMultaggrUbLocal(SCIP_VAR *var, SCIP_SET *set)
Definition var.c:8500
SCIP_RETCODE SCIPvarGetProbvarSum(SCIP_VAR **var, SCIP_SET *set, SCIP_Real *scalar, SCIP_Real *constant)
Definition var.c:12647
SCIP_RETCODE SCIPvarIncGMIeffSum(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real gmieff)
Definition var.c:16399
SCIP_Real SCIPvarGetLastGMIScore(SCIP_VAR *var, SCIP_STAT *stat)
Definition var.c:16443
void SCIPvarAdjustUb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *ub)
Definition var.c:6534
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_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, int naggvars, SCIP_VAR **aggvars, SCIP_Real *scalars, SCIP_Real constant, SCIP_Bool *infeasible, SCIP_Bool *aggregated)
Definition var.c:5446
SCIP_Real SCIPvarGetAvgConflictlengthCurrentRun(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition var.c:15404
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:8097
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_VAR *vlbvar, SCIP_Real vlbcoef, SCIP_Real vlbconstant, SCIP_Bool transitive, SCIP_Bool *infeasible, int *nbdchgs)
Definition var.c:10001
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:2496
SCIP_Real SCIPvarGetVSIDSCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition var.c:15928
SCIP_RETCODE SCIPvarChgName(SCIP_VAR *var, BMS_BLKMEM *blkmem, const char *name)
Definition var.c:2913
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_VAR *vubvar, SCIP_Real vubcoef, SCIP_Real vubconstant, SCIP_Bool transitive, SCIP_Bool *infeasible, int *nbdchgs)
Definition var.c:10465
SCIP_Real SCIPvarGetMultaggrLbGlobal(SCIP_VAR *var, SCIP_SET *set)
Definition var.c:8566
SCIP_RETCODE SCIPvarSetRelaxSol(SCIP_VAR *var, SCIP_SET *set, SCIP_RELAXATION *relaxation, SCIP_Real solval, SCIP_Bool updateobj)
Definition var.c:13862
SCIP_RETCODE SCIPvarChgBranchFactor(SCIP_VAR *var, SCIP_SET *set, SCIP_Real branchfactor)
Definition var.c:11560
SCIP_Real SCIPvarGetAvgCutoffsCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition var.c:16312
SCIP_Bool SCIPvarDoNotMultaggr(SCIP_VAR *var)
Definition var.c:5881
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:1609
internal methods for problem variables