Scippy

SCIP

Solving Constraint Integer Programs

scip_var.c
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-2025 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file scip_var.c
26 * @ingroup OTHER_CFILES
27 * @brief public methods for SCIP variables
28 * @author Tobias Achterberg
29 * @author Timo Berthold
30 * @author Gerald Gamrath
31 * @author Leona Gottwald
32 * @author Stefan Heinz
33 * @author Gregor Hendel
34 * @author Thorsten Koch
35 * @author Alexander Martin
36 * @author Marc Pfetsch
37 * @author Michael Winkler
38 * @author Kati Wolter
39 *
40 * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE
41 */
42
43/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
44
45#include <ctype.h>
47#include "lpi/lpi.h"
48#include "scip/branch.h"
49#include "scip/clock.h"
50#include "scip/conflict.h"
51#include "scip/debug.h"
52#include "scip/history.h"
53#include "scip/implics.h"
54#include "scip/lp.h"
55#include "scip/prob.h"
56#include "scip/pub_cons.h"
57#include "scip/pub_implics.h"
58#include "scip/pub_lp.h"
59#include "scip/pub_message.h"
60#include "scip/pub_misc.h"
61#include "scip/pub_tree.h"
62#include "scip/pub_var.h"
63#include "scip/relax.h"
64#include "scip/scip_general.h"
65#include "scip/scip_lp.h"
66#include "scip/scip_mem.h"
67#include "scip/scip_message.h"
68#include "scip/scip_numerics.h"
69#include "scip/scip_prob.h"
70#include "scip/scip_probing.h"
71#include "scip/scip_sol.h"
73#include "scip/scip_tree.h"
74#include "scip/scip_var.h"
75#include "scip/set.h"
76#include "scip/sol.h"
77#include "scip/solve.h"
78#include "scip/stat.h"
79#include "scip/struct_lp.h"
80#include "scip/struct_mem.h"
81#include "scip/struct_primal.h"
82#include "scip/struct_prob.h"
83#include "scip/struct_scip.h"
84#include "scip/struct_set.h"
85#include "scip/struct_stat.h"
86#include "scip/struct_tree.h"
87#include "scip/struct_var.h"
88#include "scip/tree.h"
89#include "scip/var.h"
90
91
92/** creates and captures problem variable; if variable is of integral type, fractional bounds are automatically rounded;
93 * an integer variable with bounds zero and one is automatically converted into a binary variable;
94 *
95 * @warning When doing column generation and the original problem is a maximization problem, notice that SCIP will
96 * transform the problem into a minimization problem by multiplying the objective function by -1. Thus, the
97 * original objective function value of variables created during the solving process has to be multiplied by
98 * -1, too.
99 *
100 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
101 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
102 *
103 * @pre This method can be called if @p scip is in one of the following stages:
104 * - \ref SCIP_STAGE_PROBLEM
105 * - \ref SCIP_STAGE_TRANSFORMING
106 * - \ref SCIP_STAGE_INITPRESOLVE
107 * - \ref SCIP_STAGE_PRESOLVING
108 * - \ref SCIP_STAGE_EXITPRESOLVE
109 * - \ref SCIP_STAGE_PRESOLVED
110 * - \ref SCIP_STAGE_SOLVING
111 *
112 * @note the variable gets captured, hence at one point you have to release it using the method SCIPreleaseVar()
113 */
115 SCIP* scip, /**< SCIP data structure */
116 SCIP_VAR** var, /**< pointer to variable object */
117 const char* name, /**< name of variable, or NULL for automatic name creation */
118 SCIP_Real lb, /**< lower bound of variable */
119 SCIP_Real ub, /**< upper bound of variable */
120 SCIP_Real obj, /**< objective function value */
121 SCIP_VARTYPE vartype, /**< type of variable */
122 SCIP_Bool initial, /**< should var's column be present in the initial root LP? */
123 SCIP_Bool removable, /**< is var's column removable from the LP (due to aging or cleanup)? */
124 SCIP_DECL_VARDELORIG ((*vardelorig)), /**< frees user data of original variable, or NULL */
125 SCIP_DECL_VARTRANS ((*vartrans)), /**< creates transformed user data by transforming original user data, or NULL */
126 SCIP_DECL_VARDELTRANS ((*vardeltrans)), /**< frees user data of transformed variable, or NULL */
127 SCIP_DECL_VARCOPY ((*varcopy)), /**< copies variable data if wanted to subscip, or NULL */
128 SCIP_VARDATA* vardata /**< user data for this specific variable */
129 )
130{
131 assert(var != NULL);
132 assert(lb <= ub);
133
135
136 /* forbid infinite objective function values */
137 if( SCIPisInfinity(scip, REALABS(obj)) )
138 {
139 SCIPerrorMessage("invalid objective function value: value is infinite\n");
140 return SCIP_INVALIDDATA;
141 }
142
143 switch( scip->set->stage )
144 {
146 SCIP_CALL( SCIPvarCreateOriginal(var, scip->mem->probmem, scip->set, scip->stat,
147 name, lb, ub, obj, vartype, initial, removable, vardelorig, vartrans, vardeltrans, varcopy, vardata) );
148 break;
149
156 SCIP_CALL( SCIPvarCreateTransformed(var, scip->mem->probmem, scip->set, scip->stat,
157 name, lb, ub, obj, vartype, initial, removable, vardelorig, vartrans, vardeltrans, varcopy, vardata) );
158 break;
159
160 default:
161 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
162 return SCIP_INVALIDCALL;
163 } /*lint !e788*/
164
165 return SCIP_OKAY;
166}
167
168/** creates and captures problem variable with optional callbacks and variable data set to NULL, which can be set
169 * afterwards using SCIPvarSetDelorigData(), SCIPvarSetTransData(),
170 * SCIPvarSetDeltransData(), SCIPvarSetCopy(), and SCIPvarSetData(); sets variable flags initial=TRUE
171 * and removable = FALSE, which can be adjusted by using SCIPvarSetInitial() and SCIPvarSetRemovable(), resp.;
172 * if variable is of integral type, fractional bounds are automatically rounded;
173 * an integer variable with bounds zero and one is automatically converted into a binary variable;
174 *
175 * @warning When doing column generation and the original problem is a maximization problem, notice that SCIP will
176 * transform the problem into a minimization problem by multiplying the objective function by -1. Thus, the
177 * original objective function value of variables created during the solving process has to be multiplied by
178 * -1, too.
179 *
180 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
181 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
182 *
183 * @pre This method can be called if @p scip is in one of the following stages:
184 * - \ref SCIP_STAGE_PROBLEM
185 * - \ref SCIP_STAGE_TRANSFORMING
186 * - \ref SCIP_STAGE_INITPRESOLVE
187 * - \ref SCIP_STAGE_PRESOLVING
188 * - \ref SCIP_STAGE_EXITPRESOLVE
189 * - \ref SCIP_STAGE_PRESOLVED
190 * - \ref SCIP_STAGE_SOLVING
191 *
192 * @note the variable gets captured, hence at one point you have to release it using the method SCIPreleaseVar()
193 */
195 SCIP* scip, /**< SCIP data structure */
196 SCIP_VAR** var, /**< pointer to variable object */
197 const char* name, /**< name of variable, or NULL for automatic name creation */
198 SCIP_Real lb, /**< lower bound of variable */
199 SCIP_Real ub, /**< upper bound of variable */
200 SCIP_Real obj, /**< objective function value */
201 SCIP_VARTYPE vartype /**< type of variable */
202 )
203{
204 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateVarBasic", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
205
206 SCIP_CALL( SCIPcreateVar(scip, var, name, lb, ub, obj, vartype, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
207
208 return SCIP_OKAY;
209}
210
211/** outputs the variable name to the file stream
212 *
213 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
214 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
215 *
216 * @pre This method can be called if @p scip is in one of the following stages:
217 * - \ref SCIP_STAGE_PROBLEM
218 * - \ref SCIP_STAGE_TRANSFORMING
219 * - \ref SCIP_STAGE_TRANSFORMED
220 * - \ref SCIP_STAGE_INITPRESOLVE
221 * - \ref SCIP_STAGE_PRESOLVING
222 * - \ref SCIP_STAGE_EXITPRESOLVE
223 * - \ref SCIP_STAGE_PRESOLVED
224 * - \ref SCIP_STAGE_INITSOLVE
225 * - \ref SCIP_STAGE_SOLVING
226 * - \ref SCIP_STAGE_SOLVED
227 * - \ref SCIP_STAGE_EXITSOLVE
228 * - \ref SCIP_STAGE_FREETRANS
229 */
231 SCIP* scip, /**< SCIP data structure */
232 FILE* file, /**< output file, or NULL for stdout */
233 SCIP_VAR* var, /**< variable to output */
234 SCIP_Bool type /**< should the variable type be also posted */
235 )
236{
237 assert(scip != NULL);
238 assert(var != NULL);
239
240 SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarName", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
241
242 /* print variable name */
243 if( SCIPvarIsNegated(var) )
244 {
245 SCIP_VAR* negatedvar;
246
247 SCIP_CALL( SCIPgetNegatedVar(scip, var, &negatedvar) );
248 SCIPinfoMessage(scip, file, "<~%s>", SCIPvarGetName(negatedvar));
249 }
250 else
251 {
252 SCIPinfoMessage(scip, file, "<%s>", SCIPvarGetName(var));
253 }
254
255 if( type )
256 {
257 /* print variable type */
258 SCIPinfoMessage(scip, file, "[%c]",
262 }
263
264 return SCIP_OKAY;
265}
266
267/** print the given list of variables to output stream separated by the given delimiter character;
268 *
269 * i. e. the variables x1, x2, ..., xn with given delimiter ',' are written as: <x1>, <x2>, ..., <xn>;
270 *
271 * the method SCIPparseVarsList() can parse such a string
272 *
273 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
274 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
275 *
276 * @pre This method can be called if @p scip is in one of the following stages:
277 * - \ref SCIP_STAGE_PROBLEM
278 * - \ref SCIP_STAGE_TRANSFORMING
279 * - \ref SCIP_STAGE_TRANSFORMED
280 * - \ref SCIP_STAGE_INITPRESOLVE
281 * - \ref SCIP_STAGE_PRESOLVING
282 * - \ref SCIP_STAGE_EXITPRESOLVE
283 * - \ref SCIP_STAGE_PRESOLVED
284 * - \ref SCIP_STAGE_INITSOLVE
285 * - \ref SCIP_STAGE_SOLVING
286 * - \ref SCIP_STAGE_SOLVED
287 * - \ref SCIP_STAGE_EXITSOLVE
288 * - \ref SCIP_STAGE_FREETRANS
289 *
290 * @note The printing process is done via the message handler system.
291 */
293 SCIP* scip, /**< SCIP data structure */
294 FILE* file, /**< output file, or NULL for stdout */
295 SCIP_VAR** vars, /**< variable array to output */
296 int nvars, /**< number of variables */
297 SCIP_Bool type, /**< should the variable type be also posted */
298 char delimiter /**< character which is used for delimitation */
299 )
300{
301 int v;
302
303 SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsList", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
304
305 for( v = 0; v < nvars; ++v )
306 {
307 if( v > 0 )
308 {
309 SCIPinfoMessage(scip, file, "%c", delimiter);
310 }
311
312 /* print variable name */
313 SCIP_CALL( SCIPwriteVarName(scip, file, vars[v], type) );
314 }
315
316 return SCIP_OKAY;
317}
318
319/** print the given variables and coefficients as linear sum in the following form
320 * c1 <x1> + c2 <x2> ... + cn <xn>
321 *
322 * This string can be parsed by the method SCIPparseVarsLinearsum().
323 *
324 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
325 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
326 *
327 * @pre This method can be called if @p scip is in one of the following stages:
328 * - \ref SCIP_STAGE_PROBLEM
329 * - \ref SCIP_STAGE_TRANSFORMING
330 * - \ref SCIP_STAGE_TRANSFORMED
331 * - \ref SCIP_STAGE_INITPRESOLVE
332 * - \ref SCIP_STAGE_PRESOLVING
333 * - \ref SCIP_STAGE_EXITPRESOLVE
334 * - \ref SCIP_STAGE_PRESOLVED
335 * - \ref SCIP_STAGE_INITSOLVE
336 * - \ref SCIP_STAGE_SOLVING
337 * - \ref SCIP_STAGE_SOLVED
338 * - \ref SCIP_STAGE_EXITSOLVE
339 * - \ref SCIP_STAGE_FREETRANS
340 *
341 * @note The printing process is done via the message handler system.
342 */
344 SCIP* scip, /**< SCIP data structure */
345 FILE* file, /**< output file, or NULL for stdout */
346 SCIP_VAR** vars, /**< variable array to output */
347 SCIP_Real* vals, /**< array of coefficients or NULL if all coefficients are 1.0 */
348 int nvars, /**< number of variables */
349 SCIP_Bool type /**< should the variable type be also posted */
350 )
351{
352 int v;
353
354 SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsLinearsum", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
355
356 for( v = 0; v < nvars; ++v )
357 {
358 if( vals != NULL )
359 {
360 if( vals[v] == 1.0 )
361 {
362 if( v > 0 )
363 SCIPinfoMessage(scip, file, " +");
364 }
365 else if( vals[v] == -1.0 )
366 SCIPinfoMessage(scip, file, " -");
367 else
368 SCIPinfoMessage(scip, file, " %+.15g", vals[v]);
369 }
370 else if( nvars > 0 )
371 SCIPinfoMessage(scip, file, " +");
372
373 /* print variable name */
374 SCIP_CALL( SCIPwriteVarName(scip, file, vars[v], type) );
375 }
376
377 return SCIP_OKAY;
378}
379
380/** print the given terms as signomial in the following form
381 * c1 <x11>^e11 <x12>^e12 ... <x1n>^e1n + c2 <x21>^e21 <x22>^e22 ... + ... + cn <xn1>^en1 ...
382 *
383 * This string can be parsed by the method SCIPparseVarsPolynomial().
384 *
385 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
386 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
387 *
388 * @pre This method can be called if @p scip is in one of the following stages:
389 * - \ref SCIP_STAGE_PROBLEM
390 * - \ref SCIP_STAGE_TRANSFORMING
391 * - \ref SCIP_STAGE_TRANSFORMED
392 * - \ref SCIP_STAGE_INITPRESOLVE
393 * - \ref SCIP_STAGE_PRESOLVING
394 * - \ref SCIP_STAGE_EXITPRESOLVE
395 * - \ref SCIP_STAGE_PRESOLVED
396 * - \ref SCIP_STAGE_INITSOLVE
397 * - \ref SCIP_STAGE_SOLVING
398 * - \ref SCIP_STAGE_SOLVED
399 * - \ref SCIP_STAGE_EXITSOLVE
400 * - \ref SCIP_STAGE_FREETRANS
401 *
402 * @note The printing process is done via the message handler system.
403 */
405 SCIP* scip, /**< SCIP data structure */
406 FILE* file, /**< output file, or NULL for stdout */
407 SCIP_VAR*** monomialvars, /**< arrays with variables for each monomial */
408 SCIP_Real** monomialexps, /**< arrays with variable exponents, or NULL if always 1.0 */
409 SCIP_Real* monomialcoefs, /**< array with monomial coefficients */
410 int* monomialnvars, /**< array with number of variables for each monomial */
411 int nmonomials, /**< number of monomials */
412 SCIP_Bool type /**< should the variable type be also posted */
413 )
414{
415 int i;
416 int v;
417
418 assert(scip != NULL);
419 assert(monomialvars != NULL || nmonomials == 0);
420 assert(monomialcoefs != NULL || nmonomials == 0);
421 assert(monomialnvars != NULL || nmonomials == 0);
422
423 SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsPolynomial", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
424
425 if( nmonomials == 0 )
426 {
427 SCIPinfoMessage(scip, file, " 0 ");
428 return SCIP_OKAY;
429 }
430
431 for( i = 0; i < nmonomials; ++i )
432 {
433 if( monomialcoefs[i] == 1.0 ) /*lint !e613*/
434 {
435 if( i > 0 )
436 SCIPinfoMessage(scip, file, " +");
437 }
438 else if( monomialcoefs[i] == -1.0 ) /*lint !e613*/
439 SCIPinfoMessage(scip, file, " -");
440 else
441 SCIPinfoMessage(scip, file, " %+.15g", monomialcoefs[i]); /*lint !e613*/
442
443 assert(monomialvars[i] != NULL || monomialnvars[i] == 0); /*lint !e613*/
444
445 for( v = 0; v < monomialnvars[i]; ++v ) /*lint !e613*/
446 {
447 SCIP_CALL( SCIPwriteVarName(scip, file, monomialvars[i][v], type) ); /*lint !e613*/
448 if( monomialexps != NULL && monomialexps[i] != NULL && monomialexps[i][v] != 1.0 )
449 {
450 SCIPinfoMessage(scip, file, "^%.15g", monomialexps[i][v]);
451 }
452 }
453 }
454
455 return SCIP_OKAY;
456}
457
458/** parses variable information (in cip format) out of a string; if the parsing process was successful a variable is
459 * created and captured; if variable is of integral type, fractional bounds are automatically rounded; an integer
460 * variable with bounds zero and one is automatically converted into a binary variable
461 *
462 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
463 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
464 *
465 * @pre This method can be called if @p scip is in one of the following stages:
466 * - \ref SCIP_STAGE_PROBLEM
467 * - \ref SCIP_STAGE_TRANSFORMING
468 * - \ref SCIP_STAGE_INITPRESOLVE
469 * - \ref SCIP_STAGE_PRESOLVING
470 * - \ref SCIP_STAGE_EXITPRESOLVE
471 * - \ref SCIP_STAGE_PRESOLVED
472 * - \ref SCIP_STAGE_SOLVING
473 */
475 SCIP* scip, /**< SCIP data structure */
476 SCIP_VAR** var, /**< pointer to store the problem variable */
477 const char* str, /**< string to parse */
478 SCIP_Bool initial, /**< should var's column be present in the initial root LP? */
479 SCIP_Bool removable, /**< is var's column removable from the LP (due to aging or cleanup)? */
480 SCIP_DECL_VARCOPY ((*varcopy)), /**< copies variable data if wanted to subscip, or NULL */
481 SCIP_DECL_VARDELORIG ((*vardelorig)), /**< frees user data of original variable */
482 SCIP_DECL_VARTRANS ((*vartrans)), /**< creates transformed user data by transforming original user data */
483 SCIP_DECL_VARDELTRANS ((*vardeltrans)), /**< frees user data of transformed variable */
484 SCIP_VARDATA* vardata, /**< user data for this specific variable */
485 char** endptr, /**< pointer to store the final string position if successful */
486 SCIP_Bool* success /**< pointer store if the paring process was successful */
487 )
488{
489 assert(var != NULL);
490
492
493 switch( scip->set->stage )
494 {
496 SCIP_CALL( SCIPvarParseOriginal(var, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
497 str, initial, removable, varcopy, vardelorig, vartrans, vardeltrans, vardata, endptr, success) );
498 break;
499
506 SCIP_CALL( SCIPvarParseTransformed(var, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
507 str, initial, removable, varcopy, vardelorig, vartrans, vardeltrans, vardata, endptr, success) );
508 break;
509
510 default:
511 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
512 return SCIP_INVALIDCALL;
513 } /*lint !e788*/
514
515 return SCIP_OKAY;
516}
517
518/** parses the given string for a variable name and stores the variable in the corresponding pointer if such a variable
519 * exits and returns the position where the parsing stopped
520 *
521 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
522 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
523 *
524 * @pre This method can be called if @p scip is in one of the following stages:
525 * - \ref SCIP_STAGE_PROBLEM
526 * - \ref SCIP_STAGE_TRANSFORMING
527 * - \ref SCIP_STAGE_INITPRESOLVE
528 * - \ref SCIP_STAGE_PRESOLVING
529 * - \ref SCIP_STAGE_EXITPRESOLVE
530 * - \ref SCIP_STAGE_PRESOLVED
531 * - \ref SCIP_STAGE_SOLVING
532 */
534 SCIP* scip, /**< SCIP data structure */
535 const char* str, /**< string to parse */
536 SCIP_VAR** var, /**< pointer to store the problem variable, or NULL if it does not exit */
537 char** endptr /**< pointer to store the final string position if successful */
538 )
539{
540 char varname[SCIP_MAXSTRLEN];
541
542 assert(str != NULL);
543 assert(var != NULL);
544 assert(endptr != NULL);
545
546 SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarName", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
547
548 SCIPstrCopySection(str, '<', '>', varname, SCIP_MAXSTRLEN, endptr);
549 assert(*endptr != NULL);
550
551 if( *endptr == str )
552 {
553 *var = NULL;
554 return SCIP_OKAY;
555 }
556
557 /* check if we have a negated variable */
558 if( *varname == '~' )
559 {
560 SCIPdebugMsg(scip, "parsed negated variable name <%s>\n", &varname[1]);
561
562 /* search for the variable and ignore '~' */
563 (*var) = SCIPfindVar(scip, &varname[1]);
564
565 if( *var != NULL )
566 {
567 SCIP_CALL( SCIPgetNegatedVar(scip, *var, var) );
568 }
569 }
570 else
571 {
572 SCIPdebugMsg(scip, "parsed variable name <%s>\n", varname);
573
574 /* search for the variable */
575 (*var) = SCIPfindVar(scip, varname);
576 }
577
578 str = *endptr;
579
580 /* skip additional variable type marker */
581 if( *str == '[' && (str[1] == SCIP_VARTYPE_BINARY_CHAR || str[1] == SCIP_VARTYPE_INTEGER_CHAR ||
582 str[1] == SCIP_VARTYPE_IMPLINT_CHAR || str[1] == SCIP_VARTYPE_CONTINUOUS_CHAR ) && str[2] == ']' )
583 (*endptr) += 3;
584
585 return SCIP_OKAY;
586}
587
588/** parse the given string as variable list (here ',' is the delimiter)) (<x1>, <x2>, ..., <xn>) (see
589 * SCIPwriteVarsList() ); if it was successful, the pointer success is set to TRUE
590 *
591 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
592 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
593 *
594 * @pre This method can be called if @p scip is in one of the following stages:
595 * - \ref SCIP_STAGE_PROBLEM
596 * - \ref SCIP_STAGE_TRANSFORMING
597 * - \ref SCIP_STAGE_INITPRESOLVE
598 * - \ref SCIP_STAGE_PRESOLVING
599 * - \ref SCIP_STAGE_EXITPRESOLVE
600 * - \ref SCIP_STAGE_PRESOLVED
601 * - \ref SCIP_STAGE_SOLVING
602 *
603 * @note The pointer success in only set to FALSE in the case that a variable with a parsed variable name does not exist.
604 *
605 * @note If the number of (parsed) variables is greater than the available slots in the variable array, nothing happens
606 * except that the required size is stored in the corresponding integer; the reason for this approach is that we
607 * cannot reallocate memory, since we do not know how the memory has been allocated (e.g., by a C++ 'new' or SCIP
608 * memory functions).
609 */
611 SCIP* scip, /**< SCIP data structure */
612 const char* str, /**< string to parse */
613 SCIP_VAR** vars, /**< array to store the parsed variable */
614 int* nvars, /**< pointer to store number of parsed variables */
615 int varssize, /**< size of the variable array */
616 int* requiredsize, /**< pointer to store the required array size for the active variables */
617 char** endptr, /**< pointer to store the final string position if successful */
618 char delimiter, /**< character which is used for delimitation */
619 SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
620 )
621{
622 SCIP_VAR** tmpvars;
623 SCIP_VAR* var;
624 int ntmpvars = 0;
625 int v;
626
627 assert( nvars != NULL );
628 assert( requiredsize != NULL );
629 assert( endptr != NULL );
630 assert( success != NULL );
631
632 SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsList", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
633
634 /* allocate buffer memory for temporary storing the parsed variables */
635 SCIP_CALL( SCIPallocBufferArray(scip, &tmpvars, varssize) );
636
637 *success = TRUE;
638
639 do
640 {
641 *endptr = (char*)str;
642
643 /* parse variable name */
644 SCIP_CALL( SCIPparseVarName(scip, str, &var, endptr) );
645
646 if( var == NULL )
647 break;
648
649 str = *endptr;
650
651 /* store the variable in the tmp array */
652 if( ntmpvars < varssize )
653 tmpvars[ntmpvars] = var;
654
655 ntmpvars++;
656
657 SCIP_CALL( SCIPskipSpace((char**)&str) );
658 }
659 while( *str == delimiter );
660
661 *endptr = (char*)str;
662
663 /* if all variable name searches were successful and the variable array has enough slots, copy the collected variables */
664 if( (*success) && ntmpvars <= varssize )
665 {
666 for( v = 0; v < ntmpvars; ++v )
667 vars[v] = tmpvars[v];
668
669 (*nvars) = ntmpvars;
670 }
671 else
672 (*nvars) = 0;
673
674 (*requiredsize) = ntmpvars;
675
676 /* free buffer arrays */
677 SCIPfreeBufferArray(scip, &tmpvars);
678
679 return SCIP_OKAY;
680}
681
682/** parse the given string as linear sum of variables and coefficients (c1 <x1> + c2 <x2> + ... + cn <xn>)
683 * (see SCIPwriteVarsLinearsum() ); if it was successful, the pointer success is set to TRUE
684 *
685 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
686 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
687 *
688 * @pre This method can be called if @p scip is in one of the following stages:
689 * - \ref SCIP_STAGE_PROBLEM
690 * - \ref SCIP_STAGE_TRANSFORMING
691 * - \ref SCIP_STAGE_INITPRESOLVE
692 * - \ref SCIP_STAGE_PRESOLVING
693 * - \ref SCIP_STAGE_EXITPRESOLVE
694 * - \ref SCIP_STAGE_PRESOLVED
695 * - \ref SCIP_STAGE_SOLVING
696 *
697 * @note The pointer success in only set to FALSE in the case that a variable with a parsed variable name does not exist.
698 *
699 * @note If the number of (parsed) variables is greater than the available slots in the variable array, nothing happens
700 * except that the required size is stored in the corresponding integer; the reason for this approach is that we
701 * cannot reallocate memory, since we do not know how the memory has been allocated (e.g., by a C++ 'new' or SCIP
702 * memory functions).
703 */
705 SCIP* scip, /**< SCIP data structure */
706 const char* str, /**< string to parse */
707 SCIP_VAR** vars, /**< array to store the parsed variables */
708 SCIP_Real* vals, /**< array to store the parsed coefficients */
709 int* nvars, /**< pointer to store number of parsed variables */
710 int varssize, /**< size of the variable array */
711 int* requiredsize, /**< pointer to store the required array size for the active variables */
712 char** endptr, /**< pointer to store the final string position if successful */
713 SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
714 )
715{
716 SCIP_VAR*** monomialvars;
717 SCIP_Real** monomialexps;
718 SCIP_Real* monomialcoefs;
719 int* monomialnvars;
720 int nmonomials;
721
722 SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsLinearsum", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
723
724 assert(scip != NULL);
725 assert(str != NULL);
726 assert(vars != NULL || varssize == 0);
727 assert(vals != NULL || varssize == 0);
728 assert(nvars != NULL);
729 assert(requiredsize != NULL);
730 assert(endptr != NULL);
731 assert(success != NULL);
732
733 *requiredsize = 0;
734
735 SCIP_CALL( SCIPparseVarsPolynomial(scip, str, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, &nmonomials, endptr, success) );
736
737 if( !*success )
738 {
739 assert(nmonomials == 0); /* SCIPparseVarsPolynomial should have freed all buffers, so no need to call free here */
740 return SCIP_OKAY;
741 }
742
743 /* check if linear sum is just "0" */
744 if( nmonomials == 1 && monomialnvars[0] == 0 && monomialcoefs[0] == 0.0 )
745 {
746 *nvars = 0;
747 *requiredsize = 0;
748
749 SCIPfreeParseVarsPolynomialData(scip, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, nmonomials);
750
751 return SCIP_OKAY;
752 }
753
754 *nvars = nmonomials;
755 *requiredsize = nmonomials;
756
757 /* if we have enough slots in the variables array, copy variables over */
758 if( varssize >= nmonomials )
759 {
760 int v;
761
762 for( v = 0; v < nmonomials; ++v )
763 {
764 if( monomialnvars[v] == 0 )
765 {
766 SCIPerrorMessage("constant in linear sum\n");
767 *success = FALSE;
768 break;
769 }
770 if( monomialnvars[v] > 1 || monomialexps[v][0] != 1.0 )
771 {
772 SCIPerrorMessage("nonlinear monomial in linear sum\n");
773 *success = FALSE;
774 break;
775 }
776 assert(monomialnvars[v] == 1);
777 assert(monomialvars[v][0] != NULL);
778 assert(monomialexps[v][0] == 1.0);
779
780 vars[v] = monomialvars[v][0]; /*lint !e613*/
781 vals[v] = monomialcoefs[v]; /*lint !e613*/
782 }
783 }
784
785 SCIPfreeParseVarsPolynomialData(scip, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, nmonomials);
786
787 return SCIP_OKAY;
788}
789
790/** parse the given string as signomial of variables and coefficients
791 * (c1 <x11>^e11 <x12>^e12 ... <x1n>^e1n + c2 <x21>^e21 <x22>^e22 ... + ... + cn <xn1>^en1 ...)
792 * (see SCIPwriteVarsPolynomial()); if it was successful, the pointer success is set to TRUE
793 *
794 * The user has to call SCIPfreeParseVarsPolynomialData(scip, monomialvars, monomialexps,
795 * monomialcoefs, monomialnvars, *nmonomials) short after SCIPparseVarsPolynomial to free all the
796 * allocated memory again.
797 *
798 * Parsing is stopped at the end of string (indicated by the \\0-character) or when no more monomials
799 * are recognized.
800 *
801 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
802 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
803 *
804 * @pre This method can be called if @p scip is in one of the following stages:
805 * - \ref SCIP_STAGE_PROBLEM
806 * - \ref SCIP_STAGE_TRANSFORMING
807 * - \ref SCIP_STAGE_INITPRESOLVE
808 * - \ref SCIP_STAGE_PRESOLVING
809 * - \ref SCIP_STAGE_EXITPRESOLVE
810 * - \ref SCIP_STAGE_PRESOLVED
811 * - \ref SCIP_STAGE_SOLVING
812 */
814 SCIP* scip, /**< SCIP data structure */
815 const char* str, /**< string to parse */
816 SCIP_VAR**** monomialvars, /**< pointer to store arrays with variables for each monomial */
817 SCIP_Real*** monomialexps, /**< pointer to store arrays with variable exponents */
818 SCIP_Real** monomialcoefs, /**< pointer to store array with monomial coefficients */
819 int** monomialnvars, /**< pointer to store array with number of variables for each monomial */
820 int* nmonomials, /**< pointer to store number of parsed monomials */
821 char** endptr, /**< pointer to store the final string position if successful */
822 SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
823 )
824{
825 typedef enum
826 {
827 SCIPPARSEPOLYNOMIAL_STATE_BEGIN, /* we are at the beginning of a monomial */
828 SCIPPARSEPOLYNOMIAL_STATE_INTERMED, /* we are in between the factors of a monomial */
829 SCIPPARSEPOLYNOMIAL_STATE_COEF, /* we parse the coefficient of a monomial */
830 SCIPPARSEPOLYNOMIAL_STATE_VARS, /* we parse monomial variables */
831 SCIPPARSEPOLYNOMIAL_STATE_EXPONENT, /* we parse the exponent of a variable */
832 SCIPPARSEPOLYNOMIAL_STATE_END, /* we are at the end the polynomial */
833 SCIPPARSEPOLYNOMIAL_STATE_ERROR /* a parsing error occured */
834 } SCIPPARSEPOLYNOMIAL_STATES;
835
836 SCIPPARSEPOLYNOMIAL_STATES state;
837 int monomialssize;
838
839 /* data of currently parsed monomial */
840 int varssize;
841 int nvars;
842 SCIP_VAR** vars;
843 SCIP_Real* exponents;
844 SCIP_Real coef;
845
846 assert(scip != NULL);
847 assert(str != NULL);
848 assert(monomialvars != NULL);
849 assert(monomialexps != NULL);
850 assert(monomialnvars != NULL);
851 assert(monomialcoefs != NULL);
852 assert(nmonomials != NULL);
853 assert(endptr != NULL);
854 assert(success != NULL);
855
856 SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsPolynomial", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
857
858 *success = FALSE;
859 *nmonomials = 0;
860 monomialssize = 0;
861 *monomialvars = NULL;
862 *monomialexps = NULL;
863 *monomialcoefs = NULL;
864 *monomialnvars = NULL;
865
866 /* initialize state machine */
867 state = SCIPPARSEPOLYNOMIAL_STATE_BEGIN;
868 varssize = 0;
869 nvars = 0;
870 vars = NULL;
871 exponents = NULL;
872 coef = SCIP_INVALID;
873
874 SCIPdebugMsg(scip, "parsing polynomial from '%s'\n", str);
875
876 while( *str && state != SCIPPARSEPOLYNOMIAL_STATE_END && state != SCIPPARSEPOLYNOMIAL_STATE_ERROR )
877 {
878 /* skip white space */
879 SCIP_CALL( SCIPskipSpace((char**)&str) );
880
881 assert(state != SCIPPARSEPOLYNOMIAL_STATE_END);
882
883 switch( state )
884 {
885 case SCIPPARSEPOLYNOMIAL_STATE_BEGIN:
886 {
887 if( coef != SCIP_INVALID ) /*lint !e777*/
888 {
889 SCIPdebugMsg(scip, "push monomial with coefficient <%g> and <%d> vars\n", coef, nvars);
890
891 /* push previous monomial */
892 if( monomialssize <= *nmonomials )
893 {
894 monomialssize = SCIPcalcMemGrowSize(scip, *nmonomials+1);
895
896 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, *nmonomials, monomialssize) );
897 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, *nmonomials, monomialssize) );
898 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, *nmonomials, monomialssize) );
899 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, *nmonomials, monomialssize) );
900 }
901
902 if( nvars > 0 )
903 {
904 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*monomialvars)[*nmonomials], vars, nvars) ); /*lint !e866*/
905 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*monomialexps)[*nmonomials], exponents, nvars) ); /*lint !e866*/
906 }
907 else
908 {
909 (*monomialvars)[*nmonomials] = NULL;
910 (*monomialexps)[*nmonomials] = NULL;
911 }
912 (*monomialcoefs)[*nmonomials] = coef;
913 (*monomialnvars)[*nmonomials] = nvars;
914 ++*nmonomials;
915
916 nvars = 0;
917 coef = SCIP_INVALID;
918 }
919
920 if( *str == '<' )
921 {
922 /* there seem to come a variable at the beginning of a monomial
923 * so assume the coefficient is 1.0
924 */
925 state = SCIPPARSEPOLYNOMIAL_STATE_VARS;
926 coef = 1.0;
927 }
928 else if( *str == '-' || *str == '+' || isdigit(*str) )
929 state = SCIPPARSEPOLYNOMIAL_STATE_COEF;
930 else
931 state = SCIPPARSEPOLYNOMIAL_STATE_END;
932
933 break;
934 }
935
936 case SCIPPARSEPOLYNOMIAL_STATE_INTERMED:
937 {
938 if( *str == '<' )
939 {
940 /* there seem to come another variable */
941 state = SCIPPARSEPOLYNOMIAL_STATE_VARS;
942 }
943 else if( *str == '-' || *str == '+' || isdigit(*str) )
944 {
945 /* there seem to come a coefficient, which means the next monomial */
946 state = SCIPPARSEPOLYNOMIAL_STATE_BEGIN;
947 }
948 else /* since we cannot detect the symbols we stop parsing the polynomial */
949 state = SCIPPARSEPOLYNOMIAL_STATE_END;
950
951 break;
952 }
953
954 case SCIPPARSEPOLYNOMIAL_STATE_COEF:
955 {
956 if( *str == '+' && !isdigit(str[1]) )
957 {
958 /* only a plus sign, without number */
959 coef = 1.0;
960 ++str;
961 }
962 else if( *str == '-' && !isdigit(str[1]) )
963 {
964 /* only a minus sign, without number */
965 coef = -1.0;
966 ++str;
967 }
968 else if( SCIPstrToRealValue(str, &coef, endptr) )
969 {
970 str = *endptr;
971 }
972 else
973 {
974 SCIPerrorMessage("could not parse number in the beginning of '%s'\n", str);
975 state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
976 break;
977 }
978
979 /* after the coefficient we go into the intermediate state, i.e., expecting next variables */
980 state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED; /*lint !e838*/
981
982 break;
983 }
984
985 case SCIPPARSEPOLYNOMIAL_STATE_VARS:
986 {
987 SCIP_VAR* var;
988
989 assert(*str == '<');
990
991 /* parse variable name */
992 SCIP_CALL( SCIPparseVarName(scip, str, &var, endptr) );
993
994 /* check if variable name was parsed */
995 if( *endptr == str )
996 {
997 state = SCIPPARSEPOLYNOMIAL_STATE_END;
998 break;
999 }
1000
1001 if( var == NULL )
1002 {
1003 SCIPerrorMessage("did not find variable in the beginning of %s\n", str);
1004 state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
1005 break;
1006 }
1007
1008 /* add variable to vars array */
1009 if( nvars + 1 > varssize )
1010 {
1011 varssize = SCIPcalcMemGrowSize(scip, nvars+1);
1012 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &vars, nvars, varssize) );
1013 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &exponents, nvars, varssize) );
1014 }
1015 assert(vars != NULL);
1016 assert(exponents != NULL);
1017
1018 vars[nvars] = var;
1019 exponents[nvars] = 1.0;
1020 ++nvars;
1021
1022 str = *endptr;
1023
1024 if( *str == '^' )
1025 state = SCIPPARSEPOLYNOMIAL_STATE_EXPONENT;
1026 else
1027 state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED;
1028
1029 break;
1030 }
1031
1032 case SCIPPARSEPOLYNOMIAL_STATE_EXPONENT:
1033 {
1034 assert(*str == '^');
1035 assert(nvars > 0); /* we should be in a monomial that has already a variable */
1036 assert(exponents != NULL);
1037 ++str;
1038
1039 if( !SCIPstrToRealValue(str, &exponents[nvars-1], endptr) )
1040 {
1041 SCIPerrorMessage("could not parse number in the beginning of '%s'\n", str);
1042 state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
1043 break;
1044 }
1045 str = *endptr;
1046
1047 /* after the exponent we go into the intermediate state, i.e., expecting next variables */
1048 state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED; /*lint !e838*/
1049 break;
1050 }
1051
1052 /* coverity[dead_error_line] */
1053 case SCIPPARSEPOLYNOMIAL_STATE_END:
1054 /* coverity[dead_error_line] */
1055 case SCIPPARSEPOLYNOMIAL_STATE_ERROR:
1056 default:
1057 SCIPerrorMessage("unexpected state\n");
1058 return SCIP_READERROR;
1059 }
1060 }
1061
1062 /* set end pointer */
1063 *endptr = (char*)str;
1064
1065 /* check state at end of string */
1066 switch( state )
1067 {
1068 case SCIPPARSEPOLYNOMIAL_STATE_BEGIN:
1069 case SCIPPARSEPOLYNOMIAL_STATE_END:
1070 case SCIPPARSEPOLYNOMIAL_STATE_INTERMED:
1071 {
1072 if( coef != SCIP_INVALID ) /*lint !e777*/
1073 {
1074 /* push last monomial */
1075 SCIPdebugMsg(scip, "push monomial with coefficient <%g> and <%d> vars\n", coef, nvars);
1076 if( monomialssize <= *nmonomials )
1077 {
1078 monomialssize = *nmonomials+1;
1079 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, *nmonomials, monomialssize) );
1080 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, *nmonomials, monomialssize) );
1081 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, *nmonomials, monomialssize) );
1082 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, *nmonomials, monomialssize) );
1083 }
1084
1085 if( nvars > 0 )
1086 {
1087 /* shrink vars and exponents array to needed size and take over ownership */
1088 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &vars, varssize, nvars) );
1089 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &exponents, varssize, nvars) );
1090 (*monomialvars)[*nmonomials] = vars;
1091 (*monomialexps)[*nmonomials] = exponents;
1092 vars = NULL;
1093 exponents = NULL;
1094 }
1095 else
1096 {
1097 (*monomialvars)[*nmonomials] = NULL;
1098 (*monomialexps)[*nmonomials] = NULL;
1099 }
1100 (*monomialcoefs)[*nmonomials] = coef;
1101 (*monomialnvars)[*nmonomials] = nvars;
1102 ++*nmonomials;
1103 }
1104
1105 *success = TRUE;
1106 break;
1107 }
1108
1109 case SCIPPARSEPOLYNOMIAL_STATE_COEF:
1110 case SCIPPARSEPOLYNOMIAL_STATE_VARS:
1111 case SCIPPARSEPOLYNOMIAL_STATE_EXPONENT:
1112 {
1113 SCIPerrorMessage("unexpected parsing state at end of polynomial string\n");
1114 }
1115 /*lint -fallthrough*/
1116 case SCIPPARSEPOLYNOMIAL_STATE_ERROR:
1117 assert(!*success);
1118 break;
1119 }
1120
1121 /* free memory to store current monomial, if still existing */
1122 SCIPfreeBlockMemoryArrayNull(scip, &vars, varssize);
1123 SCIPfreeBlockMemoryArrayNull(scip, &exponents, varssize);
1124
1125 if( *success && *nmonomials > 0 )
1126 {
1127 /* shrink arrays to required size, so we do not need to keep monomialssize around */
1128 assert(*nmonomials <= monomialssize);
1129 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, monomialssize, *nmonomials) );
1130 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, monomialssize, *nmonomials) );
1131 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, monomialssize, *nmonomials) );
1132 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, monomialssize, *nmonomials) );
1133
1134 /* SCIPwriteVarsPolynomial(scip, NULL, *monomialvars, *monomialexps, *monomialcoefs, *monomialnvars, *nmonomials, FALSE); */
1135 }
1136 else
1137 {
1138 /* in case of error, cleanup all data here */
1139 SCIPfreeParseVarsPolynomialData(scip, monomialvars, monomialexps, monomialcoefs, monomialnvars, *nmonomials);
1140 *nmonomials = 0;
1141 }
1142
1143 return SCIP_OKAY;
1144}
1145
1146/** frees memory allocated when parsing a signomial from a string
1147 *
1148 * @pre This method can be called if @p scip is in one of the following stages:
1149 * - \ref SCIP_STAGE_PROBLEM
1150 * - \ref SCIP_STAGE_TRANSFORMING
1151 * - \ref SCIP_STAGE_INITPRESOLVE
1152 * - \ref SCIP_STAGE_PRESOLVING
1153 * - \ref SCIP_STAGE_EXITPRESOLVE
1154 * - \ref SCIP_STAGE_PRESOLVED
1155 * - \ref SCIP_STAGE_SOLVING
1156 */
1158 SCIP* scip, /**< SCIP data structure */
1159 SCIP_VAR**** monomialvars, /**< pointer to store arrays with variables for each monomial */
1160 SCIP_Real*** monomialexps, /**< pointer to store arrays with variable exponents */
1161 SCIP_Real** monomialcoefs, /**< pointer to store array with monomial coefficients */
1162 int** monomialnvars, /**< pointer to store array with number of variables for each monomial */
1163 int nmonomials /**< pointer to store number of parsed monomials */
1164 )
1165{
1166 int i;
1167
1168 assert(scip != NULL);
1169 assert(monomialvars != NULL);
1170 assert(monomialexps != NULL);
1171 assert(monomialcoefs != NULL);
1172 assert(monomialnvars != NULL);
1173
1174 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPfreeParseVarsPolynomialData", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1175
1176 if( nmonomials == 0 )
1177 return;
1178
1179 assert(*monomialvars != NULL);
1180 assert(*monomialexps != NULL);
1181 assert(*monomialcoefs != NULL);
1182 assert(*monomialnvars != NULL);
1183
1184 for( i = nmonomials - 1; i >= 0; --i )
1185 {
1186 SCIPfreeBlockMemoryArrayNull(scip, &(*monomialexps)[i], (*monomialnvars)[i]);
1187 SCIPfreeBlockMemoryArrayNull(scip, &(*monomialvars)[i], (*monomialnvars)[i]);
1188 }
1189
1190 SCIPfreeBlockMemoryArray(scip, monomialcoefs, nmonomials);
1191 SCIPfreeBlockMemoryArray(scip, monomialnvars, nmonomials);
1192 SCIPfreeBlockMemoryArray(scip, monomialexps, nmonomials);
1193 SCIPfreeBlockMemoryArray(scip, monomialvars, nmonomials);
1194}
1195
1196/** increases usage counter of variable
1197 *
1198 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1199 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1200 *
1201 * @pre This method can be called if @p scip is in one of the following stages:
1202 * - \ref SCIP_STAGE_PROBLEM
1203 * - \ref SCIP_STAGE_TRANSFORMING
1204 * - \ref SCIP_STAGE_TRANSFORMED
1205 * - \ref SCIP_STAGE_INITPRESOLVE
1206 * - \ref SCIP_STAGE_PRESOLVING
1207 * - \ref SCIP_STAGE_EXITPRESOLVE
1208 * - \ref SCIP_STAGE_PRESOLVED
1209 * - \ref SCIP_STAGE_INITSOLVE
1210 * - \ref SCIP_STAGE_SOLVING
1211 * - \ref SCIP_STAGE_SOLVED
1212 * - \ref SCIP_STAGE_EXITSOLVE
1213 */
1215 SCIP* scip, /**< SCIP data structure */
1216 SCIP_VAR* var /**< variable to capture */
1217 )
1218{
1219 SCIP_CALL( SCIPcheckStage(scip, "SCIPcaptureVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1220 assert(var->scip == scip);
1221
1222 SCIPvarCapture(var);
1223
1224 return SCIP_OKAY;
1225}
1226
1227/** decreases usage counter of variable, if the usage pointer reaches zero the variable gets freed
1228 *
1229 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1230 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1231 *
1232 * @pre This method can be called if @p scip is in one of the following stages:
1233 * - \ref SCIP_STAGE_PROBLEM
1234 * - \ref SCIP_STAGE_TRANSFORMING
1235 * - \ref SCIP_STAGE_TRANSFORMED
1236 * - \ref SCIP_STAGE_INITPRESOLVE
1237 * - \ref SCIP_STAGE_PRESOLVING
1238 * - \ref SCIP_STAGE_EXITPRESOLVE
1239 * - \ref SCIP_STAGE_PRESOLVED
1240 * - \ref SCIP_STAGE_INITSOLVE
1241 * - \ref SCIP_STAGE_SOLVING
1242 * - \ref SCIP_STAGE_SOLVED
1243 * - \ref SCIP_STAGE_EXITSOLVE
1244 * - \ref SCIP_STAGE_FREETRANS
1245 *
1246 * @note the pointer of the variable will be NULLed
1247 */
1249 SCIP* scip, /**< SCIP data structure */
1250 SCIP_VAR** var /**< pointer to variable */
1251 )
1252{
1253 assert(var != NULL);
1254 assert(*var != NULL);
1255 assert((*var)->scip == scip);
1256
1257 SCIP_CALL( SCIPcheckStage(scip, "SCIPreleaseVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1258
1259 switch( scip->set->stage )
1260 {
1261 case SCIP_STAGE_PROBLEM:
1262 SCIP_CALL( SCIPvarRelease(var, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp) );
1263 return SCIP_OKAY;
1264
1272 case SCIP_STAGE_SOLVING:
1273 case SCIP_STAGE_SOLVED:
1276 if( !SCIPvarIsTransformed(*var) && (*var)->nuses == 1 && (*var)->data.original.transvar != NULL )
1277 {
1278 SCIPerrorMessage("cannot release last use of original variable while associated transformed variable exists\n");
1279 return SCIP_INVALIDCALL;
1280 }
1281 SCIP_CALL( SCIPvarRelease(var, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp) );
1282 return SCIP_OKAY;
1283
1284 default:
1285 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
1286 return SCIP_INVALIDCALL;
1287 } /*lint !e788*/
1288}
1289
1290/** changes the name of a variable
1291 *
1292 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1293 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1294 *
1295 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PROBLEM
1296 *
1297 * @note to get the current name of a variable, use SCIPvarGetName() from pub_var.h
1298 */
1300 SCIP* scip, /**< SCIP data structure */
1301 SCIP_VAR* var, /**< variable */
1302 const char* name /**< new name of constraint */
1303 )
1304{
1306 assert( var->scip == scip );
1307
1309 {
1310 SCIPerrorMessage("variable names can only be changed in problem creation stage\n");
1311 SCIPABORT();
1312 return SCIP_INVALIDCALL; /*lint !e527*/
1313 }
1314
1315 /* remove variable's name from the namespace if the variable was already added */
1316 if( SCIPvarGetProbindex(var) != -1 )
1317 {
1318 SCIP_CALL( SCIPprobRemoveVarName(scip->origprob, var) );
1319 }
1320
1321 /* change variable name */
1322 SCIP_CALL( SCIPvarChgName(var, SCIPblkmem(scip), name) );
1323
1324 /* add variable's name to the namespace if the variable was already added */
1325 if( SCIPvarGetProbindex(var) != -1 )
1326 {
1327 SCIP_CALL( SCIPprobAddVarName(scip->origprob, var) );
1328 }
1329
1330 return SCIP_OKAY;
1331}
1332
1333/** gets and captures transformed variable of a given variable; if the variable is not yet transformed,
1334 * a new transformed variable for this variable is created
1335 *
1336 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1337 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1338 *
1339 * @pre This method can be called if @p scip is in one of the following stages:
1340 * - \ref SCIP_STAGE_TRANSFORMING
1341 * - \ref SCIP_STAGE_TRANSFORMED
1342 * - \ref SCIP_STAGE_INITPRESOLVE
1343 * - \ref SCIP_STAGE_PRESOLVING
1344 * - \ref SCIP_STAGE_EXITPRESOLVE
1345 * - \ref SCIP_STAGE_PRESOLVED
1346 * - \ref SCIP_STAGE_INITSOLVE
1347 * - \ref SCIP_STAGE_SOLVING
1348 */
1350 SCIP* scip, /**< SCIP data structure */
1351 SCIP_VAR* var, /**< variable to get/create transformed variable for */
1352 SCIP_VAR** transvar /**< pointer to store the transformed variable */
1353 )
1354{
1355 assert(transvar != NULL);
1356
1357 SCIP_CALL( SCIPcheckStage(scip, "SCIPtransformVar", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1358
1359 if( SCIPvarIsTransformed(var) )
1360 {
1361 *transvar = var;
1362 SCIPvarCapture(*transvar);
1363 }
1364 else
1365 {
1366 SCIP_CALL( SCIPvarTransform(var, scip->mem->probmem, scip->set, scip->stat, scip->origprob->objsense, transvar) );
1367 }
1368
1369 return SCIP_OKAY;
1370}
1371
1372/** gets and captures transformed variables for an array of variables;
1373 * if a variable of the array is not yet transformed, a new transformed variable for this variable is created;
1374 * it is possible to call this method with vars == transvars
1375 *
1376 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1377 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1378 *
1379 * @pre This method can be called if @p scip is in one of the following stages:
1380 * - \ref SCIP_STAGE_TRANSFORMING
1381 * - \ref SCIP_STAGE_TRANSFORMED
1382 * - \ref SCIP_STAGE_INITPRESOLVE
1383 * - \ref SCIP_STAGE_PRESOLVING
1384 * - \ref SCIP_STAGE_EXITPRESOLVE
1385 * - \ref SCIP_STAGE_PRESOLVED
1386 * - \ref SCIP_STAGE_INITSOLVE
1387 * - \ref SCIP_STAGE_SOLVING
1388 */
1390 SCIP* scip, /**< SCIP data structure */
1391 int nvars, /**< number of variables to get/create transformed variables for */
1392 SCIP_VAR** vars, /**< array with variables to get/create transformed variables for */
1393 SCIP_VAR** transvars /**< array to store the transformed variables */
1394 )
1395{
1396 int v;
1397
1398 assert(nvars == 0 || vars != NULL);
1399 assert(nvars == 0 || transvars != NULL);
1400
1401 SCIP_CALL( SCIPcheckStage(scip, "SCIPtransformVars", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1402
1403 for( v = 0; v < nvars; ++v )
1404 {
1405 if( SCIPvarIsTransformed(vars[v]) )
1406 {
1407 transvars[v] = vars[v];
1408 SCIPvarCapture(transvars[v]);
1409 }
1410 else
1411 {
1412 SCIP_CALL( SCIPvarTransform(vars[v], scip->mem->probmem, scip->set, scip->stat, scip->origprob->objsense,
1413 &transvars[v]) );
1414 }
1415 }
1416
1417 return SCIP_OKAY;
1418}
1419
1420/** gets corresponding transformed variable of a given variable;
1421 * returns NULL as transvar, if transformed variable is not yet existing
1422 *
1423 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1424 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1425 *
1426 * @pre This method can be called if @p scip is in one of the following stages:
1427 * - \ref SCIP_STAGE_TRANSFORMING
1428 * - \ref SCIP_STAGE_TRANSFORMED
1429 * - \ref SCIP_STAGE_INITPRESOLVE
1430 * - \ref SCIP_STAGE_PRESOLVING
1431 * - \ref SCIP_STAGE_EXITPRESOLVE
1432 * - \ref SCIP_STAGE_PRESOLVED
1433 * - \ref SCIP_STAGE_INITSOLVE
1434 * - \ref SCIP_STAGE_SOLVING
1435 * - \ref SCIP_STAGE_SOLVED
1436 * - \ref SCIP_STAGE_EXITSOLVE
1437 * - \ref SCIP_STAGE_FREETRANS
1438 */
1440 SCIP* scip, /**< SCIP data structure */
1441 SCIP_VAR* var, /**< variable to get transformed variable for */
1442 SCIP_VAR** transvar /**< pointer to store the transformed variable */
1443 )
1444{
1445 assert(transvar != NULL);
1446
1447 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetTransformedVar", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1448
1449 if( SCIPvarIsTransformed(var) )
1450 *transvar = var;
1451 else
1452 {
1453 SCIP_CALL( SCIPvarGetTransformed(var, scip->mem->probmem, scip->set, scip->stat, transvar) );
1454 }
1455
1456 return SCIP_OKAY;
1457}
1458
1459/** gets corresponding transformed variables for an array of variables;
1460 * stores NULL in a transvars slot, if the transformed variable is not yet existing;
1461 * it is possible to call this method with vars == transvars, but remember that variables that are not
1462 * yet transformed will be replaced with NULL
1463 *
1464 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1465 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1466 *
1467 * @pre This method can be called if @p scip is in one of the following stages:
1468 * - \ref SCIP_STAGE_TRANSFORMING
1469 * - \ref SCIP_STAGE_TRANSFORMED
1470 * - \ref SCIP_STAGE_INITPRESOLVE
1471 * - \ref SCIP_STAGE_PRESOLVING
1472 * - \ref SCIP_STAGE_EXITPRESOLVE
1473 * - \ref SCIP_STAGE_PRESOLVED
1474 * - \ref SCIP_STAGE_INITSOLVE
1475 * - \ref SCIP_STAGE_SOLVING
1476 * - \ref SCIP_STAGE_SOLVED
1477 * - \ref SCIP_STAGE_EXITSOLVE
1478 * - \ref SCIP_STAGE_FREETRANS
1479 */
1481 SCIP* scip, /**< SCIP data structure */
1482 int nvars, /**< number of variables to get transformed variables for */
1483 SCIP_VAR** vars, /**< array with variables to get transformed variables for */
1484 SCIP_VAR** transvars /**< array to store the transformed variables */
1485 )
1486{
1487 int v;
1488
1489 assert(nvars == 0 || vars != NULL);
1490 assert(nvars == 0 || transvars != NULL);
1491
1492 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetTransformedVars", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1493
1494 for( v = 0; v < nvars; ++v )
1495 {
1496 if( SCIPvarIsTransformed(vars[v]) )
1497 transvars[v] = vars[v];
1498 else
1499 {
1500 SCIP_CALL( SCIPvarGetTransformed(vars[v], scip->mem->probmem, scip->set, scip->stat, &transvars[v]) );
1501 }
1502 }
1503
1504 return SCIP_OKAY;
1505}
1506
1507/** gets negated variable x' = lb + ub - x of variable x; negated variable is created, if not yet existing;
1508 * in difference to \ref SCIPcreateVar, the negated variable must not be released (unless captured explicitly)
1509 *
1510 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1511 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1512 *
1513 * @pre This method can be called if @p scip is in one of the following stages:
1514 * - \ref SCIP_STAGE_PROBLEM
1515 * - \ref SCIP_STAGE_TRANSFORMING
1516 * - \ref SCIP_STAGE_TRANSFORMED
1517 * - \ref SCIP_STAGE_INITPRESOLVE
1518 * - \ref SCIP_STAGE_PRESOLVING
1519 * - \ref SCIP_STAGE_EXITPRESOLVE
1520 * - \ref SCIP_STAGE_PRESOLVED
1521 * - \ref SCIP_STAGE_INITSOLVE
1522 * - \ref SCIP_STAGE_SOLVING
1523 * - \ref SCIP_STAGE_SOLVED
1524 * - \ref SCIP_STAGE_EXITSOLVE
1525 * - \ref SCIP_STAGE_FREETRANS
1526 */
1528 SCIP* scip, /**< SCIP data structure */
1529 SCIP_VAR* var, /**< variable to get negated variable for */
1530 SCIP_VAR** negvar /**< pointer to store the negated variable */
1531 )
1532{
1533 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNegatedVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1534 assert( var->scip == scip );
1535
1536 SCIP_CALL( SCIPvarNegate(var, scip->mem->probmem, scip->set, scip->stat, negvar) );
1537
1538 return SCIP_OKAY;
1539}
1540
1541/** gets negated variables x' = lb + ub - x of variables x; negated variables are created, if not yet existing
1542 *
1543 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1544 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1545 *
1546 * @pre This method can be called if @p scip is in one of the following stages:
1547 * - \ref SCIP_STAGE_PROBLEM
1548 * - \ref SCIP_STAGE_TRANSFORMING
1549 * - \ref SCIP_STAGE_TRANSFORMED
1550 * - \ref SCIP_STAGE_INITPRESOLVE
1551 * - \ref SCIP_STAGE_PRESOLVING
1552 * - \ref SCIP_STAGE_EXITPRESOLVE
1553 * - \ref SCIP_STAGE_PRESOLVED
1554 * - \ref SCIP_STAGE_INITSOLVE
1555 * - \ref SCIP_STAGE_SOLVING
1556 * - \ref SCIP_STAGE_SOLVED
1557 * - \ref SCIP_STAGE_EXITSOLVE
1558 * - \ref SCIP_STAGE_FREETRANS
1559 */
1561 SCIP* scip, /**< SCIP data structure */
1562 int nvars, /**< number of variables to get negated variables for */
1563 SCIP_VAR** vars, /**< array of variables to get negated variables for */
1564 SCIP_VAR** negvars /**< array to store the negated variables */
1565 )
1566{
1567 int v;
1568
1569 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNegatedVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1570
1571 for( v = 0; v < nvars; ++v )
1572 {
1573 SCIP_CALL( SCIPvarNegate(vars[v], scip->mem->probmem, scip->set, scip->stat, &(negvars[v])) );
1574 }
1575
1576 return SCIP_OKAY;
1577}
1578
1579/** gets a binary variable that is equal to the given binary variable, and that is either active, fixed, or
1580 * multi-aggregated, or the negated variable of an active, fixed, or multi-aggregated variable
1581 *
1582 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1583 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1584 *
1585 * @pre This method can be called if @p scip is in one of the following stages:
1586 * - \ref SCIP_STAGE_PROBLEM
1587 * - \ref SCIP_STAGE_TRANSFORMED
1588 * - \ref SCIP_STAGE_INITPRESOLVE
1589 * - \ref SCIP_STAGE_PRESOLVING
1590 * - \ref SCIP_STAGE_EXITPRESOLVE
1591 * - \ref SCIP_STAGE_PRESOLVED
1592 * - \ref SCIP_STAGE_INITSOLVE
1593 * - \ref SCIP_STAGE_SOLVING
1594 * - \ref SCIP_STAGE_SOLVED
1595 * - \ref SCIP_STAGE_EXITSOLVE
1596 */
1598 SCIP* scip, /**< SCIP data structure */
1599 SCIP_VAR* var, /**< binary variable to get binary representative for */
1600 SCIP_VAR** repvar, /**< pointer to store the binary representative */
1601 SCIP_Bool* negated /**< pointer to store whether the negation of an active variable was returned */
1602 )
1603{
1604 assert(scip != NULL);
1605 assert(var != NULL);
1606 assert(repvar != NULL);
1607 assert(negated != NULL);
1608 assert(var->scip == scip);
1609
1610 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetBinvarRepresentative", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1611
1612 /* get the active representative of the given variable */
1613 *repvar = var;
1614 *negated = FALSE;
1615 SCIP_CALL( SCIPvarGetProbvarBinary(repvar, negated) );
1616
1617 /* negate the representative, if it corresponds to the negation of the given variable */
1618 if( *negated )
1619 {
1620 SCIP_CALL( SCIPgetNegatedVar(scip, *repvar, repvar) );
1621 }
1622
1623 return SCIP_OKAY;
1624}
1625
1626/** gets binary variables that are equal to the given binary variables, and which are either active, fixed, or
1627 * multi-aggregated, or the negated variables of active, fixed, or multi-aggregated variables
1628 *
1629 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1630 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1631 *
1632 * @pre This method can be called if @p scip is in one of the following stages:
1633 * - \ref SCIP_STAGE_PROBLEM
1634 * - \ref SCIP_STAGE_TRANSFORMED
1635 * - \ref SCIP_STAGE_INITPRESOLVE
1636 * - \ref SCIP_STAGE_PRESOLVING
1637 * - \ref SCIP_STAGE_EXITPRESOLVE
1638 * - \ref SCIP_STAGE_PRESOLVED
1639 * - \ref SCIP_STAGE_INITSOLVE
1640 * - \ref SCIP_STAGE_SOLVING
1641 * - \ref SCIP_STAGE_SOLVED
1642 * - \ref SCIP_STAGE_EXITSOLVE
1643 */
1645 SCIP* scip, /**< SCIP data structure */
1646 int nvars, /**< number of binary variables to get representatives for */
1647 SCIP_VAR** vars, /**< binary variables to get binary representatives for */
1648 SCIP_VAR** repvars, /**< array to store the binary representatives */
1649 SCIP_Bool* negated /**< array to store whether the negation of an active variable was returned */
1650 )
1651{
1652 int v;
1653
1654 assert(scip != NULL);
1655 assert(vars != NULL || nvars == 0);
1656 assert(repvars != NULL || nvars == 0);
1657 assert(negated != NULL || nvars == 0);
1658
1659 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetBinvarRepresentatives", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1660
1661 if( nvars == 0 )
1662 return SCIP_OKAY;
1663
1664 /* get the active representative of the given variable */
1665 BMScopyMemoryArray(repvars, vars, nvars);
1666 BMSclearMemoryArray(negated, nvars);
1667 SCIP_CALL( SCIPvarsGetProbvarBinary(&repvars, &negated, nvars) );
1668
1669 /* negate the representatives, if they correspond to the negation of the given variables */
1670 for( v = nvars - 1; v >= 0; --v )
1671 if( negated[v] )
1672 {
1673 SCIP_CALL( SCIPgetNegatedVar(scip, repvars[v], &(repvars[v])) );
1674 }
1675
1676 return SCIP_OKAY;
1677}
1678
1679/** flattens aggregation graph of multi-aggregated variable in order to avoid exponential recursion later on
1680 *
1681 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1682 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1683 *
1684 * @pre This method can be called if @p scip is in one of the following stages:
1685 * - \ref SCIP_STAGE_INITPRESOLVE
1686 * - \ref SCIP_STAGE_PRESOLVING
1687 * - \ref SCIP_STAGE_EXITPRESOLVE
1688 * - \ref SCIP_STAGE_PRESOLVED
1689 * - \ref SCIP_STAGE_INITSOLVE
1690 * - \ref SCIP_STAGE_SOLVING
1691 * - \ref SCIP_STAGE_SOLVED
1692 */
1694 SCIP* scip, /**< SCIP data structure */
1695 SCIP_VAR* var /**< problem variable */
1696 )
1697{
1698 assert( scip != NULL );
1699 assert( var != NULL );
1700 SCIP_CALL( SCIPcheckStage(scip, "SCIPflattenVarAggregationGraph", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
1701
1702 SCIP_CALL( SCIPvarFlattenAggregationGraph(var, scip->mem->probmem, scip->set, scip->eventqueue) );
1703
1704 return SCIP_OKAY;
1705}
1706
1707/** Transforms a given linear sum of variables, that is a_1*x_1 + ... + a_n*x_n + c into a corresponding linear sum of
1708 * active variables, that is b_1*y_1 + ... + b_m*y_m + d.
1709 *
1710 * If the number of needed active variables is greater than the available slots in the variable array, nothing happens
1711 * except that the required size is stored in the corresponding variable (requiredsize). Otherwise, the active variable
1712 * representation is stored in the variable array, scalar array and constant.
1713 *
1714 * The reason for this approach is that we cannot reallocate memory, since we do not know how the memory has been
1715 * allocated (e.g., by a C++ 'new' or SCIP functions).
1716 *
1717 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1718 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1719 *
1720 * @pre This method can be called if @p scip is in one of the following stages:
1721 * - \ref SCIP_STAGE_TRANSFORMED
1722 * - \ref SCIP_STAGE_INITPRESOLVE
1723 * - \ref SCIP_STAGE_PRESOLVING
1724 * - \ref SCIP_STAGE_EXITPRESOLVE
1725 * - \ref SCIP_STAGE_PRESOLVED
1726 * - \ref SCIP_STAGE_INITSOLVE
1727 * - \ref SCIP_STAGE_SOLVING
1728 * - \ref SCIP_STAGE_SOLVED
1729 * - \ref SCIP_STAGE_EXITSOLVE
1730 * - \ref SCIP_STAGE_FREETRANS
1731 *
1732 * @note The resulting linear sum is stored into the given variable array, scalar array, and constant. That means the
1733 * given entries are overwritten.
1734 *
1735 * @note That method can be used to convert a single variables into variable space of active variables. Therefore call
1736 * the method with the linear sum 1.0*x + 0.0.
1737 */
1739 SCIP* scip, /**< SCIP data structure */
1740 SCIP_VAR** vars, /**< variable array x_1, ..., x_n in the linear sum which will be
1741 * overwritten by the variable array y_1, ..., y_m in the linear sum
1742 * w.r.t. active variables */
1743 SCIP_Real* scalars, /**< scalars a_1, ..., a_n in linear sum which will be overwritten to the
1744 * scalars b_1, ..., b_m in the linear sum of the active variables */
1745 int* nvars, /**< pointer to number of variables in the linear sum which will be
1746 * overwritten by the number of variables in the linear sum corresponding
1747 * to the active variables */
1748 int varssize, /**< available slots in vars and scalars array which is needed to check if
1749 * the array are large enough for the linear sum w.r.t. active
1750 * variables */
1751 SCIP_Real* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c which
1752 * will chnage to constant d in the linear sum b_1*y_1 + ... + b_m*y_m +
1753 * d w.r.t. the active variables */
1754 int* requiredsize, /**< pointer to store the required array size for the linear sum w.r.t. the
1755 * active variables */
1756 SCIP_Bool mergemultiples /**< should multiple occurrences of a var be replaced by a single coeff? */
1757 )
1758{
1759 assert( scip != NULL );
1760 assert( nvars != NULL );
1761 assert( vars != NULL || *nvars == 0 );
1762 assert( scalars != NULL || *nvars == 0 );
1763 assert( constant != NULL );
1764 assert( requiredsize != NULL );
1765 assert( *nvars <= varssize );
1766
1767 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetProbvarLinearSum", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1768 SCIP_CALL( SCIPvarGetActiveRepresentatives(scip->set, vars, scalars, nvars, varssize, constant, requiredsize, mergemultiples) );
1769
1770 return SCIP_OKAY;
1771}
1772
1773/** transforms given variable, scalar and constant to the corresponding active, fixed, or
1774 * multi-aggregated variable, scalar and constant; if the variable resolves to a fixed variable,
1775 * "scalar" will be 0.0 and the value of the sum will be stored in "constant"; a multi-aggregation
1776 * with only one active variable (this can happen due to fixings after the multi-aggregation),
1777 * is treated like an aggregation; if the multi-aggregation constant is infinite, "scalar" will be 0.0
1778 *
1779 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1780 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1781 *
1782 * @pre This method can be called if @p scip is in one of the following stages:
1783 * - \ref SCIP_STAGE_TRANSFORMED
1784 * - \ref SCIP_STAGE_INITPRESOLVE
1785 * - \ref SCIP_STAGE_PRESOLVING
1786 * - \ref SCIP_STAGE_EXITPRESOLVE
1787 * - \ref SCIP_STAGE_PRESOLVED
1788 * - \ref SCIP_STAGE_INITSOLVE
1789 * - \ref SCIP_STAGE_SOLVING
1790 * - \ref SCIP_STAGE_SOLVED
1791 * - \ref SCIP_STAGE_EXITSOLVE
1792 * - \ref SCIP_STAGE_FREETRANS
1793 */
1795 SCIP* scip, /**< SCIP data structure */
1796 SCIP_VAR** var, /**< pointer to problem variable x in sum a*x + c */
1797 SCIP_Real* scalar, /**< pointer to scalar a in sum a*x + c */
1798 SCIP_Real* constant /**< pointer to constant c in sum a*x + c */
1799 )
1800{
1801 assert(scip != NULL);
1802 assert(var != NULL);
1803 assert(scalar != NULL);
1804 assert(constant != NULL);
1805
1806 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetProbvarSum", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1807 SCIP_CALL( SCIPvarGetProbvarSum(var, scip->set, scalar, constant) );
1808
1809 return SCIP_OKAY;
1810}
1811
1812/** return for given variables all their active counterparts; all active variables will be pairwise different
1813 * @note It does not hold that the first output variable is the active variable for the first input variable.
1814 *
1815 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1816 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1817 *
1818 * @pre This method can be called if @p scip is in one of the following stages:
1819 * - \ref SCIP_STAGE_TRANSFORMED
1820 * - \ref SCIP_STAGE_INITPRESOLVE
1821 * - \ref SCIP_STAGE_PRESOLVING
1822 * - \ref SCIP_STAGE_EXITPRESOLVE
1823 * - \ref SCIP_STAGE_PRESOLVED
1824 * - \ref SCIP_STAGE_INITSOLVE
1825 * - \ref SCIP_STAGE_SOLVING
1826 * - \ref SCIP_STAGE_SOLVED
1827 * - \ref SCIP_STAGE_EXITSOLVE
1828 * - \ref SCIP_STAGE_FREETRANS
1829 */
1831 SCIP* scip, /**< SCIP data structure */
1832 SCIP_VAR** vars, /**< variable array with given variables and as output all active
1833 * variables, if enough slots exist
1834 */
1835 int* nvars, /**< number of given variables, and as output number of active variables,
1836 * if enough slots exist
1837 */
1838 int varssize, /**< available slots in vars array */
1839 int* requiredsize /**< pointer to store the required array size for the active variables */
1840 )
1841{
1842 assert(scip != NULL);
1843 assert(nvars != NULL);
1844 assert(vars != NULL || *nvars == 0);
1845 assert(varssize >= *nvars);
1846 assert(requiredsize != NULL);
1847
1848 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetActiveVars", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1849 SCIP_CALL( SCIPvarsGetActiveVars(scip->set, vars, nvars, varssize, requiredsize) );
1850
1851 return SCIP_OKAY;
1852}
1853
1854/** returns the reduced costs of the variable in the current node's LP relaxation;
1855 * the current node has to have a feasible LP.
1856 *
1857 * returns SCIP_INVALID if the variable is active but not in the current LP;
1858 * returns 0 if the variable has been aggregated out or fixed in presolving.
1859 *
1860 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1861 *
1862 * @note The return value of this method should be used carefully if the dual feasibility check was explictely disabled.
1863 */
1865 SCIP* scip, /**< SCIP data structure */
1866 SCIP_VAR* var /**< variable to get reduced costs, should be a column in current node LP */
1867 )
1868{
1869 assert( scip != NULL );
1870 assert( var != NULL );
1871 assert( var->scip == scip );
1872
1873 switch( SCIPvarGetStatus(var) )
1874 {
1876 if( var->data.original.transvar == NULL )
1877 return SCIP_INVALID;
1879
1881 return SCIPgetColRedcost(scip, SCIPvarGetCol(var));
1882
1884 return SCIP_INVALID;
1885
1890 return 0.0;
1891
1892 default:
1893 SCIPerrorMessage("unknown variable status\n");
1894 SCIPABORT();
1895 return 0.0; /*lint !e527*/
1896 }
1897}
1898
1899/** returns the implied reduced costs of the variable in the current node's LP relaxation;
1900 * the current node has to have a feasible LP.
1901 *
1902 * returns SCIP_INVALID if the variable is active but not in the current LP;
1903 * returns 0 if the variable has been aggregated out or fixed in presolving.
1904 *
1905 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1906 *
1907 * @note The return value of this method should be used carefully if the dual feasibility check was explictely disabled.
1908 */
1910 SCIP* scip, /**< SCIP data structure */
1911 SCIP_VAR* var, /**< variable to get reduced costs, should be a column in current node LP */
1912 SCIP_Bool varfixing /**< FALSE if for x == 0, TRUE for x == 1 */
1913 )
1914{
1915 assert( scip != NULL );
1916 assert( var != NULL );
1917 assert( var->scip == scip );
1918
1919 switch( SCIPvarGetStatus(var) )
1920 {
1922 if( var->data.original.transvar == NULL )
1923 return SCIP_INVALID;
1924 return SCIPgetVarImplRedcost(scip, var->data.original.transvar, varfixing);
1925
1927 return SCIPvarGetImplRedcost(var, scip->set, varfixing, scip->stat, scip->transprob, scip->lp);
1928
1930 return SCIP_INVALID;
1931
1936 return 0.0;
1937
1938 default:
1939 SCIPerrorMessage("unknown variable status\n");
1940 SCIPABORT();
1941 return 0.0; /*lint !e527*/
1942 }
1943}
1944
1945
1946/** returns the Farkas coefficient of the variable in the current node's LP relaxation;
1947 * the current node has to have an infeasible LP.
1948 *
1949 * returns SCIP_INVALID if the variable is active but not in the current LP;
1950 * returns 0 if the variable has been aggregated out or fixed in presolving.
1951 *
1952 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1953 */
1955 SCIP* scip, /**< SCIP data structure */
1956 SCIP_VAR* var /**< variable to get reduced costs, should be a column in current node LP */
1957 )
1958{
1959 assert(scip != NULL);
1960 assert(var != NULL);
1961 assert(var->scip == scip);
1962
1963 switch( SCIPvarGetStatus(var) )
1964 {
1966 if( var->data.original.transvar == NULL )
1967 return SCIP_INVALID;
1969
1972
1974 return SCIP_INVALID;
1975
1980 return 0.0;
1981
1982 default:
1983 SCIPerrorMessage("unknown variable status\n");
1984 SCIPABORT();
1985 return 0.0; /*lint !e527*/
1986 }
1987}
1988
1989/** returns lower bound of variable directly before or after the bound change given by the bound change index
1990 * was applied
1991 */
1993 SCIP* scip, /**< SCIP data structure */
1994 SCIP_VAR* var, /**< problem variable */
1995 SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
1996 SCIP_Bool after /**< should the bound change with given index be included? */
1997 )
1998{
1999 SCIP_VARSTATUS varstatus;
2000 SCIP_BDCHGINFO* bdchginfo;
2001 assert(var != NULL);
2002
2003 varstatus = SCIPvarGetStatus(var);
2004
2005 /* get bounds of attached variables */
2006 switch( varstatus )
2007 {
2009 assert(var->data.original.transvar != NULL);
2010 return SCIPgetVarLbAtIndex(scip, var->data.original.transvar, bdchgidx, after);
2011
2014 if( bdchgidx == NULL )
2015 return SCIPvarGetLbLocal(var);
2016 else
2017 {
2018 bdchginfo = SCIPvarGetLbchgInfo(var, bdchgidx, after);
2019 if( bdchginfo != NULL )
2020 return SCIPbdchginfoGetNewbound(bdchginfo);
2021 else
2022 return var->glbdom.lb;
2023 }
2024
2026 return var->glbdom.lb;
2027
2028 case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c -> y = (x-c)/a */
2029 assert(var->data.aggregate.var != NULL);
2030 if( var->data.aggregate.scalar > 0.0 )
2031 {
2032 SCIP_Real lb;
2033
2034 lb = SCIPgetVarLbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2035
2036 /* a > 0 -> get lower bound of y */
2037 if( SCIPisInfinity(scip, -lb) )
2038 return -SCIPinfinity(scip);
2039 else if( SCIPisInfinity(scip, lb) )
2040 return SCIPinfinity(scip);
2041 else
2042 return var->data.aggregate.scalar * lb + var->data.aggregate.constant;
2043 }
2044 else if( var->data.aggregate.scalar < 0.0 )
2045 {
2046 SCIP_Real ub;
2047
2048 ub = SCIPgetVarUbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2049
2050 /* a < 0 -> get upper bound of y */
2051 if( SCIPisInfinity(scip, -ub) )
2052 return SCIPinfinity(scip);
2053 else if( SCIPisInfinity(scip, ub) )
2054 return -SCIPinfinity(scip);
2055 else
2056 return var->data.aggregate.scalar * ub + var->data.aggregate.constant;
2057 }
2058 else
2059 {
2060 SCIPerrorMessage("scalar is zero in aggregation\n");
2061 SCIPABORT();
2062 return SCIP_INVALID; /*lint !e527*/
2063 }
2064
2066 /* handle multi-aggregated variables depending on one variable only (possibly caused by SCIPvarFlattenAggregationGraph()) */
2067 if ( var->data.multaggr.nvars == 1 )
2068 {
2069 assert(var->data.multaggr.vars != NULL);
2070 assert(var->data.multaggr.scalars != NULL);
2071 assert(var->data.multaggr.vars[0] != NULL);
2072
2073 if( var->data.multaggr.scalars[0] > 0.0 )
2074 {
2075 SCIP_Real lb;
2076
2077 lb = SCIPgetVarLbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2078
2079 /* a > 0 -> get lower bound of y */
2080 if( SCIPisInfinity(scip, -lb) )
2081 return -SCIPinfinity(scip);
2082 else if( SCIPisInfinity(scip, lb) )
2083 return SCIPinfinity(scip);
2084 else
2085 return var->data.multaggr.scalars[0] * lb + var->data.multaggr.constant;
2086 }
2087 else if( var->data.multaggr.scalars[0] < 0.0 )
2088 {
2089 SCIP_Real ub;
2090
2091 ub = SCIPgetVarUbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2092
2093 /* a < 0 -> get upper bound of y */
2094 if( SCIPisInfinity(scip, -ub) )
2095 return SCIPinfinity(scip);
2096 else if( SCIPisInfinity(scip, ub) )
2097 return -SCIPinfinity(scip);
2098 else
2099 return var->data.multaggr.scalars[0] * ub + var->data.multaggr.constant;
2100 }
2101 else
2102 {
2103 SCIPerrorMessage("scalar is zero in multi-aggregation\n");
2104 SCIPABORT();
2105 return SCIP_INVALID; /*lint !e527*/
2106 }
2107 }
2108 SCIPerrorMessage("cannot get the bounds of a multi-aggregated variable.\n");
2109 SCIPABORT();
2110 return SCIP_INVALID; /*lint !e527*/
2111
2112 case SCIP_VARSTATUS_NEGATED: /* x' = offset - x -> x = offset - x' */
2113 assert(var->negatedvar != NULL);
2115 assert(var->negatedvar->negatedvar == var);
2116 return var->data.negate.constant - SCIPgetVarUbAtIndex(scip, var->negatedvar, bdchgidx, after);
2117
2118 default:
2119 SCIPerrorMessage("unknown variable status\n");
2120 SCIPABORT();
2121 return SCIP_INVALID; /*lint !e527*/
2122 }
2123}
2124
2125/** returns upper bound of variable directly before or after the bound change given by the bound change index
2126 * was applied
2127 */
2129 SCIP* scip, /**< SCIP data structure */
2130 SCIP_VAR* var, /**< problem variable */
2131 SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2132 SCIP_Bool after /**< should the bound change with given index be included? */
2133 )
2134{
2135 SCIP_VARSTATUS varstatus;
2136 SCIP_BDCHGINFO* bdchginfo;
2137 assert(var != NULL);
2138
2139 varstatus = SCIPvarGetStatus(var);
2140
2141 /* get bounds of attached variables */
2142 switch( varstatus )
2143 {
2145 assert(var->data.original.transvar != NULL);
2146 return SCIPgetVarUbAtIndex(scip, var->data.original.transvar, bdchgidx, after);
2147
2150 if( bdchgidx == NULL )
2151 return SCIPvarGetUbLocal(var);
2152 else
2153 {
2154 bdchginfo = SCIPvarGetUbchgInfo(var, bdchgidx, after);
2155 if( bdchginfo != NULL )
2156 return SCIPbdchginfoGetNewbound(bdchginfo);
2157 else
2158 return var->glbdom.ub;
2159 }
2160
2162 return var->glbdom.ub;
2163
2164 case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c -> y = (x-c)/a */
2165 assert(var->data.aggregate.var != NULL);
2166 if( var->data.aggregate.scalar > 0.0 )
2167 {
2168 SCIP_Real ub;
2169
2170 ub = SCIPgetVarUbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2171
2172 /* a > 0 -> get lower bound of y */
2173 if( SCIPisInfinity(scip, -ub) )
2174 return -SCIPinfinity(scip);
2175 else if( SCIPisInfinity(scip, ub) )
2176 return SCIPinfinity(scip);
2177 else
2178 return var->data.aggregate.scalar * ub + var->data.aggregate.constant;
2179 }
2180 else if( var->data.aggregate.scalar < 0.0 )
2181 {
2182 SCIP_Real lb;
2183
2184 lb = SCIPgetVarLbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2185
2186 /* a < 0 -> get upper bound of y */
2187 if ( SCIPisInfinity(scip, -lb) )
2188 return SCIPinfinity(scip);
2189 else if ( SCIPisInfinity(scip, lb) )
2190 return -SCIPinfinity(scip);
2191 else
2192 return var->data.aggregate.scalar * lb + var->data.aggregate.constant;
2193 }
2194 else
2195 {
2196 SCIPerrorMessage("scalar is zero in aggregation\n");
2197 SCIPABORT();
2198 return SCIP_INVALID; /*lint !e527*/
2199 }
2200
2202 /* handle multi-aggregated variables depending on one variable only (possibly caused by SCIPvarFlattenAggregationGraph()) */
2203 if ( var->data.multaggr.nvars == 1 )
2204 {
2205 assert(var->data.multaggr.vars != NULL);
2206 assert(var->data.multaggr.scalars != NULL);
2207 assert(var->data.multaggr.vars[0] != NULL);
2208
2209 if( var->data.multaggr.scalars[0] > 0.0 )
2210 {
2211 SCIP_Real ub;
2212
2213 ub = SCIPgetVarUbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2214
2215 /* a > 0 -> get lower bound of y */
2216 if ( SCIPisInfinity(scip, -ub) )
2217 return -SCIPinfinity(scip);
2218 else if ( SCIPisInfinity(scip, ub) )
2219 return SCIPinfinity(scip);
2220 else
2221 return var->data.multaggr.scalars[0] * ub + var->data.multaggr.constant;
2222 }
2223 else if( var->data.multaggr.scalars[0] < 0.0 )
2224 {
2225 SCIP_Real lb;
2226
2227 lb = SCIPgetVarLbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2228
2229 /* a < 0 -> get upper bound of y */
2230 if ( SCIPisInfinity(scip, -lb) )
2231 return SCIPinfinity(scip);
2232 else if ( SCIPisInfinity(scip, lb) )
2233 return -SCIPinfinity(scip);
2234 else
2235 return var->data.multaggr.scalars[0] * lb + var->data.multaggr.constant;
2236 }
2237 else
2238 {
2239 SCIPerrorMessage("scalar is zero in multi-aggregation\n");
2240 SCIPABORT();
2241 return SCIP_INVALID; /*lint !e527*/
2242 }
2243 }
2244 SCIPerrorMessage("cannot get the bounds of a multiple aggregated variable.\n");
2245 SCIPABORT();
2246 return SCIP_INVALID; /*lint !e527*/
2247
2248 case SCIP_VARSTATUS_NEGATED: /* x' = offset - x -> x = offset - x' */
2249 assert(var->negatedvar != NULL);
2251 assert(var->negatedvar->negatedvar == var);
2252 return var->data.negate.constant - SCIPgetVarLbAtIndex(scip, var->negatedvar, bdchgidx, after);
2253
2254 default:
2255 SCIPerrorMessage("unknown variable status\n");
2256 SCIPABORT();
2257 return SCIP_INVALID; /*lint !e527*/
2258 }
2259}
2260
2261/** returns lower or upper bound of variable directly before or after the bound change given by the bound change index
2262 * was applied
2263 */
2265 SCIP* scip, /**< SCIP data structure */
2266 SCIP_VAR* var, /**< problem variable */
2267 SCIP_BOUNDTYPE boundtype, /**< type of bound: lower or upper bound */
2268 SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2269 SCIP_Bool after /**< should the bound change with given index be included? */
2270 )
2271{
2272 if( boundtype == SCIP_BOUNDTYPE_LOWER )
2273 return SCIPgetVarLbAtIndex(scip, var, bdchgidx, after);
2274 else
2275 {
2276 assert(boundtype == SCIP_BOUNDTYPE_UPPER);
2277 return SCIPgetVarUbAtIndex(scip, var, bdchgidx, after);
2278 }
2279}
2280
2281/** returns whether the binary variable was fixed at the time given by the bound change index */
2283 SCIP* scip, /**< SCIP data structure */
2284 SCIP_VAR* var, /**< problem variable */
2285 SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2286 SCIP_Bool after /**< should the bound change with given index be included? */
2287 )
2288{
2289 assert(var != NULL);
2290 assert(SCIPvarIsBinary(var));
2291
2292 /* check the current bounds first in order to decide at which bound change information we have to look
2293 * (which is expensive because we have to follow the aggregation tree to the active variable)
2294 */
2295 return ((SCIPvarGetLbLocal(var) > 0.5 && SCIPgetVarLbAtIndex(scip, var, bdchgidx, after) > 0.5)
2296 || (SCIPvarGetUbLocal(var) < 0.5 && SCIPgetVarUbAtIndex(scip, var, bdchgidx, after) < 0.5));
2297}
2298
2299/** gets solution value for variable in current node
2300 *
2301 * @return solution value for variable in current node
2302 *
2303 * @pre This method can be called if @p scip is in one of the following stages:
2304 * - \ref SCIP_STAGE_PRESOLVED
2305 * - \ref SCIP_STAGE_SOLVING
2306 */
2308 SCIP* scip, /**< SCIP data structure */
2309 SCIP_VAR* var /**< variable to get solution value for */
2310 )
2311{
2313 assert( var->scip == scip );
2314
2315 return SCIPvarGetSol(var, SCIPtreeHasCurrentNodeLP(scip->tree));
2316}
2317
2318/** gets solution values of multiple variables in current node
2319 *
2320 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2321 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2322 *
2323 * @pre This method can be called if @p scip is in one of the following stages:
2324 * - \ref SCIP_STAGE_PRESOLVED
2325 * - \ref SCIP_STAGE_SOLVING
2326 */
2328 SCIP* scip, /**< SCIP data structure */
2329 int nvars, /**< number of variables to get solution value for */
2330 SCIP_VAR** vars, /**< array with variables to get value for */
2331 SCIP_Real* vals /**< array to store solution values of variables */
2332 )
2333{
2334 int v;
2335
2336 assert(nvars == 0 || vars != NULL);
2337 assert(nvars == 0 || vals != NULL);
2338
2340
2341 if( SCIPtreeHasCurrentNodeLP(scip->tree) )
2342 {
2343 for( v = 0; v < nvars; ++v )
2344 vals[v] = SCIPvarGetLPSol(vars[v]);
2345 }
2346 else
2347 {
2348 for( v = 0; v < nvars; ++v )
2349 vals[v] = SCIPvarGetPseudoSol(vars[v]);
2350 }
2351
2352 return SCIP_OKAY;
2353}
2354
2355/** sets the solution value of all variables in the global relaxation solution to zero
2356 *
2357 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2358 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2359 *
2360 * @pre This method can be called if @p scip is in one of the following stages:
2361 * - \ref SCIP_STAGE_PRESOLVED
2362 * - \ref SCIP_STAGE_SOLVING
2363 */
2365 SCIP* scip, /**< SCIP data structure */
2366 SCIP_RELAX* relax /**< relaxator data structure */
2367 )
2368{
2369 SCIP_VAR** vars;
2370 int nvars;
2371 int v;
2372
2373 assert(scip != NULL);
2374
2375 SCIP_CALL( SCIPcheckStage(scip, "SCIPclearRelaxSolVals", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2376
2377 /* update the responsible relax pointer */
2378 SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2379
2380 /* the relaxation solution is already cleared */
2381 if( SCIPrelaxationIsSolZero(scip->relaxation) )
2382 return SCIP_OKAY;
2383
2384 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
2385
2386 for( v = 0; v < nvars; v++ )
2387 {
2388 SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, 0.0, FALSE) );
2389 }
2390
2391 SCIPrelaxationSetSolObj(scip->relaxation, 0.0);
2392 SCIPrelaxationSetSolZero(scip->relaxation, TRUE);
2393
2394 return SCIP_OKAY;
2395}
2396
2397/** sets the value of the given variable in the global relaxation solution;
2398 * this solution can be filled by the relaxation handlers and can be used by heuristics and for separation;
2399 * You can use SCIPclearRelaxSolVals() to set all values to zero, initially;
2400 * after setting all solution values, you have to call SCIPmarkRelaxSolValid()
2401 * to inform SCIP that the stored solution is valid
2402 *
2403 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2404 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2405 *
2406 * @pre This method can be called if @p scip is in one of the following stages:
2407 * - \ref SCIP_STAGE_PRESOLVED
2408 * - \ref SCIP_STAGE_SOLVING
2409 *
2410 * @note This method incrementally updates the objective value of the relaxation solution. If the whole solution
2411 * should be updated, using SCIPsetRelaxSolVals() instead or calling SCIPclearRelaxSolVals() before setting
2412 * the first value to reset the solution and the objective value to 0 may help the numerics.
2413 */
2415 SCIP* scip, /**< SCIP data structure */
2416 SCIP_RELAX* relax, /**< relaxator data structure */
2417 SCIP_VAR* var, /**< variable to set value for */
2418 SCIP_Real val /**< solution value of variable */
2419 )
2420{
2421 assert(scip != NULL);
2422
2424
2425 SCIP_CALL( SCIPvarSetRelaxSol(var, scip->set, scip->relaxation, val, TRUE) );
2426
2427 if( val != 0.0 )
2428 SCIPrelaxationSetSolZero(scip->relaxation, FALSE);
2430 SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2431
2432 return SCIP_OKAY;
2433}
2434
2435/** sets the values of the given variables in the global relaxation solution and informs SCIP about the validity
2436 * and whether the solution can be enforced via linear cuts;
2437 * this solution can be filled by the relaxation handlers and can be used by heuristics and for separation;
2438 * the solution is automatically cleared, s.t. all other variables get value 0.0
2439 *
2440 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2441 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2442 *
2443 * @pre This method can be called if @p scip is in one of the following stages:
2444 * - \ref SCIP_STAGE_PRESOLVED
2445 * - \ref SCIP_STAGE_SOLVING
2446 */
2448 SCIP* scip, /**< SCIP data structure */
2449 SCIP_RELAX* relax, /**< relaxator data structure */
2450 int nvars, /**< number of variables to set relaxation solution value for */
2451 SCIP_VAR** vars, /**< array with variables to set value for */
2452 SCIP_Real* vals, /**< array with solution values of variables */
2453 SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2454 )
2455{
2456 int v;
2457
2458 assert(scip != NULL);
2459 assert(nvars == 0 || vars != NULL);
2460 assert(nvars == 0 || vals != NULL);
2461
2462 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolVals", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2463
2465
2466 for( v = 0; v < nvars; v++ )
2467 {
2468 SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, vals[v], TRUE) );
2469 }
2470
2471 SCIPrelaxationSetSolZero(scip->relaxation, FALSE);
2472 SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2473 SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2474
2475 return SCIP_OKAY;
2476}
2477
2478/** sets the values of the variables in the global relaxation solution to the values in the given primal solution
2479 * and informs SCIP about the validity and whether the solution can be enforced via linear cuts;
2480 * the relaxation solution can be filled by the relaxation handlers and might be used by heuristics and for separation
2481 *
2482 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2483 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2484 *
2485 * @pre This method can be called if @p scip is in one of the following stages:
2486 * - \ref SCIP_STAGE_PRESOLVED
2487 * - \ref SCIP_STAGE_SOLVING
2488 */
2490 SCIP* scip, /**< SCIP data structure */
2491 SCIP_RELAX* relax, /**< relaxator data structure */
2492 SCIP_SOL* sol, /**< primal relaxation solution */
2493 SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2494 )
2495{
2496 SCIP_VAR** vars;
2497 SCIP_Real* vals;
2498 int nvars;
2499 int v;
2500
2501 assert(scip != NULL);
2502
2503 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolValsSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2504
2505 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
2506
2507 /* alloc buffer array for solution values of the variables and get the values */
2508 SCIP_CALL( SCIPallocBufferArray(scip, &vals, nvars) );
2509 SCIP_CALL( SCIPgetSolVals(scip, sol, nvars, vars, vals) );
2510
2512
2513 for( v = 0; v < nvars; v++ )
2514 {
2515 SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, vals[v], FALSE) );
2516 }
2517
2518 SCIPrelaxationSetSolObj(scip->relaxation, SCIPsolGetObj(sol, scip->set, scip->transprob, scip->origprob));
2519
2520 SCIPrelaxationSetSolZero(scip->relaxation, FALSE);
2521 SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2522 SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2523
2524 SCIPfreeBufferArray(scip, &vals);
2525
2526 return SCIP_OKAY;
2527}
2528
2529/** returns whether the relaxation solution is valid
2530 *
2531 * @return TRUE, if the relaxation solution is valid; FALSE, otherwise
2532 *
2533 * @pre This method can be called if @p scip is in one of the following stages:
2534 * - \ref SCIP_STAGE_PRESOLVED
2535 * - \ref SCIP_STAGE_SOLVING
2536 */
2538 SCIP* scip /**< SCIP data structure */
2539 )
2540{
2541 assert(scip != NULL);
2542
2544
2545 return SCIPrelaxationIsSolValid(scip->relaxation);
2546}
2547
2548/** informs SCIP that the relaxation solution is valid and whether the relaxation can be enforced through linear cuts
2549 *
2550 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2551 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2552 *
2553 * @pre This method can be called if @p scip is in one of the following stages:
2554 * - \ref SCIP_STAGE_PRESOLVED
2555 * - \ref SCIP_STAGE_SOLVING
2556 */
2558 SCIP* scip, /**< SCIP data structure */
2559 SCIP_RELAX* relax, /**< relaxator data structure that set the current relaxation solution */
2560 SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2561 )
2562{
2563 assert(scip != NULL);
2564
2565 SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkRelaxSolValid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2566
2567 SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2568 SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2569
2570 return SCIP_OKAY;
2571}
2572
2573/** informs SCIP, that the relaxation solution is invalid
2574 *
2575 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2576 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2577 *
2578 * @pre This method can be called if @p scip is in one of the following stages:
2579 * - \ref SCIP_STAGE_PRESOLVED
2580 * - \ref SCIP_STAGE_SOLVING
2581 */
2583 SCIP* scip /**< SCIP data structure */
2584 )
2585{
2586 assert(scip != NULL);
2587
2588 SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkRelaxSolInvalid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2589
2591
2592 return SCIP_OKAY;
2593}
2594
2595/** gets the relaxation solution value of the given variable
2596 *
2597 * @return the relaxation solution value of the given variable
2598 *
2599 * @pre This method can be called if @p scip is in one of the following stages:
2600 * - \ref SCIP_STAGE_PRESOLVED
2601 * - \ref SCIP_STAGE_SOLVING
2602 */
2604 SCIP* scip, /**< SCIP data structure */
2605 SCIP_VAR* var /**< variable to get value for */
2606 )
2607{
2608 assert(scip != NULL);
2609 assert(var != NULL);
2610 assert(var->scip == scip);
2611
2613
2614 if( !SCIPrelaxationIsSolValid(scip->relaxation) )
2615 {
2616 SCIPerrorMessage("Relaxation Solution is not valid!\n");
2617 SCIPABORT();
2618 return SCIP_INVALID; /*lint !e527*/
2619 }
2620
2621 return SCIPvarGetRelaxSol(var, scip->set);
2622}
2623
2624/** gets the relaxation solution objective value
2625 *
2626 * @return the objective value of the relaxation solution
2627 *
2628 * @pre This method can be called if @p scip is in one of the following stages:
2629 * - \ref SCIP_STAGE_PRESOLVED
2630 * - \ref SCIP_STAGE_SOLVING
2631 */
2633 SCIP* scip /**< SCIP data structure */
2634 )
2635{
2636 assert(scip != NULL);
2637
2639
2640 if( !SCIPrelaxationIsSolValid(scip->relaxation) )
2641 {
2642 SCIPerrorMessage("Relaxation Solution is not valid!\n");
2643 SCIPABORT();
2644 return SCIP_INVALID; /*lint !e527*/
2645 }
2646
2647 return SCIPrelaxationGetSolObj(scip->relaxation);
2648}
2649
2650/** determine which branching direction should be evaluated first by strong branching
2651 *
2652 * @return TRUE iff strong branching should first evaluate the down child
2653 *
2654 */
2656 SCIP* scip, /**< SCIP data structure */
2657 SCIP_VAR* var /**< variable to determine the branching direction on */
2658 )
2659{
2660 switch( scip->set->branch_firstsbchild )
2661 {
2662 case 'u':
2663 return FALSE;
2664 case 'd':
2665 return TRUE;
2666 case 'a':
2667 return (SCIPvarGetNLocksDown(var) > SCIPvarGetNLocksUp(var));
2668 default:
2669 assert(scip->set->branch_firstsbchild == 'h');
2671 }
2672}
2673
2674/** start strong branching - call before any strong branching
2675 *
2676 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2677 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2678 *
2679 * @pre This method can be called if @p scip is in one of the following stages:
2680 * - \ref SCIP_STAGE_PRESOLVED
2681 * - \ref SCIP_STAGE_SOLVING
2682 *
2683 * @note if propagation is enabled, strong branching is not done directly on the LP, but probing nodes are created
2684 * which allow to perform propagation but also creates some overhead
2685 */
2687 SCIP* scip, /**< SCIP data structure */
2688 SCIP_Bool enablepropagation /**< should propagation be done before solving the strong branching LP? */
2689 )
2690{
2691 assert( scip != NULL );
2692 SCIP_CALL( SCIPcheckStage(scip, "SCIPstartStrongbranch", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2693
2694 assert(!SCIPinProbing(scip));
2695
2696 SCIPdebugMsg(scip, "starting strong branching mode%s: lpcount=%" SCIP_LONGINT_FORMAT "\n", enablepropagation ? " with propagation" : "", scip->stat->lpcount - scip->stat->nsbdivinglps);
2697
2698 /* start probing mode to allow propagation before solving the strong branching LPs; if no propagation should be done,
2699 * start the strong branching mode in the LP interface
2700 */
2701 if( enablepropagation )
2702 {
2703 if( SCIPtreeProbing(scip->tree) )
2704 {
2705 SCIPerrorMessage("cannot start strong branching with propagation while in probing mode\n");
2706 return SCIP_INVALIDCALL;
2707 }
2708
2709 if( scip->lp != NULL && SCIPlpDiving(scip->lp) )
2710 {
2711 SCIPerrorMessage("cannot start strong branching with propagation while in diving mode\n");
2712 return SCIP_INVALIDCALL;
2713 }
2714
2715 /* other then in SCIPstartProbing(), we do not disable collecting variable statistics during strong branching;
2716 * we cannot disable it, because the pseudo costs would not be updated, otherwise,
2717 * and reliability branching would end up doing strong branching all the time
2718 */
2719 SCIP_CALL( SCIPtreeStartProbing(scip->tree, scip->mem->probmem, scip->set, scip->lp, scip->relaxation, scip->transprob, TRUE) );
2720
2721 /* inform the LP that the current probing mode is used for strong branching */
2723 }
2724 else
2725 {
2727 }
2728
2729 /* reset local strong branching info */
2730 scip->stat->lastsblpsolstats[0] = scip->stat->lastsblpsolstats[1] = SCIP_LPSOLSTAT_NOTSOLVED;
2731
2732 return SCIP_OKAY;
2733}
2734
2735/** end strong branching - call after any strong branching
2736 *
2737 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2738 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2739 *
2740 * @pre This method can be called if @p scip is in one of the following stages:
2741 * - \ref SCIP_STAGE_PRESOLVED
2742 * - \ref SCIP_STAGE_SOLVING
2743 */
2745 SCIP* scip /**< SCIP data structure */
2746 )
2747{
2748 assert( scip != NULL );
2749
2750 SCIP_CALL( SCIPcheckStage(scip, "SCIPendStrongbranch", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2751
2752 /* depending on whether the strong branching mode was started with propagation enabled or not, we end the strong
2753 * branching probing mode or the LP strong branching mode
2754 */
2755 if( SCIPtreeProbing(scip->tree) )
2756 {
2757 SCIP_NODE* node;
2758 SCIP_DOMCHG* domchg;
2759 SCIP_VAR** boundchgvars;
2760 SCIP_Real* bounds;
2761 SCIP_BOUNDTYPE* boundtypes;
2762 int nboundchgs;
2763 int nbnds;
2764 int i;
2765
2766 /* collect all bound changes deducted during probing, which were applied at the probing root and apply them to the
2767 * focusnode
2768 */
2769 node = SCIPgetCurrentNode(scip);
2771 assert(SCIPgetProbingDepth(scip) == 0);
2772
2773 domchg = SCIPnodeGetDomchg(node);
2774 nboundchgs = SCIPdomchgGetNBoundchgs(domchg);
2775
2776 SCIP_CALL( SCIPallocBufferArray(scip, &boundchgvars, nboundchgs) );
2777 SCIP_CALL( SCIPallocBufferArray(scip, &bounds, nboundchgs) );
2778 SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, nboundchgs) );
2779
2780 for( i = 0, nbnds = 0; i < nboundchgs; ++i )
2781 {
2782 SCIP_BOUNDCHG* boundchg;
2783
2784 boundchg = SCIPdomchgGetBoundchg(domchg, i);
2785
2786 /* ignore redundant bound changes */
2787 if( SCIPboundchgIsRedundant(boundchg) )
2788 continue;
2789
2790 boundchgvars[nbnds] = SCIPboundchgGetVar(boundchg);
2791 bounds[nbnds] = SCIPboundchgGetNewbound(boundchg);
2792 boundtypes[nbnds] = SCIPboundchgGetBoundtype(boundchg);
2793 ++nbnds;
2794 }
2795
2796 SCIPdebugMsg(scip, "ending strong branching with probing: %d bound changes collected\n", nbnds);
2797
2798 /* inform the LP that the probing mode is not used for strong branching anymore */
2800
2801 /* switch back from probing to normal operation mode and restore variables and constraints to focus node */
2802 SCIP_CALL( SCIPtreeEndProbing(scip->tree, scip->reopt, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
2803 scip->transprob, scip->origprob, scip->lp, scip->relaxation, scip->primal,
2804 scip->branchcand, scip->eventqueue, scip->eventfilter, scip->cliquetable) );
2805
2806 /* apply the collected bound changes */
2807 for( i = 0; i < nbnds; ++i )
2808 {
2809 if( boundtypes[i] == SCIP_BOUNDTYPE_LOWER )
2810 {
2811 SCIPdebugMsg(scip, "apply probing lower bound change <%s> >= %.9g\n", SCIPvarGetName(boundchgvars[i]), bounds[i]);
2812 SCIP_CALL( SCIPchgVarLb(scip, boundchgvars[i], bounds[i]) );
2813 }
2814 else
2815 {
2816 SCIPdebugMsg(scip, "apply probing upper bound change <%s> <= %.9g\n", SCIPvarGetName(boundchgvars[i]), bounds[i]);
2817 SCIP_CALL( SCIPchgVarUb(scip, boundchgvars[i], bounds[i]) );
2818 }
2819 }
2820
2821 SCIPfreeBufferArray(scip, &boundtypes);
2822 SCIPfreeBufferArray(scip, &bounds);
2823 SCIPfreeBufferArray(scip, &boundchgvars);
2824 }
2825 else
2826 {
2827 SCIPdebugMsg(scip, "ending strong branching\n");
2828
2830 }
2831
2832 return SCIP_OKAY;
2833}
2834
2835/** analyze the strong branching for the given variable; that includes conflict analysis for infeasible branches and
2836 * storing of root reduced cost information
2837 */
2838static
2840 SCIP* scip, /**< SCIP data structure */
2841 SCIP_VAR* var, /**< variable to analyze */
2842 SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
2843 SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
2844 SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
2845 * infeasible downwards branch, or NULL */
2846 SCIP_Bool* upconflict /**< pointer to store whether a conflict constraint was created for an
2847 * infeasible upwards branch, or NULL */
2848 )
2849{
2850 SCIP_COL* col;
2851 SCIP_Bool downcutoff;
2852 SCIP_Bool upcutoff;
2853
2854 col = SCIPvarGetCol(var);
2855 assert(col != NULL);
2856
2857 downcutoff = col->sbdownvalid && SCIPsetIsGE(scip->set, col->sbdown, scip->lp->cutoffbound);
2858 upcutoff = col->sbupvalid && SCIPsetIsGE(scip->set, col->sbup, scip->lp->cutoffbound);
2859
2860 if( downinf != NULL )
2861 *downinf = downcutoff;
2862 if( upinf != NULL )
2863 *upinf = upcutoff;
2864
2865 /* analyze infeasible strong branching sub problems:
2866 * because the strong branching's bound change is necessary for infeasibility, it cannot be undone;
2867 * therefore, infeasible strong branchings on non-binary variables will not produce a valid conflict constraint
2868 */
2869 if( scip->set->conf_enable && scip->set->conf_usesb && scip->set->nconflicthdlrs > 0
2870 && SCIPvarIsBinary(var) && SCIPtreeGetCurrentDepth(scip->tree) > 0 )
2871 {
2872 if( (downcutoff && SCIPsetFeasCeil(scip->set, col->primsol-1.0) >= col->lb - 0.5)
2873 || (upcutoff && SCIPsetFeasFloor(scip->set, col->primsol+1.0) <= col->ub + 0.5) )
2874 {
2875 assert(downconflict != NULL);
2876 assert(upconflict != NULL);
2877 SCIP_CALL( SCIPconflictAnalyzeStrongbranch(scip->conflict, scip->conflictstore, scip->mem->probmem, scip->set, scip->stat,
2878 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, col, downconflict, upconflict) );
2879 }
2880 }
2881
2882 /* the strong branching results can be used to strengthen the root reduced cost information which is used for example
2883 * to propagate against the cutoff bound
2884 *
2885 * @note Ignore the results if the LP solution of the down (up) branch LP is smaller which should not happened by
2886 * theory but can arise due to numerical issues.
2887 */
2888 if( SCIPtreeGetCurrentDepth(scip->tree) == 0 && SCIPvarIsBinary(var) && SCIPlpIsDualReliable(scip->lp) )
2889 {
2890 SCIP_Real lpobjval;
2891
2893
2894 lpobjval = SCIPlpGetObjval(scip->lp, scip->set, scip->transprob);
2895
2896 if( col->sbdownvalid && SCIPsetFeasCeil(scip->set, col->primsol-1.0) >= col->lb - 0.5 && lpobjval < col->sbdown )
2897 SCIPvarUpdateBestRootSol(var, scip->set, SCIPvarGetUbGlobal(var), -(col->sbdown - lpobjval), lpobjval);
2898 if( col->sbupvalid && SCIPsetFeasFloor(scip->set, col->primsol+1.0) <= col->ub + 0.5 && lpobjval < col->sbup )
2899 SCIPvarUpdateBestRootSol(var, scip->set, SCIPvarGetLbGlobal(var), col->sbup - lpobjval, lpobjval);
2900 }
2901
2902 return SCIP_OKAY;
2903}
2904
2905/** gets strong branching information on column variable with fractional value
2906 *
2907 * Before calling this method, the strong branching mode must have been activated by calling SCIPstartStrongbranch();
2908 * after strong branching was done for all candidate variables, the strong branching mode must be ended by
2909 * SCIPendStrongbranch(). Since this method does not apply domain propagation before strongbranching,
2910 * propagation should not be enabled in the SCIPstartStrongbranch() call.
2911 *
2912 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2913 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2914 *
2915 * @pre This method can be called if @p scip is in one of the following stages:
2916 * - \ref SCIP_STAGE_PRESOLVED
2917 * - \ref SCIP_STAGE_SOLVING
2918 */
2920 SCIP* scip, /**< SCIP data structure */
2921 SCIP_VAR* var, /**< variable to get strong branching values for */
2922 int itlim, /**< iteration limit for strong branchings */
2923 SCIP_Bool idempotent, /**< should scip's state remain the same after the call (statistics, column states...), or should it be updated ? */
2924 SCIP_Real* down, /**< stores dual bound after branching column down */
2925 SCIP_Real* up, /**< stores dual bound after branching column up */
2926 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
2927 * otherwise, it can only be used as an estimate value */
2928 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
2929 * otherwise, it can only be used as an estimate value */
2930 SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
2931 SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
2932 SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
2933 * infeasible downwards branch, or NULL */
2934 SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
2935 * infeasible upwards branch, or NULL */
2936 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
2937 * solving process should be stopped (e.g., due to a time limit) */
2938 )
2939{
2940 SCIP_COL* col;
2941 SCIP_Real lpobjval;
2942 SCIP_Real localdown;
2943 SCIP_Real localup;
2944 SCIP_Bool localdownvalid;
2945 SCIP_Bool localupvalid;
2946
2947 assert(var != NULL);
2948 assert(lperror != NULL);
2949 assert(!SCIPinProbing(scip)); /* we should not be in strong branching with propagation mode */
2950 assert(var->scip == scip);
2951
2952 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchFrac", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2953
2954 lpobjval = SCIPgetLPObjval(scip);
2955 if( downvalid != NULL )
2956 *downvalid = FALSE;
2957 if( upvalid != NULL )
2958 *upvalid = FALSE;
2959 if( downinf != NULL )
2960 *downinf = FALSE;
2961 if( upinf != NULL )
2962 *upinf = FALSE;
2963 if( downconflict != NULL )
2964 *downconflict = FALSE;
2965 if( upconflict != NULL )
2966 *upconflict = FALSE;
2967
2969 {
2970 SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
2971 return SCIP_INVALIDDATA;
2972 }
2973
2974 col = SCIPvarGetCol(var);
2975 assert(col != NULL);
2976
2977 if( !SCIPcolIsInLP(col) )
2978 {
2979 SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
2980 return SCIP_INVALIDDATA;
2981 }
2982
2983 /* check if the solving process should be aborted */
2984 if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
2985 {
2986 /* mark this as if the LP failed */
2987 *lperror = TRUE;
2988 return SCIP_OKAY;
2989 }
2990
2991 /* call strong branching for column with fractional value */
2992 SCIP_CALL( SCIPcolGetStrongbranch(col, FALSE, scip->set, scip->stat, scip->transprob, scip->lp, itlim, !idempotent, !idempotent,
2993 &localdown, &localup, &localdownvalid, &localupvalid, lperror) );
2994
2995 /* update lower bound by the higher pseudo objective value */
2996 if( !SCIPisZero(scip, SCIPvarGetObj(var)) )
2997 {
2998 SCIP_Real oldbound;
2999 SCIP_Real newbound;
3000 SCIP_Real pseudoobjval;
3001 SCIP_BOUNDTYPE boundtype = SCIPvarGetBestBoundType(var);
3002
3003 if( boundtype == SCIP_BOUNDTYPE_UPPER )
3004 {
3005 oldbound = SCIPvarGetUbLocal(var);
3006 newbound = SCIPfeasFloor(scip, SCIPvarGetLPSol(var));
3007 }
3008 else
3009 {
3010 oldbound = SCIPvarGetLbLocal(var);
3011 newbound = SCIPfeasCeil(scip, SCIPvarGetLPSol(var));
3012 }
3013
3014 if( scip->set->misc_exactsolve )
3015 pseudoobjval = SCIPlpGetModifiedProvedPseudoObjval(scip->lp, scip->set, var, oldbound, newbound, boundtype);
3016 else
3017 pseudoobjval = SCIPlpGetModifiedPseudoObjval(scip->lp, scip->set, scip->transprob, var, oldbound, newbound, boundtype);
3018
3019 if( pseudoobjval > lpobjval )
3020 {
3021 if( boundtype == SCIP_BOUNDTYPE_UPPER )
3022 {
3023 if( !localdownvalid || localdown < pseudoobjval )
3024 {
3025 localdown = pseudoobjval;
3026 localdownvalid = TRUE;
3027 }
3028 }
3029 else
3030 {
3031 if( !localupvalid || localup < pseudoobjval )
3032 {
3033 localup = pseudoobjval;
3034 localupvalid = TRUE;
3035 }
3036 }
3037 }
3038 }
3039
3040 /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3041 * declare the sub nodes infeasible
3042 */
3043 if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3044 {
3045 if( !idempotent ) /*lint !e774*/
3046 {
3047 SCIP_CALL( analyzeStrongbranch(scip, var, NULL, NULL, downconflict, upconflict) );
3048 }
3049
3050 if( downinf != NULL )
3051 *downinf = localdownvalid && SCIPsetIsGE(scip->set, localdown, scip->lp->cutoffbound);
3052 if( upinf != NULL )
3053 *upinf = localupvalid && SCIPsetIsGE(scip->set, localup, scip->lp->cutoffbound);
3054 }
3055
3056 if( down != NULL )
3057 *down = localdown;
3058 if( up != NULL )
3059 *up = localup;
3060 if( downvalid != NULL )
3061 *downvalid = localdownvalid;
3062 if( upvalid != NULL )
3063 *upvalid = localupvalid;
3064
3065 return SCIP_OKAY;
3066}
3067
3068/** create, solve, and evaluate a single strong branching child (for strong branching with propagation) */
3069static
3071 SCIP* scip, /**< SCIP data structure */
3072 SCIP_VAR* var, /**< variable to get strong branching values for */
3073 SCIP_Bool down, /**< do we regard the down child? */
3074 SCIP_Bool firstchild, /**< is this the first of the two strong branching children? */
3075 SCIP_Bool propagate, /**< should domain propagation be performed? */
3076 SCIP_Real newbound, /**< new bound to apply at the strong branching child */
3077 int itlim, /**< iteration limit for strong branchings */
3078 int maxproprounds, /**< maximum number of propagation rounds (-1: no limit, -2: parameter
3079 * settings) */
3080 SCIP_Real* value, /**< stores dual bound for strong branching child */
3081 SCIP_Bool* valid, /**< stores whether the returned value is a valid dual bound, or NULL;
3082 * otherwise, it can only be used as an estimate value */
3083 SCIP_Longint* ndomreductions, /**< pointer to store the number of domain reductions found, or NULL */
3084 SCIP_Bool* conflict, /**< pointer to store whether a conflict constraint was created for an
3085 * infeasible strong branching child, or NULL */
3086 SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred or the
3087 * solving process should be stopped (e.g., due to a time limit) */
3088 SCIP_VAR** vars, /**< active problem variables */
3089 int nvars, /**< number of active problem variables */
3090 SCIP_Real* newlbs, /**< array to store valid lower bounds for all active variables, or NULL */
3091 SCIP_Real* newubs, /**< array to store valid upper bounds for all active variables, or NULL */
3092 SCIP_Bool* foundsol, /**< pointer to store whether a primal solution was found during strong branching */
3093 SCIP_Bool* cutoff /**< pointer to store whether the strong branching child is infeasible */
3094 )
3095{
3096 SCIP_Longint ndomreds;
3097
3098 assert(value != NULL);
3099 assert(foundsol != NULL);
3100 assert(cutoff != NULL);
3101 assert(lperror != NULL);
3102 assert(valid != NULL ? !(*valid) : TRUE);
3103
3104 *foundsol = FALSE;
3105 *cutoff = FALSE;
3106 *lperror = FALSE;
3107
3108 /* check whether the strong branching child is already infeasible due to the bound change */
3109 if( down )
3110 {
3111 /* the down branch is infeasible due to the branching bound change; since this means that solval is not within the
3112 * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3113 * are valid for and were already applied at the probing root
3114 */
3115 if( newbound < SCIPvarGetLbLocal(var) - 0.5 )
3116 {
3117 *value = SCIPinfinity(scip);
3118
3119 if( valid != NULL )
3120 *valid = TRUE;
3121
3122 /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3123 if( conflict != NULL )
3124 *conflict = TRUE;
3125
3126 *cutoff = TRUE;
3127
3128 return SCIP_OKAY;
3129 }
3130 }
3131 else
3132 {
3133 /* the up branch is infeasible due to the branching bound change; since this means that solval is not within the
3134 * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3135 * are valid for and were already applied at the probing root
3136 */
3137 if( newbound > SCIPvarGetUbLocal(var) + 0.5 )
3138 {
3139 *value = SCIPinfinity(scip);
3140
3141 if( valid != NULL )
3142 *valid = TRUE;
3143
3144 /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3145 if( conflict != NULL )
3146 *conflict = TRUE;
3147
3148 *cutoff = TRUE;
3149
3150 return SCIP_OKAY;
3151 }
3152 }
3153
3154 /* we need to ensure that we can create at least one new probing node without exceeding the maximal tree depth */
3156 {
3157 /* create a new probing node for the strong branching child and apply the new bound for the variable */
3159
3160 if( down )
3161 {
3162 assert(SCIPisGE(scip, newbound, SCIPvarGetLbLocal(var)));
3163 if( SCIPisLT(scip, newbound, SCIPvarGetUbLocal(var)) )
3164 {
3165 SCIP_CALL( SCIPchgVarUbProbing(scip, var, newbound) );
3166 }
3167 }
3168 else
3169 {
3170 assert(SCIPisLE(scip, newbound, SCIPvarGetUbLocal(var)));
3171 if( SCIPisGT(scip, newbound, SCIPvarGetLbLocal(var)) )
3172 {
3173 SCIP_CALL( SCIPchgVarLbProbing(scip, var, newbound) );
3174 }
3175 }
3176 }
3177 else
3178 {
3179 if( valid != NULL )
3180 *valid = FALSE;
3181
3182 *cutoff = FALSE;
3183
3184 if( conflict != NULL )
3185 *conflict = FALSE;
3186
3187 return SCIP_OKAY;
3188 }
3189
3190 /* propagate domains at the probing node */
3191 if( propagate )
3192 {
3193 /* start time measuring */
3194 SCIPclockStart(scip->stat->strongpropclock, scip->set);
3195
3196 ndomreds = 0;
3197 SCIP_CALL( SCIPpropagateProbing(scip, maxproprounds, cutoff, &ndomreds) );
3198
3199 /* store number of domain reductions in strong branching */
3200 if( down )
3201 SCIPstatAdd(scip->stat, scip->set, nsbdowndomchgs, ndomreds);
3202 else
3203 SCIPstatAdd(scip->stat, scip->set, nsbupdomchgs, ndomreds);
3204
3205 if( ndomreductions != NULL )
3206 *ndomreductions = ndomreds;
3207
3208 /* stop time measuring */
3209 SCIPclockStop(scip->stat->strongpropclock, scip->set);
3210
3211 if( *cutoff )
3212 {
3213 *value = SCIPinfinity(scip);
3214
3215 if( valid != NULL )
3216 *valid = TRUE;
3217
3218 SCIPdebugMsg(scip, "%s branch of var <%s> detected infeasible during propagation\n",
3219 down ? "down" : "up", SCIPvarGetName(var));
3220 }
3221 }
3222
3223 /* if propagation did not already detect infeasibility, solve the probing LP */
3224 if( !(*cutoff) )
3225 {
3226 SCIP_CALL( SCIPsolveProbingLP(scip, itlim, lperror, cutoff) );
3227 assert(SCIPisLPRelax(scip));
3228
3229 if( *cutoff )
3230 {
3231 assert(!(*lperror));
3232
3233 *value = SCIPinfinity(scip);
3234
3235 if( valid != NULL )
3236 *valid = TRUE;
3237
3238 SCIPdebugMsg(scip, "%s branch of var <%s> detected infeasible in LP solving: status=%d\n",
3239 down ? "down" : "up", SCIPvarGetName(var), SCIPgetLPSolstat(scip));
3240 }
3241 else if( !(*lperror) )
3242 {
3243 /* save the lp solution status */
3244 scip->stat->lastsblpsolstats[down ? 0 : 1] = SCIPgetLPSolstat(scip);
3245
3246 switch( SCIPgetLPSolstat(scip) )
3247 {
3249 {
3250 *value = SCIPgetLPObjval(scip);
3251 assert(SCIPisLT(scip, *value, SCIPgetCutoffbound(scip)));
3252
3253 SCIPdebugMsg(scip, "probing LP solved to optimality, objective value: %16.9g\n", *value);
3254
3255 if( valid != NULL )
3256 *valid = TRUE;
3257
3258 /* check the strong branching LP solution for feasibility */
3259 SCIP_CALL( SCIPtryStrongbranchLPSol(scip, foundsol, cutoff) );
3260 break;
3261 }
3263 ++scip->stat->nsbtimesiterlimhit;
3264 /*lint -fallthrough*/
3266 {
3267 /* use LP value as estimate */
3268 SCIP_LPI* lpi;
3269 SCIP_Real objval;
3270 SCIP_Real looseobjval;
3271
3272 SCIPdebugMsg(scip, "probing LP hit %s limit\n", SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_ITERLIMIT ? "iteration" : "time");
3273
3274 /* we access the LPI directly, because when a time limit was hit, we cannot access objective value and dual
3275 * feasibility using the SCIPlp... methods; we should try to avoid direct calls to the LPI, but this is rather
3276 * uncritical here, because we are immediately after the SCIPsolveProbingLP() call, because we access the LPI
3277 * read-only, and we check SCIPlpiWasSolved() first
3278 */
3279 SCIP_CALL( SCIPgetLPI(scip, &lpi) );
3280
3281 if( SCIPlpiWasSolved(lpi) )
3282 {
3283 SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
3284 looseobjval = SCIPlpGetLooseObjval(scip->lp, scip->set, scip->transprob);
3285
3286 /* the infinity value in the LPI should not be smaller than SCIP's infinity value */
3287 assert(!SCIPlpiIsInfinity(lpi, objval) || SCIPisInfinity(scip, objval));
3288
3289 /* we use SCIP's infinity value here because a value larger than this is counted as infeasible by SCIP */
3290 if( SCIPisInfinity(scip, objval) )
3291 *value = SCIPinfinity(scip);
3292 else if( SCIPisInfinity(scip, -looseobjval) )
3293 *value = -SCIPinfinity(scip);
3294 else
3295 *value = objval + looseobjval;
3296
3297 if( SCIPlpiIsDualFeasible(lpi) )
3298 {
3299 if( valid != NULL )
3300 *valid = TRUE;
3301
3302 if( SCIPisGE(scip, *value, SCIPgetCutoffbound(scip)) )
3303 *cutoff = TRUE;
3304 }
3305 }
3306 break;
3307 }
3310 *lperror = TRUE;
3311 break;
3312 case SCIP_LPSOLSTAT_NOTSOLVED: /* should only be the case for *cutoff = TRUE or *lperror = TRUE */
3313 case SCIP_LPSOLSTAT_OBJLIMIT: /* in this case, *cutoff should be TRUE and we should not get here */
3314 case SCIP_LPSOLSTAT_INFEASIBLE: /* in this case, *cutoff should be TRUE and we should not get here */
3315 default:
3316 SCIPerrorMessage("invalid LP solution status <%d>\n", SCIPgetLPSolstat(scip));
3317 return SCIP_INVALIDDATA;
3318 } /*lint !e788*/
3319 }
3320
3321 /* If columns are missing in the LP, the cutoff flag may be wrong. Therefore, we need to set it and the valid pointer
3322 * to false here.
3323 */
3324 if( (*cutoff) && !SCIPallColsInLP(scip) )
3325 {
3326 *cutoff = FALSE;
3327 }
3328
3329#ifndef NDEBUG
3330 if( *lperror )
3331 {
3332 SCIPdebugMsg(scip, "error during strong branching probing LP solving: status=%d\n", SCIPgetLPSolstat(scip));
3333 }
3334#endif
3335 }
3336
3337 /* if the subproblem was feasible, we store the local bounds of the variables after propagation and (possibly)
3338 * conflict analysis
3339 * @todo do this after propagation? should be able to get valid bounds more often, but they might be weaker
3340 */
3341 if( !(*cutoff) && newlbs != NULL)
3342 {
3343 int v;
3344
3345 assert(newubs != NULL);
3346
3347 /* initialize the newlbs and newubs to the current local bounds */
3348 if( firstchild )
3349 {
3350 for( v = 0; v < nvars; ++v )
3351 {
3352 newlbs[v] = SCIPvarGetLbLocal(vars[v]);
3353 newubs[v] = SCIPvarGetUbLocal(vars[v]);
3354 }
3355 }
3356 /* update newlbs and newubs: take the weaker of the already stored bounds and the current local bounds */
3357 else
3358 {
3359 for( v = 0; v < nvars; ++v )
3360 {
3361 SCIP_Real lb = SCIPvarGetLbLocal(vars[v]);
3362 SCIP_Real ub = SCIPvarGetUbLocal(vars[v]);
3363
3364 newlbs[v] = MIN(newlbs[v], lb);
3365 newubs[v] = MAX(newubs[v], ub);
3366 }
3367 }
3368 }
3369
3370 /* revert all changes at the probing node */
3372
3373 return SCIP_OKAY;
3374}
3375
3376/** gets strong branching information with previous domain propagation on column variable
3377 *
3378 * Before calling this method, the strong branching mode must have been activated by calling SCIPstartStrongbranch();
3379 * after strong branching was done for all candidate variables, the strong branching mode must be ended by
3380 * SCIPendStrongbranch(). Since this method applies domain propagation before strongbranching, propagation has to be be
3381 * enabled in the SCIPstartStrongbranch() call.
3382 *
3383 * Before solving the strong branching LP, domain propagation can be performed. The number of propagation rounds
3384 * can be specified by the parameter @p maxproprounds.
3385 *
3386 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3387 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3388 *
3389 * @pre This method can be called if @p scip is in one of the following stages:
3390 * - \ref SCIP_STAGE_PRESOLVED
3391 * - \ref SCIP_STAGE_SOLVING
3392 *
3393 * @warning When using this method, LP banching candidates and solution values must be copied beforehand, because
3394 * they are updated w.r.t. the strong branching LP solution.
3395 */
3397 SCIP* scip, /**< SCIP data structure */
3398 SCIP_VAR* var, /**< variable to get strong branching values for */
3399 SCIP_Real solval, /**< value of the variable in the current LP solution */
3400 SCIP_Real lpobjval, /**< LP objective value of the current LP solution */
3401 int itlim, /**< iteration limit for strong branchings */
3402 int maxproprounds, /**< maximum number of propagation rounds (-1: no limit, -2: parameter
3403 * settings) */
3404 SCIP_Real* down, /**< stores dual bound after branching column down */
3405 SCIP_Real* up, /**< stores dual bound after branching column up */
3406 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
3407 * otherwise, it can only be used as an estimate value */
3408 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
3409 * otherwise, it can only be used as an estimate value */
3410 SCIP_Longint* ndomredsdown, /**< pointer to store the number of domain reductions down, or NULL */
3411 SCIP_Longint* ndomredsup, /**< pointer to store the number of domain reductions up, or NULL */
3412 SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
3413 SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
3414 SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
3415 * infeasible downwards branch, or NULL */
3416 SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
3417 * infeasible upwards branch, or NULL */
3418 SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred or the
3419 * solving process should be stopped (e.g., due to a time limit) */
3420 SCIP_Real* newlbs, /**< array to store valid lower bounds for all active variables, or NULL */
3421 SCIP_Real* newubs /**< array to store valid upper bounds for all active variables, or NULL */
3422 )
3423{
3424 SCIP_COL* col;
3425 SCIP_VAR** vars;
3426 SCIP_Longint oldniters;
3427 SCIP_Real newub;
3428 SCIP_Real newlb;
3429 SCIP_Bool propagate;
3430 SCIP_Bool cutoff;
3431 SCIP_Bool downchild;
3432 SCIP_Bool firstchild;
3433 SCIP_Bool foundsol;
3434 SCIP_Bool downvalidlocal;
3435 SCIP_Bool upvalidlocal;
3436 SCIP_Bool allcolsinlp;
3437 SCIP_Bool enabledconflict;
3438 int oldnconflicts;
3439 int nvars;
3440
3441 assert(var != NULL);
3442 assert(SCIPvarIsIntegral(var));
3443 assert(down != NULL);
3444 assert(up != NULL);
3445 assert(lperror != NULL);
3446 assert((newlbs != NULL) == (newubs != NULL));
3447 assert(SCIPinProbing(scip));
3448 assert(var->scip == scip);
3449
3450 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchWithPropagation", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3451
3452 /* check whether propagation should be performed */
3453 propagate = (maxproprounds != 0 && maxproprounds != -3);
3454
3455 /* Check, if all existing columns are in LP.
3456 * If this is not the case, we may still return that the up and down dual bounds are valid, because the branching
3457 * rule should not apply them otherwise.
3458 * However, we must not set the downinf or upinf pointers to TRUE based on the dual bound, because we cannot
3459 * guarantee that this node can be cut off.
3460 */
3461 allcolsinlp = SCIPallColsInLP(scip);
3462
3463 /* if maxproprounds is -2, change it to 0, which for the following calls means using the parameter settings */
3464 if( maxproprounds == -2 )
3465 maxproprounds = 0;
3466
3467 *down = lpobjval;
3468 *up = lpobjval;
3469 if( downvalid != NULL )
3470 *downvalid = FALSE;
3471 if( upvalid != NULL )
3472 *upvalid = FALSE;
3473 if( downinf != NULL )
3474 *downinf = FALSE;
3475 if( upinf != NULL )
3476 *upinf = FALSE;
3477 if( downconflict != NULL )
3478 *downconflict = FALSE;
3479 if( upconflict != NULL )
3480 *upconflict = FALSE;
3481 if( ndomredsdown != NULL )
3482 *ndomredsdown = 0;
3483 if( ndomredsup != NULL )
3484 *ndomredsup = 0;
3485
3486 *lperror = FALSE;
3487
3488 vars = SCIPgetVars(scip);
3489 nvars = SCIPgetNVars(scip);
3490
3491 scip->stat->lastsblpsolstats[0] = scip->stat->lastsblpsolstats[1] = SCIP_LPSOLSTAT_NOTSOLVED;
3492
3493 /* check if the solving process should be aborted */
3494 if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3495 {
3496 /* mark this as if the LP failed */
3497 *lperror = TRUE;
3498 return SCIP_OKAY;
3499 }
3500
3502 {
3503 SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3504 return SCIP_INVALIDDATA;
3505 }
3506
3507 col = SCIPvarGetCol(var);
3508 assert(col != NULL);
3509
3510 if( !SCIPcolIsInLP(col) )
3511 {
3512 SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3513 return SCIP_INVALIDDATA;
3514 }
3515
3516 newlb = SCIPfeasFloor(scip, solval + 1.0);
3517 newub = SCIPfeasCeil(scip, solval - 1.0);
3518
3519 SCIPdebugMsg(scip, "strong branching on var <%s>: solval=%g, lb=%g, ub=%g\n", SCIPvarGetName(var), solval,
3521
3522 /* the up branch is infeasible due to the branching bound change; since this means that solval is not within the
3523 * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3524 * are valid for and were already applied at the probing root
3525 */
3526 if( newlb > SCIPvarGetUbLocal(var) + 0.5 )
3527 {
3528 *up = SCIPinfinity(scip);
3529
3530 if( upinf != NULL )
3531 *upinf = TRUE;
3532
3533 if( upvalid != NULL )
3534 *upvalid = TRUE;
3535
3536 /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3537 if( upconflict != NULL )
3538 *upconflict = TRUE;
3539
3540 SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3541 *down, *up, FALSE, TRUE, 0LL, INT_MAX);
3542
3543 /* we do not regard the down branch; its valid pointer stays set to FALSE */
3544 return SCIP_OKAY;
3545 }
3546
3547 /* the down branch is infeasible due to the branching bound change; since this means that solval is not within the
3548 * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3549 * are valid for and were already applied at the probing root
3550 */
3551 if( newub < SCIPvarGetLbLocal(var) - 0.5 )
3552 {
3553 *down = SCIPinfinity(scip);
3554
3555 if( downinf != NULL )
3556 *downinf = TRUE;
3557
3558 if( downvalid != NULL )
3559 *downvalid = TRUE;
3560
3561 /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3562 if( downconflict != NULL )
3563 *downconflict = TRUE;
3564
3565 SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3566 *down, *up, TRUE, FALSE, 0LL, INT_MAX);
3567
3568 /* we do not regard the up branch; its valid pointer stays set to FALSE */
3569 return SCIP_OKAY;
3570 }
3571
3572 /* We now do strong branching by creating the two potential child nodes as probing nodes and solving them one after
3573 * the other. We will stop when the first child is detected infeasible, saving the effort we would need for the
3574 * second child. Since empirically, the up child tends to be infeasible more often, we do strongbranching first on
3575 * the up branch.
3576 */
3577 oldniters = scip->stat->nsbdivinglpiterations;
3578 firstchild = TRUE;
3579 cutoff = FALSE;
3580
3581 /* switch conflict analysis according to usesb parameter */
3582 enabledconflict = scip->set->conf_enable;
3583 scip->set->conf_enable = (scip->set->conf_enable && scip->set->conf_usesb);
3584
3585 /* @todo: decide the branch to look at first based on the cutoffs in previous calls? */
3586 downchild = SCIPisStrongbranchDownFirst(scip, var);
3587
3588 downvalidlocal = FALSE;
3589 upvalidlocal = FALSE;
3590
3591 do
3592 {
3593 oldnconflicts = SCIPconflictGetNConflicts(scip->conflict);
3594
3595 if( downchild )
3596 {
3597 SCIP_CALL( performStrongbranchWithPropagation(scip, var, downchild, firstchild || cutoff, propagate, newub, itlim, maxproprounds,
3598 down, &downvalidlocal, ndomredsdown, downconflict, lperror, vars, nvars, newlbs, newubs, &foundsol, &cutoff) );
3599
3600 /* check for infeasibility */
3601 if( cutoff )
3602 {
3603 if( downinf != NULL )
3604 *downinf = TRUE;
3605
3606 if( downconflict != NULL
3607 && ( SCIPvarGetLbLocal(var) > newub + 0.5 || SCIPconflictGetNConflicts(scip->conflict) > oldnconflicts ) )
3608 *downconflict = TRUE;
3609 }
3610
3611 /* check whether new solutions rendered the other child infeasible */
3612 if( foundsol && allcolsinlp && SCIPisGE(scip, upvalidlocal ? *up : lpobjval, SCIPgetCutoffbound(scip)) )
3613 {
3614 if( upinf != NULL )
3615 *upinf = TRUE;
3616
3617 upvalidlocal = TRUE;
3618 cutoff = TRUE;
3619 }
3620 }
3621 else
3622 {
3623 SCIP_CALL( performStrongbranchWithPropagation(scip, var, downchild, firstchild || cutoff, propagate, newlb, itlim, maxproprounds,
3624 up, &upvalidlocal, ndomredsup, upconflict, lperror, vars, nvars, newlbs, newubs, &foundsol, &cutoff) );
3625
3626 /* check for infeasibility */
3627 if( cutoff )
3628 {
3629 if( upinf != NULL )
3630 *upinf = TRUE;
3631
3632 if( upconflict != NULL
3633 && ( SCIPvarGetUbLocal(var) < newlb - 0.5 || SCIPconflictGetNConflicts(scip->conflict) > oldnconflicts ) )
3634 *upconflict = TRUE;
3635 }
3636
3637 /* check whether new solutions rendered the other child infeasible */
3638 if( foundsol && allcolsinlp && SCIPisGE(scip, downvalidlocal ? *down : lpobjval, SCIPgetCutoffbound(scip)) )
3639 {
3640 if( downinf != NULL )
3641 *downinf = TRUE;
3642
3643 downvalidlocal = TRUE;
3644 cutoff = TRUE;
3645 }
3646 }
3647
3648 downchild = !downchild;
3649 firstchild = !firstchild;
3650 }
3651 /* if a child is cut off and forceall is FALSE, we do not regard the other child */
3652 while( !firstchild && ( !cutoff || scip->set->branch_forceall ) );
3653
3654 /* update lower bound by the higher pseudo objective value */
3655 if( ( downinf == NULL || !(*downinf) ) && ( upinf == NULL || !(*upinf) ) && !SCIPisZero(scip, SCIPvarGetObj(var)) )
3656 {
3657 SCIP_Real oldbound;
3658 SCIP_Real newbound;
3659 SCIP_Real pseudoobjval;
3660 SCIP_BOUNDTYPE boundtype = SCIPvarGetBestBoundType(var);
3661
3662 if( boundtype == SCIP_BOUNDTYPE_UPPER )
3663 {
3664 oldbound = SCIPvarGetUbLocal(var);
3665 newbound = newub;
3666 }
3667 else
3668 {
3669 oldbound = SCIPvarGetLbLocal(var);
3670 newbound = newlb;
3671 }
3672
3673 if( scip->set->misc_exactsolve )
3674 pseudoobjval = SCIPlpGetModifiedProvedPseudoObjval(scip->lp, scip->set, var, oldbound, newbound, boundtype);
3675 else
3676 pseudoobjval = SCIPlpGetModifiedPseudoObjval(scip->lp, scip->set, scip->transprob, var, oldbound, newbound, boundtype);
3677
3678 if( pseudoobjval > lpobjval )
3679 {
3680 if( boundtype == SCIP_BOUNDTYPE_UPPER )
3681 {
3682 if( !downvalidlocal || *down < pseudoobjval )
3683 {
3684 *down = pseudoobjval;
3685 downvalidlocal = TRUE;
3686
3687 if( downinf != NULL && allcolsinlp && SCIPisGE(scip, *down, SCIPgetCutoffbound(scip)) )
3688 *downinf = TRUE;
3689 }
3690 }
3691 else
3692 {
3693 if( !upvalidlocal || *up < pseudoobjval )
3694 {
3695 *up = pseudoobjval;
3696 upvalidlocal = TRUE;
3697
3698 if( upinf != NULL && allcolsinlp && SCIPisGE(scip, *up, SCIPgetCutoffbound(scip)) )
3699 *upinf = TRUE;
3700 }
3701 }
3702 }
3703 }
3704
3705 /* set strong branching information in column */
3706 if( *lperror )
3707 {
3708 SCIPcolInvalidateStrongbranchData(col, scip->set, scip->stat, scip->lp);
3709 }
3710 else
3711 {
3712 SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3713 *down, *up, downvalidlocal, upvalidlocal, scip->stat->nsbdivinglpiterations - oldniters, itlim);
3714 }
3715
3716 if( downvalid != NULL )
3717 *downvalid = downvalidlocal;
3718 if( upvalid != NULL )
3719 *upvalid = upvalidlocal;
3720
3721 scip->set->conf_enable = enabledconflict;
3722
3723 return SCIP_OKAY; /*lint !e438*/
3724}
3725
3726/** gets strong branching information on column variable x with integral LP solution value (val); that is, the down branch
3727 * is (val -1.0) and the up brach ins (val +1.0)
3728 *
3729 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3730 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3731 *
3732 * @pre This method can be called if @p scip is in one of the following stages:
3733 * - \ref SCIP_STAGE_PRESOLVED
3734 * - \ref SCIP_STAGE_SOLVING
3735 *
3736 * @note If the integral LP solution value is the lower or upper bound of the variable, the corresponding branch will be
3737 * marked as infeasible. That is, the valid pointer and the infeasible pointer are set to TRUE.
3738 */
3740 SCIP* scip, /**< SCIP data structure */
3741 SCIP_VAR* var, /**< variable to get strong branching values for */
3742 int itlim, /**< iteration limit for strong branchings */
3743 SCIP_Bool idempotent, /**< should scip's state remain the same after the call (statistics, column states...), or should it be updated ? */
3744 SCIP_Real* down, /**< stores dual bound after branching column down */
3745 SCIP_Real* up, /**< stores dual bound after branching column up */
3746 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
3747 * otherwise, it can only be used as an estimate value */
3748 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
3749 * otherwise, it can only be used as an estimate value */
3750 SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
3751 SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
3752 SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
3753 * infeasible downwards branch, or NULL */
3754 SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
3755 * infeasible upwards branch, or NULL */
3756 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3757 * solving process should be stopped (e.g., due to a time limit) */
3758 )
3759{
3760 SCIP_COL* col;
3761 SCIP_Real lpobjval;
3762 SCIP_Real localdown;
3763 SCIP_Real localup;
3764 SCIP_Bool localdownvalid;
3765 SCIP_Bool localupvalid;
3766
3767 assert(var != NULL);
3768 assert(lperror != NULL);
3769 assert(var->scip == scip);
3770
3771 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchInt", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3772
3773 lpobjval = SCIPgetLPObjval(scip);
3774 if( downvalid != NULL )
3775 *downvalid = FALSE;
3776 if( upvalid != NULL )
3777 *upvalid = FALSE;
3778 if( downinf != NULL )
3779 *downinf = FALSE;
3780 if( upinf != NULL )
3781 *upinf = FALSE;
3782 if( downconflict != NULL )
3783 *downconflict = FALSE;
3784 if( upconflict != NULL )
3785 *upconflict = FALSE;
3786
3788 {
3789 SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3790 return SCIP_INVALIDDATA;
3791 }
3792
3793 col = SCIPvarGetCol(var);
3794 assert(col != NULL);
3795
3796 if( !SCIPcolIsInLP(col) )
3797 {
3798 SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3799 return SCIP_INVALIDDATA;
3800 }
3801
3802 /* check if the solving process should be aborted */
3803 if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3804 {
3805 /* mark this as if the LP failed */
3806 *lperror = TRUE;
3807 return SCIP_OKAY;
3808 }
3809
3810 /* call strong branching for column */
3811 SCIP_CALL( SCIPcolGetStrongbranch(col, TRUE, scip->set, scip->stat, scip->transprob, scip->lp, itlim, !idempotent, !idempotent,
3812 &localdown, &localup, &localdownvalid, &localupvalid, lperror) );
3813
3814 /* update lower bound by the higher pseudo objective value */
3815 if( !SCIPisZero(scip, SCIPvarGetObj(var)) )
3816 {
3817 SCIP_Real oldbound;
3818 SCIP_Real newbound;
3819 SCIP_Real pseudoobjval;
3820 SCIP_BOUNDTYPE boundtype = SCIPvarGetBestBoundType(var);
3821
3822 if( boundtype == SCIP_BOUNDTYPE_UPPER )
3823 {
3824 oldbound = SCIPvarGetUbLocal(var);
3825 newbound = SCIPfeasCeil(scip, SCIPvarGetLPSol(var)) - 1.0;
3826 }
3827 else
3828 {
3829 oldbound = SCIPvarGetLbLocal(var);
3830 newbound = SCIPfeasFloor(scip, SCIPvarGetLPSol(var)) + 1.0;
3831 }
3832
3833 if( scip->set->misc_exactsolve )
3834 pseudoobjval = SCIPlpGetModifiedProvedPseudoObjval(scip->lp, scip->set, var, oldbound, newbound, boundtype);
3835 else
3836 pseudoobjval = SCIPlpGetModifiedPseudoObjval(scip->lp, scip->set, scip->transprob, var, oldbound, newbound, boundtype);
3837
3838 if( pseudoobjval > lpobjval )
3839 {
3840 if( boundtype == SCIP_BOUNDTYPE_UPPER )
3841 {
3842 if( !localdownvalid || localdown < pseudoobjval )
3843 {
3844 localdown = pseudoobjval;
3845 localdownvalid = TRUE;
3846 }
3847 }
3848 else
3849 {
3850 if( !localupvalid || localup < pseudoobjval )
3851 {
3852 localup = pseudoobjval;
3853 localupvalid = TRUE;
3854 }
3855 }
3856 }
3857 }
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 if( !idempotent ) /*lint !e774*/
3865 {
3866 SCIP_CALL( analyzeStrongbranch(scip, var, NULL, NULL, downconflict, upconflict) );
3867 }
3868
3869 if( downinf != NULL )
3870 *downinf = localdownvalid && SCIPsetIsGE(scip->set, localdown, scip->lp->cutoffbound);
3871 if( upinf != NULL )
3872 *upinf = localupvalid && SCIPsetIsGE(scip->set, localup, scip->lp->cutoffbound);
3873 }
3874
3875 if( down != NULL )
3876 *down = localdown;
3877 if( up != NULL )
3878 *up = localup;
3879 if( downvalid != NULL )
3880 *downvalid = localdownvalid;
3881 if( upvalid != NULL )
3882 *upvalid = localupvalid;
3883
3884 return SCIP_OKAY;
3885}
3886
3887/** gets strong branching information on column variables with fractional values
3888 *
3889 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3890 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3891 *
3892 * @pre This method can be called if @p scip is in one of the following stages:
3893 * - \ref SCIP_STAGE_PRESOLVED
3894 * - \ref SCIP_STAGE_SOLVING
3895 */
3897 SCIP* scip, /**< SCIP data structure */
3898 SCIP_VAR** vars, /**< variables to get strong branching values for */
3899 int nvars, /**< number of variables */
3900 int itlim, /**< iteration limit for strong branchings */
3901 SCIP_Real* down, /**< stores dual bounds after branching variables down */
3902 SCIP_Real* up, /**< stores dual bounds after branching variables up */
3903 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
3904 * otherwise, they can only be used as an estimate value */
3905 SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
3906 * otherwise, they can only be used as an estimate value */
3907 SCIP_Bool* downinf, /**< array to store whether the downward branches are infeasible, or NULL */
3908 SCIP_Bool* upinf, /**< array to store whether the upward branches are infeasible, or NULL */
3909 SCIP_Bool* downconflict, /**< array to store whether conflict constraints were created for
3910 * infeasible downward branches, or NULL */
3911 SCIP_Bool* upconflict, /**< array to store whether conflict constraints were created for
3912 * infeasible upward branches, or NULL */
3913 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3914 * solving process should be stopped (e.g., due to a time limit) */
3915 )
3916{
3917 SCIP_COL** cols;
3918 int j;
3919
3920 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarsStrongbranchesFrac", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3921
3922 assert( lperror != NULL );
3923 assert( vars != NULL );
3924
3925 /* set up data */
3926 cols = NULL;
3927 SCIP_CALL( SCIPallocBufferArray(scip, &cols, nvars) );
3928 assert(cols != NULL);
3929 for( j = 0; j < nvars; ++j )
3930 {
3931 SCIP_VAR* var;
3932 SCIP_COL* col;
3933
3934 if( downvalid != NULL )
3935 downvalid[j] = FALSE;
3936 if( upvalid != NULL )
3937 upvalid[j] = FALSE;
3938 if( downinf != NULL )
3939 downinf[j] = FALSE;
3940 if( upinf != NULL )
3941 upinf[j] = FALSE;
3942 if( downconflict != NULL )
3943 downconflict[j] = FALSE;
3944 if( upconflict != NULL )
3945 upconflict[j] = FALSE;
3946
3947 var = vars[j];
3948 assert( var != NULL );
3950 {
3951 SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3952 SCIPfreeBufferArray(scip, &cols);
3953 return SCIP_INVALIDDATA;
3954 }
3955
3956 col = SCIPvarGetCol(var);
3957 assert(col != NULL);
3958 cols[j] = col;
3959
3960 if( !SCIPcolIsInLP(col) )
3961 {
3962 SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3963 SCIPfreeBufferArray(scip, &cols);
3964 return SCIP_INVALIDDATA;
3965 }
3966 }
3967
3968 /* check if the solving process should be aborted */
3969 if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3970 {
3971 /* mark this as if the LP failed */
3972 *lperror = TRUE;
3973 }
3974 else
3975 {
3976 /* call strong branching for columns with fractional value */
3977 SCIP_CALL( SCIPcolGetStrongbranches(cols, nvars, FALSE, scip->set, scip->stat, scip->transprob, scip->lp, itlim,
3978 down, up, downvalid, upvalid, lperror) );
3979
3980 /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3981 * declare the sub nodes infeasible
3982 */
3983 if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3984 {
3985 for( j = 0; j < nvars; ++j )
3986 {
3987 SCIP_CALL( analyzeStrongbranch(scip, vars[j], (downinf != NULL) ? (&(downinf[j])) : NULL,
3988 (upinf != NULL) ? (&(upinf[j])) : NULL, (downconflict != NULL) ? (&(downconflict[j])) : NULL,
3989 (upconflict != NULL) ? (&(upconflict[j])) : NULL) );
3990 }
3991 }
3992 }
3993 SCIPfreeBufferArray(scip, &cols);
3994
3995 return SCIP_OKAY;
3996}
3997
3998/** gets strong branching information on column variables with integral values
3999 *
4000 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4001 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4002 *
4003 * @pre This method can be called if @p scip is in one of the following stages:
4004 * - \ref SCIP_STAGE_PRESOLVED
4005 * - \ref SCIP_STAGE_SOLVING
4006 */
4008 SCIP* scip, /**< SCIP data structure */
4009 SCIP_VAR** vars, /**< variables to get strong branching values for */
4010 int nvars, /**< number of variables */
4011 int itlim, /**< iteration limit for strong branchings */
4012 SCIP_Real* down, /**< stores dual bounds after branching variables down */
4013 SCIP_Real* up, /**< stores dual bounds after branching variables up */
4014 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
4015 * otherwise, they can only be used as an estimate value */
4016 SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
4017 * otherwise, they can only be used as an estimate value */
4018 SCIP_Bool* downinf, /**< array to store whether the downward branches are infeasible, or NULL */
4019 SCIP_Bool* upinf, /**< array to store whether the upward branches are infeasible, or NULL */
4020 SCIP_Bool* downconflict, /**< array to store whether conflict constraints were created for
4021 * infeasible downward branches, or NULL */
4022 SCIP_Bool* upconflict, /**< array to store whether conflict constraints were created for
4023 * infeasible upward branches, or NULL */
4024 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
4025 * solving process should be stopped (e.g., due to a time limit) */
4026 )
4027{
4028 SCIP_COL** cols;
4029 int j;
4030
4031 assert(lperror != NULL);
4032
4033 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarsStrongbranchesInt", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4034
4035 assert( vars != NULL );
4036
4037 /* set up data */
4038 cols = NULL;
4039 SCIP_CALL( SCIPallocBufferArray(scip, &cols, nvars) );
4040 assert(cols != NULL);
4041 for( j = 0; j < nvars; ++j )
4042 {
4043 SCIP_VAR* var;
4044 SCIP_COL* col;
4045
4046 if( downvalid != NULL )
4047 downvalid[j] = FALSE;
4048 if( upvalid != NULL )
4049 upvalid[j] = FALSE;
4050 if( downinf != NULL )
4051 downinf[j] = FALSE;
4052 if( upinf != NULL )
4053 upinf[j] = FALSE;
4054 if( downconflict != NULL )
4055 downconflict[j] = FALSE;
4056 if( upconflict != NULL )
4057 upconflict[j] = FALSE;
4058
4059 var = vars[j];
4060 assert( var != NULL );
4062 {
4063 SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
4064 SCIPfreeBufferArray(scip, &cols);
4065 return SCIP_INVALIDDATA;
4066 }
4067
4068 col = SCIPvarGetCol(var);
4069 assert(col != NULL);
4070 cols[j] = col;
4071
4072 if( !SCIPcolIsInLP(col) )
4073 {
4074 SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
4075 SCIPfreeBufferArray(scip, &cols);
4076 return SCIP_INVALIDDATA;
4077 }
4078 }
4079
4080 /* check if the solving process should be aborted */
4081 if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
4082 {
4083 /* mark this as if the LP failed */
4084 *lperror = TRUE;
4085 }
4086 else
4087 {
4088 /* call strong branching for columns */
4089 SCIP_CALL( SCIPcolGetStrongbranches(cols, nvars, TRUE, scip->set, scip->stat, scip->transprob, scip->lp, itlim,
4090 down, up, downvalid, upvalid, lperror) );
4091
4092 /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
4093 * declare the sub nodes infeasible
4094 */
4095 if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
4096 {
4097 for( j = 0; j < nvars; ++j )
4098 {
4099 SCIP_CALL( analyzeStrongbranch(scip, vars[j], (downinf != NULL) ? (&(downinf[j])) : NULL,
4100 (upinf != NULL) ? (&(upinf[j])) : NULL, (downconflict != NULL) ? (&(downconflict[j])) : NULL,
4101 (upconflict != NULL) ? (&(upconflict[j])) : NULL) );
4102 }
4103 }
4104 }
4105 SCIPfreeBufferArray(scip, &cols);
4106
4107 return SCIP_OKAY;
4108}
4109
4110/** get LP solution status of last strong branching call (currently only works for strong branching with propagation) */
4112 SCIP* scip, /**< SCIP data structure */
4113 SCIP_BRANCHDIR branchdir /**< branching direction for which LP solution status is requested */
4114 )
4115{
4116 assert(NULL != scip);
4117 assert(branchdir == SCIP_BRANCHDIR_DOWNWARDS || branchdir == SCIP_BRANCHDIR_UPWARDS);
4118
4119 return scip->stat->lastsblpsolstats[branchdir == SCIP_BRANCHDIR_DOWNWARDS ? 0 : 1];
4120}
4121
4122/** gets strong branching information on COLUMN variable of the last SCIPgetVarStrongbranch() call;
4123 * returns values of SCIP_INVALID, if strong branching was not yet called on the given variable;
4124 * keep in mind, that the returned old values may have nothing to do with the current LP solution
4125 *
4126 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4127 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4128 *
4129 * @pre This method can be called if @p scip is in one of the following stages:
4130 * - \ref SCIP_STAGE_SOLVING
4131 * - \ref SCIP_STAGE_SOLVED
4132 */
4134 SCIP* scip, /**< SCIP data structure */
4135 SCIP_VAR* var, /**< variable to get last strong branching values for */
4136 SCIP_Real* down, /**< stores dual bound after branching column down */
4137 SCIP_Real* up, /**< stores dual bound after branching column up */
4138 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4139 * otherwise, it can only be used as an estimate value */
4140 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4141 * otherwise, it can only be used as an estimate value */
4142 SCIP_Real* solval, /**< stores LP solution value of variable at the last strong branching call, or NULL */
4143 SCIP_Real* lpobjval /**< stores LP objective value at last strong branching call, or NULL */
4144 )
4145{
4146 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchLast", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
4147
4149 {
4150 SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable\n");
4151 return SCIP_INVALIDDATA;
4152 }
4153
4154 SCIPcolGetStrongbranchLast(SCIPvarGetCol(var), down, up, downvalid, upvalid, solval, lpobjval);
4155
4156 return SCIP_OKAY;
4157}
4158
4159/** sets strong branching information for a column variable
4160 *
4161 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4162 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4163 *
4164 * @pre This method can be called if @p scip is in one of the following stages:
4165 * - \ref SCIP_STAGE_SOLVING
4166 */
4168 SCIP* scip, /**< SCIP data structure */
4169 SCIP_VAR* var, /**< variable to set last strong branching values for */
4170 SCIP_Real lpobjval, /**< objective value of the current LP */
4171 SCIP_Real primsol, /**< primal solution value of the column in the current LP */
4172 SCIP_Real down, /**< dual bound after branching column down */
4173 SCIP_Real up, /**< dual bound after branching column up */
4174 SCIP_Bool downvalid, /**< is the returned down value a valid dual bound? */
4175 SCIP_Bool upvalid, /**< is the returned up value a valid dual bound? */
4176 SCIP_Longint iter, /**< total number of strong branching iterations */
4177 int itlim /**< iteration limit applied to the strong branching call */
4178 )
4179{
4180 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetVarStrongbranchData", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4181
4183 {
4184 SCIPerrorMessage("cannot set strong branching information on non-COLUMN variable\n");
4185 return SCIP_INVALIDDATA;
4186 }
4187
4188 SCIPcolSetStrongbranchData(SCIPvarGetCol(var), scip->set, scip->stat, scip->lp, lpobjval, primsol,
4189 down, up, downvalid, upvalid, iter, itlim);
4190
4191 return SCIP_OKAY;
4192}
4193
4194/** rounds the current solution and tries it afterwards; if feasible, adds it to storage
4195 *
4196 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4197 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4198 *
4199 * @pre This method can be called if @p scip is in one of the following stages:
4200 * - \ref SCIP_STAGE_SOLVING
4201 */
4203 SCIP* scip, /**< SCIP data structure */
4204 SCIP_Bool* foundsol, /**< stores whether solution was feasible and good enough to keep */
4205 SCIP_Bool* cutoff /**< stores whether solution was cutoff due to exceeding the cutoffbound */
4206 )
4207{
4208 assert(scip != NULL);
4209 assert(foundsol != NULL);
4210 assert(cutoff != NULL);
4211
4212 SCIP_CALL( SCIPcheckStage(scip, "SCIPtryStrongbranchLPSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4213
4214 if( scip->set->branch_checksbsol )
4215 {
4216 SCIP_SOL* sol;
4217 SCIP_Bool rounded = TRUE;
4219 SCIP_Longint oldnbestsolsfound = scip->primal->nbestsolsfound;
4220
4221 /* start clock for strong branching solutions */
4222 SCIPclockStart(scip->stat->sbsoltime, scip->set);
4223
4226
4227 /* try to round the strong branching solution */
4228 if( scip->set->branch_roundsbsol )
4229 {
4230 SCIP_CALL( SCIProundSol(scip, sol, &rounded) );
4231 }
4232
4233 /* check the solution for feasibility if rounding worked well (or was not tried) */
4234 if( rounded )
4235 {
4236 SCIP_CALL( SCIPtrySolFree(scip, &sol, FALSE, FALSE, FALSE, TRUE, FALSE, foundsol) );
4237 }
4238 else
4239 {
4240 SCIP_CALL( SCIPfreeSol(scip, &sol) );
4241 }
4242
4243 if( *foundsol )
4244 {
4245 SCIPdebugMsg(scip, "found new solution in strong branching\n");
4246
4247 scip->stat->nsbsolsfound++;
4248
4249 if( scip->primal->nbestsolsfound != oldnbestsolsfound )
4250 {
4251 scip->stat->nsbbestsolsfound++;
4252 }
4253
4254 if( SCIPisGE(scip, value, SCIPgetCutoffbound(scip)) )
4255 *cutoff = TRUE;
4256 }
4257
4258 /* stop clock for strong branching solutions */
4259 SCIPclockStop(scip->stat->sbsoltime, scip->set);
4260 }
4261 return SCIP_OKAY;
4262}
4263
4264
4265/** gets node number of the last node in current branch and bound run, where strong branching was used on the
4266 * given variable, or -1 if strong branching was never applied to the variable in current run
4267 *
4268 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4269 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4270 *
4271 * @pre This method can be called if @p scip is in one of the following stages:
4272 * - \ref SCIP_STAGE_TRANSFORMING
4273 * - \ref SCIP_STAGE_TRANSFORMED
4274 * - \ref SCIP_STAGE_INITPRESOLVE
4275 * - \ref SCIP_STAGE_PRESOLVING
4276 * - \ref SCIP_STAGE_EXITPRESOLVE
4277 * - \ref SCIP_STAGE_PRESOLVED
4278 * - \ref SCIP_STAGE_INITSOLVE
4279 * - \ref SCIP_STAGE_SOLVING
4280 * - \ref SCIP_STAGE_SOLVED
4281 * - \ref SCIP_STAGE_EXITSOLVE
4282 */
4284 SCIP* scip, /**< SCIP data structure */
4285 SCIP_VAR* var /**< variable to get last strong branching node for */
4286 )
4287{
4288 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarStrongbranchNode", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4289
4290 assert( var->scip == scip );
4291
4293 return -1;
4294
4296}
4297
4298/** if strong branching was already applied on the variable at the current node, returns the number of LPs solved after
4299 * the LP where the strong branching on this variable was applied;
4300 * if strong branching was not yet applied on the variable at the current node, returns INT_MAX
4301 *
4302 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4303 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4304 *
4305 * @pre This method can be called if @p scip is in one of the following stages:
4306 * - \ref SCIP_STAGE_TRANSFORMING
4307 * - \ref SCIP_STAGE_TRANSFORMED
4308 * - \ref SCIP_STAGE_INITPRESOLVE
4309 * - \ref SCIP_STAGE_PRESOLVING
4310 * - \ref SCIP_STAGE_EXITPRESOLVE
4311 * - \ref SCIP_STAGE_PRESOLVED
4312 * - \ref SCIP_STAGE_INITSOLVE
4313 * - \ref SCIP_STAGE_SOLVING
4314 * - \ref SCIP_STAGE_SOLVED
4315 * - \ref SCIP_STAGE_EXITSOLVE
4316 */
4318 SCIP* scip, /**< SCIP data structure */
4319 SCIP_VAR* var /**< variable to get strong branching LP age for */
4320 )
4321{
4322 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarStrongbranchLPAge", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4323
4324 assert( var->scip == scip );
4325
4327 return SCIP_LONGINT_MAX;
4328
4330}
4331
4332/** gets number of times, strong branching was applied in current run on the given variable
4333 *
4334 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4335 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4336 *
4337 * @pre This method can be called if @p scip is in one of the following stages:
4338 * - \ref SCIP_STAGE_TRANSFORMING
4339 * - \ref SCIP_STAGE_TRANSFORMED
4340 * - \ref SCIP_STAGE_INITPRESOLVE
4341 * - \ref SCIP_STAGE_PRESOLVING
4342 * - \ref SCIP_STAGE_EXITPRESOLVE
4343 * - \ref SCIP_STAGE_PRESOLVED
4344 * - \ref SCIP_STAGE_INITSOLVE
4345 * - \ref SCIP_STAGE_SOLVING
4346 * - \ref SCIP_STAGE_SOLVED
4347 * - \ref SCIP_STAGE_EXITSOLVE
4348 */
4350 SCIP* scip, /**< SCIP data structure */
4351 SCIP_VAR* var /**< variable to get last strong branching node for */
4352 )
4353{
4354 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarNStrongbranchs", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4355
4356 assert( var->scip == scip );
4357
4359 return 0;
4360
4362}
4363
4364/** adds given values to lock numbers of type @p locktype of variable for rounding
4365 *
4366 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4367 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4368 *
4369 * @pre This method can be called if @p scip is in one of the following stages:
4370 * - \ref SCIP_STAGE_PROBLEM
4371 * - \ref SCIP_STAGE_TRANSFORMING
4372 * - \ref SCIP_STAGE_TRANSFORMED
4373 * - \ref SCIP_STAGE_INITPRESOLVE
4374 * - \ref SCIP_STAGE_PRESOLVING
4375 * - \ref SCIP_STAGE_EXITPRESOLVE
4376 * - \ref SCIP_STAGE_PRESOLVED
4377 * - \ref SCIP_STAGE_INITSOLVE
4378 * - \ref SCIP_STAGE_SOLVING
4379 * - \ref SCIP_STAGE_EXITSOLVE
4380 * - \ref SCIP_STAGE_FREETRANS
4381 */
4383 SCIP* scip, /**< SCIP data structure */
4384 SCIP_VAR* var, /**< problem variable */
4385 SCIP_LOCKTYPE locktype, /**< type of the variable locks */
4386 int nlocksdown, /**< modification in number of rounding down locks */
4387 int nlocksup /**< modification in number of rounding up locks */
4388 )
4389{
4390 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarLocksType", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4391
4392 assert( var->scip == scip );
4393
4394 switch( scip->set->stage )
4395 {
4396 case SCIP_STAGE_PROBLEM:
4397 assert(!SCIPvarIsTransformed(var));
4398 /*lint -fallthrough*/
4406 case SCIP_STAGE_SOLVING:
4409 SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, locktype, nlocksdown, nlocksup) );
4410 return SCIP_OKAY;
4411
4412 default:
4413 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4414 return SCIP_INVALIDCALL;
4415 } /*lint !e788*/
4416}
4417
4418/** adds given values to lock numbers of variable for rounding
4419 *
4420 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4421 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4422 *
4423 * @pre This method can be called if @p scip is in one of the following stages:
4424 * - \ref SCIP_STAGE_PROBLEM
4425 * - \ref SCIP_STAGE_TRANSFORMING
4426 * - \ref SCIP_STAGE_TRANSFORMED
4427 * - \ref SCIP_STAGE_INITPRESOLVE
4428 * - \ref SCIP_STAGE_PRESOLVING
4429 * - \ref SCIP_STAGE_EXITPRESOLVE
4430 * - \ref SCIP_STAGE_PRESOLVED
4431 * - \ref SCIP_STAGE_INITSOLVE
4432 * - \ref SCIP_STAGE_SOLVING
4433 * - \ref SCIP_STAGE_EXITSOLVE
4434 * - \ref SCIP_STAGE_FREETRANS
4435 *
4436 * @note This method will always add variable locks of type model
4437 *
4438 * @note It is recommented to use SCIPaddVarLocksType()
4439 */
4441 SCIP* scip, /**< SCIP data structure */
4442 SCIP_VAR* var, /**< problem variable */
4443 int nlocksdown, /**< modification in number of rounding down locks */
4444 int nlocksup /**< modification in number of rounding up locks */
4445 )
4446{
4447 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarLocks", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4448
4449 SCIP_CALL( SCIPaddVarLocksType(scip, var, SCIP_LOCKTYPE_MODEL, nlocksdown, nlocksup) );
4450
4451 return SCIP_OKAY;
4452}
4453
4454/** add locks of variable with respect to the lock status of the constraint and its negation;
4455 * this method should be called whenever the lock status of a variable in a constraint changes, for example if
4456 * the coefficient of the variable changed its sign or if the left or right hand sides of the constraint were
4457 * added or removed
4458 *
4459 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4460 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4461 *
4462 * @pre This method can be called if @p scip is in one of the following stages:
4463 * - \ref SCIP_STAGE_PROBLEM
4464 * - \ref SCIP_STAGE_TRANSFORMING
4465 * - \ref SCIP_STAGE_TRANSFORMED
4466 * - \ref SCIP_STAGE_INITPRESOLVE
4467 * - \ref SCIP_STAGE_PRESOLVING
4468 * - \ref SCIP_STAGE_EXITPRESOLVE
4469 * - \ref SCIP_STAGE_INITSOLVE
4470 * - \ref SCIP_STAGE_SOLVING
4471 * - \ref SCIP_STAGE_EXITSOLVE
4472 * - \ref SCIP_STAGE_FREETRANS
4473 */
4475 SCIP* scip, /**< SCIP data structure */
4476 SCIP_VAR* var, /**< problem variable */
4477 SCIP_CONS* cons, /**< constraint */
4478 SCIP_Bool lockdown, /**< should the rounding be locked in downwards direction? */
4479 SCIP_Bool lockup /**< should the rounding be locked in upwards direction? */
4480 )
4481{
4482 int nlocksdown[NLOCKTYPES];
4483 int nlocksup[NLOCKTYPES];
4484 int i;
4485
4486 SCIP_CALL( SCIPcheckStage(scip, "SCIPlockVarCons", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4487
4488 assert( var->scip == scip );
4489
4490 for( i = 0; i < NLOCKTYPES; i++ )
4491 {
4492 nlocksdown[i] = 0;
4493 nlocksup[i] = 0;
4494
4495 if( SCIPconsIsLockedTypePos(cons, (SCIP_LOCKTYPE) i) )
4496 {
4497 if( lockdown )
4498 ++nlocksdown[i];
4499 if( lockup )
4500 ++nlocksup[i];
4501 }
4502 if( SCIPconsIsLockedTypeNeg(cons, (SCIP_LOCKTYPE) i) )
4503 {
4504 if( lockdown )
4505 ++nlocksup[i];
4506 if( lockup )
4507 ++nlocksdown[i];
4508 }
4509 }
4510
4511 switch( scip->set->stage )
4512 {
4513 case SCIP_STAGE_PROBLEM:
4514 assert(!SCIPvarIsTransformed(var));
4515 /*lint -fallthrough*/
4522 case SCIP_STAGE_SOLVING:
4525 for( i = 0; i < NLOCKTYPES; i++ )
4526 {
4527 if( nlocksdown[i] == 0 && nlocksup[i] == 0 )
4528 continue;
4529
4530 SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, (SCIP_LOCKTYPE) i, nlocksdown[i], nlocksup[i]) );
4531 }
4532 return SCIP_OKAY;
4533
4534 default:
4535 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4536 return SCIP_INVALIDCALL;
4537 } /*lint !e788*/
4538}
4539
4540/** remove locks of type @p locktype of variable with respect to the lock status of the constraint and its negation;
4541 * this method should be called whenever the lock status of a variable in a constraint changes, for example if
4542 * the coefficient of the variable changed its sign or if the left or right hand sides of the constraint were
4543 * added or removed
4544 *
4545 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4546 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4547 *
4548 * @pre This method can be called if @p scip is in one of the following stages:
4549 * - \ref SCIP_STAGE_PROBLEM
4550 * - \ref SCIP_STAGE_TRANSFORMING
4551 * - \ref SCIP_STAGE_TRANSFORMED
4552 * - \ref SCIP_STAGE_INITPRESOLVE
4553 * - \ref SCIP_STAGE_PRESOLVING
4554 * - \ref SCIP_STAGE_EXITPRESOLVE
4555 * - \ref SCIP_STAGE_INITSOLVE
4556 * - \ref SCIP_STAGE_SOLVING
4557 * - \ref SCIP_STAGE_EXITSOLVE
4558 * - \ref SCIP_STAGE_FREETRANS
4559 */
4561 SCIP* scip, /**< SCIP data structure */
4562 SCIP_VAR* var, /**< problem variable */
4563 SCIP_CONS* cons, /**< constraint */
4564 SCIP_Bool lockdown, /**< should the rounding be unlocked in downwards direction? */
4565 SCIP_Bool lockup /**< should the rounding be unlocked in upwards direction? */
4566 )
4567{
4568 int nlocksdown[NLOCKTYPES];
4569 int nlocksup[NLOCKTYPES];
4570 int i;
4571
4572 SCIP_CALL( SCIPcheckStage(scip, "SCIPunlockVarCons", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4573
4574 assert( var->scip == scip );
4575
4576 for( i = 0; i < NLOCKTYPES; i++ )
4577 {
4578 nlocksdown[i] = 0;
4579 nlocksup[i] = 0;
4580
4581 if( SCIPconsIsLockedTypePos(cons, (SCIP_LOCKTYPE) i) )
4582 {
4583 if( lockdown )
4584 ++nlocksdown[i];
4585 if( lockup )
4586 ++nlocksup[i];
4587 }
4588 if( SCIPconsIsLockedTypeNeg(cons, (SCIP_LOCKTYPE) i) )
4589 {
4590 if( lockdown )
4591 ++nlocksup[i];
4592 if( lockup )
4593 ++nlocksdown[i];
4594 }
4595 }
4596 switch( scip->set->stage )
4597 {
4598 case SCIP_STAGE_PROBLEM:
4599 assert(!SCIPvarIsTransformed(var));
4600 /*lint -fallthrough*/
4607 case SCIP_STAGE_SOLVING:
4610 for( i = 0; i < NLOCKTYPES; i++ )
4611 {
4612 if( nlocksdown[i] == 0 && nlocksup[i] == 0 )
4613 continue;
4614
4615 SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, (SCIP_LOCKTYPE) i, -nlocksdown[i], -nlocksup[i]) );
4616 }
4617 return SCIP_OKAY;
4618
4619 default:
4620 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4621 return SCIP_INVALIDCALL;
4622 } /*lint !e788*/
4623}
4624
4625/** changes variable's objective value
4626 *
4627 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4628 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4629 *
4630 * @pre This method can be called if @p scip is in one of the following stages:
4631 * - \ref SCIP_STAGE_PROBLEM
4632 * - \ref SCIP_STAGE_TRANSFORMING
4633 * - \ref SCIP_STAGE_PRESOLVING
4634 * - \ref SCIP_STAGE_PRESOLVED
4635 */
4637 SCIP* scip, /**< SCIP data structure */
4638 SCIP_VAR* var, /**< variable to change the objective value for */
4639 SCIP_Real newobj /**< new objective value */
4640 )
4641{
4643
4644 assert( var->scip == scip );
4645
4646 /* forbid infinite objective values */
4647 if( SCIPisInfinity(scip, REALABS(newobj)) )
4648 {
4649 SCIPerrorMessage("invalid objective value: objective value is infinite\n");
4650 return SCIP_INVALIDDATA;
4651 }
4652
4653 switch( scip->set->stage )
4654 {
4655 case SCIP_STAGE_PROBLEM:
4656 assert(!SCIPvarIsTransformed(var));
4657 SCIP_CALL( SCIPvarChgObj(var, scip->mem->probmem, scip->set, scip->origprob, scip->primal, scip->lp, scip->eventqueue, newobj) );
4658 return SCIP_OKAY;
4659
4664 SCIP_CALL( SCIPvarChgObj(var, scip->mem->probmem, scip->set, scip->transprob, scip->primal, scip->lp, scip->eventqueue, newobj) );
4665 return SCIP_OKAY;
4666
4667 default:
4668 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4669 return SCIP_INVALIDCALL;
4670 } /*lint !e788*/
4671}
4672
4673/** adds value to variable's objective value
4674 *
4675 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4676 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4677 *
4678 * @pre This method can be called if @p scip is in one of the following stages:
4679 * - \ref SCIP_STAGE_PROBLEM
4680 * - \ref SCIP_STAGE_TRANSFORMING
4681 * - \ref SCIP_STAGE_PRESOLVING
4682 * - \ref SCIP_STAGE_EXITPRESOLVE
4683 * - \ref SCIP_STAGE_PRESOLVED
4684 */
4686 SCIP* scip, /**< SCIP data structure */
4687 SCIP_VAR* var, /**< variable to change the objective value for */
4688 SCIP_Real addobj /**< additional objective value */
4689 )
4690{
4692
4693 assert( var->scip == scip );
4694
4695 switch( scip->set->stage )
4696 {
4697 case SCIP_STAGE_PROBLEM:
4698 assert(!SCIPvarIsTransformed(var));
4699 SCIP_CALL( SCIPvarAddObj(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->primal,
4700 scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue, addobj) );
4701 return SCIP_OKAY;
4702
4707 SCIP_CALL( SCIPvarAddObj(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->primal,
4708 scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue, addobj) );
4709 return SCIP_OKAY;
4710
4711 default:
4712 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4713 return SCIP_INVALIDCALL;
4714 } /*lint !e788*/
4715}
4716
4717/** returns the adjusted (i.e. rounded, if the given variable is of integral type) lower bound value;
4718 * does not change the bounds of the variable
4719 *
4720 * @return adjusted lower bound for the given variable; the bound of the variable is not changed
4721 *
4722 * @pre This method can be called if @p scip is in one of the following stages:
4723 * - \ref SCIP_STAGE_PROBLEM
4724 * - \ref SCIP_STAGE_TRANSFORMING
4725 * - \ref SCIP_STAGE_TRANSFORMED
4726 * - \ref SCIP_STAGE_INITPRESOLVE
4727 * - \ref SCIP_STAGE_PRESOLVING
4728 * - \ref SCIP_STAGE_EXITPRESOLVE
4729 * - \ref SCIP_STAGE_PRESOLVED
4730 * - \ref SCIP_STAGE_INITSOLVE
4731 * - \ref SCIP_STAGE_SOLVING
4732 * - \ref SCIP_STAGE_SOLVED
4733 * - \ref SCIP_STAGE_EXITSOLVE
4734 * - \ref SCIP_STAGE_FREETRANS
4735 */
4737 SCIP* scip, /**< SCIP data structure */
4738 SCIP_VAR* var, /**< variable to adjust the bound for */
4739 SCIP_Real lb /**< lower bound value to adjust */
4740 )
4741{
4742 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPadjustedVarLb", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
4743
4744 SCIPvarAdjustLb(var, scip->set, &lb);
4745
4746 return lb;
4747}
4748
4749/** returns the adjusted (i.e. rounded, if the given variable is of integral type) upper bound value;
4750 * does not change the bounds of the variable
4751 *
4752 * @return adjusted upper bound for the given variable; the bound of the variable is not changed
4753 *
4754 * @pre This method can be called if @p scip is in one of the following stages:
4755 * - \ref SCIP_STAGE_PROBLEM
4756 * - \ref SCIP_STAGE_TRANSFORMING
4757 * - \ref SCIP_STAGE_TRANSFORMED
4758 * - \ref SCIP_STAGE_INITPRESOLVE
4759 * - \ref SCIP_STAGE_PRESOLVING
4760 * - \ref SCIP_STAGE_EXITPRESOLVE
4761 * - \ref SCIP_STAGE_PRESOLVED
4762 * - \ref SCIP_STAGE_INITSOLVE
4763 * - \ref SCIP_STAGE_SOLVING
4764 * - \ref SCIP_STAGE_SOLVED
4765 * - \ref SCIP_STAGE_EXITSOLVE
4766 * - \ref SCIP_STAGE_FREETRANS
4767 */
4769 SCIP* scip, /**< SCIP data structure */
4770 SCIP_VAR* var, /**< variable to adjust the bound for */
4771 SCIP_Real ub /**< upper bound value to adjust */
4772 )
4773{
4774 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPadjustedVarUb", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
4775
4776 SCIPvarAdjustUb(var, scip->set, &ub);
4777
4778 return ub;
4779}
4780
4781/** depending on SCIP's stage, changes lower bound of variable in the problem, in preprocessing, or in current node;
4782 * if possible, adjusts bound to integral value; doesn't store any inference information in the bound change, such
4783 * that in conflict analysis, this change is treated like a branching decision
4784 *
4785 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4786 * SCIPgetVars()) gets resorted.
4787 *
4788 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4789 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4790 *
4791 * @pre This method can be called if @p scip is in one of the following stages:
4792 * - \ref SCIP_STAGE_PROBLEM
4793 * - \ref SCIP_STAGE_TRANSFORMING
4794 * - \ref SCIP_STAGE_PRESOLVING
4795 * - \ref SCIP_STAGE_SOLVING
4796 *
4797 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4798 */
4800 SCIP* scip, /**< SCIP data structure */
4801 SCIP_VAR* var, /**< variable to change the bound for */
4802 SCIP_Real newbound /**< new value for bound */
4803 )
4804{
4806
4807 SCIPvarAdjustLb(var, scip->set, &newbound);
4808
4809 /* ignore tightenings of lower bounds to +infinity during solving process */
4811 {
4812#ifndef NDEBUG
4813 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4814 SCIPvarGetLbLocal(var));
4815#endif
4816 return SCIP_OKAY;
4817 }
4818
4819 switch( scip->set->stage )
4820 {
4821 case SCIP_STAGE_PROBLEM:
4822 assert(!SCIPvarIsTransformed(var));
4823 SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
4824 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4825 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4826 SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4827 scip->branchcand, scip->eventqueue, newbound) );
4828 break;
4829
4832 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4833 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4834 break;
4835
4837 if( !SCIPinProbing(scip) )
4838 {
4839 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4840 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4841
4842 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4843 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable,
4844 var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
4845
4847 {
4848 SCIP_Bool infeasible;
4849
4850 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
4851 assert(!infeasible);
4852 }
4853 break;
4854 }
4855 /*lint -fallthrough*/
4856 case SCIP_STAGE_SOLVING:
4857 SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
4858 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4859 scip->cliquetable, var, newbound,
4861 break;
4862
4863 default:
4864 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4865 return SCIP_INVALIDCALL;
4866 } /*lint !e788*/
4867
4868 return SCIP_OKAY;
4869}
4870
4871/** depending on SCIP's stage, changes upper bound of variable in the problem, in preprocessing, or in current node;
4872 * if possible, adjusts bound to integral value; doesn't store any inference information in the bound change, such
4873 * that in conflict analysis, this change is treated like a branching decision
4874 *
4875 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4876 * SCIPgetVars()) gets resorted.
4877 *
4878 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4879 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4880 *
4881 * @pre This method can be called if @p scip is in one of the following stages:
4882 * - \ref SCIP_STAGE_PROBLEM
4883 * - \ref SCIP_STAGE_TRANSFORMING
4884 * - \ref SCIP_STAGE_PRESOLVING
4885 * - \ref SCIP_STAGE_SOLVING
4886 *
4887 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4888 */
4890 SCIP* scip, /**< SCIP data structure */
4891 SCIP_VAR* var, /**< variable to change the bound for */
4892 SCIP_Real newbound /**< new value for bound */
4893 )
4894{
4896
4897 SCIPvarAdjustUb(var, scip->set, &newbound);
4898
4899 /* ignore tightenings of upper bounds to -infinity during solving process */
4900 if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4901 {
4902#ifndef NDEBUG
4903 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
4904 SCIPvarGetUbLocal(var));
4905#endif
4906 return SCIP_OKAY;
4907 }
4908
4909 switch( scip->set->stage )
4910 {
4911 case SCIP_STAGE_PROBLEM:
4912 assert(!SCIPvarIsTransformed(var));
4913 SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
4914 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4915 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4916 SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4917 scip->branchcand, scip->eventqueue, newbound) );
4918 break;
4919
4922 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4923 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4924 break;
4925
4927 if( !SCIPinProbing(scip) )
4928 {
4929 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4930 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4931
4932 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4933 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4934 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
4935
4937 {
4938 SCIP_Bool infeasible;
4939
4940 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
4941 assert(!infeasible);
4942 }
4943 break;
4944 }
4945 /*lint -fallthrough*/
4946 case SCIP_STAGE_SOLVING:
4947 SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
4948 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4949 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
4950 break;
4951
4952 default:
4953 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4954 return SCIP_INVALIDCALL;
4955 } /*lint !e788*/
4956
4957 return SCIP_OKAY;
4958}
4959
4960/** changes lower bound of variable in the given node; if possible, adjust bound to integral value; doesn't store any
4961 * inference information in the bound change, such that in conflict analysis, this change is treated like a branching
4962 * decision
4963 *
4964 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4965 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4966 *
4967 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
4968 */
4970 SCIP* scip, /**< SCIP data structure */
4971 SCIP_NODE* node, /**< node to change bound at, or NULL for current node */
4972 SCIP_VAR* var, /**< variable to change the bound for */
4973 SCIP_Real newbound /**< new value for bound */
4974 )
4975{
4977
4978 if( node == NULL )
4979 {
4980 SCIP_CALL( SCIPchgVarLb(scip, var, newbound) );
4981 }
4982 else
4983 {
4984 SCIPvarAdjustLb(var, scip->set, &newbound);
4985
4986 /* ignore tightenings of lower bounds to +infinity during solving process */
4988 {
4989#ifndef NDEBUG
4990 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4991 SCIPvarGetLbLocal(var));
4992#endif
4993 return SCIP_OKAY;
4994 }
4995
4996 SCIP_CALL( SCIPnodeAddBoundchg(node, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
4997 scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4999 }
5000
5001 return SCIP_OKAY;
5002}
5003
5004/** changes upper bound of variable in the given node; if possible, adjust bound to integral value; doesn't store any
5005 * inference information in the bound change, such that in conflict analysis, this change is treated like a branching
5006 * decision
5007 *
5008 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5009 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5010 *
5011 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
5012 */
5014 SCIP* scip, /**< SCIP data structure */
5015 SCIP_NODE* node, /**< node to change bound at, or NULL for current node */
5016 SCIP_VAR* var, /**< variable to change the bound for */
5017 SCIP_Real newbound /**< new value for bound */
5018 )
5019{
5021
5022 if( node == NULL )
5023 {
5024 SCIP_CALL( SCIPchgVarUb(scip, var, newbound) );
5025 }
5026 else
5027 {
5028 SCIPvarAdjustUb(var, scip->set, &newbound);
5029
5030 /* ignore tightenings of upper bounds to -infinity during solving process */
5031 if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5032 {
5033#ifndef NDEBUG
5034 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5035 SCIPvarGetUbLocal(var));
5036#endif
5037 return SCIP_OKAY;
5038 }
5039
5040 SCIP_CALL( SCIPnodeAddBoundchg(node, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5041 scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5043 }
5044
5045 return SCIP_OKAY;
5046}
5047
5048/** changes global lower bound of variable; if possible, adjust bound to integral value; also tightens the local bound,
5049 * if the global bound is better than the local bound
5050 *
5051 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5052 * SCIPgetVars()) gets resorted.
5053 *
5054 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5055 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5056 *
5057 * @pre This method can be called if @p scip is in one of the following stages:
5058 * - \ref SCIP_STAGE_PROBLEM
5059 * - \ref SCIP_STAGE_TRANSFORMING
5060 * - \ref SCIP_STAGE_TRANSFORMED
5061 * - \ref SCIP_STAGE_PRESOLVING
5062 * - \ref SCIP_STAGE_SOLVING
5063 *
5064 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5065 */
5067 SCIP* scip, /**< SCIP data structure */
5068 SCIP_VAR* var, /**< variable to change the bound for */
5069 SCIP_Real newbound /**< new value for bound */
5070 )
5071{
5072 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbGlobal", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5073
5074 SCIPvarAdjustLb(var, scip->set, &newbound);
5075
5076 /* ignore tightenings of lower bounds to +infinity during solving process */
5078 {
5079#ifndef NDEBUG
5080 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
5081 SCIPvarGetLbLocal(var));
5082#endif
5083 return SCIP_OKAY;
5084 }
5085
5086 switch( scip->set->stage )
5087 {
5088 case SCIP_STAGE_PROBLEM:
5089 assert(!SCIPvarIsTransformed(var));
5090 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5091 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5092 SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5093 scip->branchcand, scip->eventqueue, newbound) );
5094 SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
5095 break;
5096
5099 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5100 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5101 break;
5102
5104 if( !SCIPinProbing(scip) )
5105 {
5106 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5107 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5108
5109 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5110 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5112
5114 {
5115 SCIP_Bool infeasible;
5116
5117 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
5118 assert(!infeasible);
5119 }
5120 break;
5121 }
5122 /*lint -fallthrough*/
5123 case SCIP_STAGE_SOLVING:
5124 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5125 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5127 break;
5128
5129 default:
5130 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5131 return SCIP_INVALIDCALL;
5132 } /*lint !e788*/
5133
5134 return SCIP_OKAY;
5135}
5136
5137/** changes global upper bound of variable; if possible, adjust bound to integral value; also tightens the local bound,
5138 * if the global bound is better than the local bound
5139 *
5140 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5141 * SCIPgetVars()) gets resorted.
5142 *
5143 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5144 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5145 *
5146 * @pre This method can be called if @p scip is in one of the following stages:
5147 * - \ref SCIP_STAGE_PROBLEM
5148 * - \ref SCIP_STAGE_TRANSFORMING
5149 * - \ref SCIP_STAGE_TRANSFORMED
5150 * - \ref SCIP_STAGE_PRESOLVING
5151 * - \ref SCIP_STAGE_SOLVING
5152 *
5153 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5154 */
5156 SCIP* scip, /**< SCIP data structure */
5157 SCIP_VAR* var, /**< variable to change the bound for */
5158 SCIP_Real newbound /**< new value for bound */
5159 )
5160{
5161 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbGlobal", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5162
5163 SCIPvarAdjustUb(var, scip->set, &newbound);
5164
5165 /* ignore tightenings of upper bounds to -infinity during solving process */
5166 if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5167 {
5168#ifndef NDEBUG
5169 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5170 SCIPvarGetUbLocal(var));
5171#endif
5172 return SCIP_OKAY;
5173 }
5174
5175 switch( scip->set->stage )
5176 {
5177 case SCIP_STAGE_PROBLEM:
5178 assert(!SCIPvarIsTransformed(var));
5179 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5180 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5181 SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5182 scip->branchcand, scip->eventqueue, newbound) );
5183 SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
5184 break;
5185
5188 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5189 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5190 break;
5191
5193 if( !SCIPinProbing(scip) )
5194 {
5195 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5196 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5197
5198 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5199 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5201
5203 {
5204 SCIP_Bool infeasible;
5205
5206 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
5207 assert(!infeasible);
5208 }
5209 break;
5210 }
5211 /*lint -fallthrough*/
5212 case SCIP_STAGE_SOLVING:
5213 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5214 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5216 break;
5217
5218 default:
5219 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5220 return SCIP_INVALIDCALL;
5221 } /*lint !e788*/
5222
5223 return SCIP_OKAY;
5224}
5225
5226/** changes lazy lower bound of the variable, this is only possible if the variable is not in the LP yet
5227 *
5228 * Lazy bounds are bounds that are already enforced by constraints and the objective function.
5229 * Setting a lazy lower bound has the consequence that for variables which lower bound equals the lazy lower bound,
5230 * the lower bound does not need to be passed on to the LP solver.
5231 * This is especially useful in a column generation (branch-and-price) setting.
5232 *
5233 * @attention If the variable has a global lower bound below lazylb, then the global lower bound is tightened to
5234 * lazylb by a call to SCIPchgVarLbGlobal().
5235 *
5236 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5237 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5238 *
5239 * @pre This method can be called if @p scip is in one of the following stages:
5240 * - \ref SCIP_STAGE_PROBLEM
5241 * - \ref SCIP_STAGE_TRANSFORMING
5242 * - \ref SCIP_STAGE_TRANSFORMED
5243 * - \ref SCIP_STAGE_PRESOLVING
5244 * - \ref SCIP_STAGE_SOLVING
5245 */
5247 SCIP* scip, /**< SCIP data structure */
5248 SCIP_VAR* var, /**< problem variable */
5249 SCIP_Real lazylb /**< the lazy lower bound to be set */
5250 )
5251{
5252 assert(scip != NULL);
5253 assert(var != NULL);
5254
5256
5257 if( SCIPisGT(scip, lazylb, SCIPvarGetLbGlobal(var)) )
5258 {
5259 SCIP_CALL( SCIPchgVarLbGlobal(scip, var, lazylb) );
5260 }
5261
5262 SCIP_CALL( SCIPvarChgLbLazy(var, scip->set, lazylb) );
5263
5264 return SCIP_OKAY;
5265}
5266
5267/** changes lazy upper bound of the variable, this is only possible if the variable is not in the LP yet
5268 *
5269 * Lazy bounds are bounds that are already enforced by constraints and the objective function.
5270 * Setting a lazy upper bound has the consequence that for variables which upper bound equals the lazy upper bound,
5271 * the upper bound does not need to be passed on to the LP solver.
5272 * This is especially useful in a column generation (branch-and-price) setting.
5273 *
5274 * @attention If the variable has a global upper bound above lazyub, then the global upper bound is tightened to
5275 * lazyub by a call to SCIPchgVarUbGlobal().
5276 *
5277 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5278 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5279 *
5280 * @pre This method can be called if @p scip is in one of the following stages:
5281 * - \ref SCIP_STAGE_PROBLEM
5282 * - \ref SCIP_STAGE_TRANSFORMING
5283 * - \ref SCIP_STAGE_TRANSFORMED
5284 * - \ref SCIP_STAGE_PRESOLVING
5285 * - \ref SCIP_STAGE_SOLVING
5286 */
5288 SCIP* scip, /**< SCIP data structure */
5289 SCIP_VAR* var, /**< problem variable */
5290 SCIP_Real lazyub /**< the lazy lower bound to be set */
5291 )
5292{
5293 assert(scip != NULL);
5294 assert(var != NULL);
5295
5297
5298 if( SCIPisLT(scip, lazyub, SCIPvarGetUbGlobal(var)) )
5299 {
5300 SCIP_CALL( SCIPchgVarUbGlobal(scip, var, lazyub) );
5301 }
5302
5303 SCIP_CALL( SCIPvarChgUbLazy(var, scip->set, lazyub) );
5304
5305 return SCIP_OKAY;
5306}
5307
5308/** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
5309 * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5310 * doesn't store any inference information in the bound change, such that in conflict analysis, this change
5311 * is treated like a branching decision
5312 *
5313 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5314 * SCIPgetVars()) gets resorted.
5315 *
5316 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5317 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5318 *
5319 * @pre This method can be called if @p scip is in one of the following stages:
5320 * - \ref SCIP_STAGE_PROBLEM
5321 * - \ref SCIP_STAGE_PRESOLVING
5322 * - \ref SCIP_STAGE_SOLVING
5323 *
5324 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5325 */
5327 SCIP* scip, /**< SCIP data structure */
5328 SCIP_VAR* var, /**< variable to change the bound for */
5329 SCIP_Real newbound, /**< new value for bound */
5330 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5331 SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
5332 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5333 )
5334{
5335 SCIP_Real lb;
5336 SCIP_Real ub;
5337
5338 assert(infeasible != NULL);
5339
5341 /** @todo if needed provide pending local/global bound changes that will be flushed after leaving diving mode (as in struct_tree.h) */
5343
5344 *infeasible = FALSE;
5345 if( tightened != NULL )
5346 *tightened = FALSE;
5347
5348 SCIPvarAdjustLb(var, scip->set, &newbound);
5349
5350 /* ignore tightenings of lower bounds to +infinity during solving process */
5352 {
5353#ifndef NDEBUG
5354 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
5355 SCIPvarGetLbLocal(var));
5356#endif
5357 return SCIP_OKAY;
5358 }
5359
5360 /* get current bounds */
5361 lb = SCIPcomputeVarLbLocal(scip, var);
5362 ub = SCIPcomputeVarUbLocal(scip, var);
5363 assert(SCIPsetIsLE(scip->set, lb, ub));
5364
5365 if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
5366 {
5367 *infeasible = TRUE;
5368 return SCIP_OKAY;
5369 }
5370 newbound = MIN(newbound, ub);
5371
5372 if( (force && SCIPsetIsLE(scip->set, newbound, lb)) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
5373 return SCIP_OKAY;
5374
5375 switch( scip->set->stage )
5376 {
5377 case SCIP_STAGE_PROBLEM:
5378 assert(!SCIPvarIsTransformed(var));
5379 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5380 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5381 SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5382 scip->branchcand, scip->eventqueue, newbound) );
5383 SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
5384 break;
5386 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5387 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5388 break;
5390 if( !SCIPinProbing(scip) )
5391 {
5392 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5393 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5394
5395 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5396 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5398
5400 {
5401 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5402 assert(!(*infeasible));
5403 }
5404 break;
5405 }
5406 /*lint -fallthrough*/
5407 case SCIP_STAGE_SOLVING:
5408 SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
5409 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable,
5410 var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
5411 break;
5412
5413 default:
5414 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5415 return SCIP_INVALIDCALL;
5416 } /*lint !e788*/
5417
5418 /* check whether the lower bound improved */
5419 if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
5420 *tightened = TRUE;
5421
5422 return SCIP_OKAY;
5423}
5424
5425/** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
5426 * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5427 * doesn't store any inference information in the bound change, such that in conflict analysis, this change
5428 * is treated like a branching decision
5429 *
5430 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5431 * SCIPgetVars()) gets resorted.
5432 *
5433 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5434 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5435 *
5436 * @pre This method can be called if @p scip is in one of the following stages:
5437 * - \ref SCIP_STAGE_PROBLEM
5438 * - \ref SCIP_STAGE_PRESOLVING
5439 * - \ref SCIP_STAGE_SOLVING
5440 *
5441 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5442 */
5444 SCIP* scip, /**< SCIP data structure */
5445 SCIP_VAR* var, /**< variable to change the bound for */
5446 SCIP_Real newbound, /**< new value for bound */
5447 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5448 SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
5449 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5450 )
5451{
5452 SCIP_Real lb;
5453 SCIP_Real ub;
5454
5455 assert(infeasible != NULL);
5457
5458 /** @todo if needed provide pending local/global bound changes that will be flushed after leaving diving mode (as in struct_tree.h) */
5460
5461 *infeasible = FALSE;
5462 if( tightened != NULL )
5463 *tightened = FALSE;
5464
5465 SCIPvarAdjustUb(var, scip->set, &newbound);
5466
5467 /* ignore tightenings of upper bounds to -infinity during solving process */
5468 if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5469 {
5470#ifndef NDEBUG
5471 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5472 SCIPvarGetUbLocal(var));
5473#endif
5474 return SCIP_OKAY;
5475 }
5476
5477 /* get current bounds */
5478 lb = SCIPcomputeVarLbLocal(scip, var);
5479 ub = SCIPcomputeVarUbLocal(scip, var);
5480 assert(SCIPsetIsLE(scip->set, lb, ub));
5481
5482 if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
5483 {
5484 *infeasible = TRUE;
5485 return SCIP_OKAY;
5486 }
5487 newbound = MAX(newbound, lb);
5488
5489 if( (force && SCIPsetIsGE(scip->set, newbound, ub)) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
5490 return SCIP_OKAY;
5491
5492 switch( scip->set->stage )
5493 {
5494 case SCIP_STAGE_PROBLEM:
5495 assert(!SCIPvarIsTransformed(var));
5496 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5497 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5498 SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5499 scip->branchcand, scip->eventqueue, newbound) );
5500 SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
5501 break;
5503 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5504 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5505 break;
5507 if( !SCIPinProbing(scip) )
5508 {
5509 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5510 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5511
5512 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5513 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5515
5517 {
5518 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5519 assert(!(*infeasible));
5520 }
5521 break;
5522 }
5523 /*lint -fallthrough*/
5524 case SCIP_STAGE_SOLVING:
5525 SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
5526 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5527 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
5528 break;
5529
5530 default:
5531 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5532 return SCIP_INVALIDCALL;
5533 } /*lint !e788*/
5534
5535 /* check whether the upper bound improved */
5536 if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
5537 *tightened = TRUE;
5538
5539 return SCIP_OKAY;
5540}
5541
5542/** fixes variable in preprocessing or in the current node, if the new bound is tighter (w.r.t. bound strengthening
5543 * epsilon) than the current bound; if possible, adjusts bound to integral value; the given inference constraint is
5544 * stored, such that the conflict analysis is able to find out the reason for the deduction of the bound change
5545 *
5546 * @note In presolving stage when not in probing mode the variable will be fixed directly, otherwise this method
5547 * changes first the lowerbound by calling SCIPinferVarLbCons and second the upperbound by calling
5548 * SCIPinferVarUbCons
5549 *
5550 * @note If SCIP is in presolving stage, it can happen that the internal variable array (which get be accessed via
5551 * SCIPgetVars()) gets resorted.
5552 *
5553 * @note During presolving, an integer variable which bound changes to {0,1} is upgraded to a binary variable.
5554 */
5556 SCIP* scip, /**< SCIP data structure */
5557 SCIP_VAR* var, /**< variable to change the bound for */
5558 SCIP_Real fixedval, /**< new value for fixation */
5559 SCIP_CONS* infercons, /**< constraint that deduced the bound change */
5560 int inferinfo, /**< user information for inference to help resolving the conflict */
5561 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5562 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5563 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5564 )
5565{
5566 assert(scip != NULL);
5567 assert(var != NULL);
5568 assert(infeasible != NULL);
5569
5570 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarFixCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5571
5572 if( tightened != NULL )
5573 *tightened = FALSE;
5574
5575 /* in presolving case we take the shortcut to directly fix the variables */
5577 {
5578 SCIP_Bool fixed;
5579
5580 SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5581 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter,
5582 scip->eventqueue, scip->cliquetable, fixedval, infeasible, &fixed) );
5583
5584 if( tightened != NULL )
5585 *tightened = fixed;
5586 }
5587 /* otherwise we use the lb and ub methods */
5588 else
5589 {
5590 SCIP_Bool lbtightened;
5591
5592 SCIP_CALL( SCIPinferVarLbCons(scip, var, fixedval, infercons, inferinfo, force, infeasible, &lbtightened) );
5593
5594 if( ! (*infeasible) )
5595 {
5596 SCIP_CALL( SCIPinferVarUbCons(scip, var, fixedval, infercons, inferinfo, force, infeasible, tightened) );
5597
5598 if( tightened != NULL )
5599 *tightened |= lbtightened;
5600 }
5601 }
5602
5603 return SCIP_OKAY;
5604}
5605
5606/** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
5607 * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5608 * the given inference constraint is stored, such that the conflict analysis is able to find out the reason
5609 * for the deduction of the bound change
5610 *
5611 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5612 * SCIPgetVars()) gets resorted.
5613 *
5614 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5615 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5616 *
5617 * @pre This method can be called if @p scip is in one of the following stages:
5618 * - \ref SCIP_STAGE_PROBLEM
5619 * - \ref SCIP_STAGE_PRESOLVING
5620 * - \ref SCIP_STAGE_SOLVING
5621 *
5622 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5623 */
5625 SCIP* scip, /**< SCIP data structure */
5626 SCIP_VAR* var, /**< variable to change the bound for */
5627 SCIP_Real newbound, /**< new value for bound */
5628 SCIP_CONS* infercons, /**< constraint that deduced the bound change */
5629 int inferinfo, /**< user information for inference to help resolving the conflict */
5630 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5631 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5632 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5633 )
5634{
5635 SCIP_Real lb;
5636 SCIP_Real ub;
5637
5638 assert(infeasible != NULL);
5639
5640 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarLbCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5641
5642 *infeasible = FALSE;
5643 if( tightened != NULL )
5644 *tightened = FALSE;
5645
5646 SCIPvarAdjustLb(var, scip->set, &newbound);
5647
5648 /* get current bounds */
5649 lb = SCIPvarGetLbLocal(var);
5650 ub = SCIPvarGetUbLocal(var);
5651 assert(SCIPsetIsLE(scip->set, lb, ub));
5652
5653 if( SCIPisInfinity(scip, newbound) || SCIPisFeasGT(scip, newbound, ub) )
5654 {
5655 *infeasible = TRUE;
5656 return SCIP_OKAY;
5657 }
5658
5659 newbound = MIN(newbound, ub);
5660
5661 if( (force && SCIPsetIsLE(scip->set, newbound, lb)) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
5662 return SCIP_OKAY;
5663
5664 switch( scip->set->stage )
5665 {
5666 case SCIP_STAGE_PROBLEM:
5667 assert(!SCIPvarIsTransformed(var));
5668 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5669 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5670 SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5671 scip->branchcand, scip->eventqueue, newbound) );
5672 SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
5673 break;
5674
5676 if( !SCIPinProbing(scip) )
5677 {
5678 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5679 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5680
5681 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5682 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5684
5686 {
5687 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5688 assert(!(*infeasible));
5689 }
5690 break;
5691 }
5692 /*lint -fallthrough*/
5693 case SCIP_STAGE_SOLVING:
5694 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
5695 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5696 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, infercons, NULL, inferinfo, FALSE) );
5697 break;
5698
5699 default:
5700 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5701 return SCIP_INVALIDCALL;
5702 } /*lint !e788*/
5703
5704 /* check whether the lower bound improved */
5705 if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
5706 *tightened = TRUE;
5707
5708 return SCIP_OKAY;
5709}
5710
5711/** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
5712 * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5713 * the given inference constraint is stored, such that the conflict analysis is able to find out the reason
5714 * for the deduction of the bound change
5715 *
5716 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5717 * SCIPgetVars()) gets resorted.
5718 *
5719 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5720 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5721 *
5722 * @pre This method can be called if @p scip is in one of the following stages:
5723 * - \ref SCIP_STAGE_PROBLEM
5724 * - \ref SCIP_STAGE_PRESOLVING
5725 * - \ref SCIP_STAGE_SOLVING
5726 *
5727 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5728 */
5730 SCIP* scip, /**< SCIP data structure */
5731 SCIP_VAR* var, /**< variable to change the bound for */
5732 SCIP_Real newbound, /**< new value for bound */
5733 SCIP_CONS* infercons, /**< constraint that deduced the bound change */
5734 int inferinfo, /**< user information for inference to help resolving the conflict */
5735 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5736 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5737 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5738 )
5739{
5740 SCIP_Real lb;
5741 SCIP_Real ub;
5742
5743 assert(infeasible != NULL);
5744
5745 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarUbCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5746
5747 *infeasible = FALSE;
5748 if( tightened != NULL )
5749 *tightened = FALSE;
5750
5751 SCIPvarAdjustUb(var, scip->set, &newbound);
5752
5753 /* get current bounds */
5754 lb = SCIPvarGetLbLocal(var);
5755 ub = SCIPvarGetUbLocal(var);
5756 assert(SCIPsetIsLE(scip->set, lb, ub));
5757
5758 if( SCIPisInfinity(scip, -newbound) || SCIPisFeasLT(scip, newbound, lb) )
5759 {
5760 *infeasible = TRUE;
5761 return SCIP_OKAY;
5762 }
5763
5764 newbound = MAX(newbound, lb);
5765
5766 if( (force && SCIPsetIsGE(scip->set, newbound, ub)) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
5767 return SCIP_OKAY;
5768
5769 switch( scip->set->stage )
5770 {
5771 case SCIP_STAGE_PROBLEM:
5772 assert(!SCIPvarIsTransformed(var));
5773 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5774 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5775 SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5776 scip->branchcand, scip->eventqueue, newbound) );
5777 SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
5778 break;
5779
5781 if( !SCIPinProbing(scip) )
5782 {
5783 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5784 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5785
5786 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5787 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5789
5791 {
5792 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5793 assert(!(*infeasible));
5794 }
5795 break;
5796 }
5797 /*lint -fallthrough*/
5798 case SCIP_STAGE_SOLVING:
5799 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
5800 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5801 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, infercons, NULL, inferinfo, FALSE) );
5802 break;
5803
5804 default:
5805 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5806 return SCIP_INVALIDCALL;
5807 } /*lint !e788*/
5808
5809 /* check whether the upper bound improved */
5810 if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
5811 *tightened = TRUE;
5812
5813 return SCIP_OKAY;
5814}
5815
5816/** depending on SCIP's stage, fixes binary variable in the problem, in preprocessing, or in current node;
5817 * the given inference constraint is stored, such that the conflict analysis is able to find out the reason for the
5818 * deduction of the fixing
5819 *
5820 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5821 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5822 *
5823 * @pre This method can be called if @p scip is in one of the following stages:
5824 * - \ref SCIP_STAGE_PROBLEM
5825 * - \ref SCIP_STAGE_PRESOLVING
5826 * - \ref SCIP_STAGE_SOLVING
5827 */
5829 SCIP* scip, /**< SCIP data structure */
5830 SCIP_VAR* var, /**< binary variable to fix */
5831 SCIP_Bool fixedval, /**< value to fix binary variable to */
5832 SCIP_CONS* infercons, /**< constraint that deduced the fixing */
5833 int inferinfo, /**< user information for inference to help resolving the conflict */
5834 SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
5835 SCIP_Bool* tightened /**< pointer to store whether the fixing tightened the local bounds, or NULL */
5836 )
5837{
5838 SCIP_Real lb;
5839 SCIP_Real ub;
5840
5841 assert(SCIPvarIsBinary(var));
5842 assert(fixedval == TRUE || fixedval == FALSE);
5843 assert(infeasible != NULL);
5844
5845 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferBinvarCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5846
5847 *infeasible = FALSE;
5848 if( tightened != NULL )
5849 *tightened = FALSE;
5850
5851 /* get current bounds */
5852 lb = SCIPvarGetLbLocal(var);
5853 ub = SCIPvarGetUbLocal(var);
5854 assert(SCIPsetIsEQ(scip->set, lb, 0.0) || SCIPsetIsEQ(scip->set, lb, 1.0));
5855 assert(SCIPsetIsEQ(scip->set, ub, 0.0) || SCIPsetIsEQ(scip->set, ub, 1.0));
5856 assert(SCIPsetIsLE(scip->set, lb, ub));
5857
5858 /* check, if variable is already fixed */
5859 if( (lb > 0.5) || (ub < 0.5) )
5860 {
5861 *infeasible = (fixedval == (lb < 0.5));
5862
5863 return SCIP_OKAY;
5864 }
5865
5866 /* apply the fixing */
5867 switch( scip->set->stage )
5868 {
5869 case SCIP_STAGE_PROBLEM:
5870 assert(!SCIPvarIsTransformed(var));
5871 if( fixedval == TRUE )
5872 {
5873 SCIP_CALL( SCIPchgVarLb(scip, var, 1.0) );
5874 }
5875 else
5876 {
5877 SCIP_CALL( SCIPchgVarUb(scip, var, 0.0) );
5878 }
5879 break;
5880
5882 if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
5883 {
5884 SCIP_Bool fixed;
5885
5886 SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5887 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
5888 scip->cliquetable, (SCIP_Real)fixedval, infeasible, &fixed) );
5889 break;
5890 }
5891 /*lint -fallthrough*/
5892 case SCIP_STAGE_SOLVING:
5893 if( fixedval == TRUE )
5894 {
5895 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
5896 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5897 scip->cliquetable, var, 1.0, SCIP_BOUNDTYPE_LOWER, infercons, NULL, inferinfo, FALSE) );
5898 }
5899 else
5900 {
5901 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
5902 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5903 scip->cliquetable, var, 0.0, SCIP_BOUNDTYPE_UPPER, infercons, NULL, inferinfo, FALSE) );
5904 }
5905 break;
5906
5907 default:
5908 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5909 return SCIP_INVALIDCALL;
5910 } /*lint !e788*/
5911
5912 if( tightened != NULL )
5913 *tightened = TRUE;
5914
5915 return SCIP_OKAY;
5916}
5917
5918/** fixes variable in preprocessing or in the current node, if the new bound is tighter (w.r.t. bound strengthening
5919 * epsilon) than the current bound; if possible, adjusts bound to integral value; the given inference constraint is
5920 * stored, such that the conflict analysis is able to find out the reason for the deduction of the bound change
5921 *
5922 * @note In presolving stage when not in probing mode the variable will be fixed directly, otherwise this method
5923 * changes first the lowerbound by calling SCIPinferVarLbProp and second the upperbound by calling
5924 * SCIPinferVarUbProp
5925 *
5926 * @note If SCIP is in presolving stage, it can happen that the internal variable array (which get be accessed via
5927 * SCIPgetVars()) gets resorted.
5928 *
5929 * @note During presolving, an integer variable which bound changes to {0,1} is upgraded to a binary variable.
5930 */
5932 SCIP* scip, /**< SCIP data structure */
5933 SCIP_VAR* var, /**< variable to change the bound for */
5934 SCIP_Real fixedval, /**< new value for fixation */
5935 SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
5936 int inferinfo, /**< user information for inference to help resolving the conflict */
5937 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5938 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5939 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5940 )
5941{
5942 assert(scip != NULL);
5943 assert(var != NULL);
5944 assert(infeasible != NULL);
5945
5946 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarFixProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5947
5948 if( tightened != NULL )
5949 *tightened = FALSE;
5950
5951 /* in presolving case we take the shortcut to directly fix the variables */
5953 {
5954 SCIP_Bool fixed;
5955
5956 SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5957 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
5958 scip->cliquetable, fixedval, infeasible, &fixed) );
5959
5960 if( tightened != NULL )
5961 *tightened = fixed;
5962 }
5963 /* otherwise we use the lb and ub methods */
5964 else
5965 {
5966 SCIP_Bool lbtightened;
5967
5968 SCIP_CALL( SCIPinferVarLbProp(scip, var, fixedval, inferprop, inferinfo, force, infeasible, &lbtightened) );
5969
5970 if( ! (*infeasible) )
5971 {
5972 SCIP_CALL( SCIPinferVarUbProp(scip, var, fixedval, inferprop, inferinfo, force, infeasible, tightened) );
5973
5974 if( tightened != NULL )
5975 *tightened |= lbtightened;
5976 }
5977 }
5978
5979 return SCIP_OKAY;
5980}
5981
5982/** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
5983 * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5984 * the given inference propagator is stored, such that the conflict analysis is able to find out the reason
5985 * for the deduction of the bound change
5986 *
5987 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5988 * SCIPgetVars()) gets resorted.
5989 *
5990 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5991 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5992 *
5993 * @pre This method can be called if @p scip is in one of the following stages:
5994 * - \ref SCIP_STAGE_PROBLEM
5995 * - \ref SCIP_STAGE_PRESOLVING
5996 * - \ref SCIP_STAGE_SOLVING
5997 *
5998 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5999 */
6001 SCIP* scip, /**< SCIP data structure */
6002 SCIP_VAR* var, /**< variable to change the bound for */
6003 SCIP_Real newbound, /**< new value for bound */
6004 SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
6005 int inferinfo, /**< user information for inference to help resolving the conflict */
6006 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6007 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
6008 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6009 )
6010{
6011 SCIP_Real lb;
6012 SCIP_Real ub;
6013
6014 assert(infeasible != NULL);
6015
6016 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarLbProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6017
6018 *infeasible = FALSE;
6019 if( tightened != NULL )
6020 *tightened = FALSE;
6021
6022 SCIPvarAdjustLb(var, scip->set, &newbound);
6023
6024 /* ignore tightenings of lower bounds to +infinity during solving process */
6026 {
6027#ifndef NDEBUG
6028 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
6029 SCIPvarGetLbLocal(var));
6030#endif
6031 return SCIP_OKAY;
6032 }
6033
6034 /* get current bounds */
6035 lb = SCIPvarGetLbLocal(var);
6036 ub = SCIPvarGetUbLocal(var);
6037 assert(SCIPsetIsLE(scip->set, lb, ub));
6038
6039 if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
6040 {
6041 *infeasible = TRUE;
6042 return SCIP_OKAY;
6043 }
6044 newbound = MIN(newbound, ub);
6045
6046 if( (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub))
6047 || SCIPsetIsLE(scip->set, newbound, lb) )
6048 return SCIP_OKAY;
6049
6050 switch( scip->set->stage )
6051 {
6052 case SCIP_STAGE_PROBLEM:
6053 assert(!SCIPvarIsTransformed(var));
6054 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6055 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6056 SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6057 scip->branchcand, scip->eventqueue, newbound) );
6058 SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
6059 break;
6060
6062 if( !SCIPinProbing(scip) )
6063 {
6064 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6065 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6066
6067 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6068 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6070
6072 {
6073 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6074 assert(!(*infeasible));
6075 }
6076 break;
6077 }
6078 /*lint -fallthrough*/
6079 case SCIP_STAGE_SOLVING:
6080 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
6081 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
6082 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, NULL, inferprop, inferinfo, FALSE) );
6083 break;
6084
6085 default:
6086 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6087 return SCIP_INVALIDCALL;
6088 } /*lint !e788*/
6089
6090 /* check whether the lower bound improved */
6091 if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
6092 *tightened = TRUE;
6093
6094 return SCIP_OKAY;
6095}
6096
6097/** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
6098 * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
6099 * the given inference propagator is stored, such that the conflict analysis is able to find out the reason
6100 * for the deduction of the bound change
6101 *
6102 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6103 * SCIPgetVars()) gets resorted.
6104 *
6105 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6106 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6107 *
6108 * @pre This method can be called if @p scip is in one of the following stages:
6109 * - \ref SCIP_STAGE_PROBLEM
6110 * - \ref SCIP_STAGE_PRESOLVING
6111 * - \ref SCIP_STAGE_SOLVING
6112 *
6113 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6114 */
6116 SCIP* scip, /**< SCIP data structure */
6117 SCIP_VAR* var, /**< variable to change the bound for */
6118 SCIP_Real newbound, /**< new value for bound */
6119 SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
6120 int inferinfo, /**< user information for inference to help resolving the conflict */
6121 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6122 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
6123 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6124 )
6125{
6126 SCIP_Real lb;
6127 SCIP_Real ub;
6128
6129 assert(infeasible != NULL);
6130
6131 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarUbProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6132
6133 *infeasible = FALSE;
6134 if( tightened != NULL )
6135 *tightened = FALSE;
6136
6137 SCIPvarAdjustUb(var, scip->set, &newbound);
6138
6139 /* ignore tightenings of upper bounds to -infinity during solving process */
6140 if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6141 {
6142#ifndef NDEBUG
6143 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
6144 SCIPvarGetUbLocal(var));
6145#endif
6146 return SCIP_OKAY;
6147 }
6148
6149 /* get current bounds */
6150 lb = SCIPvarGetLbLocal(var);
6151 ub = SCIPvarGetUbLocal(var);
6152 assert(SCIPsetIsLE(scip->set, lb, ub));
6153
6154 if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
6155 {
6156 *infeasible = TRUE;
6157 return SCIP_OKAY;
6158 }
6159 newbound = MAX(newbound, lb);
6160
6161 if( (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub))
6162 || SCIPsetIsGE(scip->set, newbound, ub) )
6163 return SCIP_OKAY;
6164
6165 switch( scip->set->stage )
6166 {
6167 case SCIP_STAGE_PROBLEM:
6168 assert(!SCIPvarIsTransformed(var));
6169 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6170 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6171 SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6172 scip->branchcand, scip->eventqueue, newbound) );
6173 SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
6174 break;
6175
6177 if( !SCIPinProbing(scip) )
6178 {
6179 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6180 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6181
6182 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6183 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6185
6187 {
6188 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6189 assert(!(*infeasible));
6190 }
6191 break;
6192 }
6193 /*lint -fallthrough*/
6194 case SCIP_STAGE_SOLVING:
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,
6197 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, NULL, inferprop, inferinfo, FALSE) );
6198 break;
6199
6200 default:
6201 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6202 return SCIP_INVALIDCALL;
6203 } /*lint !e788*/
6204
6205 /* check whether the upper bound improved */
6206 if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
6207 *tightened = TRUE;
6208
6209 return SCIP_OKAY;
6210}
6211
6212/** depending on SCIP's stage, fixes binary variable in the problem, in preprocessing, or in current node;
6213 * the given inference propagator is stored, such that the conflict analysis is able to find out the reason for the
6214 * deduction of the fixing
6215 *
6216 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6217 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6218 *
6219 * @pre This method can be called if @p scip is in one of the following stages:
6220 * - \ref SCIP_STAGE_PROBLEM
6221 * - \ref SCIP_STAGE_PRESOLVING
6222 * - \ref SCIP_STAGE_PRESOLVED
6223 * - \ref SCIP_STAGE_SOLVING
6224 */
6226 SCIP* scip, /**< SCIP data structure */
6227 SCIP_VAR* var, /**< binary variable to fix */
6228 SCIP_Bool fixedval, /**< value to fix binary variable to */
6229 SCIP_PROP* inferprop, /**< propagator that deduced the fixing */
6230 int inferinfo, /**< user information for inference to help resolving the conflict */
6231 SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
6232 SCIP_Bool* tightened /**< pointer to store whether the fixing tightened the local bounds, or NULL */
6233 )
6234{
6235 SCIP_Real lb;
6236 SCIP_Real ub;
6237
6238 assert(SCIPvarIsBinary(var));
6239 assert(fixedval == TRUE || fixedval == FALSE);
6240 assert(infeasible != NULL);
6241
6242 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferBinvarProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6243
6244 *infeasible = FALSE;
6245 if( tightened != NULL )
6246 *tightened = FALSE;
6247
6248 /* get current bounds */
6249 lb = SCIPvarGetLbLocal(var);
6250 ub = SCIPvarGetUbLocal(var);
6251 assert(SCIPsetIsEQ(scip->set, lb, 0.0) || SCIPsetIsEQ(scip->set, lb, 1.0));
6252 assert(SCIPsetIsEQ(scip->set, ub, 0.0) || SCIPsetIsEQ(scip->set, ub, 1.0));
6253 assert(SCIPsetIsLE(scip->set, lb, ub));
6254
6255 /* check, if variable is already fixed */
6256 if( (lb > 0.5) || (ub < 0.5) )
6257 {
6258 *infeasible = (fixedval == (lb < 0.5));
6259
6260 return SCIP_OKAY;
6261 }
6262
6263 /* apply the fixing */
6264 switch( scip->set->stage )
6265 {
6266 case SCIP_STAGE_PROBLEM:
6267 assert(!SCIPvarIsTransformed(var));
6268 if( fixedval == TRUE )
6269 {
6270 SCIP_CALL( SCIPchgVarLb(scip, var, 1.0) );
6271 }
6272 else
6273 {
6274 SCIP_CALL( SCIPchgVarUb(scip, var, 0.0) );
6275 }
6276 break;
6277
6279 if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
6280 {
6281 SCIP_Bool fixed;
6282
6283 SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6284 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
6285 scip->cliquetable, (SCIP_Real)fixedval, infeasible, &fixed) );
6286 break;
6287 }
6288 /*lint -fallthrough*/
6289 case SCIP_STAGE_SOLVING:
6290 if( fixedval == TRUE )
6291 {
6292 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
6293 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, 1.0,
6294 SCIP_BOUNDTYPE_LOWER, NULL, inferprop, inferinfo, FALSE) );
6295 }
6296 else
6297 {
6298 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
6299 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, 0.0,
6300 SCIP_BOUNDTYPE_UPPER, NULL, inferprop, inferinfo, FALSE) );
6301 }
6302 break;
6303
6304 default:
6305 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6306 return SCIP_INVALIDCALL;
6307 } /*lint !e788*/
6308
6309 if( tightened != NULL )
6310 *tightened = TRUE;
6311
6312 return SCIP_OKAY;
6313}
6314
6315/** changes global lower bound of variable in preprocessing or in the current node, if the new bound is tighter
6316 * (w.r.t. bound strengthening epsilon) than the current global bound; if possible, adjusts bound to integral value;
6317 * also tightens the local bound, if the global bound is better than the local bound
6318 *
6319 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6320 * SCIPgetVars()) gets resorted.
6321 *
6322 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6323 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6324 *
6325 * @pre This method can be called if @p scip is in one of the following stages:
6326 * - \ref SCIP_STAGE_PROBLEM
6327 * - \ref SCIP_STAGE_TRANSFORMING
6328 * - \ref SCIP_STAGE_PRESOLVING
6329 * - \ref SCIP_STAGE_SOLVING
6330 *
6331 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6332 */
6334 SCIP* scip, /**< SCIP data structure */
6335 SCIP_VAR* var, /**< variable to change the bound for */
6336 SCIP_Real newbound, /**< new value for bound */
6337 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6338 SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
6339 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6340 )
6341{
6342 SCIP_Real lb;
6343 SCIP_Real ub;
6344
6345 assert(infeasible != NULL);
6346
6347 SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarLbGlobal", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6348
6349 *infeasible = FALSE;
6350 if( tightened != NULL )
6351 *tightened = FALSE;
6352
6353 SCIPvarAdjustLb(var, scip->set, &newbound);
6354
6355 /* ignore tightenings of lower bounds to +infinity during solving process */
6357 {
6358#ifndef NDEBUG
6359 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
6360 SCIPvarGetLbLocal(var));
6361#endif
6362 return SCIP_OKAY;
6363 }
6364
6365 /* get current bounds */
6366 lb = SCIPvarGetLbGlobal(var);
6367 ub = SCIPvarGetUbGlobal(var);
6368 assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPsetIsLE(scip->set, lb, ub));
6369
6370 if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
6371 {
6372 *infeasible = TRUE;
6373 return SCIP_OKAY;
6374 }
6375 newbound = MIN(newbound, ub);
6376
6377 /* bound changes of less than epsilon are ignored by SCIPvarChgLb or raise an assert in SCIPnodeAddBoundinfer,
6378 * so don't apply them even if force is set
6379 */
6380 if( SCIPsetIsEQ(scip->set, lb, newbound) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
6381 return SCIP_OKAY;
6382
6383 switch( scip->set->stage )
6384 {
6385 case SCIP_STAGE_PROBLEM:
6386 assert(!SCIPvarIsTransformed(var));
6387 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6388 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6389 SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6390 scip->branchcand, scip->eventqueue, newbound) );
6391 SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
6392 break;
6393
6395 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6396 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6397 break;
6398
6400 if( !SCIPinProbing(scip) )
6401 {
6402 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6403 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6404
6405 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6406 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6408
6410 {
6411 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6412 assert(!(*infeasible));
6413 }
6414 break;
6415 }
6416 /*lint -fallthrough*/
6417 case SCIP_STAGE_SOLVING:
6418 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6419 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6421 break;
6422
6423 default:
6424 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6425 return SCIP_INVALIDCALL;
6426 } /*lint !e788*/
6427
6428 /* coverity: unreachable code */
6429 if( tightened != NULL && lb < SCIPcomputeVarLbGlobal(scip, var) )
6430 *tightened = TRUE;
6431
6432 return SCIP_OKAY;
6433}
6434
6435/** changes global upper bound of variable in preprocessing or in the current node, if the new bound is tighter
6436 * (w.r.t. bound strengthening epsilon) than the current global bound; if possible, adjusts bound to integral value;
6437 * also tightens the local bound, if the global bound is better than the local bound
6438 *
6439 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6440 * SCIPgetVars()) gets resorted.
6441 *
6442 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6443 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6444 *
6445 * @pre This method can be called if @p scip is in one of the following stages:
6446 * - \ref SCIP_STAGE_PROBLEM
6447 * - \ref SCIP_STAGE_TRANSFORMING
6448 * - \ref SCIP_STAGE_PRESOLVING
6449 * - \ref SCIP_STAGE_SOLVING
6450 *
6451 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6452 */
6454 SCIP* scip, /**< SCIP data structure */
6455 SCIP_VAR* var, /**< variable to change the bound for */
6456 SCIP_Real newbound, /**< new value for bound */
6457 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6458 SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
6459 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6460 )
6461{
6462 SCIP_Real lb;
6463 SCIP_Real ub;
6464
6465 assert(infeasible != NULL);
6466
6467 SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarUbGlobal", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6468
6469 *infeasible = FALSE;
6470 if( tightened != NULL )
6471 *tightened = FALSE;
6472
6473 SCIPvarAdjustUb(var, scip->set, &newbound);
6474
6475 /* ignore tightenings of upper bounds to -infinity during solving process */
6476 if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6477 {
6478#ifndef NDEBUG
6479 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
6480 SCIPvarGetUbLocal(var));
6481#endif
6482 return SCIP_OKAY;
6483 }
6484
6485 /* get current bounds */
6486 lb = SCIPvarGetLbGlobal(var);
6487 ub = SCIPvarGetUbGlobal(var);
6488 assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPsetIsLE(scip->set, lb, ub));
6489
6490 if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
6491 {
6492 *infeasible = TRUE;
6493 return SCIP_OKAY;
6494 }
6495 newbound = MAX(newbound, lb);
6496
6497 /* bound changes of less than epsilon are ignored by SCIPvarChgUb or raise an assert in SCIPnodeAddBoundinfer,
6498 * so don't apply them even if force is set
6499 */
6500 if( SCIPsetIsEQ(scip->set, ub, newbound) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
6501 return SCIP_OKAY;
6502
6503 switch( scip->set->stage )
6504 {
6505 case SCIP_STAGE_PROBLEM:
6506 assert(!SCIPvarIsTransformed(var));
6507 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6508 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6509 SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6510 scip->branchcand, scip->eventqueue, newbound) );
6511 SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
6512 break;
6513
6515 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6516 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6517 break;
6518
6520 if( !SCIPinProbing(scip) )
6521 {
6522 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6523 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6524
6525 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6526 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6528
6530 {
6531 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6532 assert(!(*infeasible));
6533 }
6534 break;
6535 }
6536 /*lint -fallthrough*/
6537 case SCIP_STAGE_SOLVING:
6538 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6539 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6541 break;
6542
6543 default:
6544 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6545 return SCIP_INVALIDCALL;
6546 } /*lint !e788*/
6547
6548 /* coverity: unreachable code */
6549 if( tightened != NULL && ub > SCIPcomputeVarUbGlobal(scip, var) )
6550 *tightened = TRUE;
6551
6552 return SCIP_OKAY;
6553}
6554
6555/* some simple variable functions implemented as defines */
6556#undef SCIPcomputeVarLbGlobal
6557#undef SCIPcomputeVarUbGlobal
6558#undef SCIPcomputeVarLbLocal
6559#undef SCIPcomputeVarUbLocal
6560
6561/** for a multi-aggregated variable, returns the global lower bound computed by adding the global bounds from all aggregation variables
6562 *
6563 * 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
6564 * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetLbGlobal.
6565 *
6566 * @return the global lower bound computed by adding the global bounds from all aggregation variables
6567 */
6569 SCIP* scip, /**< SCIP data structure */
6570 SCIP_VAR* var /**< variable to compute the bound for */
6571 )
6572{
6573 assert(scip != NULL);
6574 assert(var != NULL);
6575
6577 return SCIPvarGetMultaggrLbGlobal(var, scip->set);
6578 else
6579 return SCIPvarGetLbGlobal(var);
6580}
6581
6582/** for a multi-aggregated variable, returns the global upper bound computed by adding the global bounds from all aggregation variables
6583 *
6584 * 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
6585 * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetUbGlobal
6586 *
6587 * @return the global upper bound computed by adding the global bounds from all aggregation variables
6588 */
6590 SCIP* scip, /**< SCIP data structure */
6591 SCIP_VAR* var /**< variable to compute the bound for */
6592 )
6593{
6594 assert(scip != NULL);
6595 assert(var != NULL);
6596
6598 return SCIPvarGetMultaggrUbGlobal(var, scip->set);
6599 else
6600 return SCIPvarGetUbGlobal(var);
6601}
6602
6603/** for a multi-aggregated variable, returns the local lower bound computed by adding the local bounds from all aggregation variables
6604 *
6605 * 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
6606 * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetLbLocal.
6607 *
6608 * @return the local lower bound computed by adding the global bounds from all aggregation variables
6609 */
6611 SCIP* scip, /**< SCIP data structure */
6612 SCIP_VAR* var /**< variable to compute the bound for */
6613 )
6614{
6615 assert(scip != NULL);
6616 assert(var != NULL);
6617
6619 return SCIPvarGetMultaggrLbLocal(var, scip->set);
6620 else
6621 return SCIPvarGetLbLocal(var);
6622}
6623
6624/** for a multi-aggregated variable, returns the local upper bound computed by adding the local bounds from all aggregation variables
6625 *
6626 * 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
6627 * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetUbLocal.
6628 *
6629 * @return the local upper bound computed by adding the global bounds from all aggregation variables
6630 */
6632 SCIP* scip, /**< SCIP data structure */
6633 SCIP_VAR* var /**< variable to compute the bound for */
6634 )
6635{
6636 assert(scip != NULL);
6637 assert(var != NULL);
6638
6640 return SCIPvarGetMultaggrUbLocal(var, scip->set);
6641 else
6642 return SCIPvarGetUbLocal(var);
6643}
6644
6645/** for a multi-aggregated variable, gives the global lower bound computed by adding the global bounds from all
6646 * aggregation variables, this global bound may be tighter than the one given by SCIPvarGetLbGlobal, since the latter is
6647 * not updated if bounds of aggregation variables are changing
6648 *
6649 * calling this function for a non-multi-aggregated variable is not allowed
6650 */
6652 SCIP* scip, /**< SCIP data structure */
6653 SCIP_VAR* var /**< variable to compute the bound for */
6654 )
6655{
6657 return SCIPvarGetMultaggrLbGlobal(var, scip->set);
6658}
6659
6660/** for a multi-aggregated variable, gives the global upper bound computed by adding the global bounds from all
6661 * aggregation variables, this upper bound may be tighter than the one given by SCIPvarGetUbGlobal, since the latter is
6662 * not updated if bounds of aggregation variables are changing
6663 *
6664 * calling this function for a non-multi-aggregated variable is not allowed
6665 */
6667 SCIP* scip, /**< SCIP data structure */
6668 SCIP_VAR* var /**< variable to compute the bound for */
6669 )
6670{
6672 return SCIPvarGetMultaggrUbGlobal(var, scip->set);
6673}
6674
6675/** for a multi-aggregated variable, gives the local lower bound computed by adding the local bounds from all
6676 * aggregation variables, this lower bound may be tighter than the one given by SCIPvarGetLbLocal, since the latter is
6677 * not updated if bounds of aggregation variables are changing
6678 *
6679 * calling this function for a non-multi-aggregated variable is not allowed
6680 */
6682 SCIP* scip, /**< SCIP data structure */
6683 SCIP_VAR* var /**< variable to compute the bound for */
6684 )
6685{
6687 return SCIPvarGetMultaggrLbLocal(var, scip->set);
6688}
6689
6690/** for a multi-aggregated variable, gives the local upper bound computed by adding the local bounds from all
6691 * aggregation variables, this upper bound may be tighter than the one given by SCIPvarGetUbLocal, since the latter is
6692 * not updated if bounds of aggregation variables are changing
6693 *
6694 * calling this function for a non-multi-aggregated variable is not allowed
6695 */
6697 SCIP* scip, /**< SCIP data structure */
6698 SCIP_VAR* var /**< variable to compute the bound for */
6699 )
6700{
6702 return SCIPvarGetMultaggrUbLocal(var, scip->set);
6703}
6704
6705/** returns solution value and index of variable lower bound that is closest to the variable's value in the given primal
6706 * solution or current LP solution if no primal solution is given; returns an index of -1 if no variable lower bound is
6707 * available
6708 *
6709 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6710 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6711 *
6712 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
6713 */
6715 SCIP* scip, /**< SCIP data structure */
6716 SCIP_VAR* var, /**< active problem variable */
6717 SCIP_SOL* sol, /**< primal solution, or NULL for LP solution */
6718 SCIP_Real* closestvlb, /**< pointer to store the value of the closest variable lower bound */
6719 int* closestvlbidx /**< pointer to store the index of the closest variable lower bound */
6720 )
6721{
6722 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarClosestVlb", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6723
6724 SCIPvarGetClosestVlb(var, sol, scip->set, scip->stat, closestvlb, closestvlbidx);
6725
6726 return SCIP_OKAY;
6727}
6728
6729/** returns solution value and index of variable upper bound that is closest to the variable's value in the given primal solution;
6730 * or current LP solution if no primal solution is given; returns an index of -1 if no variable upper bound is available
6731 *
6732 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6733 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6734 *
6735 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
6736 */
6738 SCIP* scip, /**< SCIP data structure */
6739 SCIP_VAR* var, /**< active problem variable */
6740 SCIP_SOL* sol, /**< primal solution, or NULL for LP solution */
6741 SCIP_Real* closestvub, /**< pointer to store the value of the closest variable lower bound */
6742 int* closestvubidx /**< pointer to store the index of the closest variable lower bound */
6743 )
6744{
6745 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarClosestVub", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6746
6747 SCIPvarGetClosestVub(var, sol, scip->set, scip->stat, closestvub, closestvubidx);
6748
6749 return SCIP_OKAY;
6750}
6751
6752/** informs variable x about a globally valid variable lower bound x >= b*z + d with integer variable z;
6753 * if z is binary, the corresponding valid implication for z is also added;
6754 * if z is non-continuous and 1/b not too small, the corresponding valid upper/lower bound
6755 * z <= (x-d)/b or z >= (x-d)/b (depending on the sign of of b) is added, too;
6756 * improves the global bounds of the variable and the vlb variable if possible
6757 *
6758 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6759 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6760 *
6761 * @pre This method can be called if @p scip is in one of the following stages:
6762 * - \ref SCIP_STAGE_PRESOLVING
6763 * - \ref SCIP_STAGE_PRESOLVED
6764 * - \ref SCIP_STAGE_SOLVING
6765 */
6767 SCIP* scip, /**< SCIP data structure */
6768 SCIP_VAR* var, /**< problem variable */
6769 SCIP_VAR* vlbvar, /**< variable z in x >= b*z + d */
6770 SCIP_Real vlbcoef, /**< coefficient b in x >= b*z + d */
6771 SCIP_Real vlbconstant, /**< constant d in x >= b*z + d */
6772 SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6773 int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6774 )
6775{
6776 int nlocalbdchgs;
6777
6779
6780 SCIP_CALL( SCIPvarAddVlb(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->tree,
6781 scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, vlbvar, vlbcoef, vlbconstant,
6782 TRUE, infeasible, &nlocalbdchgs) );
6783
6784 *nbdchgs = nlocalbdchgs;
6785
6786 /* 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
6787 * detected infeasibility
6788 */
6789 if( !(*infeasible) && SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisZero(scip, 1.0/vlbcoef) )
6790 {
6791 if( vlbcoef > 0.0 )
6792 {
6793 /* if b > 0, we have a variable upper bound: x >= b*z + d => z <= (x-d)/b */
6794 SCIP_CALL( SCIPvarAddVub(vlbvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6795 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vlbcoef,
6796 -vlbconstant/vlbcoef, TRUE, infeasible, &nlocalbdchgs) );
6797 }
6798 else
6799 {
6800 /* if b < 0, we have a variable lower bound: x >= b*z + d => z >= (x-d)/b */
6801 SCIP_CALL( SCIPvarAddVlb(vlbvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6802 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vlbcoef,
6803 -vlbconstant/vlbcoef, TRUE, infeasible, &nlocalbdchgs) );
6804 }
6805 *nbdchgs += nlocalbdchgs;
6806 }
6807
6808 return SCIP_OKAY;
6809}
6810
6811/** informs variable x about a globally valid variable upper bound x <= b*z + d with integer variable z;
6812 * if z is binary, the corresponding valid implication for z is also added;
6813 * if z is non-continuous and 1/b not too small, the corresponding valid lower/upper bound
6814 * z >= (x-d)/b or z <= (x-d)/b (depending on the sign of of b) is added, too;
6815 * improves the global bounds of the variable and the vlb variable if possible
6816 *
6817 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6818 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6819 *
6820 * @pre This method can be called if @p scip is in one of the following stages:
6821 * - \ref SCIP_STAGE_PRESOLVING
6822 * - \ref SCIP_STAGE_PRESOLVED
6823 * - \ref SCIP_STAGE_SOLVING
6824 */
6826 SCIP* scip, /**< SCIP data structure */
6827 SCIP_VAR* var, /**< problem variable */
6828 SCIP_VAR* vubvar, /**< variable z in x <= b*z + d */
6829 SCIP_Real vubcoef, /**< coefficient b in x <= b*z + d */
6830 SCIP_Real vubconstant, /**< constant d in x <= b*z + d */
6831 SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6832 int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6833 )
6834{
6835 int nlocalbdchgs;
6836
6838
6839 SCIP_CALL( SCIPvarAddVub(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->tree,
6840 scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, vubvar, vubcoef, vubconstant, TRUE,
6841 infeasible, &nlocalbdchgs) );
6842
6843 *nbdchgs = nlocalbdchgs;
6844
6845 /* 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
6846 * detected infeasibility
6847 */
6848 if( !(*infeasible) && SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisZero(scip, 1.0/vubcoef) )
6849 {
6850 if( vubcoef > 0.0 )
6851 {
6852 /* if b < 0, we have a variable lower bound: x >= b*z + d => z >= (x-d)/b */
6853 SCIP_CALL( SCIPvarAddVlb(vubvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6854 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vubcoef,
6855 -vubconstant/vubcoef, TRUE, infeasible, &nlocalbdchgs) );
6856 }
6857 else
6858 {
6859 /* if b > 0, we have a variable upper bound: x >= b*z + d => z <= (x-d)/b */
6860 SCIP_CALL( SCIPvarAddVub(vubvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6861 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vubcoef,
6862 -vubconstant/vubcoef, TRUE, infeasible, &nlocalbdchgs) );
6863 }
6864 *nbdchgs += nlocalbdchgs;
6865 }
6866
6867 return SCIP_OKAY;
6868}
6869
6870/** informs binary variable x about a globally valid implication: x == 0 or x == 1 ==> y <= b or y >= b;
6871 * also adds the corresponding implication or variable bound to the implied variable;
6872 * if the implication is conflicting, the variable is fixed to the opposite value;
6873 * if the variable is already fixed to the given value, the implication is performed immediately;
6874 * if the implication is redundant with respect to the variables' global bounds, it is ignored
6875 *
6876 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6877 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6878 *
6879 * @pre This method can be called if @p scip is in one of the following stages:
6880 * - \ref SCIP_STAGE_TRANSFORMED
6881 * - \ref SCIP_STAGE_PRESOLVING
6882 * - \ref SCIP_STAGE_PRESOLVED
6883 * - \ref SCIP_STAGE_SOLVING
6884 */
6886 SCIP* scip, /**< SCIP data structure */
6887 SCIP_VAR* var, /**< problem variable */
6888 SCIP_Bool varfixing, /**< FALSE if y should be added in implications for x == 0, TRUE for x == 1 */
6889 SCIP_VAR* implvar, /**< variable y in implication y <= b or y >= b */
6890 SCIP_BOUNDTYPE impltype, /**< type of implication y <= b (SCIP_BOUNDTYPE_UPPER)
6891 * or y >= b (SCIP_BOUNDTYPE_LOWER) */
6892 SCIP_Real implbound, /**< bound b in implication y <= b or y >= b */
6893 SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6894 int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6895 )
6896{
6897 SCIP_VAR* implprobvar;
6898
6899 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarImplication", FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6900
6901 assert(infeasible != NULL);
6902 *infeasible = FALSE;
6903
6904 if ( nbdchgs != NULL )
6905 *nbdchgs = 0;
6906
6907 if( !SCIPvarIsBinary(var) )
6908 {
6909 SCIPerrorMessage("can't add implication for nonbinary variable\n");
6910 return SCIP_INVALIDDATA;
6911 }
6912
6913 implprobvar = SCIPvarGetProbvar(implvar);
6914 /* transform implication containing two binary variables to a clique; the condition ensures that the active representative
6915 * of implvar is actually binary
6916 */
6917 if( SCIPvarIsBinary(implvar) && (SCIPvarIsActive(implvar) || (implprobvar != NULL && SCIPvarIsBinary(implprobvar))) )
6918 {
6919 assert(SCIPisFeasEQ(scip, implbound, 1.0) || SCIPisFeasZero(scip, implbound));
6920 assert((impltype == SCIP_BOUNDTYPE_UPPER) == SCIPisFeasZero(scip, implbound));
6921
6922 /* only add clique if implication is not redundant with respect to global bounds of the implication variable */
6923 if( (impltype == SCIP_BOUNDTYPE_LOWER && SCIPvarGetLbGlobal(implvar) < 0.5) ||
6924 (impltype == SCIP_BOUNDTYPE_UPPER && SCIPvarGetUbGlobal(implvar) > 0.5) )
6925 {
6926 SCIP_VAR* vars[2];
6927 SCIP_Bool vals[2];
6928
6929 vars[0] = var;
6930 vars[1] = implvar;
6931 vals[0] = varfixing;
6932 vals[1] = (impltype == SCIP_BOUNDTYPE_UPPER);
6933
6934 SCIP_CALL( SCIPaddClique(scip, vars, vals, 2, FALSE, infeasible, nbdchgs) );
6935 }
6936
6937 return SCIP_OKAY;
6938 }
6939
6940 /* the implication graph can only handle 'real' binary (SCIP_VARTYPE_BINARY) variables, therefore we transform the
6941 * implication in variable bounds, (lowerbound of y will be abbreviated by lby, upperbound equivlaent) the follwing
6942 * four cases are:
6943 *
6944 * 1. (x >= 1 => y >= b) => y >= (b - lby) * x + lby
6945 * 2. (x >= 1 => y <= b) => y <= (b - uby) * x + uby
6946 * 3. (x <= 0 => y >= b) => y >= (lby - b) * x + b
6947 * 4. (x <= 0 => y <= b) => y <= (uby - b) * x + b
6948 */
6950 {
6951 SCIP_Real lby;
6952 SCIP_Real uby;
6953
6954 lby = SCIPvarGetLbGlobal(implvar);
6955 uby = SCIPvarGetUbGlobal(implvar);
6956
6957 if( varfixing == TRUE )
6958 {
6959 if( impltype == SCIP_BOUNDTYPE_LOWER )
6960 {
6961 /* we return if the lower bound is infinity */
6962 if( SCIPisInfinity(scip, -lby) )
6963 return SCIP_OKAY;
6964
6965 SCIP_CALL( SCIPvarAddVlb(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6966 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6967 implbound - lby, lby, TRUE, infeasible, nbdchgs) );
6968 }
6969 else
6970 {
6971 /* we return if the upper bound is infinity */
6972 if( SCIPisInfinity(scip, uby) )
6973 return SCIP_OKAY;
6974
6975 SCIP_CALL( SCIPvarAddVub(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6976 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6977 implbound - uby, uby, TRUE, infeasible, nbdchgs) );
6978 }
6979 }
6980 else
6981 {
6982 if( impltype == SCIP_BOUNDTYPE_LOWER )
6983 {
6984 /* we return if the lower bound is infinity */
6985 if( SCIPisInfinity(scip, -lby) )
6986 return SCIP_OKAY;
6987
6988 SCIP_CALL( SCIPvarAddVlb(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6989 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6990 lby - implbound, implbound, TRUE, infeasible, nbdchgs) );
6991 }
6992 else
6993 {
6994 /* we return if the upper bound is infinity */
6995 if( SCIPisInfinity(scip, uby) )
6996 return SCIP_OKAY;
6997
6998 SCIP_CALL( SCIPvarAddVub(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6999 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
7000 uby - implbound, implbound, TRUE, infeasible, nbdchgs) );
7001 }
7002 }
7003 }
7004 else
7005 {
7006 SCIP_CALL( SCIPvarAddImplic(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
7007 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, varfixing, implvar, impltype,
7008 implbound, TRUE, infeasible, nbdchgs) );
7009 }
7010
7011 return SCIP_OKAY;
7012}
7013
7014/** adds a clique information to SCIP, stating that at most one of the given binary variables can be set to 1;
7015 * if a variable appears twice in the same clique, the corresponding implications are performed
7016 *
7017 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7018 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7019 *
7020 * @pre This method can be called if @p scip is in one of the following stages:
7021 * - \ref SCIP_STAGE_TRANSFORMED
7022 * - \ref SCIP_STAGE_PRESOLVING
7023 * - \ref SCIP_STAGE_PRESOLVED
7024 * - \ref SCIP_STAGE_SOLVING
7025 */
7027 SCIP* scip, /**< SCIP data structure */
7028 SCIP_VAR** vars, /**< binary variables in the clique from which at most one can be set to 1 */
7029 SCIP_Bool* values, /**< values of the variables in the clique; NULL to use TRUE for all vars */
7030 int nvars, /**< number of variables in the clique */
7031 SCIP_Bool isequation, /**< is the clique an equation or an inequality? */
7032 SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
7033 int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
7034 )
7035{
7037
7038 *infeasible = FALSE;
7039 if( nbdchgs != NULL )
7040 *nbdchgs = 0;
7041
7042 if( nvars > 1 )
7043 {
7044 /* add the clique to the clique table */
7045 SCIP_CALL( SCIPcliquetableAdd(scip->cliquetable, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
7046 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, vars, values, nvars, isequation,
7047 infeasible, nbdchgs) );
7048 }
7049
7050 return SCIP_OKAY;
7051}
7052
7053/** relabels the given labels in-place in an increasing fashion: the first seen label is 0, the next label 1, etc...
7054 *
7055 * @note every label equal to -1 is treated as a previously unseen, unique label and gets a new ordered label.
7056 */
7057static
7059 SCIP*const scip, /**< SCIP data structure */
7060 int* labels, /**< current labels that will be overwritten */
7061 int const nlabels, /**< number of variables in the clique */
7062 int* nclasses /**< pointer to store the total number of distinct labels */
7063 )
7064{
7065 SCIP_HASHMAP* classidx2newlabel;
7066
7067 int classidx;
7068 int i;
7069
7070 SCIP_CALL( SCIPhashmapCreate(&classidx2newlabel, SCIPblkmem(scip), nlabels) );
7071
7072 classidx = 0;
7073
7074 /* loop over labels to create local class indices that obey the variable order */
7075 for( i = 0; i < nlabels; ++i )
7076 {
7077 int currentlabel = labels[i];
7078 int localclassidx;
7079
7080 /* labels equal to -1 are stored as singleton classes */
7081 if( currentlabel == -1 )
7082 {
7083 ++classidx;
7084 localclassidx = classidx;
7085 }
7086 else
7087 {
7088 assert(currentlabel >= 0);
7089 /* look up the class index image in the hash map; if it is not stored yet, new class index is created and stored */
7090 if( !SCIPhashmapExists(classidx2newlabel, (void*)(size_t)currentlabel) )
7091 {
7092 ++classidx;
7093 localclassidx = classidx;
7094 SCIP_CALL( SCIPhashmapInsertInt(classidx2newlabel, (void*)(size_t)currentlabel, classidx) ); /*lint !e571*/
7095 }
7096 else
7097 {
7098 localclassidx = SCIPhashmapGetImageInt(classidx2newlabel, (void*)(size_t)currentlabel); /*lint !e571*/
7099 }
7100 }
7101 assert(localclassidx - 1 >= 0);
7102 assert(localclassidx - 1 <= i);
7103
7104 /* indices start with zero, but we have an offset of 1 because we cannot store 0 in a hashmap */
7105 labels[i] = localclassidx - 1;
7106 }
7107
7108 assert(classidx > 0);
7109 assert(classidx <= nlabels);
7110 *nclasses = classidx;
7111
7112 SCIPhashmapFree(&classidx2newlabel);
7113
7114 return SCIP_OKAY;
7115}
7116
7117/** sort the variables w.r.t. the given labels; thereby ensure the current order of the variables with the same label. */
7118static
7120 SCIP* scip, /**< SCIP data structure */
7121 SCIP_VAR** vars, /**< variable array */
7122 int* classlabels, /**< array that contains a class label for every variable */
7123 SCIP_VAR** sortedvars, /**< array to store variables after stable sorting */
7124 int* sortedindices, /**< array to store indices of sorted variables in the original vars array */
7125 int* classesstartposs, /**< starting position array for each label class (must have size nclasses + 1) */
7126 int nvars, /**< size of the vars arrays */
7127 int nclasses /**< number of label classes */
7128 )
7129{
7130 SCIP_VAR*** varpointers;
7131 int** indexpointers;
7132 int* classcount;
7133
7134 int nextpos;
7135 int c;
7136 int v;
7137
7138 assert(scip != NULL);
7139 assert(vars != NULL);
7140 assert(sortedindices != NULL);
7141 assert(classesstartposs != NULL);
7142
7143 assert(nvars == 0 || vars != NULL);
7144
7145 if( nvars == 0 )
7146 return SCIP_OKAY;
7147
7148 assert(classlabels != NULL);
7149 assert(nclasses > 0);
7150
7151 /* we first count all class cardinalities and allocate temporary memory for a bucket sort */
7152 SCIP_CALL( SCIPallocBufferArray(scip, &classcount, nclasses) );
7153 BMSclearMemoryArray(classcount, nclasses);
7154
7155 /* first we count for each class the number of elements */
7156 for( v = nvars - 1; v >= 0; --v )
7157 {
7158 assert(0 <= classlabels[v] && classlabels[v] < nclasses);
7159 ++(classcount[classlabels[v]]);
7160 }
7161
7162#ifndef NDEBUG
7163 BMSclearMemoryArray(sortedvars, nvars);
7164 BMSclearMemoryArray(sortedindices, nvars);
7165#endif
7166 SCIP_CALL( SCIPallocBufferArray(scip, &varpointers, nclasses) );
7167 SCIP_CALL( SCIPallocBufferArray(scip, &indexpointers, nclasses) );
7168
7169 nextpos = 0;
7170 /* now we initialize all start pointers for each class, so they will be ordered */
7171 for( c = 0; c < nclasses; ++c )
7172 {
7173 /* to reach the goal that all variables of each class will be standing next to each other we will initialize the
7174 * starting pointers for each class by adding the cardinality of each class to the last class starting pointer
7175 * e.g. class1 has 4 elements and class2 has 3 elements then the starting pointer for class1 will be the pointer
7176 * to sortedvars[0], the starting pointer to class2 will be the pointer to sortedvars[4] and to class3 it will be
7177 * the pointer to sortedvars[7]
7178 */
7179 varpointers[c] = (SCIP_VAR**) (sortedvars + nextpos);
7180 indexpointers[c] = (int*) (sortedindices + nextpos);
7181 classesstartposs[c] = nextpos;
7182 assert(classcount[c] > 0);
7183 nextpos += classcount[c];
7184 assert(nextpos > 0);
7185 }
7186 assert(nextpos == nvars);
7187 classesstartposs[c] = nextpos;
7188
7189 /* now we copy all variables to the right order */
7190 for( v = 0; v < nvars; ++v )
7191 {
7192 /* copy variable itself to the right position */
7193 *(varpointers[classlabels[v]]) = vars[v]; /*lint !e613*/
7194 ++(varpointers[classlabels[v]]);
7195
7196 /* copy index */
7197 *(indexpointers[classlabels[v]]) = v;
7198 ++(indexpointers[classlabels[v]]);
7199 }
7200
7201/* in debug mode, we ensure the correctness of the mapping */
7202#ifndef NDEBUG
7203 for( v = 0; v < nvars; ++v )
7204 {
7205 assert(sortedvars[v] != NULL);
7206 assert(sortedindices[v] >= 0);
7207
7208 /* assert that the sorted indices map back to the correct variable in the original order */
7209 assert(vars[sortedindices[v]] == sortedvars[v]);
7210 }
7211#endif
7212
7213 /* free temporary memory */
7214 SCIPfreeBufferArray(scip, &indexpointers);
7215 SCIPfreeBufferArray(scip, &varpointers);
7216 SCIPfreeBufferArray(scip, &classcount);
7217
7218 return SCIP_OKAY;
7219}
7220
7221
7222/* calculate clique partition for a maximal amount of comparisons on variables due to expensive algorithm
7223 * @todo: check for a good value, maybe it's better to check parts of variables
7224 */
7225#define MAXNCLIQUEVARSCOMP 1000000
7226
7227/** calculates a partition of the given set of binary variables into cliques;
7228 * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7229 * were assigned to the same clique;
7230 * the first variable is always assigned to clique 0, and a variable can only be assigned to clique i if at least one of
7231 * the preceding variables was assigned to clique i-1;
7232 * for each clique at most 1 variables can be set to TRUE in a feasible solution;
7233 *
7234 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7235 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7236 *
7237 * @pre This method can be called if @p scip is in one of the following stages:
7238 * - \ref SCIP_STAGE_INITPRESOLVE
7239 * - \ref SCIP_STAGE_PRESOLVING
7240 * - \ref SCIP_STAGE_EXITPRESOLVE
7241 * - \ref SCIP_STAGE_PRESOLVED
7242 * - \ref SCIP_STAGE_SOLVING
7243 */
7244static
7246 SCIP*const scip, /**< SCIP data structure */
7247 SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7248 SCIP_Bool*const values, /**< clique value (TRUE or FALSE) for each variable in the clique */
7249 int const nvars, /**< number of variables in the array */
7250 int*const cliquepartition, /**< array of length nvars to store the clique partition */
7251 int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7252 )
7253{
7254 SCIP_VAR** cliquevars;
7255 SCIP_Bool* cliquevalues;
7256 int i;
7257 int maxncliquevarscomp;
7258 int ncliquevars;
7259
7260 /* allocate temporary memory for storing the variables of the current clique */
7261 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &cliquevars, nvars) );
7262 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &cliquevalues, nvars) );
7263
7264 /* initialize the cliquepartition array with -1 */
7265 for( i = nvars - 1; i >= 0; --i )
7266 cliquepartition[i] = -1;
7267
7268 maxncliquevarscomp = (int) MIN(nvars * (SCIP_Longint)nvars, MAXNCLIQUEVARSCOMP);
7269 /* calculate the clique partition */
7270 *ncliques = 0;
7271 for( i = 0; i < nvars; ++i )
7272 {
7273 if( cliquepartition[i] == -1 )
7274 {
7275 int j;
7276
7277 /* variable starts a new clique */
7278 cliquepartition[i] = *ncliques;
7279 cliquevars[0] = vars[i];
7280 cliquevalues[0] = values[i];
7281 ncliquevars = 1;
7282
7283 /* if variable is not active (multi-aggregated or fixed), it cannot be in any clique */
7284 if( SCIPvarIsActive(vars[i]) && SCIPvarGetNCliques(vars[i], values[i]) > 0 )
7285 {
7286 /* greedily fill up the clique */
7287 for( j = i+1; j < nvars; ++j )
7288 {
7289 /* if variable is not active (multi-aggregated or fixed), it cannot be in any clique */
7290 if( cliquepartition[j] == -1 && SCIPvarIsActive(vars[j]) )
7291 {
7292 int k;
7293
7294 /* check if every variable in the current clique can be extended by tmpvars[j] */
7295 for( k = ncliquevars - 1; k >= 0; --k )
7296 {
7297 if( !SCIPvarsHaveCommonClique(vars[j], values[j], cliquevars[k], cliquevalues[k], FALSE) )
7298 break;
7299 }
7300
7301 if( k == -1 )
7302 {
7303 /* put the variable into the same clique */
7304 cliquepartition[j] = cliquepartition[i];
7305 cliquevars[ncliquevars] = vars[j];
7306 cliquevalues[ncliquevars] = values[j];
7307 ++ncliquevars;
7308 }
7309 }
7310 }
7311 }
7312
7313 /* this clique is finished */
7314 ++(*ncliques);
7315 }
7316 assert(cliquepartition[i] >= 0 && cliquepartition[i] < i+1);
7317
7318 /* break if we reached the maximal number of comparisons */
7319 if( i * nvars > maxncliquevarscomp )
7320 break;
7321 }
7322 /* if we had to many variables fill up the cliquepartition and put each variable in a separate clique */
7323 for( ; i < nvars; ++i )
7324 {
7325 if( cliquepartition[i] == -1 )
7326 {
7327 cliquepartition[i] = *ncliques;
7328 ++(*ncliques);
7329 }
7330 }
7331
7332 SCIPsetFreeBufferArray(scip->set, &cliquevalues);
7333 SCIPsetFreeBufferArray(scip->set, &cliquevars);
7334
7335 return SCIP_OKAY;
7336}
7337
7338/** calculates a partition of the given set of binary variables into cliques; takes into account independent clique components
7339 *
7340 * The algorithm performs the following steps:
7341 * - recomputes connected components of the clique table, if necessary
7342 * - computes a clique partition for every connected component greedily.
7343 * - relabels the resulting clique partition such that it satisfies the description below
7344 *
7345 * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7346 * were assigned to the same clique;
7347 * the first variable is always assigned to clique 0, and a variable can only be assigned to clique i if at least one of
7348 * the preceding variables was assigned to clique i-1;
7349 * for each clique at most 1 variables can be set to TRUE in a feasible solution;
7350 *
7351 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7352 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7353 *
7354 * @pre This method can be called if @p scip is in one of the following stages:
7355 * - \ref SCIP_STAGE_INITPRESOLVE
7356 * - \ref SCIP_STAGE_PRESOLVING
7357 * - \ref SCIP_STAGE_EXITPRESOLVE
7358 * - \ref SCIP_STAGE_PRESOLVED
7359 * - \ref SCIP_STAGE_SOLVING
7360 */
7362 SCIP*const scip, /**< SCIP data structure */
7363 SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7364 int const nvars, /**< number of variables in the clique */
7365 int*const cliquepartition, /**< array of length nvars to store the clique partition */
7366 int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7367 )
7368{
7369 SCIP_VAR** tmpvars;
7370
7371 SCIP_VAR** sortedtmpvars;
7372 SCIP_Bool* tmpvalues;
7373 SCIP_Bool* sortedtmpvalues;
7374 int* componentlabels;
7375 int* sortedindices;
7376 int* componentstartposs;
7377 int i;
7378 int c;
7379
7380 int ncomponents;
7381
7382 assert(scip != NULL);
7383 assert(nvars == 0 || vars != NULL);
7384 assert(nvars == 0 || cliquepartition != NULL);
7385 assert(ncliques != NULL);
7386
7387 SCIP_CALL( SCIPcheckStage(scip, "SCIPcalcCliquePartition", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7388
7389 if( nvars == 0 )
7390 {
7391 *ncliques = 0;
7392 return SCIP_OKAY;
7393 }
7394
7395 /* early abort if no cliques are present */
7396 if( SCIPgetNCliques(scip) == 0 )
7397 {
7398 for( i = 0; i < nvars; ++i )
7399 cliquepartition[i] = i;
7400
7401 *ncliques = nvars;
7402
7403 return SCIP_OKAY;
7404 }
7405
7406 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &tmpvalues, nvars) );
7407 SCIP_CALL( SCIPsetDuplicateBufferArray(scip->set, &tmpvars, vars, nvars) );
7408 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &componentlabels, nvars) );
7409 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedindices, nvars) );
7410
7411 /* initialize the tmpvalues array */
7412 for( i = nvars - 1; i >= 0; --i )
7413 {
7414 tmpvalues[i] = TRUE;
7415 cliquepartition[i] = -1;
7416 }
7417
7418 /* get corresponding active problem variables */
7419 SCIP_CALL( SCIPvarsGetProbvarBinary(&tmpvars, &tmpvalues, nvars) );
7420
7421 ncomponents = -1;
7422
7423 /* update clique components if necessary */
7424 if( SCIPcliquetableNeedsComponentUpdate(scip->cliquetable) )
7425 {
7426 SCIP_VAR** allvars;
7427 int nallbinvars;
7428 int nallintvars;
7429 int nallimplvars;
7430
7431 SCIP_CALL( SCIPgetVarsData(scip, &allvars, NULL, &nallbinvars, &nallintvars, &nallimplvars, NULL) );
7432
7433 SCIP_CALL( SCIPcliquetableComputeCliqueComponents(scip->cliquetable, scip->set, SCIPblkmem(scip), allvars, nallbinvars, nallintvars, nallimplvars) );
7434 }
7435
7436 assert(!SCIPcliquetableNeedsComponentUpdate(scip->cliquetable));
7437
7438 /* store the global clique component labels */
7439 for( i = 0; i < nvars; ++i )
7440 {
7441 if( SCIPvarIsActive(tmpvars[i]) )
7442 componentlabels[i] = SCIPcliquetableGetVarComponentIdx(scip->cliquetable, tmpvars[i]);
7443 else
7444 componentlabels[i] = -1;
7445 }
7446
7447 /* relabel component labels order consistent as prerequisite for a stable sort */
7448 SCIP_CALL( relabelOrderConsistent(scip, componentlabels, nvars, &ncomponents) );
7449 assert(ncomponents >= 1);
7450 assert(ncomponents <= nvars);
7451
7452 /* allocate storage array for the starting positions of the components */
7453 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &componentstartposs, ncomponents + 1) );
7454
7455 /* stable sort the variables w.r.t. the component labels so that we can restrict the quadratic algorithm to the components */
7456 if( ncomponents > 1 )
7457 {
7458 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedtmpvars, nvars) );
7459 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedtmpvalues, nvars) );
7460 SCIP_CALL( labelSortStable(scip, tmpvars, componentlabels, sortedtmpvars, sortedindices, componentstartposs, nvars, ncomponents) );
7461
7462 /* reassign the tmpvalues with respect to the sorting */
7463 for( i = 0; i < nvars; ++i )
7464 {
7465 assert(tmpvars[sortedindices[i]] == sortedtmpvars[i]);
7466 sortedtmpvalues[i] = tmpvalues[sortedindices[i]];
7467 }
7468 }
7469 else
7470 {
7471 /* if we have only one large connected component, skip the stable sorting and prepare the data differently */
7472 sortedtmpvars = tmpvars;
7473 sortedtmpvalues = tmpvalues;
7474 componentstartposs[0] = 0;
7475 componentstartposs[1] = nvars;
7476
7477 /* sorted indices are the identity */
7478 for( i = 0; i < nvars; ++i )
7479 sortedindices[i] = i;
7480 }
7481
7482 *ncliques = 0;
7483 /* calculate a greedy clique partition for each connected component */
7484 for( c = 0; c < ncomponents; ++c )
7485 {
7486 int* localcliquepartition;
7487 int nlocalcliques;
7488 int ncomponentvars;
7489 int l;
7490
7491 /* extract the number of variables in this connected component */
7492 ncomponentvars = componentstartposs[c + 1] - componentstartposs[c];
7493 nlocalcliques = 0;
7494
7495 /* allocate necessary memory to hold the intermediate component clique partition */
7496 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &localcliquepartition, ncomponentvars) );
7497
7498 /* call greedy clique algorithm for all component variables */
7499 SCIP_CALL( calcCliquePartitionGreedy(scip, &(sortedtmpvars[componentstartposs[c]]), &(sortedtmpvalues[componentstartposs[c]]),
7500 ncomponentvars, localcliquepartition, &nlocalcliques) );
7501
7502 assert(nlocalcliques >= 1);
7503 assert(nlocalcliques <= ncomponentvars);
7504
7505 /* store the obtained clique partition with an offset of ncliques for the original variables */
7506 for( l = componentstartposs[c]; l < componentstartposs[c + 1]; ++l )
7507 {
7508 int origvaridx = sortedindices[l];
7509 assert(cliquepartition[origvaridx] == -1);
7510 assert(localcliquepartition[l - componentstartposs[c]] <= l - componentstartposs[c]);
7511 cliquepartition[origvaridx] = localcliquepartition[l - componentstartposs[c]] + (*ncliques);
7512 }
7513 *ncliques += nlocalcliques;
7514
7515 /* free the local clique partition */
7516 SCIPsetFreeBufferArray(scip->set, &localcliquepartition);
7517 }
7518
7519 /* except in the two trivial cases, we have to ensure the order consistency of the partition indices */
7520 if( ncomponents > 1 && ncomponents < nvars )
7521 {
7522 int partitionsize;
7523 SCIP_CALL( relabelOrderConsistent(scip, cliquepartition, nvars, &partitionsize) );
7524
7525 assert(partitionsize == *ncliques);
7526 }
7527
7528 if( ncomponents > 1 )
7529 {
7530 SCIPsetFreeBufferArray(scip->set, &sortedtmpvalues);
7531 SCIPsetFreeBufferArray(scip->set, &sortedtmpvars);
7532 }
7533
7534 /* use the greedy algorithm as a whole to verify the result on small number of variables */
7535#ifdef SCIP_DISABLED_CODE
7536 {
7537 int* debugcliquepartition;
7538 int ndebugcliques;
7539
7540 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &debugcliquepartition, nvars) );
7541
7542 /* call greedy clique algorithm for all component variables */
7543 SCIP_CALL( calcCliquePartitionGreedy(scip, tmpvars, tmpvalues, nvars, debugcliquepartition, &ndebugcliques) );
7544
7545 /* loop and compare the traditional greedy clique with */
7546 for( i = 0; i < nvars; ++i )
7547 assert(i * nvars > MAXNCLIQUEVARSCOMP || cliquepartition[i] == debugcliquepartition[i]);
7548
7549 SCIPsetFreeBufferArray(scip->set, &debugcliquepartition);
7550 }
7551#endif
7552
7553 /* free temporary memory */
7554 SCIPsetFreeBufferArray(scip->set, &componentstartposs);
7555 SCIPsetFreeBufferArray(scip->set, &sortedindices);
7556 SCIPsetFreeBufferArray(scip->set, &componentlabels);
7557 SCIPsetFreeBufferArray(scip->set, &tmpvars);
7558 SCIPsetFreeBufferArray(scip->set, &tmpvalues);
7559
7560 return SCIP_OKAY;
7561}
7562
7563/** calculates a partition of the given set of binary variables into negated cliques;
7564 * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7565 * were assigned to the same negated clique;
7566 * the first variable is always assigned to clique 0 and a variable can only be assigned to clique i if at least one of
7567 * the preceding variables was assigned to clique i-1;
7568 * for each clique with n_c variables at least n_c-1 variables can be set to TRUE in a feasible solution;
7569 *
7570 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7571 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7572 *
7573 * @pre This method can be called if @p scip is in one of the following stages:
7574 * - \ref SCIP_STAGE_INITPRESOLVE
7575 * - \ref SCIP_STAGE_PRESOLVING
7576 * - \ref SCIP_STAGE_EXITPRESOLVE
7577 * - \ref SCIP_STAGE_PRESOLVED
7578 * - \ref SCIP_STAGE_SOLVING
7579 */
7581 SCIP*const scip, /**< SCIP data structure */
7582 SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7583 int const nvars, /**< number of variables in the clique */
7584 int*const cliquepartition, /**< array of length nvars to store the clique partition */
7585 int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7586 )
7587{
7588 SCIP_VAR** negvars;
7589 int v;
7590
7591 assert(scip != NULL);
7592 assert(cliquepartition != NULL || nvars == 0);
7593 assert(ncliques != NULL);
7594
7595 if( nvars == 0 )
7596 {
7597 *ncliques = 0;
7598 return SCIP_OKAY;
7599 }
7600 assert(vars != NULL);
7601
7602 /* allocate temporary memory */
7603 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &negvars, nvars) );
7604
7605 /* get all negated variables */
7606 for( v = nvars - 1; v >= 0; --v )
7607 {
7608 SCIP_CALL( SCIPgetNegatedVar(scip, vars[v], &(negvars[v])) );
7609 }
7610
7611 /* calculate cliques on negated variables, which are "negated" cliques on normal variables array */
7612 SCIP_CALL( SCIPcalcCliquePartition( scip, negvars, nvars, cliquepartition, ncliques) );
7613
7614 /* free temporary memory */
7615 SCIPsetFreeBufferArray(scip->set, &negvars);
7616
7617 return SCIP_OKAY;
7618}
7619
7620
7621/** force SCIP to clean up all cliques; cliques do not get automatically cleaned up after presolving. Use
7622 * this method to prevent inactive variables in cliques when retrieved via SCIPgetCliques()
7623 *
7624 * @return SCIP_OKAY if everything worked, otherwise a suitable error code is passed
7625 *
7626 * @pre This method can be called if @p scip is in one of the following stages:
7627 * - \ref SCIP_STAGE_TRANSFORMED
7628 * - \ref SCIP_STAGE_INITPRESOLVE
7629 * - \ref SCIP_STAGE_PRESOLVING
7630 * - \ref SCIP_STAGE_EXITPRESOLVE
7631 * - \ref SCIP_STAGE_PRESOLVED
7632 * - \ref SCIP_STAGE_INITSOLVE
7633 * - \ref SCIP_STAGE_SOLVING
7634 * - \ref SCIP_STAGE_SOLVED
7635 * - \ref SCIP_STAGE_EXITSOLVE
7636 */
7638 SCIP* scip, /**< SCIP data structure */
7639 SCIP_Bool* infeasible /**< pointer to store if cleanup detected infeasibility */
7640 )
7641{
7642 int nlocalbdchgs;
7643 SCIP_Bool globalinfeasibility;
7644
7645 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPcleanupCliques", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7646
7647 globalinfeasibility = FALSE;
7648 nlocalbdchgs = 0;
7649 SCIP_CALL( SCIPcliquetableCleanup(scip->cliquetable, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
7650 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, &nlocalbdchgs,
7651 &globalinfeasibility) );
7652
7653 if( infeasible != NULL )
7654 *infeasible = globalinfeasibility;
7655
7656 if( globalinfeasibility )
7657 scip->stat->status = SCIP_STATUS_INFEASIBLE;
7658
7659 return SCIP_OKAY;
7660}
7661
7662/** gets the number of cliques in the clique table
7663 *
7664 * @return number of cliques in the clique table
7665 *
7666 * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7667 * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
7668 *
7669 * @pre This method can be called if @p scip is in one of the following stages:
7670 * - \ref SCIP_STAGE_TRANSFORMED
7671 * - \ref SCIP_STAGE_INITPRESOLVE
7672 * - \ref SCIP_STAGE_PRESOLVING
7673 * - \ref SCIP_STAGE_EXITPRESOLVE
7674 * - \ref SCIP_STAGE_PRESOLVED
7675 * - \ref SCIP_STAGE_INITSOLVE
7676 * - \ref SCIP_STAGE_SOLVING
7677 * - \ref SCIP_STAGE_SOLVED
7678 * - \ref SCIP_STAGE_EXITSOLVE
7679 */
7681 SCIP* scip /**< SCIP data structure */
7682 )
7683{
7685
7686 return SCIPcliquetableGetNCliques(scip->cliquetable);
7687}
7688
7689/** gets the number of cliques created so far by the cliquetable
7690 *
7691 * @return number of cliques created so far by the cliquetable
7692 *
7693 * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7694 * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
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 */
7708 SCIP* scip /**< SCIP data structure */
7709 )
7710{
7711 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNCliquesCreated", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7712
7713 return SCIPcliquetableGetNCliquesCreated(scip->cliquetable);
7714}
7715
7716/** gets the array of cliques in the clique table
7717 *
7718 * @return array of cliques in the clique table
7719 *
7720 * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7721 * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
7722 *
7723 * @pre This method can be called if @p scip is in one of the following stages:
7724 * - \ref SCIP_STAGE_TRANSFORMED
7725 * - \ref SCIP_STAGE_INITPRESOLVE
7726 * - \ref SCIP_STAGE_PRESOLVING
7727 * - \ref SCIP_STAGE_EXITPRESOLVE
7728 * - \ref SCIP_STAGE_PRESOLVED
7729 * - \ref SCIP_STAGE_INITSOLVE
7730 * - \ref SCIP_STAGE_SOLVING
7731 * - \ref SCIP_STAGE_SOLVED
7732 * - \ref SCIP_STAGE_EXITSOLVE
7733 */
7735 SCIP* scip /**< SCIP data structure */
7736 )
7737{
7739
7740 return SCIPcliquetableGetCliques(scip->cliquetable);
7741}
7742
7743/** returns whether there is a clique that contains both given variable/value pairs;
7744 * the variables must be active binary variables;
7745 * if regardimplics is FALSE, only the cliques in the clique table are looked at;
7746 * if regardimplics is TRUE, both the cliques and the implications of the implication graph are regarded
7747 *
7748 * @return TRUE, if there is a clique that contains both variable/clique pairs; FALSE, otherwise
7749 *
7750 * @pre This method can be called if @p scip is in one of the following stages:
7751 * - \ref SCIP_STAGE_TRANSFORMED
7752 * - \ref SCIP_STAGE_INITPRESOLVE
7753 * - \ref SCIP_STAGE_PRESOLVING
7754 * - \ref SCIP_STAGE_EXITPRESOLVE
7755 * - \ref SCIP_STAGE_PRESOLVED
7756 * - \ref SCIP_STAGE_INITSOLVE
7757 * - \ref SCIP_STAGE_SOLVING
7758 * - \ref SCIP_STAGE_SOLVED
7759 * - \ref SCIP_STAGE_EXITSOLVE
7760 *
7761 * @note a variable with it's negated variable are NOT! in a clique
7762 * @note a variable with itself are in a clique
7763 */
7765 SCIP* scip, /**< SCIP data structure */
7766 SCIP_VAR* var1, /**< first variable */
7767 SCIP_Bool value1, /**< value of first variable */
7768 SCIP_VAR* var2, /**< second variable */
7769 SCIP_Bool value2, /**< value of second variable */
7770 SCIP_Bool regardimplics /**< should the implication graph also be searched for a clique? */
7771 )
7772{
7773 assert(scip != NULL);
7774 assert(var1 != NULL);
7775 assert(var2 != NULL);
7776 assert(SCIPvarIsActive(var1));
7777 assert(SCIPvarIsActive(var2));
7778 assert(SCIPvarIsBinary(var1));
7779 assert(SCIPvarIsBinary(var2));
7780
7781 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPhaveVarsCommonClique", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7782
7783 /* if both variables together have more cliques then actual cliques exist, then they have a common clique (in debug
7784 * mode we check this for correctness), otherwise we need to call the pairwise comparison method for these variables
7785 */
7786#ifndef NDEBUG
7787 assert((SCIPvarGetNCliques(var1, value1) + SCIPvarGetNCliques(var2, value2) > SCIPcliquetableGetNCliques(scip->cliquetable)) ? SCIPvarsHaveCommonClique(var1, value1, var2, value2, FALSE) : TRUE);
7788#endif
7789
7790 return (SCIPvarGetNCliques(var1, value1) + SCIPvarGetNCliques(var2, value2) > SCIPcliquetableGetNCliques(scip->cliquetable)
7791 || SCIPvarsHaveCommonClique(var1, value1, var2, value2, regardimplics));
7792}
7793
7794/** writes the clique graph to a gml file
7795 *
7796 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7797 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7798 *
7799 * @pre This method can be called if @p scip is in one of the following stages:
7800 * - \ref SCIP_STAGE_TRANSFORMED
7801 * - \ref SCIP_STAGE_INITPRESOLVE
7802 * - \ref SCIP_STAGE_PRESOLVING
7803 * - \ref SCIP_STAGE_EXITPRESOLVE
7804 * - \ref SCIP_STAGE_PRESOLVED
7805 * - \ref SCIP_STAGE_INITSOLVE
7806 * - \ref SCIP_STAGE_SOLVING
7807 * - \ref SCIP_STAGE_SOLVED
7808 * - \ref SCIP_STAGE_EXITSOLVE
7809 *
7810 * @note there can be duplicated arcs in the output file
7811 *
7812 * If @p writenodeweights is true, only nodes corresponding to variables that have a fractional value and only edges
7813 * between such nodes are written.
7814 */
7816 SCIP* scip, /**< SCIP data structure */
7817 const char* fname, /**< name of file */
7818 SCIP_Bool writenodeweights /**< should we write weights of nodes? */
7819 )
7820{
7821 FILE* gmlfile;
7822 SCIP_HASHMAP* nodehashmap;
7823 SCIP_CLIQUE** cliques;
7824 SCIP_VAR** clqvars;
7825 SCIP_VAR** allvars;
7826 SCIP_Bool* clqvalues;
7827 char nodename[SCIP_MAXSTRLEN];
7828 int nallvars;
7829 int nbinvars;
7830 int nintvars;
7831 int nimplvars;
7832 int ncliques;
7833 int c;
7834 int v1;
7835 int v2;
7836 int id1;
7837 int id2;
7838
7839 assert(scip != NULL);
7840 assert(fname != NULL);
7841
7842 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPwriteCliqueGraph", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7843
7844 /* get all active variables */
7845 SCIP_CALL( SCIPgetVarsData(scip, &allvars, &nallvars, &nbinvars, &nintvars, &nimplvars, NULL) );
7846
7847 /* no possible variables for cliques exist */
7848 if( nbinvars + nimplvars == 0 )
7849 return SCIP_OKAY;
7850
7851 ncliques = SCIPgetNCliques(scip);
7852
7853 /* no cliques and do not wont to check for binary implications */
7854 if( ncliques == 0 )
7855 return SCIP_OKAY;
7856
7857 /* open gml file */
7858 gmlfile = fopen(fname, "w");
7859
7860 if( gmlfile == NULL )
7861 {
7862 SCIPerrorMessage("cannot open graph file <%s>\n", fname);
7863 SCIPABORT();
7864 return SCIP_INVALIDDATA; /*lint !e527*/
7865 }
7866
7867 /* create the hash map */
7868 SCIP_CALL_FINALLY( SCIPhashmapCreate(&nodehashmap, SCIPblkmem(scip), nbinvars+nimplvars), fclose(gmlfile) );
7869
7870 /* write starting of gml file */
7871 SCIPgmlWriteOpening(gmlfile, TRUE);
7872
7873 cliques = SCIPgetCliques(scip);
7874
7875 /* write nodes and arcs for all cliques */
7876 for( c = ncliques - 1; c >= 0; --c )
7877 {
7878 clqvalues = SCIPcliqueGetValues(cliques[c]);
7879 clqvars = SCIPcliqueGetVars(cliques[c]);
7880
7881 for( v1 = SCIPcliqueGetNVars(cliques[c]) - 1; v1 >= 0; --v1 )
7882 {
7883 id1 = clqvalues[v1] ? SCIPvarGetProbindex(clqvars[v1]) : (nallvars + SCIPvarGetProbindex(clqvars[v1]));
7884
7885 /* if corresponding node was not added yet, add it */
7886 if( !SCIPhashmapExists(nodehashmap, (void*)(size_t)id1) )
7887 {
7888 assert(id1 >= 0);
7889 SCIP_CALL_FINALLY( SCIPhashmapInsertInt(nodehashmap, (void*)(size_t)id1, 1), fclose(gmlfile) ); /*lint !e571*/
7890
7891 (void) SCIPsnprintf(nodename, SCIP_MAXSTRLEN, "%s%s", (id1 >= nallvars ? "~" : ""), SCIPvarGetName(clqvars[v1]));
7892
7893 /* write new gml node for new variable */
7894 if ( writenodeweights )
7895 {
7896 if ( ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v1])) )
7897 SCIPgmlWriteNodeWeight(gmlfile, (unsigned int)id1, nodename, NULL, NULL, NULL, SCIPgetSolVal(scip, NULL, clqvars[v1]));
7898 }
7899 else
7900 {
7901 SCIPgmlWriteNode(gmlfile, (unsigned int)id1, nodename, NULL, NULL, NULL);
7902 }
7903 }
7904
7905 for( v2 = SCIPcliqueGetNVars(cliques[c]) - 1; v2 >= 0; --v2 )
7906 {
7907 if( v1 == v2 )
7908 continue;
7909
7910 id2 = clqvalues[v2] ? SCIPvarGetProbindex(clqvars[v2]) : (nallvars + SCIPvarGetProbindex(clqvars[v2]));
7911
7912 /* if corresponding node was not added yet, add it */
7913 if( !SCIPhashmapExists(nodehashmap, (void*)(size_t)id2) )
7914 {
7915 assert(id2 >= 0);
7916 SCIP_CALL_FINALLY( SCIPhashmapInsertInt(nodehashmap, (void*)(size_t)id2, 1), fclose(gmlfile) ); /*lint !e571*/
7917
7918 (void) SCIPsnprintf(nodename, SCIP_MAXSTRLEN, "%s%s", (id2 >= nallvars ? "~" : ""), SCIPvarGetName(clqvars[v2]));
7919
7920 /* write new gml node for new variable */
7921 if ( writenodeweights )
7922 {
7923 if ( ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v2])) )
7924 SCIPgmlWriteNodeWeight(gmlfile, (unsigned int)id2, nodename, NULL, NULL, NULL, SCIPgetSolVal(scip, NULL, clqvars[v2]));
7925 }
7926 else
7927 {
7928 SCIPgmlWriteNode(gmlfile, (unsigned int)id2, nodename, NULL, NULL, NULL);
7929 }
7930 }
7931
7932 /* write gml arc between resultant and operand */
7933 if ( ! writenodeweights || ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v2])) )
7934 SCIPgmlWriteArc(gmlfile, (unsigned int)id1, (unsigned int)id2, NULL, NULL);
7935 }
7936 }
7937 }
7938
7939 /* free the hash map */
7940 SCIPhashmapFree(&nodehashmap);
7941
7942 SCIPgmlWriteClosing(gmlfile);
7943 fclose(gmlfile);
7944
7945 return SCIP_OKAY;
7946}
7947
7948/** Removes (irrelevant) variable from all its global structures, i.e. cliques, implications and variable bounds.
7949 * This is an advanced method which should be used with care.
7950 *
7951 * @return SCIP_OKAY if everything worked, otherwise a suitable error code is passed
7952 *
7953 * @pre This method can be called if @p scip is in one of the following stages:
7954 * - \ref SCIP_STAGE_TRANSFORMED
7955 * - \ref SCIP_STAGE_INITPRESOLVE
7956 * - \ref SCIP_STAGE_PRESOLVING
7957 * - \ref SCIP_STAGE_EXITPRESOLVE
7958 * - \ref SCIP_STAGE_PRESOLVED
7959 * - \ref SCIP_STAGE_INITSOLVE
7960 * - \ref SCIP_STAGE_SOLVING
7961 * - \ref SCIP_STAGE_SOLVED
7962 * - \ref SCIP_STAGE_EXITSOLVE
7963 */
7965 SCIP* scip, /**< SCIP data structure */
7966 SCIP_VAR* var /**< variable to remove from global structures */
7967 )
7968{
7969 assert(scip != NULL);
7970
7971 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPremoveVarFromGlobalStructures", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7972
7973 /* mark the variable as deletable from global structures - This is necessary for the delayed clean up of cliques */
7975
7976 /* remove variable from all its cliques, implications, and variable bounds */
7978
7979 return SCIP_OKAY;
7980}
7981
7982/** sets the branch factor of the variable; this value can be used in the branching methods to scale the score
7983 * values of the variables; higher factor leads to a higher probability that this variable is chosen for branching
7984 *
7985 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7986 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7987 *
7988 * @pre This method can be called if @p scip is in one of the following stages:
7989 * - \ref SCIP_STAGE_PROBLEM
7990 * - \ref SCIP_STAGE_TRANSFORMING
7991 * - \ref SCIP_STAGE_TRANSFORMED
7992 * - \ref SCIP_STAGE_INITPRESOLVE
7993 * - \ref SCIP_STAGE_PRESOLVING
7994 * - \ref SCIP_STAGE_EXITPRESOLVE
7995 * - \ref SCIP_STAGE_PRESOLVED
7996 * - \ref SCIP_STAGE_SOLVING
7997 */
7999 SCIP* scip, /**< SCIP data structure */
8000 SCIP_VAR* var, /**< problem variable */
8001 SCIP_Real branchfactor /**< factor to weigh variable's branching score with */
8002 )
8003{
8004 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8005
8006 SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, branchfactor) );
8007
8008 return SCIP_OKAY;
8009}
8010
8011/** scales the branch factor of the variable with the given value
8012 *
8013 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8014 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8015 *
8016 * @pre This method can be called if @p scip is in one of the following stages:
8017 * - \ref SCIP_STAGE_PROBLEM
8018 * - \ref SCIP_STAGE_TRANSFORMING
8019 * - \ref SCIP_STAGE_TRANSFORMED
8020 * - \ref SCIP_STAGE_INITPRESOLVE
8021 * - \ref SCIP_STAGE_PRESOLVING
8022 * - \ref SCIP_STAGE_EXITPRESOLVE
8023 * - \ref SCIP_STAGE_PRESOLVED
8024 * - \ref SCIP_STAGE_SOLVING
8025 */
8027 SCIP* scip, /**< SCIP data structure */
8028 SCIP_VAR* var, /**< problem variable */
8029 SCIP_Real scale /**< factor to scale variable's branching factor with */
8030 )
8031{
8032 SCIP_CALL( SCIPcheckStage(scip, "SCIPscaleVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8033
8034 SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, scale * SCIPvarGetBranchFactor(var)) );
8035
8036 return SCIP_OKAY;
8037}
8038
8039/** adds the given value to the branch factor of the variable
8040 *
8041 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8042 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8043 *
8044 * @pre This method can be called if @p scip is in one of the following stages:
8045 * - \ref SCIP_STAGE_PROBLEM
8046 * - \ref SCIP_STAGE_TRANSFORMING
8047 * - \ref SCIP_STAGE_TRANSFORMED
8048 * - \ref SCIP_STAGE_INITPRESOLVE
8049 * - \ref SCIP_STAGE_PRESOLVING
8050 * - \ref SCIP_STAGE_EXITPRESOLVE
8051 * - \ref SCIP_STAGE_PRESOLVED
8052 * - \ref SCIP_STAGE_SOLVING
8053 */
8055 SCIP* scip, /**< SCIP data structure */
8056 SCIP_VAR* var, /**< problem variable */
8057 SCIP_Real addfactor /**< value to add to the branch factor of the variable */
8058 )
8059{
8060 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8061
8062 SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, addfactor + SCIPvarGetBranchFactor(var)) );
8063
8064 return SCIP_OKAY;
8065}
8066
8067/** sets the branch priority of the variable; variables with higher branch priority are always preferred to variables
8068 * with lower priority in selection of branching variable
8069 *
8070 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8071 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8072 *
8073 * @pre This method can be called if @p scip is in one of the following stages:
8074 * - \ref SCIP_STAGE_PROBLEM
8075 * - \ref SCIP_STAGE_TRANSFORMING
8076 * - \ref SCIP_STAGE_TRANSFORMED
8077 * - \ref SCIP_STAGE_INITPRESOLVE
8078 * - \ref SCIP_STAGE_PRESOLVING
8079 * - \ref SCIP_STAGE_EXITPRESOLVE
8080 * - \ref SCIP_STAGE_PRESOLVED
8081 * - \ref SCIP_STAGE_SOLVING
8082 *
8083 * @note the default branching priority is 0
8084 */
8086 SCIP* scip, /**< SCIP data structure */
8087 SCIP_VAR* var, /**< problem variable */
8088 int branchpriority /**< branch priority of the variable */
8089 )
8090{
8091 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8092
8093 assert( var->scip == scip );
8094
8095 if( SCIPisTransformed(scip) )
8096 {
8097 assert(scip->branchcand != NULL);
8098
8099 /* inform the pseudo branch candidates that the branch priority changes and change the branch priority */
8100 SCIP_CALL( SCIPbranchcandUpdateVarBranchPriority(scip->branchcand, scip->set, var, branchpriority) );
8101 }
8102 else
8103 {
8104 /* change the branching priority of the variable */
8105 SCIP_CALL( SCIPvarChgBranchPriority(var, branchpriority) );
8106 }
8107
8108 return SCIP_OKAY;
8109}
8110
8111/** changes the branch priority of the variable to the given value, if it is larger than the current priority
8112 *
8113 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8114 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8115 *
8116 * @pre This method can be called if @p scip is in one of the following stages:
8117 * - \ref SCIP_STAGE_PROBLEM
8118 * - \ref SCIP_STAGE_TRANSFORMING
8119 * - \ref SCIP_STAGE_TRANSFORMED
8120 * - \ref SCIP_STAGE_INITPRESOLVE
8121 * - \ref SCIP_STAGE_PRESOLVING
8122 * - \ref SCIP_STAGE_EXITPRESOLVE
8123 * - \ref SCIP_STAGE_PRESOLVED
8124 * - \ref SCIP_STAGE_SOLVING
8125 */
8127 SCIP* scip, /**< SCIP data structure */
8128 SCIP_VAR* var, /**< problem variable */
8129 int branchpriority /**< new branch priority of the variable, if it is larger than current priority */
8130 )
8131{
8132 SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8133
8134 assert( var->scip == scip );
8135
8136 if( branchpriority > SCIPvarGetBranchPriority(var) )
8137 {
8138 SCIP_CALL( SCIPvarChgBranchPriority(var, branchpriority) );
8139 }
8140
8141 return SCIP_OKAY;
8142}
8143
8144/** adds the given value to the branch priority of the variable
8145 *
8146 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8147 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8148 *
8149 * @pre This method can be called if @p scip is in one of the following stages:
8150 * - \ref SCIP_STAGE_PROBLEM
8151 * - \ref SCIP_STAGE_TRANSFORMING
8152 * - \ref SCIP_STAGE_TRANSFORMED
8153 * - \ref SCIP_STAGE_INITPRESOLVE
8154 * - \ref SCIP_STAGE_PRESOLVING
8155 * - \ref SCIP_STAGE_EXITPRESOLVE
8156 * - \ref SCIP_STAGE_PRESOLVED
8157 * - \ref SCIP_STAGE_SOLVING
8158 */
8160 SCIP* scip, /**< SCIP data structure */
8161 SCIP_VAR* var, /**< problem variable */
8162 int addpriority /**< value to add to the branch priority of the variable */
8163 )
8164{
8165 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8166
8167 assert( var->scip == scip );
8168
8170
8171 return SCIP_OKAY;
8172}
8173
8174/** sets the branch direction of the variable (-1: prefer downwards branch, 0: automatic selection, +1: prefer upwards
8175 * branch)
8176 *
8177 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8178 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8179 *
8180 * @pre This method can be called if @p scip is in one of the following stages:
8181 * - \ref SCIP_STAGE_PROBLEM
8182 * - \ref SCIP_STAGE_TRANSFORMING
8183 * - \ref SCIP_STAGE_TRANSFORMED
8184 * - \ref SCIP_STAGE_INITPRESOLVE
8185 * - \ref SCIP_STAGE_PRESOLVING
8186 * - \ref SCIP_STAGE_EXITPRESOLVE
8187 * - \ref SCIP_STAGE_PRESOLVED
8188 * - \ref SCIP_STAGE_SOLVING
8189 */
8191 SCIP* scip, /**< SCIP data structure */
8192 SCIP_VAR* var, /**< problem variable */
8193 SCIP_BRANCHDIR branchdirection /**< preferred branch direction of the variable (downwards, upwards, auto) */
8194 )
8195{
8196 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchDirection", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8197
8198 assert( var->scip == scip );
8199
8200 SCIP_CALL( SCIPvarChgBranchDirection(var, branchdirection) );
8201
8202 return SCIP_OKAY;
8203}
8204
8205/** tightens the variable bounds due to a new variable type */
8206static
8208 SCIP* scip, /**< SCIP data structure */
8209 SCIP_VAR* var, /**< variable to change the bound for */
8210 SCIP_VARTYPE vartype, /**< new type of variable */
8211 SCIP_Bool* infeasible /**< pointer to store whether an infeasibility was detected (, due to
8212 * integrality condition of the new variable type) */
8213 )
8214{
8215 assert(scip != NULL);
8217 assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPvarIsTransformed(var));
8218 assert(var->scip == scip);
8219
8220 *infeasible = FALSE;
8221
8222 /* adjusts bounds if the variable type changed form continuous to non-continuous (integral) */
8224 {
8225 SCIP_Bool tightened;
8226
8227 /* we adjust variable bounds to integers first, since otherwise a later bound tightening with a fractional old
8228 * bound may give an assert because SCIP expects non-continuous variables to have non-fractional bounds
8229 *
8230 * we adjust bounds with a fractionality within [eps,feastol] only if the resulting bound change is a bound
8231 * tightening, because relaxing bounds may not be allowed
8232 */
8237 )
8238 {
8239 SCIP_CALL( SCIPtightenVarLbGlobal(scip, var, SCIPfeasCeil(scip, SCIPvarGetLbGlobal(var)), TRUE, infeasible, &tightened) );
8240 if( *infeasible )
8241 return SCIP_OKAY;
8242
8243 /* 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
8244 * 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
8245 */
8246 assert(tightened || SCIPisFeasLE(scip, SCIPvarGetUbGlobal(var), SCIPfeasCeil(scip, SCIPvarGetLbGlobal(var))));
8247 }
8250 )
8251 {
8252 SCIP_CALL( SCIPtightenVarUbGlobal(scip, var, SCIPfeasFloor(scip, SCIPvarGetUbGlobal(var)), TRUE, infeasible, &tightened) );
8253 if( *infeasible )
8254 return SCIP_OKAY;
8255
8256 assert(tightened || SCIPisFeasGE(scip, SCIPvarGetLbGlobal(var), SCIPfeasFloor(scip, SCIPvarGetUbGlobal(var))));
8257 }
8258 }
8259
8260 return SCIP_OKAY;
8261}
8262
8263/** changes type of variable in the problem;
8264 *
8265 * @warning This type change might change the variable array returned from SCIPgetVars() and SCIPgetVarsData();
8266 *
8267 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8268 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8269 *
8270 * @pre This method can be called if @p scip is in one of the following stages:
8271 * - \ref SCIP_STAGE_PROBLEM
8272 * - \ref SCIP_STAGE_TRANSFORMING
8273 * - \ref SCIP_STAGE_PRESOLVING
8274 *
8275 * @note If SCIP is already beyond the SCIP_STAGE_PROBLEM and a original variable is passed, the variable type of the
8276 * corresponding transformed variable is changed; the type of the original variable does not change
8277 *
8278 * @note If the type changes from a continuous variable to a non-continuous variable the bounds of the variable get
8279 * adjusted w.r.t. to integrality information
8280 */
8282 SCIP* scip, /**< SCIP data structure */
8283 SCIP_VAR* var, /**< variable to change the bound for */
8284 SCIP_VARTYPE vartype, /**< new type of variable */
8285 SCIP_Bool* infeasible /**< pointer to store whether an infeasibility was detected (, due to
8286 * integrality condition of the new variable type) */
8287 )
8288{
8290
8291 assert(var != NULL);
8292 assert(var->scip == scip);
8293
8294 if( SCIPvarIsNegated(var) )
8295 {
8296 SCIPdebugMsg(scip, "upgrading type of negated variable <%s> from %d to %d\n", SCIPvarGetName(var), SCIPvarGetType(var), vartype);
8297 var = SCIPvarGetNegationVar(var);
8298 }
8299#ifndef NDEBUG
8300 else
8301 {
8303 {
8304 SCIPdebugMsg(scip, "upgrading type of variable <%s> from %d to %d\n", SCIPvarGetName(var), SCIPvarGetType(var), vartype);
8305 }
8306 }
8307#endif
8308
8309 /* change variable type */
8310 switch( scip->set->stage )
8311 {
8312 case SCIP_STAGE_PROBLEM:
8313 assert(!SCIPvarIsTransformed(var));
8314
8315 /* first adjust the variable due to new integrality information */
8316 SCIP_CALL( tightenBounds(scip, var, vartype, infeasible) );
8317
8318 /* second change variable type */
8319 if( SCIPvarGetProbindex(var) >= 0 )
8320 {
8321 SCIP_CALL( SCIPprobChgVarType(scip->origprob, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8322 scip->branchcand, scip->eventqueue, scip->cliquetable, var, vartype) );
8323 }
8324 else
8325 {
8326 SCIP_CALL( SCIPvarChgType(var, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8327 scip->eventqueue, vartype) );
8328 }
8329 break;
8330
8332 if( !SCIPvarIsTransformed(var) )
8333 {
8334 SCIP_VAR* transvar;
8335
8336 SCIP_CALL( SCIPgetTransformedVar(scip, var, &transvar) );
8337 assert(transvar != NULL);
8338
8339 /* recall method with transformed variable */
8340 SCIP_CALL( SCIPchgVarType(scip, transvar, vartype, infeasible) );
8341 return SCIP_OKAY;
8342 }
8343
8344 /* first adjust the variable due to new integrality information */
8345 SCIP_CALL( tightenBounds(scip, var, vartype, infeasible) );
8346
8347 /* second change variable type */
8348 if( SCIPvarGetProbindex(var) >= 0 )
8349 {
8350 SCIP_CALL( SCIPprobChgVarType(scip->transprob, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8351 scip->branchcand, scip->eventqueue, scip->cliquetable, var, vartype) );
8352 }
8353 else
8354 {
8355 SCIP_CALL( SCIPvarChgType(var, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8356 scip->eventqueue, vartype) );
8357 }
8358 break;
8359
8360 default:
8361 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
8362 return SCIP_INVALIDCALL;
8363 } /*lint !e788*/
8364
8365 return SCIP_OKAY;
8366}
8367
8368/** in problem creation and solving stage, both bounds of the variable are set to the given value;
8369 * in presolving stage, the variable is converted into a fixed variable, and bounds are changed respectively;
8370 * conversion into a fixed variable changes the vars array returned from SCIPgetVars() and SCIPgetVarsData(),
8371 * and also renders arrays returned from the SCIPvarGetImpl...() methods invalid
8372 *
8373 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8374 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8375 *
8376 * @pre This method can be called if @p scip is in one of the following stages:
8377 * - \ref SCIP_STAGE_PROBLEM
8378 * - \ref SCIP_STAGE_PRESOLVING
8379 * - \ref SCIP_STAGE_SOLVING
8380 */
8382 SCIP* scip, /**< SCIP data structure */
8383 SCIP_VAR* var, /**< variable to fix */
8384 SCIP_Real fixedval, /**< value to fix variable to */
8385 SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
8386 SCIP_Bool* fixed /**< pointer to store whether the fixing was performed (variable was unfixed) */
8387 )
8388{
8389 assert(var != NULL);
8390 assert(infeasible != NULL);
8391 assert(fixed != NULL);
8392
8394
8395 *infeasible = FALSE;
8396 *fixed = FALSE;
8397
8398 /* in the problem creation stage, modify the bounds as requested, independently from the current bounds */
8399 if( scip->set->stage != SCIP_STAGE_PROBLEM )
8400 {
8402 {
8403 *infeasible = !SCIPsetIsFeasEQ(scip->set, fixedval, SCIPvarGetLbLocal(var));
8404 return SCIP_OKAY;
8405 }
8406 else if( ( SCIPvarIsIntegral(var) && !SCIPsetIsFeasIntegral(scip->set, fixedval) )
8407 || SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetLbLocal(var))
8408 || SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8409 {
8410 *infeasible = TRUE;
8411 return SCIP_OKAY;
8412 }
8413 }
8414 else
8416
8417 switch( scip->set->stage )
8418 {
8419 case SCIP_STAGE_PROBLEM:
8420 /* in the problem creation stage, modify the bounds as requested, independently from the current bounds */
8421 SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
8422 SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
8423 *fixed = TRUE;
8424 return SCIP_OKAY;
8425
8427 if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
8428 {
8429 SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8430 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8431 scip->cliquetable, fixedval, infeasible, fixed) );
8432 return SCIP_OKAY;
8433 }
8434 /*lint -fallthrough*/
8435 case SCIP_STAGE_SOLVING:
8436 if( SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetLbLocal(var)) )
8437 {
8438 if( SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8439 {
8440 *infeasible = TRUE;
8441 return SCIP_OKAY;
8442 }
8443 else
8444 {
8445 SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
8446 *fixed = TRUE;
8447 }
8448 }
8449 if( SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8450 {
8451 if( SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetLbLocal(var)) )
8452 {
8453 *infeasible = TRUE;
8454 return SCIP_OKAY;
8455 }
8456 else
8457 {
8458 SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
8459 *fixed = TRUE;
8460 }
8461 }
8462 return SCIP_OKAY;
8463
8464 default:
8465 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
8466 return SCIP_INVALIDCALL;
8467 } /*lint !e788*/
8468}
8469
8470/** From a given equality a*x + b*y == c, aggregates one of the variables and removes it from the set of
8471 * active problem variables. This changes the vars array returned from SCIPgetVars() and SCIPgetVarsData(),
8472 * and also renders the arrays returned from the SCIPvarGetImpl...() methods for the two variables invalid.
8473 * In the first step, the equality is transformed into an equality with active problem variables
8474 * a'*x' + b'*y' == c'. If x' == y', this leads to the detection of redundancy if a' == -b' and c' == 0,
8475 * of infeasibility, if a' == -b' and c' != 0, or to a variable fixing x' == c'/(a'+b') (and possible
8476 * infeasibility) otherwise.
8477 * In the second step, the variable to be aggregated is chosen among x' and y', prefering a less strict variable
8478 * type as aggregation variable (i.e. continuous variables are preferred over implicit integers, implicit integers
8479 * over integers, and integers over binaries). If none of the variables is continuous, it is tried to find an integer
8480 * aggregation (i.e. integral coefficients a'' and b'', such that a''*x' + b''*y' == c''). This can lead to
8481 * the detection of infeasibility (e.g. if c'' is fractional), or to a rejection of the aggregation (denoted by
8482 * aggregated == FALSE), if the resulting integer coefficients are too large and thus numerically instable.
8483 *
8484 * The output flags have the following meaning:
8485 * - infeasible: the problem is infeasible
8486 * - redundant: the equality can be deleted from the constraint set
8487 * - aggregated: the aggregation was successfully performed (the variables were not aggregated before)
8488 *
8489 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8490 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8491 *
8492 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PRESOLVING
8493 */
8495 SCIP* scip, /**< SCIP data structure */
8496 SCIP_VAR* varx, /**< variable x in equality a*x + b*y == c */
8497 SCIP_VAR* vary, /**< variable y in equality a*x + b*y == c */
8498 SCIP_Real scalarx, /**< multiplier a in equality a*x + b*y == c */
8499 SCIP_Real scalary, /**< multiplier b in equality a*x + b*y == c */
8500 SCIP_Real rhs, /**< right hand side c in equality a*x + b*y == c */
8501 SCIP_Bool* infeasible, /**< pointer to store whether the aggregation is infeasible */
8502 SCIP_Bool* redundant, /**< pointer to store whether the equality is (now) redundant */
8503 SCIP_Bool* aggregated /**< pointer to store whether the aggregation was successful */
8504 )
8505{
8506 SCIP_Real constantx;
8507 SCIP_Real constanty;
8508
8509 assert(infeasible != NULL);
8510 assert(redundant != NULL);
8511 assert(aggregated != NULL);
8512
8514
8515 *infeasible = FALSE;
8516 *redundant = FALSE;
8517 *aggregated = FALSE;
8518
8519 if( SCIPtreeProbing(scip->tree) )
8520 {
8521 SCIPerrorMessage("cannot aggregate variables during probing\n");
8522 return SCIP_INVALIDCALL;
8523 }
8524 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
8525
8526 /* do not perform aggregation if it is globally deactivated */
8527 if( scip->set->presol_donotaggr )
8528 return SCIP_OKAY;
8529
8530 /* get the corresponding equality in active problem variable space:
8531 * transform both expressions "a*x + 0" and "b*y + 0" into problem variable space
8532 */
8533 constantx = 0.0;
8534 constanty = 0.0;
8535 SCIP_CALL( SCIPvarGetProbvarSum(&varx, scip->set, &scalarx, &constantx) );
8536 SCIP_CALL( SCIPvarGetProbvarSum(&vary, scip->set, &scalary, &constanty) );
8537
8538 /* we cannot aggregate multi-aggregated variables */
8540 return SCIP_OKAY;
8541
8542 /* move the constant to the right hand side to acquire the form "a'*x' + b'*y' == c'" */
8543 rhs -= (constantx + constanty);
8544
8545 /* if a scalar is zero, treat the variable as fixed-to-zero variable */
8546 if( SCIPsetIsZero(scip->set, scalarx) )
8547 varx = NULL;
8548 if( SCIPsetIsZero(scip->set, scalary) )
8549 vary = NULL;
8550
8551 /* capture the special cases that less than two variables are left, due to resolutions to a fixed variable or
8552 * to the same active variable
8553 */
8554 if( varx == NULL && vary == NULL )
8555 {
8556 /* both variables were resolved to fixed variables */
8557 *infeasible = !SCIPsetIsZero(scip->set, rhs);
8558 *redundant = TRUE;
8559 }
8560 else if( varx == NULL )
8561 {
8562 assert(SCIPsetIsZero(scip->set, scalarx));
8563 assert(!SCIPsetIsZero(scip->set, scalary));
8564
8565 /* variable x was resolved to fixed variable: variable y can be fixed to c'/b' */
8566 SCIP_CALL( SCIPvarFix(vary, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8567 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8568 scip->cliquetable, rhs/scalary, infeasible, aggregated) );
8569 *redundant = TRUE;
8570 }
8571 else if( vary == NULL )
8572 {
8573 assert(SCIPsetIsZero(scip->set, scalary));
8574 assert(!SCIPsetIsZero(scip->set, scalarx));
8575
8576 /* variable y was resolved to fixed variable: variable x can be fixed to c'/a' */
8577 SCIP_CALL( SCIPvarFix(varx, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8578 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8579 scip->cliquetable, rhs/scalarx, infeasible, aggregated) );
8580 *redundant = TRUE;
8581 }
8582 else if( varx == vary )
8583 {
8584 /* both variables were resolved to the same active problem variable: this variable can be fixed */
8585 scalarx += scalary;
8586 if( SCIPsetIsZero(scip->set, scalarx) )
8587 {
8588 /* left hand side of equality is zero: equality is potentially infeasible */
8589 *infeasible = !SCIPsetIsZero(scip->set, rhs);
8590 }
8591 else
8592 {
8593 /* sum of scalars is not zero: fix variable x' == y' to c'/(a'+b') */
8594 SCIP_CALL( SCIPvarFix(varx, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8595 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8596 scip->cliquetable, rhs/scalarx, infeasible, aggregated) );
8597 }
8598 *redundant = TRUE;
8599 }
8600 else
8601 {
8602 /* both variables are different active problem variables, and both scalars are non-zero: try to aggregate them */
8603 SCIP_CALL( SCIPvarTryAggregateVars(scip->set, scip->mem->probmem, scip->stat, scip->transprob, scip->origprob,
8604 scip->primal, scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventfilter,
8605 scip->eventqueue, varx, vary, scalarx, scalary, rhs, infeasible, aggregated) );
8606 *redundant = *aggregated;
8607 }
8608
8609 return SCIP_OKAY;
8610}
8611
8612/** converts variable into multi-aggregated variable; this changes the variable array returned from
8613 * SCIPgetVars() and SCIPgetVarsData();
8614 *
8615 * @warning The integrality condition is not checked anymore on the multi-aggregated variable. You must not
8616 * multi-aggregate an integer variable without being sure, that integrality on the aggregation variables
8617 * implies integrality on the aggregated variable.
8618 *
8619 * The output flags have the following meaning:
8620 * - infeasible: the problem is infeasible
8621 * - aggregated: the aggregation was successfully performed (the variables were not aggregated before)
8622 *
8623 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8624 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8625 *
8626 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PRESOLVING
8627 */
8629 SCIP* scip, /**< SCIP data structure */
8630 SCIP_VAR* var, /**< variable x to aggregate */
8631 int naggvars, /**< number n of variables in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8632 SCIP_VAR** aggvars, /**< variables y_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8633 SCIP_Real* scalars, /**< multipliers a_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8634 SCIP_Real constant, /**< constant shift c in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8635 SCIP_Bool* infeasible, /**< pointer to store whether the aggregation is infeasible */
8636 SCIP_Bool* aggregated /**< pointer to store whether the aggregation was successful */
8637 )
8638{
8639 SCIP_CALL( SCIPcheckStage(scip, "SCIPmultiaggregateVar", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
8640
8641 assert(var->scip == scip);
8642
8643 if( SCIPtreeProbing(scip->tree) )
8644 {
8645 SCIPerrorMessage("cannot multi-aggregate variables during probing\n");
8646 return SCIP_INVALIDCALL;
8647 }
8648 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
8649
8650 SCIP_CALL( SCIPvarMultiaggregate(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8651 scip->primal, scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventfilter,
8652 scip->eventqueue, naggvars, aggvars, scalars, constant, infeasible, aggregated) );
8653
8654 return SCIP_OKAY;
8655}
8656
8657/** returns whether aggregation of variables is not allowed */
8659 SCIP* scip /**< SCIP data structure */
8660 )
8661{
8662 assert(scip != NULL);
8663
8664 return scip->set->presol_donotaggr;
8665}
8666
8667/** returns whether multi-aggregation is disabled */
8669 SCIP* scip /**< SCIP data structure */
8670 )
8671{
8672 assert(scip != NULL);
8673
8674 return scip->set->presol_donotmultaggr;
8675}
8676
8677/** returns whether variable is not allowed to be aggregated */
8679 SCIP* scip, /**< SCIP data structure */
8680 SCIP_VAR* var /**< variable x to aggregate */
8681 )
8682{
8683 assert(scip != NULL);
8684 assert(var != NULL);
8685 assert(var->scip == scip);
8686
8687 return scip->set->presol_donotaggr || SCIPvarDoNotAggr(var);
8688}
8689
8690/** returns whether variable is not allowed to be multi-aggregated */
8692 SCIP* scip, /**< SCIP data structure */
8693 SCIP_VAR* var /**< variable x to aggregate */
8694 )
8695{
8696 assert(scip != NULL);
8697 assert(var != NULL);
8698 assert(var->scip == scip);
8699
8700 return scip->set->presol_donotmultaggr || SCIPvarDoNotMultaggr(var);
8701}
8702
8703/** returns whether dual reductions are allowed during propagation and presolving
8704 *
8705 * @deprecated Please use SCIPallowStrongDualReds()
8706 */
8708 SCIP* scip /**< SCIP data structure */
8709 )
8710{
8711 assert(scip != NULL);
8712
8713 return !scip->set->reopt_enable && scip->set->misc_allowstrongdualreds;
8714}
8715
8716/** returns whether strong dual reductions are allowed during propagation and presolving
8717 *
8718 * @note A reduction is called strong dual, if it may discard feasible/optimal solutions, but leaves at least one
8719 * optimal solution intact. Often such reductions are based on analyzing the objective function and variable
8720 * locks.
8721 */
8723 SCIP* scip /**< SCIP data structure */
8724 )
8725{
8726 assert(scip != NULL);
8727
8728 return !scip->set->reopt_enable && scip->set->misc_allowstrongdualreds;
8729}
8730
8731/** returns whether propagation w.r.t. current objective is allowed
8732 *
8733 * @deprecated Please use SCIPallowWeakDualReds()
8734 */
8736 SCIP* scip /**< SCIP data structure */
8737 )
8738{
8739 assert(scip != NULL);
8740
8741 return !scip->set->reopt_enable && scip->set->misc_allowweakdualreds;
8742}
8743
8744/** returns whether weak dual reductions are allowed during propagation and presolving
8745 *
8746 * @note A reduction is called weak dual, if it may discard feasible solutions, but leaves at all optimal solutions
8747 * intact. Often such reductions are based on analyzing the objective function, reduced costs, and/or dual LPs.
8748 */
8750 SCIP* scip /**< SCIP data structure */
8751 )
8752{
8753 assert(scip != NULL);
8754
8755 return !scip->set->reopt_enable && scip->set->misc_allowweakdualreds;
8756}
8757
8758/** marks the variable that it must not be aggregated
8759 *
8760 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8761 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8762 *
8763 * @pre This method can be called if @p scip is in one of the following stages:
8764 * - \ref SCIP_STAGE_INIT
8765 * - \ref SCIP_STAGE_PROBLEM
8766 * - \ref SCIP_STAGE_TRANSFORMING
8767 * - \ref SCIP_STAGE_TRANSFORMED
8768 * - \ref SCIP_STAGE_INITPRESOLVE
8769 * - \ref SCIP_STAGE_PRESOLVING
8770 * - \ref SCIP_STAGE_EXITPRESOLVE
8771 *
8772 * @note There exists no "unmark" method since it has to be ensured that if a plugin requires that a variable is not
8773 * aggregated that this is will be the case.
8774 */
8776 SCIP* scip, /**< SCIP data structure */
8777 SCIP_VAR* var /**< variable to delete */
8778 )
8779{
8780 assert(scip != NULL);
8781 assert(var != NULL);
8782 assert(var->scip == scip);
8783
8784 SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkDoNotAggrVar", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE) );
8785
8787
8788 return SCIP_OKAY;
8789}
8790
8791/** marks the variable that it must not be multi-aggregated
8792 *
8793 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8794 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8795 *
8796 * @pre This method can be called if @p scip is in one of the following stages:
8797 * - \ref SCIP_STAGE_INIT
8798 * - \ref SCIP_STAGE_PROBLEM
8799 * - \ref SCIP_STAGE_TRANSFORMING
8800 * - \ref SCIP_STAGE_TRANSFORMED
8801 * - \ref SCIP_STAGE_INITPRESOLVE
8802 * - \ref SCIP_STAGE_PRESOLVING
8803 * - \ref SCIP_STAGE_EXITPRESOLVE
8804 *
8805 * @note There exists no "unmark" method since it has to be ensured that if a plugin requires that a variable is not
8806 * multi-aggregated that this is will be the case.
8807 */
8809 SCIP* scip, /**< SCIP data structure */
8810 SCIP_VAR* var /**< variable to delete */
8811 )
8812{
8813 assert(scip != NULL);
8814 assert(var != NULL);
8815 assert(var->scip == scip);
8816
8817 SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkDoNotMultaggrVar", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE) );
8818
8820
8821 return SCIP_OKAY;
8822}
8823
8824/** enables the collection of statistics for a variable
8825 *
8826 * @pre This method can be called if @p scip is in one of the following stages:
8827 * - \ref SCIP_STAGE_PROBLEM
8828 * - \ref SCIP_STAGE_INITPRESOLVE
8829 * - \ref SCIP_STAGE_PRESOLVING
8830 * - \ref SCIP_STAGE_EXITPRESOLVE
8831 * - \ref SCIP_STAGE_SOLVING
8832 * - \ref SCIP_STAGE_SOLVED
8833 */
8835 SCIP* scip /**< SCIP data structure */
8836 )
8837{
8838 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPenableVarHistory", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8839
8841}
8842
8843/** disables the collection of any statistic for a variable
8844 *
8845 * @pre This method can be called if @p scip is in one of the following stages:
8846 * - \ref SCIP_STAGE_PROBLEM
8847 * - \ref SCIP_STAGE_INITPRESOLVE
8848 * - \ref SCIP_STAGE_PRESOLVING
8849 * - \ref SCIP_STAGE_EXITPRESOLVE
8850 * - \ref SCIP_STAGE_SOLVING
8851 * - \ref SCIP_STAGE_SOLVED
8852 */
8854 SCIP* scip /**< SCIP data structure */
8855 )
8856{
8857 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPdisableVarHistory", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8858
8860}
8861
8862/** updates the pseudo costs of the given variable and the global pseudo costs after a change of "solvaldelta" in the
8863 * variable's solution value and resulting change of "objdelta" in the in the LP's objective value;
8864 * the update is ignored, if the objective value difference is infinite
8865 *
8866 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8867 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8868 *
8869 * @pre This method can be called if @p scip is in one of the following stages:
8870 * - \ref SCIP_STAGE_SOLVING
8871 * - \ref SCIP_STAGE_SOLVED
8872 */
8874 SCIP* scip, /**< SCIP data structure */
8875 SCIP_VAR* var, /**< problem variable */
8876 SCIP_Real solvaldelta, /**< difference of variable's new LP value - old LP value */
8877 SCIP_Real objdelta, /**< difference of new LP's objective value - old LP's objective value */
8878 SCIP_Real weight /**< weight in (0,1] of this update in pseudo cost sum */
8879 )
8880{
8881 SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateVarPseudocost", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8882
8883 if( !SCIPsetIsInfinity(scip->set, 2*objdelta) ) /* differences infinity - eps should also be treated as infinity */
8884 {
8885 if( scip->set->branch_divingpscost || (!scip->lp->diving && !SCIPtreeProbing(scip->tree)) )
8886 {
8887 SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, solvaldelta, objdelta, weight) );
8888 }
8889 }
8890
8891 return SCIP_OKAY;
8892}
8893
8894/** gets the variable's pseudo cost value for the given change of the variable's LP value
8895 *
8896 * @return the variable's pseudo cost value for the given change of the variable's LP value
8897 *
8898 * @pre This method can be called if @p scip is in one of the following stages:
8899 * - \ref SCIP_STAGE_INITPRESOLVE
8900 * - \ref SCIP_STAGE_PRESOLVING
8901 * - \ref SCIP_STAGE_EXITPRESOLVE
8902 * - \ref SCIP_STAGE_PRESOLVED
8903 * - \ref SCIP_STAGE_INITSOLVE
8904 * - \ref SCIP_STAGE_SOLVING
8905 * - \ref SCIP_STAGE_SOLVED
8906 */
8908 SCIP* scip, /**< SCIP data structure */
8909 SCIP_VAR* var, /**< problem variable */
8910 SCIP_Real solvaldelta /**< difference of variable's new LP value - old LP value */
8911 )
8912{
8913 assert( var->scip == scip );
8914
8915 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostVal", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8916
8917 return SCIPvarGetPseudocost(var, scip->stat, solvaldelta);
8918}
8919
8920/** gets the variable's pseudo cost value for the given change of the variable's LP value,
8921 * only using the pseudo cost information of the current run
8922 *
8923 * @return the variable's pseudo cost value for the given change of the variable's LP value,
8924 * only using the pseudo cost information of the current run
8925 *
8926 * @pre This method can be called if @p scip is in one of the following stages:
8927 * - \ref SCIP_STAGE_INITPRESOLVE
8928 * - \ref SCIP_STAGE_PRESOLVING
8929 * - \ref SCIP_STAGE_EXITPRESOLVE
8930 * - \ref SCIP_STAGE_PRESOLVED
8931 * - \ref SCIP_STAGE_INITSOLVE
8932 * - \ref SCIP_STAGE_SOLVING
8933 * - \ref SCIP_STAGE_SOLVED
8934 */
8936 SCIP* scip, /**< SCIP data structure */
8937 SCIP_VAR* var, /**< problem variable */
8938 SCIP_Real solvaldelta /**< difference of variable's new LP value - old LP value */
8939 )
8940{
8941 assert( var->scip == scip );
8942
8943 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostValCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8944
8945 return SCIPvarGetPseudocostCurrentRun(var, scip->stat, solvaldelta);
8946}
8947
8948/** gets the variable's pseudo cost value for the given direction
8949 *
8950 * @return the variable's pseudo cost value for the given direction
8951 *
8952 * @pre This method can be called if @p scip is in one of the following stages:
8953 * - \ref SCIP_STAGE_INITPRESOLVE
8954 * - \ref SCIP_STAGE_PRESOLVING
8955 * - \ref SCIP_STAGE_EXITPRESOLVE
8956 * - \ref SCIP_STAGE_PRESOLVED
8957 * - \ref SCIP_STAGE_INITSOLVE
8958 * - \ref SCIP_STAGE_SOLVING
8959 * - \ref SCIP_STAGE_SOLVED
8960 */
8962 SCIP* scip, /**< SCIP data structure */
8963 SCIP_VAR* var, /**< problem variable */
8964 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8965 )
8966{
8967 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocost", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8968 assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8969 assert(var->scip == scip);
8970
8971 return SCIPvarGetPseudocost(var, scip->stat, dir == SCIP_BRANCHDIR_DOWNWARDS ? -1.0 : 1.0);
8972}
8973
8974/** gets the variable's pseudo cost value for the given direction,
8975 * only using the pseudo cost information of the current run
8976 *
8977 * @return the variable's pseudo cost value for the given direction,
8978 * only using the pseudo cost information of the current run
8979 *
8980 * @pre This method can be called if @p scip is in one of the following stages:
8981 * - \ref SCIP_STAGE_INITPRESOLVE
8982 * - \ref SCIP_STAGE_PRESOLVING
8983 * - \ref SCIP_STAGE_EXITPRESOLVE
8984 * - \ref SCIP_STAGE_PRESOLVED
8985 * - \ref SCIP_STAGE_INITSOLVE
8986 * - \ref SCIP_STAGE_SOLVING
8987 * - \ref SCIP_STAGE_SOLVED
8988 */
8990 SCIP* scip, /**< SCIP data structure */
8991 SCIP_VAR* var, /**< problem variable */
8992 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8993 )
8994{
8995 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8996 assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8997 assert(var->scip == scip);
8998
8999 return SCIPvarGetPseudocostCurrentRun(var, scip->stat, dir == SCIP_BRANCHDIR_DOWNWARDS ? -1.0 : 1.0);
9000}
9001
9002/** gets the variable's (possible fractional) number of pseudo cost updates for the given direction
9003 *
9004 * @return the variable's (possible fractional) number of pseudo cost updates for the given direction
9005 *
9006 * @pre This method can be called if @p scip is in one of the following stages:
9007 * - \ref SCIP_STAGE_INITPRESOLVE
9008 * - \ref SCIP_STAGE_PRESOLVING
9009 * - \ref SCIP_STAGE_EXITPRESOLVE
9010 * - \ref SCIP_STAGE_PRESOLVED
9011 * - \ref SCIP_STAGE_INITSOLVE
9012 * - \ref SCIP_STAGE_SOLVING
9013 * - \ref SCIP_STAGE_SOLVED
9014 */
9016 SCIP* scip, /**< SCIP data structure */
9017 SCIP_VAR* var, /**< problem variable */
9018 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9019 )
9020{
9021 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCount", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9022 assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
9023 assert(var->scip == scip);
9024
9025 return SCIPvarGetPseudocostCount(var, dir);
9026}
9027
9028/** gets the variable's (possible fractional) number of pseudo cost updates for the given direction,
9029 * only using the pseudo cost information of the current run
9030 *
9031 * @return the variable's (possible fractional) number of pseudo cost updates for the given direction,
9032 * only using the pseudo cost information of the current run
9033 *
9034 * @pre This method can be called if @p scip is in one of the following stages:
9035 * - \ref SCIP_STAGE_INITPRESOLVE
9036 * - \ref SCIP_STAGE_PRESOLVING
9037 * - \ref SCIP_STAGE_EXITPRESOLVE
9038 * - \ref SCIP_STAGE_PRESOLVED
9039 * - \ref SCIP_STAGE_INITSOLVE
9040 * - \ref SCIP_STAGE_SOLVING
9041 * - \ref SCIP_STAGE_SOLVED
9042 */
9044 SCIP* scip, /**< SCIP data structure */
9045 SCIP_VAR* var, /**< problem variable */
9046 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9047 )
9048{
9049 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCountCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9050 assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
9051 assert(var->scip == scip);
9052
9053 return SCIPvarGetPseudocostCountCurrentRun(var, dir);
9054}
9055
9056/** get pseudo cost variance of the variable, either for entire solve or only for current branch and bound run
9057 *
9058 * @return returns the (corrected) variance of pseudo code information collected so far.
9059 *
9060 * @pre This method can be called if @p scip is in one of the following stages:
9061 * - \ref SCIP_STAGE_INITPRESOLVE
9062 * - \ref SCIP_STAGE_PRESOLVING
9063 * - \ref SCIP_STAGE_EXITPRESOLVE
9064 * - \ref SCIP_STAGE_PRESOLVED
9065 * - \ref SCIP_STAGE_INITSOLVE
9066 * - \ref SCIP_STAGE_SOLVING
9067 * - \ref SCIP_STAGE_SOLVED
9068 */
9070 SCIP* scip, /**< SCIP data structure */
9071 SCIP_VAR* var, /**< problem variable */
9072 SCIP_BRANCHDIR dir, /**< branching direction (downwards, or upwards) */
9073 SCIP_Bool onlycurrentrun /**< only for pseudo costs of current branch and bound run */
9074 )
9075{
9076 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostVariance", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9077 assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
9078 assert(var->scip == scip);
9079
9080 return SCIPvarGetPseudocostVariance(var, dir, onlycurrentrun);
9081}
9082
9083/** calculates a confidence bound for this variable under the assumption of normally distributed pseudo costs
9084 *
9085 * The confidence bound \f$ \theta \geq 0\f$ denotes the interval borders \f$ [X - \theta, \ X + \theta]\f$, which contains
9086 * the true pseudo costs of the variable, i.e., the expected value of the normal distribution, with a probability
9087 * of 2 * clevel - 1.
9088 *
9089 * @return value of confidence bound for this variable
9090 */
9092 SCIP* scip, /**< SCIP data structure */
9093 SCIP_VAR* var, /**< variable in question */
9094 SCIP_BRANCHDIR dir, /**< the branching direction for the confidence bound */
9095 SCIP_Bool onlycurrentrun, /**< should only the current run be taken into account */
9096 SCIP_CONFIDENCELEVEL clevel /**< confidence level for the interval */
9097 )
9098{
9099 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPcalculatePscostConfidenceBound", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9100
9101 return SCIPvarCalcPscostConfidenceBound(var, scip->set, dir, onlycurrentrun, clevel);
9102}
9103
9104/** check if variable pseudo-costs have a significant difference in location. The significance depends on
9105 * the choice of \p clevel and on the kind of tested hypothesis. The one-sided hypothesis, which
9106 * should be rejected, is that fracy * mu_y >= fracx * mu_x, where mu_y and mu_x denote the
9107 * unknown location means of the underlying pseudo-cost distributions of x and y.
9108 *
9109 * This method is applied best if variable x has a better pseudo-cost score than y. The method hypothesizes that y were actually
9110 * better than x (despite the current information), meaning that y can be expected to yield branching
9111 * decisions as least as good as x in the long run. If the method returns TRUE, the current history information is
9112 * sufficient to safely rely on the alternative hypothesis that x yields indeed a better branching score (on average)
9113 * than y.
9114 *
9115 * @note The order of x and y matters for the one-sided hypothesis
9116 *
9117 * @note set \p onesided to FALSE if you are not sure which variable is better. The hypothesis tested then reads
9118 * fracy * mu_y == fracx * mu_x vs the alternative hypothesis fracy * mu_y != fracx * mu_x.
9119 *
9120 * @return TRUE if the hypothesis can be safely rejected at the given confidence level
9121 */
9123 SCIP* scip, /**< SCIP data structure */
9124 SCIP_VAR* varx, /**< variable x */
9125 SCIP_Real fracx, /**< the fractionality of variable x */
9126 SCIP_VAR* vary, /**< variable y */
9127 SCIP_Real fracy, /**< the fractionality of variable y */
9128 SCIP_BRANCHDIR dir, /**< branching direction */
9129 SCIP_CONFIDENCELEVEL clevel, /**< confidence level for rejecting hypothesis */
9130 SCIP_Bool onesided /**< should a one-sided hypothesis y >= x be tested? */
9131 )
9132{
9133 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPsignificantVarPscostDifference", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9134
9135 return SCIPvarSignificantPscostDifference(scip->set, scip->stat, varx, fracx, vary, fracy, dir, clevel, onesided);
9136}
9137
9138/** tests at a given confidence level whether the variable pseudo-costs only have a small probability to
9139 * exceed a \p threshold. This is useful to determine if past observations provide enough evidence
9140 * to skip an expensive strong-branching step if there is already a candidate that has been proven to yield an improvement
9141 * of at least \p threshold.
9142 *
9143 * @note use \p clevel to adjust the level of confidence. For SCIP_CONFIDENCELEVEL_MIN, the method returns TRUE if
9144 * the estimated probability to exceed \p threshold is less than 25 %.
9145 *
9146 * @see SCIP_Confidencelevel for a list of available levels. The used probability limits refer to the one-sided levels
9147 * of confidence.
9148 *
9149 * @return TRUE if the variable pseudo-cost probabilistic model is likely to be smaller than \p threshold
9150 * at the given confidence level \p clevel.
9151 */
9153 SCIP* scip, /**< SCIP data structure */
9154 SCIP_VAR* var, /**< variable x */
9155 SCIP_Real frac, /**< the fractionality of variable x */
9156 SCIP_Real threshold, /**< the threshold to test against */
9157 SCIP_BRANCHDIR dir, /**< branching direction */
9158 SCIP_CONFIDENCELEVEL clevel /**< confidence level for rejecting hypothesis */
9159 )
9160{
9161 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPpscostThresholdProbabilityTest", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9162
9163 return SCIPvarPscostThresholdProbabilityTest(scip->set, scip->stat, var, frac, threshold, dir, clevel);
9164}
9165
9166/** check if the current pseudo cost relative error in a direction violates the given threshold. The Relative
9167 * Error is calculated at a specific confidence level
9168 *
9169 * @return TRUE if relative error in variable pseudo costs is smaller than \p threshold
9170 */
9172 SCIP* scip, /**< SCIP data structure */
9173 SCIP_VAR* var, /**< variable in question */
9174 SCIP_Real threshold, /**< threshold for relative errors to be considered reliable (enough) */
9175 SCIP_CONFIDENCELEVEL clevel /**< a given confidence level */
9176 )
9177{
9178 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisVarPscostRelerrorReliable", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9179
9180 return SCIPvarIsPscostRelerrorReliable(var, scip->set, scip->stat, threshold, clevel);
9181}
9182
9183/** gets the variable's pseudo cost score value for the given LP solution value
9184 *
9185 * @return the variable's pseudo cost score value for the given LP solution value
9186 *
9187 * @pre This method can be called if @p scip is in one of the following stages:
9188 * - \ref SCIP_STAGE_INITPRESOLVE
9189 * - \ref SCIP_STAGE_PRESOLVING
9190 * - \ref SCIP_STAGE_EXITPRESOLVE
9191 * - \ref SCIP_STAGE_PRESOLVED
9192 * - \ref SCIP_STAGE_INITSOLVE
9193 * - \ref SCIP_STAGE_SOLVING
9194 * - \ref SCIP_STAGE_SOLVED
9195 */
9197 SCIP* scip, /**< SCIP data structure */
9198 SCIP_VAR* var, /**< problem variable */
9199 SCIP_Real solval /**< variable's LP solution value */
9200 )
9201{
9202 SCIP_Real downsol;
9203 SCIP_Real upsol;
9204 SCIP_Real pscostdown;
9205 SCIP_Real pscostup;
9206
9207 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9208
9209 assert( var->scip == scip );
9210
9211 downsol = SCIPsetFeasCeil(scip->set, solval-1.0);
9212 upsol = SCIPsetFeasFloor(scip->set, solval+1.0);
9213 pscostdown = SCIPvarGetPseudocost(var, scip->stat, downsol-solval);
9214 pscostup = SCIPvarGetPseudocost(var, scip->stat, upsol-solval);
9215
9216 return SCIPbranchGetScore(scip->set, var, pscostdown, pscostup);
9217}
9218
9219/** gets the variable's pseudo cost score value for the given LP solution value,
9220 * only using the pseudo cost information of the current run
9221 *
9222 * @return the variable's pseudo cost score value for the given LP solution value,
9223 * only using the pseudo cost information of the current run
9224 *
9225 * @pre This method can be called if @p scip is in one of the following stages:
9226 * - \ref SCIP_STAGE_INITPRESOLVE
9227 * - \ref SCIP_STAGE_PRESOLVING
9228 * - \ref SCIP_STAGE_EXITPRESOLVE
9229 * - \ref SCIP_STAGE_PRESOLVED
9230 * - \ref SCIP_STAGE_INITSOLVE
9231 * - \ref SCIP_STAGE_SOLVING
9232 * - \ref SCIP_STAGE_SOLVED
9233 */
9235 SCIP* scip, /**< SCIP data structure */
9236 SCIP_VAR* var, /**< problem variable */
9237 SCIP_Real solval /**< variable's LP solution value */
9238 )
9239{
9240 SCIP_Real downsol;
9241 SCIP_Real upsol;
9242 SCIP_Real pscostdown;
9243 SCIP_Real pscostup;
9244
9245 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9246
9247 assert( var->scip == scip );
9248
9249 downsol = SCIPsetFeasCeil(scip->set, solval-1.0);
9250 upsol = SCIPsetFeasFloor(scip->set, solval+1.0);
9251 pscostdown = SCIPvarGetPseudocostCurrentRun(var, scip->stat, downsol-solval);
9252 pscostup = SCIPvarGetPseudocostCurrentRun(var, scip->stat, upsol-solval);
9253
9254 return SCIPbranchGetScore(scip->set, var, pscostdown, pscostup);
9255}
9256
9257/** returns the variable's VSIDS value
9258 *
9259 * @return the variable's VSIDS value
9260 *
9261 * @pre This method can be called if @p scip is in one of the following stages:
9262 * - \ref SCIP_STAGE_INITPRESOLVE
9263 * - \ref SCIP_STAGE_PRESOLVING
9264 * - \ref SCIP_STAGE_EXITPRESOLVE
9265 * - \ref SCIP_STAGE_PRESOLVED
9266 * - \ref SCIP_STAGE_INITSOLVE
9267 * - \ref SCIP_STAGE_SOLVING
9268 * - \ref SCIP_STAGE_SOLVED
9269 */
9271 SCIP* scip, /**< SCIP data structure */
9272 SCIP_VAR* var, /**< problem variable */
9273 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9274 )
9275{
9277
9278 assert( var->scip == scip );
9279
9281 {
9282 SCIPerrorMessage("invalid branching direction %d when asking for VSIDS value\n", dir);
9283 return SCIP_INVALID;
9284 }
9285
9286 return SCIPvarGetVSIDS(var, scip->stat, dir);
9287}
9288
9289/** returns the variable's VSIDS value only using conflicts of the current run
9290 *
9291 * @return the variable's VSIDS value only using conflicts of the current run
9292 *
9293 * @pre This method can be called if @p scip is in one of the following stages:
9294 * - \ref SCIP_STAGE_INITPRESOLVE
9295 * - \ref SCIP_STAGE_PRESOLVING
9296 * - \ref SCIP_STAGE_EXITPRESOLVE
9297 * - \ref SCIP_STAGE_PRESOLVED
9298 * - \ref SCIP_STAGE_INITSOLVE
9299 * - \ref SCIP_STAGE_SOLVING
9300 * - \ref SCIP_STAGE_SOLVED
9301 */
9303 SCIP* scip, /**< SCIP data structure */
9304 SCIP_VAR* var, /**< problem variable */
9305 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9306 )
9307{
9308 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarVSIDSCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9309
9310 assert( var->scip == scip );
9311
9313 {
9314 SCIPerrorMessage("invalid branching direction %d when asking for VSIDS value\n", dir);
9315 return SCIP_INVALID;
9316 }
9317
9318 return SCIPvarGetVSIDSCurrentRun(var, scip->stat, dir);
9319}
9320
9321/** returns the variable's conflict score value
9322 *
9323 * @return the variable's conflict score value
9324 *
9325 * @pre This method can be called if @p scip is in one of the following stages:
9326 * - \ref SCIP_STAGE_INITPRESOLVE
9327 * - \ref SCIP_STAGE_PRESOLVING
9328 * - \ref SCIP_STAGE_EXITPRESOLVE
9329 * - \ref SCIP_STAGE_PRESOLVED
9330 * - \ref SCIP_STAGE_INITSOLVE
9331 * - \ref SCIP_STAGE_SOLVING
9332 * - \ref SCIP_STAGE_SOLVED
9333 */
9335 SCIP* scip, /**< SCIP data structure */
9336 SCIP_VAR* var /**< problem variable */
9337 )
9338{
9339 SCIP_Real downscore;
9340 SCIP_Real upscore;
9341
9342 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9343
9344 assert( var->scip == scip );
9345
9346 downscore = SCIPvarGetVSIDS(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9347 upscore = SCIPvarGetVSIDS(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9348
9349 return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9350}
9351
9352/** returns the variable's conflict score value only using conflicts of the current run
9353 *
9354 * @return the variable's conflict score value only using conflicts of the current run
9355 *
9356 * @pre This method can be called if @p scip is in one of the following stages:
9357 * - \ref SCIP_STAGE_INITPRESOLVE
9358 * - \ref SCIP_STAGE_PRESOLVING
9359 * - \ref SCIP_STAGE_EXITPRESOLVE
9360 * - \ref SCIP_STAGE_PRESOLVED
9361 * - \ref SCIP_STAGE_INITSOLVE
9362 * - \ref SCIP_STAGE_SOLVING
9363 * - \ref SCIP_STAGE_SOLVED
9364 */
9366 SCIP* scip, /**< SCIP data structure */
9367 SCIP_VAR* var /**< problem variable */
9368 )
9369{
9370 SCIP_Real downscore;
9371 SCIP_Real upscore;
9372
9373 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9374
9375 assert( var->scip == scip );
9376
9379
9380 return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9381}
9382
9383/** returns the variable's conflict length score
9384 *
9385 * @return the variable's conflict length score
9386 *
9387 * @pre This method can be called if @p scip is in one of the following stages:
9388 * - \ref SCIP_STAGE_INITPRESOLVE
9389 * - \ref SCIP_STAGE_PRESOLVING
9390 * - \ref SCIP_STAGE_EXITPRESOLVE
9391 * - \ref SCIP_STAGE_PRESOLVED
9392 * - \ref SCIP_STAGE_INITSOLVE
9393 * - \ref SCIP_STAGE_SOLVING
9394 * - \ref SCIP_STAGE_SOLVED
9395 */
9397 SCIP* scip, /**< SCIP data structure */
9398 SCIP_VAR* var /**< problem variable */
9399 )
9400{
9401 SCIP_Real downscore;
9402 SCIP_Real upscore;
9403
9404 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictlengthScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9405
9406 assert( var->scip == scip );
9407
9410
9411 return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9412}
9413
9414/** returns the variable's conflict length score only using conflicts of the current run
9415 *
9416 * @return the variable's conflict length score only using conflicts of the current run
9417 *
9418 * @pre This method can be called if @p scip is in one of the following stages:
9419 * - \ref SCIP_STAGE_INITPRESOLVE
9420 * - \ref SCIP_STAGE_PRESOLVING
9421 * - \ref SCIP_STAGE_EXITPRESOLVE
9422 * - \ref SCIP_STAGE_PRESOLVED
9423 * - \ref SCIP_STAGE_INITSOLVE
9424 * - \ref SCIP_STAGE_SOLVING
9425 * - \ref SCIP_STAGE_SOLVED
9426 */
9428 SCIP* scip, /**< SCIP data structure */
9429 SCIP_VAR* var /**< problem variable */
9430 )
9431{
9432 SCIP_Real downscore;
9433 SCIP_Real upscore;
9434
9435 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictlengthScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9436
9437 assert( var->scip == scip );
9438
9441
9442 return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9443}
9444
9445/** returns the variable's average conflict length
9446 *
9447 * @return the variable's average conflict length
9448 *
9449 * @pre This method can be called if @p scip is in one of the following stages:
9450 * - \ref SCIP_STAGE_INITPRESOLVE
9451 * - \ref SCIP_STAGE_PRESOLVING
9452 * - \ref SCIP_STAGE_EXITPRESOLVE
9453 * - \ref SCIP_STAGE_PRESOLVED
9454 * - \ref SCIP_STAGE_INITSOLVE
9455 * - \ref SCIP_STAGE_SOLVING
9456 * - \ref SCIP_STAGE_SOLVED
9457 */
9459 SCIP* scip, /**< SCIP data structure */
9460 SCIP_VAR* var, /**< problem variable */
9461 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9462 )
9463{
9464 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgConflictlength", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9465
9466 assert( var->scip == scip );
9467
9468 return SCIPvarGetAvgConflictlength(var, dir);
9469}
9470
9471/** returns the variable's average conflict length only using conflicts of the current run
9472 *
9473 * @return the variable's average conflict length only using conflicts of the current run
9474 *
9475 * @pre This method can be called if @p scip is in one of the following stages:
9476 * - \ref SCIP_STAGE_INITPRESOLVE
9477 * - \ref SCIP_STAGE_PRESOLVING
9478 * - \ref SCIP_STAGE_EXITPRESOLVE
9479 * - \ref SCIP_STAGE_PRESOLVED
9480 * - \ref SCIP_STAGE_INITSOLVE
9481 * - \ref SCIP_STAGE_SOLVING
9482 * - \ref SCIP_STAGE_SOLVED
9483 */
9485 SCIP* scip, /**< SCIP data structure */
9486 SCIP_VAR* var, /**< problem variable */
9487 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9488 )
9489{
9490 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgConflictlengthCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9491
9492 assert( var->scip == scip );
9493
9495}
9496
9497/** returns the average number of inferences found after branching on the variable in given direction;
9498 * if branching on the variable in the given direction was yet evaluated, the average number of inferences
9499 * over all variables for branching in the given direction is returned
9500 *
9501 * @return the average number of inferences found after branching on the variable in given direction
9502 *
9503 * @pre This method can be called if @p scip is in one of the following stages:
9504 * - \ref SCIP_STAGE_INITPRESOLVE
9505 * - \ref SCIP_STAGE_PRESOLVING
9506 * - \ref SCIP_STAGE_EXITPRESOLVE
9507 * - \ref SCIP_STAGE_PRESOLVED
9508 * - \ref SCIP_STAGE_INITSOLVE
9509 * - \ref SCIP_STAGE_SOLVING
9510 * - \ref SCIP_STAGE_SOLVED
9511 */
9513 SCIP* scip, /**< SCIP data structure */
9514 SCIP_VAR* var, /**< problem variable */
9515 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9516 )
9517{
9518 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferences", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9519
9520 assert( var->scip == scip );
9521
9522 return SCIPvarGetAvgInferences(var, scip->stat, dir);
9523}
9524
9525/** returns the average number of inferences found after branching on the variable in given direction in the current run;
9526 * if branching on the variable in the given direction was yet evaluated, the average number of inferences
9527 * over all variables for branching in the given direction is returned
9528 *
9529 * @return the average number of inferences found after branching on the variable in given direction in the current run
9530 *
9531 * @pre This method can be called if @p scip is in one of the following stages:
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 * - \ref SCIP_STAGE_SOLVED
9539 */
9541 SCIP* scip, /**< SCIP data structure */
9542 SCIP_VAR* var, /**< problem variable */
9543 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9544 )
9545{
9546 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferencesCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9547
9548 assert( var->scip == scip );
9549
9550 return SCIPvarGetAvgInferencesCurrentRun(var, scip->stat, dir);
9551}
9552
9553/** returns the variable's average inference score value
9554 *
9555 * @return the variable's average inference score value
9556 *
9557 * @pre This method can be called if @p scip is in one of the following stages:
9558 * - \ref SCIP_STAGE_INITPRESOLVE
9559 * - \ref SCIP_STAGE_PRESOLVING
9560 * - \ref SCIP_STAGE_EXITPRESOLVE
9561 * - \ref SCIP_STAGE_PRESOLVED
9562 * - \ref SCIP_STAGE_INITSOLVE
9563 * - \ref SCIP_STAGE_SOLVING
9564 * - \ref SCIP_STAGE_SOLVED
9565 */
9567 SCIP* scip, /**< SCIP data structure */
9568 SCIP_VAR* var /**< problem variable */
9569 )
9570{
9571 SCIP_Real inferdown;
9572 SCIP_Real inferup;
9573
9574 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9575
9576 assert( var->scip == scip );
9577
9578 inferdown = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9580
9581 return SCIPbranchGetScore(scip->set, var, inferdown, inferup);
9582}
9583
9584/** returns the variable's average inference score value only using inferences of the current run
9585 *
9586 * @return the variable's average inference score value only using inferences of the current run
9587 *
9588 * @pre This method can be called if @p scip is in one of the following stages:
9589 * - \ref SCIP_STAGE_INITPRESOLVE
9590 * - \ref SCIP_STAGE_PRESOLVING
9591 * - \ref SCIP_STAGE_EXITPRESOLVE
9592 * - \ref SCIP_STAGE_PRESOLVED
9593 * - \ref SCIP_STAGE_INITSOLVE
9594 * - \ref SCIP_STAGE_SOLVING
9595 * - \ref SCIP_STAGE_SOLVED
9596 */
9598 SCIP* scip, /**< SCIP data structure */
9599 SCIP_VAR* var /**< problem variable */
9600 )
9601{
9602 SCIP_Real inferdown;
9603 SCIP_Real inferup;
9604
9605 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9606
9607 assert( var->scip == scip );
9608
9611
9612 return SCIPbranchGetScore(scip->set, var, inferdown, inferup);
9613}
9614
9615/** initializes the upwards and downwards pseudocosts, conflict scores, conflict lengths, inference scores, cutoff scores
9616 * of a variable to the given values
9617 *
9618 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9619 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9620 *
9621 * @pre This method can be called if @p scip is in one of the following stages:
9622 * - \ref SCIP_STAGE_TRANSFORMED
9623 * - \ref SCIP_STAGE_INITPRESOLVE
9624 * - \ref SCIP_STAGE_PRESOLVING
9625 * - \ref SCIP_STAGE_EXITPRESOLVE
9626 * - \ref SCIP_STAGE_PRESOLVED
9627 * - \ref SCIP_STAGE_INITSOLVE
9628 * - \ref SCIP_STAGE_SOLVING
9629 */
9631 SCIP* scip, /**< SCIP data structure */
9632 SCIP_VAR* var, /**< variable which should be initialized */
9633 SCIP_Real downpscost, /**< value to which pseudocosts for downwards branching should be initialized */
9634 SCIP_Real uppscost, /**< value to which pseudocosts for upwards branching should be initialized */
9635 SCIP_Real downvsids, /**< value to which VSIDS score for downwards branching should be initialized */
9636 SCIP_Real upvsids, /**< value to which VSIDS score for upwards branching should be initialized */
9637 SCIP_Real downconflen, /**< value to which conflict length score for downwards branching should be initialized */
9638 SCIP_Real upconflen, /**< value to which conflict length score for upwards branching should be initialized */
9639 SCIP_Real downinfer, /**< value to which inference counter for downwards branching should be initialized */
9640 SCIP_Real upinfer, /**< value to which inference counter for upwards branching should be initialized */
9641 SCIP_Real downcutoff, /**< value to which cutoff counter for downwards branching should be initialized */
9642 SCIP_Real upcutoff /**< value to which cutoff counter for upwards branching should be initialized */
9643 )
9644{
9645 SCIP_CALL( SCIPcheckStage(scip, "SCIPinitVarBranchStats", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
9646
9647 assert(downpscost >= 0.0 && uppscost >= 0.0);
9648 assert(downvsids >= 0.0 && upvsids >= 0.0);
9649 assert(downconflen >= 0.0 && upconflen >= 0.0);
9650 assert(downinfer >= 0.0 && upinfer >= 0.0);
9651 assert(downcutoff >= 0.0 && upcutoff >= 0.0);
9652
9653 if( !SCIPisFeasZero(scip, downpscost) || !SCIPisFeasZero(scip, downvsids)
9654 || !SCIPisFeasZero(scip, downinfer) || !SCIPisFeasZero(scip, downcutoff) )
9655 {
9657 SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, -1.0, downpscost, 1.0) );
9659 SCIP_CALL( SCIPvarIncVSIDS(var, NULL, scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, SCIP_UNKNOWN, downvsids) );
9661 }
9662
9663 if( !SCIPisFeasZero(scip, downconflen) )
9664 {
9666 }
9667
9668 if( !SCIPisFeasZero(scip, uppscost) || !SCIPisFeasZero(scip, upvsids)
9669 || !SCIPisFeasZero(scip, upinfer) || !SCIPisFeasZero(scip, upcutoff) )
9670 {
9672 SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, 1.0, uppscost, 1.0) );
9676 }
9677
9678 if( !SCIPisFeasZero(scip, upconflen) )
9679 {
9681 }
9682
9683 return SCIP_OKAY;
9684}
9685
9686/** initializes the upwards and downwards conflict scores, conflict lengths, inference scores, cutoff scores of a
9687 * variable w.r.t. a value by the given values (SCIP_VALUEHISTORY)
9688 *
9689 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9690 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9691 *
9692 * @pre This method can be called if @p scip is in one of the following stages:
9693 * - \ref SCIP_STAGE_TRANSFORMED
9694 * - \ref SCIP_STAGE_INITPRESOLVE
9695 * - \ref SCIP_STAGE_PRESOLVING
9696 * - \ref SCIP_STAGE_EXITPRESOLVE
9697 * - \ref SCIP_STAGE_PRESOLVED
9698 * - \ref SCIP_STAGE_INITSOLVE
9699 * - \ref SCIP_STAGE_SOLVING
9700 */
9702 SCIP* scip, /**< SCIP data structure */
9703 SCIP_VAR* var, /**< variable which should be initialized */
9704 SCIP_Real value, /**< domain value, or SCIP_UNKNOWN */
9705 SCIP_Real downvsids, /**< value to which VSIDS score for downwards branching should be initialized */
9706 SCIP_Real upvsids, /**< value to which VSIDS score for upwards branching should be initialized */
9707 SCIP_Real downconflen, /**< value to which conflict length score for downwards branching should be initialized */
9708 SCIP_Real upconflen, /**< value to which conflict length score for upwards branching should be initialized */
9709 SCIP_Real downinfer, /**< value to which inference counter for downwards branching should be initialized */
9710 SCIP_Real upinfer, /**< value to which inference counter for upwards branching should be initialized */
9711 SCIP_Real downcutoff, /**< value to which cutoff counter for downwards branching should be initialized */
9712 SCIP_Real upcutoff /**< value to which cutoff counter for upwards branching should be initialized */
9713 )
9714{
9715 SCIP_CALL( SCIPcheckStage(scip, "SCIPinitVarValueBranchStats", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
9716
9717 assert(downvsids >= 0.0 && upvsids >= 0.0);
9718 assert(downconflen >= 0.0 && upconflen >= 0.0);
9719 assert(downinfer >= 0.0 && upinfer >= 0.0);
9720 assert(downcutoff >= 0.0 && upcutoff >= 0.0);
9721
9722 if( !SCIPisFeasZero(scip, downvsids) || !SCIPisFeasZero(scip, downinfer) || !SCIPisFeasZero(scip, downcutoff) )
9723 {
9725 SCIP_CALL( SCIPvarIncInferenceSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downinfer) );
9726 SCIP_CALL( SCIPvarIncVSIDS(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downvsids) );
9727 SCIP_CALL( SCIPvarIncCutoffSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downcutoff) );
9728 }
9729
9730 if( !SCIPisFeasZero(scip, downconflen) )
9731 {
9732 SCIP_CALL( SCIPvarIncNActiveConflicts(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downconflen) );
9733 }
9734
9735 if( !SCIPisFeasZero(scip, upvsids) || !SCIPisFeasZero(scip, upinfer) || !SCIPisFeasZero(scip, upcutoff) )
9736 {
9738 SCIP_CALL( SCIPvarIncInferenceSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upinfer) );
9739 SCIP_CALL( SCIPvarIncVSIDS(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upvsids) );
9740 SCIP_CALL( SCIPvarIncCutoffSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upcutoff) );
9741 }
9742
9743 if( !SCIPisFeasZero(scip, upconflen) )
9744 {
9745 SCIP_CALL( SCIPvarIncNActiveConflicts(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upconflen) );
9746 }
9747
9748 return SCIP_OKAY;
9749}
9750
9751/** returns the average number of cutoffs found after branching on the variable in given direction;
9752 * if branching on the variable in the given direction was yet evaluated, the average number of cutoffs
9753 * over all variables for branching in the given direction is returned
9754 *
9755 * @return the average number of cutoffs found after branching on the variable in given direction
9756 *
9757 * @pre This method can be called if @p scip is in one of the following stages:
9758 * - \ref SCIP_STAGE_INITPRESOLVE
9759 * - \ref SCIP_STAGE_PRESOLVING
9760 * - \ref SCIP_STAGE_EXITPRESOLVE
9761 * - \ref SCIP_STAGE_PRESOLVED
9762 * - \ref SCIP_STAGE_INITSOLVE
9763 * - \ref SCIP_STAGE_SOLVING
9764 * - \ref SCIP_STAGE_SOLVED
9765 */
9767 SCIP* scip, /**< SCIP data structure */
9768 SCIP_VAR* var, /**< problem variable */
9769 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9770 )
9771{
9772 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffs", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9773
9774 assert( var->scip == scip );
9775
9776 return SCIPvarGetAvgCutoffs(var, scip->stat, dir);
9777}
9778
9779/** returns the average number of cutoffs found after branching on the variable in given direction in the current run;
9780 * if branching on the variable in the given direction was yet evaluated, the average number of cutoffs
9781 * over all variables for branching in the given direction is returned
9782 *
9783 * @return the average number of cutoffs found after branching on the variable in given direction in the current run
9784 *
9785 * @pre This method can be called if @p scip is in one of the following stages:
9786 * - \ref SCIP_STAGE_INITPRESOLVE
9787 * - \ref SCIP_STAGE_PRESOLVING
9788 * - \ref SCIP_STAGE_EXITPRESOLVE
9789 * - \ref SCIP_STAGE_PRESOLVED
9790 * - \ref SCIP_STAGE_INITSOLVE
9791 * - \ref SCIP_STAGE_SOLVING
9792 * - \ref SCIP_STAGE_SOLVED
9793 */
9795 SCIP* scip, /**< SCIP data structure */
9796 SCIP_VAR* var, /**< problem variable */
9797 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9798 )
9799{
9800 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffsCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9801
9802 assert( var->scip == scip );
9803
9804 return SCIPvarGetAvgCutoffsCurrentRun(var, scip->stat, dir);
9805}
9806
9807/** returns the variable's average cutoff score value
9808 *
9809 * @return the variable's average cutoff score value
9810 *
9811 * @pre This method can be called if @p scip is in one of the following stages:
9812 * - \ref SCIP_STAGE_INITPRESOLVE
9813 * - \ref SCIP_STAGE_PRESOLVING
9814 * - \ref SCIP_STAGE_EXITPRESOLVE
9815 * - \ref SCIP_STAGE_PRESOLVED
9816 * - \ref SCIP_STAGE_INITSOLVE
9817 * - \ref SCIP_STAGE_SOLVING
9818 * - \ref SCIP_STAGE_SOLVED
9819 */
9821 SCIP* scip, /**< SCIP data structure */
9822 SCIP_VAR* var /**< problem variable */
9823 )
9824{
9825 SCIP_Real cutoffdown;
9826 SCIP_Real cutoffup;
9827
9828 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9829
9830 assert( var->scip == scip );
9831
9832 cutoffdown = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9833 cutoffup = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9834
9835 return SCIPbranchGetScore(scip->set, var, cutoffdown, cutoffup);
9836}
9837
9838/** returns the variable's average cutoff score value, only using cutoffs of the current run
9839 *
9840 * @return the variable's average cutoff score value, only using cutoffs of the current run
9841 *
9842 * @pre This method can be called if @p scip is in one of the following stages:
9843 * - \ref SCIP_STAGE_INITPRESOLVE
9844 * - \ref SCIP_STAGE_PRESOLVING
9845 * - \ref SCIP_STAGE_EXITPRESOLVE
9846 * - \ref SCIP_STAGE_PRESOLVED
9847 * - \ref SCIP_STAGE_INITSOLVE
9848 * - \ref SCIP_STAGE_SOLVING
9849 * - \ref SCIP_STAGE_SOLVED
9850 */
9852 SCIP* scip, /**< SCIP data structure */
9853 SCIP_VAR* var /**< problem variable */
9854 )
9855{
9856 SCIP_Real cutoffdown;
9857 SCIP_Real cutoffup;
9858
9859 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9860
9861 assert( var->scip == scip );
9862
9865
9866 return SCIPbranchGetScore(scip->set, var, cutoffdown, cutoffup);
9867}
9868
9869/** returns the variable's average inference/cutoff score value, weighting the cutoffs of the variable with the given
9870 * factor
9871 *
9872 * @return the variable's average inference/cutoff score value
9873 *
9874 * @pre This method can be called if @p scip is in one of the following stages:
9875 * - \ref SCIP_STAGE_INITPRESOLVE
9876 * - \ref SCIP_STAGE_PRESOLVING
9877 * - \ref SCIP_STAGE_EXITPRESOLVE
9878 * - \ref SCIP_STAGE_PRESOLVED
9879 * - \ref SCIP_STAGE_INITSOLVE
9880 * - \ref SCIP_STAGE_SOLVING
9881 * - \ref SCIP_STAGE_SOLVED
9882 */
9884 SCIP* scip, /**< SCIP data structure */
9885 SCIP_VAR* var, /**< problem variable */
9886 SCIP_Real cutoffweight /**< factor to weigh average number of cutoffs in branching score */
9887 )
9888{
9889 SCIP_Real avginferdown;
9890 SCIP_Real avginferup;
9891 SCIP_Real avginfer;
9892 SCIP_Real inferdown;
9893 SCIP_Real inferup;
9894 SCIP_Real cutoffdown;
9895 SCIP_Real cutoffup;
9896
9897 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceCutoffScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9898
9899 assert( var->scip == scip );
9900
9901 avginferdown = SCIPhistoryGetAvgInferences(scip->stat->glbhistory, SCIP_BRANCHDIR_DOWNWARDS);
9902 avginferup = SCIPhistoryGetAvgInferences(scip->stat->glbhistory, SCIP_BRANCHDIR_UPWARDS);
9903 avginfer = (avginferdown + avginferup)/2.0;
9904 inferdown = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9906 cutoffdown = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9907 cutoffup = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9908
9909 return SCIPbranchGetScore(scip->set, var,
9910 inferdown + cutoffweight * avginfer * cutoffdown, inferup + cutoffweight * avginfer * cutoffup);
9911}
9912
9913/** returns the variable's average inference/cutoff score value, weighting the cutoffs of the variable with the given
9914 * factor, only using inferences and cutoffs of the current run
9915 *
9916 * @return the variable's average inference/cutoff score value, only using inferences and cutoffs of the current run
9917 *
9918 * @pre This method can be called if @p scip is in one of the following stages:
9919 * - \ref SCIP_STAGE_INITPRESOLVE
9920 * - \ref SCIP_STAGE_PRESOLVING
9921 * - \ref SCIP_STAGE_EXITPRESOLVE
9922 * - \ref SCIP_STAGE_PRESOLVED
9923 * - \ref SCIP_STAGE_INITSOLVE
9924 * - \ref SCIP_STAGE_SOLVING
9925 * - \ref SCIP_STAGE_SOLVED
9926 */
9928 SCIP* scip, /**< SCIP data structure */
9929 SCIP_VAR* var, /**< problem variable */
9930 SCIP_Real cutoffweight /**< factor to weigh average number of cutoffs in branching score */
9931 )
9932{
9933 SCIP_Real avginferdown;
9934 SCIP_Real avginferup;
9935 SCIP_Real avginfer;
9936 SCIP_Real inferdown;
9937 SCIP_Real inferup;
9938 SCIP_Real cutoffdown;
9939 SCIP_Real cutoffup;
9940
9941 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceCutoffScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9942
9943 assert( var->scip == scip );
9944
9945 avginferdown = SCIPhistoryGetAvgInferences(scip->stat->glbhistorycrun, SCIP_BRANCHDIR_DOWNWARDS);
9946 avginferup = SCIPhistoryGetAvgInferences(scip->stat->glbhistorycrun, SCIP_BRANCHDIR_UPWARDS);
9947 avginfer = (avginferdown + avginferup)/2.0;
9952
9953 return SCIPbranchGetScore(scip->set, var,
9954 inferdown + cutoffweight * avginfer * cutoffdown, inferup + cutoffweight * avginfer * cutoffup);
9955}
9956
9957/** returns the variable's average GMI efficacy score value
9958 *
9959 * @return the variable's average GMI efficacy score value
9960 *
9961 * @pre This method can be called if @p scip is in one of the following stages:
9962 * - \ref SCIP_STAGE_INITPRESOLVE
9963 * - \ref SCIP_STAGE_PRESOLVING
9964 * - \ref SCIP_STAGE_EXITPRESOLVE
9965 * - \ref SCIP_STAGE_PRESOLVED
9966 * - \ref SCIP_STAGE_INITSOLVE
9967 * - \ref SCIP_STAGE_SOLVING
9968 * - \ref SCIP_STAGE_SOLVED
9969 */
9971 SCIP* scip, /**< SCIP data structure */
9972 SCIP_VAR* var /**< problem variable */
9973 )
9974{
9975 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgGMIScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9976
9977 assert( var->scip == scip );
9978
9979 return SCIPvarGetAvgGMIScore(var, scip->stat);
9980}
9981
9982/** sets the variable's average GMI efficacy score value
9983 *
9984 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9985 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9986 *
9987 * @pre This method can be called if @p scip is in one of the following stages:
9988 * - \ref SCIP_STAGE_INITPRESOLVE
9989 * - \ref SCIP_STAGE_PRESOLVING
9990 * - \ref SCIP_STAGE_EXITPRESOLVE
9991 * - \ref SCIP_STAGE_PRESOLVED
9992 * - \ref SCIP_STAGE_INITSOLVE
9993 * - \ref SCIP_STAGE_SOLVING
9994 * - \ref SCIP_STAGE_SOLVED
9995 */
9996SCIP_EXPORT
9998 SCIP* scip, /**< SCIP data structure */
9999 SCIP_VAR* var, /**< problem variable */
10000 SCIP_Real gmieff /**< Efficacy of last GMI cut generated from when var was basic /frac */
10001 )
10002{
10003 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPincVarGMISumScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
10004
10005 assert( var->scip == scip );
10006
10007 SCIP_CALL( SCIPvarIncGMIeffSum(var, scip->stat, gmieff) );
10008
10009 return SCIP_OKAY;
10010}
10011
10012/** returns the variable's last GMI efficacy score value
10013 *
10014 * @return the variable's last GMI efficacy score value
10015 *
10016 * @pre This method can be called if @p scip is in one of the following stages:
10017 * - \ref SCIP_STAGE_INITPRESOLVE
10018 * - \ref SCIP_STAGE_PRESOLVING
10019 * - \ref SCIP_STAGE_EXITPRESOLVE
10020 * - \ref SCIP_STAGE_PRESOLVED
10021 * - \ref SCIP_STAGE_INITSOLVE
10022 * - \ref SCIP_STAGE_SOLVING
10023 * - \ref SCIP_STAGE_SOLVED
10024 */
10026 SCIP* scip, /**< SCIP data structure */
10027 SCIP_VAR* var /**< problem variable */
10028 )
10029{
10030 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarLastGMIScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
10031
10032 assert( var->scip == scip );
10033
10034 return SCIPvarGetLastGMIScore(var, scip->stat);
10035}
10036
10037/** sets the variable's last GMI efficacy score value
10038 *
10039 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
10040 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
10041 *
10042 * @pre This method can be called if @p scip is in one of the following stages:
10043 * - \ref SCIP_STAGE_INITPRESOLVE
10044 * - \ref SCIP_STAGE_PRESOLVING
10045 * - \ref SCIP_STAGE_EXITPRESOLVE
10046 * - \ref SCIP_STAGE_PRESOLVED
10047 * - \ref SCIP_STAGE_INITSOLVE
10048 * - \ref SCIP_STAGE_SOLVING
10049 * - \ref SCIP_STAGE_SOLVED
10050 */
10052 SCIP* scip, /**< SCIP data structure */
10053 SCIP_VAR* var, /**< problem variable */
10054 SCIP_Real gmieff /**< efficacy of GMI cut from tableau row when variable is basic / frac */
10055 )
10056{
10057 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPsetVarLastGMIScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
10058
10059 assert( var->scip == scip );
10060
10061 SCIP_CALL( SCIPvarSetLastGMIScore(var, scip->stat, gmieff) );
10062
10063 return SCIP_OKAY;
10064}
10065
10066/** outputs variable information to file stream via the message system
10067 *
10068 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
10069 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
10070 *
10071 * @pre This method can be called if @p scip is in one of the following stages:
10072 * - \ref SCIP_STAGE_PROBLEM
10073 * - \ref SCIP_STAGE_TRANSFORMING
10074 * - \ref SCIP_STAGE_TRANSFORMED
10075 * - \ref SCIP_STAGE_INITPRESOLVE
10076 * - \ref SCIP_STAGE_PRESOLVING
10077 * - \ref SCIP_STAGE_EXITPRESOLVE
10078 * - \ref SCIP_STAGE_PRESOLVED
10079 * - \ref SCIP_STAGE_INITSOLVE
10080 * - \ref SCIP_STAGE_SOLVING
10081 * - \ref SCIP_STAGE_SOLVED
10082 * - \ref SCIP_STAGE_EXITSOLVE
10083 * - \ref SCIP_STAGE_FREETRANS
10084 *
10085 * @note If the message handler is set to a NULL pointer nothing will be printed
10086 */
10088 SCIP* scip, /**< SCIP data structure */
10089 SCIP_VAR* var, /**< problem variable */
10090 FILE* file /**< output file (or NULL for standard output) */
10091 )
10092{
10093 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
10094
10095 SCIP_CALL( SCIPvarPrint(var, scip->set, scip->messagehdlr, file) );
10096
10097 return SCIP_OKAY;
10098}
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:2202
methods for debugging
#define NULL
Definition: def.h:262
#define SCIP_MAXSTRLEN
Definition: def.h:283
#define SCIP_Longint
Definition: def.h:157
#define SCIP_MAXTREEDEPTH
Definition: def.h:311
#define SCIP_VARTYPE_INTEGER_CHAR
Definition: def.h:144
#define SCIP_VARTYPE_IMPLINT_CHAR
Definition: def.h:145
#define SCIP_INVALID
Definition: def.h:192
#define SCIP_Bool
Definition: def.h:91
#define MIN(x, y)
Definition: def.h:238
#define SCIP_Real
Definition: def.h:172
#define SCIP_UNKNOWN
Definition: def.h:193
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define MAX(x, y)
Definition: def.h:234
#define SCIP_CALL_ABORT(x)
Definition: def.h:348
#define SCIP_VARTYPE_BINARY_CHAR
Definition: def.h:143
#define SCIP_LONGINT_FORMAT
Definition: def.h:164
#define SCIP_VARTYPE_CONTINUOUS_CHAR
Definition: def.h:146
#define SCIPABORT()
Definition: def.h:341
#define REALABS(x)
Definition: def.h:196
#define SCIP_LONGINT_MAX
Definition: def.h:158
#define SCIP_CALL(x)
Definition: def.h:369
#define SCIP_CALL_FINALLY(x, y)
Definition: def.h:411
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:548
void SCIPgmlWriteNode(FILE *file, unsigned int id, const char *label, const char *nodetype, const char *fillcolor, const char *bordercolor)
Definition: misc.c:500
void SCIPgmlWriteClosing(FILE *file)
Definition: misc.c:702
void SCIPgmlWriteOpening(FILE *file, SCIP_Bool directed)
Definition: misc.c:686
void SCIPgmlWriteArc(FILE *file, unsigned int source, unsigned int target, const char *label, const char *color)
Definition: misc.c:642
SCIP_Bool SCIPisTransformed(SCIP *scip)
Definition: scip_general.c:606
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:390
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:3110
int SCIPhashmapGetImageInt(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3283
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3076
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3425
SCIP_RETCODE SCIPhashmapInsertInt(SCIP_HASHMAP *hashmap, void *origin, int image)
Definition: misc.c:3194
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
Definition: lpi_clp.cpp:3959
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_clp.cpp:2794
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2637
SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2414
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
#define SCIPdebugMsg
Definition: scip_message.h:78
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
SCIP_Real SCIPgetColRedcost(SCIP *scip, SCIP_COL *col)
Definition: scip_lp.c:1158
SCIP_Longint SCIPcolGetStrongbranchNode(SCIP_COL *col)
Definition: lp.c:17202
int SCIPcolGetNStrongbranchs(SCIP_COL *col)
Definition: lp.c:17212
SCIP_Bool SCIPcolIsInLP(SCIP_COL *col)
Definition: lp.c:17144
SCIP_Real SCIPgetColFarkasCoef(SCIP *scip, SCIP_COL *col)
Definition: scip_lp.c:1184
SCIP_Bool SCIPconsIsLockedTypePos(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
Definition: cons.c:8602
SCIP_Bool SCIPconsIsLockedTypeNeg(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
Definition: cons.c:8614
SCIP_Bool SCIPinDive(SCIP *scip)
Definition: scip_lp.c:2779
SCIP_Bool SCIPisLPRelax(SCIP *scip)
Definition: scip_lp.c:226
SCIP_RETCODE SCIPgetLPI(SCIP *scip, SCIP_LPI **lpi)
Definition: scip_lp.c:989
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip_lp.c:169
SCIP_Bool SCIPallColsInLP(SCIP *scip)
Definition: scip_lp.c:650
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition: scip_lp.c:248
#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:7521
SCIP_DOMCHG * SCIPnodeGetDomchg(SCIP_NODE *node)
Definition: tree.c:7626
int SCIPgetProbingDepth(SCIP *scip)
Definition: scip_probing.c:198
SCIP_RETCODE SCIPchgVarUbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_probing.c:345
SCIP_RETCODE SCIPchgVarLbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_probing.c:301
SCIP_RETCODE SCIPpropagateProbing(SCIP *scip, int maxproprounds, SCIP_Bool *cutoff, SCIP_Longint *ndomredsfound)
Definition: scip_probing.c:580
SCIP_RETCODE SCIPbacktrackProbing(SCIP *scip, int probingdepth)
Definition: scip_probing.c:225
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip_probing.c:97
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
Definition: scip_probing.c:165
SCIP_RETCODE SCIPsolveProbingLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition: scip_probing.c:820
void SCIPsolSetStrongbranching(SCIP_SOL *sol)
Definition: sol.c:2909
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip_sol.c:837
SCIP_RETCODE SCIPcreateLPSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip_sol.c:222
SCIP_RETCODE SCIPgetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip_sol.c:1250
SCIP_RETCODE SCIProundSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
Definition: scip_sol.c:2307
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:3046
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1213
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition: scip_tree.c:91
SCIP_RETCODE SCIPgetVarStrongbranchFrac(SCIP *scip, SCIP_VAR *var, int itlim, SCIP_Bool idempotent, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *downconflict, SCIP_Bool *upconflict, SCIP_Bool *lperror)
Definition: scip_var.c:2919
SCIP_Real SCIPgetRelaxSolObj(SCIP *scip)
Definition: scip_var.c:2632
SCIP_RETCODE SCIPinitVarBranchStats(SCIP *scip, SCIP_VAR *var, SCIP_Real downpscost, SCIP_Real uppscost, SCIP_Real downvsids, SCIP_Real upvsids, SCIP_Real downconflen, SCIP_Real upconflen, SCIP_Real downinfer, SCIP_Real upinfer, SCIP_Real downcutoff, SCIP_Real upcutoff)
Definition: scip_var.c:9630
SCIP_RETCODE SCIPgetProbvarLinearSum(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize, SCIP_Bool mergemultiples)
Definition: scip_var.c:1738
SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5326
SCIP_Real SCIPgetVarBdAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2264
SCIP_RETCODE SCIPinitVarValueBranchStats(SCIP *scip, SCIP_VAR *var, SCIP_Real value, SCIP_Real downvsids, SCIP_Real upvsids, SCIP_Real downconflen, SCIP_Real upconflen, SCIP_Real downinfer, SCIP_Real upinfer, SCIP_Real downcutoff, SCIP_Real upcutoff)
Definition: scip_var.c:9701
SCIP_RETCODE SCIPaddVarLocks(SCIP *scip, SCIP_VAR *var, int nlocksdown, int nlocksup)
Definition: scip_var.c:4440
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:17807
SCIP_Real SCIPgetVarMultaggrLbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6651
SCIP_Bool SCIPpscostThresholdProbabilityTest(SCIP *scip, SCIP_VAR *var, SCIP_Real frac, SCIP_Real threshold, SCIP_BRANCHDIR dir, SCIP_CONFIDENCELEVEL clevel)
Definition: scip_var.c:9152
SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:4474
SCIP_BOUNDTYPE SCIPvarGetBestBoundType(SCIP_VAR *var)
Definition: var.c:18208
SCIP_RETCODE SCIPremoveVarFromGlobalStructures(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:7964
SCIP_Real SCIPvarGetSol(SCIP_VAR *var, SCIP_Bool getlpval)
Definition: var.c:13275
SCIP_Bool SCIPdoNotAggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8678
void SCIPdisableVarHistory(SCIP *scip)
Definition: scip_var.c:8853
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17766
SCIP_Bool SCIPgetVarWasFixedAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2282
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:17617
SCIP_RETCODE SCIPincVarGMISumScore(SCIP *scip, SCIP_VAR *var, SCIP_Real gmieff)
Definition: scip_var.c:9997
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:5931
SCIP_BOUNDTYPE SCIPboundchgGetBoundtype(SCIP_BOUNDCHG *boundchg)
Definition: var.c:17364
SCIP_Real SCIPgetVarMultaggrLbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6681
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:6115
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:7026
SCIP_RETCODE SCIPcalcCliquePartition(SCIP *const scip, SCIP_VAR **const vars, int const nvars, int *const cliquepartition, int *const ncliques)
Definition: scip_var.c:7361
SCIP_RETCODE SCIPsetRelaxSolVal(SCIP *scip, SCIP_RELAX *relax, SCIP_VAR *var, SCIP_Real val)
Definition: scip_var.c:2414
SCIP_RETCODE SCIPtightenVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6453
SCIP_Real SCIPgetVarAvgInferenceScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9597
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:3739
SCIP_VAR * SCIPboundchgGetVar(SCIP_BOUNDCHG *boundchg)
Definition: var.c:17344
SCIP_Real SCIPgetVarPseudocostCountCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9043
SCIP_Real SCIPgetVarAvgInferenceScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9566
SCIP_RETCODE SCIPscaleVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real scale)
Definition: scip_var.c:8026
SCIP_RETCODE SCIPendStrongbranch(SCIP *scip)
Definition: scip_var.c:2744
SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4799
SCIP_Real SCIPgetVarMultaggrUbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6666
SCIP_BOUNDCHG * SCIPdomchgGetBoundchg(SCIP_DOMCHG *domchg, int pos)
Definition: var.c:17392
SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition: scip_var.c:1480
SCIP_Real SCIPgetVarPseudocostCount(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9015
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17556
SCIP_RETCODE SCIPcalcNegatedCliquePartition(SCIP *const scip, SCIP_VAR **const vars, int const nvars, int *const cliquepartition, int *const ncliques)
Definition: scip_var.c:7580
SCIP_Real SCIPgetVarPseudocostCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:8989
SCIP_RETCODE SCIPwriteCliqueGraph(SCIP *scip, const char *fname, SCIP_Bool writenodeweights)
Definition: scip_var.c:7815
SCIP_RETCODE SCIPchgVarName(SCIP *scip, SCIP_VAR *var, const char *name)
Definition: scip_var.c:1299
SCIP_Bool SCIPdoNotAggr(SCIP *scip)
Definition: scip_var.c:8658
SCIP_Real SCIPgetVarMultaggrUbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6696
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:18162
int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition: var.c:3416
SCIP_RETCODE SCIPupdateVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition: scip_var.c:8126
SCIP_Real SCIPgetVarAvgConflictlength(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9458
SCIP_Bool SCIPisVarPscostRelerrorReliable(SCIP *scip, SCIP_VAR *var, SCIP_Real threshold, SCIP_CONFIDENCELEVEL clevel)
Definition: scip_var.c:9171
SCIP_RETCODE SCIPgetBinvarRepresentatives(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **repvars, SCIP_Bool *negated)
Definition: scip_var.c:1644
SCIP_BDCHGINFO * SCIPvarGetLbchgInfo(SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: var.c:16595
SCIP_Bool SCIPdoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8691
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition: var.c:17579
SCIP_Real SCIPgetVarPseudocost(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:8961
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:9851
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:8494
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:5729
SCIP_Bool SCIPallowObjProp(SCIP *scip)
Definition: scip_var.c:8735
SCIP_Real SCIPboundchgGetNewbound(SCIP_BOUNDCHG *boundchg)
Definition: var.c:17334
SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4889
SCIP_RETCODE SCIPchgVarUbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:5013
SCIP_Real SCIPgetVarAvgInferencesCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9540
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17944
SCIP_VAR * SCIPvarGetProbvar(SCIP_VAR *var)
Definition: var.c:12236
SCIP_CLIQUE ** SCIPgetCliques(SCIP *scip)
Definition: scip_var.c:7734
SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5443
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:17602
SCIP_RETCODE SCIPgetProbvarSum(SCIP *scip, SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: scip_var.c:1794
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:18106
SCIP_RETCODE SCIPchgVarBranchDirection(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR branchdirection)
Definition: scip_var.c:8190
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:6825
SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
Definition: scip_var.c:4382
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:6766
SCIP_RETCODE SCIPchgVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition: scip_var.c:8085
SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:4560
SCIP_Real SCIPgetVarFarkasCoef(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1954
SCIP_RETCODE SCIPgetVarClosestVub(SCIP *scip, SCIP_VAR *var, SCIP_SOL *sol, SCIP_Real *closestvub, int *closestvubidx)
Definition: scip_var.c:6737
SCIP_Real SCIPgetVarAvgCutoffsCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9794
SCIP_RETCODE SCIPchgVarLbLazy(SCIP *scip, SCIP_VAR *var, SCIP_Real lazylb)
Definition: scip_var.c:5246
SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2128
int SCIPdomchgGetNBoundchgs(SCIP_DOMCHG *domchg)
Definition: var.c:17384
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17786
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17437
SCIP_Longint SCIPgetVarStrongbranchNode(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:4283
SCIP_RETCODE SCIPtransformVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition: scip_var.c:1389
SCIP_RETCODE SCIPmultiaggregateVar(SCIP *scip, SCIP_VAR *var, int naggvars, SCIP_VAR **aggvars, SCIP_Real *scalars, SCIP_Real constant, SCIP_Bool *infeasible, SCIP_Bool *aggregated)
Definition: scip_var.c:8628
void SCIPfreeParseVarsPolynomialData(SCIP *scip, SCIP_VAR ****monomialvars, SCIP_Real ***monomialexps, SCIP_Real **monomialcoefs, int **monomialnvars, int nmonomials)
Definition: scip_var.c:1157
SCIP_LPSOLSTAT SCIPgetLastStrongbranchLPSolStat(SCIP *scip, SCIP_BRANCHDIR branchdir)
Definition: scip_var.c:4111
SCIP_RETCODE SCIPaddVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real addfactor)
Definition: scip_var.c:8054
int SCIPgetNCliquesCreated(SCIP *scip)
Definition: scip_var.c:7707
SCIP_RETCODE SCIPcleanupCliques(SCIP *scip, SCIP_Bool *infeasible)
Definition: scip_var.c:7637
void SCIPvarMarkDeleteGlobalStructures(SCIP_VAR *var)
Definition: var.c:17694
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1248
SCIP_Real SCIPadjustedVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real ub)
Definition: scip_var.c:4768
SCIP_Longint SCIPgetVarStrongbranchLPAge(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:4317
SCIP_RETCODE SCIPchgVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:5066
SCIP_RETCODE SCIPmarkRelaxSolValid(SCIP *scip, SCIP_RELAX *relax, SCIP_Bool includeslp)
Definition: scip_var.c:2557
SCIP_RETCODE SCIPgetVarsStrongbranchesFrac(SCIP *scip, SCIP_VAR **vars, int nvars, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *downconflict, SCIP_Bool *upconflict, SCIP_Bool *lperror)
Definition: scip_var.c:3896
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:4167
SCIP_Real SCIPvarGetBranchFactor(SCIP_VAR *var)
Definition: var.c:18256
SCIP_Bool SCIPdoNotMultaggr(SCIP *scip)
Definition: scip_var.c:8668
SCIP_Real SCIPgetVarPseudocostVal(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta)
Definition: scip_var.c:8907
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:9396
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:9122
SCIP_Real SCIPgetRelaxSolVal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:2603
SCIP_RETCODE SCIPgetVarStrongbranchWithPropagation(SCIP *scip, SCIP_VAR *var, SCIP_Real solval, SCIP_Real lpobjval, int itlim, int maxproprounds, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Longint *ndomredsdown, SCIP_Longint *ndomredsup, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *downconflict, SCIP_Bool *upconflict, SCIP_Bool *lperror, SCIP_Real *newlbs, SCIP_Real *newubs)
Definition: scip_var.c:3396
SCIP_Real SCIPadjustedVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real lb)
Definition: scip_var.c:4736
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:17628
SCIP_Real SCIPgetVarAvgCutoffs(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9766
SCIP_Real SCIPvarGetPseudoSol(SCIP_VAR *var)
Definition: var.c:18548
SCIP_Bool SCIPisRelaxSolValid(SCIP *scip)
Definition: scip_var.c:2537
SCIP_RETCODE SCIPgetVarClosestVlb(SCIP *scip, SCIP_VAR *var, SCIP_SOL *sol, SCIP_Real *closestvlb, int *closestvlbidx)
Definition: scip_var.c:6714
SCIP_Bool SCIPallowDualReds(SCIP *scip)
Definition: scip_var.c:8707
SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:8281
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
Definition: var.c:18470
SCIP_RETCODE SCIPflattenVarAggregationGraph(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1693
SCIP_Real SCIPcomputeVarLbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6568
SCIP_Real SCIPgetVarSol(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:2307
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip_var.c:1527
SCIP_Real SCIPgetVarPseudocostScoreCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real solval)
Definition: scip_var.c:9234
SCIP_Bool SCIPhaveVarsCommonClique(SCIP *scip, SCIP_VAR *var1, SCIP_Bool value1, SCIP_VAR *var2, SCIP_Bool value2, SCIP_Bool regardimplics)
Definition: scip_var.c:7764
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:6885
SCIP_RETCODE SCIPsetRelaxSolVals(SCIP *scip, SCIP_RELAX *relax, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Bool includeslp)
Definition: scip_var.c:2447
SCIP_Real SCIPcalculatePscostConfidenceBound(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun, SCIP_CONFIDENCELEVEL clevel)
Definition: scip_var.c:9091
int SCIPvarGetNCliques(SCIP_VAR *var, SCIP_Bool varfixing)
Definition: var.c:18448
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:18152
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:17592
SCIP_RETCODE SCIPchgVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:5155
SCIP_Real SCIPcomputeVarLbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6610
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:17374
SCIP_Real SCIPgetVarPseudocostValCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta)
Definition: scip_var.c:8935
SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
Definition: var.c:17922
SCIP_RETCODE SCIPupdateVarPseudocost(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
Definition: scip_var.c:8873
int SCIPgetNCliques(SCIP *scip)
Definition: scip_var.c:7680
SCIP_BDCHGINFO * SCIPvarGetUbchgInfo(SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: var.c:16651
SCIP_Real SCIPgetVarAvgGMIScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9970
int SCIPvarGetBranchPriority(SCIP_VAR *var)
Definition: var.c:18268
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:8159
SCIP_RETCODE SCIPtransformVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip_var.c:1349
SCIP_Real SCIPgetVarRedcost(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1864
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:18096
SCIP_RETCODE SCIPmarkDoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8808
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition: scip_var.c:8381
SCIP_RETCODE SCIPmarkRelaxSolInvalid(SCIP *scip)
Definition: scip_var.c:2582
SCIP_Real SCIPgetVarAvgInferenceCutoffScoreCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real cutoffweight)
Definition: scip_var.c:9927
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:5624
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:4007
SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:1992
SCIP_RETCODE SCIPparseVarsPolynomial(SCIP *scip, const char *str, SCIP_VAR ****monomialvars, SCIP_Real ***monomialexps, SCIP_Real **monomialcoefs, int **monomialnvars, int *nmonomials, char **endptr, SCIP_Bool *success)
Definition: scip_var.c:813
SCIP_Real SCIPgetVarLastGMIScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:10025
SCIP_Real SCIPgetVarConflictScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9334
SCIP_RETCODE SCIPprintVar(SCIP *scip, SCIP_VAR *var, FILE *file)
Definition: scip_var.c:10087
SCIP_Real SCIPgetVarAvgCutoffScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9820
SCIP_RETCODE SCIPchgVarLbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4969
SCIP_RETCODE SCIPvarGetProbvarBinary(SCIP_VAR **var, SCIP_Bool *negated)
Definition: var.c:12328
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:10051
SCIP_RETCODE SCIPchgVarUbLazy(SCIP *scip, SCIP_VAR *var, SCIP_Real lazyub)
Definition: scip_var.c:5287
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:5828
int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition: var.c:3429
SCIP_RETCODE SCIPtryStrongbranchLPSol(SCIP *scip, SCIP_Bool *foundsol, SCIP_Bool *cutoff)
Definition: scip_var.c:4202
SCIP_RETCODE SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
Definition: scip_var.c:230
SCIP_RETCODE SCIPgetVarSols(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip_var.c:2327
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:4636
SCIP_RETCODE SCIPgetBinvarRepresentative(SCIP *scip, SCIP_VAR *var, SCIP_VAR **repvar, SCIP_Bool *negated)
Definition: scip_var.c:1597
SCIP_Real SCIPgetVarAvgInferenceCutoffScore(SCIP *scip, SCIP_VAR *var, SCIP_Real cutoffweight)
Definition: scip_var.c:9883
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:6589
SCIP_Real SCIPcomputeVarUbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6631
SCIP_RETCODE SCIPgetActiveVars(SCIP *scip, SCIP_VAR **vars, int *nvars, int varssize, int *requiredsize)
Definition: scip_var.c:1830
int SCIPgetVarNStrongbranchs(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:4349
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:4133
SCIP_Real SCIPgetVarVSIDS(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9270
SCIP_Bool SCIPvarsHaveCommonClique(SCIP_VAR *var1, SCIP_Bool value1, SCIP_VAR *var2, SCIP_Bool value2, SCIP_Bool regardimplics)
Definition: var.c:11493
SCIP_Real SCIPgetVarConflictlengthScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9427
SCIP_Real SCIPgetVarVSIDSCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9302
SCIP_Bool SCIPisStrongbranchDownFirst(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:2655
SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18688
void SCIPenableVarHistory(SCIP *scip)
Definition: scip_var.c:8834
SCIP_Real SCIPgetVarImplRedcost(SCIP *scip, SCIP_VAR *var, SCIP_Bool varfixing)
Definition: scip_var.c:1909
SCIP_Bool SCIPallowWeakDualReds(SCIP *scip)
Definition: scip_var.c:8749
SCIP_Real SCIPgetVarPseudocostVariance(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun)
Definition: scip_var.c:9069
SCIP_RETCODE SCIPgetNegatedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **negvars)
Definition: scip_var.c:1560
SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip_var.c:1439
SCIP_Real SCIPgetVarConflictScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9365
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1214
SCIP_Real SCIPgetVarPseudocostScore(SCIP *scip, SCIP_VAR *var, SCIP_Real solval)
Definition: scip_var.c:9196
SCIP_RETCODE SCIPstartStrongbranch(SCIP *scip, SCIP_Bool enablepropagation)
Definition: scip_var.c:2686
SCIP_RETCODE SCIPclearRelaxSolVals(SCIP *scip, SCIP_RELAX *relax)
Definition: scip_var.c:2364
SCIP_RETCODE SCIPmarkDoNotAggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8775
SCIP_Real SCIPgetVarAvgInferences(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9512
SCIP_Bool SCIPallowStrongDualReds(SCIP *scip)
Definition: scip_var.c:8722
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:6225
SCIP_RETCODE SCIPvarsGetProbvarBinary(SCIP_VAR ***vars, SCIP_Bool **negatedarr, int nvars)
Definition: var.c:12296
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:5555
SCIP_Real SCIPgetVarAvgConflictlengthCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9484
SCIP_RETCODE SCIPsetRelaxSolValsSol(SCIP *scip, SCIP_RELAX *relax, SCIP_SOL *sol, SCIP_Bool includeslp)
Definition: scip_var.c:2489
SCIP_RETCODE SCIPchgVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real branchfactor)
Definition: scip_var.c:7998
SCIP_RETCODE SCIPtightenVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6333
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:6000
SCIP_RETCODE SCIPaddVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real addobj)
Definition: scip_var.c:4685
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10878
SCIP_Bool SCIPstrToRealValue(const char *str, SCIP_Real *value, char **endptr)
Definition: misc.c:11006
void SCIPstrCopySection(const char *str, char startchar, char endchar, char *token, int size, char **endptr)
Definition: misc.c:11036
SCIP_RETCODE SCIPskipSpace(char **s)
Definition: misc.c:10867
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 SCIPlpGetModifiedProvedPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype)
Definition: lp.c:13383
SCIP_Real SCIPlpGetLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13169
SCIP_RETCODE SCIPlpStartStrongbranch(SCIP_LP *lp)
Definition: lp.c:4178
SCIP_Real SCIPlpGetModifiedPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype)
Definition: lp.c:13343
void SCIPcolInvalidateStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4262
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:4297
SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13130
SCIP_RETCODE SCIPlpEndStrongbranch(SCIP_LP *lp)
Definition: lp.c:4193
SCIP_Longint SCIPcolGetStrongbranchLPAge(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4735
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition: lp.c:17876
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:4703
void SCIPlpStartStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16376
void SCIPlpEndStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16389
SCIP_Bool SCIPlpIsDualReliable(SCIP_LP *lp)
Definition: lp.c:17856
static const SCIP_Real scalars[]
Definition: lp.c:5739
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:4208
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:4480
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:2358
internal methods for storing and manipulating the main problem
public methods for managing constraints
public methods for implications, variable bounds, and cliques
public methods for LP management
public methods for message output
#define SCIPerrorMessage
Definition: pub_message.h:64
public data structures and miscellaneous methods
public methods for branch and bound tree
public methods for problem variables
SCIP_Bool SCIPrelaxationIsSolZero(SCIP_RELAXATION *relaxation)
Definition: relax.c:785
void SCIPrelaxationSetSolZero(SCIP_RELAXATION *relaxation, SCIP_Bool iszero)
Definition: relax.c:774
void SCIPrelaxationSetSolValid(SCIP_RELAXATION *relaxation, SCIP_Bool isvalid, SCIP_Bool includeslp)
Definition: relax.c:795
void SCIPrelaxationSetSolObj(SCIP_RELAXATION *relaxation, SCIP_Real obj)
Definition: relax.c:828
SCIP_Real SCIPrelaxationGetSolObj(SCIP_RELAXATION *relaxation)
Definition: relax.c:839
void SCIPrelaxationSetSolRelax(SCIP_RELAXATION *relaxation, SCIP_RELAX *relax)
Definition: relax.c:880
SCIP_Bool SCIPrelaxationIsSolValid(SCIP_RELAXATION *relaxation)
Definition: relax.c:808
internal methods for relaxators
general public methods
public methods for the LP relaxation, rows and columns
public methods for memory management
public methods for message handling
public methods for numerical tolerances
public methods for global and local (sub)problems
public methods for the probing mode
public methods for solutions
public methods for querying solving statistics
public methods for the branch-and-bound tree
static SCIP_RETCODE analyzeStrongbranch(SCIP *scip, SCIP_VAR *var, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *downconflict, SCIP_Bool *upconflict)
Definition: scip_var.c:2839
static SCIP_RETCODE calcCliquePartitionGreedy(SCIP *const scip, SCIP_VAR **const vars, SCIP_Bool *const values, int const nvars, int *const cliquepartition, int *const ncliques)
Definition: scip_var.c:7245
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:3070
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:7119
static SCIP_RETCODE relabelOrderConsistent(SCIP *const scip, int *labels, int const nlabels, int *nclasses)
Definition: scip_var.c:7058
#define MAXNCLIQUEVARSCOMP
Definition: scip_var.c:7225
static SCIP_RETCODE tightenBounds(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:8207
public methods for SCIP variables
SCIP_Bool SCIPsetIsLbBetter(SCIP_SET *set, SCIP_Real newlb, SCIP_Real oldlb, SCIP_Real oldub)
Definition: set.c:7022
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6293
SCIP_Real SCIPsetFeasCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6775
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6663
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6597
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6257
SCIP_Real SCIPsetFeasFloor(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6764
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6221
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6619
SCIP_Bool SCIPsetIsUbBetter(SCIP_SET *set, SCIP_Real newub, SCIP_Real oldlb, SCIP_Real oldub)
Definition: set.c:7043
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6199
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6311
SCIP_Bool SCIPsetIsFeasIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6740
internal methods for global SCIP settings
#define SCIPsetFreeBufferArray(set, ptr)
Definition: set.h:1755
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1748
#define SCIPsetDuplicateBufferArray(set, ptr, source, num)
Definition: set.h:1750
SCIP_Real SCIPsolGetObj(SCIP_SOL *sol, SCIP_SET *set, SCIP_PROB *transprob, SCIP_PROB *origprob)
Definition: sol.c:1571
internal methods for storing primal CIP solutions
SCIP_Bool SCIPsolveIsStopped(SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool checknodelimits)
Definition: solve.c:102
internal methods for main solving loop and node processing
void SCIPstatEnableVarHistory(SCIP_STAT *stat)
Definition: stat.c:166
void SCIPstatDisableVarHistory(SCIP_STAT *stat)
Definition: stat.c:156
internal methods for problem statistics
#define SCIPstatAdd(stat, set, field, val)
Definition: stat.h:280
SCIP_VAR * var
Definition: struct_var.h:187
SCIP_Real scalar
Definition: struct_var.h:185
SCIP_Real constant
Definition: struct_var.h:186
SCIP_Real lb
Definition: struct_lp.h:138
SCIP_Real ub
Definition: struct_lp.h:139
SCIP_Real sbdown
Definition: struct_lp.h:153
SCIP_Real sbup
Definition: struct_lp.h:154
unsigned int sbupvalid
Definition: struct_lp.h:190
SCIP_Real primsol
Definition: struct_lp.h:148
unsigned int sbdownvalid
Definition: struct_lp.h:188
SCIP_Real lb
Definition: struct_var.h:170
SCIP_Real ub
Definition: struct_var.h:171
SCIP_VAR ** vars
Definition: struct_var.h:195
SCIP_Real constant
Definition: struct_var.h:193
SCIP_Real * scalars
Definition: struct_var.h:194
SCIP_Real constant
Definition: struct_var.h:203
SCIP_VAR * transvar
Definition: struct_var.h:179
SCIP_ORIGINAL original
Definition: struct_var.h:229
SCIP_AGGREGATE aggregate
Definition: struct_var.h:231
SCIP_VAR * negatedvar
Definition: struct_var.h:242
SCIP * scip
Definition: struct_var.h:288
union SCIP_Var::@22 data
SCIP_DOM glbdom
Definition: struct_var.h:225
unsigned int vartype
Definition: struct_var.h:280
SCIP_MULTAGGR multaggr
Definition: struct_var.h:232
SCIP_NEGATE negate
Definition: struct_var.h:233
data structures for LP management
datastructures for block memory pools and memory buffers
datastructures for collecting primal CIP solutions and primal informations
datastructures for storing and manipulating the main problem
SCIP main data structure.
datastructures for global SCIP settings
datastructures for problem statistics
data structures for branch and bound tree
datastructures for problem variables
SCIP_Bool SCIPtreeProbing(SCIP_TREE *tree)
Definition: tree.c:8405
int SCIPtreeGetProbingDepth(SCIP_TREE *tree)
Definition: tree.c:8551
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:6522
SCIP_NODE * SCIPtreeGetCurrentNode(SCIP_TREE *tree)
Definition: tree.c:8506
SCIP_Bool SCIPtreeHasCurrentNodeLP(SCIP_TREE *tree)
Definition: tree.c:8540
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:1833
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:2118
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:6956
int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
Definition: tree.c:8523
internal methods for branch and bound tree
@ SCIP_BRANCHDIR_DOWNWARDS
Definition: type_history.h:43
@ SCIP_BRANCHDIR_UPWARDS
Definition: type_history.h:44
enum SCIP_BranchDir SCIP_BRANCHDIR
Definition: type_history.h:48
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition: type_lp.h:51
@ SCIP_BOUNDTYPE_UPPER
Definition: type_lp.h:57
@ SCIP_BOUNDTYPE_LOWER
Definition: type_lp.h:56
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:59
@ SCIP_LPSOLSTAT_ERROR
Definition: type_lp.h:49
@ SCIP_LPSOLSTAT_NOTSOLVED
Definition: type_lp.h:42
@ SCIP_LPSOLSTAT_OPTIMAL
Definition: type_lp.h:43
@ SCIP_LPSOLSTAT_TIMELIMIT
Definition: type_lp.h:48
@ SCIP_LPSOLSTAT_UNBOUNDEDRAY
Definition: type_lp.h:45
@ SCIP_LPSOLSTAT_INFEASIBLE
Definition: type_lp.h:44
@ SCIP_LPSOLSTAT_OBJLIMIT
Definition: type_lp.h:46
@ SCIP_LPSOLSTAT_ITERLIMIT
Definition: type_lp.h:47
enum SCIP_Confidencelevel SCIP_CONFIDENCELEVEL
Definition: type_misc.h:53
@ SCIP_READERROR
Definition: type_retcode.h:45
@ SCIP_INVALIDDATA
Definition: type_retcode.h:52
@ SCIP_OKAY
Definition: type_retcode.h:42
@ SCIP_INVALIDCALL
Definition: type_retcode.h:51
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
@ SCIP_STAGE_PROBLEM
Definition: type_set.h:45
@ SCIP_STAGE_INITPRESOLVE
Definition: type_set.h:48
@ SCIP_STAGE_SOLVED
Definition: type_set.h:54
@ SCIP_STAGE_PRESOLVING
Definition: type_set.h:49
@ SCIP_STAGE_TRANSFORMED
Definition: type_set.h:47
@ SCIP_STAGE_INITSOLVE
Definition: type_set.h:52
@ SCIP_STAGE_EXITPRESOLVE
Definition: type_set.h:50
@ SCIP_STAGE_EXITSOLVE
Definition: type_set.h:55
@ SCIP_STAGE_FREETRANS
Definition: type_set.h:56
@ SCIP_STAGE_SOLVING
Definition: type_set.h:53
@ SCIP_STAGE_TRANSFORMING
Definition: type_set.h:46
@ SCIP_STAGE_PRESOLVED
Definition: type_set.h:51
@ SCIP_STATUS_INFEASIBLE
Definition: type_stat.h:62
@ SCIP_NODETYPE_PROBINGNODE
Definition: type_tree.h:42
struct SCIP_VarData SCIP_VARDATA
Definition: type_var.h:120
#define NLOCKTYPES
Definition: type_var.h:94
#define SCIP_DECL_VARDELORIG(x)
Definition: type_var.h:131
#define SCIP_DECL_VARTRANS(x)
Definition: type_var.h:151
@ SCIP_VARTYPE_INTEGER
Definition: type_var.h:63
@ SCIP_VARTYPE_CONTINUOUS
Definition: type_var.h:71
@ SCIP_VARTYPE_IMPLINT
Definition: type_var.h:64
@ SCIP_VARTYPE_BINARY
Definition: type_var.h:62
@ SCIP_VARSTATUS_ORIGINAL
Definition: type_var.h:49
@ SCIP_VARSTATUS_FIXED
Definition: type_var.h:52
@ SCIP_VARSTATUS_COLUMN
Definition: type_var.h:51
@ SCIP_VARSTATUS_MULTAGGR
Definition: type_var.h:54
@ SCIP_VARSTATUS_NEGATED
Definition: type_var.h:55
@ SCIP_VARSTATUS_AGGREGATED
Definition: type_var.h:53
@ SCIP_VARSTATUS_LOOSE
Definition: type_var.h:50
#define SCIP_DECL_VARCOPY(x)
Definition: type_var.h:194
#define SCIP_DECL_VARDELTRANS(x)
Definition: type_var.h:164
enum SCIP_LockType SCIP_LOCKTYPE
Definition: type_var.h:100
@ SCIP_LOCKTYPE_MODEL
Definition: type_var.h:97
enum SCIP_Vartype SCIP_VARTYPE
Definition: type_var.h:73
enum SCIP_Varstatus SCIP_VARSTATUS
Definition: type_var.h:57
SCIP_RETCODE SCIPvarAddObj(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_Real addobj)
Definition: var.c:6336
SCIP_Real SCIPvarGetPseudocost(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real solvaldelta)
Definition: var.c:14495
SCIP_RETCODE SCIPvarsGetActiveVars(SCIP_SET *set, SCIP_VAR **vars, int *nvars, int varssize, int *requiredsize)
Definition: var.c:12024
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:15465
SCIP_RETCODE SCIPvarChgLbLazy(SCIP_VAR *var, SCIP_SET *set, SCIP_Real lazylb)
Definition: var.c:7476
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:14591
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:6261
SCIP_Real SCIPvarGetPseudocostVariance(SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun)
Definition: var.c:14710
SCIP_Real SCIPvarGetImplRedcost(SCIP_VAR *var, SCIP_SET *set, SCIP_Bool varfixing, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp)
Definition: var.c:13486
SCIP_RETCODE SCIPvarSetLastGMIScore(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real gmieff)
Definition: var.c:16501
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:15549
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:15069
SCIP_Real SCIPvarGetAvgCutoffs(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:16283
SCIP_RETCODE SCIPvarUpdatePseudocost(SCIP_VAR *var, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
Definition: var.c:14397
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:16142
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:14216
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:15205
void SCIPvarAdjustLb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *lb)
Definition: var.c:6514
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:7182
SCIP_Real SCIPvarCalcPscostConfidenceBound(SCIP_VAR *var, SCIP_SET *set, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun, SCIP_CONFIDENCELEVEL clevel)
Definition: var.c:14764
SCIP_Bool SCIPvarIsPscostRelerrorReliable(SCIP_VAR *var, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real threshold, SCIP_CONFIDENCELEVEL clevel)
Definition: var.c:14802
SCIP_RETCODE SCIPvarChgLbOriginal(SCIP_VAR *var, SCIP_SET *set, SCIP_Real newbound)
Definition: var.c:6564
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:16377
SCIP_Real SCIPvarGetVSIDS(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:18561
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:15633
SCIP_Real SCIPvarGetMultaggrLbLocal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8441
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:14879
void SCIPvarCapture(SCIP_VAR *var)
Definition: var.c:2847
SCIP_RETCODE SCIPvarChgBranchDirection(SCIP_VAR *var, SCIP_BRANCHDIR branchdirection)
Definition: var.c:11836
SCIP_Real SCIPvarGetPseudocostCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real solvaldelta)
Definition: var.c:14544
SCIP_Bool SCIPvarDoNotAggr(SCIP_VAR *var)
Definition: var.c:5845
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:6175
SCIP_RETCODE SCIPvarFlattenAggregationGraph(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: var.c:4421
void SCIPvarUpdateBestRootSol(SCIP_VAR *var, SCIP_SET *set, SCIP_Real rootsol, SCIP_Real rootredcost, SCIP_Real rootlpobjval)
Definition: var.c:13298
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:15378
SCIP_Real SCIPvarGetPseudocostCountCurrentRun(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:14636
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:7330
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:3926
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:6623
SCIP_Real SCIPvarGetAvgInferences(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:16085
SCIP_Real SCIPvarGetMultaggrUbGlobal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8639
void SCIPvarGetClosestVlb(SCIP_VAR *var, SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real *closestvlb, int *closestvlbidx)
Definition: var.c:14141
SCIP_RETCODE SCIPvarChgUbLazy(SCIP_VAR *var, SCIP_SET *set, SCIP_Real lazyub)
Definition: var.c:7499
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:14945
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:5289
SCIP_Real SCIPvarGetRelaxSol(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:13941
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:10930
SCIP_RETCODE SCIPvarMarkDoNotAggr(SCIP_VAR *var)
Definition: var.c:6103
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:7977
SCIP_RETCODE SCIPvarChgBranchPriority(SCIP_VAR *var, int branchpriority)
Definition: var.c:11705
SCIP_RETCODE SCIPvarMarkDoNotMultaggr(SCIP_VAR *var)
Definition: var.c:6139
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:5914
SCIP_Real SCIPvarGetMultaggrUbLocal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8507
SCIP_RETCODE SCIPvarGetProbvarSum(SCIP_VAR **var, SCIP_SET *set, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12665
SCIP_RETCODE SCIPvarIncGMIeffSum(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real gmieff)
Definition: var.c:16417
SCIP_Real SCIPvarGetLastGMIScore(SCIP_VAR *var, SCIP_STAT *stat)
Definition: var.c:16461
void SCIPvarAdjustUb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *ub)
Definition: var.c:6531
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:5443
SCIP_Real SCIPvarGetAvgConflictlengthCurrentRun(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:15422
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:8104
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:10007
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:15946
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:10473
SCIP_Real SCIPvarGetMultaggrLbGlobal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8573
SCIP_RETCODE SCIPvarSetRelaxSol(SCIP_VAR *var, SCIP_SET *set, SCIP_RELAXATION *relaxation, SCIP_Real solval, SCIP_Bool updateobj)
Definition: var.c:13880
SCIP_RETCODE SCIPvarChgBranchFactor(SCIP_VAR *var, SCIP_SET *set, SCIP_Real branchfactor)
Definition: var.c:11578
SCIP_Real SCIPvarGetAvgCutoffsCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:16330
SCIP_Bool SCIPvarDoNotMultaggr(SCIP_VAR *var)
Definition: var.c:5878
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