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