Scippy

SCIP

Solving Constraint Integer Programs

scip_var.c
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-2024 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file scip_var.c
26 * @ingroup OTHER_CFILES
27 * @brief public methods for SCIP variables
28 * @author Tobias Achterberg
29 * @author Timo Berthold
30 * @author Gerald Gamrath
31 * @author Leona Gottwald
32 * @author Stefan Heinz
33 * @author Gregor Hendel
34 * @author Thorsten Koch
35 * @author Alexander Martin
36 * @author Marc Pfetsch
37 * @author Michael Winkler
38 * @author Kati Wolter
39 *
40 * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE
41 */
42
43/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
44
45#include <ctype.h>
47#include "lpi/lpi.h"
48#include "scip/branch.h"
49#include "scip/clock.h"
50#include "scip/conflict.h"
51#include "scip/debug.h"
52#include "scip/history.h"
53#include "scip/implics.h"
54#include "scip/lp.h"
55#include "scip/prob.h"
56#include "scip/pub_cons.h"
57#include "scip/pub_implics.h"
58#include "scip/pub_lp.h"
59#include "scip/pub_message.h"
60#include "scip/pub_misc.h"
61#include "scip/pub_tree.h"
62#include "scip/pub_var.h"
63#include "scip/relax.h"
64#include "scip/scip_general.h"
65#include "scip/scip_lp.h"
66#include "scip/scip_mem.h"
67#include "scip/scip_message.h"
68#include "scip/scip_numerics.h"
69#include "scip/scip_prob.h"
70#include "scip/scip_probing.h"
71#include "scip/scip_sol.h"
73#include "scip/scip_tree.h"
74#include "scip/scip_var.h"
75#include "scip/set.h"
76#include "scip/sol.h"
77#include "scip/solve.h"
78#include "scip/stat.h"
79#include "scip/struct_lp.h"
80#include "scip/struct_mem.h"
81#include "scip/struct_primal.h"
82#include "scip/struct_prob.h"
83#include "scip/struct_scip.h"
84#include "scip/struct_set.h"
85#include "scip/struct_stat.h"
86#include "scip/struct_tree.h"
87#include "scip/struct_var.h"
88#include "scip/tree.h"
89#include "scip/var.h"
90
91
92/** creates and captures problem variable; if variable is of integral type, fractional bounds are automatically rounded;
93 * an integer variable with bounds zero and one is automatically converted into a binary variable;
94 *
95 * @warning When doing column generation and the original problem is a maximization problem, notice that SCIP will
96 * transform the problem into a minimization problem by multiplying the objective function by -1. Thus, the
97 * original objective function value of variables created during the solving process has to be multiplied by
98 * -1, too.
99 *
100 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
101 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
102 *
103 * @pre This method can be called if @p scip is in one of the following stages:
104 * - \ref SCIP_STAGE_PROBLEM
105 * - \ref SCIP_STAGE_TRANSFORMING
106 * - \ref SCIP_STAGE_INITPRESOLVE
107 * - \ref SCIP_STAGE_PRESOLVING
108 * - \ref SCIP_STAGE_EXITPRESOLVE
109 * - \ref SCIP_STAGE_PRESOLVED
110 * - \ref SCIP_STAGE_SOLVING
111 *
112 * @note the variable gets captured, hence at one point you have to release it using the method SCIPreleaseVar()
113 */
115 SCIP* scip, /**< SCIP data structure */
116 SCIP_VAR** var, /**< pointer to variable object */
117 const char* name, /**< name of variable, or NULL for automatic name creation */
118 SCIP_Real lb, /**< lower bound of variable */
119 SCIP_Real ub, /**< upper bound of variable */
120 SCIP_Real obj, /**< objective function value */
121 SCIP_VARTYPE vartype, /**< type of variable */
122 SCIP_Bool initial, /**< should var's column be present in the initial root LP? */
123 SCIP_Bool removable, /**< is var's column removable from the LP (due to aging or cleanup)? */
124 SCIP_DECL_VARDELORIG ((*vardelorig)), /**< frees user data of original variable, or NULL */
125 SCIP_DECL_VARTRANS ((*vartrans)), /**< creates transformed user data by transforming original user data, or NULL */
126 SCIP_DECL_VARDELTRANS ((*vardeltrans)), /**< frees user data of transformed variable, or NULL */
127 SCIP_DECL_VARCOPY ((*varcopy)), /**< copies variable data if wanted to subscip, or NULL */
128 SCIP_VARDATA* vardata /**< user data for this specific variable */
129 )
130{
131 assert(var != NULL);
132 assert(lb <= ub);
133
135
136 /* forbid infinite objective function values */
137 if( SCIPisInfinity(scip, REALABS(obj)) )
138 {
139 SCIPerrorMessage("invalid objective function value: value is infinite\n");
140 return SCIP_INVALIDDATA;
141 }
142
143 switch( scip->set->stage )
144 {
146 SCIP_CALL( SCIPvarCreateOriginal(var, scip->mem->probmem, scip->set, scip->stat,
147 name, lb, ub, obj, vartype, initial, removable, vardelorig, vartrans, vardeltrans, varcopy, vardata) );
148 break;
149
156 SCIP_CALL( SCIPvarCreateTransformed(var, scip->mem->probmem, scip->set, scip->stat,
157 name, lb, ub, obj, vartype, initial, removable, vardelorig, vartrans, vardeltrans, varcopy, vardata) );
158 break;
159
160 default:
161 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
162 return SCIP_INVALIDCALL;
163 } /*lint !e788*/
164
165 return SCIP_OKAY;
166}
167
168/** creates and captures problem variable with optional callbacks and variable data set to NULL, which can be set
169 * afterwards using SCIPvarSetDelorigData(), SCIPvarSetTransData(),
170 * SCIPvarSetDeltransData(), SCIPvarSetCopy(), and SCIPvarSetData(); sets variable flags initial=TRUE
171 * and removable = FALSE, which can be adjusted by using SCIPvarSetInitial() and SCIPvarSetRemovable(), resp.;
172 * if variable is of integral type, fractional bounds are automatically rounded;
173 * an integer variable with bounds zero and one is automatically converted into a binary variable;
174 *
175 * @warning When doing column generation and the original problem is a maximization problem, notice that SCIP will
176 * transform the problem into a minimization problem by multiplying the objective function by -1. Thus, the
177 * original objective function value of variables created during the solving process has to be multiplied by
178 * -1, too.
179 *
180 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
181 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
182 *
183 * @pre This method can be called if @p scip is in one of the following stages:
184 * - \ref SCIP_STAGE_PROBLEM
185 * - \ref SCIP_STAGE_TRANSFORMING
186 * - \ref SCIP_STAGE_INITPRESOLVE
187 * - \ref SCIP_STAGE_PRESOLVING
188 * - \ref SCIP_STAGE_EXITPRESOLVE
189 * - \ref SCIP_STAGE_PRESOLVED
190 * - \ref SCIP_STAGE_SOLVING
191 *
192 * @note the variable gets captured, hence at one point you have to release it using the method SCIPreleaseVar()
193 */
195 SCIP* scip, /**< SCIP data structure */
196 SCIP_VAR** var, /**< pointer to variable object */
197 const char* name, /**< name of variable, or NULL for automatic name creation */
198 SCIP_Real lb, /**< lower bound of variable */
199 SCIP_Real ub, /**< upper bound of variable */
200 SCIP_Real obj, /**< objective function value */
201 SCIP_VARTYPE vartype /**< type of variable */
202 )
203{
204 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateVarBasic", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
205
206 SCIP_CALL( SCIPcreateVar(scip, var, name, lb, ub, obj, vartype, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
207
208 return SCIP_OKAY;
209}
210
211/** outputs the variable name to the file stream
212 *
213 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
214 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
215 *
216 * @pre This method can be called if @p scip is in one of the following stages:
217 * - \ref SCIP_STAGE_PROBLEM
218 * - \ref SCIP_STAGE_TRANSFORMING
219 * - \ref SCIP_STAGE_TRANSFORMED
220 * - \ref SCIP_STAGE_INITPRESOLVE
221 * - \ref SCIP_STAGE_PRESOLVING
222 * - \ref SCIP_STAGE_EXITPRESOLVE
223 * - \ref SCIP_STAGE_PRESOLVED
224 * - \ref SCIP_STAGE_INITSOLVE
225 * - \ref SCIP_STAGE_SOLVING
226 * - \ref SCIP_STAGE_SOLVED
227 * - \ref SCIP_STAGE_EXITSOLVE
228 * - \ref SCIP_STAGE_FREETRANS
229 */
231 SCIP* scip, /**< SCIP data structure */
232 FILE* file, /**< output file, or NULL for stdout */
233 SCIP_VAR* var, /**< variable to output */
234 SCIP_Bool type /**< should the variable type be also posted */
235 )
236{
237 assert(scip != NULL);
238 assert(var != NULL);
239
240 SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarName", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
241
242 /* print variable name */
243 if( SCIPvarIsNegated(var) )
244 {
245 SCIP_VAR* negatedvar;
246
247 SCIP_CALL( SCIPgetNegatedVar(scip, var, &negatedvar) );
248 SCIPinfoMessage(scip, file, "<~%s>", SCIPvarGetName(negatedvar));
249 }
250 else
251 {
252 SCIPinfoMessage(scip, file, "<%s>", SCIPvarGetName(var));
253 }
254
255 if( type )
256 {
257 /* print variable type */
258 SCIPinfoMessage(scip, file, "[%c]",
262 }
263
264 return SCIP_OKAY;
265}
266
267/** print the given list of variables to output stream separated by the given delimiter character;
268 *
269 * i. e. the variables x1, x2, ..., xn with given delimiter ',' are written as: <x1>, <x2>, ..., <xn>;
270 *
271 * the method SCIPparseVarsList() can parse such a string
272 *
273 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
274 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
275 *
276 * @pre This method can be called if @p scip is in one of the following stages:
277 * - \ref SCIP_STAGE_PROBLEM
278 * - \ref SCIP_STAGE_TRANSFORMING
279 * - \ref SCIP_STAGE_TRANSFORMED
280 * - \ref SCIP_STAGE_INITPRESOLVE
281 * - \ref SCIP_STAGE_PRESOLVING
282 * - \ref SCIP_STAGE_EXITPRESOLVE
283 * - \ref SCIP_STAGE_PRESOLVED
284 * - \ref SCIP_STAGE_INITSOLVE
285 * - \ref SCIP_STAGE_SOLVING
286 * - \ref SCIP_STAGE_SOLVED
287 * - \ref SCIP_STAGE_EXITSOLVE
288 * - \ref SCIP_STAGE_FREETRANS
289 *
290 * @note The printing process is done via the message handler system.
291 */
293 SCIP* scip, /**< SCIP data structure */
294 FILE* file, /**< output file, or NULL for stdout */
295 SCIP_VAR** vars, /**< variable array to output */
296 int nvars, /**< number of variables */
297 SCIP_Bool type, /**< should the variable type be also posted */
298 char delimiter /**< character which is used for delimitation */
299 )
300{
301 int v;
302
303 SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsList", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
304
305 for( v = 0; v < nvars; ++v )
306 {
307 if( v > 0 )
308 {
309 SCIPinfoMessage(scip, file, "%c", delimiter);
310 }
311
312 /* print variable name */
313 SCIP_CALL( SCIPwriteVarName(scip, file, vars[v], type) );
314 }
315
316 return SCIP_OKAY;
317}
318
319/** print the given variables and coefficients as linear sum in the following form
320 * c1 <x1> + c2 <x2> ... + cn <xn>
321 *
322 * This string can be parsed by the method SCIPparseVarsLinearsum().
323 *
324 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
325 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
326 *
327 * @pre This method can be called if @p scip is in one of the following stages:
328 * - \ref SCIP_STAGE_PROBLEM
329 * - \ref SCIP_STAGE_TRANSFORMING
330 * - \ref SCIP_STAGE_TRANSFORMED
331 * - \ref SCIP_STAGE_INITPRESOLVE
332 * - \ref SCIP_STAGE_PRESOLVING
333 * - \ref SCIP_STAGE_EXITPRESOLVE
334 * - \ref SCIP_STAGE_PRESOLVED
335 * - \ref SCIP_STAGE_INITSOLVE
336 * - \ref SCIP_STAGE_SOLVING
337 * - \ref SCIP_STAGE_SOLVED
338 * - \ref SCIP_STAGE_EXITSOLVE
339 * - \ref SCIP_STAGE_FREETRANS
340 *
341 * @note The printing process is done via the message handler system.
342 */
344 SCIP* scip, /**< SCIP data structure */
345 FILE* file, /**< output file, or NULL for stdout */
346 SCIP_VAR** vars, /**< variable array to output */
347 SCIP_Real* vals, /**< array of coefficients or NULL if all coefficients are 1.0 */
348 int nvars, /**< number of variables */
349 SCIP_Bool type /**< should the variable type be also posted */
350 )
351{
352 int v;
353
354 SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsLinearsum", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
355
356 for( v = 0; v < nvars; ++v )
357 {
358 if( vals != NULL )
359 {
360 if( vals[v] == 1.0 )
361 {
362 if( v > 0 )
363 SCIPinfoMessage(scip, file, " +");
364 }
365 else if( vals[v] == -1.0 )
366 SCIPinfoMessage(scip, file, " -");
367 else
368 SCIPinfoMessage(scip, file, " %+.15g", vals[v]);
369 }
370 else if( nvars > 0 )
371 SCIPinfoMessage(scip, file, " +");
372
373 /* print variable name */
374 SCIP_CALL( SCIPwriteVarName(scip, file, vars[v], type) );
375 }
376
377 return SCIP_OKAY;
378}
379
380/** print the given terms as signomial in the following form
381 * c1 <x11>^e11 <x12>^e12 ... <x1n>^e1n + c2 <x21>^e21 <x22>^e22 ... + ... + cn <xn1>^en1 ...
382 *
383 * This string can be parsed by the method SCIPparseVarsPolynomial().
384 *
385 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
386 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
387 *
388 * @pre This method can be called if @p scip is in one of the following stages:
389 * - \ref SCIP_STAGE_PROBLEM
390 * - \ref SCIP_STAGE_TRANSFORMING
391 * - \ref SCIP_STAGE_TRANSFORMED
392 * - \ref SCIP_STAGE_INITPRESOLVE
393 * - \ref SCIP_STAGE_PRESOLVING
394 * - \ref SCIP_STAGE_EXITPRESOLVE
395 * - \ref SCIP_STAGE_PRESOLVED
396 * - \ref SCIP_STAGE_INITSOLVE
397 * - \ref SCIP_STAGE_SOLVING
398 * - \ref SCIP_STAGE_SOLVED
399 * - \ref SCIP_STAGE_EXITSOLVE
400 * - \ref SCIP_STAGE_FREETRANS
401 *
402 * @note The printing process is done via the message handler system.
403 */
405 SCIP* scip, /**< SCIP data structure */
406 FILE* file, /**< output file, or NULL for stdout */
407 SCIP_VAR*** monomialvars, /**< arrays with variables for each monomial */
408 SCIP_Real** monomialexps, /**< arrays with variable exponents, or NULL if always 1.0 */
409 SCIP_Real* monomialcoefs, /**< array with monomial coefficients */
410 int* monomialnvars, /**< array with number of variables for each monomial */
411 int nmonomials, /**< number of monomials */
412 SCIP_Bool type /**< should the variable type be also posted */
413 )
414{
415 int i;
416 int v;
417
418 assert(scip != NULL);
419 assert(monomialvars != NULL || nmonomials == 0);
420 assert(monomialcoefs != NULL || nmonomials == 0);
421 assert(monomialnvars != NULL || nmonomials == 0);
422
423 SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsPolynomial", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
424
425 if( nmonomials == 0 )
426 {
427 SCIPinfoMessage(scip, file, " 0 ");
428 return SCIP_OKAY;
429 }
430
431 for( i = 0; i < nmonomials; ++i )
432 {
433 if( monomialcoefs[i] == 1.0 ) /*lint !e613*/
434 {
435 if( i > 0 )
436 SCIPinfoMessage(scip, file, " +");
437 }
438 else if( monomialcoefs[i] == -1.0 ) /*lint !e613*/
439 SCIPinfoMessage(scip, file, " -");
440 else
441 SCIPinfoMessage(scip, file, " %+.15g", monomialcoefs[i]); /*lint !e613*/
442
443 assert(monomialvars[i] != NULL || monomialnvars[i] == 0); /*lint !e613*/
444
445 for( v = 0; v < monomialnvars[i]; ++v ) /*lint !e613*/
446 {
447 SCIP_CALL( SCIPwriteVarName(scip, file, monomialvars[i][v], type) ); /*lint !e613*/
448 if( monomialexps != NULL && monomialexps[i] != NULL && monomialexps[i][v] != 1.0 )
449 {
450 SCIPinfoMessage(scip, file, "^%.15g", monomialexps[i][v]);
451 }
452 }
453 }
454
455 return SCIP_OKAY;
456}
457
458/** parses variable information (in cip format) out of a string; if the parsing process was successful a variable is
459 * created and captured; if variable is of integral type, fractional bounds are automatically rounded; an integer
460 * variable with bounds zero and one is automatically converted into a binary variable
461 *
462 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
463 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
464 *
465 * @pre This method can be called if @p scip is in one of the following stages:
466 * - \ref SCIP_STAGE_PROBLEM
467 * - \ref SCIP_STAGE_TRANSFORMING
468 * - \ref SCIP_STAGE_INITPRESOLVE
469 * - \ref SCIP_STAGE_PRESOLVING
470 * - \ref SCIP_STAGE_EXITPRESOLVE
471 * - \ref SCIP_STAGE_PRESOLVED
472 * - \ref SCIP_STAGE_SOLVING
473 */
475 SCIP* scip, /**< SCIP data structure */
476 SCIP_VAR** var, /**< pointer to store the problem variable */
477 const char* str, /**< string to parse */
478 SCIP_Bool initial, /**< should var's column be present in the initial root LP? */
479 SCIP_Bool removable, /**< is var's column removable from the LP (due to aging or cleanup)? */
480 SCIP_DECL_VARCOPY ((*varcopy)), /**< copies variable data if wanted to subscip, or NULL */
481 SCIP_DECL_VARDELORIG ((*vardelorig)), /**< frees user data of original variable */
482 SCIP_DECL_VARTRANS ((*vartrans)), /**< creates transformed user data by transforming original user data */
483 SCIP_DECL_VARDELTRANS ((*vardeltrans)), /**< frees user data of transformed variable */
484 SCIP_VARDATA* vardata, /**< user data for this specific variable */
485 char** endptr, /**< pointer to store the final string position if successful */
486 SCIP_Bool* success /**< pointer store if the paring process was successful */
487 )
488{
489 assert(var != NULL);
490
492
493 switch( scip->set->stage )
494 {
496 SCIP_CALL( SCIPvarParseOriginal(var, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
497 str, initial, removable, varcopy, vardelorig, vartrans, vardeltrans, vardata, endptr, success) );
498 break;
499
506 SCIP_CALL( SCIPvarParseTransformed(var, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
507 str, initial, removable, varcopy, vardelorig, vartrans, vardeltrans, vardata, endptr, success) );
508 break;
509
510 default:
511 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
512 return SCIP_INVALIDCALL;
513 } /*lint !e788*/
514
515 return SCIP_OKAY;
516}
517
518/** parses the given string for a variable name and stores the variable in the corresponding pointer if such a variable
519 * exits and returns the position where the parsing stopped
520 *
521 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
522 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
523 *
524 * @pre This method can be called if @p scip is in one of the following stages:
525 * - \ref SCIP_STAGE_PROBLEM
526 * - \ref SCIP_STAGE_TRANSFORMING
527 * - \ref SCIP_STAGE_INITPRESOLVE
528 * - \ref SCIP_STAGE_PRESOLVING
529 * - \ref SCIP_STAGE_EXITPRESOLVE
530 * - \ref SCIP_STAGE_PRESOLVED
531 * - \ref SCIP_STAGE_SOLVING
532 */
534 SCIP* scip, /**< SCIP data structure */
535 const char* str, /**< string to parse */
536 SCIP_VAR** var, /**< pointer to store the problem variable, or NULL if it does not exit */
537 char** endptr /**< pointer to store the final string position if successful */
538 )
539{
540 char varname[SCIP_MAXSTRLEN];
541
542 assert(str != NULL);
543 assert(var != NULL);
544 assert(endptr != NULL);
545
546 SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarName", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
547
548 SCIPstrCopySection(str, '<', '>', varname, SCIP_MAXSTRLEN, endptr);
549 assert(*endptr != NULL);
550
551 if( *endptr == str )
552 {
553 *var = NULL;
554 return SCIP_OKAY;
555 }
556
557 /* check if we have a negated variable */
558 if( *varname == '~' )
559 {
560 SCIPdebugMsg(scip, "parsed negated variable name <%s>\n", &varname[1]);
561
562 /* search for the variable and ignore '~' */
563 (*var) = SCIPfindVar(scip, &varname[1]);
564
565 if( *var != NULL )
566 {
567 SCIP_CALL( SCIPgetNegatedVar(scip, *var, var) );
568 }
569 }
570 else
571 {
572 SCIPdebugMsg(scip, "parsed variable name <%s>\n", varname);
573
574 /* search for the variable */
575 (*var) = SCIPfindVar(scip, varname);
576 }
577
578 str = *endptr;
579
580 /* skip additional variable type marker */
581 if( *str == '[' && (str[1] == SCIP_VARTYPE_BINARY_CHAR || str[1] == SCIP_VARTYPE_INTEGER_CHAR ||
582 str[1] == SCIP_VARTYPE_IMPLINT_CHAR || str[1] == SCIP_VARTYPE_CONTINUOUS_CHAR ) && str[2] == ']' )
583 (*endptr) += 3;
584
585 return SCIP_OKAY;
586}
587
588/** parse the given string as variable list (here ',' is the delimiter)) (<x1>, <x2>, ..., <xn>) (see
589 * SCIPwriteVarsList() ); if it was successful, the pointer success is set to TRUE
590 *
591 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
592 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
593 *
594 * @pre This method can be called if @p scip is in one of the following stages:
595 * - \ref SCIP_STAGE_PROBLEM
596 * - \ref SCIP_STAGE_TRANSFORMING
597 * - \ref SCIP_STAGE_INITPRESOLVE
598 * - \ref SCIP_STAGE_PRESOLVING
599 * - \ref SCIP_STAGE_EXITPRESOLVE
600 * - \ref SCIP_STAGE_PRESOLVED
601 * - \ref SCIP_STAGE_SOLVING
602 *
603 * @note The pointer success in only set to FALSE in the case that a variable with a parsed variable name does not exist.
604 *
605 * @note If the number of (parsed) variables is greater than the available slots in the variable array, nothing happens
606 * except that the required size is stored in the corresponding integer; the reason for this approach is that we
607 * cannot reallocate memory, since we do not know how the memory has been allocated (e.g., by a C++ 'new' or SCIP
608 * memory functions).
609 */
611 SCIP* scip, /**< SCIP data structure */
612 const char* str, /**< string to parse */
613 SCIP_VAR** vars, /**< array to store the parsed variable */
614 int* nvars, /**< pointer to store number of parsed variables */
615 int varssize, /**< size of the variable array */
616 int* requiredsize, /**< pointer to store the required array size for the active variables */
617 char** endptr, /**< pointer to store the final string position if successful */
618 char delimiter, /**< character which is used for delimitation */
619 SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
620 )
621{
622 SCIP_VAR** tmpvars;
623 SCIP_VAR* var;
624 int ntmpvars = 0;
625 int v;
626
627 assert( nvars != NULL );
628 assert( requiredsize != NULL );
629 assert( endptr != NULL );
630 assert( success != NULL );
631
632 SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsList", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
633
634 /* allocate buffer memory for temporary storing the parsed variables */
635 SCIP_CALL( SCIPallocBufferArray(scip, &tmpvars, varssize) );
636
637 *success = TRUE;
638
639 do
640 {
641 *endptr = (char*)str;
642
643 /* parse variable name */
644 SCIP_CALL( SCIPparseVarName(scip, str, &var, endptr) );
645
646 if( var == NULL )
647 break;
648
649 str = *endptr;
650
651 /* store the variable in the tmp array */
652 if( ntmpvars < varssize )
653 tmpvars[ntmpvars] = var;
654
655 ntmpvars++;
656
657 SCIP_CALL( SCIPskipSpace((char**)&str) );
658 }
659 while( *str == delimiter );
660
661 *endptr = (char*)str;
662
663 /* if all variable name searches were successful and the variable array has enough slots, copy the collected variables */
664 if( (*success) && ntmpvars <= varssize )
665 {
666 for( v = 0; v < ntmpvars; ++v )
667 vars[v] = tmpvars[v];
668
669 (*nvars) = ntmpvars;
670 }
671 else
672 (*nvars) = 0;
673
674 (*requiredsize) = ntmpvars;
675
676 /* free buffer arrays */
677 SCIPfreeBufferArray(scip, &tmpvars);
678
679 return SCIP_OKAY;
680}
681
682/** parse the given string as linear sum of variables and coefficients (c1 <x1> + c2 <x2> + ... + cn <xn>)
683 * (see SCIPwriteVarsLinearsum() ); if it was successful, the pointer success is set to TRUE
684 *
685 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
686 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
687 *
688 * @pre This method can be called if @p scip is in one of the following stages:
689 * - \ref SCIP_STAGE_PROBLEM
690 * - \ref SCIP_STAGE_TRANSFORMING
691 * - \ref SCIP_STAGE_INITPRESOLVE
692 * - \ref SCIP_STAGE_PRESOLVING
693 * - \ref SCIP_STAGE_EXITPRESOLVE
694 * - \ref SCIP_STAGE_PRESOLVED
695 * - \ref SCIP_STAGE_SOLVING
696 *
697 * @note The pointer success in only set to FALSE in the case that a variable with a parsed variable name does not exist.
698 *
699 * @note If the number of (parsed) variables is greater than the available slots in the variable array, nothing happens
700 * except that the required size is stored in the corresponding integer; the reason for this approach is that we
701 * cannot reallocate memory, since we do not know how the memory has been allocated (e.g., by a C++ 'new' or SCIP
702 * memory functions).
703 */
705 SCIP* scip, /**< SCIP data structure */
706 const char* str, /**< string to parse */
707 SCIP_VAR** vars, /**< array to store the parsed variables */
708 SCIP_Real* vals, /**< array to store the parsed coefficients */
709 int* nvars, /**< pointer to store number of parsed variables */
710 int varssize, /**< size of the variable array */
711 int* requiredsize, /**< pointer to store the required array size for the active variables */
712 char** endptr, /**< pointer to store the final string position if successful */
713 SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
714 )
715{
716 SCIP_VAR*** monomialvars;
717 SCIP_Real** monomialexps;
718 SCIP_Real* monomialcoefs;
719 int* monomialnvars;
720 int nmonomials;
721
722 SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsLinearsum", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
723
724 assert(scip != NULL);
725 assert(str != NULL);
726 assert(vars != NULL || varssize == 0);
727 assert(vals != NULL || varssize == 0);
728 assert(nvars != NULL);
729 assert(requiredsize != NULL);
730 assert(endptr != NULL);
731 assert(success != NULL);
732
733 *requiredsize = 0;
734
735 SCIP_CALL( SCIPparseVarsPolynomial(scip, str, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, &nmonomials, endptr, success) );
736
737 if( !*success )
738 {
739 assert(nmonomials == 0); /* SCIPparseVarsPolynomial should have freed all buffers, so no need to call free here */
740 return SCIP_OKAY;
741 }
742
743 /* check if linear sum is just "0" */
744 if( nmonomials == 1 && monomialnvars[0] == 0 && monomialcoefs[0] == 0.0 )
745 {
746 *nvars = 0;
747 *requiredsize = 0;
748
749 SCIPfreeParseVarsPolynomialData(scip, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, nmonomials);
750
751 return SCIP_OKAY;
752 }
753
754 *nvars = nmonomials;
755 *requiredsize = nmonomials;
756
757 /* if we have enough slots in the variables array, copy variables over */
758 if( varssize >= nmonomials )
759 {
760 int v;
761
762 for( v = 0; v < nmonomials; ++v )
763 {
764 if( monomialnvars[v] == 0 )
765 {
766 SCIPerrorMessage("constant in linear sum\n");
767 *success = FALSE;
768 break;
769 }
770 if( monomialnvars[v] > 1 || monomialexps[v][0] != 1.0 )
771 {
772 SCIPerrorMessage("nonlinear monomial in linear sum\n");
773 *success = FALSE;
774 break;
775 }
776 assert(monomialnvars[v] == 1);
777 assert(monomialvars[v][0] != NULL);
778 assert(monomialexps[v][0] == 1.0);
779
780 vars[v] = monomialvars[v][0]; /*lint !e613*/
781 vals[v] = monomialcoefs[v]; /*lint !e613*/
782 }
783 }
784
785 SCIPfreeParseVarsPolynomialData(scip, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, nmonomials);
786
787 return SCIP_OKAY;
788}
789
790/** parse the given string as signomial of variables and coefficients
791 * (c1 <x11>^e11 <x12>^e12 ... <x1n>^e1n + c2 <x21>^e21 <x22>^e22 ... + ... + cn <xn1>^en1 ...)
792 * (see SCIPwriteVarsPolynomial()); if it was successful, the pointer success is set to TRUE
793 *
794 * The user has to call SCIPfreeParseVarsPolynomialData(scip, monomialvars, monomialexps,
795 * monomialcoefs, monomialnvars, *nmonomials) short after SCIPparseVarsPolynomial to free all the
796 * allocated memory again.
797 *
798 * Parsing is stopped at the end of string (indicated by the \\0-character) or when no more monomials
799 * are recognized.
800 *
801 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
802 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
803 *
804 * @pre This method can be called if @p scip is in one of the following stages:
805 * - \ref SCIP_STAGE_PROBLEM
806 * - \ref SCIP_STAGE_TRANSFORMING
807 * - \ref SCIP_STAGE_INITPRESOLVE
808 * - \ref SCIP_STAGE_PRESOLVING
809 * - \ref SCIP_STAGE_EXITPRESOLVE
810 * - \ref SCIP_STAGE_PRESOLVED
811 * - \ref SCIP_STAGE_SOLVING
812 */
814 SCIP* scip, /**< SCIP data structure */
815 const char* str, /**< string to parse */
816 SCIP_VAR**** monomialvars, /**< pointer to store arrays with variables for each monomial */
817 SCIP_Real*** monomialexps, /**< pointer to store arrays with variable exponents */
818 SCIP_Real** monomialcoefs, /**< pointer to store array with monomial coefficients */
819 int** monomialnvars, /**< pointer to store array with number of variables for each monomial */
820 int* nmonomials, /**< pointer to store number of parsed monomials */
821 char** endptr, /**< pointer to store the final string position if successful */
822 SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
823 )
824{
825 typedef enum
826 {
827 SCIPPARSEPOLYNOMIAL_STATE_BEGIN, /* we are at the beginning of a monomial */
828 SCIPPARSEPOLYNOMIAL_STATE_INTERMED, /* we are in between the factors of a monomial */
829 SCIPPARSEPOLYNOMIAL_STATE_COEF, /* we parse the coefficient of a monomial */
830 SCIPPARSEPOLYNOMIAL_STATE_VARS, /* we parse monomial variables */
831 SCIPPARSEPOLYNOMIAL_STATE_EXPONENT, /* we parse the exponent of a variable */
832 SCIPPARSEPOLYNOMIAL_STATE_END, /* we are at the end the polynomial */
833 SCIPPARSEPOLYNOMIAL_STATE_ERROR /* a parsing error occured */
834 } SCIPPARSEPOLYNOMIAL_STATES;
835
836 SCIPPARSEPOLYNOMIAL_STATES state;
837 int monomialssize;
838
839 /* data of currently parsed monomial */
840 int varssize;
841 int nvars;
842 SCIP_VAR** vars;
843 SCIP_Real* exponents;
844 SCIP_Real coef;
845
846 assert(scip != NULL);
847 assert(str != NULL);
848 assert(monomialvars != NULL);
849 assert(monomialexps != NULL);
850 assert(monomialnvars != NULL);
851 assert(monomialcoefs != NULL);
852 assert(nmonomials != NULL);
853 assert(endptr != NULL);
854 assert(success != NULL);
855
856 SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsPolynomial", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
857
858 *success = FALSE;
859 *nmonomials = 0;
860 monomialssize = 0;
861 *monomialvars = NULL;
862 *monomialexps = NULL;
863 *monomialcoefs = NULL;
864 *monomialnvars = NULL;
865
866 /* initialize state machine */
867 state = SCIPPARSEPOLYNOMIAL_STATE_BEGIN;
868 varssize = 0;
869 nvars = 0;
870 vars = NULL;
871 exponents = NULL;
872 coef = SCIP_INVALID;
873
874 SCIPdebugMsg(scip, "parsing polynomial from '%s'\n", str);
875
876 while( *str && state != SCIPPARSEPOLYNOMIAL_STATE_END && state != SCIPPARSEPOLYNOMIAL_STATE_ERROR )
877 {
878 /* skip white space */
879 SCIP_CALL( SCIPskipSpace((char**)&str) );
880
881 assert(state != SCIPPARSEPOLYNOMIAL_STATE_END);
882
883 switch( state )
884 {
885 case SCIPPARSEPOLYNOMIAL_STATE_BEGIN:
886 {
887 if( coef != SCIP_INVALID ) /*lint !e777*/
888 {
889 SCIPdebugMsg(scip, "push monomial with coefficient <%g> and <%d> vars\n", coef, nvars);
890
891 /* push previous monomial */
892 if( monomialssize <= *nmonomials )
893 {
894 monomialssize = SCIPcalcMemGrowSize(scip, *nmonomials+1);
895
896 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, *nmonomials, monomialssize) );
897 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, *nmonomials, monomialssize) );
898 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, *nmonomials, monomialssize) );
899 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, *nmonomials, monomialssize) );
900 }
901
902 if( nvars > 0 )
903 {
904 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*monomialvars)[*nmonomials], vars, nvars) ); /*lint !e866*/
905 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*monomialexps)[*nmonomials], exponents, nvars) ); /*lint !e866*/
906 }
907 else
908 {
909 (*monomialvars)[*nmonomials] = NULL;
910 (*monomialexps)[*nmonomials] = NULL;
911 }
912 (*monomialcoefs)[*nmonomials] = coef;
913 (*monomialnvars)[*nmonomials] = nvars;
914 ++*nmonomials;
915
916 nvars = 0;
917 coef = SCIP_INVALID;
918 }
919
920 if( *str == '<' )
921 {
922 /* there seem to come a variable at the beginning of a monomial
923 * so assume the coefficient is 1.0
924 */
925 state = SCIPPARSEPOLYNOMIAL_STATE_VARS;
926 coef = 1.0;
927 }
928 else if( *str == '-' || *str == '+' || isdigit(*str) )
929 state = SCIPPARSEPOLYNOMIAL_STATE_COEF;
930 else
931 state = SCIPPARSEPOLYNOMIAL_STATE_END;
932
933 break;
934 }
935
936 case SCIPPARSEPOLYNOMIAL_STATE_INTERMED:
937 {
938 if( *str == '<' )
939 {
940 /* there seem to come another variable */
941 state = SCIPPARSEPOLYNOMIAL_STATE_VARS;
942 }
943 else if( *str == '-' || *str == '+' || isdigit(*str) )
944 {
945 /* there seem to come a coefficient, which means the next monomial */
946 state = SCIPPARSEPOLYNOMIAL_STATE_BEGIN;
947 }
948 else /* since we cannot detect the symbols we stop parsing the polynomial */
949 state = SCIPPARSEPOLYNOMIAL_STATE_END;
950
951 break;
952 }
953
954 case SCIPPARSEPOLYNOMIAL_STATE_COEF:
955 {
956 if( *str == '+' && !isdigit(str[1]) )
957 {
958 /* only a plus sign, without number */
959 coef = 1.0;
960 ++str;
961 }
962 else if( *str == '-' && !isdigit(str[1]) )
963 {
964 /* only a minus sign, without number */
965 coef = -1.0;
966 ++str;
967 }
968 else if( SCIPstrToRealValue(str, &coef, endptr) )
969 {
970 str = *endptr;
971 }
972 else
973 {
974 SCIPerrorMessage("could not parse number in the beginning of '%s'\n", str);
975 state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
976 break;
977 }
978
979 /* after the coefficient we go into the intermediate state, i.e., expecting next variables */
980 state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED; /*lint !e838*/
981
982 break;
983 }
984
985 case SCIPPARSEPOLYNOMIAL_STATE_VARS:
986 {
987 SCIP_VAR* var;
988
989 assert(*str == '<');
990
991 /* parse variable name */
992 SCIP_CALL( SCIPparseVarName(scip, str, &var, endptr) );
993
994 /* check if variable name was parsed */
995 if( *endptr == str )
996 {
997 state = SCIPPARSEPOLYNOMIAL_STATE_END;
998 break;
999 }
1000
1001 if( var == NULL )
1002 {
1003 SCIPerrorMessage("did not find variable in the beginning of %s\n", str);
1004 state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
1005 break;
1006 }
1007
1008 /* add variable to vars array */
1009 if( nvars + 1 > varssize )
1010 {
1011 varssize = SCIPcalcMemGrowSize(scip, nvars+1);
1012 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &vars, nvars, varssize) );
1013 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &exponents, nvars, varssize) );
1014 }
1015 assert(vars != NULL);
1016 assert(exponents != NULL);
1017
1018 vars[nvars] = var;
1019 exponents[nvars] = 1.0;
1020 ++nvars;
1021
1022 str = *endptr;
1023
1024 if( *str == '^' )
1025 state = SCIPPARSEPOLYNOMIAL_STATE_EXPONENT;
1026 else
1027 state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED;
1028
1029 break;
1030 }
1031
1032 case SCIPPARSEPOLYNOMIAL_STATE_EXPONENT:
1033 {
1034 assert(*str == '^');
1035 assert(nvars > 0); /* we should be in a monomial that has already a variable */
1036 assert(exponents != NULL);
1037 ++str;
1038
1039 if( !SCIPstrToRealValue(str, &exponents[nvars-1], endptr) )
1040 {
1041 SCIPerrorMessage("could not parse number in the beginning of '%s'\n", str);
1042 state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
1043 break;
1044 }
1045 str = *endptr;
1046
1047 /* after the exponent we go into the intermediate state, i.e., expecting next variables */
1048 state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED; /*lint !e838*/
1049 break;
1050 }
1051
1052 /* coverity[dead_error_line] */
1053 case SCIPPARSEPOLYNOMIAL_STATE_END:
1054 /* coverity[dead_error_line] */
1055 case SCIPPARSEPOLYNOMIAL_STATE_ERROR:
1056 default:
1057 SCIPerrorMessage("unexpected state\n");
1058 return SCIP_READERROR;
1059 }
1060 }
1061
1062 /* set end pointer */
1063 *endptr = (char*)str;
1064
1065 /* check state at end of string */
1066 switch( state )
1067 {
1068 case SCIPPARSEPOLYNOMIAL_STATE_BEGIN:
1069 case SCIPPARSEPOLYNOMIAL_STATE_END:
1070 case SCIPPARSEPOLYNOMIAL_STATE_INTERMED:
1071 {
1072 if( coef != SCIP_INVALID ) /*lint !e777*/
1073 {
1074 /* push last monomial */
1075 SCIPdebugMsg(scip, "push monomial with coefficient <%g> and <%d> vars\n", coef, nvars);
1076 if( monomialssize <= *nmonomials )
1077 {
1078 monomialssize = *nmonomials+1;
1079 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, *nmonomials, monomialssize) );
1080 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, *nmonomials, monomialssize) );
1081 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, *nmonomials, monomialssize) );
1082 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, *nmonomials, monomialssize) );
1083 }
1084
1085 if( nvars > 0 )
1086 {
1087 /* shrink vars and exponents array to needed size and take over ownership */
1088 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &vars, varssize, nvars) );
1089 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &exponents, varssize, nvars) );
1090 (*monomialvars)[*nmonomials] = vars;
1091 (*monomialexps)[*nmonomials] = exponents;
1092 vars = NULL;
1093 exponents = NULL;
1094 }
1095 else
1096 {
1097 (*monomialvars)[*nmonomials] = NULL;
1098 (*monomialexps)[*nmonomials] = NULL;
1099 }
1100 (*monomialcoefs)[*nmonomials] = coef;
1101 (*monomialnvars)[*nmonomials] = nvars;
1102 ++*nmonomials;
1103 }
1104
1105 *success = TRUE;
1106 break;
1107 }
1108
1109 case SCIPPARSEPOLYNOMIAL_STATE_COEF:
1110 case SCIPPARSEPOLYNOMIAL_STATE_VARS:
1111 case SCIPPARSEPOLYNOMIAL_STATE_EXPONENT:
1112 {
1113 SCIPerrorMessage("unexpected parsing state at end of polynomial string\n");
1114 }
1115 /*lint -fallthrough*/
1116 case SCIPPARSEPOLYNOMIAL_STATE_ERROR:
1117 assert(!*success);
1118 break;
1119 }
1120
1121 /* free memory to store current monomial, if still existing */
1122 SCIPfreeBlockMemoryArrayNull(scip, &vars, varssize);
1123 SCIPfreeBlockMemoryArrayNull(scip, &exponents, varssize);
1124
1125 if( *success && *nmonomials > 0 )
1126 {
1127 /* shrink arrays to required size, so we do not need to keep monomialssize around */
1128 assert(*nmonomials <= monomialssize);
1129 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, monomialssize, *nmonomials) );
1130 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, monomialssize, *nmonomials) );
1131 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, monomialssize, *nmonomials) );
1132 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, monomialssize, *nmonomials) );
1133
1134 /* SCIPwriteVarsPolynomial(scip, NULL, *monomialvars, *monomialexps, *monomialcoefs, *monomialnvars, *nmonomials, FALSE); */
1135 }
1136 else
1137 {
1138 /* in case of error, cleanup all data here */
1139 SCIPfreeParseVarsPolynomialData(scip, monomialvars, monomialexps, monomialcoefs, monomialnvars, *nmonomials);
1140 *nmonomials = 0;
1141 }
1142
1143 return SCIP_OKAY;
1144}
1145
1146/** frees memory allocated when parsing a signomial from a string
1147 *
1148 * @pre This method can be called if @p scip is in one of the following stages:
1149 * - \ref SCIP_STAGE_PROBLEM
1150 * - \ref SCIP_STAGE_TRANSFORMING
1151 * - \ref SCIP_STAGE_INITPRESOLVE
1152 * - \ref SCIP_STAGE_PRESOLVING
1153 * - \ref SCIP_STAGE_EXITPRESOLVE
1154 * - \ref SCIP_STAGE_PRESOLVED
1155 * - \ref SCIP_STAGE_SOLVING
1156 */
1158 SCIP* scip, /**< SCIP data structure */
1159 SCIP_VAR**** monomialvars, /**< pointer to store arrays with variables for each monomial */
1160 SCIP_Real*** monomialexps, /**< pointer to store arrays with variable exponents */
1161 SCIP_Real** monomialcoefs, /**< pointer to store array with monomial coefficients */
1162 int** monomialnvars, /**< pointer to store array with number of variables for each monomial */
1163 int nmonomials /**< pointer to store number of parsed monomials */
1164 )
1165{
1166 int i;
1167
1168 assert(scip != NULL);
1169 assert(monomialvars != NULL);
1170 assert(monomialexps != NULL);
1171 assert(monomialcoefs != NULL);
1172 assert(monomialnvars != NULL);
1173
1174 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPfreeParseVarsPolynomialData", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1175
1176 if( nmonomials == 0 )
1177 return;
1178
1179 assert(*monomialvars != NULL);
1180 assert(*monomialexps != NULL);
1181 assert(*monomialcoefs != NULL);
1182 assert(*monomialnvars != NULL);
1183
1184 for( i = nmonomials - 1; i >= 0; --i )
1185 {
1186 SCIPfreeBlockMemoryArrayNull(scip, &(*monomialexps)[i], (*monomialnvars)[i]);
1187 SCIPfreeBlockMemoryArrayNull(scip, &(*monomialvars)[i], (*monomialnvars)[i]);
1188 }
1189
1190 SCIPfreeBlockMemoryArray(scip, monomialcoefs, nmonomials);
1191 SCIPfreeBlockMemoryArray(scip, monomialnvars, nmonomials);
1192 SCIPfreeBlockMemoryArray(scip, monomialexps, nmonomials);
1193 SCIPfreeBlockMemoryArray(scip, monomialvars, nmonomials);
1194}
1195
1196/** increases usage counter of variable
1197 *
1198 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1199 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1200 *
1201 * @pre This method can be called if @p scip is in one of the following stages:
1202 * - \ref SCIP_STAGE_PROBLEM
1203 * - \ref SCIP_STAGE_TRANSFORMING
1204 * - \ref SCIP_STAGE_TRANSFORMED
1205 * - \ref SCIP_STAGE_INITPRESOLVE
1206 * - \ref SCIP_STAGE_PRESOLVING
1207 * - \ref SCIP_STAGE_EXITPRESOLVE
1208 * - \ref SCIP_STAGE_PRESOLVED
1209 * - \ref SCIP_STAGE_INITSOLVE
1210 * - \ref SCIP_STAGE_SOLVING
1211 * - \ref SCIP_STAGE_SOLVED
1212 * - \ref SCIP_STAGE_EXITSOLVE
1213 */
1215 SCIP* scip, /**< SCIP data structure */
1216 SCIP_VAR* var /**< variable to capture */
1217 )
1218{
1219 SCIP_CALL( SCIPcheckStage(scip, "SCIPcaptureVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1220 assert(var->scip == scip);
1221
1222 SCIPvarCapture(var);
1223
1224 return SCIP_OKAY;
1225}
1226
1227/** decreases usage counter of variable, if the usage pointer reaches zero the variable gets freed
1228 *
1229 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1230 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1231 *
1232 * @pre This method can be called if @p scip is in one of the following stages:
1233 * - \ref SCIP_STAGE_PROBLEM
1234 * - \ref SCIP_STAGE_TRANSFORMING
1235 * - \ref SCIP_STAGE_TRANSFORMED
1236 * - \ref SCIP_STAGE_INITPRESOLVE
1237 * - \ref SCIP_STAGE_PRESOLVING
1238 * - \ref SCIP_STAGE_EXITPRESOLVE
1239 * - \ref SCIP_STAGE_PRESOLVED
1240 * - \ref SCIP_STAGE_INITSOLVE
1241 * - \ref SCIP_STAGE_SOLVING
1242 * - \ref SCIP_STAGE_SOLVED
1243 * - \ref SCIP_STAGE_EXITSOLVE
1244 * - \ref SCIP_STAGE_FREETRANS
1245 *
1246 * @note the pointer of the variable will be NULLed
1247 */
1249 SCIP* scip, /**< SCIP data structure */
1250 SCIP_VAR** var /**< pointer to variable */
1251 )
1252{
1253 assert(var != NULL);
1254 assert(*var != NULL);
1255 assert((*var)->scip == scip);
1256
1257 SCIP_CALL( SCIPcheckStage(scip, "SCIPreleaseVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1258
1259 switch( scip->set->stage )
1260 {
1261 case SCIP_STAGE_PROBLEM:
1262 SCIP_CALL( SCIPvarRelease(var, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp) );
1263 return SCIP_OKAY;
1264
1272 case SCIP_STAGE_SOLVING:
1273 case SCIP_STAGE_SOLVED:
1276 if( !SCIPvarIsTransformed(*var) && (*var)->nuses == 1 && (*var)->data.original.transvar != NULL )
1277 {
1278 SCIPerrorMessage("cannot release last use of original variable while associated transformed variable exists\n");
1279 return SCIP_INVALIDCALL;
1280 }
1281 SCIP_CALL( SCIPvarRelease(var, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp) );
1282 return SCIP_OKAY;
1283
1284 default:
1285 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
1286 return SCIP_INVALIDCALL;
1287 } /*lint !e788*/
1288}
1289
1290/** changes the name of a variable
1291 *
1292 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1293 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1294 *
1295 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PROBLEM
1296 *
1297 * @note to get the current name of a variable, use SCIPvarGetName() from pub_var.h
1298 */
1300 SCIP* scip, /**< SCIP data structure */
1301 SCIP_VAR* var, /**< variable */
1302 const char* name /**< new name of constraint */
1303 )
1304{
1306 assert( var->scip == scip );
1307
1309 {
1310 SCIPerrorMessage("variable names can only be changed in problem creation stage\n");
1311 SCIPABORT();
1312 return SCIP_INVALIDCALL; /*lint !e527*/
1313 }
1314
1315 /* remove variable's name from the namespace if the variable was already added */
1316 if( SCIPvarGetProbindex(var) != -1 )
1317 {
1318 SCIP_CALL( SCIPprobRemoveVarName(scip->origprob, var) );
1319 }
1320
1321 /* change variable name */
1322 SCIP_CALL( SCIPvarChgName(var, SCIPblkmem(scip), name) );
1323
1324 /* add variable's name to the namespace if the variable was already added */
1325 if( SCIPvarGetProbindex(var) != -1 )
1326 {
1327 SCIP_CALL( SCIPprobAddVarName(scip->origprob, var) );
1328 }
1329
1330 return SCIP_OKAY;
1331}
1332
1333/** gets and captures transformed variable of a given variable; if the variable is not yet transformed,
1334 * a new transformed variable for this variable is created
1335 *
1336 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1337 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1338 *
1339 * @pre This method can be called if @p scip is in one of the following stages:
1340 * - \ref SCIP_STAGE_TRANSFORMING
1341 * - \ref SCIP_STAGE_TRANSFORMED
1342 * - \ref SCIP_STAGE_INITPRESOLVE
1343 * - \ref SCIP_STAGE_PRESOLVING
1344 * - \ref SCIP_STAGE_EXITPRESOLVE
1345 * - \ref SCIP_STAGE_PRESOLVED
1346 * - \ref SCIP_STAGE_INITSOLVE
1347 * - \ref SCIP_STAGE_SOLVING
1348 */
1350 SCIP* scip, /**< SCIP data structure */
1351 SCIP_VAR* var, /**< variable to get/create transformed variable for */
1352 SCIP_VAR** transvar /**< pointer to store the transformed variable */
1353 )
1354{
1355 assert(transvar != NULL);
1356
1357 SCIP_CALL( SCIPcheckStage(scip, "SCIPtransformVar", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1358
1359 if( SCIPvarIsTransformed(var) )
1360 {
1361 *transvar = var;
1362 SCIPvarCapture(*transvar);
1363 }
1364 else
1365 {
1366 SCIP_CALL( SCIPvarTransform(var, scip->mem->probmem, scip->set, scip->stat, scip->origprob->objsense, transvar) );
1367 }
1368
1369 return SCIP_OKAY;
1370}
1371
1372/** gets and captures transformed variables for an array of variables;
1373 * if a variable of the array is not yet transformed, a new transformed variable for this variable is created;
1374 * it is possible to call this method with vars == transvars
1375 *
1376 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1377 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1378 *
1379 * @pre This method can be called if @p scip is in one of the following stages:
1380 * - \ref SCIP_STAGE_TRANSFORMING
1381 * - \ref SCIP_STAGE_TRANSFORMED
1382 * - \ref SCIP_STAGE_INITPRESOLVE
1383 * - \ref SCIP_STAGE_PRESOLVING
1384 * - \ref SCIP_STAGE_EXITPRESOLVE
1385 * - \ref SCIP_STAGE_PRESOLVED
1386 * - \ref SCIP_STAGE_INITSOLVE
1387 * - \ref SCIP_STAGE_SOLVING
1388 */
1390 SCIP* scip, /**< SCIP data structure */
1391 int nvars, /**< number of variables to get/create transformed variables for */
1392 SCIP_VAR** vars, /**< array with variables to get/create transformed variables for */
1393 SCIP_VAR** transvars /**< array to store the transformed variables */
1394 )
1395{
1396 int v;
1397
1398 assert(nvars == 0 || vars != NULL);
1399 assert(nvars == 0 || transvars != NULL);
1400
1401 SCIP_CALL( SCIPcheckStage(scip, "SCIPtransformVars", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1402
1403 for( v = 0; v < nvars; ++v )
1404 {
1405 if( SCIPvarIsTransformed(vars[v]) )
1406 {
1407 transvars[v] = vars[v];
1408 SCIPvarCapture(transvars[v]);
1409 }
1410 else
1411 {
1412 SCIP_CALL( SCIPvarTransform(vars[v], scip->mem->probmem, scip->set, scip->stat, scip->origprob->objsense,
1413 &transvars[v]) );
1414 }
1415 }
1416
1417 return SCIP_OKAY;
1418}
1419
1420/** gets corresponding transformed variable of a given variable;
1421 * returns NULL as transvar, if transformed variable is not yet existing
1422 *
1423 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1424 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1425 *
1426 * @pre This method can be called if @p scip is in one of the following stages:
1427 * - \ref SCIP_STAGE_TRANSFORMING
1428 * - \ref SCIP_STAGE_TRANSFORMED
1429 * - \ref SCIP_STAGE_INITPRESOLVE
1430 * - \ref SCIP_STAGE_PRESOLVING
1431 * - \ref SCIP_STAGE_EXITPRESOLVE
1432 * - \ref SCIP_STAGE_PRESOLVED
1433 * - \ref SCIP_STAGE_INITSOLVE
1434 * - \ref SCIP_STAGE_SOLVING
1435 * - \ref SCIP_STAGE_SOLVED
1436 * - \ref SCIP_STAGE_EXITSOLVE
1437 * - \ref SCIP_STAGE_FREETRANS
1438 */
1440 SCIP* scip, /**< SCIP data structure */
1441 SCIP_VAR* var, /**< variable to get transformed variable for */
1442 SCIP_VAR** transvar /**< pointer to store the transformed variable */
1443 )
1444{
1445 assert(transvar != NULL);
1446
1447 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetTransformedVar", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1448
1449 if( SCIPvarIsTransformed(var) )
1450 *transvar = var;
1451 else
1452 {
1453 SCIP_CALL( SCIPvarGetTransformed(var, scip->mem->probmem, scip->set, scip->stat, transvar) );
1454 }
1455
1456 return SCIP_OKAY;
1457}
1458
1459/** gets corresponding transformed variables for an array of variables;
1460 * stores NULL in a transvars slot, if the transformed variable is not yet existing;
1461 * it is possible to call this method with vars == transvars, but remember that variables that are not
1462 * yet transformed will be replaced with NULL
1463 *
1464 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1465 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1466 *
1467 * @pre This method can be called if @p scip is in one of the following stages:
1468 * - \ref SCIP_STAGE_TRANSFORMING
1469 * - \ref SCIP_STAGE_TRANSFORMED
1470 * - \ref SCIP_STAGE_INITPRESOLVE
1471 * - \ref SCIP_STAGE_PRESOLVING
1472 * - \ref SCIP_STAGE_EXITPRESOLVE
1473 * - \ref SCIP_STAGE_PRESOLVED
1474 * - \ref SCIP_STAGE_INITSOLVE
1475 * - \ref SCIP_STAGE_SOLVING
1476 * - \ref SCIP_STAGE_SOLVED
1477 * - \ref SCIP_STAGE_EXITSOLVE
1478 * - \ref SCIP_STAGE_FREETRANS
1479 */
1481 SCIP* scip, /**< SCIP data structure */
1482 int nvars, /**< number of variables to get transformed variables for */
1483 SCIP_VAR** vars, /**< array with variables to get transformed variables for */
1484 SCIP_VAR** transvars /**< array to store the transformed variables */
1485 )
1486{
1487 int v;
1488
1489 assert(nvars == 0 || vars != NULL);
1490 assert(nvars == 0 || transvars != NULL);
1491
1492 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetTransformedVars", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1493
1494 for( v = 0; v < nvars; ++v )
1495 {
1496 if( SCIPvarIsTransformed(vars[v]) )
1497 transvars[v] = vars[v];
1498 else
1499 {
1500 SCIP_CALL( SCIPvarGetTransformed(vars[v], scip->mem->probmem, scip->set, scip->stat, &transvars[v]) );
1501 }
1502 }
1503
1504 return SCIP_OKAY;
1505}
1506
1507/** gets negated variable x' = lb + ub - x of variable x; negated variable is created, if not yet existing;
1508 * in difference to \ref SCIPcreateVar, the negated variable must not be released (unless captured explicitly)
1509 *
1510 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1511 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1512 *
1513 * @pre This method can be called if @p scip is in one of the following stages:
1514 * - \ref SCIP_STAGE_PROBLEM
1515 * - \ref SCIP_STAGE_TRANSFORMING
1516 * - \ref SCIP_STAGE_TRANSFORMED
1517 * - \ref SCIP_STAGE_INITPRESOLVE
1518 * - \ref SCIP_STAGE_PRESOLVING
1519 * - \ref SCIP_STAGE_EXITPRESOLVE
1520 * - \ref SCIP_STAGE_PRESOLVED
1521 * - \ref SCIP_STAGE_INITSOLVE
1522 * - \ref SCIP_STAGE_SOLVING
1523 * - \ref SCIP_STAGE_SOLVED
1524 * - \ref SCIP_STAGE_EXITSOLVE
1525 * - \ref SCIP_STAGE_FREETRANS
1526 */
1528 SCIP* scip, /**< SCIP data structure */
1529 SCIP_VAR* var, /**< variable to get negated variable for */
1530 SCIP_VAR** negvar /**< pointer to store the negated variable */
1531 )
1532{
1533 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNegatedVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1534 assert( var->scip == scip );
1535
1536 SCIP_CALL( SCIPvarNegate(var, scip->mem->probmem, scip->set, scip->stat, negvar) );
1537
1538 return SCIP_OKAY;
1539}
1540
1541/** gets negated variables x' = lb + ub - x of variables x; negated variables are created, if not yet existing
1542 *
1543 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1544 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1545 *
1546 * @pre This method can be called if @p scip is in one of the following stages:
1547 * - \ref SCIP_STAGE_PROBLEM
1548 * - \ref SCIP_STAGE_TRANSFORMING
1549 * - \ref SCIP_STAGE_TRANSFORMED
1550 * - \ref SCIP_STAGE_INITPRESOLVE
1551 * - \ref SCIP_STAGE_PRESOLVING
1552 * - \ref SCIP_STAGE_EXITPRESOLVE
1553 * - \ref SCIP_STAGE_PRESOLVED
1554 * - \ref SCIP_STAGE_INITSOLVE
1555 * - \ref SCIP_STAGE_SOLVING
1556 * - \ref SCIP_STAGE_SOLVED
1557 * - \ref SCIP_STAGE_EXITSOLVE
1558 * - \ref SCIP_STAGE_FREETRANS
1559 */
1561 SCIP* scip, /**< SCIP data structure */
1562 int nvars, /**< number of variables to get negated variables for */
1563 SCIP_VAR** vars, /**< array of variables to get negated variables for */
1564 SCIP_VAR** negvars /**< array to store the negated variables */
1565 )
1566{
1567 int v;
1568
1569 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNegatedVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1570
1571 for( v = 0; v < nvars; ++v )
1572 {
1573 SCIP_CALL( SCIPvarNegate(vars[v], scip->mem->probmem, scip->set, scip->stat, &(negvars[v])) );
1574 }
1575
1576 return SCIP_OKAY;
1577}
1578
1579/** gets a binary variable that is equal to the given binary variable, and that is either active, fixed, or
1580 * multi-aggregated, or the negated variable of an active, fixed, or multi-aggregated variable
1581 *
1582 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1583 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1584 *
1585 * @pre This method can be called if @p scip is in one of the following stages:
1586 * - \ref SCIP_STAGE_PROBLEM
1587 * - \ref SCIP_STAGE_TRANSFORMED
1588 * - \ref SCIP_STAGE_INITPRESOLVE
1589 * - \ref SCIP_STAGE_PRESOLVING
1590 * - \ref SCIP_STAGE_EXITPRESOLVE
1591 * - \ref SCIP_STAGE_PRESOLVED
1592 * - \ref SCIP_STAGE_INITSOLVE
1593 * - \ref SCIP_STAGE_SOLVING
1594 * - \ref SCIP_STAGE_SOLVED
1595 * - \ref SCIP_STAGE_EXITSOLVE
1596 */
1598 SCIP* scip, /**< SCIP data structure */
1599 SCIP_VAR* var, /**< binary variable to get binary representative for */
1600 SCIP_VAR** repvar, /**< pointer to store the binary representative */
1601 SCIP_Bool* negated /**< pointer to store whether the negation of an active variable was returned */
1602 )
1603{
1604 assert(scip != NULL);
1605 assert(var != NULL);
1606 assert(repvar != NULL);
1607 assert(negated != NULL);
1608 assert(var->scip == scip);
1609
1610 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetBinvarRepresentative", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1611
1612 /* get the active representative of the given variable */
1613 *repvar = var;
1614 *negated = FALSE;
1615 SCIP_CALL( SCIPvarGetProbvarBinary(repvar, negated) );
1616
1617 /* negate the representative, if it corresponds to the negation of the given variable */
1618 if( *negated )
1619 {
1620 SCIP_CALL( SCIPgetNegatedVar(scip, *repvar, repvar) );
1621 }
1622
1623 return SCIP_OKAY;
1624}
1625
1626/** gets binary variables that are equal to the given binary variables, and which are either active, fixed, or
1627 * multi-aggregated, or the negated variables of active, fixed, or multi-aggregated variables
1628 *
1629 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1630 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1631 *
1632 * @pre This method can be called if @p scip is in one of the following stages:
1633 * - \ref SCIP_STAGE_PROBLEM
1634 * - \ref SCIP_STAGE_TRANSFORMED
1635 * - \ref SCIP_STAGE_INITPRESOLVE
1636 * - \ref SCIP_STAGE_PRESOLVING
1637 * - \ref SCIP_STAGE_EXITPRESOLVE
1638 * - \ref SCIP_STAGE_PRESOLVED
1639 * - \ref SCIP_STAGE_INITSOLVE
1640 * - \ref SCIP_STAGE_SOLVING
1641 * - \ref SCIP_STAGE_SOLVED
1642 * - \ref SCIP_STAGE_EXITSOLVE
1643 */
1645 SCIP* scip, /**< SCIP data structure */
1646 int nvars, /**< number of binary variables to get representatives for */
1647 SCIP_VAR** vars, /**< binary variables to get binary representatives for */
1648 SCIP_VAR** repvars, /**< array to store the binary representatives */
1649 SCIP_Bool* negated /**< array to store whether the negation of an active variable was returned */
1650 )
1651{
1652 int v;
1653
1654 assert(scip != NULL);
1655 assert(vars != NULL || nvars == 0);
1656 assert(repvars != NULL || nvars == 0);
1657 assert(negated != NULL || nvars == 0);
1658
1659 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetBinvarRepresentatives", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1660
1661 if( nvars == 0 )
1662 return SCIP_OKAY;
1663
1664 /* get the active representative of the given variable */
1665 BMScopyMemoryArray(repvars, vars, nvars);
1666 BMSclearMemoryArray(negated, nvars);
1667 SCIP_CALL( SCIPvarsGetProbvarBinary(&repvars, &negated, nvars) );
1668
1669 /* negate the representatives, if they correspond to the negation of the given variables */
1670 for( v = nvars - 1; v >= 0; --v )
1671 if( negated[v] )
1672 {
1673 SCIP_CALL( SCIPgetNegatedVar(scip, repvars[v], &(repvars[v])) );
1674 }
1675
1676 return SCIP_OKAY;
1677}
1678
1679/** flattens aggregation graph of multi-aggregated variable in order to avoid exponential recursion later on
1680 *
1681 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1682 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1683 *
1684 * @pre This method can be called if @p scip is in one of the following stages:
1685 * - \ref SCIP_STAGE_INITPRESOLVE
1686 * - \ref SCIP_STAGE_PRESOLVING
1687 * - \ref SCIP_STAGE_EXITPRESOLVE
1688 * - \ref SCIP_STAGE_PRESOLVED
1689 * - \ref SCIP_STAGE_INITSOLVE
1690 * - \ref SCIP_STAGE_SOLVING
1691 * - \ref SCIP_STAGE_SOLVED
1692 */
1694 SCIP* scip, /**< SCIP data structure */
1695 SCIP_VAR* var /**< problem variable */
1696 )
1697{
1698 assert( scip != NULL );
1699 assert( var != NULL );
1700 SCIP_CALL( SCIPcheckStage(scip, "SCIPflattenVarAggregationGraph", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
1701
1702 SCIP_CALL( SCIPvarFlattenAggregationGraph(var, scip->mem->probmem, scip->set, scip->eventqueue) );
1703
1704 return SCIP_OKAY;
1705}
1706
1707/** Transforms a given linear sum of variables, that is a_1*x_1 + ... + a_n*x_n + c into a corresponding linear sum of
1708 * active variables, that is b_1*y_1 + ... + b_m*y_m + d.
1709 *
1710 * If the number of needed active variables is greater than the available slots in the variable array, nothing happens
1711 * except that the required size is stored in the corresponding variable (requiredsize). Otherwise, the active variable
1712 * representation is stored in the variable array, scalar array and constant.
1713 *
1714 * The reason for this approach is that we cannot reallocate memory, since we do not know how the memory has been
1715 * allocated (e.g., by a C++ 'new' or SCIP functions).
1716 *
1717 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1718 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1719 *
1720 * @pre This method can be called if @p scip is in one of the following stages:
1721 * - \ref SCIP_STAGE_TRANSFORMED
1722 * - \ref SCIP_STAGE_INITPRESOLVE
1723 * - \ref SCIP_STAGE_PRESOLVING
1724 * - \ref SCIP_STAGE_EXITPRESOLVE
1725 * - \ref SCIP_STAGE_PRESOLVED
1726 * - \ref SCIP_STAGE_INITSOLVE
1727 * - \ref SCIP_STAGE_SOLVING
1728 * - \ref SCIP_STAGE_SOLVED
1729 * - \ref SCIP_STAGE_EXITSOLVE
1730 * - \ref SCIP_STAGE_FREETRANS
1731 *
1732 * @note The resulting linear sum is stored into the given variable array, scalar array, and constant. That means the
1733 * given entries are overwritten.
1734 *
1735 * @note That method can be used to convert a single variables into variable space of active variables. Therefore call
1736 * the method with the linear sum 1.0*x + 0.0.
1737 */
1739 SCIP* scip, /**< SCIP data structure */
1740 SCIP_VAR** vars, /**< variable array x_1, ..., x_n in the linear sum which will be
1741 * overwritten by the variable array y_1, ..., y_m in the linear sum
1742 * w.r.t. active variables */
1743 SCIP_Real* scalars, /**< scalars a_1, ..., a_n in linear sum which will be overwritten to the
1744 * scalars b_1, ..., b_m in the linear sum of the active variables */
1745 int* nvars, /**< pointer to number of variables in the linear sum which will be
1746 * overwritten by the number of variables in the linear sum corresponding
1747 * to the active variables */
1748 int varssize, /**< available slots in vars and scalars array which is needed to check if
1749 * the array are large enough for the linear sum w.r.t. active
1750 * variables */
1751 SCIP_Real* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c which
1752 * will chnage to constant d in the linear sum b_1*y_1 + ... + b_m*y_m +
1753 * d w.r.t. the active variables */
1754 int* requiredsize, /**< pointer to store the required array size for the linear sum w.r.t. the
1755 * active variables */
1756 SCIP_Bool mergemultiples /**< should multiple occurrences of a var be replaced by a single coeff? */
1757 )
1758{
1759 assert( scip != NULL );
1760 assert( nvars != NULL );
1761 assert( vars != NULL || *nvars == 0 );
1762 assert( scalars != NULL || *nvars == 0 );
1763 assert( constant != NULL );
1764 assert( requiredsize != NULL );
1765 assert( *nvars <= varssize );
1766
1767 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetProbvarLinearSum", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1768 SCIP_CALL( SCIPvarGetActiveRepresentatives(scip->set, vars, scalars, nvars, varssize, constant, requiredsize, mergemultiples) );
1769
1770 return SCIP_OKAY;
1771}
1772
1773/** transforms given variable, scalar and constant to the corresponding active, fixed, or
1774 * multi-aggregated variable, scalar and constant; if the variable resolves to a fixed variable,
1775 * "scalar" will be 0.0 and the value of the sum will be stored in "constant"; a multi-aggregation
1776 * with only one active variable (this can happen due to fixings after the multi-aggregation),
1777 * is treated like an aggregation; if the multi-aggregation constant is infinite, "scalar" will be 0.0
1778 *
1779 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1780 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1781 *
1782 * @pre This method can be called if @p scip is in one of the following stages:
1783 * - \ref SCIP_STAGE_TRANSFORMED
1784 * - \ref SCIP_STAGE_INITPRESOLVE
1785 * - \ref SCIP_STAGE_PRESOLVING
1786 * - \ref SCIP_STAGE_EXITPRESOLVE
1787 * - \ref SCIP_STAGE_PRESOLVED
1788 * - \ref SCIP_STAGE_INITSOLVE
1789 * - \ref SCIP_STAGE_SOLVING
1790 * - \ref SCIP_STAGE_SOLVED
1791 * - \ref SCIP_STAGE_EXITSOLVE
1792 * - \ref SCIP_STAGE_FREETRANS
1793 */
1795 SCIP* scip, /**< SCIP data structure */
1796 SCIP_VAR** var, /**< pointer to problem variable x in sum a*x + c */
1797 SCIP_Real* scalar, /**< pointer to scalar a in sum a*x + c */
1798 SCIP_Real* constant /**< pointer to constant c in sum a*x + c */
1799 )
1800{
1801 assert(scip != NULL);
1802 assert(var != NULL);
1803 assert(scalar != NULL);
1804 assert(constant != NULL);
1805
1806 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetProbvarSum", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1807 SCIP_CALL( SCIPvarGetProbvarSum(var, scip->set, scalar, constant) );
1808
1809 return SCIP_OKAY;
1810}
1811
1812/** return for given variables all their active counterparts; all active variables will be pairwise different
1813 * @note It does not hold that the first output variable is the active variable for the first input variable.
1814 *
1815 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1816 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1817 *
1818 * @pre This method can be called if @p scip is in one of the following stages:
1819 * - \ref SCIP_STAGE_TRANSFORMED
1820 * - \ref SCIP_STAGE_INITPRESOLVE
1821 * - \ref SCIP_STAGE_PRESOLVING
1822 * - \ref SCIP_STAGE_EXITPRESOLVE
1823 * - \ref SCIP_STAGE_PRESOLVED
1824 * - \ref SCIP_STAGE_INITSOLVE
1825 * - \ref SCIP_STAGE_SOLVING
1826 * - \ref SCIP_STAGE_SOLVED
1827 * - \ref SCIP_STAGE_EXITSOLVE
1828 * - \ref SCIP_STAGE_FREETRANS
1829 */
1831 SCIP* scip, /**< SCIP data structure */
1832 SCIP_VAR** vars, /**< variable array with given variables and as output all active
1833 * variables, if enough slots exist
1834 */
1835 int* nvars, /**< number of given variables, and as output number of active variables,
1836 * if enough slots exist
1837 */
1838 int varssize, /**< available slots in vars array */
1839 int* requiredsize /**< pointer to store the required array size for the active variables */
1840 )
1841{
1842 assert(scip != NULL);
1843 assert(nvars != NULL);
1844 assert(vars != NULL || *nvars == 0);
1845 assert(varssize >= *nvars);
1846 assert(requiredsize != NULL);
1847
1848 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetActiveVars", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1849 SCIP_CALL( SCIPvarsGetActiveVars(scip->set, vars, nvars, varssize, requiredsize) );
1850
1851 return SCIP_OKAY;
1852}
1853
1854/** returns the reduced costs of the variable in the current node's LP relaxation;
1855 * the current node has to have a feasible LP.
1856 *
1857 * returns SCIP_INVALID if the variable is active but not in the current LP;
1858 * returns 0 if the variable has been aggregated out or fixed in presolving.
1859 *
1860 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1861 *
1862 * @note The return value of this method should be used carefully if the dual feasibility check was explictely disabled.
1863 */
1865 SCIP* scip, /**< SCIP data structure */
1866 SCIP_VAR* var /**< variable to get reduced costs, should be a column in current node LP */
1867 )
1868{
1869 assert( scip != NULL );
1870 assert( var != NULL );
1871 assert( var->scip == scip );
1872
1873 switch( SCIPvarGetStatus(var) )
1874 {
1876 if( var->data.original.transvar == NULL )
1877 return SCIP_INVALID;
1879
1881 return SCIPgetColRedcost(scip, SCIPvarGetCol(var));
1882
1884 return SCIP_INVALID;
1885
1890 return 0.0;
1891
1892 default:
1893 SCIPerrorMessage("unknown variable status\n");
1894 SCIPABORT();
1895 return 0.0; /*lint !e527*/
1896 }
1897}
1898
1899/** returns the implied reduced costs of the variable in the current node's LP relaxation;
1900 * the current node has to have a feasible LP.
1901 *
1902 * returns SCIP_INVALID if the variable is active but not in the current LP;
1903 * returns 0 if the variable has been aggregated out or fixed in presolving.
1904 *
1905 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1906 *
1907 * @note The return value of this method should be used carefully if the dual feasibility check was explictely disabled.
1908 */
1910 SCIP* scip, /**< SCIP data structure */
1911 SCIP_VAR* var, /**< variable to get reduced costs, should be a column in current node LP */
1912 SCIP_Bool varfixing /**< FALSE if for x == 0, TRUE for x == 1 */
1913 )
1914{
1915 assert( scip != NULL );
1916 assert( var != NULL );
1917 assert( var->scip == scip );
1918
1919 switch( SCIPvarGetStatus(var) )
1920 {
1922 if( var->data.original.transvar == NULL )
1923 return SCIP_INVALID;
1924 return SCIPgetVarImplRedcost(scip, var->data.original.transvar, varfixing);
1925
1927 return SCIPvarGetImplRedcost(var, scip->set, varfixing, scip->stat, scip->transprob, scip->lp);
1928
1930 return SCIP_INVALID;
1931
1936 return 0.0;
1937
1938 default:
1939 SCIPerrorMessage("unknown variable status\n");
1940 SCIPABORT();
1941 return 0.0; /*lint !e527*/
1942 }
1943}
1944
1945
1946/** returns the Farkas coefficient of the variable in the current node's LP relaxation;
1947 * the current node has to have an infeasible LP.
1948 *
1949 * returns SCIP_INVALID if the variable is active but not in the current LP;
1950 * returns 0 if the variable has been aggregated out or fixed in presolving.
1951 *
1952 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1953 */
1955 SCIP* scip, /**< SCIP data structure */
1956 SCIP_VAR* var /**< variable to get reduced costs, should be a column in current node LP */
1957 )
1958{
1959 assert(scip != NULL);
1960 assert(var != NULL);
1961 assert(var->scip == scip);
1962
1963 switch( SCIPvarGetStatus(var) )
1964 {
1966 if( var->data.original.transvar == NULL )
1967 return SCIP_INVALID;
1969
1972
1974 return SCIP_INVALID;
1975
1980 return 0.0;
1981
1982 default:
1983 SCIPerrorMessage("unknown variable status\n");
1984 SCIPABORT();
1985 return 0.0; /*lint !e527*/
1986 }
1987}
1988
1989/** returns lower bound of variable directly before or after the bound change given by the bound change index
1990 * was applied
1991 */
1993 SCIP* scip, /**< SCIP data structure */
1994 SCIP_VAR* var, /**< problem variable */
1995 SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
1996 SCIP_Bool after /**< should the bound change with given index be included? */
1997 )
1998{
1999 SCIP_VARSTATUS varstatus;
2000 SCIP_BDCHGINFO* bdchginfo;
2001 assert(var != NULL);
2002
2003 varstatus = SCIPvarGetStatus(var);
2004
2005 /* get bounds of attached variables */
2006 switch( varstatus )
2007 {
2009 assert(var->data.original.transvar != NULL);
2010 return SCIPgetVarLbAtIndex(scip, var->data.original.transvar, bdchgidx, after);
2011
2014 if( bdchgidx == NULL )
2015 return SCIPvarGetLbLocal(var);
2016 else
2017 {
2018 bdchginfo = SCIPvarGetLbchgInfo(var, bdchgidx, after);
2019 if( bdchginfo != NULL )
2020 return SCIPbdchginfoGetNewbound(bdchginfo);
2021 else
2022 return var->glbdom.lb;
2023 }
2024
2026 return var->glbdom.lb;
2027
2028 case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c -> y = (x-c)/a */
2029 assert(var->data.aggregate.var != NULL);
2030 if( var->data.aggregate.scalar > 0.0 )
2031 {
2032 SCIP_Real lb;
2033
2034 lb = SCIPgetVarLbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2035
2036 /* a > 0 -> get lower bound of y */
2037 if( SCIPisInfinity(scip, -lb) )
2038 return -SCIPinfinity(scip);
2039 else if( SCIPisInfinity(scip, lb) )
2040 return SCIPinfinity(scip);
2041 else
2042 return var->data.aggregate.scalar * lb + var->data.aggregate.constant;
2043 }
2044 else if( var->data.aggregate.scalar < 0.0 )
2045 {
2046 SCIP_Real ub;
2047
2048 ub = SCIPgetVarUbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2049
2050 /* a < 0 -> get upper bound of y */
2051 if( SCIPisInfinity(scip, -ub) )
2052 return SCIPinfinity(scip);
2053 else if( SCIPisInfinity(scip, ub) )
2054 return -SCIPinfinity(scip);
2055 else
2056 return var->data.aggregate.scalar * ub + var->data.aggregate.constant;
2057 }
2058 else
2059 {
2060 SCIPerrorMessage("scalar is zero in aggregation\n");
2061 SCIPABORT();
2062 return SCIP_INVALID; /*lint !e527*/
2063 }
2064
2066 /* handle multi-aggregated variables depending on one variable only (possibly caused by SCIPvarFlattenAggregationGraph()) */
2067 if ( var->data.multaggr.nvars == 1 )
2068 {
2069 assert(var->data.multaggr.vars != NULL);
2070 assert(var->data.multaggr.scalars != NULL);
2071 assert(var->data.multaggr.vars[0] != NULL);
2072
2073 if( var->data.multaggr.scalars[0] > 0.0 )
2074 {
2075 SCIP_Real lb;
2076
2077 lb = SCIPgetVarLbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2078
2079 /* a > 0 -> get lower bound of y */
2080 if( SCIPisInfinity(scip, -lb) )
2081 return -SCIPinfinity(scip);
2082 else if( SCIPisInfinity(scip, lb) )
2083 return SCIPinfinity(scip);
2084 else
2085 return var->data.multaggr.scalars[0] * lb + var->data.multaggr.constant;
2086 }
2087 else if( var->data.multaggr.scalars[0] < 0.0 )
2088 {
2089 SCIP_Real ub;
2090
2091 ub = SCIPgetVarUbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2092
2093 /* a < 0 -> get upper bound of y */
2094 if( SCIPisInfinity(scip, -ub) )
2095 return SCIPinfinity(scip);
2096 else if( SCIPisInfinity(scip, ub) )
2097 return -SCIPinfinity(scip);
2098 else
2099 return var->data.multaggr.scalars[0] * ub + var->data.multaggr.constant;
2100 }
2101 else
2102 {
2103 SCIPerrorMessage("scalar is zero in multi-aggregation\n");
2104 SCIPABORT();
2105 return SCIP_INVALID; /*lint !e527*/
2106 }
2107 }
2108 SCIPerrorMessage("cannot get the bounds of a multi-aggregated variable.\n");
2109 SCIPABORT();
2110 return SCIP_INVALID; /*lint !e527*/
2111
2112 case SCIP_VARSTATUS_NEGATED: /* x' = offset - x -> x = offset - x' */
2113 assert(var->negatedvar != NULL);
2115 assert(var->negatedvar->negatedvar == var);
2116 return var->data.negate.constant - SCIPgetVarUbAtIndex(scip, var->negatedvar, bdchgidx, after);
2117
2118 default:
2119 SCIPerrorMessage("unknown variable status\n");
2120 SCIPABORT();
2121 return SCIP_INVALID; /*lint !e527*/
2122 }
2123}
2124
2125/** returns upper bound of variable directly before or after the bound change given by the bound change index
2126 * was applied
2127 */
2129 SCIP* scip, /**< SCIP data structure */
2130 SCIP_VAR* var, /**< problem variable */
2131 SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2132 SCIP_Bool after /**< should the bound change with given index be included? */
2133 )
2134{
2135 SCIP_VARSTATUS varstatus;
2136 SCIP_BDCHGINFO* bdchginfo;
2137 assert(var != NULL);
2138
2139 varstatus = SCIPvarGetStatus(var);
2140
2141 /* get bounds of attached variables */
2142 switch( varstatus )
2143 {
2145 assert(var->data.original.transvar != NULL);
2146 return SCIPgetVarUbAtIndex(scip, var->data.original.transvar, bdchgidx, after);
2147
2150 if( bdchgidx == NULL )
2151 return SCIPvarGetUbLocal(var);
2152 else
2153 {
2154 bdchginfo = SCIPvarGetUbchgInfo(var, bdchgidx, after);
2155 if( bdchginfo != NULL )
2156 return SCIPbdchginfoGetNewbound(bdchginfo);
2157 else
2158 return var->glbdom.ub;
2159 }
2160
2162 return var->glbdom.ub;
2163
2164 case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c -> y = (x-c)/a */
2165 assert(var->data.aggregate.var != NULL);
2166 if( var->data.aggregate.scalar > 0.0 )
2167 {
2168 SCIP_Real ub;
2169
2170 ub = SCIPgetVarUbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2171
2172 /* a > 0 -> get lower bound of y */
2173 if( SCIPisInfinity(scip, -ub) )
2174 return -SCIPinfinity(scip);
2175 else if( SCIPisInfinity(scip, ub) )
2176 return SCIPinfinity(scip);
2177 else
2178 return var->data.aggregate.scalar * ub + var->data.aggregate.constant;
2179 }
2180 else if( var->data.aggregate.scalar < 0.0 )
2181 {
2182 SCIP_Real lb;
2183
2184 lb = SCIPgetVarLbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2185
2186 /* a < 0 -> get upper bound of y */
2187 if ( SCIPisInfinity(scip, -lb) )
2188 return SCIPinfinity(scip);
2189 else if ( SCIPisInfinity(scip, lb) )
2190 return -SCIPinfinity(scip);
2191 else
2192 return var->data.aggregate.scalar * lb + var->data.aggregate.constant;
2193 }
2194 else
2195 {
2196 SCIPerrorMessage("scalar is zero in aggregation\n");
2197 SCIPABORT();
2198 return SCIP_INVALID; /*lint !e527*/
2199 }
2200
2202 /* handle multi-aggregated variables depending on one variable only (possibly caused by SCIPvarFlattenAggregationGraph()) */
2203 if ( var->data.multaggr.nvars == 1 )
2204 {
2205 assert(var->data.multaggr.vars != NULL);
2206 assert(var->data.multaggr.scalars != NULL);
2207 assert(var->data.multaggr.vars[0] != NULL);
2208
2209 if( var->data.multaggr.scalars[0] > 0.0 )
2210 {
2211 SCIP_Real ub;
2212
2213 ub = SCIPgetVarUbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2214
2215 /* a > 0 -> get lower bound of y */
2216 if ( SCIPisInfinity(scip, -ub) )
2217 return -SCIPinfinity(scip);
2218 else if ( SCIPisInfinity(scip, ub) )
2219 return SCIPinfinity(scip);
2220 else
2221 return var->data.multaggr.scalars[0] * ub + var->data.multaggr.constant;
2222 }
2223 else if( var->data.multaggr.scalars[0] < 0.0 )
2224 {
2225 SCIP_Real lb;
2226
2227 lb = SCIPgetVarLbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2228
2229 /* a < 0 -> get upper bound of y */
2230 if ( SCIPisInfinity(scip, -lb) )
2231 return SCIPinfinity(scip);
2232 else if ( SCIPisInfinity(scip, lb) )
2233 return -SCIPinfinity(scip);
2234 else
2235 return var->data.multaggr.scalars[0] * lb + var->data.multaggr.constant;
2236 }
2237 else
2238 {
2239 SCIPerrorMessage("scalar is zero in multi-aggregation\n");
2240 SCIPABORT();
2241 return SCIP_INVALID; /*lint !e527*/
2242 }
2243 }
2244 SCIPerrorMessage("cannot get the bounds of a multiple aggregated variable.\n");
2245 SCIPABORT();
2246 return SCIP_INVALID; /*lint !e527*/
2247
2248 case SCIP_VARSTATUS_NEGATED: /* x' = offset - x -> x = offset - x' */
2249 assert(var->negatedvar != NULL);
2251 assert(var->negatedvar->negatedvar == var);
2252 return var->data.negate.constant - SCIPgetVarLbAtIndex(scip, var->negatedvar, bdchgidx, after);
2253
2254 default:
2255 SCIPerrorMessage("unknown variable status\n");
2256 SCIPABORT();
2257 return SCIP_INVALID; /*lint !e527*/
2258 }
2259}
2260
2261/** returns lower or upper bound of variable directly before or after the bound change given by the bound change index
2262 * was applied
2263 */
2265 SCIP* scip, /**< SCIP data structure */
2266 SCIP_VAR* var, /**< problem variable */
2267 SCIP_BOUNDTYPE boundtype, /**< type of bound: lower or upper bound */
2268 SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2269 SCIP_Bool after /**< should the bound change with given index be included? */
2270 )
2271{
2272 if( boundtype == SCIP_BOUNDTYPE_LOWER )
2273 return SCIPgetVarLbAtIndex(scip, var, bdchgidx, after);
2274 else
2275 {
2276 assert(boundtype == SCIP_BOUNDTYPE_UPPER);
2277 return SCIPgetVarUbAtIndex(scip, var, bdchgidx, after);
2278 }
2279}
2280
2281/** returns whether the binary variable was fixed at the time given by the bound change index */
2283 SCIP* scip, /**< SCIP data structure */
2284 SCIP_VAR* var, /**< problem variable */
2285 SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2286 SCIP_Bool after /**< should the bound change with given index be included? */
2287 )
2288{
2289 assert(var != NULL);
2290 assert(SCIPvarIsBinary(var));
2291
2292 /* check the current bounds first in order to decide at which bound change information we have to look
2293 * (which is expensive because we have to follow the aggregation tree to the active variable)
2294 */
2295 return ((SCIPvarGetLbLocal(var) > 0.5 && SCIPgetVarLbAtIndex(scip, var, bdchgidx, after) > 0.5)
2296 || (SCIPvarGetUbLocal(var) < 0.5 && SCIPgetVarUbAtIndex(scip, var, bdchgidx, after) < 0.5));
2297}
2298
2299/** gets solution value for variable in current node
2300 *
2301 * @return solution value for variable in current node
2302 *
2303 * @pre This method can be called if @p scip is in one of the following stages:
2304 * - \ref SCIP_STAGE_PRESOLVED
2305 * - \ref SCIP_STAGE_SOLVING
2306 */
2308 SCIP* scip, /**< SCIP data structure */
2309 SCIP_VAR* var /**< variable to get solution value for */
2310 )
2311{
2313 assert( var->scip == scip );
2314
2315 return SCIPvarGetSol(var, SCIPtreeHasCurrentNodeLP(scip->tree));
2316}
2317
2318/** gets solution values of multiple variables in current node
2319 *
2320 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2321 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2322 *
2323 * @pre This method can be called if @p scip is in one of the following stages:
2324 * - \ref SCIP_STAGE_PRESOLVED
2325 * - \ref SCIP_STAGE_SOLVING
2326 */
2328 SCIP* scip, /**< SCIP data structure */
2329 int nvars, /**< number of variables to get solution value for */
2330 SCIP_VAR** vars, /**< array with variables to get value for */
2331 SCIP_Real* vals /**< array to store solution values of variables */
2332 )
2333{
2334 int v;
2335
2336 assert(nvars == 0 || vars != NULL);
2337 assert(nvars == 0 || vals != NULL);
2338
2340
2341 if( SCIPtreeHasCurrentNodeLP(scip->tree) )
2342 {
2343 for( v = 0; v < nvars; ++v )
2344 vals[v] = SCIPvarGetLPSol(vars[v]);
2345 }
2346 else
2347 {
2348 for( v = 0; v < nvars; ++v )
2349 vals[v] = SCIPvarGetPseudoSol(vars[v]);
2350 }
2351
2352 return SCIP_OKAY;
2353}
2354
2355/** sets the solution value of all variables in the global relaxation solution to zero
2356 *
2357 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2358 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2359 *
2360 * @pre This method can be called if @p scip is in one of the following stages:
2361 * - \ref SCIP_STAGE_PRESOLVED
2362 * - \ref SCIP_STAGE_SOLVING
2363 */
2365 SCIP* scip, /**< SCIP data structure */
2366 SCIP_RELAX* relax /**< relaxator data structure */
2367 )
2368{
2369 SCIP_VAR** vars;
2370 int nvars;
2371 int v;
2372
2373 assert(scip != NULL);
2374
2375 SCIP_CALL( SCIPcheckStage(scip, "SCIPclearRelaxSolVals", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2376
2377 /* update the responsible relax pointer */
2378 SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2379
2380 /* the relaxation solution is already cleared */
2381 if( SCIPrelaxationIsSolZero(scip->relaxation) )
2382 return SCIP_OKAY;
2383
2384 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
2385
2386 for( v = 0; v < nvars; v++ )
2387 {
2388 SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, 0.0, FALSE) );
2389 }
2390
2391 SCIPrelaxationSetSolObj(scip->relaxation, 0.0);
2392 SCIPrelaxationSetSolZero(scip->relaxation, TRUE);
2393
2394 return SCIP_OKAY;
2395}
2396
2397/** sets the value of the given variable in the global relaxation solution;
2398 * this solution can be filled by the relaxation handlers and can be used by heuristics and for separation;
2399 * You can use SCIPclearRelaxSolVals() to set all values to zero, initially;
2400 * after setting all solution values, you have to call SCIPmarkRelaxSolValid()
2401 * to inform SCIP that the stored solution is valid
2402 *
2403 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2404 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2405 *
2406 * @pre This method can be called if @p scip is in one of the following stages:
2407 * - \ref SCIP_STAGE_PRESOLVED
2408 * - \ref SCIP_STAGE_SOLVING
2409 *
2410 * @note This method incrementally updates the objective value of the relaxation solution. If the whole solution
2411 * should be updated, using SCIPsetRelaxSolVals() instead or calling SCIPclearRelaxSolVals() before setting
2412 * the first value to reset the solution and the objective value to 0 may help the numerics.
2413 */
2415 SCIP* scip, /**< SCIP data structure */
2416 SCIP_RELAX* relax, /**< relaxator data structure */
2417 SCIP_VAR* var, /**< variable to set value for */
2418 SCIP_Real val /**< solution value of variable */
2419 )
2420{
2421 assert(scip != NULL);
2422
2424
2425 SCIP_CALL( SCIPvarSetRelaxSol(var, scip->set, scip->relaxation, val, TRUE) );
2426
2427 if( val != 0.0 )
2428 SCIPrelaxationSetSolZero(scip->relaxation, FALSE);
2430 SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2431
2432 return SCIP_OKAY;
2433}
2434
2435/** sets the values of the given variables in the global relaxation solution and informs SCIP about the validity
2436 * and whether the solution can be enforced via linear cuts;
2437 * this solution can be filled by the relaxation handlers and can be used by heuristics and for separation;
2438 * the solution is automatically cleared, s.t. all other variables get value 0.0
2439 *
2440 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2441 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2442 *
2443 * @pre This method can be called if @p scip is in one of the following stages:
2444 * - \ref SCIP_STAGE_PRESOLVED
2445 * - \ref SCIP_STAGE_SOLVING
2446 */
2448 SCIP* scip, /**< SCIP data structure */
2449 SCIP_RELAX* relax, /**< relaxator data structure */
2450 int nvars, /**< number of variables to set relaxation solution value for */
2451 SCIP_VAR** vars, /**< array with variables to set value for */
2452 SCIP_Real* vals, /**< array with solution values of variables */
2453 SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2454 )
2455{
2456 int v;
2457
2458 assert(scip != NULL);
2459 assert(nvars == 0 || vars != NULL);
2460 assert(nvars == 0 || vals != NULL);
2461
2462 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolVals", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2463
2465
2466 for( v = 0; v < nvars; v++ )
2467 {
2468 SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, vals[v], TRUE) );
2469 }
2470
2471 SCIPrelaxationSetSolZero(scip->relaxation, FALSE);
2472 SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2473 SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2474
2475 return SCIP_OKAY;
2476}
2477
2478/** sets the values of the variables in the global relaxation solution to the values in the given primal solution
2479 * and informs SCIP about the validity and whether the solution can be enforced via linear cuts;
2480 * the relaxation solution can be filled by the relaxation handlers and might be used by heuristics and for separation
2481 *
2482 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2483 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2484 *
2485 * @pre This method can be called if @p scip is in one of the following stages:
2486 * - \ref SCIP_STAGE_PRESOLVED
2487 * - \ref SCIP_STAGE_SOLVING
2488 */
2490 SCIP* scip, /**< SCIP data structure */
2491 SCIP_RELAX* relax, /**< relaxator data structure */
2492 SCIP_SOL* sol, /**< primal relaxation solution */
2493 SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2494 )
2495{
2496 SCIP_VAR** vars;
2497 SCIP_Real* vals;
2498 int nvars;
2499 int v;
2500
2501 assert(scip != NULL);
2502
2503 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolValsSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2504
2505 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
2506
2507 /* alloc buffer array for solution values of the variables and get the values */
2508 SCIP_CALL( SCIPallocBufferArray(scip, &vals, nvars) );
2509 SCIP_CALL( SCIPgetSolVals(scip, sol, nvars, vars, vals) );
2510
2512
2513 for( v = 0; v < nvars; v++ )
2514 {
2515 SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, vals[v], FALSE) );
2516 }
2517
2518 SCIPrelaxationSetSolObj(scip->relaxation, SCIPsolGetObj(sol, scip->set, scip->transprob, scip->origprob));
2519
2520 SCIPrelaxationSetSolZero(scip->relaxation, FALSE);
2521 SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2522 SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2523
2524 SCIPfreeBufferArray(scip, &vals);
2525
2526 return SCIP_OKAY;
2527}
2528
2529/** returns whether the relaxation solution is valid
2530 *
2531 * @return TRUE, if the relaxation solution is valid; FALSE, otherwise
2532 *
2533 * @pre This method can be called if @p scip is in one of the following stages:
2534 * - \ref SCIP_STAGE_PRESOLVED
2535 * - \ref SCIP_STAGE_SOLVING
2536 */
2538 SCIP* scip /**< SCIP data structure */
2539 )
2540{
2541 assert(scip != NULL);
2542
2544
2545 return SCIPrelaxationIsSolValid(scip->relaxation);
2546}
2547
2548/** informs SCIP that the relaxation solution is valid and whether the relaxation can be enforced through linear cuts
2549 *
2550 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2551 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2552 *
2553 * @pre This method can be called if @p scip is in one of the following stages:
2554 * - \ref SCIP_STAGE_PRESOLVED
2555 * - \ref SCIP_STAGE_SOLVING
2556 */
2558 SCIP* scip, /**< SCIP data structure */
2559 SCIP_RELAX* relax, /**< relaxator data structure that set the current relaxation solution */
2560 SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2561 )
2562{
2563 assert(scip != NULL);
2564
2565 SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkRelaxSolValid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2566
2567 SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2568 SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2569
2570 return SCIP_OKAY;
2571}
2572
2573/** informs SCIP, that the relaxation solution is invalid
2574 *
2575 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2576 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2577 *
2578 * @pre This method can be called if @p scip is in one of the following stages:
2579 * - \ref SCIP_STAGE_PRESOLVED
2580 * - \ref SCIP_STAGE_SOLVING
2581 */
2583 SCIP* scip /**< SCIP data structure */
2584 )
2585{
2586 assert(scip != NULL);
2587
2588 SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkRelaxSolInvalid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2589
2591
2592 return SCIP_OKAY;
2593}
2594
2595/** gets the relaxation solution value of the given variable
2596 *
2597 * @return the relaxation solution value of the given variable
2598 *
2599 * @pre This method can be called if @p scip is in one of the following stages:
2600 * - \ref SCIP_STAGE_PRESOLVED
2601 * - \ref SCIP_STAGE_SOLVING
2602 */
2604 SCIP* scip, /**< SCIP data structure */
2605 SCIP_VAR* var /**< variable to get value for */
2606 )
2607{
2608 assert(scip != NULL);
2609 assert(var != NULL);
2610 assert(var->scip == scip);
2611
2613
2614 if( !SCIPrelaxationIsSolValid(scip->relaxation) )
2615 {
2616 SCIPerrorMessage("Relaxation Solution is not valid!\n");
2617 SCIPABORT();
2618 return SCIP_INVALID; /*lint !e527*/
2619 }
2620
2621 return SCIPvarGetRelaxSol(var, scip->set);
2622}
2623
2624/** gets the relaxation solution objective value
2625 *
2626 * @return the objective value of the relaxation solution
2627 *
2628 * @pre This method can be called if @p scip is in one of the following stages:
2629 * - \ref SCIP_STAGE_PRESOLVED
2630 * - \ref SCIP_STAGE_SOLVING
2631 */
2633 SCIP* scip /**< SCIP data structure */
2634 )
2635{
2636 assert(scip != NULL);
2637
2639
2640 if( !SCIPrelaxationIsSolValid(scip->relaxation) )
2641 {
2642 SCIPerrorMessage("Relaxation Solution is not valid!\n");
2643 SCIPABORT();
2644 return SCIP_INVALID; /*lint !e527*/
2645 }
2646
2647 return SCIPrelaxationGetSolObj(scip->relaxation);
2648}
2649
2650/** determine which branching direction should be evaluated first by strong branching
2651 *
2652 * @return TRUE iff strong branching should first evaluate the down child
2653 *
2654 */
2656 SCIP* scip, /**< SCIP data structure */
2657 SCIP_VAR* var /**< variable to determine the branching direction on */
2658 )
2659{
2660 switch( scip->set->branch_firstsbchild )
2661 {
2662 case 'u':
2663 return FALSE;
2664 case 'd':
2665 return TRUE;
2666 case 'a':
2667 return (SCIPvarGetNLocksDown(var) > SCIPvarGetNLocksUp(var));
2668 default:
2669 assert(scip->set->branch_firstsbchild == 'h');
2671 }
2672}
2673
2674/** start strong branching - call before any strong branching
2675 *
2676 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2677 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2678 *
2679 * @pre This method can be called if @p scip is in one of the following stages:
2680 * - \ref SCIP_STAGE_PRESOLVED
2681 * - \ref SCIP_STAGE_SOLVING
2682 *
2683 * @note if propagation is enabled, strong branching is not done directly on the LP, but probing nodes are created
2684 * which allow to perform propagation but also creates some overhead
2685 */
2687 SCIP* scip, /**< SCIP data structure */
2688 SCIP_Bool enablepropagation /**< should propagation be done before solving the strong branching LP? */
2689 )
2690{
2691 assert( scip != NULL );
2692 SCIP_CALL( SCIPcheckStage(scip, "SCIPstartStrongbranch", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2693
2694 assert(!SCIPinProbing(scip));
2695
2696 SCIPdebugMsg(scip, "starting strong branching mode%s: lpcount=%" SCIP_LONGINT_FORMAT "\n", enablepropagation ? " with propagation" : "", scip->stat->lpcount - scip->stat->nsbdivinglps);
2697
2698 /* start probing mode to allow propagation before solving the strong branching LPs; if no propagation should be done,
2699 * start the strong branching mode in the LP interface
2700 */
2701 if( enablepropagation )
2702 {
2703 if( SCIPtreeProbing(scip->tree) )
2704 {
2705 SCIPerrorMessage("cannot start strong branching with propagation while in probing mode\n");
2706 return SCIP_INVALIDCALL;
2707 }
2708
2709 if( scip->lp != NULL && SCIPlpDiving(scip->lp) )
2710 {
2711 SCIPerrorMessage("cannot start strong branching with propagation while in diving mode\n");
2712 return SCIP_INVALIDCALL;
2713 }
2714
2715 /* other then in SCIPstartProbing(), we do not disable collecting variable statistics during strong branching;
2716 * we cannot disable it, because the pseudo costs would not be updated, otherwise,
2717 * and reliability branching would end up doing strong branching all the time
2718 */
2719 SCIP_CALL( SCIPtreeStartProbing(scip->tree, scip->mem->probmem, scip->set, scip->lp, scip->relaxation, scip->transprob, TRUE) );
2720
2721 /* inform the LP that the current probing mode is used for strong branching */
2723 }
2724 else
2725 {
2727 }
2728
2729 /* reset local strong branching info */
2730 scip->stat->lastsblpsolstats[0] = scip->stat->lastsblpsolstats[1] = SCIP_LPSOLSTAT_NOTSOLVED;
2731
2732 return SCIP_OKAY;
2733}
2734
2735/** end strong branching - call after any strong branching
2736 *
2737 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2738 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2739 *
2740 * @pre This method can be called if @p scip is in one of the following stages:
2741 * - \ref SCIP_STAGE_PRESOLVED
2742 * - \ref SCIP_STAGE_SOLVING
2743 */
2745 SCIP* scip /**< SCIP data structure */
2746 )
2747{
2748 assert( scip != NULL );
2749
2750 SCIP_CALL( SCIPcheckStage(scip, "SCIPendStrongbranch", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2751
2752 /* depending on whether the strong branching mode was started with propagation enabled or not, we end the strong
2753 * branching probing mode or the LP strong branching mode
2754 */
2755 if( SCIPtreeProbing(scip->tree) )
2756 {
2757 SCIP_NODE* node;
2758 SCIP_DOMCHG* domchg;
2759 SCIP_VAR** boundchgvars;
2760 SCIP_Real* bounds;
2761 SCIP_BOUNDTYPE* boundtypes;
2762 int nboundchgs;
2763 int nbnds;
2764 int i;
2765
2766 /* collect all bound changes deducted during probing, which were applied at the probing root and apply them to the
2767 * focusnode
2768 */
2769 node = SCIPgetCurrentNode(scip);
2771 assert(SCIPgetProbingDepth(scip) == 0);
2772
2773 domchg = SCIPnodeGetDomchg(node);
2774 nboundchgs = SCIPdomchgGetNBoundchgs(domchg);
2775
2776 SCIP_CALL( SCIPallocBufferArray(scip, &boundchgvars, nboundchgs) );
2777 SCIP_CALL( SCIPallocBufferArray(scip, &bounds, nboundchgs) );
2778 SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, nboundchgs) );
2779
2780 for( i = 0, nbnds = 0; i < nboundchgs; ++i )
2781 {
2782 SCIP_BOUNDCHG* boundchg;
2783
2784 boundchg = SCIPdomchgGetBoundchg(domchg, i);
2785
2786 /* ignore redundant bound changes */
2787 if( SCIPboundchgIsRedundant(boundchg) )
2788 continue;
2789
2790 boundchgvars[nbnds] = SCIPboundchgGetVar(boundchg);
2791 bounds[nbnds] = SCIPboundchgGetNewbound(boundchg);
2792 boundtypes[nbnds] = SCIPboundchgGetBoundtype(boundchg);
2793 ++nbnds;
2794 }
2795
2796 SCIPdebugMsg(scip, "ending strong branching with probing: %d bound changes collected\n", nbnds);
2797
2798 /* inform the LP that the probing mode is not used for strong branching anymore */
2800
2801 /* switch back from probing to normal operation mode and restore variables and constraints to focus node */
2802 SCIP_CALL( SCIPtreeEndProbing(scip->tree, scip->reopt, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
2803 scip->transprob, scip->origprob, scip->lp, scip->relaxation, scip->primal,
2804 scip->branchcand, scip->eventqueue, scip->eventfilter, scip->cliquetable) );
2805
2806 /* apply the collected bound changes */
2807 for( i = 0; i < nbnds; ++i )
2808 {
2809 if( boundtypes[i] == SCIP_BOUNDTYPE_LOWER )
2810 {
2811 SCIPdebugMsg(scip, "apply probing lower bound change <%s> >= %.9g\n", SCIPvarGetName(boundchgvars[i]), bounds[i]);
2812 SCIP_CALL( SCIPchgVarLb(scip, boundchgvars[i], bounds[i]) );
2813 }
2814 else
2815 {
2816 SCIPdebugMsg(scip, "apply probing upper bound change <%s> <= %.9g\n", SCIPvarGetName(boundchgvars[i]), bounds[i]);
2817 SCIP_CALL( SCIPchgVarUb(scip, boundchgvars[i], bounds[i]) );
2818 }
2819 }
2820
2821 SCIPfreeBufferArray(scip, &boundtypes);
2822 SCIPfreeBufferArray(scip, &bounds);
2823 SCIPfreeBufferArray(scip, &boundchgvars);
2824 }
2825 else
2826 {
2827 SCIPdebugMsg(scip, "ending strong branching\n");
2828
2830 }
2831
2832 return SCIP_OKAY;
2833}
2834
2835/** analyze the strong branching for the given variable; that includes conflict analysis for infeasible branches and
2836 * storing of root reduced cost information
2837 */
2838static
2840 SCIP* scip, /**< SCIP data structure */
2841 SCIP_VAR* var, /**< variable to analyze */
2842 SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
2843 SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
2844 SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
2845 * infeasible downwards branch, or NULL */
2846 SCIP_Bool* upconflict /**< pointer to store whether a conflict constraint was created for an
2847 * infeasible upwards branch, or NULL */
2848 )
2849{
2850 SCIP_COL* col;
2851 SCIP_Bool downcutoff;
2852 SCIP_Bool upcutoff;
2853
2854 col = SCIPvarGetCol(var);
2855 assert(col != NULL);
2856
2857 downcutoff = col->sbdownvalid && SCIPsetIsGE(scip->set, col->sbdown, scip->lp->cutoffbound);
2858 upcutoff = col->sbupvalid && SCIPsetIsGE(scip->set, col->sbup, scip->lp->cutoffbound);
2859
2860 if( downinf != NULL )
2861 *downinf = downcutoff;
2862 if( upinf != NULL )
2863 *upinf = upcutoff;
2864
2865 /* analyze infeasible strong branching sub problems:
2866 * because the strong branching's bound change is necessary for infeasibility, it cannot be undone;
2867 * therefore, infeasible strong branchings on non-binary variables will not produce a valid conflict constraint
2868 */
2869 if( scip->set->conf_enable && scip->set->conf_usesb && scip->set->nconflicthdlrs > 0
2870 && SCIPvarIsBinary(var) && SCIPtreeGetCurrentDepth(scip->tree) > 0 )
2871 {
2872 if( (downcutoff && SCIPsetFeasCeil(scip->set, col->primsol-1.0) >= col->lb - 0.5)
2873 || (upcutoff && SCIPsetFeasFloor(scip->set, col->primsol+1.0) <= col->ub + 0.5) )
2874 {
2875 assert(downconflict != NULL);
2876 assert(upconflict != NULL);
2877 SCIP_CALL( SCIPconflictAnalyzeStrongbranch(scip->conflict, scip->conflictstore, scip->mem->probmem, scip->set, scip->stat,
2878 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, col, downconflict, upconflict) );
2879 }
2880 }
2881
2882 /* the strong branching results can be used to strengthen the root reduced cost information which is used for example
2883 * to propagate against the cutoff bound
2884 *
2885 * @note Ignore the results if the LP solution of the down (up) branch LP is smaller which should not happened by
2886 * theory but can arise due to numerical issues.
2887 */
2888 if( SCIPtreeGetCurrentDepth(scip->tree) == 0 && SCIPvarIsBinary(var) && SCIPlpIsDualReliable(scip->lp) )
2889 {
2890 SCIP_Real lpobjval;
2891
2893
2894 lpobjval = SCIPlpGetObjval(scip->lp, scip->set, scip->transprob);
2895
2896 if( col->sbdownvalid && SCIPsetFeasCeil(scip->set, col->primsol-1.0) >= col->lb - 0.5 && lpobjval < col->sbdown )
2897 SCIPvarUpdateBestRootSol(var, scip->set, SCIPvarGetUbGlobal(var), -(col->sbdown - lpobjval), lpobjval);
2898 if( col->sbupvalid && SCIPsetFeasFloor(scip->set, col->primsol+1.0) <= col->ub + 0.5 && lpobjval < col->sbup )
2899 SCIPvarUpdateBestRootSol(var, scip->set, SCIPvarGetLbGlobal(var), col->sbup - lpobjval, lpobjval);
2900 }
2901
2902 return SCIP_OKAY;
2903}
2904
2905/** gets strong branching information on column variable with fractional value
2906 *
2907 * Before calling this method, the strong branching mode must have been activated by calling SCIPstartStrongbranch();
2908 * after strong branching was done for all candidate variables, the strong branching mode must be ended by
2909 * SCIPendStrongbranch(). Since this method does not apply domain propagation before strongbranching,
2910 * propagation should not be enabled in the SCIPstartStrongbranch() call.
2911 *
2912 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2913 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2914 *
2915 * @pre This method can be called if @p scip is in one of the following stages:
2916 * - \ref SCIP_STAGE_PRESOLVED
2917 * - \ref SCIP_STAGE_SOLVING
2918 */
2920 SCIP* scip, /**< SCIP data structure */
2921 SCIP_VAR* var, /**< variable to get strong branching values for */
2922 int itlim, /**< iteration limit for strong branchings */
2923 SCIP_Bool idempotent, /**< should scip's state remain the same after the call (statistics, column states...), or should it be updated ? */
2924 SCIP_Real* down, /**< stores dual bound after branching column down */
2925 SCIP_Real* up, /**< stores dual bound after branching column up */
2926 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
2927 * otherwise, it can only be used as an estimate value */
2928 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
2929 * otherwise, it can only be used as an estimate value */
2930 SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
2931 SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
2932 SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
2933 * infeasible downwards branch, or NULL */
2934 SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
2935 * infeasible upwards branch, or NULL */
2936 SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
2937 * solving process should be stopped (e.g., due to a time limit) */
2938 )
2939{
2940 SCIP_COL* col;
2941 SCIP_Real 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( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4824 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4825 SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4826 scip->branchcand, scip->eventqueue, newbound) );
4827 SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, 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( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4914 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4915 SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4916 scip->branchcand, scip->eventqueue, newbound) );
4917 SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, 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 /* ignore tightenings of lower bounds to +infinity during solving process */
5650 {
5651#ifndef NDEBUG
5652 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
5653 SCIPvarGetLbLocal(var));
5654#endif
5655 return SCIP_OKAY;
5656 }
5657
5658 /* get current bounds */
5659 lb = SCIPvarGetLbLocal(var);
5660 ub = SCIPvarGetUbLocal(var);
5661 assert(SCIPsetIsLE(scip->set, lb, ub));
5662
5663 if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
5664 {
5665 *infeasible = TRUE;
5666 return SCIP_OKAY;
5667 }
5668 newbound = MIN(newbound, ub);
5669
5670 if( (force && SCIPsetIsLE(scip->set, newbound, lb)) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
5671 return SCIP_OKAY;
5672
5673 switch( scip->set->stage )
5674 {
5675 case SCIP_STAGE_PROBLEM:
5676 assert(!SCIPvarIsTransformed(var));
5677 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5678 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5679 SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5680 scip->branchcand, scip->eventqueue, newbound) );
5681 SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
5682 break;
5683
5685 if( !SCIPinProbing(scip) )
5686 {
5687 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5688 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5689
5690 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5691 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5693
5695 {
5696 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5697 assert(!(*infeasible));
5698 }
5699 break;
5700 }
5701 /*lint -fallthrough*/
5702 case SCIP_STAGE_SOLVING:
5703 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
5704 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5705 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, infercons, NULL, inferinfo, FALSE) );
5706 break;
5707
5708 default:
5709 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5710 return SCIP_INVALIDCALL;
5711 } /*lint !e788*/
5712
5713 /* check whether the lower bound improved */
5714 if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
5715 *tightened = TRUE;
5716
5717 return SCIP_OKAY;
5718}
5719
5720/** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
5721 * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5722 * the given inference constraint is stored, such that the conflict analysis is able to find out the reason
5723 * for the deduction of the bound change
5724 *
5725 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5726 * SCIPgetVars()) gets resorted.
5727 *
5728 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5729 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5730 *
5731 * @pre This method can be called if @p scip is in one of the following stages:
5732 * - \ref SCIP_STAGE_PROBLEM
5733 * - \ref SCIP_STAGE_PRESOLVING
5734 * - \ref SCIP_STAGE_SOLVING
5735 *
5736 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5737 */
5739 SCIP* scip, /**< SCIP data structure */
5740 SCIP_VAR* var, /**< variable to change the bound for */
5741 SCIP_Real newbound, /**< new value for bound */
5742 SCIP_CONS* infercons, /**< constraint that deduced the bound change */
5743 int inferinfo, /**< user information for inference to help resolving the conflict */
5744 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5745 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5746 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5747 )
5748{
5749 SCIP_Real lb;
5750 SCIP_Real ub;
5751
5752 assert(infeasible != NULL);
5753
5754 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarUbCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5755
5756 *infeasible = FALSE;
5757 if( tightened != NULL )
5758 *tightened = FALSE;
5759
5760 SCIPvarAdjustUb(var, scip->set, &newbound);
5761
5762 /* ignore tightenings of upper bounds to -infinity during solving process */
5763 if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5764 {
5765#ifndef NDEBUG
5766 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5767 SCIPvarGetUbLocal(var));
5768#endif
5769 return SCIP_OKAY;
5770 }
5771
5772 /* get current bounds */
5773 lb = SCIPvarGetLbLocal(var);
5774 ub = SCIPvarGetUbLocal(var);
5775 assert(SCIPsetIsLE(scip->set, lb, ub));
5776
5777 if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
5778 {
5779 *infeasible = TRUE;
5780 return SCIP_OKAY;
5781 }
5782 newbound = MAX(newbound, lb);
5783
5784 if( (force && SCIPsetIsGE(scip->set, newbound, ub)) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
5785 return SCIP_OKAY;
5786
5787 switch( scip->set->stage )
5788 {
5789 case SCIP_STAGE_PROBLEM:
5790 assert(!SCIPvarIsTransformed(var));
5791 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5792 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5793 SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5794 scip->branchcand, scip->eventqueue, newbound) );
5795 SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
5796 break;
5797
5799 if( !SCIPinProbing(scip) )
5800 {
5801 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5802 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5803
5804 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5805 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5807
5809 {
5810 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5811 assert(!(*infeasible));
5812 }
5813 break;
5814 }
5815 /*lint -fallthrough*/
5816 case SCIP_STAGE_SOLVING:
5817 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
5818 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5819 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, infercons, NULL, inferinfo, FALSE) );
5820 break;
5821
5822 default:
5823 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5824 return SCIP_INVALIDCALL;
5825 } /*lint !e788*/
5826
5827 /* check whether the upper bound improved */
5828 if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
5829 *tightened = TRUE;
5830
5831 return SCIP_OKAY;
5832}
5833
5834/** depending on SCIP's stage, fixes binary variable in the problem, in preprocessing, or in current node;
5835 * the given inference constraint is stored, such that the conflict analysis is able to find out the reason for the
5836 * deduction of the fixing
5837 *
5838 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5839 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5840 *
5841 * @pre This method can be called if @p scip is in one of the following stages:
5842 * - \ref SCIP_STAGE_PROBLEM
5843 * - \ref SCIP_STAGE_PRESOLVING
5844 * - \ref SCIP_STAGE_SOLVING
5845 */
5847 SCIP* scip, /**< SCIP data structure */
5848 SCIP_VAR* var, /**< binary variable to fix */
5849 SCIP_Bool fixedval, /**< value to fix binary variable to */
5850 SCIP_CONS* infercons, /**< constraint that deduced the fixing */
5851 int inferinfo, /**< user information for inference to help resolving the conflict */
5852 SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
5853 SCIP_Bool* tightened /**< pointer to store whether the fixing tightened the local bounds, or NULL */
5854 )
5855{
5856 SCIP_Real lb;
5857 SCIP_Real ub;
5858
5859 assert(SCIPvarIsBinary(var));
5860 assert(fixedval == TRUE || fixedval == FALSE);
5861 assert(infeasible != NULL);
5862
5863 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferBinvarCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5864
5865 *infeasible = FALSE;
5866 if( tightened != NULL )
5867 *tightened = FALSE;
5868
5869 /* get current bounds */
5870 lb = SCIPvarGetLbLocal(var);
5871 ub = SCIPvarGetUbLocal(var);
5872 assert(SCIPsetIsEQ(scip->set, lb, 0.0) || SCIPsetIsEQ(scip->set, lb, 1.0));
5873 assert(SCIPsetIsEQ(scip->set, ub, 0.0) || SCIPsetIsEQ(scip->set, ub, 1.0));
5874 assert(SCIPsetIsLE(scip->set, lb, ub));
5875
5876 /* check, if variable is already fixed */
5877 if( (lb > 0.5) || (ub < 0.5) )
5878 {
5879 *infeasible = (fixedval == (lb < 0.5));
5880
5881 return SCIP_OKAY;
5882 }
5883
5884 /* apply the fixing */
5885 switch( scip->set->stage )
5886 {
5887 case SCIP_STAGE_PROBLEM:
5888 assert(!SCIPvarIsTransformed(var));
5889 if( fixedval == TRUE )
5890 {
5891 SCIP_CALL( SCIPchgVarLb(scip, var, 1.0) );
5892 }
5893 else
5894 {
5895 SCIP_CALL( SCIPchgVarUb(scip, var, 0.0) );
5896 }
5897 break;
5898
5900 if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
5901 {
5902 SCIP_Bool fixed;
5903
5904 SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5905 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
5906 scip->cliquetable, (SCIP_Real)fixedval, infeasible, &fixed) );
5907 break;
5908 }
5909 /*lint -fallthrough*/
5910 case SCIP_STAGE_SOLVING:
5911 if( fixedval == TRUE )
5912 {
5913 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
5914 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5915 scip->cliquetable, var, 1.0, SCIP_BOUNDTYPE_LOWER, infercons, NULL, inferinfo, FALSE) );
5916 }
5917 else
5918 {
5919 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
5920 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5921 scip->cliquetable, var, 0.0, SCIP_BOUNDTYPE_UPPER, infercons, NULL, inferinfo, FALSE) );
5922 }
5923 break;
5924
5925 default:
5926 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5927 return SCIP_INVALIDCALL;
5928 } /*lint !e788*/
5929
5930 if( tightened != NULL )
5931 *tightened = TRUE;
5932
5933 return SCIP_OKAY;
5934}
5935
5936/** fixes variable in preprocessing or in the current node, if the new bound is tighter (w.r.t. bound strengthening
5937 * epsilon) than the current bound; if possible, adjusts bound to integral value; the given inference constraint is
5938 * stored, such that the conflict analysis is able to find out the reason for the deduction of the bound change
5939 *
5940 * @note In presolving stage when not in probing mode the variable will be fixed directly, otherwise this method
5941 * changes first the lowerbound by calling SCIPinferVarLbProp and second the upperbound by calling
5942 * SCIPinferVarUbProp
5943 *
5944 * @note If SCIP is in presolving stage, it can happen that the internal variable array (which get be accessed via
5945 * SCIPgetVars()) gets resorted.
5946 *
5947 * @note During presolving, an integer variable which bound changes to {0,1} is upgraded to a binary variable.
5948 */
5950 SCIP* scip, /**< SCIP data structure */
5951 SCIP_VAR* var, /**< variable to change the bound for */
5952 SCIP_Real fixedval, /**< new value for fixation */
5953 SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
5954 int inferinfo, /**< user information for inference to help resolving the conflict */
5955 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5956 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5957 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5958 )
5959{
5960 assert(scip != NULL);
5961 assert(var != NULL);
5962 assert(infeasible != NULL);
5963
5964 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarFixProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5965
5966 if( tightened != NULL )
5967 *tightened = FALSE;
5968
5969 /* in presolving case we take the shortcut to directly fix the variables */
5971 {
5972 SCIP_Bool fixed;
5973
5974 SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5975 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
5976 scip->cliquetable, fixedval, infeasible, &fixed) );
5977
5978 if( tightened != NULL )
5979 *tightened = fixed;
5980 }
5981 /* otherwise we use the lb and ub methods */
5982 else
5983 {
5984 SCIP_Bool lbtightened;
5985
5986 SCIP_CALL( SCIPinferVarLbProp(scip, var, fixedval, inferprop, inferinfo, force, infeasible, &lbtightened) );
5987
5988 if( ! (*infeasible) )
5989 {
5990 SCIP_CALL( SCIPinferVarUbProp(scip, var, fixedval, inferprop, inferinfo, force, infeasible, tightened) );
5991
5992 if( tightened != NULL )
5993 *tightened |= lbtightened;
5994 }
5995 }
5996
5997 return SCIP_OKAY;
5998}
5999
6000/** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
6001 * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
6002 * the given inference propagator is stored, such that the conflict analysis is able to find out the reason
6003 * for the deduction of the bound change
6004 *
6005 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6006 * SCIPgetVars()) gets resorted.
6007 *
6008 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6009 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6010 *
6011 * @pre This method can be called if @p scip is in one of the following stages:
6012 * - \ref SCIP_STAGE_PROBLEM
6013 * - \ref SCIP_STAGE_PRESOLVING
6014 * - \ref SCIP_STAGE_SOLVING
6015 *
6016 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6017 */
6019 SCIP* scip, /**< SCIP data structure */
6020 SCIP_VAR* var, /**< variable to change the bound for */
6021 SCIP_Real newbound, /**< new value for bound */
6022 SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
6023 int inferinfo, /**< user information for inference to help resolving the conflict */
6024 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6025 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
6026 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6027 )
6028{
6029 SCIP_Real lb;
6030 SCIP_Real ub;
6031
6032 assert(infeasible != NULL);
6033
6034 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarLbProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6035
6036 *infeasible = FALSE;
6037 if( tightened != NULL )
6038 *tightened = FALSE;
6039
6040 SCIPvarAdjustLb(var, scip->set, &newbound);
6041
6042 /* ignore tightenings of lower bounds to +infinity during solving process */
6044 {
6045#ifndef NDEBUG
6046 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
6047 SCIPvarGetLbLocal(var));
6048#endif
6049 return SCIP_OKAY;
6050 }
6051
6052 /* get current bounds */
6053 lb = SCIPvarGetLbLocal(var);
6054 ub = SCIPvarGetUbLocal(var);
6055 assert(SCIPsetIsLE(scip->set, lb, ub));
6056
6057 if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
6058 {
6059 *infeasible = TRUE;
6060 return SCIP_OKAY;
6061 }
6062 newbound = MIN(newbound, ub);
6063
6064 if( (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub))
6065 || SCIPsetIsLE(scip->set, newbound, lb) )
6066 return SCIP_OKAY;
6067
6068 switch( scip->set->stage )
6069 {
6070 case SCIP_STAGE_PROBLEM:
6071 assert(!SCIPvarIsTransformed(var));
6072 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6073 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6074 SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6075 scip->branchcand, scip->eventqueue, newbound) );
6076 SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
6077 break;
6078
6080 if( !SCIPinProbing(scip) )
6081 {
6082 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6083 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6084
6085 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6086 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6088
6090 {
6091 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6092 assert(!(*infeasible));
6093 }
6094 break;
6095 }
6096 /*lint -fallthrough*/
6097 case SCIP_STAGE_SOLVING:
6098 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
6099 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
6100 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, NULL, inferprop, inferinfo, FALSE) );
6101 break;
6102
6103 default:
6104 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6105 return SCIP_INVALIDCALL;
6106 } /*lint !e788*/
6107
6108 /* check whether the lower bound improved */
6109 if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
6110 *tightened = TRUE;
6111
6112 return SCIP_OKAY;
6113}
6114
6115/** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
6116 * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
6117 * the given inference propagator is stored, such that the conflict analysis is able to find out the reason
6118 * for the deduction of the bound change
6119 *
6120 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6121 * SCIPgetVars()) gets resorted.
6122 *
6123 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6124 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6125 *
6126 * @pre This method can be called if @p scip is in one of the following stages:
6127 * - \ref SCIP_STAGE_PROBLEM
6128 * - \ref SCIP_STAGE_PRESOLVING
6129 * - \ref SCIP_STAGE_SOLVING
6130 *
6131 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6132 */
6134 SCIP* scip, /**< SCIP data structure */
6135 SCIP_VAR* var, /**< variable to change the bound for */
6136 SCIP_Real newbound, /**< new value for bound */
6137 SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
6138 int inferinfo, /**< user information for inference to help resolving the conflict */
6139 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6140 SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
6141 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6142 )
6143{
6144 SCIP_Real lb;
6145 SCIP_Real ub;
6146
6147 assert(infeasible != NULL);
6148
6149 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarUbProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6150
6151 *infeasible = FALSE;
6152 if( tightened != NULL )
6153 *tightened = FALSE;
6154
6155 SCIPvarAdjustUb(var, scip->set, &newbound);
6156
6157 /* ignore tightenings of upper bounds to -infinity during solving process */
6158 if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6159 {
6160#ifndef NDEBUG
6161 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
6162 SCIPvarGetUbLocal(var));
6163#endif
6164 return SCIP_OKAY;
6165 }
6166
6167 /* get current bounds */
6168 lb = SCIPvarGetLbLocal(var);
6169 ub = SCIPvarGetUbLocal(var);
6170 assert(SCIPsetIsLE(scip->set, lb, ub));
6171
6172 if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
6173 {
6174 *infeasible = TRUE;
6175 return SCIP_OKAY;
6176 }
6177 newbound = MAX(newbound, lb);
6178
6179 if( (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub))
6180 || SCIPsetIsGE(scip->set, newbound, ub) )
6181 return SCIP_OKAY;
6182
6183 switch( scip->set->stage )
6184 {
6185 case SCIP_STAGE_PROBLEM:
6186 assert(!SCIPvarIsTransformed(var));
6187 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6188 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6189 SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6190 scip->branchcand, scip->eventqueue, newbound) );
6191 SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
6192 break;
6193
6195 if( !SCIPinProbing(scip) )
6196 {
6197 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6198 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6199
6200 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6201 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6203
6205 {
6206 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6207 assert(!(*infeasible));
6208 }
6209 break;
6210 }
6211 /*lint -fallthrough*/
6212 case SCIP_STAGE_SOLVING:
6213 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
6214 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
6215 scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, NULL, inferprop, inferinfo, FALSE) );
6216 break;
6217
6218 default:
6219 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6220 return SCIP_INVALIDCALL;
6221 } /*lint !e788*/
6222
6223 /* check whether the upper bound improved */
6224 if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
6225 *tightened = TRUE;
6226
6227 return SCIP_OKAY;
6228}
6229
6230/** depending on SCIP's stage, fixes binary variable in the problem, in preprocessing, or in current node;
6231 * the given inference propagator is stored, such that the conflict analysis is able to find out the reason for the
6232 * deduction of the fixing
6233 *
6234 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6235 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6236 *
6237 * @pre This method can be called if @p scip is in one of the following stages:
6238 * - \ref SCIP_STAGE_PROBLEM
6239 * - \ref SCIP_STAGE_PRESOLVING
6240 * - \ref SCIP_STAGE_PRESOLVED
6241 * - \ref SCIP_STAGE_SOLVING
6242 */
6244 SCIP* scip, /**< SCIP data structure */
6245 SCIP_VAR* var, /**< binary variable to fix */
6246 SCIP_Bool fixedval, /**< value to fix binary variable to */
6247 SCIP_PROP* inferprop, /**< propagator that deduced the fixing */
6248 int inferinfo, /**< user information for inference to help resolving the conflict */
6249 SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
6250 SCIP_Bool* tightened /**< pointer to store whether the fixing tightened the local bounds, or NULL */
6251 )
6252{
6253 SCIP_Real lb;
6254 SCIP_Real ub;
6255
6256 assert(SCIPvarIsBinary(var));
6257 assert(fixedval == TRUE || fixedval == FALSE);
6258 assert(infeasible != NULL);
6259
6260 SCIP_CALL( SCIPcheckStage(scip, "SCIPinferBinvarProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6261
6262 *infeasible = FALSE;
6263 if( tightened != NULL )
6264 *tightened = FALSE;
6265
6266 /* get current bounds */
6267 lb = SCIPvarGetLbLocal(var);
6268 ub = SCIPvarGetUbLocal(var);
6269 assert(SCIPsetIsEQ(scip->set, lb, 0.0) || SCIPsetIsEQ(scip->set, lb, 1.0));
6270 assert(SCIPsetIsEQ(scip->set, ub, 0.0) || SCIPsetIsEQ(scip->set, ub, 1.0));
6271 assert(SCIPsetIsLE(scip->set, lb, ub));
6272
6273 /* check, if variable is already fixed */
6274 if( (lb > 0.5) || (ub < 0.5) )
6275 {
6276 *infeasible = (fixedval == (lb < 0.5));
6277
6278 return SCIP_OKAY;
6279 }
6280
6281 /* apply the fixing */
6282 switch( scip->set->stage )
6283 {
6284 case SCIP_STAGE_PROBLEM:
6285 assert(!SCIPvarIsTransformed(var));
6286 if( fixedval == TRUE )
6287 {
6288 SCIP_CALL( SCIPchgVarLb(scip, var, 1.0) );
6289 }
6290 else
6291 {
6292 SCIP_CALL( SCIPchgVarUb(scip, var, 0.0) );
6293 }
6294 break;
6295
6297 if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
6298 {
6299 SCIP_Bool fixed;
6300
6301 SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6302 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
6303 scip->cliquetable, (SCIP_Real)fixedval, infeasible, &fixed) );
6304 break;
6305 }
6306 /*lint -fallthrough*/
6307 case SCIP_STAGE_SOLVING:
6308 if( fixedval == TRUE )
6309 {
6310 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
6311 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, 1.0,
6312 SCIP_BOUNDTYPE_LOWER, NULL, inferprop, inferinfo, FALSE) );
6313 }
6314 else
6315 {
6316 SCIP_CALL( SCIPnodeAddBoundinfer(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
6317 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, 0.0,
6318 SCIP_BOUNDTYPE_UPPER, NULL, inferprop, inferinfo, FALSE) );
6319 }
6320 break;
6321
6322 default:
6323 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6324 return SCIP_INVALIDCALL;
6325 } /*lint !e788*/
6326
6327 if( tightened != NULL )
6328 *tightened = TRUE;
6329
6330 return SCIP_OKAY;
6331}
6332
6333/** changes global lower bound of variable in preprocessing or in the current node, if the new bound is tighter
6334 * (w.r.t. bound strengthening epsilon) than the current global bound; if possible, adjusts bound to integral value;
6335 * also tightens the local bound, if the global bound is better than the local bound
6336 *
6337 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6338 * SCIPgetVars()) gets resorted.
6339 *
6340 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6341 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6342 *
6343 * @pre This method can be called if @p scip is in one of the following stages:
6344 * - \ref SCIP_STAGE_PROBLEM
6345 * - \ref SCIP_STAGE_TRANSFORMING
6346 * - \ref SCIP_STAGE_PRESOLVING
6347 * - \ref SCIP_STAGE_SOLVING
6348 *
6349 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6350 */
6352 SCIP* scip, /**< SCIP data structure */
6353 SCIP_VAR* var, /**< variable to change the bound for */
6354 SCIP_Real newbound, /**< new value for bound */
6355 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6356 SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
6357 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6358 )
6359{
6360 SCIP_Real lb;
6361 SCIP_Real ub;
6362
6363 assert(infeasible != NULL);
6364
6365 SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarLbGlobal", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6366
6367 *infeasible = FALSE;
6368 if( tightened != NULL )
6369 *tightened = FALSE;
6370
6371 SCIPvarAdjustLb(var, scip->set, &newbound);
6372
6373 /* ignore tightenings of lower bounds to +infinity during solving process */
6375 {
6376#ifndef NDEBUG
6377 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
6378 SCIPvarGetLbLocal(var));
6379#endif
6380 return SCIP_OKAY;
6381 }
6382
6383 /* get current bounds */
6384 lb = SCIPvarGetLbGlobal(var);
6385 ub = SCIPvarGetUbGlobal(var);
6386 assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPsetIsLE(scip->set, lb, ub));
6387
6388 if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
6389 {
6390 *infeasible = TRUE;
6391 return SCIP_OKAY;
6392 }
6393 newbound = MIN(newbound, ub);
6394
6395 /* bound changes of less than epsilon are ignored by SCIPvarChgLb or raise an assert in SCIPnodeAddBoundinfer,
6396 * so don't apply them even if force is set
6397 */
6398 if( SCIPsetIsEQ(scip->set, lb, newbound) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
6399 return SCIP_OKAY;
6400
6401 switch( scip->set->stage )
6402 {
6403 case SCIP_STAGE_PROBLEM:
6404 assert(!SCIPvarIsTransformed(var));
6405 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6406 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6407 SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6408 scip->branchcand, scip->eventqueue, newbound) );
6409 SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
6410 break;
6411
6413 SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6414 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6415 break;
6416
6418 if( !SCIPinProbing(scip) )
6419 {
6420 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6421 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6422
6423 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6424 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6426
6428 {
6429 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6430 assert(!(*infeasible));
6431 }
6432 break;
6433 }
6434 /*lint -fallthrough*/
6435 case SCIP_STAGE_SOLVING:
6436 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6437 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6439 break;
6440
6441 default:
6442 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6443 return SCIP_INVALIDCALL;
6444 } /*lint !e788*/
6445
6446 /* coverity: unreachable code */
6447 if( tightened != NULL && lb < SCIPcomputeVarLbGlobal(scip, var) )
6448 *tightened = TRUE;
6449
6450 return SCIP_OKAY;
6451}
6452
6453/** changes global upper bound of variable in preprocessing or in the current node, if the new bound is tighter
6454 * (w.r.t. bound strengthening epsilon) than the current global bound; if possible, adjusts bound to integral value;
6455 * also tightens the local bound, if the global bound is better than the local bound
6456 *
6457 * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6458 * SCIPgetVars()) gets resorted.
6459 *
6460 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6461 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6462 *
6463 * @pre This method can be called if @p scip is in one of the following stages:
6464 * - \ref SCIP_STAGE_PROBLEM
6465 * - \ref SCIP_STAGE_TRANSFORMING
6466 * - \ref SCIP_STAGE_PRESOLVING
6467 * - \ref SCIP_STAGE_SOLVING
6468 *
6469 * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6470 */
6472 SCIP* scip, /**< SCIP data structure */
6473 SCIP_VAR* var, /**< variable to change the bound for */
6474 SCIP_Real newbound, /**< new value for bound */
6475 SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6476 SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
6477 SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6478 )
6479{
6480 SCIP_Real lb;
6481 SCIP_Real ub;
6482
6483 assert(infeasible != NULL);
6484
6485 SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarUbGlobal", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6486
6487 *infeasible = FALSE;
6488 if( tightened != NULL )
6489 *tightened = FALSE;
6490
6491 SCIPvarAdjustUb(var, scip->set, &newbound);
6492
6493 /* ignore tightenings of upper bounds to -infinity during solving process */
6494 if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6495 {
6496#ifndef NDEBUG
6497 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
6498 SCIPvarGetUbLocal(var));
6499#endif
6500 return SCIP_OKAY;
6501 }
6502
6503 /* get current bounds */
6504 lb = SCIPvarGetLbGlobal(var);
6505 ub = SCIPvarGetUbGlobal(var);
6506 assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPsetIsLE(scip->set, lb, ub));
6507
6508 if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
6509 {
6510 *infeasible = TRUE;
6511 return SCIP_OKAY;
6512 }
6513 newbound = MAX(newbound, lb);
6514
6515 /* bound changes of less than epsilon are ignored by SCIPvarChgUb or raise an assert in SCIPnodeAddBoundinfer,
6516 * so don't apply them even if force is set
6517 */
6518 if( SCIPsetIsEQ(scip->set, ub, newbound) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
6519 return SCIP_OKAY;
6520
6521 switch( scip->set->stage )
6522 {
6523 case SCIP_STAGE_PROBLEM:
6524 assert(!SCIPvarIsTransformed(var));
6525 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6526 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6527 SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6528 scip->branchcand, scip->eventqueue, newbound) );
6529 SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
6530 break;
6531
6533 SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6534 scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6535 break;
6536
6538 if( !SCIPinProbing(scip) )
6539 {
6540 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6541 assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6542
6543 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6544 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6546
6548 {
6549 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6550 assert(!(*infeasible));
6551 }
6552 break;
6553 }
6554 /*lint -fallthrough*/
6555 case SCIP_STAGE_SOLVING:
6556 SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6557 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6559 break;
6560
6561 default:
6562 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6563 return SCIP_INVALIDCALL;
6564 } /*lint !e788*/
6565
6566 /* coverity: unreachable code */
6567 if( tightened != NULL && ub > SCIPcomputeVarUbGlobal(scip, var) )
6568 *tightened = TRUE;
6569
6570 return SCIP_OKAY;
6571}
6572
6573/* some simple variable functions implemented as defines */
6574#undef SCIPcomputeVarLbGlobal
6575#undef SCIPcomputeVarUbGlobal
6576#undef SCIPcomputeVarLbLocal
6577#undef SCIPcomputeVarUbLocal
6578
6579/** for a multi-aggregated variable, returns the global lower bound computed by adding the global bounds from all aggregation variables
6580 *
6581 * 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
6582 * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetLbGlobal.
6583 *
6584 * @return the global lower bound computed by adding the global bounds from all aggregation variables
6585 */
6587 SCIP* scip, /**< SCIP data structure */
6588 SCIP_VAR* var /**< variable to compute the bound for */
6589 )
6590{
6591 assert(scip != NULL);
6592 assert(var != NULL);
6593
6595 return SCIPvarGetMultaggrLbGlobal(var, scip->set);
6596 else
6597 return SCIPvarGetLbGlobal(var);
6598}
6599
6600/** for a multi-aggregated variable, returns the global upper bound computed by adding the global bounds from all aggregation variables
6601 *
6602 * 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
6603 * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetUbGlobal
6604 *
6605 * @return the global upper bound computed by adding the global bounds from all aggregation variables
6606 */
6608 SCIP* scip, /**< SCIP data structure */
6609 SCIP_VAR* var /**< variable to compute the bound for */
6610 )
6611{
6612 assert(scip != NULL);
6613 assert(var != NULL);
6614
6616 return SCIPvarGetMultaggrUbGlobal(var, scip->set);
6617 else
6618 return SCIPvarGetUbGlobal(var);
6619}
6620
6621/** for a multi-aggregated variable, returns the local lower bound computed by adding the local bounds from all aggregation variables
6622 *
6623 * 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
6624 * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetLbLocal.
6625 *
6626 * @return the local lower bound computed by adding the global bounds from all aggregation variables
6627 */
6629 SCIP* scip, /**< SCIP data structure */
6630 SCIP_VAR* var /**< variable to compute the bound for */
6631 )
6632{
6633 assert(scip != NULL);
6634 assert(var != NULL);
6635
6637 return SCIPvarGetMultaggrLbLocal(var, scip->set);
6638 else
6639 return SCIPvarGetLbLocal(var);
6640}
6641
6642/** for a multi-aggregated variable, returns the local upper bound computed by adding the local bounds from all aggregation variables
6643 *
6644 * 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
6645 * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetUbLocal.
6646 *
6647 * @return the local upper bound computed by adding the global bounds from all aggregation variables
6648 */
6650 SCIP* scip, /**< SCIP data structure */
6651 SCIP_VAR* var /**< variable to compute the bound for */
6652 )
6653{
6654 assert(scip != NULL);
6655 assert(var != NULL);
6656
6658 return SCIPvarGetMultaggrUbLocal(var, scip->set);
6659 else
6660 return SCIPvarGetUbLocal(var);
6661}
6662
6663/** for a multi-aggregated variable, gives the global lower bound computed by adding the global bounds from all
6664 * aggregation variables, this global bound may be tighter than the one given by SCIPvarGetLbGlobal, since the latter is
6665 * not updated if bounds of aggregation variables are changing
6666 *
6667 * calling this function for a non-multi-aggregated variable is not allowed
6668 */
6670 SCIP* scip, /**< SCIP data structure */
6671 SCIP_VAR* var /**< variable to compute the bound for */
6672 )
6673{
6675 return SCIPvarGetMultaggrLbGlobal(var, scip->set);
6676}
6677
6678/** for a multi-aggregated variable, gives the global upper bound computed by adding the global bounds from all
6679 * aggregation variables, this upper bound may be tighter than the one given by SCIPvarGetUbGlobal, since the latter is
6680 * not updated if bounds of aggregation variables are changing
6681 *
6682 * calling this function for a non-multi-aggregated variable is not allowed
6683 */
6685 SCIP* scip, /**< SCIP data structure */
6686 SCIP_VAR* var /**< variable to compute the bound for */
6687 )
6688{
6690 return SCIPvarGetMultaggrUbGlobal(var, scip->set);
6691}
6692
6693/** for a multi-aggregated variable, gives the local lower bound computed by adding the local bounds from all
6694 * aggregation variables, this lower bound may be tighter than the one given by SCIPvarGetLbLocal, since the latter is
6695 * not updated if bounds of aggregation variables are changing
6696 *
6697 * calling this function for a non-multi-aggregated variable is not allowed
6698 */
6700 SCIP* scip, /**< SCIP data structure */
6701 SCIP_VAR* var /**< variable to compute the bound for */
6702 )
6703{
6705 return SCIPvarGetMultaggrLbLocal(var, scip->set);
6706}
6707
6708/** for a multi-aggregated variable, gives the local upper bound computed by adding the local bounds from all
6709 * aggregation variables, this upper bound may be tighter than the one given by SCIPvarGetUbLocal, since the latter is
6710 * not updated if bounds of aggregation variables are changing
6711 *
6712 * calling this function for a non-multi-aggregated variable is not allowed
6713 */
6715 SCIP* scip, /**< SCIP data structure */
6716 SCIP_VAR* var /**< variable to compute the bound for */
6717 )
6718{
6720 return SCIPvarGetMultaggrUbLocal(var, scip->set);
6721}
6722
6723/** returns solution value and index of variable lower bound that is closest to the variable's value in the given primal
6724 * solution or current LP solution if no primal solution is given; returns an index of -1 if no variable lower bound is
6725 * available
6726 *
6727 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6728 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6729 *
6730 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
6731 */
6733 SCIP* scip, /**< SCIP data structure */
6734 SCIP_VAR* var, /**< active problem variable */
6735 SCIP_SOL* sol, /**< primal solution, or NULL for LP solution */
6736 SCIP_Real* closestvlb, /**< pointer to store the value of the closest variable lower bound */
6737 int* closestvlbidx /**< pointer to store the index of the closest variable lower bound */
6738 )
6739{
6740 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarClosestVlb", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6741
6742 SCIPvarGetClosestVlb(var, sol, scip->set, scip->stat, closestvlb, closestvlbidx);
6743
6744 return SCIP_OKAY;
6745}
6746
6747/** returns solution value and index of variable upper bound that is closest to the variable's value in the given primal solution;
6748 * or current LP solution if no primal solution is given; returns an index of -1 if no variable upper bound is available
6749 *
6750 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6751 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6752 *
6753 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
6754 */
6756 SCIP* scip, /**< SCIP data structure */
6757 SCIP_VAR* var, /**< active problem variable */
6758 SCIP_SOL* sol, /**< primal solution, or NULL for LP solution */
6759 SCIP_Real* closestvub, /**< pointer to store the value of the closest variable lower bound */
6760 int* closestvubidx /**< pointer to store the index of the closest variable lower bound */
6761 )
6762{
6763 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarClosestVub", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6764
6765 SCIPvarGetClosestVub(var, sol, scip->set, scip->stat, closestvub, closestvubidx);
6766
6767 return SCIP_OKAY;
6768}
6769
6770/** informs variable x about a globally valid variable lower bound x >= b*z + d with integer variable z;
6771 * if z is binary, the corresponding valid implication for z is also added;
6772 * if z is non-continuous and 1/b not too small, the corresponding valid upper/lower bound
6773 * z <= (x-d)/b or z >= (x-d)/b (depending on the sign of of b) is added, too;
6774 * improves the global bounds of the variable and the vlb variable if possible
6775 *
6776 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6777 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6778 *
6779 * @pre This method can be called if @p scip is in one of the following stages:
6780 * - \ref SCIP_STAGE_PRESOLVING
6781 * - \ref SCIP_STAGE_PRESOLVED
6782 * - \ref SCIP_STAGE_SOLVING
6783 */
6785 SCIP* scip, /**< SCIP data structure */
6786 SCIP_VAR* var, /**< problem variable */
6787 SCIP_VAR* vlbvar, /**< variable z in x >= b*z + d */
6788 SCIP_Real vlbcoef, /**< coefficient b in x >= b*z + d */
6789 SCIP_Real vlbconstant, /**< constant d in x >= b*z + d */
6790 SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6791 int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6792 )
6793{
6794 int nlocalbdchgs;
6795
6797
6798 SCIP_CALL( SCIPvarAddVlb(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->tree,
6799 scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, vlbvar, vlbcoef, vlbconstant,
6800 TRUE, infeasible, &nlocalbdchgs) );
6801
6802 *nbdchgs = nlocalbdchgs;
6803
6804 /* 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
6805 * detected infeasibility
6806 */
6807 if( !(*infeasible) && SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisZero(scip, 1.0/vlbcoef) )
6808 {
6809 if( vlbcoef > 0.0 )
6810 {
6811 /* if b > 0, we have a variable upper bound: x >= b*z + d => z <= (x-d)/b */
6812 SCIP_CALL( SCIPvarAddVub(vlbvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6813 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vlbcoef,
6814 -vlbconstant/vlbcoef, TRUE, infeasible, &nlocalbdchgs) );
6815 }
6816 else
6817 {
6818 /* if b < 0, we have a variable lower bound: x >= b*z + d => z >= (x-d)/b */
6819 SCIP_CALL( SCIPvarAddVlb(vlbvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6820 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vlbcoef,
6821 -vlbconstant/vlbcoef, TRUE, infeasible, &nlocalbdchgs) );
6822 }
6823 *nbdchgs += nlocalbdchgs;
6824 }
6825
6826 return SCIP_OKAY;
6827}
6828
6829/** informs variable x about a globally valid variable upper bound x <= b*z + d with integer variable z;
6830 * if z is binary, the corresponding valid implication for z is also added;
6831 * if z is non-continuous and 1/b not too small, the corresponding valid lower/upper bound
6832 * z >= (x-d)/b or z <= (x-d)/b (depending on the sign of of b) is added, too;
6833 * improves the global bounds of the variable and the vlb variable if possible
6834 *
6835 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6836 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6837 *
6838 * @pre This method can be called if @p scip is in one of the following stages:
6839 * - \ref SCIP_STAGE_PRESOLVING
6840 * - \ref SCIP_STAGE_PRESOLVED
6841 * - \ref SCIP_STAGE_SOLVING
6842 */
6844 SCIP* scip, /**< SCIP data structure */
6845 SCIP_VAR* var, /**< problem variable */
6846 SCIP_VAR* vubvar, /**< variable z in x <= b*z + d */
6847 SCIP_Real vubcoef, /**< coefficient b in x <= b*z + d */
6848 SCIP_Real vubconstant, /**< constant d in x <= b*z + d */
6849 SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6850 int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6851 )
6852{
6853 int nlocalbdchgs;
6854
6856
6857 SCIP_CALL( SCIPvarAddVub(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->tree,
6858 scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, vubvar, vubcoef, vubconstant, TRUE,
6859 infeasible, &nlocalbdchgs) );
6860
6861 *nbdchgs = nlocalbdchgs;
6862
6863 /* 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
6864 * detected infeasibility
6865 */
6866 if( !(*infeasible) && SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisZero(scip, 1.0/vubcoef) )
6867 {
6868 if( vubcoef > 0.0 )
6869 {
6870 /* if b < 0, we have a variable lower bound: x >= b*z + d => z >= (x-d)/b */
6871 SCIP_CALL( SCIPvarAddVlb(vubvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6872 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vubcoef,
6873 -vubconstant/vubcoef, TRUE, infeasible, &nlocalbdchgs) );
6874 }
6875 else
6876 {
6877 /* if b > 0, we have a variable upper bound: x >= b*z + d => z <= (x-d)/b */
6878 SCIP_CALL( SCIPvarAddVub(vubvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6879 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vubcoef,
6880 -vubconstant/vubcoef, TRUE, infeasible, &nlocalbdchgs) );
6881 }
6882 *nbdchgs += nlocalbdchgs;
6883 }
6884
6885 return SCIP_OKAY;
6886}
6887
6888/** informs binary variable x about a globally valid implication: x == 0 or x == 1 ==> y <= b or y >= b;
6889 * also adds the corresponding implication or variable bound to the implied variable;
6890 * if the implication is conflicting, the variable is fixed to the opposite value;
6891 * if the variable is already fixed to the given value, the implication is performed immediately;
6892 * if the implication is redundant with respect to the variables' global bounds, it is ignored
6893 *
6894 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6895 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6896 *
6897 * @pre This method can be called if @p scip is in one of the following stages:
6898 * - \ref SCIP_STAGE_TRANSFORMED
6899 * - \ref SCIP_STAGE_PRESOLVING
6900 * - \ref SCIP_STAGE_PRESOLVED
6901 * - \ref SCIP_STAGE_SOLVING
6902 */
6904 SCIP* scip, /**< SCIP data structure */
6905 SCIP_VAR* var, /**< problem variable */
6906 SCIP_Bool varfixing, /**< FALSE if y should be added in implications for x == 0, TRUE for x == 1 */
6907 SCIP_VAR* implvar, /**< variable y in implication y <= b or y >= b */
6908 SCIP_BOUNDTYPE impltype, /**< type of implication y <= b (SCIP_BOUNDTYPE_UPPER)
6909 * or y >= b (SCIP_BOUNDTYPE_LOWER) */
6910 SCIP_Real implbound, /**< bound b in implication y <= b or y >= b */
6911 SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6912 int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6913 )
6914{
6915 SCIP_VAR* implprobvar;
6916
6917 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarImplication", FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6918
6919 assert(infeasible != NULL);
6920 *infeasible = FALSE;
6921
6922 if ( nbdchgs != NULL )
6923 *nbdchgs = 0;
6924
6925 if( !SCIPvarIsBinary(var) )
6926 {
6927 SCIPerrorMessage("can't add implication for nonbinary variable\n");
6928 return SCIP_INVALIDDATA;
6929 }
6930
6931 implprobvar = SCIPvarGetProbvar(implvar);
6932 /* transform implication containing two binary variables to a clique; the condition ensures that the active representative
6933 * of implvar is actually binary
6934 */
6935 if( SCIPvarIsBinary(implvar) && (SCIPvarIsActive(implvar) || (implprobvar != NULL && SCIPvarIsBinary(implprobvar))) )
6936 {
6937 assert(SCIPisFeasEQ(scip, implbound, 1.0) || SCIPisFeasZero(scip, implbound));
6938 assert((impltype == SCIP_BOUNDTYPE_UPPER) == SCIPisFeasZero(scip, implbound));
6939
6940 /* only add clique if implication is not redundant with respect to global bounds of the implication variable */
6941 if( (impltype == SCIP_BOUNDTYPE_LOWER && SCIPvarGetLbGlobal(implvar) < 0.5) ||
6942 (impltype == SCIP_BOUNDTYPE_UPPER && SCIPvarGetUbGlobal(implvar) > 0.5) )
6943 {
6944 SCIP_VAR* vars[2];
6945 SCIP_Bool vals[2];
6946
6947 vars[0] = var;
6948 vars[1] = implvar;
6949 vals[0] = varfixing;
6950 vals[1] = (impltype == SCIP_BOUNDTYPE_UPPER);
6951
6952 SCIP_CALL( SCIPaddClique(scip, vars, vals, 2, FALSE, infeasible, nbdchgs) );
6953 }
6954
6955 return SCIP_OKAY;
6956 }
6957
6958 /* the implication graph can only handle 'real' binary (SCIP_VARTYPE_BINARY) variables, therefore we transform the
6959 * implication in variable bounds, (lowerbound of y will be abbreviated by lby, upperbound equivlaent) the follwing
6960 * four cases are:
6961 *
6962 * 1. (x >= 1 => y >= b) => y >= (b - lby) * x + lby
6963 * 2. (x >= 1 => y <= b) => y <= (b - uby) * x + uby
6964 * 3. (x <= 0 => y >= b) => y >= (lby - b) * x + b
6965 * 4. (x <= 0 => y <= b) => y <= (uby - b) * x + b
6966 */
6968 {
6969 SCIP_Real lby;
6970 SCIP_Real uby;
6971
6972 lby = SCIPvarGetLbGlobal(implvar);
6973 uby = SCIPvarGetUbGlobal(implvar);
6974
6975 if( varfixing == TRUE )
6976 {
6977 if( impltype == SCIP_BOUNDTYPE_LOWER )
6978 {
6979 /* we return if the lower bound is infinity */
6980 if( SCIPisInfinity(scip, -lby) )
6981 return SCIP_OKAY;
6982
6983 SCIP_CALL( SCIPvarAddVlb(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6984 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6985 implbound - lby, lby, TRUE, infeasible, nbdchgs) );
6986 }
6987 else
6988 {
6989 /* we return if the upper bound is infinity */
6990 if( SCIPisInfinity(scip, uby) )
6991 return SCIP_OKAY;
6992
6993 SCIP_CALL( SCIPvarAddVub(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6994 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6995 implbound - uby, uby, TRUE, infeasible, nbdchgs) );
6996 }
6997 }
6998 else
6999 {
7000 if( impltype == SCIP_BOUNDTYPE_LOWER )
7001 {
7002 /* we return if the lower bound is infinity */
7003 if( SCIPisInfinity(scip, -lby) )
7004 return SCIP_OKAY;
7005
7006 SCIP_CALL( SCIPvarAddVlb(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
7007 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
7008 lby - implbound, implbound, TRUE, infeasible, nbdchgs) );
7009 }
7010 else
7011 {
7012 /* we return if the upper bound is infinity */
7013 if( SCIPisInfinity(scip, uby) )
7014 return SCIP_OKAY;
7015
7016 SCIP_CALL( SCIPvarAddVub(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
7017 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
7018 uby - implbound, implbound, TRUE, infeasible, nbdchgs) );
7019 }
7020 }
7021 }
7022 else
7023 {
7024 SCIP_CALL( SCIPvarAddImplic(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
7025 scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, varfixing, implvar, impltype,
7026 implbound, TRUE, infeasible, nbdchgs) );
7027 }
7028
7029 return SCIP_OKAY;
7030}
7031
7032/** adds a clique information to SCIP, stating that at most one of the given binary variables can be set to 1;
7033 * if a variable appears twice in the same clique, the corresponding implications are performed
7034 *
7035 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7036 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7037 *
7038 * @pre This method can be called if @p scip is in one of the following stages:
7039 * - \ref SCIP_STAGE_TRANSFORMED
7040 * - \ref SCIP_STAGE_PRESOLVING
7041 * - \ref SCIP_STAGE_PRESOLVED
7042 * - \ref SCIP_STAGE_SOLVING
7043 */
7045 SCIP* scip, /**< SCIP data structure */
7046 SCIP_VAR** vars, /**< binary variables in the clique from which at most one can be set to 1 */
7047 SCIP_Bool* values, /**< values of the variables in the clique; NULL to use TRUE for all vars */
7048 int nvars, /**< number of variables in the clique */
7049 SCIP_Bool isequation, /**< is the clique an equation or an inequality? */
7050 SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
7051 int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
7052 )
7053{
7055
7056 *infeasible = FALSE;
7057 if( nbdchgs != NULL )
7058 *nbdchgs = 0;
7059
7060 if( nvars > 1 )
7061 {
7062 /* add the clique to the clique table */
7063 SCIP_CALL( SCIPcliquetableAdd(scip->cliquetable, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
7064 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, vars, values, nvars, isequation,
7065 infeasible, nbdchgs) );
7066 }
7067
7068 return SCIP_OKAY;
7069}
7070
7071/** relabels the given labels in-place in an increasing fashion: the first seen label is 0, the next label 1, etc...
7072 *
7073 * @note every label equal to -1 is treated as a previously unseen, unique label and gets a new ordered label.
7074 */
7075static
7077 SCIP*const scip, /**< SCIP data structure */
7078 int* labels, /**< current labels that will be overwritten */
7079 int const nlabels, /**< number of variables in the clique */
7080 int* nclasses /**< pointer to store the total number of distinct labels */
7081 )
7082{
7083 SCIP_HASHMAP* classidx2newlabel;
7084
7085 int classidx;
7086 int i;
7087
7088 SCIP_CALL( SCIPhashmapCreate(&classidx2newlabel, SCIPblkmem(scip), nlabels) );
7089
7090 classidx = 0;
7091
7092 /* loop over labels to create local class indices that obey the variable order */
7093 for( i = 0; i < nlabels; ++i )
7094 {
7095 int currentlabel = labels[i];
7096 int localclassidx;
7097
7098 /* labels equal to -1 are stored as singleton classes */
7099 if( currentlabel == -1 )
7100 {
7101 ++classidx;
7102 localclassidx = classidx;
7103 }
7104 else
7105 {
7106 assert(currentlabel >= 0);
7107 /* look up the class index image in the hash map; if it is not stored yet, new class index is created and stored */
7108 if( !SCIPhashmapExists(classidx2newlabel, (void*)(size_t)currentlabel) )
7109 {
7110 ++classidx;
7111 localclassidx = classidx;
7112 SCIP_CALL( SCIPhashmapInsertInt(classidx2newlabel, (void*)(size_t)currentlabel, classidx) ); /*lint !e571*/
7113 }
7114 else
7115 {
7116 localclassidx = SCIPhashmapGetImageInt(classidx2newlabel, (void*)(size_t)currentlabel); /*lint !e571*/
7117 }
7118 }
7119 assert(localclassidx - 1 >= 0);
7120 assert(localclassidx - 1 <= i);
7121
7122 /* indices start with zero, but we have an offset of 1 because we cannot store 0 in a hashmap */
7123 labels[i] = localclassidx - 1;
7124 }
7125
7126 assert(classidx > 0);
7127 assert(classidx <= nlabels);
7128 *nclasses = classidx;
7129
7130 SCIPhashmapFree(&classidx2newlabel);
7131
7132 return SCIP_OKAY;
7133}
7134
7135/** sort the variables w.r.t. the given labels; thereby ensure the current order of the variables with the same label. */
7136static
7138 SCIP* scip, /**< SCIP data structure */
7139 SCIP_VAR** vars, /**< variable array */
7140 int* classlabels, /**< array that contains a class label for every variable */
7141 SCIP_VAR** sortedvars, /**< array to store variables after stable sorting */
7142 int* sortedindices, /**< array to store indices of sorted variables in the original vars array */
7143 int* classesstartposs, /**< starting position array for each label class (must have size nclasses + 1) */
7144 int nvars, /**< size of the vars arrays */
7145 int nclasses /**< number of label classes */
7146 )
7147{
7148 SCIP_VAR*** varpointers;
7149 int** indexpointers;
7150 int* classcount;
7151
7152 int nextpos;
7153 int c;
7154 int v;
7155
7156 assert(scip != NULL);
7157 assert(vars != NULL);
7158 assert(sortedindices != NULL);
7159 assert(classesstartposs != NULL);
7160
7161 assert(nvars == 0 || vars != NULL);
7162
7163 if( nvars == 0 )
7164 return SCIP_OKAY;
7165
7166 assert(classlabels != NULL);
7167 assert(nclasses > 0);
7168
7169 /* we first count all class cardinalities and allocate temporary memory for a bucket sort */
7170 SCIP_CALL( SCIPallocBufferArray(scip, &classcount, nclasses) );
7171 BMSclearMemoryArray(classcount, nclasses);
7172
7173 /* first we count for each class the number of elements */
7174 for( v = nvars - 1; v >= 0; --v )
7175 {
7176 assert(0 <= classlabels[v] && classlabels[v] < nclasses);
7177 ++(classcount[classlabels[v]]);
7178 }
7179
7180#ifndef NDEBUG
7181 BMSclearMemoryArray(sortedvars, nvars);
7182 BMSclearMemoryArray(sortedindices, nvars);
7183#endif
7184 SCIP_CALL( SCIPallocBufferArray(scip, &varpointers, nclasses) );
7185 SCIP_CALL( SCIPallocBufferArray(scip, &indexpointers, nclasses) );
7186
7187 nextpos = 0;
7188 /* now we initialize all start pointers for each class, so they will be ordered */
7189 for( c = 0; c < nclasses; ++c )
7190 {
7191 /* to reach the goal that all variables of each class will be standing next to each other we will initialize the
7192 * starting pointers for each class by adding the cardinality of each class to the last class starting pointer
7193 * e.g. class1 has 4 elements and class2 has 3 elements then the starting pointer for class1 will be the pointer
7194 * to sortedvars[0], the starting pointer to class2 will be the pointer to sortedvars[4] and to class3 it will be
7195 * the pointer to sortedvars[7]
7196 */
7197 varpointers[c] = (SCIP_VAR**) (sortedvars + nextpos);
7198 indexpointers[c] = (int*) (sortedindices + nextpos);
7199 classesstartposs[c] = nextpos;
7200 assert(classcount[c] > 0);
7201 nextpos += classcount[c];
7202 assert(nextpos > 0);
7203 }
7204 assert(nextpos == nvars);
7205 classesstartposs[c] = nextpos;
7206
7207 /* now we copy all variables to the right order */
7208 for( v = 0; v < nvars; ++v )
7209 {
7210 /* copy variable itself to the right position */
7211 *(varpointers[classlabels[v]]) = vars[v]; /*lint !e613*/
7212 ++(varpointers[classlabels[v]]);
7213
7214 /* copy index */
7215 *(indexpointers[classlabels[v]]) = v;
7216 ++(indexpointers[classlabels[v]]);
7217 }
7218
7219/* in debug mode, we ensure the correctness of the mapping */
7220#ifndef NDEBUG
7221 for( v = 0; v < nvars; ++v )
7222 {
7223 assert(sortedvars[v] != NULL);
7224 assert(sortedindices[v] >= 0);
7225
7226 /* assert that the sorted indices map back to the correct variable in the original order */
7227 assert(vars[sortedindices[v]] == sortedvars[v]);
7228 }
7229#endif
7230
7231 /* free temporary memory */
7232 SCIPfreeBufferArray(scip, &indexpointers);
7233 SCIPfreeBufferArray(scip, &varpointers);
7234 SCIPfreeBufferArray(scip, &classcount);
7235
7236 return SCIP_OKAY;
7237}
7238
7239
7240/* calculate clique partition for a maximal amount of comparisons on variables due to expensive algorithm
7241 * @todo: check for a good value, maybe it's better to check parts of variables
7242 */
7243#define MAXNCLIQUEVARSCOMP 1000000
7244
7245/** calculates a partition of the given set of binary variables into cliques;
7246 * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7247 * were assigned to the same clique;
7248 * the first variable is always assigned to clique 0, and a variable can only be assigned to clique i if at least one of
7249 * the preceding variables was assigned to clique i-1;
7250 * for each clique at most 1 variables can be set to TRUE in a feasible solution;
7251 *
7252 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7253 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7254 *
7255 * @pre This method can be called if @p scip is in one of the following stages:
7256 * - \ref SCIP_STAGE_INITPRESOLVE
7257 * - \ref SCIP_STAGE_PRESOLVING
7258 * - \ref SCIP_STAGE_EXITPRESOLVE
7259 * - \ref SCIP_STAGE_PRESOLVED
7260 * - \ref SCIP_STAGE_SOLVING
7261 */
7262static
7264 SCIP*const scip, /**< SCIP data structure */
7265 SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7266 SCIP_Bool*const values, /**< clique value (TRUE or FALSE) for each variable in the clique */
7267 int const nvars, /**< number of variables in the array */
7268 int*const cliquepartition, /**< array of length nvars to store the clique partition */
7269 int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7270 )
7271{
7272 SCIP_VAR** cliquevars;
7273 SCIP_Bool* cliquevalues;
7274 int i;
7275 int maxncliquevarscomp;
7276 int ncliquevars;
7277
7278 /* allocate temporary memory for storing the variables of the current clique */
7279 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &cliquevars, nvars) );
7280 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &cliquevalues, nvars) );
7281
7282 /* initialize the cliquepartition array with -1 */
7283 for( i = nvars - 1; i >= 0; --i )
7284 cliquepartition[i] = -1;
7285
7286 maxncliquevarscomp = (int) MIN(nvars * (SCIP_Longint)nvars, MAXNCLIQUEVARSCOMP);
7287 /* calculate the clique partition */
7288 *ncliques = 0;
7289 for( i = 0; i < nvars; ++i )
7290 {
7291 if( cliquepartition[i] == -1 )
7292 {
7293 int j;
7294
7295 /* variable starts a new clique */
7296 cliquepartition[i] = *ncliques;
7297 cliquevars[0] = vars[i];
7298 cliquevalues[0] = values[i];
7299 ncliquevars = 1;
7300
7301 /* if variable is not active (multi-aggregated or fixed), it cannot be in any clique */
7302 if( SCIPvarIsActive(vars[i]) && SCIPvarGetNCliques(vars[i], values[i]) > 0 )
7303 {
7304 /* greedily fill up the clique */
7305 for( j = i+1; j < nvars; ++j )
7306 {
7307 /* if variable is not active (multi-aggregated or fixed), it cannot be in any clique */
7308 if( cliquepartition[j] == -1 && SCIPvarIsActive(vars[j]) )
7309 {
7310 int k;
7311
7312 /* check if every variable in the current clique can be extended by tmpvars[j] */
7313 for( k = ncliquevars - 1; k >= 0; --k )
7314 {
7315 if( !SCIPvarsHaveCommonClique(vars[j], values[j], cliquevars[k], cliquevalues[k], FALSE) )
7316 break;
7317 }
7318
7319 if( k == -1 )
7320 {
7321 /* put the variable into the same clique */
7322 cliquepartition[j] = cliquepartition[i];
7323 cliquevars[ncliquevars] = vars[j];
7324 cliquevalues[ncliquevars] = values[j];
7325 ++ncliquevars;
7326 }
7327 }
7328 }
7329 }
7330
7331 /* this clique is finished */
7332 ++(*ncliques);
7333 }
7334 assert(cliquepartition[i] >= 0 && cliquepartition[i] < i+1);
7335
7336 /* break if we reached the maximal number of comparisons */
7337 if( i * nvars > maxncliquevarscomp )
7338 break;
7339 }
7340 /* if we had to many variables fill up the cliquepartition and put each variable in a separate clique */
7341 for( ; i < nvars; ++i )
7342 {
7343 if( cliquepartition[i] == -1 )
7344 {
7345 cliquepartition[i] = *ncliques;
7346 ++(*ncliques);
7347 }
7348 }
7349
7350 SCIPsetFreeBufferArray(scip->set, &cliquevalues);
7351 SCIPsetFreeBufferArray(scip->set, &cliquevars);
7352
7353 return SCIP_OKAY;
7354}
7355
7356/** calculates a partition of the given set of binary variables into cliques; takes into account independent clique components
7357 *
7358 * The algorithm performs the following steps:
7359 * - recomputes connected components of the clique table, if necessary
7360 * - computes a clique partition for every connected component greedily.
7361 * - relabels the resulting clique partition such that it satisfies the description below
7362 *
7363 * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7364 * were assigned to the same clique;
7365 * the first variable is always assigned to clique 0, and a variable can only be assigned to clique i if at least one of
7366 * the preceding variables was assigned to clique i-1;
7367 * for each clique at most 1 variables can be set to TRUE in a feasible solution;
7368 *
7369 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7370 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7371 *
7372 * @pre This method can be called if @p scip is in one of the following stages:
7373 * - \ref SCIP_STAGE_INITPRESOLVE
7374 * - \ref SCIP_STAGE_PRESOLVING
7375 * - \ref SCIP_STAGE_EXITPRESOLVE
7376 * - \ref SCIP_STAGE_PRESOLVED
7377 * - \ref SCIP_STAGE_SOLVING
7378 */
7380 SCIP*const scip, /**< SCIP data structure */
7381 SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7382 int const nvars, /**< number of variables in the clique */
7383 int*const cliquepartition, /**< array of length nvars to store the clique partition */
7384 int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7385 )
7386{
7387 SCIP_VAR** tmpvars;
7388
7389 SCIP_VAR** sortedtmpvars;
7390 SCIP_Bool* tmpvalues;
7391 SCIP_Bool* sortedtmpvalues;
7392 int* componentlabels;
7393 int* sortedindices;
7394 int* componentstartposs;
7395 int i;
7396 int c;
7397
7398 int ncomponents;
7399
7400 assert(scip != NULL);
7401 assert(nvars == 0 || vars != NULL);
7402 assert(nvars == 0 || cliquepartition != NULL);
7403 assert(ncliques != NULL);
7404
7405 SCIP_CALL( SCIPcheckStage(scip, "SCIPcalcCliquePartition", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7406
7407 if( nvars == 0 )
7408 {
7409 *ncliques = 0;
7410 return SCIP_OKAY;
7411 }
7412
7413 /* early abort if no cliques are present */
7414 if( SCIPgetNCliques(scip) == 0 )
7415 {
7416 for( i = 0; i < nvars; ++i )
7417 cliquepartition[i] = i;
7418
7419 *ncliques = nvars;
7420
7421 return SCIP_OKAY;
7422 }
7423
7424 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &tmpvalues, nvars) );
7425 SCIP_CALL( SCIPsetDuplicateBufferArray(scip->set, &tmpvars, vars, nvars) );
7426 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &componentlabels, nvars) );
7427 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedindices, nvars) );
7428
7429 /* initialize the tmpvalues array */
7430 for( i = nvars - 1; i >= 0; --i )
7431 {
7432 tmpvalues[i] = TRUE;
7433 cliquepartition[i] = -1;
7434 }
7435
7436 /* get corresponding active problem variables */
7437 SCIP_CALL( SCIPvarsGetProbvarBinary(&tmpvars, &tmpvalues, nvars) );
7438
7439 ncomponents = -1;
7440
7441 /* update clique components if necessary */
7442 if( SCIPcliquetableNeedsComponentUpdate(scip->cliquetable) )
7443 {
7444 SCIP_VAR** allvars;
7445 int nallbinvars;
7446 int nallintvars;
7447 int nallimplvars;
7448
7449 SCIP_CALL( SCIPgetVarsData(scip, &allvars, NULL, &nallbinvars, &nallintvars, &nallimplvars, NULL) );
7450
7451 SCIP_CALL( SCIPcliquetableComputeCliqueComponents(scip->cliquetable, scip->set, SCIPblkmem(scip), allvars, nallbinvars, nallintvars, nallimplvars) );
7452 }
7453
7454 assert(!SCIPcliquetableNeedsComponentUpdate(scip->cliquetable));
7455
7456 /* store the global clique component labels */
7457 for( i = 0; i < nvars; ++i )
7458 {
7459 if( SCIPvarIsActive(tmpvars[i]) )
7460 componentlabels[i] = SCIPcliquetableGetVarComponentIdx(scip->cliquetable, tmpvars[i]);
7461 else
7462 componentlabels[i] = -1;
7463 }
7464
7465 /* relabel component labels order consistent as prerequisite for a stable sort */
7466 SCIP_CALL( relabelOrderConsistent(scip, componentlabels, nvars, &ncomponents) );
7467 assert(ncomponents >= 1);
7468 assert(ncomponents <= nvars);
7469
7470 /* allocate storage array for the starting positions of the components */
7471 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &componentstartposs, ncomponents + 1) );
7472
7473 /* stable sort the variables w.r.t. the component labels so that we can restrict the quadratic algorithm to the components */
7474 if( ncomponents > 1 )
7475 {
7476 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedtmpvars, nvars) );
7477 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedtmpvalues, nvars) );
7478 SCIP_CALL( labelSortStable(scip, tmpvars, componentlabels, sortedtmpvars, sortedindices, componentstartposs, nvars, ncomponents) );
7479
7480 /* reassign the tmpvalues with respect to the sorting */
7481 for( i = 0; i < nvars; ++i )
7482 {
7483 assert(tmpvars[sortedindices[i]] == sortedtmpvars[i]);
7484 sortedtmpvalues[i] = tmpvalues[sortedindices[i]];
7485 }
7486 }
7487 else
7488 {
7489 /* if we have only one large connected component, skip the stable sorting and prepare the data differently */
7490 sortedtmpvars = tmpvars;
7491 sortedtmpvalues = tmpvalues;
7492 componentstartposs[0] = 0;
7493 componentstartposs[1] = nvars;
7494
7495 /* sorted indices are the identity */
7496 for( i = 0; i < nvars; ++i )
7497 sortedindices[i] = i;
7498 }
7499
7500 *ncliques = 0;
7501 /* calculate a greedy clique partition for each connected component */
7502 for( c = 0; c < ncomponents; ++c )
7503 {
7504 int* localcliquepartition;
7505 int nlocalcliques;
7506 int ncomponentvars;
7507 int l;
7508
7509 /* extract the number of variables in this connected component */
7510 ncomponentvars = componentstartposs[c + 1] - componentstartposs[c];
7511 nlocalcliques = 0;
7512
7513 /* allocate necessary memory to hold the intermediate component clique partition */
7514 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &localcliquepartition, ncomponentvars) );
7515
7516 /* call greedy clique algorithm for all component variables */
7517 SCIP_CALL( calcCliquePartitionGreedy(scip, &(sortedtmpvars[componentstartposs[c]]), &(sortedtmpvalues[componentstartposs[c]]),
7518 ncomponentvars, localcliquepartition, &nlocalcliques) );
7519
7520 assert(nlocalcliques >= 1);
7521 assert(nlocalcliques <= ncomponentvars);
7522
7523 /* store the obtained clique partition with an offset of ncliques for the original variables */
7524 for( l = componentstartposs[c]; l < componentstartposs[c + 1]; ++l )
7525 {
7526 int origvaridx = sortedindices[l];
7527 assert(cliquepartition[origvaridx] == -1);
7528 assert(localcliquepartition[l - componentstartposs[c]] <= l - componentstartposs[c]);
7529 cliquepartition[origvaridx] = localcliquepartition[l - componentstartposs[c]] + (*ncliques);
7530 }
7531 *ncliques += nlocalcliques;
7532
7533 /* free the local clique partition */
7534 SCIPsetFreeBufferArray(scip->set, &localcliquepartition);
7535 }
7536
7537 /* except in the two trivial cases, we have to ensure the order consistency of the partition indices */
7538 if( ncomponents > 1 && ncomponents < nvars )
7539 {
7540 int partitionsize;
7541 SCIP_CALL( relabelOrderConsistent(scip, cliquepartition, nvars, &partitionsize) );
7542
7543 assert(partitionsize == *ncliques);
7544 }
7545
7546 if( ncomponents > 1 )
7547 {
7548 SCIPsetFreeBufferArray(scip->set, &sortedtmpvalues);
7549 SCIPsetFreeBufferArray(scip->set, &sortedtmpvars);
7550 }
7551
7552 /* use the greedy algorithm as a whole to verify the result on small number of variables */
7553#ifdef SCIP_DISABLED_CODE
7554 {
7555 int* debugcliquepartition;
7556 int ndebugcliques;
7557
7558 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &debugcliquepartition, nvars) );
7559
7560 /* call greedy clique algorithm for all component variables */
7561 SCIP_CALL( calcCliquePartitionGreedy(scip, tmpvars, tmpvalues, nvars, debugcliquepartition, &ndebugcliques) );
7562
7563 /* loop and compare the traditional greedy clique with */
7564 for( i = 0; i < nvars; ++i )
7565 assert(i * nvars > MAXNCLIQUEVARSCOMP || cliquepartition[i] == debugcliquepartition[i]);
7566
7567 SCIPsetFreeBufferArray(scip->set, &debugcliquepartition);
7568 }
7569#endif
7570
7571 /* free temporary memory */
7572 SCIPsetFreeBufferArray(scip->set, &componentstartposs);
7573 SCIPsetFreeBufferArray(scip->set, &sortedindices);
7574 SCIPsetFreeBufferArray(scip->set, &componentlabels);
7575 SCIPsetFreeBufferArray(scip->set, &tmpvars);
7576 SCIPsetFreeBufferArray(scip->set, &tmpvalues);
7577
7578 return SCIP_OKAY;
7579}
7580
7581/** calculates a partition of the given set of binary variables into negated cliques;
7582 * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7583 * were assigned to the same negated clique;
7584 * the first variable is always assigned to clique 0 and a variable can only be assigned to clique i if at least one of
7585 * the preceding variables was assigned to clique i-1;
7586 * for each clique with n_c variables at least n_c-1 variables can be set to TRUE in a feasible solution;
7587 *
7588 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7589 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7590 *
7591 * @pre This method can be called if @p scip is in one of the following stages:
7592 * - \ref SCIP_STAGE_INITPRESOLVE
7593 * - \ref SCIP_STAGE_PRESOLVING
7594 * - \ref SCIP_STAGE_EXITPRESOLVE
7595 * - \ref SCIP_STAGE_PRESOLVED
7596 * - \ref SCIP_STAGE_SOLVING
7597 */
7599 SCIP*const scip, /**< SCIP data structure */
7600 SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7601 int const nvars, /**< number of variables in the clique */
7602 int*const cliquepartition, /**< array of length nvars to store the clique partition */
7603 int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7604 )
7605{
7606 SCIP_VAR** negvars;
7607 int v;
7608
7609 assert(scip != NULL);
7610 assert(cliquepartition != NULL || nvars == 0);
7611 assert(ncliques != NULL);
7612
7613 if( nvars == 0 )
7614 {
7615 *ncliques = 0;
7616 return SCIP_OKAY;
7617 }
7618 assert(vars != NULL);
7619
7620 /* allocate temporary memory */
7621 SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &negvars, nvars) );
7622
7623 /* get all negated variables */
7624 for( v = nvars - 1; v >= 0; --v )
7625 {
7626 SCIP_CALL( SCIPgetNegatedVar(scip, vars[v], &(negvars[v])) );
7627 }
7628
7629 /* calculate cliques on negated variables, which are "negated" cliques on normal variables array */
7630 SCIP_CALL( SCIPcalcCliquePartition( scip, negvars, nvars, cliquepartition, ncliques) );
7631
7632 /* free temporary memory */
7633 SCIPsetFreeBufferArray(scip->set, &negvars);
7634
7635 return SCIP_OKAY;
7636}
7637
7638
7639/** force SCIP to clean up all cliques; cliques do not get automatically cleaned up after presolving. Use
7640 * this method to prevent inactive variables in cliques when retrieved via SCIPgetCliques()
7641 *
7642 * @return SCIP_OKAY if everything worked, otherwise a suitable error code is passed
7643 *
7644 * @pre This method can be called if @p scip is in one of the following stages:
7645 * - \ref SCIP_STAGE_TRANSFORMED
7646 * - \ref SCIP_STAGE_INITPRESOLVE
7647 * - \ref SCIP_STAGE_PRESOLVING
7648 * - \ref SCIP_STAGE_EXITPRESOLVE
7649 * - \ref SCIP_STAGE_PRESOLVED
7650 * - \ref SCIP_STAGE_INITSOLVE
7651 * - \ref SCIP_STAGE_SOLVING
7652 * - \ref SCIP_STAGE_SOLVED
7653 * - \ref SCIP_STAGE_EXITSOLVE
7654 */
7656 SCIP* scip, /**< SCIP data structure */
7657 SCIP_Bool* infeasible /**< pointer to store if cleanup detected infeasibility */
7658 )
7659{
7660 int nlocalbdchgs;
7661 SCIP_Bool globalinfeasibility;
7662
7663 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPcleanupCliques", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7664
7665 globalinfeasibility = FALSE;
7666 nlocalbdchgs = 0;
7667 SCIP_CALL( SCIPcliquetableCleanup(scip->cliquetable, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
7668 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, &nlocalbdchgs,
7669 &globalinfeasibility) );
7670
7671 if( infeasible != NULL )
7672 *infeasible = globalinfeasibility;
7673
7674 if( globalinfeasibility )
7675 scip->stat->status = SCIP_STATUS_INFEASIBLE;
7676
7677 return SCIP_OKAY;
7678}
7679
7680/** gets the number of cliques in the clique table
7681 *
7682 * @return number of cliques in the clique table
7683 *
7684 * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7685 * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
7686 *
7687 * @pre This method can be called if @p scip is in one of the following stages:
7688 * - \ref SCIP_STAGE_TRANSFORMED
7689 * - \ref SCIP_STAGE_INITPRESOLVE
7690 * - \ref SCIP_STAGE_PRESOLVING
7691 * - \ref SCIP_STAGE_EXITPRESOLVE
7692 * - \ref SCIP_STAGE_PRESOLVED
7693 * - \ref SCIP_STAGE_INITSOLVE
7694 * - \ref SCIP_STAGE_SOLVING
7695 * - \ref SCIP_STAGE_SOLVED
7696 * - \ref SCIP_STAGE_EXITSOLVE
7697 */
7699 SCIP* scip /**< SCIP data structure */
7700 )
7701{
7703
7704 return SCIPcliquetableGetNCliques(scip->cliquetable);
7705}
7706
7707/** gets the number of cliques created so far by the cliquetable
7708 *
7709 * @return number of cliques created so far by the cliquetable
7710 *
7711 * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7712 * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
7713 *
7714 * @pre This method can be called if @p scip is in one of the following stages:
7715 * - \ref SCIP_STAGE_TRANSFORMED
7716 * - \ref SCIP_STAGE_INITPRESOLVE
7717 * - \ref SCIP_STAGE_PRESOLVING
7718 * - \ref SCIP_STAGE_EXITPRESOLVE
7719 * - \ref SCIP_STAGE_PRESOLVED
7720 * - \ref SCIP_STAGE_INITSOLVE
7721 * - \ref SCIP_STAGE_SOLVING
7722 * - \ref SCIP_STAGE_SOLVED
7723 * - \ref SCIP_STAGE_EXITSOLVE
7724 */
7726 SCIP* scip /**< SCIP data structure */
7727 )
7728{
7729 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNCliquesCreated", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7730
7731 return SCIPcliquetableGetNCliquesCreated(scip->cliquetable);
7732}
7733
7734/** gets the array of cliques in the clique table
7735 *
7736 * @return array of cliques in the clique table
7737 *
7738 * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7739 * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
7740 *
7741 * @pre This method can be called if @p scip is in one of the following stages:
7742 * - \ref SCIP_STAGE_TRANSFORMED
7743 * - \ref SCIP_STAGE_INITPRESOLVE
7744 * - \ref SCIP_STAGE_PRESOLVING
7745 * - \ref SCIP_STAGE_EXITPRESOLVE
7746 * - \ref SCIP_STAGE_PRESOLVED
7747 * - \ref SCIP_STAGE_INITSOLVE
7748 * - \ref SCIP_STAGE_SOLVING
7749 * - \ref SCIP_STAGE_SOLVED
7750 * - \ref SCIP_STAGE_EXITSOLVE
7751 */
7753 SCIP* scip /**< SCIP data structure */
7754 )
7755{
7757
7758 return SCIPcliquetableGetCliques(scip->cliquetable);
7759}
7760
7761/** returns whether there is a clique that contains both given variable/value pairs;
7762 * the variables must be active binary variables;
7763 * if regardimplics is FALSE, only the cliques in the clique table are looked at;
7764 * if regardimplics is TRUE, both the cliques and the implications of the implication graph are regarded
7765 *
7766 * @return TRUE, if there is a clique that contains both variable/clique pairs; FALSE, otherwise
7767 *
7768 * @pre This method can be called if @p scip is in one of the following stages:
7769 * - \ref SCIP_STAGE_TRANSFORMED
7770 * - \ref SCIP_STAGE_INITPRESOLVE
7771 * - \ref SCIP_STAGE_PRESOLVING
7772 * - \ref SCIP_STAGE_EXITPRESOLVE
7773 * - \ref SCIP_STAGE_PRESOLVED
7774 * - \ref SCIP_STAGE_INITSOLVE
7775 * - \ref SCIP_STAGE_SOLVING
7776 * - \ref SCIP_STAGE_SOLVED
7777 * - \ref SCIP_STAGE_EXITSOLVE
7778 *
7779 * @note a variable with it's negated variable are NOT! in a clique
7780 * @note a variable with itself are in a clique
7781 */
7783 SCIP* scip, /**< SCIP data structure */
7784 SCIP_VAR* var1, /**< first variable */
7785 SCIP_Bool value1, /**< value of first variable */
7786 SCIP_VAR* var2, /**< second variable */
7787 SCIP_Bool value2, /**< value of second variable */
7788 SCIP_Bool regardimplics /**< should the implication graph also be searched for a clique? */
7789 )
7790{
7791 assert(scip != NULL);
7792 assert(var1 != NULL);
7793 assert(var2 != NULL);
7794 assert(SCIPvarIsActive(var1));
7795 assert(SCIPvarIsActive(var2));
7796 assert(SCIPvarIsBinary(var1));
7797 assert(SCIPvarIsBinary(var2));
7798
7799 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPhaveVarsCommonClique", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7800
7801 /* if both variables together have more cliques then actual cliques exist, then they have a common clique (in debug
7802 * mode we check this for correctness), otherwise we need to call the pairwise comparison method for these variables
7803 */
7804#ifndef NDEBUG
7805 assert((SCIPvarGetNCliques(var1, value1) + SCIPvarGetNCliques(var2, value2) > SCIPcliquetableGetNCliques(scip->cliquetable)) ? SCIPvarsHaveCommonClique(var1, value1, var2, value2, FALSE) : TRUE);
7806#endif
7807
7808 return (SCIPvarGetNCliques(var1, value1) + SCIPvarGetNCliques(var2, value2) > SCIPcliquetableGetNCliques(scip->cliquetable)
7809 || SCIPvarsHaveCommonClique(var1, value1, var2, value2, regardimplics));
7810}
7811
7812/** writes the clique graph to a gml file
7813 *
7814 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7815 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7816 *
7817 * @pre This method can be called if @p scip is in one of the following stages:
7818 * - \ref SCIP_STAGE_TRANSFORMED
7819 * - \ref SCIP_STAGE_INITPRESOLVE
7820 * - \ref SCIP_STAGE_PRESOLVING
7821 * - \ref SCIP_STAGE_EXITPRESOLVE
7822 * - \ref SCIP_STAGE_PRESOLVED
7823 * - \ref SCIP_STAGE_INITSOLVE
7824 * - \ref SCIP_STAGE_SOLVING
7825 * - \ref SCIP_STAGE_SOLVED
7826 * - \ref SCIP_STAGE_EXITSOLVE
7827 *
7828 * @note there can be duplicated arcs in the output file
7829 *
7830 * If @p writenodeweights is true, only nodes corresponding to variables that have a fractional value and only edges
7831 * between such nodes are written.
7832 */
7834 SCIP* scip, /**< SCIP data structure */
7835 const char* fname, /**< name of file */
7836 SCIP_Bool writenodeweights /**< should we write weights of nodes? */
7837 )
7838{
7839 FILE* gmlfile;
7840 SCIP_HASHMAP* nodehashmap;
7841 SCIP_CLIQUE** cliques;
7842 SCIP_VAR** clqvars;
7843 SCIP_VAR** allvars;
7844 SCIP_Bool* clqvalues;
7845 char nodename[SCIP_MAXSTRLEN];
7846 int nallvars;
7847 int nbinvars;
7848 int nintvars;
7849 int nimplvars;
7850 int ncliques;
7851 int c;
7852 int v1;
7853 int v2;
7854 int id1;
7855 int id2;
7856
7857 assert(scip != NULL);
7858 assert(fname != NULL);
7859
7860 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPwriteCliqueGraph", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7861
7862 /* get all active variables */
7863 SCIP_CALL( SCIPgetVarsData(scip, &allvars, &nallvars, &nbinvars, &nintvars, &nimplvars, NULL) );
7864
7865 /* no possible variables for cliques exist */
7866 if( nbinvars + nimplvars == 0 )
7867 return SCIP_OKAY;
7868
7869 ncliques = SCIPgetNCliques(scip);
7870
7871 /* no cliques and do not wont to check for binary implications */
7872 if( ncliques == 0 )
7873 return SCIP_OKAY;
7874
7875 /* open gml file */
7876 gmlfile = fopen(fname, "w");
7877
7878 if( gmlfile == NULL )
7879 {
7880 SCIPerrorMessage("cannot open graph file <%s>\n", fname);
7881 SCIPABORT();
7882 return SCIP_INVALIDDATA; /*lint !e527*/
7883 }
7884
7885 /* create the hash map */
7886 SCIP_CALL_FINALLY( SCIPhashmapCreate(&nodehashmap, SCIPblkmem(scip), nbinvars+nimplvars), fclose(gmlfile) );
7887
7888 /* write starting of gml file */
7889 SCIPgmlWriteOpening(gmlfile, TRUE);
7890
7891 cliques = SCIPgetCliques(scip);
7892
7893 /* write nodes and arcs for all cliques */
7894 for( c = ncliques - 1; c >= 0; --c )
7895 {
7896 clqvalues = SCIPcliqueGetValues(cliques[c]);
7897 clqvars = SCIPcliqueGetVars(cliques[c]);
7898
7899 for( v1 = SCIPcliqueGetNVars(cliques[c]) - 1; v1 >= 0; --v1 )
7900 {
7901 id1 = clqvalues[v1] ? SCIPvarGetProbindex(clqvars[v1]) : (nallvars + SCIPvarGetProbindex(clqvars[v1]));
7902
7903 /* if corresponding node was not added yet, add it */
7904 if( !SCIPhashmapExists(nodehashmap, (void*)(size_t)id1) )
7905 {
7906 assert(id1 >= 0);
7907 SCIP_CALL_FINALLY( SCIPhashmapInsertInt(nodehashmap, (void*)(size_t)id1, 1), fclose(gmlfile) ); /*lint !e571*/
7908
7909 (void) SCIPsnprintf(nodename, SCIP_MAXSTRLEN, "%s%s", (id1 >= nallvars ? "~" : ""), SCIPvarGetName(clqvars[v1]));
7910
7911 /* write new gml node for new variable */
7912 if ( writenodeweights )
7913 {
7914 if ( ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v1])) )
7915 SCIPgmlWriteNodeWeight(gmlfile, (unsigned int)id1, nodename, NULL, NULL, NULL, SCIPgetSolVal(scip, NULL, clqvars[v1]));
7916 }
7917 else
7918 {
7919 SCIPgmlWriteNode(gmlfile, (unsigned int)id1, nodename, NULL, NULL, NULL);
7920 }
7921 }
7922
7923 for( v2 = SCIPcliqueGetNVars(cliques[c]) - 1; v2 >= 0; --v2 )
7924 {
7925 if( v1 == v2 )
7926 continue;
7927
7928 id2 = clqvalues[v2] ? SCIPvarGetProbindex(clqvars[v2]) : (nallvars + SCIPvarGetProbindex(clqvars[v2]));
7929
7930 /* if corresponding node was not added yet, add it */
7931 if( !SCIPhashmapExists(nodehashmap, (void*)(size_t)id2) )
7932 {
7933 assert(id2 >= 0);
7934 SCIP_CALL_FINALLY( SCIPhashmapInsertInt(nodehashmap, (void*)(size_t)id2, 1), fclose(gmlfile) ); /*lint !e571*/
7935
7936 (void) SCIPsnprintf(nodename, SCIP_MAXSTRLEN, "%s%s", (id2 >= nallvars ? "~" : ""), SCIPvarGetName(clqvars[v2]));
7937
7938 /* write new gml node for new variable */
7939 if ( writenodeweights )
7940 {
7941 if ( ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v2])) )
7942 SCIPgmlWriteNodeWeight(gmlfile, (unsigned int)id2, nodename, NULL, NULL, NULL, SCIPgetSolVal(scip, NULL, clqvars[v2]));
7943 }
7944 else
7945 {
7946 SCIPgmlWriteNode(gmlfile, (unsigned int)id2, nodename, NULL, NULL, NULL);
7947 }
7948 }
7949
7950 /* write gml arc between resultant and operand */
7951 if ( ! writenodeweights || ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v2])) )
7952 SCIPgmlWriteArc(gmlfile, (unsigned int)id1, (unsigned int)id2, NULL, NULL);
7953 }
7954 }
7955 }
7956
7957 /* free the hash map */
7958 SCIPhashmapFree(&nodehashmap);
7959
7960 SCIPgmlWriteClosing(gmlfile);
7961 fclose(gmlfile);
7962
7963 return SCIP_OKAY;
7964}
7965
7966/** Removes (irrelevant) variable from all its global structures, i.e. cliques, implications and variable bounds.
7967 * This is an advanced method which should be used with care.
7968 *
7969 * @return SCIP_OKAY if everything worked, otherwise a suitable error code is passed
7970 *
7971 * @pre This method can be called if @p scip is in one of the following stages:
7972 * - \ref SCIP_STAGE_TRANSFORMED
7973 * - \ref SCIP_STAGE_INITPRESOLVE
7974 * - \ref SCIP_STAGE_PRESOLVING
7975 * - \ref SCIP_STAGE_EXITPRESOLVE
7976 * - \ref SCIP_STAGE_PRESOLVED
7977 * - \ref SCIP_STAGE_INITSOLVE
7978 * - \ref SCIP_STAGE_SOLVING
7979 * - \ref SCIP_STAGE_SOLVED
7980 * - \ref SCIP_STAGE_EXITSOLVE
7981 */
7983 SCIP* scip, /**< SCIP data structure */
7984 SCIP_VAR* var /**< variable to remove from global structures */
7985 )
7986{
7987 assert(scip != NULL);
7988
7989 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPremoveVarFromGlobalStructures", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7990
7991 /* mark the variable as deletable from global structures - This is necessary for the delayed clean up of cliques */
7993
7994 /* remove variable from all its cliques, implications, and variable bounds */
7996
7997 return SCIP_OKAY;
7998}
7999
8000/** sets the branch factor of the variable; this value can be used in the branching methods to scale the score
8001 * values of the variables; higher factor leads to a higher probability that this variable is chosen for branching
8002 *
8003 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8004 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8005 *
8006 * @pre This method can be called if @p scip is in one of the following stages:
8007 * - \ref SCIP_STAGE_PROBLEM
8008 * - \ref SCIP_STAGE_TRANSFORMING
8009 * - \ref SCIP_STAGE_TRANSFORMED
8010 * - \ref SCIP_STAGE_INITPRESOLVE
8011 * - \ref SCIP_STAGE_PRESOLVING
8012 * - \ref SCIP_STAGE_EXITPRESOLVE
8013 * - \ref SCIP_STAGE_PRESOLVED
8014 * - \ref SCIP_STAGE_SOLVING
8015 */
8017 SCIP* scip, /**< SCIP data structure */
8018 SCIP_VAR* var, /**< problem variable */
8019 SCIP_Real branchfactor /**< factor to weigh variable's branching score with */
8020 )
8021{
8022 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8023
8024 SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, branchfactor) );
8025
8026 return SCIP_OKAY;
8027}
8028
8029/** scales the branch factor of the variable with the given value
8030 *
8031 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8032 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8033 *
8034 * @pre This method can be called if @p scip is in one of the following stages:
8035 * - \ref SCIP_STAGE_PROBLEM
8036 * - \ref SCIP_STAGE_TRANSFORMING
8037 * - \ref SCIP_STAGE_TRANSFORMED
8038 * - \ref SCIP_STAGE_INITPRESOLVE
8039 * - \ref SCIP_STAGE_PRESOLVING
8040 * - \ref SCIP_STAGE_EXITPRESOLVE
8041 * - \ref SCIP_STAGE_PRESOLVED
8042 * - \ref SCIP_STAGE_SOLVING
8043 */
8045 SCIP* scip, /**< SCIP data structure */
8046 SCIP_VAR* var, /**< problem variable */
8047 SCIP_Real scale /**< factor to scale variable's branching factor with */
8048 )
8049{
8050 SCIP_CALL( SCIPcheckStage(scip, "SCIPscaleVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8051
8052 SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, scale * SCIPvarGetBranchFactor(var)) );
8053
8054 return SCIP_OKAY;
8055}
8056
8057/** adds the given value to the branch factor of the variable
8058 *
8059 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8060 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8061 *
8062 * @pre This method can be called if @p scip is in one of the following stages:
8063 * - \ref SCIP_STAGE_PROBLEM
8064 * - \ref SCIP_STAGE_TRANSFORMING
8065 * - \ref SCIP_STAGE_TRANSFORMED
8066 * - \ref SCIP_STAGE_INITPRESOLVE
8067 * - \ref SCIP_STAGE_PRESOLVING
8068 * - \ref SCIP_STAGE_EXITPRESOLVE
8069 * - \ref SCIP_STAGE_PRESOLVED
8070 * - \ref SCIP_STAGE_SOLVING
8071 */
8073 SCIP* scip, /**< SCIP data structure */
8074 SCIP_VAR* var, /**< problem variable */
8075 SCIP_Real addfactor /**< value to add to the branch factor of the variable */
8076 )
8077{
8078 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8079
8080 SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, addfactor + SCIPvarGetBranchFactor(var)) );
8081
8082 return SCIP_OKAY;
8083}
8084
8085/** sets the branch priority of the variable; variables with higher branch priority are always preferred to variables
8086 * with lower priority in selection of branching variable
8087 *
8088 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8089 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8090 *
8091 * @pre This method can be called if @p scip is in one of the following stages:
8092 * - \ref SCIP_STAGE_PROBLEM
8093 * - \ref SCIP_STAGE_TRANSFORMING
8094 * - \ref SCIP_STAGE_TRANSFORMED
8095 * - \ref SCIP_STAGE_INITPRESOLVE
8096 * - \ref SCIP_STAGE_PRESOLVING
8097 * - \ref SCIP_STAGE_EXITPRESOLVE
8098 * - \ref SCIP_STAGE_PRESOLVED
8099 * - \ref SCIP_STAGE_SOLVING
8100 *
8101 * @note the default branching priority is 0
8102 */
8104 SCIP* scip, /**< SCIP data structure */
8105 SCIP_VAR* var, /**< problem variable */
8106 int branchpriority /**< branch priority of the variable */
8107 )
8108{
8109 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8110
8111 assert( var->scip == scip );
8112
8113 if( SCIPisTransformed(scip) )
8114 {
8115 assert(scip->branchcand != NULL);
8116
8117 /* inform the pseudo branch candidates that the branch priority changes and change the branch priority */
8118 SCIP_CALL( SCIPbranchcandUpdateVarBranchPriority(scip->branchcand, scip->set, var, branchpriority) );
8119 }
8120 else
8121 {
8122 /* change the branching priority of the variable */
8123 SCIP_CALL( SCIPvarChgBranchPriority(var, branchpriority) );
8124 }
8125
8126 return SCIP_OKAY;
8127}
8128
8129/** changes the branch priority of the variable to the given value, if it is larger than the current priority
8130 *
8131 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8132 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8133 *
8134 * @pre This method can be called if @p scip is in one of the following stages:
8135 * - \ref SCIP_STAGE_PROBLEM
8136 * - \ref SCIP_STAGE_TRANSFORMING
8137 * - \ref SCIP_STAGE_TRANSFORMED
8138 * - \ref SCIP_STAGE_INITPRESOLVE
8139 * - \ref SCIP_STAGE_PRESOLVING
8140 * - \ref SCIP_STAGE_EXITPRESOLVE
8141 * - \ref SCIP_STAGE_PRESOLVED
8142 * - \ref SCIP_STAGE_SOLVING
8143 */
8145 SCIP* scip, /**< SCIP data structure */
8146 SCIP_VAR* var, /**< problem variable */
8147 int branchpriority /**< new branch priority of the variable, if it is larger than current priority */
8148 )
8149{
8150 SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8151
8152 assert( var->scip == scip );
8153
8154 if( branchpriority > SCIPvarGetBranchPriority(var) )
8155 {
8156 SCIP_CALL( SCIPvarChgBranchPriority(var, branchpriority) );
8157 }
8158
8159 return SCIP_OKAY;
8160}
8161
8162/** adds the given value to the branch priority of the variable
8163 *
8164 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8165 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8166 *
8167 * @pre This method can be called if @p scip is in one of the following stages:
8168 * - \ref SCIP_STAGE_PROBLEM
8169 * - \ref SCIP_STAGE_TRANSFORMING
8170 * - \ref SCIP_STAGE_TRANSFORMED
8171 * - \ref SCIP_STAGE_INITPRESOLVE
8172 * - \ref SCIP_STAGE_PRESOLVING
8173 * - \ref SCIP_STAGE_EXITPRESOLVE
8174 * - \ref SCIP_STAGE_PRESOLVED
8175 * - \ref SCIP_STAGE_SOLVING
8176 */
8178 SCIP* scip, /**< SCIP data structure */
8179 SCIP_VAR* var, /**< problem variable */
8180 int addpriority /**< value to add to the branch priority of the variable */
8181 )
8182{
8183 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8184
8185 assert( var->scip == scip );
8186
8188
8189 return SCIP_OKAY;
8190}
8191
8192/** sets the branch direction of the variable (-1: prefer downwards branch, 0: automatic selection, +1: prefer upwards
8193 * branch)
8194 *
8195 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8196 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8197 *
8198 * @pre This method can be called if @p scip is in one of the following stages:
8199 * - \ref SCIP_STAGE_PROBLEM
8200 * - \ref SCIP_STAGE_TRANSFORMING
8201 * - \ref SCIP_STAGE_TRANSFORMED
8202 * - \ref SCIP_STAGE_INITPRESOLVE
8203 * - \ref SCIP_STAGE_PRESOLVING
8204 * - \ref SCIP_STAGE_EXITPRESOLVE
8205 * - \ref SCIP_STAGE_PRESOLVED
8206 * - \ref SCIP_STAGE_SOLVING
8207 */
8209 SCIP* scip, /**< SCIP data structure */
8210 SCIP_VAR* var, /**< problem variable */
8211 SCIP_BRANCHDIR branchdirection /**< preferred branch direction of the variable (downwards, upwards, auto) */
8212 )
8213{
8214 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchDirection", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8215
8216 assert( var->scip == scip );
8217
8218 SCIP_CALL( SCIPvarChgBranchDirection(var, branchdirection) );
8219
8220 return SCIP_OKAY;
8221}
8222
8223/** tightens the variable bounds due to a new variable type */
8224static
8226 SCIP* scip, /**< SCIP data structure */
8227 SCIP_VAR* var, /**< variable to change the bound for */
8228 SCIP_VARTYPE vartype, /**< new type of variable */
8229 SCIP_Bool* infeasible /**< pointer to store whether an infeasibility was detected (, due to
8230 * integrality condition of the new variable type) */
8231 )
8232{
8233 assert(scip != NULL);
8235 assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPvarIsTransformed(var));
8236 assert(var->scip == scip);
8237
8238 *infeasible = FALSE;
8239
8240 /* adjusts bounds if the variable type changed form continuous to non-continuous (integral) */
8242 {
8243 SCIP_Bool tightened;
8244
8245 /* we adjust variable bounds to integers first, since otherwise a later bound tightening with a fractional old
8246 * bound may give an assert because SCIP expects non-continuous variables to have non-fractional bounds
8247 *
8248 * we adjust bounds with a fractionality within [eps,feastol] only if the resulting bound change is a bound
8249 * tightening, because relaxing bounds may not be allowed
8250 */
8255 )
8256 {
8257 SCIP_CALL( SCIPtightenVarLbGlobal(scip, var, SCIPfeasCeil(scip, SCIPvarGetLbGlobal(var)), TRUE, infeasible, &tightened) );
8258 if( *infeasible )
8259 return SCIP_OKAY;
8260
8261 /* 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
8262 * 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
8263 */
8264 assert(tightened || SCIPisFeasLE(scip, SCIPvarGetUbGlobal(var), SCIPfeasCeil(scip, SCIPvarGetLbGlobal(var))));
8265 }
8268 )
8269 {
8270 SCIP_CALL( SCIPtightenVarUbGlobal(scip, var, SCIPfeasFloor(scip, SCIPvarGetUbGlobal(var)), TRUE, infeasible, &tightened) );
8271 if( *infeasible )
8272 return SCIP_OKAY;
8273
8274 assert(tightened || SCIPisFeasGE(scip, SCIPvarGetLbGlobal(var), SCIPfeasFloor(scip, SCIPvarGetUbGlobal(var))));
8275 }
8276 }
8277
8278 return SCIP_OKAY;
8279}
8280
8281/** changes type of variable in the problem;
8282 *
8283 * @warning This type change might change the variable array returned from SCIPgetVars() and SCIPgetVarsData();
8284 *
8285 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8286 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8287 *
8288 * @pre This method can be called if @p scip is in one of the following stages:
8289 * - \ref SCIP_STAGE_PROBLEM
8290 * - \ref SCIP_STAGE_TRANSFORMING
8291 * - \ref SCIP_STAGE_PRESOLVING
8292 *
8293 * @note If SCIP is already beyond the SCIP_STAGE_PROBLEM and a original variable is passed, the variable type of the
8294 * corresponding transformed variable is changed; the type of the original variable does not change
8295 *
8296 * @note If the type changes from a continuous variable to a non-continuous variable the bounds of the variable get
8297 * adjusted w.r.t. to integrality information
8298 */
8300 SCIP* scip, /**< SCIP data structure */
8301 SCIP_VAR* var, /**< variable to change the bound for */
8302 SCIP_VARTYPE vartype, /**< new type of variable */
8303 SCIP_Bool* infeasible /**< pointer to store whether an infeasibility was detected (, due to
8304 * integrality condition of the new variable type) */
8305 )
8306{
8308
8309 assert(var != NULL);
8310 assert(var->scip == scip);
8311
8312 if( SCIPvarIsNegated(var) )
8313 {
8314 SCIPdebugMsg(scip, "upgrading type of negated variable <%s> from %d to %d\n", SCIPvarGetName(var), SCIPvarGetType(var), vartype);
8315 var = SCIPvarGetNegationVar(var);
8316 }
8317#ifndef NDEBUG
8318 else
8319 {
8321 {
8322 SCIPdebugMsg(scip, "upgrading type of variable <%s> from %d to %d\n", SCIPvarGetName(var), SCIPvarGetType(var), vartype);
8323 }
8324 }
8325#endif
8326
8327 /* change variable type */
8328 switch( scip->set->stage )
8329 {
8330 case SCIP_STAGE_PROBLEM:
8331 assert(!SCIPvarIsTransformed(var));
8332
8333 /* first adjust the variable due to new integrality information */
8334 SCIP_CALL( tightenBounds(scip, var, vartype, infeasible) );
8335
8336 /* second change variable type */
8337 if( SCIPvarGetProbindex(var) >= 0 )
8338 {
8339 SCIP_CALL( SCIPprobChgVarType(scip->origprob, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8340 scip->branchcand, scip->eventqueue, scip->cliquetable, var, vartype) );
8341 }
8342 else
8343 {
8344 SCIP_CALL( SCIPvarChgType(var, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8345 scip->eventqueue, vartype) );
8346 }
8347 break;
8348
8350 if( !SCIPvarIsTransformed(var) )
8351 {
8352 SCIP_VAR* transvar;
8353
8354 SCIP_CALL( SCIPgetTransformedVar(scip, var, &transvar) );
8355 assert(transvar != NULL);
8356
8357 /* recall method with transformed variable */
8358 SCIP_CALL( SCIPchgVarType(scip, transvar, vartype, infeasible) );
8359 return SCIP_OKAY;
8360 }
8361
8362 /* first adjust the variable due to new integrality information */
8363 SCIP_CALL( tightenBounds(scip, var, vartype, infeasible) );
8364
8365 /* second change variable type */
8366 if( SCIPvarGetProbindex(var) >= 0 )
8367 {
8368 SCIP_CALL( SCIPprobChgVarType(scip->transprob, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8369 scip->branchcand, scip->eventqueue, scip->cliquetable, var, vartype) );
8370 }
8371 else
8372 {
8373 SCIP_CALL( SCIPvarChgType(var, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8374 scip->eventqueue, vartype) );
8375 }
8376 break;
8377
8378 default:
8379 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
8380 return SCIP_INVALIDCALL;
8381 } /*lint !e788*/
8382
8383 return SCIP_OKAY;
8384}
8385
8386/** in problem creation and solving stage, both bounds of the variable are set to the given value;
8387 * in presolving stage, the variable is converted into a fixed variable, and bounds are changed respectively;
8388 * conversion into a fixed variable changes the vars array returned from SCIPgetVars() and SCIPgetVarsData(),
8389 * and also renders arrays returned from the SCIPvarGetImpl...() methods invalid
8390 *
8391 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8392 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8393 *
8394 * @pre This method can be called if @p scip is in one of the following stages:
8395 * - \ref SCIP_STAGE_PROBLEM
8396 * - \ref SCIP_STAGE_PRESOLVING
8397 * - \ref SCIP_STAGE_SOLVING
8398 */
8400 SCIP* scip, /**< SCIP data structure */
8401 SCIP_VAR* var, /**< variable to fix */
8402 SCIP_Real fixedval, /**< value to fix variable to */
8403 SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
8404 SCIP_Bool* fixed /**< pointer to store whether the fixing was performed (variable was unfixed) */
8405 )
8406{
8407 assert(var != NULL);
8408 assert(infeasible != NULL);
8409 assert(fixed != NULL);
8410
8412
8413 *infeasible = FALSE;
8414 *fixed = FALSE;
8415
8416 /* in the problem creation stage, modify the bounds as requested, independently from the current bounds */
8417 if( scip->set->stage != SCIP_STAGE_PROBLEM )
8418 {
8419 if( (SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPsetIsFeasIntegral(scip->set, fixedval))
8420 || SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetLbLocal(var))
8421 || SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8422 {
8423 *infeasible = TRUE;
8424 return SCIP_OKAY;
8425 }
8426 else if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED )
8427 {
8428 *infeasible = !SCIPsetIsFeasEQ(scip->set, fixedval, SCIPvarGetLbLocal(var));
8429 return SCIP_OKAY;
8430 }
8431 }
8432 else
8434
8435 switch( scip->set->stage )
8436 {
8437 case SCIP_STAGE_PROBLEM:
8438 /* in the problem creation stage, modify the bounds as requested, independently from the current bounds;
8439 * we have to make sure, that the order of the bound changes does not intermediately produce an invalid
8440 * interval lb > ub
8441 */
8442 if( fixedval <= SCIPvarGetLbLocal(var) )
8443 {
8444 SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
8445 SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
8446 *fixed = TRUE;
8447 }
8448 else
8449 {
8450 SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
8451 SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
8452 *fixed = TRUE;
8453 }
8454 return SCIP_OKAY;
8455
8457 if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
8458 {
8459 SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8460 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8461 scip->cliquetable, fixedval, infeasible, fixed) );
8462 return SCIP_OKAY;
8463 }
8464 /*lint -fallthrough*/
8465 case SCIP_STAGE_SOLVING:
8466 if( SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetLbLocal(var)) )
8467 {
8468 if( SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8469 {
8470 *infeasible = TRUE;
8471 return SCIP_OKAY;
8472 }
8473 else
8474 {
8475 SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
8476 *fixed = TRUE;
8477 }
8478 }
8479 if( SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8480 {
8481 if( SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetLbLocal(var)) )
8482 {
8483 *infeasible = TRUE;
8484 return SCIP_OKAY;
8485 }
8486 else
8487 {
8488 SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
8489 *fixed = TRUE;
8490 }
8491 }
8492 return SCIP_OKAY;
8493
8494 default:
8495 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
8496 return SCIP_INVALIDCALL;
8497 } /*lint !e788*/
8498}
8499
8500/** From a given equality a*x + b*y == c, aggregates one of the variables and removes it from the set of
8501 * active problem variables. This changes the vars array returned from SCIPgetVars() and SCIPgetVarsData(),
8502 * and also renders the arrays returned from the SCIPvarGetImpl...() methods for the two variables invalid.
8503 * In the first step, the equality is transformed into an equality with active problem variables
8504 * a'*x' + b'*y' == c'. If x' == y', this leads to the detection of redundancy if a' == -b' and c' == 0,
8505 * of infeasibility, if a' == -b' and c' != 0, or to a variable fixing x' == c'/(a'+b') (and possible
8506 * infeasibility) otherwise.
8507 * In the second step, the variable to be aggregated is chosen among x' and y', prefering a less strict variable
8508 * type as aggregation variable (i.e. continuous variables are preferred over implicit integers, implicit integers
8509 * over integers, and integers over binaries). If none of the variables is continuous, it is tried to find an integer
8510 * aggregation (i.e. integral coefficients a'' and b'', such that a''*x' + b''*y' == c''). This can lead to
8511 * the detection of infeasibility (e.g. if c'' is fractional), or to a rejection of the aggregation (denoted by
8512 * aggregated == FALSE), if the resulting integer coefficients are too large and thus numerically instable.
8513 *
8514 * The output flags have the following meaning:
8515 * - infeasible: the problem is infeasible
8516 * - redundant: the equality can be deleted from the constraint set
8517 * - aggregated: the aggregation was successfully performed (the variables were not aggregated before)
8518 *
8519 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8520 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8521 *
8522 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PRESOLVING
8523 */
8525 SCIP* scip, /**< SCIP data structure */
8526 SCIP_VAR* varx, /**< variable x in equality a*x + b*y == c */
8527 SCIP_VAR* vary, /**< variable y in equality a*x + b*y == c */
8528 SCIP_Real scalarx, /**< multiplier a in equality a*x + b*y == c */
8529 SCIP_Real scalary, /**< multiplier b in equality a*x + b*y == c */
8530 SCIP_Real rhs, /**< right hand side c in equality a*x + b*y == c */
8531 SCIP_Bool* infeasible, /**< pointer to store whether the aggregation is infeasible */
8532 SCIP_Bool* redundant, /**< pointer to store whether the equality is (now) redundant */
8533 SCIP_Bool* aggregated /**< pointer to store whether the aggregation was successful */
8534 )
8535{
8536 SCIP_Real constantx;
8537 SCIP_Real constanty;
8538
8539 assert(infeasible != NULL);
8540 assert(redundant != NULL);
8541 assert(aggregated != NULL);
8542
8544
8545 *infeasible = FALSE;
8546 *redundant = FALSE;
8547 *aggregated = FALSE;
8548
8549 if( SCIPtreeProbing(scip->tree) )
8550 {
8551 SCIPerrorMessage("cannot aggregate variables during probing\n");
8552 return SCIP_INVALIDCALL;
8553 }
8554 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
8555
8556 /* do not perform aggregation if it is globally deactivated */
8557 if( scip->set->presol_donotaggr )
8558 return SCIP_OKAY;
8559
8560 /* get the corresponding equality in active problem variable space:
8561 * transform both expressions "a*x + 0" and "b*y + 0" into problem variable space
8562 */
8563 constantx = 0.0;
8564 constanty = 0.0;
8565 SCIP_CALL( SCIPvarGetProbvarSum(&varx, scip->set, &scalarx, &constantx) );
8566 SCIP_CALL( SCIPvarGetProbvarSum(&vary, scip->set, &scalary, &constanty) );
8567
8568 /* we cannot aggregate multi-aggregated variables */
8570 return SCIP_OKAY;
8571
8572 /* move the constant to the right hand side to acquire the form "a'*x' + b'*y' == c'" */
8573 rhs -= (constantx + constanty);
8574
8575 /* if a scalar is zero, treat the variable as fixed-to-zero variable */
8576 if( SCIPsetIsZero(scip->set, scalarx) )
8577 varx = NULL;
8578 if( SCIPsetIsZero(scip->set, scalary) )
8579 vary = NULL;
8580
8581 /* capture the special cases that less than two variables are left, due to resolutions to a fixed variable or
8582 * to the same active variable
8583 */
8584 if( varx == NULL && vary == NULL )
8585 {
8586 /* both variables were resolved to fixed variables */
8587 *infeasible = !SCIPsetIsZero(scip->set, rhs);
8588 *redundant = TRUE;
8589 }
8590 else if( varx == NULL )
8591 {
8592 assert(SCIPsetIsZero(scip->set, scalarx));
8593 assert(!SCIPsetIsZero(scip->set, scalary));
8594
8595 /* variable x was resolved to fixed variable: variable y can be fixed to c'/b' */
8596 SCIP_CALL( SCIPvarFix(vary, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8597 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8598 scip->cliquetable, rhs/scalary, infeasible, aggregated) );
8599 *redundant = TRUE;
8600 }
8601 else if( vary == NULL )
8602 {
8603 assert(SCIPsetIsZero(scip->set, scalary));
8604 assert(!SCIPsetIsZero(scip->set, scalarx));
8605
8606 /* variable y was resolved to fixed variable: variable x can be fixed to c'/a' */
8607 SCIP_CALL( SCIPvarFix(varx, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8608 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8609 scip->cliquetable, rhs/scalarx, infeasible, aggregated) );
8610 *redundant = TRUE;
8611 }
8612 else if( varx == vary )
8613 {
8614 /* both variables were resolved to the same active problem variable: this variable can be fixed */
8615 scalarx += scalary;
8616 if( SCIPsetIsZero(scip->set, scalarx) )
8617 {
8618 /* left hand side of equality is zero: equality is potentially infeasible */
8619 *infeasible = !SCIPsetIsZero(scip->set, rhs);
8620 }
8621 else
8622 {
8623 /* sum of scalars is not zero: fix variable x' == y' to c'/(a'+b') */
8624 SCIP_CALL( SCIPvarFix(varx, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8625 scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8626 scip->cliquetable, rhs/scalarx, infeasible, aggregated) );
8627 }
8628 *redundant = TRUE;
8629 }
8630 else
8631 {
8632 /* both variables are different active problem variables, and both scalars are non-zero: try to aggregate them */
8633 SCIP_CALL( SCIPvarTryAggregateVars(scip->set, scip->mem->probmem, scip->stat, scip->transprob, scip->origprob,
8634 scip->primal, scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventfilter,
8635 scip->eventqueue, varx, vary, scalarx, scalary, rhs, infeasible, aggregated) );
8636 *redundant = *aggregated;
8637 }
8638
8639 return SCIP_OKAY;
8640}
8641
8642/** converts variable into multi-aggregated variable; this changes the variable array returned from
8643 * SCIPgetVars() and SCIPgetVarsData();
8644 *
8645 * @warning The integrality condition is not checked anymore on the multi-aggregated variable. You must not
8646 * multi-aggregate an integer variable without being sure, that integrality on the aggregation variables
8647 * implies integrality on the aggregated variable.
8648 *
8649 * The output flags have the following meaning:
8650 * - infeasible: the problem is infeasible
8651 * - aggregated: the aggregation was successfully performed (the variables were not aggregated before)
8652 *
8653 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8654 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8655 *
8656 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PRESOLVING
8657 */
8659 SCIP* scip, /**< SCIP data structure */
8660 SCIP_VAR* var, /**< variable x to aggregate */
8661 int naggvars, /**< number n of variables in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8662 SCIP_VAR** aggvars, /**< variables y_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8663 SCIP_Real* scalars, /**< multipliers a_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8664 SCIP_Real constant, /**< constant shift c in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8665 SCIP_Bool* infeasible, /**< pointer to store whether the aggregation is infeasible */
8666 SCIP_Bool* aggregated /**< pointer to store whether the aggregation was successful */
8667 )
8668{
8669 SCIP_CALL( SCIPcheckStage(scip, "SCIPmultiaggregateVar", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
8670
8671 assert(var->scip == scip);
8672
8673 if( SCIPtreeProbing(scip->tree) )
8674 {
8675 SCIPerrorMessage("cannot multi-aggregate variables during probing\n");
8676 return SCIP_INVALIDCALL;
8677 }
8678 assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
8679
8680 SCIP_CALL( SCIPvarMultiaggregate(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8681 scip->primal, scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventfilter,
8682 scip->eventqueue, naggvars, aggvars, scalars, constant, infeasible, aggregated) );
8683
8684 return SCIP_OKAY;
8685}
8686
8687/** returns whether aggregation of variables is not allowed */
8689 SCIP* scip /**< SCIP data structure */
8690 )
8691{
8692 assert(scip != NULL);
8693
8694 return scip->set->presol_donotaggr;
8695}
8696
8697/** returns whether multi-aggregation is disabled */
8699 SCIP* scip /**< SCIP data structure */
8700 )
8701{
8702 assert(scip != NULL);
8703
8704 return scip->set->presol_donotmultaggr;
8705}
8706
8707/** returns whether variable is not allowed to be aggregated */
8709 SCIP* scip, /**< SCIP data structure */
8710 SCIP_VAR* var /**< variable x to aggregate */
8711 )
8712{
8713 assert(scip != NULL);
8714 assert(var != NULL);
8715 assert(var->scip == scip);
8716
8717 return scip->set->presol_donotaggr || SCIPvarDoNotAggr(var);
8718}
8719
8720/** returns whether variable is not allowed to be multi-aggregated */
8722 SCIP* scip, /**< SCIP data structure */
8723 SCIP_VAR* var /**< variable x to aggregate */
8724 )
8725{
8726 assert(scip != NULL);
8727 assert(var != NULL);
8728 assert(var->scip == scip);
8729
8730 return scip->set->presol_donotmultaggr || SCIPvarDoNotMultaggr(var);
8731}
8732
8733/** returns whether dual reductions are allowed during propagation and presolving
8734 *
8735 * @deprecated Please use SCIPallowStrongDualReds()
8736 */
8738 SCIP* scip /**< SCIP data structure */
8739 )
8740{
8741 assert(scip != NULL);
8742
8743 return !scip->set->reopt_enable && scip->set->misc_allowstrongdualreds;
8744}
8745
8746/** returns whether strong dual reductions are allowed during propagation and presolving
8747 *
8748 * @note A reduction is called strong dual, if it may discard feasible/optimal solutions, but leaves at least one
8749 * optimal solution intact. Often such reductions are based on analyzing the objective function and variable
8750 * locks.
8751 */
8753 SCIP* scip /**< SCIP data structure */
8754 )
8755{
8756 assert(scip != NULL);
8757
8758 return !scip->set->reopt_enable && scip->set->misc_allowstrongdualreds;
8759}
8760
8761/** returns whether propagation w.r.t. current objective is allowed
8762 *
8763 * @deprecated Please use SCIPallowWeakDualReds()
8764 */
8766 SCIP* scip /**< SCIP data structure */
8767 )
8768{
8769 assert(scip != NULL);
8770
8771 return !scip->set->reopt_enable && scip->set->misc_allowweakdualreds;
8772}
8773
8774/** returns whether weak dual reductions are allowed during propagation and presolving
8775 *
8776 * @note A reduction is called weak dual, if it may discard feasible solutions, but leaves at all optimal solutions
8777 * intact. Often such reductions are based on analyzing the objective function, reduced costs, and/or dual LPs.
8778 */
8780 SCIP* scip /**< SCIP data structure */
8781 )
8782{
8783 assert(scip != NULL);
8784
8785 return !scip->set->reopt_enable && scip->set->misc_allowweakdualreds;
8786}
8787
8788/** marks the variable that it must not be aggregated
8789 *
8790 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8791 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8792 *
8793 * @pre This method can be called if @p scip is in one of the following stages:
8794 * - \ref SCIP_STAGE_INIT
8795 * - \ref SCIP_STAGE_PROBLEM
8796 * - \ref SCIP_STAGE_TRANSFORMING
8797 * - \ref SCIP_STAGE_TRANSFORMED
8798 * - \ref SCIP_STAGE_INITPRESOLVE
8799 * - \ref SCIP_STAGE_PRESOLVING
8800 * - \ref SCIP_STAGE_EXITPRESOLVE
8801 *
8802 * @note There exists no "unmark" method since it has to be ensured that if a plugin requires that a variable is not
8803 * aggregated that this is will be the case.
8804 */
8806 SCIP* scip, /**< SCIP data structure */
8807 SCIP_VAR* var /**< variable to delete */
8808 )
8809{
8810 assert(scip != NULL);
8811 assert(var != NULL);
8812 assert(var->scip == scip);
8813
8814 SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkDoNotAggrVar", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE) );
8815
8817
8818 return SCIP_OKAY;
8819}
8820
8821/** marks the variable that it must not be multi-aggregated
8822 *
8823 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8824 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8825 *
8826 * @pre This method can be called if @p scip is in one of the following stages:
8827 * - \ref SCIP_STAGE_INIT
8828 * - \ref SCIP_STAGE_PROBLEM
8829 * - \ref SCIP_STAGE_TRANSFORMING
8830 * - \ref SCIP_STAGE_TRANSFORMED
8831 * - \ref SCIP_STAGE_INITPRESOLVE
8832 * - \ref SCIP_STAGE_PRESOLVING
8833 * - \ref SCIP_STAGE_EXITPRESOLVE
8834 *
8835 * @note There exists no "unmark" method since it has to be ensured that if a plugin requires that a variable is not
8836 * multi-aggregated that this is will be the case.
8837 */
8839 SCIP* scip, /**< SCIP data structure */
8840 SCIP_VAR* var /**< variable to delete */
8841 )
8842{
8843 assert(scip != NULL);
8844 assert(var != NULL);
8845 assert(var->scip == scip);
8846
8847 SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkDoNotMultaggrVar", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE) );
8848
8850
8851 return SCIP_OKAY;
8852}
8853
8854/** enables the collection of statistics for a variable
8855 *
8856 * @pre This method can be called if @p scip is in one of the following stages:
8857 * - \ref SCIP_STAGE_PROBLEM
8858 * - \ref SCIP_STAGE_INITPRESOLVE
8859 * - \ref SCIP_STAGE_PRESOLVING
8860 * - \ref SCIP_STAGE_EXITPRESOLVE
8861 * - \ref SCIP_STAGE_SOLVING
8862 * - \ref SCIP_STAGE_SOLVED
8863 */
8865 SCIP* scip /**< SCIP data structure */
8866 )
8867{
8868 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPenableVarHistory", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8869
8871}
8872
8873/** disables the collection of any statistic for a variable
8874 *
8875 * @pre This method can be called if @p scip is in one of the following stages:
8876 * - \ref SCIP_STAGE_PROBLEM
8877 * - \ref SCIP_STAGE_INITPRESOLVE
8878 * - \ref SCIP_STAGE_PRESOLVING
8879 * - \ref SCIP_STAGE_EXITPRESOLVE
8880 * - \ref SCIP_STAGE_SOLVING
8881 * - \ref SCIP_STAGE_SOLVED
8882 */
8884 SCIP* scip /**< SCIP data structure */
8885 )
8886{
8887 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPdisableVarHistory", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8888
8890}
8891
8892/** updates the pseudo costs of the given variable and the global pseudo costs after a change of "solvaldelta" in the
8893 * variable's solution value and resulting change of "objdelta" in the in the LP's objective value;
8894 * the update is ignored, if the objective value difference is infinite
8895 *
8896 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8897 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8898 *
8899 * @pre This method can be called if @p scip is in one of the following stages:
8900 * - \ref SCIP_STAGE_SOLVING
8901 * - \ref SCIP_STAGE_SOLVED
8902 */
8904 SCIP* scip, /**< SCIP data structure */
8905 SCIP_VAR* var, /**< problem variable */
8906 SCIP_Real solvaldelta, /**< difference of variable's new LP value - old LP value */
8907 SCIP_Real objdelta, /**< difference of new LP's objective value - old LP's objective value */
8908 SCIP_Real weight /**< weight in (0,1] of this update in pseudo cost sum */
8909 )
8910{
8911 SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateVarPseudocost", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8912
8913 if( !SCIPsetIsInfinity(scip->set, 2*objdelta) ) /* differences infinity - eps should also be treated as infinity */
8914 {
8915 if( scip->set->branch_divingpscost || (!scip->lp->diving && !SCIPtreeProbing(scip->tree)) )
8916 {
8917 SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, solvaldelta, objdelta, weight) );
8918 }
8919 }
8920
8921 return SCIP_OKAY;
8922}
8923
8924/** gets the variable's pseudo cost value for the given change of the variable's LP value
8925 *
8926 * @return the variable's pseudo cost value for the given change of the variable's LP value
8927 *
8928 * @pre This method can be called if @p scip is in one of the following stages:
8929 * - \ref SCIP_STAGE_INITPRESOLVE
8930 * - \ref SCIP_STAGE_PRESOLVING
8931 * - \ref SCIP_STAGE_EXITPRESOLVE
8932 * - \ref SCIP_STAGE_PRESOLVED
8933 * - \ref SCIP_STAGE_INITSOLVE
8934 * - \ref SCIP_STAGE_SOLVING
8935 * - \ref SCIP_STAGE_SOLVED
8936 */
8938 SCIP* scip, /**< SCIP data structure */
8939 SCIP_VAR* var, /**< problem variable */
8940 SCIP_Real solvaldelta /**< difference of variable's new LP value - old LP value */
8941 )
8942{
8943 assert( var->scip == scip );
8944
8945 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostVal", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8946
8947 return SCIPvarGetPseudocost(var, scip->stat, solvaldelta);
8948}
8949
8950/** gets the variable's pseudo cost value for the given change of the variable's LP value,
8951 * only using the pseudo cost information of the current run
8952 *
8953 * @return the variable's pseudo cost value for the given change of the variable's LP value,
8954 * only using the pseudo cost information of the current run
8955 *
8956 * @pre This method can be called if @p scip is in one of the following stages:
8957 * - \ref SCIP_STAGE_INITPRESOLVE
8958 * - \ref SCIP_STAGE_PRESOLVING
8959 * - \ref SCIP_STAGE_EXITPRESOLVE
8960 * - \ref SCIP_STAGE_PRESOLVED
8961 * - \ref SCIP_STAGE_INITSOLVE
8962 * - \ref SCIP_STAGE_SOLVING
8963 * - \ref SCIP_STAGE_SOLVED
8964 */
8966 SCIP* scip, /**< SCIP data structure */
8967 SCIP_VAR* var, /**< problem variable */
8968 SCIP_Real solvaldelta /**< difference of variable's new LP value - old LP value */
8969 )
8970{
8971 assert( var->scip == scip );
8972
8973 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostValCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8974
8975 return SCIPvarGetPseudocostCurrentRun(var, scip->stat, solvaldelta);
8976}
8977
8978/** gets the variable's pseudo cost value for the given direction
8979 *
8980 * @return the variable's pseudo cost value for the given direction
8981 *
8982 * @pre This method can be called if @p scip is in one of the following stages:
8983 * - \ref SCIP_STAGE_INITPRESOLVE
8984 * - \ref SCIP_STAGE_PRESOLVING
8985 * - \ref SCIP_STAGE_EXITPRESOLVE
8986 * - \ref SCIP_STAGE_PRESOLVED
8987 * - \ref SCIP_STAGE_INITSOLVE
8988 * - \ref SCIP_STAGE_SOLVING
8989 * - \ref SCIP_STAGE_SOLVED
8990 */
8992 SCIP* scip, /**< SCIP data structure */
8993 SCIP_VAR* var, /**< problem variable */
8994 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8995 )
8996{
8997 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocost", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8998 assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8999 assert(var->scip == scip);
9000
9001 return SCIPvarGetPseudocost(var, scip->stat, dir == SCIP_BRANCHDIR_DOWNWARDS ? -1.0 : 1.0);
9002}
9003
9004/** gets the variable's pseudo cost value for the given direction,
9005 * only using the pseudo cost information of the current run
9006 *
9007 * @return the variable's pseudo cost value for the given direction,
9008 * only using the pseudo cost information of the current run
9009 *
9010 * @pre This method can be called if @p scip is in one of the following stages:
9011 * - \ref SCIP_STAGE_INITPRESOLVE
9012 * - \ref SCIP_STAGE_PRESOLVING
9013 * - \ref SCIP_STAGE_EXITPRESOLVE
9014 * - \ref SCIP_STAGE_PRESOLVED
9015 * - \ref SCIP_STAGE_INITSOLVE
9016 * - \ref SCIP_STAGE_SOLVING
9017 * - \ref SCIP_STAGE_SOLVED
9018 */
9020 SCIP* scip, /**< SCIP data structure */
9021 SCIP_VAR* var, /**< problem variable */
9022 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9023 )
9024{
9025 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9026 assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
9027 assert(var->scip == scip);
9028
9029 return SCIPvarGetPseudocostCurrentRun(var, scip->stat, dir == SCIP_BRANCHDIR_DOWNWARDS ? -1.0 : 1.0);
9030}
9031
9032/** gets the variable's (possible fractional) number of pseudo cost updates for the given direction
9033 *
9034 * @return the variable's (possible fractional) number of pseudo cost updates for the given direction
9035 *
9036 * @pre This method can be called if @p scip is in one of the following stages:
9037 * - \ref SCIP_STAGE_INITPRESOLVE
9038 * - \ref SCIP_STAGE_PRESOLVING
9039 * - \ref SCIP_STAGE_EXITPRESOLVE
9040 * - \ref SCIP_STAGE_PRESOLVED
9041 * - \ref SCIP_STAGE_INITSOLVE
9042 * - \ref SCIP_STAGE_SOLVING
9043 * - \ref SCIP_STAGE_SOLVED
9044 */
9046 SCIP* scip, /**< SCIP data structure */
9047 SCIP_VAR* var, /**< problem variable */
9048 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9049 )
9050{
9051 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCount", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9052 assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
9053 assert(var->scip == scip);
9054
9055 return SCIPvarGetPseudocostCount(var, dir);
9056}
9057
9058/** gets the variable's (possible fractional) number of pseudo cost updates for the given direction,
9059 * only using the pseudo cost information of the current run
9060 *
9061 * @return the variable's (possible fractional) number of pseudo cost updates for the given direction,
9062 * only using the pseudo cost information of the current run
9063 *
9064 * @pre This method can be called if @p scip is in one of the following stages:
9065 * - \ref SCIP_STAGE_INITPRESOLVE
9066 * - \ref SCIP_STAGE_PRESOLVING
9067 * - \ref SCIP_STAGE_EXITPRESOLVE
9068 * - \ref SCIP_STAGE_PRESOLVED
9069 * - \ref SCIP_STAGE_INITSOLVE
9070 * - \ref SCIP_STAGE_SOLVING
9071 * - \ref SCIP_STAGE_SOLVED
9072 */
9074 SCIP* scip, /**< SCIP data structure */
9075 SCIP_VAR* var, /**< problem variable */
9076 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9077 )
9078{
9079 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCountCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9080 assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
9081 assert(var->scip == scip);
9082
9083 return SCIPvarGetPseudocostCountCurrentRun(var, dir);
9084}
9085
9086/** get pseudo cost variance of the variable, either for entire solve or only for current branch and bound run
9087 *
9088 * @return returns the (corrected) variance of pseudo code information collected so far.
9089 *
9090 * @pre This method can be called if @p scip is in one of the following stages:
9091 * - \ref SCIP_STAGE_INITPRESOLVE
9092 * - \ref SCIP_STAGE_PRESOLVING
9093 * - \ref SCIP_STAGE_EXITPRESOLVE
9094 * - \ref SCIP_STAGE_PRESOLVED
9095 * - \ref SCIP_STAGE_INITSOLVE
9096 * - \ref SCIP_STAGE_SOLVING
9097 * - \ref SCIP_STAGE_SOLVED
9098 */
9100 SCIP* scip, /**< SCIP data structure */
9101 SCIP_VAR* var, /**< problem variable */
9102 SCIP_BRANCHDIR dir, /**< branching direction (downwards, or upwards) */
9103 SCIP_Bool onlycurrentrun /**< only for pseudo costs of current branch and bound run */
9104 )
9105{
9106 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostVariance", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9107 assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
9108 assert(var->scip == scip);
9109
9110 return SCIPvarGetPseudocostVariance(var, dir, onlycurrentrun);
9111}
9112
9113/** calculates a confidence bound for this variable under the assumption of normally distributed pseudo costs
9114 *
9115 * The confidence bound \f$ \theta \geq 0\f$ denotes the interval borders \f$ [X - \theta, \ X + \theta]\f$, which contains
9116 * the true pseudo costs of the variable, i.e., the expected value of the normal distribution, with a probability
9117 * of 2 * clevel - 1.
9118 *
9119 * @return value of confidence bound for this variable
9120 */
9122 SCIP* scip, /**< SCIP data structure */
9123 SCIP_VAR* var, /**< variable in question */
9124 SCIP_BRANCHDIR dir, /**< the branching direction for the confidence bound */
9125 SCIP_Bool onlycurrentrun, /**< should only the current run be taken into account */
9126 SCIP_CONFIDENCELEVEL clevel /**< confidence level for the interval */
9127 )
9128{
9129 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPcalculatePscostConfidenceBound", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9130
9131 return SCIPvarCalcPscostConfidenceBound(var, scip->set, dir, onlycurrentrun, clevel);
9132}
9133
9134/** check if variable pseudo-costs have a significant difference in location. The significance depends on
9135 * the choice of \p clevel and on the kind of tested hypothesis. The one-sided hypothesis, which
9136 * should be rejected, is that fracy * mu_y >= fracx * mu_x, where mu_y and mu_x denote the
9137 * unknown location means of the underlying pseudo-cost distributions of x and y.
9138 *
9139 * This method is applied best if variable x has a better pseudo-cost score than y. The method hypothesizes that y were actually
9140 * better than x (despite the current information), meaning that y can be expected to yield branching
9141 * decisions as least as good as x in the long run. If the method returns TRUE, the current history information is
9142 * sufficient to safely rely on the alternative hypothesis that x yields indeed a better branching score (on average)
9143 * than y.
9144 *
9145 * @note The order of x and y matters for the one-sided hypothesis
9146 *
9147 * @note set \p onesided to FALSE if you are not sure which variable is better. The hypothesis tested then reads
9148 * fracy * mu_y == fracx * mu_x vs the alternative hypothesis fracy * mu_y != fracx * mu_x.
9149 *
9150 * @return TRUE if the hypothesis can be safely rejected at the given confidence level
9151 */
9153 SCIP* scip, /**< SCIP data structure */
9154 SCIP_VAR* varx, /**< variable x */
9155 SCIP_Real fracx, /**< the fractionality of variable x */
9156 SCIP_VAR* vary, /**< variable y */
9157 SCIP_Real fracy, /**< the fractionality of variable y */
9158 SCIP_BRANCHDIR dir, /**< branching direction */
9159 SCIP_CONFIDENCELEVEL clevel, /**< confidence level for rejecting hypothesis */
9160 SCIP_Bool onesided /**< should a one-sided hypothesis y >= x be tested? */
9161 )
9162{
9163 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPsignificantVarPscostDifference", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9164
9165 return SCIPvarSignificantPscostDifference(scip->set, scip->stat, varx, fracx, vary, fracy, dir, clevel, onesided);
9166}
9167
9168/** tests at a given confidence level whether the variable pseudo-costs only have a small probability to
9169 * exceed a \p threshold. This is useful to determine if past observations provide enough evidence
9170 * to skip an expensive strong-branching step if there is already a candidate that has been proven to yield an improvement
9171 * of at least \p threshold.
9172 *
9173 * @note use \p clevel to adjust the level of confidence. For SCIP_CONFIDENCELEVEL_MIN, the method returns TRUE if
9174 * the estimated probability to exceed \p threshold is less than 25 %.
9175 *
9176 * @see SCIP_Confidencelevel for a list of available levels. The used probability limits refer to the one-sided levels
9177 * of confidence.
9178 *
9179 * @return TRUE if the variable pseudo-cost probabilistic model is likely to be smaller than \p threshold
9180 * at the given confidence level \p clevel.
9181 */
9183 SCIP* scip, /**< SCIP data structure */
9184 SCIP_VAR* var, /**< variable x */
9185 SCIP_Real frac, /**< the fractionality of variable x */
9186 SCIP_Real threshold, /**< the threshold to test against */
9187 SCIP_BRANCHDIR dir, /**< branching direction */
9188 SCIP_CONFIDENCELEVEL clevel /**< confidence level for rejecting hypothesis */
9189 )
9190{
9191 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPpscostThresholdProbabilityTest", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9192
9193 return SCIPvarPscostThresholdProbabilityTest(scip->set, scip->stat, var, frac, threshold, dir, clevel);
9194}
9195
9196/** check if the current pseudo cost relative error in a direction violates the given threshold. The Relative
9197 * Error is calculated at a specific confidence level
9198 *
9199 * @return TRUE if relative error in variable pseudo costs is smaller than \p threshold
9200 */
9202 SCIP* scip, /**< SCIP data structure */
9203 SCIP_VAR* var, /**< variable in question */
9204 SCIP_Real threshold, /**< threshold for relative errors to be considered reliable (enough) */
9205 SCIP_CONFIDENCELEVEL clevel /**< a given confidence level */
9206 )
9207{
9208 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisVarPscostRelerrorReliable", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9209
9210 return SCIPvarIsPscostRelerrorReliable(var, scip->set, scip->stat, threshold, clevel);
9211}
9212
9213/** gets the variable's pseudo cost score value for the given LP solution value
9214 *
9215 * @return the variable's pseudo cost score value for the given LP solution value
9216 *
9217 * @pre This method can be called if @p scip is in one of the following stages:
9218 * - \ref SCIP_STAGE_INITPRESOLVE
9219 * - \ref SCIP_STAGE_PRESOLVING
9220 * - \ref SCIP_STAGE_EXITPRESOLVE
9221 * - \ref SCIP_STAGE_PRESOLVED
9222 * - \ref SCIP_STAGE_INITSOLVE
9223 * - \ref SCIP_STAGE_SOLVING
9224 * - \ref SCIP_STAGE_SOLVED
9225 */
9227 SCIP* scip, /**< SCIP data structure */
9228 SCIP_VAR* var, /**< problem variable */
9229 SCIP_Real solval /**< variable's LP solution value */
9230 )
9231{
9232 SCIP_Real downsol;
9233 SCIP_Real upsol;
9234 SCIP_Real pscostdown;
9235 SCIP_Real pscostup;
9236
9237 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9238
9239 assert( var->scip == scip );
9240
9241 downsol = SCIPsetFeasCeil(scip->set, solval-1.0);
9242 upsol = SCIPsetFeasFloor(scip->set, solval+1.0);
9243 pscostdown = SCIPvarGetPseudocost(var, scip->stat, downsol-solval);
9244 pscostup = SCIPvarGetPseudocost(var, scip->stat, upsol-solval);
9245
9246 return SCIPbranchGetScore(scip->set, var, pscostdown, pscostup);
9247}
9248
9249/** gets the variable's pseudo cost score value for the given LP solution value,
9250 * only using the pseudo cost information of the current run
9251 *
9252 * @return the variable's pseudo cost score value for the given LP solution value,
9253 * only using the pseudo cost information of the current run
9254 *
9255 * @pre This method can be called if @p scip is in one of the following stages:
9256 * - \ref SCIP_STAGE_INITPRESOLVE
9257 * - \ref SCIP_STAGE_PRESOLVING
9258 * - \ref SCIP_STAGE_EXITPRESOLVE
9259 * - \ref SCIP_STAGE_PRESOLVED
9260 * - \ref SCIP_STAGE_INITSOLVE
9261 * - \ref SCIP_STAGE_SOLVING
9262 * - \ref SCIP_STAGE_SOLVED
9263 */
9265 SCIP* scip, /**< SCIP data structure */
9266 SCIP_VAR* var, /**< problem variable */
9267 SCIP_Real solval /**< variable's LP solution value */
9268 )
9269{
9270 SCIP_Real downsol;
9271 SCIP_Real upsol;
9272 SCIP_Real pscostdown;
9273 SCIP_Real pscostup;
9274
9275 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9276
9277 assert( var->scip == scip );
9278
9279 downsol = SCIPsetFeasCeil(scip->set, solval-1.0);
9280 upsol = SCIPsetFeasFloor(scip->set, solval+1.0);
9281 pscostdown = SCIPvarGetPseudocostCurrentRun(var, scip->stat, downsol-solval);
9282 pscostup = SCIPvarGetPseudocostCurrentRun(var, scip->stat, upsol-solval);
9283
9284 return SCIPbranchGetScore(scip->set, var, pscostdown, pscostup);
9285}
9286
9287/** returns the variable's VSIDS value
9288 *
9289 * @return the variable's VSIDS value
9290 *
9291 * @pre This method can be called if @p scip is in one of the following stages:
9292 * - \ref SCIP_STAGE_INITPRESOLVE
9293 * - \ref SCIP_STAGE_PRESOLVING
9294 * - \ref SCIP_STAGE_EXITPRESOLVE
9295 * - \ref SCIP_STAGE_PRESOLVED
9296 * - \ref SCIP_STAGE_INITSOLVE
9297 * - \ref SCIP_STAGE_SOLVING
9298 * - \ref SCIP_STAGE_SOLVED
9299 */
9301 SCIP* scip, /**< SCIP data structure */
9302 SCIP_VAR* var, /**< problem variable */
9303 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9304 )
9305{
9307
9308 assert( var->scip == scip );
9309
9311 {
9312 SCIPerrorMessage("invalid branching direction %d when asking for VSIDS value\n", dir);
9313 return SCIP_INVALID;
9314 }
9315
9316 return SCIPvarGetVSIDS(var, scip->stat, dir);
9317}
9318
9319/** returns the variable's VSIDS value only using conflicts of the current run
9320 *
9321 * @return the variable's VSIDS value only using conflicts of the current run
9322 *
9323 * @pre This method can be called if @p scip is in one of the following stages:
9324 * - \ref SCIP_STAGE_INITPRESOLVE
9325 * - \ref SCIP_STAGE_PRESOLVING
9326 * - \ref SCIP_STAGE_EXITPRESOLVE
9327 * - \ref SCIP_STAGE_PRESOLVED
9328 * - \ref SCIP_STAGE_INITSOLVE
9329 * - \ref SCIP_STAGE_SOLVING
9330 * - \ref SCIP_STAGE_SOLVED
9331 */
9333 SCIP* scip, /**< SCIP data structure */
9334 SCIP_VAR* var, /**< problem variable */
9335 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9336 )
9337{
9338 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarVSIDSCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9339
9340 assert( var->scip == scip );
9341
9343 {
9344 SCIPerrorMessage("invalid branching direction %d when asking for VSIDS value\n", dir);
9345 return SCIP_INVALID;
9346 }
9347
9348 return SCIPvarGetVSIDSCurrentRun(var, scip->stat, dir);
9349}
9350
9351/** returns the variable's conflict score value
9352 *
9353 * @return the variable's conflict score value
9354 *
9355 * @pre This method can be called if @p scip is in one of the following stages:
9356 * - \ref SCIP_STAGE_INITPRESOLVE
9357 * - \ref SCIP_STAGE_PRESOLVING
9358 * - \ref SCIP_STAGE_EXITPRESOLVE
9359 * - \ref SCIP_STAGE_PRESOLVED
9360 * - \ref SCIP_STAGE_INITSOLVE
9361 * - \ref SCIP_STAGE_SOLVING
9362 * - \ref SCIP_STAGE_SOLVED
9363 */
9365 SCIP* scip, /**< SCIP data structure */
9366 SCIP_VAR* var /**< problem variable */
9367 )
9368{
9369 SCIP_Real downscore;
9370 SCIP_Real upscore;
9371
9372 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9373
9374 assert( var->scip == scip );
9375
9376 downscore = SCIPvarGetVSIDS(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9377 upscore = SCIPvarGetVSIDS(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9378
9379 return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9380}
9381
9382/** returns the variable's conflict score value only using conflicts of the current run
9383 *
9384 * @return the variable's conflict score value only using conflicts of the current run
9385 *
9386 * @pre This method can be called if @p scip is in one of the following stages:
9387 * - \ref SCIP_STAGE_INITPRESOLVE
9388 * - \ref SCIP_STAGE_PRESOLVING
9389 * - \ref SCIP_STAGE_EXITPRESOLVE
9390 * - \ref SCIP_STAGE_PRESOLVED
9391 * - \ref SCIP_STAGE_INITSOLVE
9392 * - \ref SCIP_STAGE_SOLVING
9393 * - \ref SCIP_STAGE_SOLVED
9394 */
9396 SCIP* scip, /**< SCIP data structure */
9397 SCIP_VAR* var /**< problem variable */
9398 )
9399{
9400 SCIP_Real downscore;
9401 SCIP_Real upscore;
9402
9403 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9404
9405 assert( var->scip == scip );
9406
9409
9410 return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9411}
9412
9413/** returns the variable's conflict length score
9414 *
9415 * @return the variable's conflict length score
9416 *
9417 * @pre This method can be called if @p scip is in one of the following stages:
9418 * - \ref SCIP_STAGE_INITPRESOLVE
9419 * - \ref SCIP_STAGE_PRESOLVING
9420 * - \ref SCIP_STAGE_EXITPRESOLVE
9421 * - \ref SCIP_STAGE_PRESOLVED
9422 * - \ref SCIP_STAGE_INITSOLVE
9423 * - \ref SCIP_STAGE_SOLVING
9424 * - \ref SCIP_STAGE_SOLVED
9425 */
9427 SCIP* scip, /**< SCIP data structure */
9428 SCIP_VAR* var /**< problem variable */
9429 )
9430{
9431 SCIP_Real downscore;
9432 SCIP_Real upscore;
9433
9434 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictlengthScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9435
9436 assert( var->scip == scip );
9437
9440
9441 return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9442}
9443
9444/** returns the variable's conflict length score only using conflicts of the current run
9445 *
9446 * @return the variable's conflict length score only using conflicts of the current run
9447 *
9448 * @pre This method can be called if @p scip is in one of the following stages:
9449 * - \ref SCIP_STAGE_INITPRESOLVE
9450 * - \ref SCIP_STAGE_PRESOLVING
9451 * - \ref SCIP_STAGE_EXITPRESOLVE
9452 * - \ref SCIP_STAGE_PRESOLVED
9453 * - \ref SCIP_STAGE_INITSOLVE
9454 * - \ref SCIP_STAGE_SOLVING
9455 * - \ref SCIP_STAGE_SOLVED
9456 */
9458 SCIP* scip, /**< SCIP data structure */
9459 SCIP_VAR* var /**< problem variable */
9460 )
9461{
9462 SCIP_Real downscore;
9463 SCIP_Real upscore;
9464
9465 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictlengthScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9466
9467 assert( var->scip == scip );
9468
9471
9472 return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9473}
9474
9475/** returns the variable's average conflict length
9476 *
9477 * @return the variable's average conflict length
9478 *
9479 * @pre This method can be called if @p scip is in one of the following stages:
9480 * - \ref SCIP_STAGE_INITPRESOLVE
9481 * - \ref SCIP_STAGE_PRESOLVING
9482 * - \ref SCIP_STAGE_EXITPRESOLVE
9483 * - \ref SCIP_STAGE_PRESOLVED
9484 * - \ref SCIP_STAGE_INITSOLVE
9485 * - \ref SCIP_STAGE_SOLVING
9486 * - \ref SCIP_STAGE_SOLVED
9487 */
9489 SCIP* scip, /**< SCIP data structure */
9490 SCIP_VAR* var, /**< problem variable */
9491 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9492 )
9493{
9494 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgConflictlength", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9495
9496 assert( var->scip == scip );
9497
9498 return SCIPvarGetAvgConflictlength(var, dir);
9499}
9500
9501/** returns the variable's average conflict length only using conflicts of the current run
9502 *
9503 * @return the variable's average conflict length only using conflicts of the current run
9504 *
9505 * @pre This method can be called if @p scip is in one of the following stages:
9506 * - \ref SCIP_STAGE_INITPRESOLVE
9507 * - \ref SCIP_STAGE_PRESOLVING
9508 * - \ref SCIP_STAGE_EXITPRESOLVE
9509 * - \ref SCIP_STAGE_PRESOLVED
9510 * - \ref SCIP_STAGE_INITSOLVE
9511 * - \ref SCIP_STAGE_SOLVING
9512 * - \ref SCIP_STAGE_SOLVED
9513 */
9515 SCIP* scip, /**< SCIP data structure */
9516 SCIP_VAR* var, /**< problem variable */
9517 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9518 )
9519{
9520 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgConflictlengthCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9521
9522 assert( var->scip == scip );
9523
9525}
9526
9527/** returns the average number of inferences found after branching on the variable in given direction;
9528 * if branching on the variable in the given direction was yet evaluated, the average number of inferences
9529 * over all variables for branching in the given direction is returned
9530 *
9531 * @return the average number of inferences found after branching on the variable in given direction
9532 *
9533 * @pre This method can be called if @p scip is in one of the following stages:
9534 * - \ref SCIP_STAGE_INITPRESOLVE
9535 * - \ref SCIP_STAGE_PRESOLVING
9536 * - \ref SCIP_STAGE_EXITPRESOLVE
9537 * - \ref SCIP_STAGE_PRESOLVED
9538 * - \ref SCIP_STAGE_INITSOLVE
9539 * - \ref SCIP_STAGE_SOLVING
9540 * - \ref SCIP_STAGE_SOLVED
9541 */
9543 SCIP* scip, /**< SCIP data structure */
9544 SCIP_VAR* var, /**< problem variable */
9545 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9546 )
9547{
9548 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferences", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9549
9550 assert( var->scip == scip );
9551
9552 return SCIPvarGetAvgInferences(var, scip->stat, dir);
9553}
9554
9555/** returns the average number of inferences found after branching on the variable in given direction in the current run;
9556 * if branching on the variable in the given direction was yet evaluated, the average number of inferences
9557 * over all variables for branching in the given direction is returned
9558 *
9559 * @return the average number of inferences found after branching on the variable in given direction in the current run
9560 *
9561 * @pre This method can be called if @p scip is in one of the following stages:
9562 * - \ref SCIP_STAGE_INITPRESOLVE
9563 * - \ref SCIP_STAGE_PRESOLVING
9564 * - \ref SCIP_STAGE_EXITPRESOLVE
9565 * - \ref SCIP_STAGE_PRESOLVED
9566 * - \ref SCIP_STAGE_INITSOLVE
9567 * - \ref SCIP_STAGE_SOLVING
9568 * - \ref SCIP_STAGE_SOLVED
9569 */
9571 SCIP* scip, /**< SCIP data structure */
9572 SCIP_VAR* var, /**< problem variable */
9573 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9574 )
9575{
9576 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferencesCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9577
9578 assert( var->scip == scip );
9579
9580 return SCIPvarGetAvgInferencesCurrentRun(var, scip->stat, dir);
9581}
9582
9583/** returns the variable's average inference score value
9584 *
9585 * @return the variable's average inference score value
9586 *
9587 * @pre This method can be called if @p scip is in one of the following stages:
9588 * - \ref SCIP_STAGE_INITPRESOLVE
9589 * - \ref SCIP_STAGE_PRESOLVING
9590 * - \ref SCIP_STAGE_EXITPRESOLVE
9591 * - \ref SCIP_STAGE_PRESOLVED
9592 * - \ref SCIP_STAGE_INITSOLVE
9593 * - \ref SCIP_STAGE_SOLVING
9594 * - \ref SCIP_STAGE_SOLVED
9595 */
9597 SCIP* scip, /**< SCIP data structure */
9598 SCIP_VAR* var /**< problem variable */
9599 )
9600{
9601 SCIP_Real inferdown;
9602 SCIP_Real inferup;
9603
9604 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9605
9606 assert( var->scip == scip );
9607
9608 inferdown = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9610
9611 return SCIPbranchGetScore(scip->set, var, inferdown, inferup);
9612}
9613
9614/** returns the variable's average inference score value only using inferences of the current run
9615 *
9616 * @return the variable's average inference score value only using inferences of the current run
9617 *
9618 * @pre This method can be called if @p scip is in one of the following stages:
9619 * - \ref SCIP_STAGE_INITPRESOLVE
9620 * - \ref SCIP_STAGE_PRESOLVING
9621 * - \ref SCIP_STAGE_EXITPRESOLVE
9622 * - \ref SCIP_STAGE_PRESOLVED
9623 * - \ref SCIP_STAGE_INITSOLVE
9624 * - \ref SCIP_STAGE_SOLVING
9625 * - \ref SCIP_STAGE_SOLVED
9626 */
9628 SCIP* scip, /**< SCIP data structure */
9629 SCIP_VAR* var /**< problem variable */
9630 )
9631{
9632 SCIP_Real inferdown;
9633 SCIP_Real inferup;
9634
9635 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9636
9637 assert( var->scip == scip );
9638
9641
9642 return SCIPbranchGetScore(scip->set, var, inferdown, inferup);
9643}
9644
9645/** initializes the upwards and downwards pseudocosts, conflict scores, conflict lengths, inference scores, cutoff scores
9646 * of a variable to the given values
9647 *
9648 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9649 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9650 *
9651 * @pre This method can be called if @p scip is in one of the following stages:
9652 * - \ref SCIP_STAGE_TRANSFORMED
9653 * - \ref SCIP_STAGE_INITPRESOLVE
9654 * - \ref SCIP_STAGE_PRESOLVING
9655 * - \ref SCIP_STAGE_EXITPRESOLVE
9656 * - \ref SCIP_STAGE_PRESOLVED
9657 * - \ref SCIP_STAGE_INITSOLVE
9658 * - \ref SCIP_STAGE_SOLVING
9659 */
9661 SCIP* scip, /**< SCIP data structure */
9662 SCIP_VAR* var, /**< variable which should be initialized */
9663 SCIP_Real downpscost, /**< value to which pseudocosts for downwards branching should be initialized */
9664 SCIP_Real uppscost, /**< value to which pseudocosts for upwards branching should be initialized */
9665 SCIP_Real downvsids, /**< value to which VSIDS score for downwards branching should be initialized */
9666 SCIP_Real upvsids, /**< value to which VSIDS score for upwards branching should be initialized */
9667 SCIP_Real downconflen, /**< value to which conflict length score for downwards branching should be initialized */
9668 SCIP_Real upconflen, /**< value to which conflict length score for upwards branching should be initialized */
9669 SCIP_Real downinfer, /**< value to which inference counter for downwards branching should be initialized */
9670 SCIP_Real upinfer, /**< value to which inference counter for upwards branching should be initialized */
9671 SCIP_Real downcutoff, /**< value to which cutoff counter for downwards branching should be initialized */
9672 SCIP_Real upcutoff /**< value to which cutoff counter for upwards branching should be initialized */
9673 )
9674{
9675 SCIP_CALL( SCIPcheckStage(scip, "SCIPinitVarBranchStats", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
9676
9677 assert(downpscost >= 0.0 && uppscost >= 0.0);
9678 assert(downvsids >= 0.0 && upvsids >= 0.0);
9679 assert(downconflen >= 0.0 && upconflen >= 0.0);
9680 assert(downinfer >= 0.0 && upinfer >= 0.0);
9681 assert(downcutoff >= 0.0 && upcutoff >= 0.0);
9682
9683 if( !SCIPisFeasZero(scip, downpscost) || !SCIPisFeasZero(scip, downvsids)
9684 || !SCIPisFeasZero(scip, downinfer) || !SCIPisFeasZero(scip, downcutoff) )
9685 {
9687 SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, -1.0, downpscost, 1.0) );
9689 SCIP_CALL( SCIPvarIncVSIDS(var, NULL, scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, SCIP_UNKNOWN, downvsids) );
9691 }
9692
9693 if( !SCIPisFeasZero(scip, downconflen) )
9694 {
9696 }
9697
9698 if( !SCIPisFeasZero(scip, uppscost) || !SCIPisFeasZero(scip, upvsids)
9699 || !SCIPisFeasZero(scip, upinfer) || !SCIPisFeasZero(scip, upcutoff) )
9700 {
9702 SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, 1.0, uppscost, 1.0) );
9706 }
9707
9708 if( !SCIPisFeasZero(scip, upconflen) )
9709 {
9711 }
9712
9713 return SCIP_OKAY;
9714}
9715
9716/** initializes the upwards and downwards conflict scores, conflict lengths, inference scores, cutoff scores of a
9717 * variable w.r.t. a value by the given values (SCIP_VALUEHISTORY)
9718 *
9719 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9720 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9721 *
9722 * @pre This method can be called if @p scip is in one of the following stages:
9723 * - \ref SCIP_STAGE_TRANSFORMED
9724 * - \ref SCIP_STAGE_INITPRESOLVE
9725 * - \ref SCIP_STAGE_PRESOLVING
9726 * - \ref SCIP_STAGE_EXITPRESOLVE
9727 * - \ref SCIP_STAGE_PRESOLVED
9728 * - \ref SCIP_STAGE_INITSOLVE
9729 * - \ref SCIP_STAGE_SOLVING
9730 */
9732 SCIP* scip, /**< SCIP data structure */
9733 SCIP_VAR* var, /**< variable which should be initialized */
9734 SCIP_Real value, /**< domain value, or SCIP_UNKNOWN */
9735 SCIP_Real downvsids, /**< value to which VSIDS score for downwards branching should be initialized */
9736 SCIP_Real upvsids, /**< value to which VSIDS score for upwards branching should be initialized */
9737 SCIP_Real downconflen, /**< value to which conflict length score for downwards branching should be initialized */
9738 SCIP_Real upconflen, /**< value to which conflict length score for upwards branching should be initialized */
9739 SCIP_Real downinfer, /**< value to which inference counter for downwards branching should be initialized */
9740 SCIP_Real upinfer, /**< value to which inference counter for upwards branching should be initialized */
9741 SCIP_Real downcutoff, /**< value to which cutoff counter for downwards branching should be initialized */
9742 SCIP_Real upcutoff /**< value to which cutoff counter for upwards branching should be initialized */
9743 )
9744{
9745 SCIP_CALL( SCIPcheckStage(scip, "SCIPinitVarValueBranchStats", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
9746
9747 assert(downvsids >= 0.0 && upvsids >= 0.0);
9748 assert(downconflen >= 0.0 && upconflen >= 0.0);
9749 assert(downinfer >= 0.0 && upinfer >= 0.0);
9750 assert(downcutoff >= 0.0 && upcutoff >= 0.0);
9751
9752 if( !SCIPisFeasZero(scip, downvsids) || !SCIPisFeasZero(scip, downinfer) || !SCIPisFeasZero(scip, downcutoff) )
9753 {
9755 SCIP_CALL( SCIPvarIncInferenceSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downinfer) );
9756 SCIP_CALL( SCIPvarIncVSIDS(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downvsids) );
9757 SCIP_CALL( SCIPvarIncCutoffSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downcutoff) );
9758 }
9759
9760 if( !SCIPisFeasZero(scip, downconflen) )
9761 {
9762 SCIP_CALL( SCIPvarIncNActiveConflicts(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downconflen) );
9763 }
9764
9765 if( !SCIPisFeasZero(scip, upvsids) || !SCIPisFeasZero(scip, upinfer) || !SCIPisFeasZero(scip, upcutoff) )
9766 {
9768 SCIP_CALL( SCIPvarIncInferenceSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upinfer) );
9769 SCIP_CALL( SCIPvarIncVSIDS(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upvsids) );
9770 SCIP_CALL( SCIPvarIncCutoffSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upcutoff) );
9771 }
9772
9773 if( !SCIPisFeasZero(scip, upconflen) )
9774 {
9775 SCIP_CALL( SCIPvarIncNActiveConflicts(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upconflen) );
9776 }
9777
9778 return SCIP_OKAY;
9779}
9780
9781/** returns the average number of cutoffs found after branching on the variable in given direction;
9782 * if branching on the variable in the given direction was yet evaluated, the average number of cutoffs
9783 * over all variables for branching in the given direction is returned
9784 *
9785 * @return the average number of cutoffs found after branching on the variable in given direction
9786 *
9787 * @pre This method can be called if @p scip is in one of the following stages:
9788 * - \ref SCIP_STAGE_INITPRESOLVE
9789 * - \ref SCIP_STAGE_PRESOLVING
9790 * - \ref SCIP_STAGE_EXITPRESOLVE
9791 * - \ref SCIP_STAGE_PRESOLVED
9792 * - \ref SCIP_STAGE_INITSOLVE
9793 * - \ref SCIP_STAGE_SOLVING
9794 * - \ref SCIP_STAGE_SOLVED
9795 */
9797 SCIP* scip, /**< SCIP data structure */
9798 SCIP_VAR* var, /**< problem variable */
9799 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9800 )
9801{
9802 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffs", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9803
9804 assert( var->scip == scip );
9805
9806 return SCIPvarGetAvgCutoffs(var, scip->stat, dir);
9807}
9808
9809/** returns the average number of cutoffs found after branching on the variable in given direction in the current run;
9810 * if branching on the variable in the given direction was yet evaluated, the average number of cutoffs
9811 * over all variables for branching in the given direction is returned
9812 *
9813 * @return the average number of cutoffs found after branching on the variable in given direction in the current run
9814 *
9815 * @pre This method can be called if @p scip is in one of the following stages:
9816 * - \ref SCIP_STAGE_INITPRESOLVE
9817 * - \ref SCIP_STAGE_PRESOLVING
9818 * - \ref SCIP_STAGE_EXITPRESOLVE
9819 * - \ref SCIP_STAGE_PRESOLVED
9820 * - \ref SCIP_STAGE_INITSOLVE
9821 * - \ref SCIP_STAGE_SOLVING
9822 * - \ref SCIP_STAGE_SOLVED
9823 */
9825 SCIP* scip, /**< SCIP data structure */
9826 SCIP_VAR* var, /**< problem variable */
9827 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9828 )
9829{
9830 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffsCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9831
9832 assert( var->scip == scip );
9833
9834 return SCIPvarGetAvgCutoffsCurrentRun(var, scip->stat, dir);
9835}
9836
9837/** returns the variable's average cutoff score value
9838 *
9839 * @return the variable's average cutoff score value
9840 *
9841 * @pre This method can be called if @p scip is in one of the following stages:
9842 * - \ref SCIP_STAGE_INITPRESOLVE
9843 * - \ref SCIP_STAGE_PRESOLVING
9844 * - \ref SCIP_STAGE_EXITPRESOLVE
9845 * - \ref SCIP_STAGE_PRESOLVED
9846 * - \ref SCIP_STAGE_INITSOLVE
9847 * - \ref SCIP_STAGE_SOLVING
9848 * - \ref SCIP_STAGE_SOLVED
9849 */
9851 SCIP* scip, /**< SCIP data structure */
9852 SCIP_VAR* var /**< problem variable */
9853 )
9854{
9855 SCIP_Real cutoffdown;
9856 SCIP_Real cutoffup;
9857
9858 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9859
9860 assert( var->scip == scip );
9861
9862 cutoffdown = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9863 cutoffup = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9864
9865 return SCIPbranchGetScore(scip->set, var, cutoffdown, cutoffup);
9866}
9867
9868/** returns the variable's average cutoff score value, only using cutoffs of the current run
9869 *
9870 * @return the variable's average cutoff score value, only using cutoffs of the current run
9871 *
9872 * @pre This method can be called if @p scip is in one of the following stages:
9873 * - \ref SCIP_STAGE_INITPRESOLVE
9874 * - \ref SCIP_STAGE_PRESOLVING
9875 * - \ref SCIP_STAGE_EXITPRESOLVE
9876 * - \ref SCIP_STAGE_PRESOLVED
9877 * - \ref SCIP_STAGE_INITSOLVE
9878 * - \ref SCIP_STAGE_SOLVING
9879 * - \ref SCIP_STAGE_SOLVED
9880 */
9882 SCIP* scip, /**< SCIP data structure */
9883 SCIP_VAR* var /**< problem variable */
9884 )
9885{
9886 SCIP_Real cutoffdown;
9887 SCIP_Real cutoffup;
9888
9889 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9890
9891 assert( var->scip == scip );
9892
9895
9896 return SCIPbranchGetScore(scip->set, var, cutoffdown, cutoffup);
9897}
9898
9899/** returns the variable's average inference/cutoff score value, weighting the cutoffs of the variable with the given
9900 * factor
9901 *
9902 * @return the variable's average inference/cutoff score value
9903 *
9904 * @pre This method can be called if @p scip is in one of the following stages:
9905 * - \ref SCIP_STAGE_INITPRESOLVE
9906 * - \ref SCIP_STAGE_PRESOLVING
9907 * - \ref SCIP_STAGE_EXITPRESOLVE
9908 * - \ref SCIP_STAGE_PRESOLVED
9909 * - \ref SCIP_STAGE_INITSOLVE
9910 * - \ref SCIP_STAGE_SOLVING
9911 * - \ref SCIP_STAGE_SOLVED
9912 */
9914 SCIP* scip, /**< SCIP data structure */
9915 SCIP_VAR* var, /**< problem variable */
9916 SCIP_Real cutoffweight /**< factor to weigh average number of cutoffs in branching score */
9917 )
9918{
9919 SCIP_Real avginferdown;
9920 SCIP_Real avginferup;
9921 SCIP_Real avginfer;
9922 SCIP_Real inferdown;
9923 SCIP_Real inferup;
9924 SCIP_Real cutoffdown;
9925 SCIP_Real cutoffup;
9926
9927 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceCutoffScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9928
9929 assert( var->scip == scip );
9930
9931 avginferdown = SCIPhistoryGetAvgInferences(scip->stat->glbhistory, SCIP_BRANCHDIR_DOWNWARDS);
9932 avginferup = SCIPhistoryGetAvgInferences(scip->stat->glbhistory, SCIP_BRANCHDIR_UPWARDS);
9933 avginfer = (avginferdown + avginferup)/2.0;
9934 inferdown = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9936 cutoffdown = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9937 cutoffup = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9938
9939 return SCIPbranchGetScore(scip->set, var,
9940 inferdown + cutoffweight * avginfer * cutoffdown, inferup + cutoffweight * avginfer * cutoffup);
9941}
9942
9943/** returns the variable's average inference/cutoff score value, weighting the cutoffs of the variable with the given
9944 * factor, only using inferences and cutoffs of the current run
9945 *
9946 * @return the variable's average inference/cutoff score value, only using inferences and cutoffs of the current run
9947 *
9948 * @pre This method can be called if @p scip is in one of the following stages:
9949 * - \ref SCIP_STAGE_INITPRESOLVE
9950 * - \ref SCIP_STAGE_PRESOLVING
9951 * - \ref SCIP_STAGE_EXITPRESOLVE
9952 * - \ref SCIP_STAGE_PRESOLVED
9953 * - \ref SCIP_STAGE_INITSOLVE
9954 * - \ref SCIP_STAGE_SOLVING
9955 * - \ref SCIP_STAGE_SOLVED
9956 */
9958 SCIP* scip, /**< SCIP data structure */
9959 SCIP_VAR* var, /**< problem variable */
9960 SCIP_Real cutoffweight /**< factor to weigh average number of cutoffs in branching score */
9961 )
9962{
9963 SCIP_Real avginferdown;
9964 SCIP_Real avginferup;
9965 SCIP_Real avginfer;
9966 SCIP_Real inferdown;
9967 SCIP_Real inferup;
9968 SCIP_Real cutoffdown;
9969 SCIP_Real cutoffup;
9970
9971 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceCutoffScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9972
9973 assert( var->scip == scip );
9974
9975 avginferdown = SCIPhistoryGetAvgInferences(scip->stat->glbhistorycrun, SCIP_BRANCHDIR_DOWNWARDS);
9976 avginferup = SCIPhistoryGetAvgInferences(scip->stat->glbhistorycrun, SCIP_BRANCHDIR_UPWARDS);
9977 avginfer = (avginferdown + avginferup)/2.0;
9982
9983 return SCIPbranchGetScore(scip->set, var,
9984 inferdown + cutoffweight * avginfer * cutoffdown, inferup + cutoffweight * avginfer * cutoffup);
9985}
9986
9987/** returns the variable's average GMI efficacy score value
9988 *
9989 * @return the variable's average GMI efficacy score value
9990 *
9991 * @pre This method can be called if @p scip is in one of the following stages:
9992 * - \ref SCIP_STAGE_INITPRESOLVE
9993 * - \ref SCIP_STAGE_PRESOLVING
9994 * - \ref SCIP_STAGE_EXITPRESOLVE
9995 * - \ref SCIP_STAGE_PRESOLVED
9996 * - \ref SCIP_STAGE_INITSOLVE
9997 * - \ref SCIP_STAGE_SOLVING
9998 * - \ref SCIP_STAGE_SOLVED
9999 */
10001 SCIP* scip, /**< SCIP data structure */
10002 SCIP_VAR* var /**< problem variable */
10003 )
10004{
10005 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgGMIScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
10006
10007 assert( var->scip == scip );
10008
10009 return SCIPvarGetAvgGMIScore(var, scip->stat);
10010}
10011
10012/** sets the variable's average GMI efficacy score value
10013 *
10014 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
10015 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
10016 *
10017 * @pre This method can be called if @p scip is in one of the following stages:
10018 * - \ref SCIP_STAGE_INITPRESOLVE
10019 * - \ref SCIP_STAGE_PRESOLVING
10020 * - \ref SCIP_STAGE_EXITPRESOLVE
10021 * - \ref SCIP_STAGE_PRESOLVED
10022 * - \ref SCIP_STAGE_INITSOLVE
10023 * - \ref SCIP_STAGE_SOLVING
10024 * - \ref SCIP_STAGE_SOLVED
10025 */
10026SCIP_EXPORT
10028 SCIP* scip, /**< SCIP data structure */
10029 SCIP_VAR* var, /**< problem variable */
10030 SCIP_Real gmieff /**< Efficacy of last GMI cut generated from when var was basic /frac */
10031 )
10032{
10033 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPincVarGMISumScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
10034
10035 assert( var->scip == scip );
10036
10037 SCIP_CALL( SCIPvarIncGMIeffSum(var, scip->stat, gmieff) );
10038
10039 return SCIP_OKAY;
10040}
10041
10042/** returns the variable's last GMI efficacy score value
10043 *
10044 * @return the variable's last GMI efficacy score value
10045 *
10046 * @pre This method can be called if @p scip is in one of the following stages:
10047 * - \ref SCIP_STAGE_INITPRESOLVE
10048 * - \ref SCIP_STAGE_PRESOLVING
10049 * - \ref SCIP_STAGE_EXITPRESOLVE
10050 * - \ref SCIP_STAGE_PRESOLVED
10051 * - \ref SCIP_STAGE_INITSOLVE
10052 * - \ref SCIP_STAGE_SOLVING
10053 * - \ref SCIP_STAGE_SOLVED
10054 */
10056 SCIP* scip, /**< SCIP data structure */
10057 SCIP_VAR* var /**< problem variable */
10058 )
10059{
10060 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarLastGMIScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
10061
10062 assert( var->scip == scip );
10063
10064 return SCIPvarGetLastGMIScore(var, scip->stat);
10065}
10066
10067/** sets the variable's last GMI efficacy score value
10068 *
10069 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
10070 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
10071 *
10072 * @pre This method can be called if @p scip is in one of the following stages:
10073 * - \ref SCIP_STAGE_INITPRESOLVE
10074 * - \ref SCIP_STAGE_PRESOLVING
10075 * - \ref SCIP_STAGE_EXITPRESOLVE
10076 * - \ref SCIP_STAGE_PRESOLVED
10077 * - \ref SCIP_STAGE_INITSOLVE
10078 * - \ref SCIP_STAGE_SOLVING
10079 * - \ref SCIP_STAGE_SOLVED
10080 */
10082 SCIP* scip, /**< SCIP data structure */
10083 SCIP_VAR* var, /**< problem variable */
10084 SCIP_Real gmieff /**< efficacy of GMI cut from tableau row when variable is basic / frac */
10085 )
10086{
10087 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPsetVarLastGMIScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
10088
10089 assert( var->scip == scip );
10090
10091 SCIP_CALL( SCIPvarSetLastGMIScore(var, scip->stat, gmieff) );
10092
10093 return SCIP_OKAY;
10094}
10095
10096/** outputs variable information to file stream via the message system
10097 *
10098 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
10099 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
10100 *
10101 * @pre This method can be called if @p scip is in one of the following stages:
10102 * - \ref SCIP_STAGE_PROBLEM
10103 * - \ref SCIP_STAGE_TRANSFORMING
10104 * - \ref SCIP_STAGE_TRANSFORMED
10105 * - \ref SCIP_STAGE_INITPRESOLVE
10106 * - \ref SCIP_STAGE_PRESOLVING
10107 * - \ref SCIP_STAGE_EXITPRESOLVE
10108 * - \ref SCIP_STAGE_PRESOLVED
10109 * - \ref SCIP_STAGE_INITSOLVE
10110 * - \ref SCIP_STAGE_SOLVING
10111 * - \ref SCIP_STAGE_SOLVED
10112 * - \ref SCIP_STAGE_EXITSOLVE
10113 * - \ref SCIP_STAGE_FREETRANS
10114 *
10115 * @note If the message handler is set to a NULL pointer nothing will be printed
10116 */
10118 SCIP* scip, /**< SCIP data structure */
10119 SCIP_VAR* var, /**< problem variable */
10120 FILE* file /**< output file (or NULL for standard output) */
10121 )
10122{
10123 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
10124
10125 SCIP_CALL( SCIPvarPrint(var, scip->set, scip->messagehdlr, file) );
10126
10127 return SCIP_OKAY;
10128}
SCIP_RETCODE SCIPbranchcandUpdateVarBranchPriority(SCIP_BRANCHCAND *branchcand, SCIP_SET *set, SCIP_VAR *var, int branchpriority)
Definition: branch.c:1176
SCIP_Real SCIPbranchGetScore(SCIP_SET *set, SCIP_VAR *var, SCIP_Real downgain, SCIP_Real upgain)
Definition: branch.c:2190
internal methods for branching rules and branching candidate storage
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:360
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:290
internal methods for clocks and timing issues
internal methods for conflict analysis
int SCIPconflictGetNConflicts(SCIP_CONFLICT *conflict)
SCIP_RETCODE SCIPconflictAnalyzeStrongbranch(SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_COL *col, SCIP_Bool *downconflict, SCIP_Bool *upconflict)
SCIP_RETCODE SCIPcheckStage(SCIP *scip, const char *method, SCIP_Bool init, SCIP_Bool problem, SCIP_Bool transforming, SCIP_Bool transformed, SCIP_Bool initpresolve, SCIP_Bool presolving, SCIP_Bool exitpresolve, SCIP_Bool presolved, SCIP_Bool initsolve, SCIP_Bool solving, SCIP_Bool solved, SCIP_Bool exitsolve, SCIP_Bool freetrans, SCIP_Bool freescip)
Definition: debug.c:2208
methods for debugging
#define NULL
Definition: def.h:266
#define SCIP_MAXSTRLEN
Definition: def.h:287
#define SCIP_Longint
Definition: def.h:157
#define SCIP_MAXTREEDEPTH
Definition: def.h:315
#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:242
#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:238
#define SCIP_CALL_ABORT(x)
Definition: def.h:352
#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:345
#define REALABS(x)
Definition: def.h:196
#define SCIP_LONGINT_MAX
Definition: def.h:158
#define SCIP_CALL(x)
Definition: def.h:373
#define SCIP_CALL_FINALLY(x, y)
Definition: def.h:415
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:3111
int SCIPhashmapGetImageInt(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3284
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3077
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3426
SCIP_RETCODE SCIPhashmapInsertInt(SCIP_HASHMAP *hashmap, void *origin, int image)
Definition: misc.c:3195
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
Definition: lpi_clp.cpp:3931
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_clp.cpp:2766
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2609
SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2386
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
#define SCIPdebugMsg
Definition: scip_message.h:78
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
SCIP_Real SCIPgetColRedcost(SCIP *scip, SCIP_COL *col)
Definition: scip_lp.c:1154
SCIP_Longint SCIPcolGetStrongbranchNode(SCIP_COL *col)
Definition: lp.c:17173
int SCIPcolGetNStrongbranchs(SCIP_COL *col)
Definition: lp.c:17183
SCIP_Bool SCIPcolIsInLP(SCIP_COL *col)
Definition: lp.c:17115
SCIP_Real SCIPgetColFarkasCoef(SCIP *scip, SCIP_COL *col)
Definition: scip_lp.c:1180
SCIP_Bool SCIPconsIsLockedTypePos(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
Definition: cons.c:8583
SCIP_Bool SCIPconsIsLockedTypeNeg(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
Definition: cons.c:8595
SCIP_Bool SCIPinDive(SCIP *scip)
Definition: scip_lp.c:2775
SCIP_Bool SCIPisLPRelax(SCIP *scip)
Definition: scip_lp.c:225
SCIP_RETCODE SCIPgetLPI(SCIP *scip, SCIP_LPI **lpi)
Definition: scip_lp.c:985
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip_lp.c:168
SCIP_Bool SCIPallColsInLP(SCIP *scip)
Definition: scip_lp.c:649
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition: scip_lp.c:247
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:110
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:139
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip_mem.h:99
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip_mem.h:111
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:105
SCIP_NODETYPE SCIPnodeGetType(SCIP_NODE *node)
Definition: tree.c:7500
SCIP_DOMCHG * SCIPnodeGetDomchg(SCIP_NODE *node)
Definition: tree.c:7605
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 SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition: scip_tree.c:91
SCIP_RETCODE SCIPgetVarStrongbranchFrac(SCIP *scip, SCIP_VAR *var, int itlim, SCIP_Bool idempotent, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *downconflict, SCIP_Bool *upconflict, SCIP_Bool *lperror)
Definition: scip_var.c:2919
SCIP_Real SCIPgetRelaxSolObj(SCIP *scip)
Definition: scip_var.c:2632
SCIP_RETCODE SCIPinitVarBranchStats(SCIP *scip, SCIP_VAR *var, SCIP_Real downpscost, SCIP_Real uppscost, SCIP_Real downvsids, SCIP_Real upvsids, SCIP_Real downconflen, SCIP_Real upconflen, SCIP_Real downinfer, SCIP_Real upinfer, SCIP_Real downcutoff, SCIP_Real upcutoff)
Definition: scip_var.c:9660
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:9731
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:17788
SCIP_Real SCIPgetVarMultaggrLbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6669
SCIP_Bool SCIPpscostThresholdProbabilityTest(SCIP *scip, SCIP_VAR *var, SCIP_Real frac, SCIP_Real threshold, SCIP_BRANCHDIR dir, SCIP_CONFIDENCELEVEL clevel)
Definition: scip_var.c:9182
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:18189
SCIP_RETCODE SCIPremoveVarFromGlobalStructures(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:7982
SCIP_Real SCIPvarGetSol(SCIP_VAR *var, SCIP_Bool getlpval)
Definition: var.c:13256
SCIP_Bool SCIPdoNotAggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8708
void SCIPdisableVarHistory(SCIP *scip)
Definition: scip_var.c:8883
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17747
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:17598
SCIP_RETCODE SCIPincVarGMISumScore(SCIP *scip, SCIP_VAR *var, SCIP_Real gmieff)
Definition: scip_var.c:10027
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:5949
SCIP_BOUNDTYPE SCIPboundchgGetBoundtype(SCIP_BOUNDCHG *boundchg)
Definition: var.c:17345
SCIP_Real SCIPgetVarMultaggrLbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6699
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:6133
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:7044
SCIP_RETCODE SCIPcalcCliquePartition(SCIP *const scip, SCIP_VAR **const vars, int const nvars, int *const cliquepartition, int *const ncliques)
Definition: scip_var.c:7379
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:6471
SCIP_Real SCIPgetVarAvgInferenceScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9627
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:17325
SCIP_Real SCIPgetVarPseudocostCountCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9073
SCIP_Real SCIPgetVarAvgInferenceScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9596
SCIP_RETCODE SCIPscaleVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real scale)
Definition: scip_var.c:8044
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:6684
SCIP_BOUNDCHG * SCIPdomchgGetBoundchg(SCIP_DOMCHG *domchg, int pos)
Definition: var.c:17373
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:9045
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17537
SCIP_RETCODE SCIPcalcNegatedCliquePartition(SCIP *const scip, SCIP_VAR **const vars, int const nvars, int *const cliquepartition, int *const ncliques)
Definition: scip_var.c:7598
SCIP_Real SCIPgetVarPseudocostCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9019
SCIP_RETCODE SCIPwriteCliqueGraph(SCIP *scip, const char *fname, SCIP_Bool writenodeweights)
Definition: scip_var.c:7833
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:8688
SCIP_Real SCIPgetVarMultaggrUbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6714
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:18143
int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition: var.c:3416
SCIP_RETCODE SCIPupdateVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition: scip_var.c:8144
SCIP_Real SCIPgetVarAvgConflictlength(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9488
SCIP_Bool SCIPisVarPscostRelerrorReliable(SCIP *scip, SCIP_VAR *var, SCIP_Real threshold, SCIP_CONFIDENCELEVEL clevel)
Definition: scip_var.c:9201
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:16576
SCIP_Bool SCIPdoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8721
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition: var.c:17560
SCIP_Real SCIPgetVarPseudocost(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:8991
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:9881
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:8524
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:5738
SCIP_Bool SCIPallowObjProp(SCIP *scip)
Definition: scip_var.c:8765
SCIP_Real SCIPboundchgGetNewbound(SCIP_BOUNDCHG *boundchg)
Definition: var.c:17315
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:9570
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17925
SCIP_VAR * SCIPvarGetProbvar(SCIP_VAR *var)
Definition: var.c:12217
SCIP_CLIQUE ** SCIPgetCliques(SCIP *scip)
Definition: scip_var.c:7752
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:17583
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:18087
SCIP_RETCODE SCIPchgVarBranchDirection(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR branchdirection)
Definition: scip_var.c:8208
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:6843
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:6784
SCIP_RETCODE SCIPchgVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition: scip_var.c:8103
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:6755
SCIP_Real SCIPgetVarAvgCutoffsCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9824
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:17365
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17767
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17418
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:8658
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:8072
int SCIPgetNCliquesCreated(SCIP *scip)
Definition: scip_var.c:7725
SCIP_RETCODE SCIPcleanupCliques(SCIP *scip, SCIP_Bool *infeasible)
Definition: scip_var.c:7655
void SCIPvarMarkDeleteGlobalStructures(SCIP_VAR *var)
Definition: var.c:17675
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:18237
SCIP_Bool SCIPdoNotMultaggr(SCIP *scip)
Definition: scip_var.c:8698
SCIP_Real SCIPgetVarPseudocostVal(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta)
Definition: scip_var.c:8937
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:9426
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:9152
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:17609
SCIP_Real SCIPgetVarAvgCutoffs(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9796
SCIP_Real SCIPvarGetPseudoSol(SCIP_VAR *var)
Definition: var.c:18529
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:6732
SCIP_Bool SCIPallowDualReds(SCIP *scip)
Definition: scip_var.c:8737
SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:8299
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
Definition: var.c:18451
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:6586
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:9264
SCIP_Bool SCIPhaveVarsCommonClique(SCIP *scip, SCIP_VAR *var1, SCIP_Bool value1, SCIP_VAR *var2, SCIP_Bool value2, SCIP_Bool regardimplics)
Definition: scip_var.c:7782
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:6903
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:9121
int SCIPvarGetNCliques(SCIP_VAR *var, SCIP_Bool varfixing)
Definition: var.c:18429
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:18133
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:17573
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:6628
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:17355
SCIP_Real SCIPgetVarPseudocostValCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta)
Definition: scip_var.c:8965
SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
Definition: var.c:17903
SCIP_RETCODE SCIPupdateVarPseudocost(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
Definition: scip_var.c:8903
int SCIPgetNCliques(SCIP *scip)
Definition: scip_var.c:7698
SCIP_BDCHGINFO * SCIPvarGetUbchgInfo(SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: var.c:16632
SCIP_Real SCIPgetVarAvgGMIScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:10000
int SCIPvarGetBranchPriority(SCIP_VAR *var)
Definition: var.c:18249
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:8177
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:18077
SCIP_RETCODE SCIPmarkDoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8838
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition: scip_var.c:8399
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:9957
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:10055
SCIP_Real SCIPgetVarConflictScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9364
SCIP_RETCODE SCIPprintVar(SCIP *scip, SCIP_VAR *var, FILE *file)
Definition: scip_var.c:10117
SCIP_Real SCIPgetVarAvgCutoffScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9850
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:12309
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:10081
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:5846
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:9913
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:6607
SCIP_Real SCIPcomputeVarUbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6649
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:9300
SCIP_Bool SCIPvarsHaveCommonClique(SCIP_VAR *var1, SCIP_Bool value1, SCIP_VAR *var2, SCIP_Bool value2, SCIP_Bool regardimplics)
Definition: var.c:11474
SCIP_Real SCIPgetVarConflictlengthScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9457
SCIP_Real SCIPgetVarVSIDSCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9332
SCIP_Bool SCIPisStrongbranchDownFirst(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:2655
SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18669
void SCIPenableVarHistory(SCIP *scip)
Definition: scip_var.c:8864
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:8779
SCIP_Real SCIPgetVarPseudocostVariance(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun)
Definition: scip_var.c:9099
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:9395
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:9226
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:8805
SCIP_Real SCIPgetVarAvgInferences(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9542
SCIP_Bool SCIPallowStrongDualReds(SCIP *scip)
Definition: scip_var.c:8752
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:6243
SCIP_RETCODE SCIPvarsGetProbvarBinary(SCIP_VAR ***vars, SCIP_Bool **negatedarr, int nvars)
Definition: var.c:12277
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:9514
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:8016
SCIP_RETCODE SCIPtightenVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6351
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:6018
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:10880
SCIP_Bool SCIPstrToRealValue(const char *str, SCIP_Real *value, char **endptr)
Definition: misc.c:11008
void SCIPstrCopySection(const char *str, char startchar, char endchar, char *token, int size, char **endptr)
Definition: misc.c:11038
SCIP_RETCODE SCIPskipSpace(char **s)
Definition: misc.c:10869
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:13372
SCIP_Real SCIPlpGetLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13158
SCIP_RETCODE SCIPlpStartStrongbranch(SCIP_LP *lp)
Definition: lp.c:4180
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:13332
void SCIPcolInvalidateStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4264
SCIP_RETCODE SCIPcolGetStrongbranch(SCIP_COL *col, SCIP_Bool integral, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp, int itlim, SCIP_Bool updatecol, SCIP_Bool updatestat, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *lperror)
Definition: lp.c:4299
SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13119
SCIP_RETCODE SCIPlpEndStrongbranch(SCIP_LP *lp)
Definition: lp.c:4195
SCIP_Longint SCIPcolGetStrongbranchLPAge(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4739
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition: lp.c:17847
void SCIPcolGetStrongbranchLast(SCIP_COL *col, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Real *solval, SCIP_Real *lpobjval)
Definition: lp.c:4707
void SCIPlpStartStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16345
void SCIPlpEndStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16358
SCIP_Bool SCIPlpIsDualReliable(SCIP_LP *lp)
Definition: lp.c:17827
static const SCIP_Real scalars[]
Definition: lp.c:5743
void SCIPcolSetStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Real lpobjval, SCIP_Real primsol, SCIP_Real sbdown, SCIP_Real sbup, SCIP_Bool sbdownvalid, SCIP_Bool sbupvalid, SCIP_Longint iter, int itlim)
Definition: lp.c:4210
SCIP_RETCODE SCIPcolGetStrongbranches(SCIP_COL **cols, int ncols, SCIP_Bool integral, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *lperror)
Definition: lp.c:4484
internal methods for LP management
interface methods for specific LP solvers
memory allocation routines
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:134
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:130
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:57
SCIP_RETCODE SCIPprobAddVarName(SCIP_PROB *prob, SCIP_VAR *var)
Definition: prob.c:939
SCIP_RETCODE SCIPprobRemoveVarName(SCIP_PROB *prob, SCIP_VAR *var)
Definition: prob.c:955
SCIP_RETCODE SCIPprobChgVarType(SCIP_PROB *prob, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_VAR *var, SCIP_VARTYPE vartype)
Definition: prob.c:1175
SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
Definition: prob.c:2350
internal methods for storing and manipulating the main problem
public methods for managing constraints
public methods for implications, variable bounds, and cliques
public methods for LP management
public methods for message output
#define SCIPerrorMessage
Definition: pub_message.h:64
public data structures and miscellaneous methods
public methods for branch and bound tree
public methods for problem variables
SCIP_Bool SCIPrelaxationIsSolZero(SCIP_RELAXATION *relaxation)
Definition: relax.c:785
void SCIPrelaxationSetSolZero(SCIP_RELAXATION *relaxation, SCIP_Bool iszero)
Definition: relax.c:774
void SCIPrelaxationSetSolValid(SCIP_RELAXATION *relaxation, SCIP_Bool isvalid, SCIP_Bool includeslp)
Definition: relax.c:795
void SCIPrelaxationSetSolObj(SCIP_RELAXATION *relaxation, SCIP_Real obj)
Definition: relax.c:828
SCIP_Real SCIPrelaxationGetSolObj(SCIP_RELAXATION *relaxation)
Definition: relax.c:839
void SCIPrelaxationSetSolRelax(SCIP_RELAXATION *relaxation, SCIP_RELAX *relax)
Definition: relax.c:880
SCIP_Bool SCIPrelaxationIsSolValid(SCIP_RELAXATION *relaxation)
Definition: relax.c:808
internal methods for relaxators
general public methods
public methods for the LP relaxation, rows and columns
public methods for memory management
public methods for message handling
public methods for numerical tolerances
public methods for global and local (sub)problems
public methods for the probing mode
public methods for solutions
public methods for querying solving statistics
public methods for the branch-and-bound tree
static SCIP_RETCODE analyzeStrongbranch(SCIP *scip, SCIP_VAR *var, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *downconflict, SCIP_Bool *upconflict)
Definition: scip_var.c:2839
static SCIP_RETCODE calcCliquePartitionGreedy(SCIP *const scip, SCIP_VAR **const vars, SCIP_Bool *const values, int const nvars, int *const cliquepartition, int *const ncliques)
Definition: scip_var.c:7263
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:7137
static SCIP_RETCODE relabelOrderConsistent(SCIP *const scip, int *labels, int const nlabels, int *nclasses)
Definition: scip_var.c:7076
#define MAXNCLIQUEVARSCOMP
Definition: scip_var.c:7243
static SCIP_RETCODE tightenBounds(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:8225
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:8384
int SCIPtreeGetProbingDepth(SCIP_TREE *tree)
Definition: tree.c:8530
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:6500
SCIP_NODE * SCIPtreeGetCurrentNode(SCIP_TREE *tree)
Definition: tree.c:8485
SCIP_Bool SCIPtreeHasCurrentNodeLP(SCIP_TREE *tree)
Definition: tree.c:8519
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:1831
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:2106
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:6935
int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
Definition: tree.c:8502
internal methods for branch and bound tree
@ SCIP_BRANCHDIR_DOWNWARDS
Definition: type_history.h:43
@ SCIP_BRANCHDIR_UPWARDS
Definition: type_history.h:44
enum SCIP_BranchDir SCIP_BRANCHDIR
Definition: type_history.h:48
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition: type_lp.h:51
@ SCIP_BOUNDTYPE_UPPER
Definition: type_lp.h:57
@ SCIP_BOUNDTYPE_LOWER
Definition: type_lp.h:56
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:59
@ SCIP_LPSOLSTAT_ERROR
Definition: type_lp.h:49
@ SCIP_LPSOLSTAT_NOTSOLVED
Definition: type_lp.h:42
@ SCIP_LPSOLSTAT_OPTIMAL
Definition: type_lp.h:43
@ SCIP_LPSOLSTAT_TIMELIMIT
Definition: type_lp.h:48
@ SCIP_LPSOLSTAT_UNBOUNDEDRAY
Definition: type_lp.h:45
@ SCIP_LPSOLSTAT_INFEASIBLE
Definition: type_lp.h:44
@ SCIP_LPSOLSTAT_OBJLIMIT
Definition: type_lp.h:46
@ SCIP_LPSOLSTAT_ITERLIMIT
Definition: type_lp.h:47
enum SCIP_Confidencelevel SCIP_CONFIDENCELEVEL
Definition: type_misc.h:53
@ SCIP_READERROR
Definition: type_retcode.h:45
@ SCIP_INVALIDDATA
Definition: type_retcode.h:52
@ SCIP_OKAY
Definition: type_retcode.h:42
@ SCIP_INVALIDCALL
Definition: type_retcode.h:51
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
@ SCIP_STAGE_PROBLEM
Definition: type_set.h:45
@ SCIP_STAGE_INITPRESOLVE
Definition: type_set.h:48
@ SCIP_STAGE_SOLVED
Definition: type_set.h:54
@ SCIP_STAGE_PRESOLVING
Definition: type_set.h:49
@ SCIP_STAGE_TRANSFORMED
Definition: type_set.h:47
@ SCIP_STAGE_INITSOLVE
Definition: type_set.h:52
@ SCIP_STAGE_EXITPRESOLVE
Definition: type_set.h:50
@ SCIP_STAGE_EXITSOLVE
Definition: type_set.h:55
@ SCIP_STAGE_FREETRANS
Definition: type_set.h:56
@ SCIP_STAGE_SOLVING
Definition: type_set.h:53
@ SCIP_STAGE_TRANSFORMING
Definition: type_set.h:46
@ SCIP_STAGE_PRESOLVED
Definition: type_set.h:51
@ SCIP_STATUS_INFEASIBLE
Definition: type_stat.h:62
@ SCIP_NODETYPE_PROBINGNODE
Definition: type_tree.h:42
struct SCIP_VarData SCIP_VARDATA
Definition: type_var.h:120
#define NLOCKTYPES
Definition: type_var.h:94
#define SCIP_DECL_VARDELORIG(x)
Definition: type_var.h:131
#define SCIP_DECL_VARTRANS(x)
Definition: type_var.h:151
@ SCIP_VARTYPE_INTEGER
Definition: type_var.h:63
@ SCIP_VARTYPE_CONTINUOUS
Definition: type_var.h:71
@ SCIP_VARTYPE_IMPLINT
Definition: type_var.h:64
@ SCIP_VARTYPE_BINARY
Definition: type_var.h:62
@ SCIP_VARSTATUS_ORIGINAL
Definition: type_var.h:49
@ SCIP_VARSTATUS_FIXED
Definition: type_var.h:52
@ SCIP_VARSTATUS_COLUMN
Definition: type_var.h:51
@ SCIP_VARSTATUS_MULTAGGR
Definition: type_var.h:54
@ SCIP_VARSTATUS_NEGATED
Definition: type_var.h:55
@ SCIP_VARSTATUS_AGGREGATED
Definition: type_var.h:53
@ SCIP_VARSTATUS_LOOSE
Definition: type_var.h:50
#define SCIP_DECL_VARCOPY(x)
Definition: type_var.h:194
#define SCIP_DECL_VARDELTRANS(x)
Definition: type_var.h:164
enum SCIP_LockType SCIP_LOCKTYPE
Definition: type_var.h:100
@ SCIP_LOCKTYPE_MODEL
Definition: type_var.h:97
enum SCIP_Vartype SCIP_VARTYPE
Definition: type_var.h:73
enum SCIP_Varstatus SCIP_VARSTATUS
Definition: type_var.h:57
SCIP_RETCODE SCIPvarAddObj(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_Real addobj)
Definition: var.c:6339
SCIP_Real SCIPvarGetPseudocost(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real solvaldelta)
Definition: var.c:14476
SCIP_RETCODE SCIPvarsGetActiveVars(SCIP_SET *set, SCIP_VAR **vars, int *nvars, int varssize, int *requiredsize)
Definition: var.c:12005
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:15446
SCIP_RETCODE SCIPvarChgLbLazy(SCIP_VAR *var, SCIP_SET *set, SCIP_Real lazylb)
Definition: var.c:7469
SCIP_RETCODE SCIPvarCreateTransformed(SCIP_VAR **var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
Definition: var.c:2117
SCIP_Real SCIPvarGetPseudocostCount(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:14572
SCIP_RETCODE SCIPvarGetTransformed(SCIP_VAR *origvar, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR **transvar)
Definition: var.c:3548
SCIP_RETCODE SCIPvarChgObj(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_Real newobj)
Definition: var.c:6264
SCIP_Real SCIPvarGetPseudocostVariance(SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun)
Definition: var.c:14691
SCIP_Real SCIPvarGetImplRedcost(SCIP_VAR *var, SCIP_SET *set, SCIP_Bool varfixing, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp)
Definition: var.c:13467
SCIP_RETCODE SCIPvarSetLastGMIScore(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real gmieff)
Definition: var.c:16482
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:15530
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:15050
SCIP_Real SCIPvarGetAvgCutoffs(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:16264
SCIP_RETCODE SCIPvarUpdatePseudocost(SCIP_VAR *var, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
Definition: var.c:14378
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:16123
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:14197
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:15186
void SCIPvarAdjustLb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *lb)
Definition: var.c:6517
SCIP_RETCODE SCIPvarChgLbGlobal(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_Real newbound)
Definition: var.c:7185
SCIP_Real SCIPvarCalcPscostConfidenceBound(SCIP_VAR *var, SCIP_SET *set, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun, SCIP_CONFIDENCELEVEL clevel)
Definition: var.c:14745
SCIP_Bool SCIPvarIsPscostRelerrorReliable(SCIP_VAR *var, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real threshold, SCIP_CONFIDENCELEVEL clevel)
Definition: var.c:14783
SCIP_RETCODE SCIPvarChgLbOriginal(SCIP_VAR *var, SCIP_SET *set, SCIP_Real newbound)
Definition: var.c:6567
SCIP_RETCODE SCIPvarPrint(SCIP_VAR *var, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: var.c:3006
SCIP_Real SCIPvarGetAvgGMIScore(SCIP_VAR *var, SCIP_STAT *stat)
Definition: var.c:16358
SCIP_Real SCIPvarGetVSIDS(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:18542
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:15614
SCIP_Real SCIPvarGetMultaggrLbLocal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8434
SCIP_Bool SCIPvarSignificantPscostDifference(SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *varx, SCIP_Real fracx, SCIP_VAR *vary, SCIP_Real fracy, SCIP_BRANCHDIR dir, SCIP_CONFIDENCELEVEL clevel, SCIP_Bool onesided)
Definition: var.c:14860
void SCIPvarCapture(SCIP_VAR *var)
Definition: var.c:2847
SCIP_RETCODE SCIPvarChgBranchDirection(SCIP_VAR *var, SCIP_BRANCHDIR branchdirection)
Definition: var.c:11817
SCIP_Real SCIPvarGetPseudocostCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real solvaldelta)
Definition: var.c:14525
SCIP_Bool SCIPvarDoNotAggr(SCIP_VAR *var)
Definition: var.c:5848
SCIP_RETCODE SCIPvarChgType(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_VARTYPE vartype)
Definition: var.c:6178
SCIP_RETCODE SCIPvarFlattenAggregationGraph(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: var.c:4424
void SCIPvarUpdateBestRootSol(SCIP_VAR *var, SCIP_SET *set, SCIP_Real rootsol, SCIP_Real rootredcost, SCIP_Real rootlpobjval)
Definition: var.c:13279
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:15359
SCIP_Real SCIPvarGetPseudocostCountCurrentRun(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:14617
SCIP_RETCODE SCIPvarChgUbGlobal(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_Real newbound)
Definition: var.c:7328
SCIP_RETCODE SCIPvarGetActiveRepresentatives(SCIP_SET *set, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize, SCIP_Bool mergemultiples)
Definition: var.c:3929
SCIP_RETCODE SCIPvarParseTransformed(SCIP_VAR **var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, const char *str, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARCOPY((*varcopy)), SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_VARDATA *vardata, char **endptr, SCIP_Bool *success)
Definition: var.c:2560
SCIP_RETCODE SCIPvarChgUbOriginal(SCIP_VAR *var, SCIP_SET *set, SCIP_Real newbound)
Definition: var.c:6626
SCIP_Real SCIPvarGetAvgInferences(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:16066
SCIP_Real SCIPvarGetMultaggrUbGlobal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8632
void SCIPvarGetClosestVlb(SCIP_VAR *var, SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real *closestvlb, int *closestvlbidx)
Definition: var.c:14122
SCIP_RETCODE SCIPvarChgUbLazy(SCIP_VAR *var, SCIP_SET *set, SCIP_Real lazyub)
Definition: var.c:7492
SCIP_Bool SCIPvarPscostThresholdProbabilityTest(SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var, SCIP_Real frac, SCIP_Real threshold, SCIP_BRANCHDIR dir, SCIP_CONFIDENCELEVEL clevel)
Definition: var.c:14926
SCIP_RETCODE SCIPvarTryAggregateVars(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_CLIQUETABLE *cliquetable, SCIP_BRANCHCAND *branchcand, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_VAR *varx, SCIP_VAR *vary, SCIP_Real scalarx, SCIP_Real scalary, SCIP_Real rhs, SCIP_Bool *infeasible, SCIP_Bool *aggregated)
Definition: var.c:5292
SCIP_Real SCIPvarGetRelaxSol(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:13922
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:10911
SCIP_RETCODE SCIPvarMarkDoNotAggr(SCIP_VAR *var)
Definition: var.c:6106
SCIP_RETCODE SCIPvarChgLbLocal(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_Real newbound)
Definition: var.c:7970
SCIP_RETCODE SCIPvarChgBranchPriority(SCIP_VAR *var, int branchpriority)
Definition: var.c:11686
SCIP_RETCODE SCIPvarMarkDoNotMultaggr(SCIP_VAR *var)
Definition: var.c:6142
SCIP_RETCODE SCIPvarAddLocks(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LOCKTYPE locktype, int addnlocksdown, int addnlocksup)
Definition: var.c:3167
SCIP_RETCODE SCIPvarNegate(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR **negvar)
Definition: var.c:5917
SCIP_Real SCIPvarGetMultaggrUbLocal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8500
SCIP_RETCODE SCIPvarGetProbvarSum(SCIP_VAR **var, SCIP_SET *set, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12646
SCIP_RETCODE SCIPvarIncGMIeffSum(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real gmieff)
Definition: var.c:16398
SCIP_Real SCIPvarGetLastGMIScore(SCIP_VAR *var, SCIP_STAT *stat)
Definition: var.c:16442
void SCIPvarAdjustUb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *ub)
Definition: var.c:6534
SCIP_RETCODE SCIPvarMultiaggregate(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_CLIQUETABLE *cliquetable, SCIP_BRANCHCAND *branchcand, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, int naggvars, SCIP_VAR **aggvars, SCIP_Real *scalars, SCIP_Real constant, SCIP_Bool *infeasible, SCIP_Bool *aggregated)
Definition: var.c:5446
SCIP_Real SCIPvarGetAvgConflictlengthCurrentRun(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:15403
SCIP_RETCODE SCIPvarChgUbLocal(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_Real newbound)
Definition: var.c:8097
SCIP_RETCODE SCIPvarAddVlb(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_CLIQUETABLE *cliquetable, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_VAR *vlbvar, SCIP_Real vlbcoef, SCIP_Real vlbconstant, SCIP_Bool transitive, SCIP_Bool *infeasible, int *nbdchgs)
Definition: var.c:10000
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:15927
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:10464
SCIP_Real SCIPvarGetMultaggrLbGlobal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8566
SCIP_RETCODE SCIPvarSetRelaxSol(SCIP_VAR *var, SCIP_SET *set, SCIP_RELAXATION *relaxation, SCIP_Real solval, SCIP_Bool updateobj)
Definition: var.c:13861
SCIP_RETCODE SCIPvarChgBranchFactor(SCIP_VAR *var, SCIP_SET *set, SCIP_Real branchfactor)
Definition: var.c:11559
SCIP_Real SCIPvarGetAvgCutoffsCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:16311
SCIP_Bool SCIPvarDoNotMultaggr(SCIP_VAR *var)
Definition: var.c:5881
SCIP_RETCODE SCIPvarRemoveCliquesImplicsVbs(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_CLIQUETABLE *cliquetable, SCIP_SET *set, SCIP_Bool irrelevantvar, SCIP_Bool onlyredundant, SCIP_Bool removefromvar)
Definition: var.c:1609
internal methods for problem variables