Scippy

SCIP

Solving Constraint Integer Programs

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