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-2022 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file scip_var.c
17  * @ingroup OTHER_CFILES
18  * @brief public methods for SCIP variables
19  * @author Tobias Achterberg
20  * @author Timo Berthold
21  * @author Gerald Gamrath
22  * @author Leona Gottwald
23  * @author Stefan Heinz
24  * @author Gregor Hendel
25  * @author Thorsten Koch
26  * @author Alexander Martin
27  * @author Marc Pfetsch
28  * @author Michael Winkler
29  * @author Kati Wolter
30  *
31  * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE
32  */
33 
34 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
35 
36 #include "blockmemshell/memory.h"
37 #include "lpi/lpi.h"
38 #include "scip/branch.h"
39 #include "scip/clock.h"
40 #include "scip/conflict.h"
41 #include "scip/debug.h"
42 #include "scip/history.h"
43 #include "scip/implics.h"
44 #include "scip/lp.h"
45 #include "scip/prob.h"
46 #include "scip/pub_cons.h"
47 #include "scip/pub_implics.h"
48 #include "scip/pub_lp.h"
49 #include "scip/pub_message.h"
50 #include "scip/pub_misc.h"
51 #include "scip/pub_tree.h"
52 #include "scip/pub_var.h"
53 #include "scip/relax.h"
54 #include "scip/scip_general.h"
55 #include "scip/scip_lp.h"
56 #include "scip/scip_mem.h"
57 #include "scip/scip_message.h"
58 #include "scip/scip_numerics.h"
59 #include "scip/scip_prob.h"
60 #include "scip/scip_probing.h"
61 #include "scip/scip_sol.h"
62 #include "scip/scip_solvingstats.h"
63 #include "scip/scip_tree.h"
64 #include "scip/scip_var.h"
65 #include "scip/set.h"
66 #include "scip/sol.h"
67 #include "scip/solve.h"
68 #include "scip/stat.h"
69 #include "scip/struct_lp.h"
70 #include "scip/struct_mem.h"
71 #include "scip/struct_primal.h"
72 #include "scip/struct_prob.h"
73 #include "scip/struct_scip.h"
74 #include "scip/struct_set.h"
75 #include "scip/struct_stat.h"
76 #include "scip/struct_tree.h"
77 #include "scip/struct_var.h"
78 #include "scip/tree.h"
79 #include "scip/var.h"
80 #include <ctype.h>
81 
82 
83 /** creates and captures problem variable; if variable is of integral type, fractional bounds are automatically rounded;
84  * an integer variable with bounds zero and one is automatically converted into a binary variable;
85  *
86  * @warning When doing column generation and the original problem is a maximization problem, notice that SCIP will
87  * transform the problem into a minimization problem by multiplying the objective function by -1. Thus, the
88  * original objective function value of variables created during the solving process has to be multiplied by
89  * -1, too.
90  *
91  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
92  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
93  *
94  * @pre This method can be called if @p scip is in one of the following stages:
95  * - \ref SCIP_STAGE_PROBLEM
96  * - \ref SCIP_STAGE_TRANSFORMING
97  * - \ref SCIP_STAGE_INITPRESOLVE
98  * - \ref SCIP_STAGE_PRESOLVING
99  * - \ref SCIP_STAGE_EXITPRESOLVE
100  * - \ref SCIP_STAGE_PRESOLVED
101  * - \ref SCIP_STAGE_SOLVING
102  *
103  * @note the variable gets captured, hence at one point you have to release it using the method SCIPreleaseVar()
104  */
106  SCIP* scip, /**< SCIP data structure */
107  SCIP_VAR** var, /**< pointer to variable object */
108  const char* name, /**< name of variable, or NULL for automatic name creation */
109  SCIP_Real lb, /**< lower bound of variable */
110  SCIP_Real ub, /**< upper bound of variable */
111  SCIP_Real obj, /**< objective function value */
112  SCIP_VARTYPE vartype, /**< type of variable */
113  SCIP_Bool initial, /**< should var's column be present in the initial root LP? */
114  SCIP_Bool removable, /**< is var's column removable from the LP (due to aging or cleanup)? */
115  SCIP_DECL_VARDELORIG ((*vardelorig)), /**< frees user data of original variable, or NULL */
116  SCIP_DECL_VARTRANS ((*vartrans)), /**< creates transformed user data by transforming original user data, or NULL */
117  SCIP_DECL_VARDELTRANS ((*vardeltrans)), /**< frees user data of transformed variable, or NULL */
118  SCIP_DECL_VARCOPY ((*varcopy)), /**< copies variable data if wanted to subscip, or NULL */
119  SCIP_VARDATA* vardata /**< user data for this specific variable */
120  )
121 {
122  assert(var != NULL);
123  assert(lb <= ub);
124 
125  SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateVar", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
126 
127  /* forbid infinite objective function values */
128  if( SCIPisInfinity(scip, REALABS(obj)) )
129  {
130  SCIPerrorMessage("invalid objective function value: value is infinite\n");
131  return SCIP_INVALIDDATA;
132  }
133 
134  switch( scip->set->stage )
135  {
136  case SCIP_STAGE_PROBLEM:
137  SCIP_CALL( SCIPvarCreateOriginal(var, scip->mem->probmem, scip->set, scip->stat,
138  name, lb, ub, obj, vartype, initial, removable, vardelorig, vartrans, vardeltrans, varcopy, vardata) );
139  break;
140 
146  case SCIP_STAGE_SOLVING:
147  SCIP_CALL( SCIPvarCreateTransformed(var, scip->mem->probmem, scip->set, scip->stat,
148  name, lb, ub, obj, vartype, initial, removable, vardelorig, vartrans, vardeltrans, varcopy, vardata) );
149  break;
150 
151  default:
152  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
153  return SCIP_INVALIDCALL;
154  } /*lint !e788*/
155 
156  return SCIP_OKAY;
157 }
158 
159 /** creates and captures problem variable with optional callbacks and variable data set to NULL, which can be set
160  * afterwards using SCIPvarSetDelorigData(), SCIPvarSetTransData(),
161  * SCIPvarSetDeltransData(), SCIPvarSetCopy(), and SCIPvarSetData(); sets variable flags initial=TRUE
162  * and removable = FALSE, which can be adjusted by using SCIPvarSetInitial() and SCIPvarSetRemovable(), resp.;
163  * if variable is of integral type, fractional bounds are automatically rounded;
164  * an integer variable with bounds zero and one is automatically converted into a binary variable;
165  *
166  * @warning When doing column generation and the original problem is a maximization problem, notice that SCIP will
167  * transform the problem into a minimization problem by multiplying the objective function by -1. Thus, the
168  * original objective function value of variables created during the solving process has to be multiplied by
169  * -1, too.
170  *
171  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
172  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
173  *
174  * @pre This method can be called if @p scip is in one of the following stages:
175  * - \ref SCIP_STAGE_PROBLEM
176  * - \ref SCIP_STAGE_TRANSFORMING
177  * - \ref SCIP_STAGE_INITPRESOLVE
178  * - \ref SCIP_STAGE_PRESOLVING
179  * - \ref SCIP_STAGE_EXITPRESOLVE
180  * - \ref SCIP_STAGE_PRESOLVED
181  * - \ref SCIP_STAGE_SOLVING
182  *
183  * @note the variable gets captured, hence at one point you have to release it using the method SCIPreleaseVar()
184  */
186  SCIP* scip, /**< SCIP data structure */
187  SCIP_VAR** var, /**< pointer to variable object */
188  const char* name, /**< name of variable, or NULL for automatic name creation */
189  SCIP_Real lb, /**< lower bound of variable */
190  SCIP_Real ub, /**< upper bound of variable */
191  SCIP_Real obj, /**< objective function value */
192  SCIP_VARTYPE vartype /**< type of variable */
193  )
194 {
195  SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateVarBasic", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
196 
197  SCIP_CALL( SCIPcreateVar(scip, var, name, lb, ub, obj, vartype, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
198 
199  return SCIP_OKAY;
200 }
201 
202 /** outputs the variable name to the file stream
203  *
204  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
205  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
206  *
207  * @pre This method can be called if @p scip is in one of the following stages:
208  * - \ref SCIP_STAGE_PROBLEM
209  * - \ref SCIP_STAGE_TRANSFORMING
210  * - \ref SCIP_STAGE_TRANSFORMED
211  * - \ref SCIP_STAGE_INITPRESOLVE
212  * - \ref SCIP_STAGE_PRESOLVING
213  * - \ref SCIP_STAGE_EXITPRESOLVE
214  * - \ref SCIP_STAGE_PRESOLVED
215  * - \ref SCIP_STAGE_INITSOLVE
216  * - \ref SCIP_STAGE_SOLVING
217  * - \ref SCIP_STAGE_SOLVED
218  * - \ref SCIP_STAGE_EXITSOLVE
219  * - \ref SCIP_STAGE_FREETRANS
220  */
222  SCIP* scip, /**< SCIP data structure */
223  FILE* file, /**< output file, or NULL for stdout */
224  SCIP_VAR* var, /**< variable to output */
225  SCIP_Bool type /**< should the variable type be also posted */
226  )
227 {
228  assert(scip != NULL);
229  assert(var != NULL);
230 
231  SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarName", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
232 
233  /* print variable name */
234  if( SCIPvarIsNegated(var) )
235  {
236  SCIP_VAR* negatedvar;
237 
238  SCIP_CALL( SCIPgetNegatedVar(scip, var, &negatedvar) );
239  SCIPinfoMessage(scip, file, "<~%s>", SCIPvarGetName(negatedvar));
240  }
241  else
242  {
243  SCIPinfoMessage(scip, file, "<%s>", SCIPvarGetName(var));
244  }
245 
246  if( type )
247  {
248  /* print variable type */
249  SCIPinfoMessage(scip, file, "[%c]",
253  }
254 
255  return SCIP_OKAY;
256 }
257 
258 /** print the given list of variables to output stream separated by the given delimiter character;
259  *
260  * i. e. the variables x1, x2, ..., xn with given delimiter ',' are written as: <x1>, <x2>, ..., <xn>;
261  *
262  * the method SCIPparseVarsList() can parse such a string
263  *
264  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
265  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
266  *
267  * @pre This method can be called if @p scip is in one of the following stages:
268  * - \ref SCIP_STAGE_PROBLEM
269  * - \ref SCIP_STAGE_TRANSFORMING
270  * - \ref SCIP_STAGE_TRANSFORMED
271  * - \ref SCIP_STAGE_INITPRESOLVE
272  * - \ref SCIP_STAGE_PRESOLVING
273  * - \ref SCIP_STAGE_EXITPRESOLVE
274  * - \ref SCIP_STAGE_PRESOLVED
275  * - \ref SCIP_STAGE_INITSOLVE
276  * - \ref SCIP_STAGE_SOLVING
277  * - \ref SCIP_STAGE_SOLVED
278  * - \ref SCIP_STAGE_EXITSOLVE
279  * - \ref SCIP_STAGE_FREETRANS
280  *
281  * @note The printing process is done via the message handler system.
282  */
284  SCIP* scip, /**< SCIP data structure */
285  FILE* file, /**< output file, or NULL for stdout */
286  SCIP_VAR** vars, /**< variable array to output */
287  int nvars, /**< number of variables */
288  SCIP_Bool type, /**< should the variable type be also posted */
289  char delimiter /**< character which is used for delimitation */
290  )
291 {
292  int v;
293 
294  SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsList", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
295 
296  for( v = 0; v < nvars; ++v )
297  {
298  if( v > 0 )
299  {
300  SCIPinfoMessage(scip, file, "%c", delimiter);
301  }
302 
303  /* print variable name */
304  SCIP_CALL( SCIPwriteVarName(scip, file, vars[v], type) );
305  }
306 
307  return SCIP_OKAY;
308 }
309 
310 /** print the given variables and coefficients as linear sum in the following form
311  * c1 <x1> + c2 <x2> ... + cn <xn>
312  *
313  * This string can be parsed by the method SCIPparseVarsLinearsum().
314  *
315  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
316  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
317  *
318  * @pre This method can be called if @p scip is in one of the following stages:
319  * - \ref SCIP_STAGE_PROBLEM
320  * - \ref SCIP_STAGE_TRANSFORMING
321  * - \ref SCIP_STAGE_TRANSFORMED
322  * - \ref SCIP_STAGE_INITPRESOLVE
323  * - \ref SCIP_STAGE_PRESOLVING
324  * - \ref SCIP_STAGE_EXITPRESOLVE
325  * - \ref SCIP_STAGE_PRESOLVED
326  * - \ref SCIP_STAGE_INITSOLVE
327  * - \ref SCIP_STAGE_SOLVING
328  * - \ref SCIP_STAGE_SOLVED
329  * - \ref SCIP_STAGE_EXITSOLVE
330  * - \ref SCIP_STAGE_FREETRANS
331  *
332  * @note The printing process is done via the message handler system.
333  */
335  SCIP* scip, /**< SCIP data structure */
336  FILE* file, /**< output file, or NULL for stdout */
337  SCIP_VAR** vars, /**< variable array to output */
338  SCIP_Real* vals, /**< array of coefficients or NULL if all coefficients are 1.0 */
339  int nvars, /**< number of variables */
340  SCIP_Bool type /**< should the variable type be also posted */
341  )
342 {
343  int v;
344 
345  SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsLinearsum", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
346 
347  for( v = 0; v < nvars; ++v )
348  {
349  if( vals != NULL )
350  {
351  if( vals[v] == 1.0 )
352  {
353  if( v > 0 )
354  SCIPinfoMessage(scip, file, " +");
355  }
356  else if( vals[v] == -1.0 )
357  SCIPinfoMessage(scip, file, " -");
358  else
359  SCIPinfoMessage(scip, file, " %+.15g", vals[v]);
360  }
361  else if( nvars > 0 )
362  SCIPinfoMessage(scip, file, " +");
363 
364  /* print variable name */
365  SCIP_CALL( SCIPwriteVarName(scip, file, vars[v], type) );
366  }
367 
368  return SCIP_OKAY;
369 }
370 
371 /** print the given terms as signomial in the following form
372  * c1 <x11>^e11 <x12>^e12 ... <x1n>^e1n + c2 <x21>^e21 <x22>^e22 ... + ... + cn <xn1>^en1 ...
373  *
374  * This string can be parsed by the method SCIPparseVarsPolynomial().
375  *
376  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
377  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
378  *
379  * @pre This method can be called if @p scip is in one of the following stages:
380  * - \ref SCIP_STAGE_PROBLEM
381  * - \ref SCIP_STAGE_TRANSFORMING
382  * - \ref SCIP_STAGE_TRANSFORMED
383  * - \ref SCIP_STAGE_INITPRESOLVE
384  * - \ref SCIP_STAGE_PRESOLVING
385  * - \ref SCIP_STAGE_EXITPRESOLVE
386  * - \ref SCIP_STAGE_PRESOLVED
387  * - \ref SCIP_STAGE_INITSOLVE
388  * - \ref SCIP_STAGE_SOLVING
389  * - \ref SCIP_STAGE_SOLVED
390  * - \ref SCIP_STAGE_EXITSOLVE
391  * - \ref SCIP_STAGE_FREETRANS
392  *
393  * @note The printing process is done via the message handler system.
394  */
396  SCIP* scip, /**< SCIP data structure */
397  FILE* file, /**< output file, or NULL for stdout */
398  SCIP_VAR*** monomialvars, /**< arrays with variables for each monomial */
399  SCIP_Real** monomialexps, /**< arrays with variable exponents, or NULL if always 1.0 */
400  SCIP_Real* monomialcoefs, /**< array with monomial coefficients */
401  int* monomialnvars, /**< array with number of variables for each monomial */
402  int nmonomials, /**< number of monomials */
403  SCIP_Bool type /**< should the variable type be also posted */
404  )
405 {
406  int i;
407  int v;
408 
409  assert(scip != NULL);
410  assert(monomialvars != NULL || nmonomials == 0);
411  assert(monomialcoefs != NULL || nmonomials == 0);
412  assert(monomialnvars != NULL || nmonomials == 0);
413 
414  SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsPolynomial", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
415 
416  if( nmonomials == 0 )
417  {
418  SCIPinfoMessage(scip, file, " 0 ");
419  return SCIP_OKAY;
420  }
421 
422  for( i = 0; i < nmonomials; ++i )
423  {
424  if( monomialcoefs[i] == 1.0 ) /*lint !e613*/
425  {
426  if( i > 0 )
427  SCIPinfoMessage(scip, file, " +");
428  }
429  else if( monomialcoefs[i] == -1.0 ) /*lint !e613*/
430  SCIPinfoMessage(scip, file, " -");
431  else
432  SCIPinfoMessage(scip, file, " %+.15g", monomialcoefs[i]); /*lint !e613*/
433 
434  assert(monomialvars[i] != NULL || monomialnvars[i] == 0); /*lint !e613*/
435 
436  for( v = 0; v < monomialnvars[i]; ++v ) /*lint !e613*/
437  {
438  SCIP_CALL( SCIPwriteVarName(scip, file, monomialvars[i][v], type) ); /*lint !e613*/
439  if( monomialexps != NULL && monomialexps[i] != NULL && monomialexps[i][v] != 1.0 )
440  {
441  SCIPinfoMessage(scip, file, "^%.15g", monomialexps[i][v]);
442  }
443  }
444  }
445 
446  return SCIP_OKAY;
447 }
448 
449 /** parses variable information (in cip format) out of a string; if the parsing process was successful a variable is
450  * created and captured; if variable is of integral type, fractional bounds are automatically rounded; an integer
451  * variable with bounds zero and one is automatically converted into a binary variable
452  *
453  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
454  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
455  *
456  * @pre This method can be called if @p scip is in one of the following stages:
457  * - \ref SCIP_STAGE_PROBLEM
458  * - \ref SCIP_STAGE_TRANSFORMING
459  * - \ref SCIP_STAGE_INITPRESOLVE
460  * - \ref SCIP_STAGE_PRESOLVING
461  * - \ref SCIP_STAGE_EXITPRESOLVE
462  * - \ref SCIP_STAGE_PRESOLVED
463  * - \ref SCIP_STAGE_SOLVING
464  */
466  SCIP* scip, /**< SCIP data structure */
467  SCIP_VAR** var, /**< pointer to store the problem variable */
468  const char* str, /**< string to parse */
469  SCIP_Bool initial, /**< should var's column be present in the initial root LP? */
470  SCIP_Bool removable, /**< is var's column removable from the LP (due to aging or cleanup)? */
471  SCIP_DECL_VARCOPY ((*varcopy)), /**< copies variable data if wanted to subscip, or NULL */
472  SCIP_DECL_VARDELORIG ((*vardelorig)), /**< frees user data of original variable */
473  SCIP_DECL_VARTRANS ((*vartrans)), /**< creates transformed user data by transforming original user data */
474  SCIP_DECL_VARDELTRANS ((*vardeltrans)), /**< frees user data of transformed variable */
475  SCIP_VARDATA* vardata, /**< user data for this specific variable */
476  char** endptr, /**< pointer to store the final string position if successful */
477  SCIP_Bool* success /**< pointer store if the paring process was successful */
478  )
479 {
480  assert(var != NULL);
481 
482  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVar", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
483 
484  switch( scip->set->stage )
485  {
486  case SCIP_STAGE_PROBLEM:
487  SCIP_CALL( SCIPvarParseOriginal(var, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
488  str, initial, removable, varcopy, vardelorig, vartrans, vardeltrans, vardata, endptr, success) );
489  break;
490 
496  case SCIP_STAGE_SOLVING:
497  SCIP_CALL( SCIPvarParseTransformed(var, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
498  str, initial, removable, varcopy, vardelorig, vartrans, vardeltrans, vardata, endptr, success) );
499  break;
500 
501  default:
502  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
503  return SCIP_INVALIDCALL;
504  } /*lint !e788*/
505 
506  return SCIP_OKAY;
507 }
508 
509 /** parses the given string for a variable name and stores the variable in the corresponding pointer if such a variable
510  * exits and returns the position where the parsing stopped
511  *
512  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
513  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
514  *
515  * @pre This method can be called if @p scip is in one of the following stages:
516  * - \ref SCIP_STAGE_PROBLEM
517  * - \ref SCIP_STAGE_TRANSFORMING
518  * - \ref SCIP_STAGE_INITPRESOLVE
519  * - \ref SCIP_STAGE_PRESOLVING
520  * - \ref SCIP_STAGE_EXITPRESOLVE
521  * - \ref SCIP_STAGE_PRESOLVED
522  * - \ref SCIP_STAGE_SOLVING
523  */
525  SCIP* scip, /**< SCIP data structure */
526  const char* str, /**< string to parse */
527  SCIP_VAR** var, /**< pointer to store the problem variable, or NULL if it does not exit */
528  char** endptr /**< pointer to store the final string position if successful */
529  )
530 {
531  char varname[SCIP_MAXSTRLEN];
532 
533  assert(str != NULL);
534  assert(var != NULL);
535  assert(endptr != NULL);
536 
537  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarName", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
538 
539  SCIPstrCopySection(str, '<', '>', varname, SCIP_MAXSTRLEN, endptr);
540  assert(*endptr != NULL);
541 
542  if( *varname == '\0' )
543  {
544  SCIPerrorMessage("invalid variable name string given: could not find '<'\n");
545  return SCIP_INVALIDDATA;
546  }
547 
548  /* check if we have a negated variable */
549  if( *varname == '~' )
550  {
551  SCIPdebugMsg(scip, "parsed negated variable name <%s>\n", &varname[1]);
552 
553  /* search for the variable and ignore '~' */
554  (*var) = SCIPfindVar(scip, &varname[1]);
555 
556  if( *var != NULL )
557  {
558  SCIP_CALL( SCIPgetNegatedVar(scip, *var, var) );
559  }
560  }
561  else
562  {
563  SCIPdebugMsg(scip, "parsed variable name <%s>\n", varname);
564 
565  /* search for the variable */
566  (*var) = SCIPfindVar(scip, varname);
567  }
568 
569  str = *endptr;
570 
571  /* skip additional variable type marker */
572  if( *str == '[' && (str[1] == SCIP_VARTYPE_BINARY_CHAR || str[1] == SCIP_VARTYPE_INTEGER_CHAR ||
573  str[1] == SCIP_VARTYPE_IMPLINT_CHAR || str[1] == SCIP_VARTYPE_CONTINUOUS_CHAR ) && str[2] == ']' )
574  (*endptr) += 3;
575 
576  return SCIP_OKAY;
577 }
578 
579 /** parse the given string as variable list (here ',' is the delimiter)) (<x1>, <x2>, ..., <xn>) (see
580  * SCIPwriteVarsList() ); if it was successful, the pointer success is set to TRUE
581  *
582  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
583  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
584  *
585  * @pre This method can be called if @p scip is in one of the following stages:
586  * - \ref SCIP_STAGE_PROBLEM
587  * - \ref SCIP_STAGE_TRANSFORMING
588  * - \ref SCIP_STAGE_INITPRESOLVE
589  * - \ref SCIP_STAGE_PRESOLVING
590  * - \ref SCIP_STAGE_EXITPRESOLVE
591  * - \ref SCIP_STAGE_PRESOLVED
592  * - \ref SCIP_STAGE_SOLVING
593  *
594  * @note The pointer success in only set to FALSE in the case that a variable with a parsed variable name does not exist.
595  *
596  * @note If the number of (parsed) variables is greater than the available slots in the variable array, nothing happens
597  * except that the required size is stored in the corresponding integer; the reason for this approach is that we
598  * cannot reallocate memory, since we do not know how the memory has been allocated (e.g., by a C++ 'new' or SCIP
599  * memory functions).
600  */
602  SCIP* scip, /**< SCIP data structure */
603  const char* str, /**< string to parse */
604  SCIP_VAR** vars, /**< array to store the parsed variable */
605  int* nvars, /**< pointer to store number of parsed variables */
606  int varssize, /**< size of the variable array */
607  int* requiredsize, /**< pointer to store the required array size for the active variables */
608  char** endptr, /**< pointer to store the final string position if successful */
609  char delimiter, /**< character which is used for delimitation */
610  SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
611  )
612 {
613  SCIP_VAR** tmpvars;
614  SCIP_VAR* var;
615  int ntmpvars = 0;
616  int v;
617 
618  assert( nvars != NULL );
619  assert( requiredsize != NULL );
620  assert( endptr != NULL );
621  assert( success != NULL );
622 
623  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsList", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
624 
625  /* allocate buffer memory for temporary storing the parsed variables */
626  SCIP_CALL( SCIPallocBufferArray(scip, &tmpvars, varssize) );
627 
628  (*success) = TRUE;
629 
630  do
631  {
632  *endptr = (char*)str;
633 
634  /* parse variable name */
635  SCIP_CALL( SCIPparseVarName(scip, str, &var, endptr) );
636 
637  if( var == NULL )
638  {
639  SCIPdebugMsg(scip, "variable with name <%s> does not exist\n", SCIPvarGetName(var));
640  (*success) = FALSE;
641  break;
642  }
643 
644  /* store the variable in the tmp array */
645  if( ntmpvars < varssize )
646  tmpvars[ntmpvars] = var;
647 
648  ntmpvars++;
649 
650  str = *endptr;
651 
652  while( isspace((unsigned char)*str) )
653  str++;
654  }
655  while( *str == delimiter );
656 
657  *endptr = (char*)str;
658 
659  /* if all variable name searches were successful and the variable array has enough slots, copy the collected variables */
660  if( (*success) && ntmpvars <= varssize )
661  {
662  for( v = 0; v < ntmpvars; ++v )
663  vars[v] = tmpvars[v];
664 
665  (*nvars) = ntmpvars;
666  }
667  else
668  (*nvars) = 0;
669 
670  (*requiredsize) = ntmpvars;
671 
672  /* free buffer arrays */
673  SCIPfreeBufferArray(scip, &tmpvars);
674 
675  return SCIP_OKAY;
676 }
677 
678 /** parse the given string as linear sum of variables and coefficients (c1 <x1> + c2 <x2> + ... + cn <xn>)
679  * (see SCIPwriteVarsLinearsum() ); if it was successful, the pointer success is set to TRUE
680  *
681  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
682  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
683  *
684  * @pre This method can be called if @p scip is in one of the following stages:
685  * - \ref SCIP_STAGE_PROBLEM
686  * - \ref SCIP_STAGE_TRANSFORMING
687  * - \ref SCIP_STAGE_INITPRESOLVE
688  * - \ref SCIP_STAGE_PRESOLVING
689  * - \ref SCIP_STAGE_EXITPRESOLVE
690  * - \ref SCIP_STAGE_PRESOLVED
691  * - \ref SCIP_STAGE_SOLVING
692  *
693  * @note The pointer success in only set to FALSE in the case that a variable with a parsed variable name does not exist.
694  *
695  * @note If the number of (parsed) variables is greater than the available slots in the variable array, nothing happens
696  * except that the required size is stored in the corresponding integer; the reason for this approach is that we
697  * cannot reallocate memory, since we do not know how the memory has been allocated (e.g., by a C++ 'new' or SCIP
698  * memory functions).
699  */
701  SCIP* scip, /**< SCIP data structure */
702  const char* str, /**< string to parse */
703  SCIP_VAR** vars, /**< array to store the parsed variables */
704  SCIP_Real* vals, /**< array to store the parsed coefficients */
705  int* nvars, /**< pointer to store number of parsed variables */
706  int varssize, /**< size of the variable array */
707  int* requiredsize, /**< pointer to store the required array size for the active variables */
708  char** endptr, /**< pointer to store the final string position if successful */
709  SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
710  )
711 {
712  SCIP_VAR*** monomialvars;
713  SCIP_Real** monomialexps;
714  SCIP_Real* monomialcoefs;
715  int* monomialnvars;
716  int nmonomials;
717 
718  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsLinearsum", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
719 
720  assert(scip != NULL);
721  assert(str != NULL);
722  assert(vars != NULL || varssize == 0);
723  assert(vals != NULL || varssize == 0);
724  assert(nvars != NULL);
725  assert(requiredsize != NULL);
726  assert(endptr != NULL);
727  assert(success != NULL);
728 
729  *requiredsize = 0;
730 
731  SCIP_CALL( SCIPparseVarsPolynomial(scip, str, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, &nmonomials, endptr, success) );
732 
733  if( !*success )
734  {
735  assert(nmonomials == 0); /* SCIPparseVarsPolynomial should have freed all buffers, so no need to call free here */
736  return SCIP_OKAY;
737  }
738 
739  /* check if linear sum is just "0" */
740  if( nmonomials == 1 && monomialnvars[0] == 0 && monomialcoefs[0] == 0.0 )
741  {
742  *nvars = 0;
743  *requiredsize = 0;
744 
745  SCIPfreeParseVarsPolynomialData(scip, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, nmonomials);
746 
747  return SCIP_OKAY;
748  }
749 
750  *nvars = nmonomials;
751  *requiredsize = nmonomials;
752 
753  /* if we have enough slots in the variables array, copy variables over */
754  if( varssize >= nmonomials )
755  {
756  int v;
757 
758  for( v = 0; v < nmonomials; ++v )
759  {
760  if( monomialnvars[v] == 0 )
761  {
762  SCIPerrorMessage("constant in linear sum\n");
763  *success = FALSE;
764  break;
765  }
766  if( monomialnvars[v] > 1 || monomialexps[v][0] != 1.0 )
767  {
768  SCIPerrorMessage("nonlinear monomial in linear sum\n");
769  *success = FALSE;
770  break;
771  }
772  assert(monomialnvars[v] == 1);
773  assert(monomialvars[v][0] != NULL);
774  assert(monomialexps[v][0] == 1.0);
775 
776  vars[v] = monomialvars[v][0]; /*lint !e613*/
777  vals[v] = monomialcoefs[v]; /*lint !e613*/
778  }
779  }
780 
781  SCIPfreeParseVarsPolynomialData(scip, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, nmonomials);
782 
783  return SCIP_OKAY;
784 }
785 
786 /** parse the given string as signomial of variables and coefficients
787  * (c1 <x11>^e11 <x12>^e12 ... <x1n>^e1n + c2 <x21>^e21 <x22>^e22 ... + ... + cn <xn1>^en1 ...)
788  * (see SCIPwriteVarsPolynomial()); if it was successful, the pointer success is set to TRUE
789  *
790  * The user has to call SCIPfreeParseVarsPolynomialData(scip, monomialvars, monomialexps,
791  * monomialcoefs, monomialnvars, *nmonomials) short after SCIPparseVarsPolynomial to free all the
792  * allocated memory again.
793  *
794  * Parsing is stopped at the end of string (indicated by the \\0-character) or when no more monomials
795  * are recognized.
796  *
797  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
798  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
799  *
800  * @pre This method can be called if @p scip is in one of the following stages:
801  * - \ref SCIP_STAGE_PROBLEM
802  * - \ref SCIP_STAGE_TRANSFORMING
803  * - \ref SCIP_STAGE_INITPRESOLVE
804  * - \ref SCIP_STAGE_PRESOLVING
805  * - \ref SCIP_STAGE_EXITPRESOLVE
806  * - \ref SCIP_STAGE_PRESOLVED
807  * - \ref SCIP_STAGE_SOLVING
808  */
810  SCIP* scip, /**< SCIP data structure */
811  const char* str, /**< string to parse */
812  SCIP_VAR**** monomialvars, /**< pointer to store arrays with variables for each monomial */
813  SCIP_Real*** monomialexps, /**< pointer to store arrays with variable exponents */
814  SCIP_Real** monomialcoefs, /**< pointer to store array with monomial coefficients */
815  int** monomialnvars, /**< pointer to store array with number of variables for each monomial */
816  int* nmonomials, /**< pointer to store number of parsed monomials */
817  char** endptr, /**< pointer to store the final string position if successful */
818  SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
819  )
820 {
821  typedef enum
822  {
823  SCIPPARSEPOLYNOMIAL_STATE_BEGIN, /* we are at the beginning of a monomial */
824  SCIPPARSEPOLYNOMIAL_STATE_INTERMED, /* we are in between the factors of a monomial */
825  SCIPPARSEPOLYNOMIAL_STATE_COEF, /* we parse the coefficient of a monomial */
826  SCIPPARSEPOLYNOMIAL_STATE_VARS, /* we parse monomial variables */
827  SCIPPARSEPOLYNOMIAL_STATE_EXPONENT, /* we parse the exponent of a variable */
828  SCIPPARSEPOLYNOMIAL_STATE_END, /* we are at the end the polynomial */
829  SCIPPARSEPOLYNOMIAL_STATE_ERROR /* a parsing error occured */
830  } SCIPPARSEPOLYNOMIAL_STATES;
831 
832  SCIPPARSEPOLYNOMIAL_STATES state;
833  int monomialssize;
834 
835  /* data of currently parsed monomial */
836  int varssize;
837  int nvars;
838  SCIP_VAR** vars;
839  SCIP_Real* exponents;
840  SCIP_Real coef;
841 
842  assert(scip != NULL);
843  assert(str != NULL);
844  assert(monomialvars != NULL);
845  assert(monomialexps != NULL);
846  assert(monomialnvars != NULL);
847  assert(monomialcoefs != NULL);
848  assert(nmonomials != NULL);
849  assert(endptr != NULL);
850  assert(success != NULL);
851 
852  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsPolynomial", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
853 
854  *success = FALSE;
855  *nmonomials = 0;
856  monomialssize = 0;
857  *monomialvars = NULL;
858  *monomialexps = NULL;
859  *monomialcoefs = NULL;
860  *monomialnvars = NULL;
861 
862  /* initialize state machine */
863  state = SCIPPARSEPOLYNOMIAL_STATE_BEGIN;
864  varssize = 0;
865  nvars = 0;
866  vars = NULL;
867  exponents = NULL;
868  coef = SCIP_INVALID;
869 
870  SCIPdebugMsg(scip, "parsing polynomial from '%s'\n", str);
871 
872  while( *str && state != SCIPPARSEPOLYNOMIAL_STATE_END && state != SCIPPARSEPOLYNOMIAL_STATE_ERROR )
873  {
874  /* skip white space */
875  while( isspace((unsigned char)*str) )
876  str++;
877 
878  assert(state != SCIPPARSEPOLYNOMIAL_STATE_END);
879 
880  switch( state )
881  {
882  case SCIPPARSEPOLYNOMIAL_STATE_BEGIN:
883  {
884  if( coef != SCIP_INVALID ) /*lint !e777*/
885  {
886  SCIPdebugMsg(scip, "push monomial with coefficient <%g> and <%d> vars\n", coef, nvars);
887 
888  /* push previous monomial */
889  if( monomialssize <= *nmonomials )
890  {
891  monomialssize = SCIPcalcMemGrowSize(scip, *nmonomials+1);
892 
893  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, *nmonomials, monomialssize) );
894  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, *nmonomials, monomialssize) );
895  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, *nmonomials, monomialssize) );
896  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, *nmonomials, monomialssize) );
897  }
898 
899  if( nvars > 0 )
900  {
901  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*monomialvars)[*nmonomials], vars, nvars) ); /*lint !e866*/
902  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*monomialexps)[*nmonomials], exponents, nvars) ); /*lint !e866*/
903  }
904  else
905  {
906  (*monomialvars)[*nmonomials] = NULL;
907  (*monomialexps)[*nmonomials] = NULL;
908  }
909  (*monomialcoefs)[*nmonomials] = coef;
910  (*monomialnvars)[*nmonomials] = nvars;
911  ++*nmonomials;
912 
913  nvars = 0;
914  coef = SCIP_INVALID;
915  }
916 
917  if( *str == '<' )
918  {
919  /* there seem to come a variable at the beginning of a monomial
920  * so assume the coefficient is 1.0
921  */
922  state = SCIPPARSEPOLYNOMIAL_STATE_VARS;
923  coef = 1.0;
924  }
925  else if( *str == '-' || *str == '+' || isdigit(*str) )
926  state = SCIPPARSEPOLYNOMIAL_STATE_COEF;
927  else
928  state = SCIPPARSEPOLYNOMIAL_STATE_END;
929 
930  break;
931  }
932 
933  case SCIPPARSEPOLYNOMIAL_STATE_INTERMED:
934  {
935  if( *str == '<' )
936  {
937  /* there seem to come another variable */
938  state = SCIPPARSEPOLYNOMIAL_STATE_VARS;
939  }
940  else if( *str == '-' || *str == '+' || isdigit(*str) )
941  {
942  /* there seem to come a coefficient, which means the next monomial */
943  state = SCIPPARSEPOLYNOMIAL_STATE_BEGIN;
944  }
945  else /* since we cannot detect the symbols we stop parsing the polynomial */
946  state = SCIPPARSEPOLYNOMIAL_STATE_END;
947 
948  break;
949  }
950 
951  case SCIPPARSEPOLYNOMIAL_STATE_COEF:
952  {
953  if( *str == '+' && !isdigit(str[1]) )
954  {
955  /* only a plus sign, without number */
956  coef = 1.0;
957  ++str;
958  }
959  else if( *str == '-' && !isdigit(str[1]) )
960  {
961  /* only a minus sign, without number */
962  coef = -1.0;
963  ++str;
964  }
965  else if( SCIPstrToRealValue(str, &coef, endptr) )
966  {
967  str = *endptr;
968  }
969  else
970  {
971  SCIPerrorMessage("could not parse number in the beginning of '%s'\n", str);
972  state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
973  break;
974  }
975 
976  /* after the coefficient we go into the intermediate state, i.e., expecting next variables */
977  state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED; /*lint !e838*/
978 
979  break;
980  }
981 
982  case SCIPPARSEPOLYNOMIAL_STATE_VARS:
983  {
984  SCIP_VAR* var;
985 
986  assert(*str == '<');
987 
988  /* parse variable name */
989  SCIP_CALL( SCIPparseVarName(scip, str, &var, endptr) );
990 
991  /* check if variable name was parsed */
992  if( *endptr == str )
993  {
994  state = SCIPPARSEPOLYNOMIAL_STATE_END;
995  break;
996  }
997 
998  if( var == NULL )
999  {
1000  SCIPerrorMessage("did not find variable in the beginning of %s\n", str);
1001  state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
1002  break;
1003  }
1004 
1005  /* add variable to vars array */
1006  if( nvars + 1 > varssize )
1007  {
1008  varssize = SCIPcalcMemGrowSize(scip, nvars+1);
1009  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &vars, nvars, varssize) );
1010  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &exponents, nvars, varssize) );
1011  }
1012  assert(vars != NULL);
1013  assert(exponents != NULL);
1014 
1015  vars[nvars] = var;
1016  exponents[nvars] = 1.0;
1017  ++nvars;
1018 
1019  str = *endptr;
1020 
1021  if( *str == '^' )
1022  state = SCIPPARSEPOLYNOMIAL_STATE_EXPONENT;
1023  else
1024  state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED;
1025 
1026  break;
1027  }
1028 
1029  case SCIPPARSEPOLYNOMIAL_STATE_EXPONENT:
1030  {
1031  assert(*str == '^');
1032  assert(nvars > 0); /* we should be in a monomial that has already a variable */
1033  assert(exponents != NULL);
1034  ++str;
1035 
1036  if( !SCIPstrToRealValue(str, &exponents[nvars-1], endptr) )
1037  {
1038  SCIPerrorMessage("could not parse number in the beginning of '%s'\n", str);
1039  state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
1040  break;
1041  }
1042  str = *endptr;
1043 
1044  /* after the exponent we go into the intermediate state, i.e., expecting next variables */
1045  state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED; /*lint !e838*/
1046  break;
1047  }
1048 
1049  case SCIPPARSEPOLYNOMIAL_STATE_END:
1050  case SCIPPARSEPOLYNOMIAL_STATE_ERROR:
1051  default:
1052  SCIPerrorMessage("unexpected state\n");
1053  return SCIP_READERROR;
1054  }
1055  }
1056 
1057  /* set end pointer */
1058  *endptr = (char*)str;
1059 
1060  /* check state at end of string */
1061  switch( state )
1062  {
1063  case SCIPPARSEPOLYNOMIAL_STATE_BEGIN:
1064  case SCIPPARSEPOLYNOMIAL_STATE_END:
1065  case SCIPPARSEPOLYNOMIAL_STATE_INTERMED:
1066  {
1067  if( coef != SCIP_INVALID ) /*lint !e777*/
1068  {
1069  /* push last monomial */
1070  SCIPdebugMsg(scip, "push monomial with coefficient <%g> and <%d> vars\n", coef, nvars);
1071  if( monomialssize <= *nmonomials )
1072  {
1073  monomialssize = *nmonomials+1;
1074  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, *nmonomials, monomialssize) );
1075  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, *nmonomials, monomialssize) );
1076  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, *nmonomials, monomialssize) );
1077  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, *nmonomials, monomialssize) );
1078  }
1079 
1080  if( nvars > 0 )
1081  {
1082  /* shrink vars and exponents array to needed size and take over ownership */
1083  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &vars, varssize, nvars) );
1084  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &exponents, varssize, nvars) );
1085  (*monomialvars)[*nmonomials] = vars;
1086  (*monomialexps)[*nmonomials] = exponents;
1087  vars = NULL;
1088  exponents = NULL;
1089  }
1090  else
1091  {
1092  (*monomialvars)[*nmonomials] = NULL;
1093  (*monomialexps)[*nmonomials] = NULL;
1094  }
1095  (*monomialcoefs)[*nmonomials] = coef;
1096  (*monomialnvars)[*nmonomials] = nvars;
1097  ++*nmonomials;
1098  }
1099 
1100  *success = TRUE;
1101  break;
1102  }
1103 
1104  case SCIPPARSEPOLYNOMIAL_STATE_COEF:
1105  case SCIPPARSEPOLYNOMIAL_STATE_VARS:
1106  case SCIPPARSEPOLYNOMIAL_STATE_EXPONENT:
1107  {
1108  SCIPerrorMessage("unexpected parsing state at end of polynomial string\n");
1109  }
1110  /*lint -fallthrough*/
1111  case SCIPPARSEPOLYNOMIAL_STATE_ERROR:
1112  assert(!*success);
1113  break;
1114  }
1115 
1116  /* free memory to store current monomial, if still existing */
1117  SCIPfreeBlockMemoryArrayNull(scip, &vars, varssize);
1118  SCIPfreeBlockMemoryArrayNull(scip, &exponents, varssize);
1119 
1120  if( *success && *nmonomials > 0 )
1121  {
1122  /* shrink arrays to required size, so we do not need to keep monomialssize around */
1123  assert(*nmonomials <= monomialssize);
1124  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, monomialssize, *nmonomials) );
1125  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, monomialssize, *nmonomials) );
1126  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, monomialssize, *nmonomials) );
1127  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, monomialssize, *nmonomials) );
1128 
1129  /* SCIPwriteVarsPolynomial(scip, NULL, *monomialvars, *monomialexps, *monomialcoefs, *monomialnvars, *nmonomials, FALSE); */
1130  }
1131  else
1132  {
1133  /* in case of error, cleanup all data here */
1134  SCIPfreeParseVarsPolynomialData(scip, monomialvars, monomialexps, monomialcoefs, monomialnvars, *nmonomials);
1135  *nmonomials = 0;
1136  }
1137 
1138  return SCIP_OKAY;
1139 }
1140 
1141 /** frees memory allocated when parsing a signomial from a string
1142  *
1143  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1144  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1145  *
1146  * @pre This method can be called if @p scip is in one of the following stages:
1147  * - \ref SCIP_STAGE_PROBLEM
1148  * - \ref SCIP_STAGE_TRANSFORMING
1149  * - \ref SCIP_STAGE_INITPRESOLVE
1150  * - \ref SCIP_STAGE_PRESOLVING
1151  * - \ref SCIP_STAGE_EXITPRESOLVE
1152  * - \ref SCIP_STAGE_PRESOLVED
1153  * - \ref SCIP_STAGE_SOLVING
1154  */
1156  SCIP* scip, /**< SCIP data structure */
1157  SCIP_VAR**** monomialvars, /**< pointer to store arrays with variables for each monomial */
1158  SCIP_Real*** monomialexps, /**< pointer to store arrays with variable exponents */
1159  SCIP_Real** monomialcoefs, /**< pointer to store array with monomial coefficients */
1160  int** monomialnvars, /**< pointer to store array with number of variables for each monomial */
1161  int nmonomials /**< pointer to store number of parsed monomials */
1162  )
1163 {
1164  int i;
1165 
1166  assert(scip != NULL);
1167  assert(monomialvars != NULL);
1168  assert(monomialexps != NULL);
1169  assert(monomialcoefs != NULL);
1170  assert(monomialnvars != NULL);
1171  assert((*monomialvars != NULL) == (nmonomials > 0));
1172  assert((*monomialexps != NULL) == (nmonomials > 0));
1173  assert((*monomialcoefs != NULL) == (nmonomials > 0));
1174  assert((*monomialnvars != NULL) == (nmonomials > 0));
1175 
1176  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPfreeParseVarsPolynomialData", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1177 
1178  if( nmonomials == 0 )
1179  return;
1180 
1181  for( i = nmonomials - 1; i >= 0; --i )
1182  {
1183  SCIPfreeBlockMemoryArrayNull(scip, &(*monomialexps)[i], (*monomialnvars)[i]);
1184  SCIPfreeBlockMemoryArrayNull(scip, &(*monomialvars)[i], (*monomialnvars)[i]);
1185  }
1186 
1187  SCIPfreeBlockMemoryArray(scip, monomialcoefs, nmonomials);
1188  SCIPfreeBlockMemoryArray(scip, monomialnvars, nmonomials);
1189  SCIPfreeBlockMemoryArray(scip, monomialexps, nmonomials);
1190  SCIPfreeBlockMemoryArray(scip, monomialvars, nmonomials);
1191 }
1192 
1193 /** increases usage counter of variable
1194  *
1195  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1196  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1197  *
1198  * @pre This method can be called if @p scip is in one of the following stages:
1199  * - \ref SCIP_STAGE_PROBLEM
1200  * - \ref SCIP_STAGE_TRANSFORMING
1201  * - \ref SCIP_STAGE_TRANSFORMED
1202  * - \ref SCIP_STAGE_INITPRESOLVE
1203  * - \ref SCIP_STAGE_PRESOLVING
1204  * - \ref SCIP_STAGE_EXITPRESOLVE
1205  * - \ref SCIP_STAGE_PRESOLVED
1206  * - \ref SCIP_STAGE_INITSOLVE
1207  * - \ref SCIP_STAGE_SOLVING
1208  * - \ref SCIP_STAGE_SOLVED
1209  * - \ref SCIP_STAGE_EXITSOLVE
1210  */
1212  SCIP* scip, /**< SCIP data structure */
1213  SCIP_VAR* var /**< variable to capture */
1214  )
1215 {
1216  SCIP_CALL( SCIPcheckStage(scip, "SCIPcaptureVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1217  assert(var->scip == scip);
1218 
1219  SCIPvarCapture(var);
1220 
1221  return SCIP_OKAY;
1222 }
1223 
1224 /** decreases usage counter of variable, if the usage pointer reaches zero the variable gets freed
1225  *
1226  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1227  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1228  *
1229  * @pre This method can be called if @p scip is in one of the following stages:
1230  * - \ref SCIP_STAGE_PROBLEM
1231  * - \ref SCIP_STAGE_TRANSFORMING
1232  * - \ref SCIP_STAGE_TRANSFORMED
1233  * - \ref SCIP_STAGE_INITPRESOLVE
1234  * - \ref SCIP_STAGE_PRESOLVING
1235  * - \ref SCIP_STAGE_EXITPRESOLVE
1236  * - \ref SCIP_STAGE_PRESOLVED
1237  * - \ref SCIP_STAGE_INITSOLVE
1238  * - \ref SCIP_STAGE_SOLVING
1239  * - \ref SCIP_STAGE_SOLVED
1240  * - \ref SCIP_STAGE_EXITSOLVE
1241  * - \ref SCIP_STAGE_FREETRANS
1242  *
1243  * @note the pointer of the variable will be NULLed
1244  */
1246  SCIP* scip, /**< SCIP data structure */
1247  SCIP_VAR** var /**< pointer to variable */
1248  )
1249 {
1250  assert(var != NULL);
1251  assert(*var != NULL);
1252  assert((*var)->scip == scip);
1253 
1254  SCIP_CALL( SCIPcheckStage(scip, "SCIPreleaseVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1255 
1256  switch( scip->set->stage )
1257  {
1258  case SCIP_STAGE_PROBLEM:
1259  SCIP_CALL( SCIPvarRelease(var, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp) );
1260  return SCIP_OKAY;
1261 
1265  case SCIP_STAGE_PRESOLVING:
1267  case SCIP_STAGE_PRESOLVED:
1268  case SCIP_STAGE_INITSOLVE:
1269  case SCIP_STAGE_SOLVING:
1270  case SCIP_STAGE_SOLVED:
1271  case SCIP_STAGE_EXITSOLVE:
1272  case SCIP_STAGE_FREETRANS:
1273  if( !SCIPvarIsTransformed(*var) && (*var)->nuses == 1 && (*var)->data.original.transvar != NULL )
1274  {
1275  SCIPerrorMessage("cannot release last use of original variable while associated transformed variable exists\n");
1276  return SCIP_INVALIDCALL;
1277  }
1278  SCIP_CALL( SCIPvarRelease(var, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp) );
1279  return SCIP_OKAY;
1280 
1281  default:
1282  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
1283  return SCIP_INVALIDCALL;
1284  } /*lint !e788*/
1285 }
1286 
1287 /** changes the name of a variable
1288  *
1289  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1290  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1291  *
1292  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PROBLEM
1293  *
1294  * @note to get the current name of a variable, use SCIPvarGetName() from pub_var.h
1295  */
1297  SCIP* scip, /**< SCIP data structure */
1298  SCIP_VAR* var, /**< variable */
1299  const char* name /**< new name of constraint */
1300  )
1301 {
1302  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarName", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
1303  assert( var->scip == scip );
1304 
1305  if( SCIPgetStage(scip) != SCIP_STAGE_PROBLEM )
1306  {
1307  SCIPerrorMessage("variable names can only be changed in problem creation stage\n");
1308  SCIPABORT();
1309  return SCIP_INVALIDCALL; /*lint !e527*/
1310  }
1311 
1312  /* remove variable's name from the namespace if the variable was already added */
1313  if( SCIPvarGetProbindex(var) != -1 )
1314  {
1315  SCIP_CALL( SCIPprobRemoveVarName(scip->origprob, var) );
1316  }
1317 
1318  /* change variable name */
1319  SCIP_CALL( SCIPvarChgName(var, SCIPblkmem(scip), name) );
1320 
1321  /* add variable's name to the namespace if the variable was already added */
1322  if( SCIPvarGetProbindex(var) != -1 )
1323  {
1324  SCIP_CALL( SCIPprobAddVarName(scip->origprob, var) );
1325  }
1326 
1327  return SCIP_OKAY;
1328 }
1329 
1330 /** gets and captures transformed variable of a given variable; if the variable is not yet transformed,
1331  * a new transformed variable for this variable is created
1332  *
1333  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1334  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1335  *
1336  * @pre This method can be called if @p scip is in one of the following stages:
1337  * - \ref SCIP_STAGE_TRANSFORMING
1338  * - \ref SCIP_STAGE_TRANSFORMED
1339  * - \ref SCIP_STAGE_INITPRESOLVE
1340  * - \ref SCIP_STAGE_PRESOLVING
1341  * - \ref SCIP_STAGE_EXITPRESOLVE
1342  * - \ref SCIP_STAGE_PRESOLVED
1343  * - \ref SCIP_STAGE_INITSOLVE
1344  * - \ref SCIP_STAGE_SOLVING
1345  */
1347  SCIP* scip, /**< SCIP data structure */
1348  SCIP_VAR* var, /**< variable to get/create transformed variable for */
1349  SCIP_VAR** transvar /**< pointer to store the transformed variable */
1350  )
1351 {
1352  assert(transvar != NULL);
1353 
1354  SCIP_CALL( SCIPcheckStage(scip, "SCIPtransformVar", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1355 
1356  if( SCIPvarIsTransformed(var) )
1357  {
1358  *transvar = var;
1359  SCIPvarCapture(*transvar);
1360  }
1361  else
1362  {
1363  SCIP_CALL( SCIPvarTransform(var, scip->mem->probmem, scip->set, scip->stat, scip->origprob->objsense, transvar) );
1364  }
1365 
1366  return SCIP_OKAY;
1367 }
1368 
1369 /** gets and captures transformed variables for an array of variables;
1370  * if a variable of the array is not yet transformed, a new transformed variable for this variable is created;
1371  * it is possible to call this method with vars == transvars
1372  *
1373  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1374  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1375  *
1376  * @pre This method can be called if @p scip is in one of the following stages:
1377  * - \ref SCIP_STAGE_TRANSFORMING
1378  * - \ref SCIP_STAGE_TRANSFORMED
1379  * - \ref SCIP_STAGE_INITPRESOLVE
1380  * - \ref SCIP_STAGE_PRESOLVING
1381  * - \ref SCIP_STAGE_EXITPRESOLVE
1382  * - \ref SCIP_STAGE_PRESOLVED
1383  * - \ref SCIP_STAGE_INITSOLVE
1384  * - \ref SCIP_STAGE_SOLVING
1385  */
1387  SCIP* scip, /**< SCIP data structure */
1388  int nvars, /**< number of variables to get/create transformed variables for */
1389  SCIP_VAR** vars, /**< array with variables to get/create transformed variables for */
1390  SCIP_VAR** transvars /**< array to store the transformed variables */
1391  )
1392 {
1393  int v;
1394 
1395  assert(nvars == 0 || vars != NULL);
1396  assert(nvars == 0 || transvars != NULL);
1397 
1398  SCIP_CALL( SCIPcheckStage(scip, "SCIPtransformVars", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1399 
1400  for( v = 0; v < nvars; ++v )
1401  {
1402  if( SCIPvarIsTransformed(vars[v]) )
1403  {
1404  transvars[v] = vars[v];
1405  SCIPvarCapture(transvars[v]);
1406  }
1407  else
1408  {
1409  SCIP_CALL( SCIPvarTransform(vars[v], scip->mem->probmem, scip->set, scip->stat, scip->origprob->objsense,
1410  &transvars[v]) );
1411  }
1412  }
1413 
1414  return SCIP_OKAY;
1415 }
1416 
1417 /** gets corresponding transformed variable of a given variable;
1418  * returns NULL as transvar, if transformed variable is not yet existing
1419  *
1420  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1421  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1422  *
1423  * @pre This method can be called if @p scip is in one of the following stages:
1424  * - \ref SCIP_STAGE_TRANSFORMING
1425  * - \ref SCIP_STAGE_TRANSFORMED
1426  * - \ref SCIP_STAGE_INITPRESOLVE
1427  * - \ref SCIP_STAGE_PRESOLVING
1428  * - \ref SCIP_STAGE_EXITPRESOLVE
1429  * - \ref SCIP_STAGE_PRESOLVED
1430  * - \ref SCIP_STAGE_INITSOLVE
1431  * - \ref SCIP_STAGE_SOLVING
1432  * - \ref SCIP_STAGE_SOLVED
1433  * - \ref SCIP_STAGE_EXITSOLVE
1434  * - \ref SCIP_STAGE_FREETRANS
1435  */
1437  SCIP* scip, /**< SCIP data structure */
1438  SCIP_VAR* var, /**< variable to get transformed variable for */
1439  SCIP_VAR** transvar /**< pointer to store the transformed variable */
1440  )
1441 {
1442  assert(transvar != NULL);
1443 
1444  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetTransformedVar", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1445 
1446  if( SCIPvarIsTransformed(var) )
1447  *transvar = var;
1448  else
1449  {
1450  SCIP_CALL( SCIPvarGetTransformed(var, scip->mem->probmem, scip->set, scip->stat, transvar) );
1451  }
1452 
1453  return SCIP_OKAY;
1454 }
1455 
1456 /** gets corresponding transformed variables for an array of variables;
1457  * stores NULL in a transvars slot, if the transformed variable is not yet existing;
1458  * it is possible to call this method with vars == transvars, but remember that variables that are not
1459  * yet transformed will be replaced with NULL
1460  *
1461  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1462  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1463  *
1464  * @pre This method can be called if @p scip is in one of the following stages:
1465  * - \ref SCIP_STAGE_TRANSFORMING
1466  * - \ref SCIP_STAGE_TRANSFORMED
1467  * - \ref SCIP_STAGE_INITPRESOLVE
1468  * - \ref SCIP_STAGE_PRESOLVING
1469  * - \ref SCIP_STAGE_EXITPRESOLVE
1470  * - \ref SCIP_STAGE_PRESOLVED
1471  * - \ref SCIP_STAGE_INITSOLVE
1472  * - \ref SCIP_STAGE_SOLVING
1473  * - \ref SCIP_STAGE_SOLVED
1474  * - \ref SCIP_STAGE_EXITSOLVE
1475  * - \ref SCIP_STAGE_FREETRANS
1476  */
1478  SCIP* scip, /**< SCIP data structure */
1479  int nvars, /**< number of variables to get transformed variables for */
1480  SCIP_VAR** vars, /**< array with variables to get transformed variables for */
1481  SCIP_VAR** transvars /**< array to store the transformed variables */
1482  )
1483 {
1484  int v;
1485 
1486  assert(nvars == 0 || vars != NULL);
1487  assert(nvars == 0 || transvars != NULL);
1488 
1489  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetTransformedVars", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1490 
1491  for( v = 0; v < nvars; ++v )
1492  {
1493  if( SCIPvarIsTransformed(vars[v]) )
1494  transvars[v] = vars[v];
1495  else
1496  {
1497  SCIP_CALL( SCIPvarGetTransformed(vars[v], scip->mem->probmem, scip->set, scip->stat, &transvars[v]) );
1498  }
1499  }
1500 
1501  return SCIP_OKAY;
1502 }
1503 
1504 /** gets negated variable x' = lb + ub - x of variable x; negated variable is created, if not yet existing;
1505  * in difference to \ref SCIPcreateVar, the negated variable must not be released (unless captured explicitly)
1506  *
1507  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1508  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1509  *
1510  * @pre This method can be called if @p scip is in one of the following stages:
1511  * - \ref SCIP_STAGE_PROBLEM
1512  * - \ref SCIP_STAGE_TRANSFORMING
1513  * - \ref SCIP_STAGE_TRANSFORMED
1514  * - \ref SCIP_STAGE_INITPRESOLVE
1515  * - \ref SCIP_STAGE_PRESOLVING
1516  * - \ref SCIP_STAGE_EXITPRESOLVE
1517  * - \ref SCIP_STAGE_PRESOLVED
1518  * - \ref SCIP_STAGE_INITSOLVE
1519  * - \ref SCIP_STAGE_SOLVING
1520  * - \ref SCIP_STAGE_SOLVED
1521  * - \ref SCIP_STAGE_EXITSOLVE
1522  * - \ref SCIP_STAGE_FREETRANS
1523  */
1525  SCIP* scip, /**< SCIP data structure */
1526  SCIP_VAR* var, /**< variable to get negated variable for */
1527  SCIP_VAR** negvar /**< pointer to store the negated variable */
1528  )
1529 {
1530  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNegatedVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1531  assert( var->scip == scip );
1532 
1533  SCIP_CALL( SCIPvarNegate(var, scip->mem->probmem, scip->set, scip->stat, negvar) );
1534 
1535  return SCIP_OKAY;
1536 }
1537 
1538 /** gets negated variables x' = lb + ub - x of variables x; negated variables are created, if not yet existing
1539  *
1540  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1541  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1542  *
1543  * @pre This method can be called if @p scip is in one of the following stages:
1544  * - \ref SCIP_STAGE_PROBLEM
1545  * - \ref SCIP_STAGE_TRANSFORMING
1546  * - \ref SCIP_STAGE_TRANSFORMED
1547  * - \ref SCIP_STAGE_INITPRESOLVE
1548  * - \ref SCIP_STAGE_PRESOLVING
1549  * - \ref SCIP_STAGE_EXITPRESOLVE
1550  * - \ref SCIP_STAGE_PRESOLVED
1551  * - \ref SCIP_STAGE_INITSOLVE
1552  * - \ref SCIP_STAGE_SOLVING
1553  * - \ref SCIP_STAGE_SOLVED
1554  * - \ref SCIP_STAGE_EXITSOLVE
1555  * - \ref SCIP_STAGE_FREETRANS
1556  */
1558  SCIP* scip, /**< SCIP data structure */
1559  int nvars, /**< number of variables to get negated variables for */
1560  SCIP_VAR** vars, /**< array of variables to get negated variables for */
1561  SCIP_VAR** negvars /**< array to store the negated variables */
1562  )
1563 {
1564  int v;
1565 
1566  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNegatedVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1567 
1568  for( v = 0; v < nvars; ++v )
1569  {
1570  SCIP_CALL( SCIPvarNegate(vars[v], scip->mem->probmem, scip->set, scip->stat, &(negvars[v])) );
1571  }
1572 
1573  return SCIP_OKAY;
1574 }
1575 
1576 /** gets a binary variable that is equal to the given binary variable, and that is either active, fixed, or
1577  * multi-aggregated, or the negated variable of an active, fixed, or multi-aggregated variable
1578  *
1579  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1580  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1581  *
1582  * @pre This method can be called if @p scip is in one of the following stages:
1583  * - \ref SCIP_STAGE_PROBLEM
1584  * - \ref SCIP_STAGE_TRANSFORMED
1585  * - \ref SCIP_STAGE_INITPRESOLVE
1586  * - \ref SCIP_STAGE_PRESOLVING
1587  * - \ref SCIP_STAGE_EXITPRESOLVE
1588  * - \ref SCIP_STAGE_PRESOLVED
1589  * - \ref SCIP_STAGE_INITSOLVE
1590  * - \ref SCIP_STAGE_SOLVING
1591  * - \ref SCIP_STAGE_SOLVED
1592  * - \ref SCIP_STAGE_EXITSOLVE
1593  */
1595  SCIP* scip, /**< SCIP data structure */
1596  SCIP_VAR* var, /**< binary variable to get binary representative for */
1597  SCIP_VAR** repvar, /**< pointer to store the binary representative */
1598  SCIP_Bool* negated /**< pointer to store whether the negation of an active variable was returned */
1599  )
1600 {
1601  assert(scip != NULL);
1602  assert(var != NULL);
1603  assert(repvar != NULL);
1604  assert(negated != NULL);
1605  assert(var->scip == scip);
1606 
1607  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetBinvarRepresentative", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1608 
1609  /* get the active representative of the given variable */
1610  *repvar = var;
1611  *negated = FALSE;
1612  SCIP_CALL( SCIPvarGetProbvarBinary(repvar, negated) );
1613 
1614  /* negate the representative, if it corresponds to the negation of the given variable */
1615  if( *negated )
1616  {
1617  SCIP_CALL( SCIPgetNegatedVar(scip, *repvar, repvar) );
1618  }
1619 
1620  return SCIP_OKAY;
1621 }
1622 
1623 /** gets binary variables that are equal to the given binary variables, and which are either active, fixed, or
1624  * multi-aggregated, or the negated variables of active, fixed, or multi-aggregated variables
1625  *
1626  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1627  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1628  *
1629  * @pre This method can be called if @p scip is in one of the following stages:
1630  * - \ref SCIP_STAGE_PROBLEM
1631  * - \ref SCIP_STAGE_TRANSFORMED
1632  * - \ref SCIP_STAGE_INITPRESOLVE
1633  * - \ref SCIP_STAGE_PRESOLVING
1634  * - \ref SCIP_STAGE_EXITPRESOLVE
1635  * - \ref SCIP_STAGE_PRESOLVED
1636  * - \ref SCIP_STAGE_INITSOLVE
1637  * - \ref SCIP_STAGE_SOLVING
1638  * - \ref SCIP_STAGE_SOLVED
1639  * - \ref SCIP_STAGE_EXITSOLVE
1640  */
1642  SCIP* scip, /**< SCIP data structure */
1643  int nvars, /**< number of binary variables to get representatives for */
1644  SCIP_VAR** vars, /**< binary variables to get binary representatives for */
1645  SCIP_VAR** repvars, /**< array to store the binary representatives */
1646  SCIP_Bool* negated /**< array to store whether the negation of an active variable was returned */
1647  )
1648 {
1649  int v;
1650 
1651  assert(scip != NULL);
1652  assert(vars != NULL || nvars == 0);
1653  assert(repvars != NULL || nvars == 0);
1654  assert(negated != NULL || nvars == 0);
1655 
1656  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetBinvarRepresentatives", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1657 
1658  if( nvars == 0 )
1659  return SCIP_OKAY;
1660 
1661  /* get the active representative of the given variable */
1662  BMScopyMemoryArray(repvars, vars, nvars);
1663  BMSclearMemoryArray(negated, nvars);
1664  SCIP_CALL( SCIPvarsGetProbvarBinary(&repvars, &negated, nvars) );
1665 
1666  /* negate the representatives, if they correspond to the negation of the given variables */
1667  for( v = nvars - 1; v >= 0; --v )
1668  if( negated[v] )
1669  {
1670  SCIP_CALL( SCIPgetNegatedVar(scip, repvars[v], &(repvars[v])) );
1671  }
1672 
1673  return SCIP_OKAY;
1674 }
1675 
1676 /** flattens aggregation graph of multi-aggregated variable in order to avoid exponential recursion later on
1677  *
1678  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1679  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1680  *
1681  * @pre This method can be called if @p scip is in one of the following stages:
1682  * - \ref SCIP_STAGE_INITPRESOLVE
1683  * - \ref SCIP_STAGE_PRESOLVING
1684  * - \ref SCIP_STAGE_EXITPRESOLVE
1685  * - \ref SCIP_STAGE_PRESOLVED
1686  * - \ref SCIP_STAGE_INITSOLVE
1687  * - \ref SCIP_STAGE_SOLVING
1688  * - \ref SCIP_STAGE_SOLVED
1689  */
1691  SCIP* scip, /**< SCIP data structure */
1692  SCIP_VAR* var /**< problem variable */
1693  )
1694 {
1695  assert( scip != NULL );
1696  assert( var != NULL );
1697  SCIP_CALL( SCIPcheckStage(scip, "SCIPflattenVarAggregationGraph", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
1698 
1699  SCIP_CALL( SCIPvarFlattenAggregationGraph(var, scip->mem->probmem, scip->set, scip->eventqueue) );
1700 
1701  return SCIP_OKAY;
1702 }
1703 
1704 /** Transforms a given linear sum of variables, that is a_1*x_1 + ... + a_n*x_n + c into a corresponding linear sum of
1705  * active variables, that is b_1*y_1 + ... + b_m*y_m + d.
1706  *
1707  * If the number of needed active variables is greater than the available slots in the variable array, nothing happens
1708  * except that the required size is stored in the corresponding variable (requiredsize). Otherwise, the active variable
1709  * representation is stored in the variable array, scalar array and constant.
1710  *
1711  * The reason for this approach is that we cannot reallocate memory, since we do not know how the memory has been
1712  * allocated (e.g., by a C++ 'new' or SCIP functions).
1713  *
1714  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1715  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1716  *
1717  * @pre This method can be called if @p scip is in one of the following stages:
1718  * - \ref SCIP_STAGE_TRANSFORMED
1719  * - \ref SCIP_STAGE_INITPRESOLVE
1720  * - \ref SCIP_STAGE_PRESOLVING
1721  * - \ref SCIP_STAGE_EXITPRESOLVE
1722  * - \ref SCIP_STAGE_PRESOLVED
1723  * - \ref SCIP_STAGE_INITSOLVE
1724  * - \ref SCIP_STAGE_SOLVING
1725  * - \ref SCIP_STAGE_SOLVED
1726  * - \ref SCIP_STAGE_EXITSOLVE
1727  * - \ref SCIP_STAGE_FREETRANS
1728  *
1729  * @note The resulting linear sum is stored into the given variable array, scalar array, and constant. That means the
1730  * given entries are overwritten.
1731  *
1732  * @note That method can be used to convert a single variables into variable space of active variables. Therefore call
1733  * the method with the linear sum 1.0*x + 0.0.
1734  */
1736  SCIP* scip, /**< SCIP data structure */
1737  SCIP_VAR** vars, /**< variable array x_1, ..., x_n in the linear sum which will be
1738  * overwritten by the variable array y_1, ..., y_m in the linear sum
1739  * w.r.t. active variables */
1740  SCIP_Real* scalars, /**< scalars a_1, ..., a_n in linear sum which will be overwritten to the
1741  * scalars b_1, ..., b_m in the linear sum of the active variables */
1742  int* nvars, /**< pointer to number of variables in the linear sum which will be
1743  * overwritten by the number of variables in the linear sum corresponding
1744  * to the active variables */
1745  int varssize, /**< available slots in vars and scalars array which is needed to check if
1746  * the array are large enough for the linear sum w.r.t. active
1747  * variables */
1748  SCIP_Real* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c which
1749  * will chnage to constant d in the linear sum b_1*y_1 + ... + b_m*y_m +
1750  * d w.r.t. the active variables */
1751  int* requiredsize, /**< pointer to store the required array size for the linear sum w.r.t. the
1752  * active variables */
1753  SCIP_Bool mergemultiples /**< should multiple occurrences of a var be replaced by a single coeff? */
1754  )
1755 {
1756  assert( scip != NULL );
1757  assert( nvars != NULL );
1758  assert( vars != NULL || *nvars == 0 );
1759  assert( scalars != NULL || *nvars == 0 );
1760  assert( constant != NULL );
1761  assert( requiredsize != NULL );
1762  assert( *nvars <= varssize );
1763 
1764  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetProbvarLinearSum", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1765  SCIP_CALL( SCIPvarGetActiveRepresentatives(scip->set, vars, scalars, nvars, varssize, constant, requiredsize, mergemultiples) );
1766 
1767  return SCIP_OKAY;
1768 }
1769 
1770 /** transforms given variable, scalar and constant to the corresponding active, fixed, or
1771  * multi-aggregated variable, scalar and constant; if the variable resolves to a fixed variable,
1772  * "scalar" will be 0.0 and the value of the sum will be stored in "constant"; a multi-aggregation
1773  * with only one active variable (this can happen due to fixings after the multi-aggregation),
1774  * is treated like an aggregation; if the multi-aggregation constant is infinite, "scalar" will be 0.0
1775  *
1776  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1777  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1778  *
1779  * @pre This method can be called if @p scip is in one of the following stages:
1780  * - \ref SCIP_STAGE_TRANSFORMED
1781  * - \ref SCIP_STAGE_INITPRESOLVE
1782  * - \ref SCIP_STAGE_PRESOLVING
1783  * - \ref SCIP_STAGE_EXITPRESOLVE
1784  * - \ref SCIP_STAGE_PRESOLVED
1785  * - \ref SCIP_STAGE_INITSOLVE
1786  * - \ref SCIP_STAGE_SOLVING
1787  * - \ref SCIP_STAGE_SOLVED
1788  * - \ref SCIP_STAGE_EXITSOLVE
1789  * - \ref SCIP_STAGE_FREETRANS
1790  */
1792  SCIP* scip, /**< SCIP data structure */
1793  SCIP_VAR** var, /**< pointer to problem variable x in sum a*x + c */
1794  SCIP_Real* scalar, /**< pointer to scalar a in sum a*x + c */
1795  SCIP_Real* constant /**< pointer to constant c in sum a*x + c */
1796  )
1797 {
1798  assert(scip != NULL);
1799  assert(var != NULL);
1800  assert(scalar != NULL);
1801  assert(constant != NULL);
1802 
1803  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetProbvarSum", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1804  SCIP_CALL( SCIPvarGetProbvarSum(var, scip->set, scalar, constant) );
1805 
1806  return SCIP_OKAY;
1807 }
1808 
1809 /** return for given variables all their active counterparts; all active variables will be pairwise different
1810  * @note It does not hold that the first output variable is the active variable for the first input variable.
1811  *
1812  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1813  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1814  *
1815  * @pre This method can be called if @p scip is in one of the following stages:
1816  * - \ref SCIP_STAGE_TRANSFORMED
1817  * - \ref SCIP_STAGE_INITPRESOLVE
1818  * - \ref SCIP_STAGE_PRESOLVING
1819  * - \ref SCIP_STAGE_EXITPRESOLVE
1820  * - \ref SCIP_STAGE_PRESOLVED
1821  * - \ref SCIP_STAGE_INITSOLVE
1822  * - \ref SCIP_STAGE_SOLVING
1823  * - \ref SCIP_STAGE_SOLVED
1824  * - \ref SCIP_STAGE_EXITSOLVE
1825  * - \ref SCIP_STAGE_FREETRANS
1826  */
1828  SCIP* scip, /**< SCIP data structure */
1829  SCIP_VAR** vars, /**< variable array with given variables and as output all active
1830  * variables, if enough slots exist
1831  */
1832  int* nvars, /**< number of given variables, and as output number of active variables,
1833  * if enough slots exist
1834  */
1835  int varssize, /**< available slots in vars array */
1836  int* requiredsize /**< pointer to store the required array size for the active variables */
1837  )
1838 {
1839  assert(scip != NULL);
1840  assert(nvars != NULL);
1841  assert(vars != NULL || *nvars == 0);
1842  assert(varssize >= *nvars);
1843  assert(requiredsize != NULL);
1844 
1845  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetActiveVars", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1846  SCIP_CALL( SCIPvarsGetActiveVars(scip->set, vars, nvars, varssize, requiredsize) );
1847 
1848  return SCIP_OKAY;
1849 }
1850 
1851 /** returns the reduced costs of the variable in the current node's LP relaxation;
1852  * the current node has to have a feasible LP.
1853  *
1854  * returns SCIP_INVALID if the variable is active but not in the current LP;
1855  * returns 0 if the variable has been aggregated out or fixed in presolving.
1856  *
1857  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1858  *
1859  * @note The return value of this method should be used carefully if the dual feasibility check was explictely disabled.
1860  */
1862  SCIP* scip, /**< SCIP data structure */
1863  SCIP_VAR* var /**< variable to get reduced costs, should be a column in current node LP */
1864  )
1865 {
1866  assert( scip != NULL );
1867  assert( var != NULL );
1868  assert( var->scip == scip );
1869 
1870  switch( SCIPvarGetStatus(var) )
1871  {
1873  if( var->data.original.transvar == NULL )
1874  return SCIP_INVALID;
1875  return SCIPgetVarRedcost(scip, var->data.original.transvar);
1876 
1877  case SCIP_VARSTATUS_COLUMN:
1878  return SCIPgetColRedcost(scip, SCIPvarGetCol(var));
1879 
1880  case SCIP_VARSTATUS_LOOSE:
1881  return SCIP_INVALID;
1882 
1883  case SCIP_VARSTATUS_FIXED:
1887  return 0.0;
1888 
1889  default:
1890  SCIPerrorMessage("unknown variable status\n");
1891  SCIPABORT();
1892  return 0.0; /*lint !e527*/
1893  }
1894 }
1895 
1896 /** returns the implied reduced costs of the variable in the current node's LP relaxation;
1897  * the current node has to have a feasible LP.
1898  *
1899  * returns SCIP_INVALID if the variable is active but not in the current LP;
1900  * returns 0 if the variable has been aggregated out or fixed in presolving.
1901  *
1902  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1903  *
1904  * @note The return value of this method should be used carefully if the dual feasibility check was explictely disabled.
1905  */
1907  SCIP* scip, /**< SCIP data structure */
1908  SCIP_VAR* var, /**< variable to get reduced costs, should be a column in current node LP */
1909  SCIP_Bool varfixing /**< FALSE if for x == 0, TRUE for x == 1 */
1910  )
1911 {
1912  assert( scip != NULL );
1913  assert( var != NULL );
1914  assert( var->scip == scip );
1915 
1916  switch( SCIPvarGetStatus(var) )
1917  {
1919  if( var->data.original.transvar == NULL )
1920  return SCIP_INVALID;
1921  return SCIPgetVarImplRedcost(scip, var->data.original.transvar, varfixing);
1922 
1923  case SCIP_VARSTATUS_COLUMN:
1924  return SCIPvarGetImplRedcost(var, scip->set, varfixing, scip->stat, scip->transprob, scip->lp);
1925 
1926  case SCIP_VARSTATUS_LOOSE:
1927  return SCIP_INVALID;
1928 
1929  case SCIP_VARSTATUS_FIXED:
1933  return 0.0;
1934 
1935  default:
1936  SCIPerrorMessage("unknown variable status\n");
1937  SCIPABORT();
1938  return 0.0; /*lint !e527*/
1939  }
1940 }
1941 
1942 
1943 /** returns the Farkas coefficient of the variable in the current node's LP relaxation;
1944  * the current node has to have an infeasible LP.
1945  *
1946  * returns SCIP_INVALID if the variable is active but not in the current LP;
1947  * returns 0 if the variable has been aggregated out or fixed in presolving.
1948  *
1949  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1950  */
1952  SCIP* scip, /**< SCIP data structure */
1953  SCIP_VAR* var /**< variable to get reduced costs, should be a column in current node LP */
1954  )
1955 {
1956  assert(scip != NULL);
1957  assert(var != NULL);
1958  assert(var->scip == scip);
1959 
1960  switch( SCIPvarGetStatus(var) )
1961  {
1963  if( var->data.original.transvar == NULL )
1964  return SCIP_INVALID;
1965  return SCIPgetVarFarkasCoef(scip,var->data.original.transvar);
1966 
1967  case SCIP_VARSTATUS_COLUMN:
1968  return SCIPgetColFarkasCoef(scip,SCIPvarGetCol(var));
1969 
1970  case SCIP_VARSTATUS_LOOSE:
1971  return SCIP_INVALID;
1972 
1973  case SCIP_VARSTATUS_FIXED:
1977  return 0.0;
1978 
1979  default:
1980  SCIPerrorMessage("unknown variable status\n");
1981  SCIPABORT();
1982  return 0.0; /*lint !e527*/
1983  }
1984 }
1985 
1986 /** returns lower bound of variable directly before or after the bound change given by the bound change index
1987  * was applied
1988  */
1990  SCIP* scip, /**< SCIP data structure */
1991  SCIP_VAR* var, /**< problem variable */
1992  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
1993  SCIP_Bool after /**< should the bound change with given index be included? */
1994  )
1995 {
1996  SCIP_VARSTATUS varstatus;
1997  SCIP_BDCHGINFO* bdchginfo;
1998  assert(var != NULL);
1999 
2000  varstatus = SCIPvarGetStatus(var);
2001 
2002  /* get bounds of attached variables */
2003  switch( varstatus )
2004  {
2006  assert(var->data.original.transvar != NULL);
2007  return SCIPgetVarLbAtIndex(scip, var->data.original.transvar, bdchgidx, after);
2008 
2009  case SCIP_VARSTATUS_COLUMN:
2010  case SCIP_VARSTATUS_LOOSE:
2011  if( bdchgidx == NULL )
2012  return SCIPvarGetLbLocal(var);
2013  else
2014  {
2015  bdchginfo = SCIPvarGetLbchgInfo(var, bdchgidx, after);
2016  if( bdchginfo != NULL )
2017  return SCIPbdchginfoGetNewbound(bdchginfo);
2018  else
2019  return var->glbdom.lb;
2020  }
2021 
2022  case SCIP_VARSTATUS_FIXED:
2023  return var->glbdom.lb;
2024 
2025  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c -> y = (x-c)/a */
2026  assert(var->data.aggregate.var != NULL);
2027  if( var->data.aggregate.scalar > 0.0 )
2028  {
2029  SCIP_Real lb;
2030 
2031  lb = SCIPgetVarLbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2032 
2033  /* a > 0 -> get lower bound of y */
2034  if( SCIPisInfinity(scip, -lb) )
2035  return -SCIPinfinity(scip);
2036  else if( SCIPisInfinity(scip, lb) )
2037  return SCIPinfinity(scip);
2038  else
2039  return var->data.aggregate.scalar * lb + var->data.aggregate.constant;
2040  }
2041  else if( var->data.aggregate.scalar < 0.0 )
2042  {
2043  SCIP_Real ub;
2044 
2045  ub = SCIPgetVarUbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2046 
2047  /* a < 0 -> get upper bound of y */
2048  if( SCIPisInfinity(scip, -ub) )
2049  return SCIPinfinity(scip);
2050  else if( SCIPisInfinity(scip, ub) )
2051  return -SCIPinfinity(scip);
2052  else
2053  return var->data.aggregate.scalar * ub + var->data.aggregate.constant;
2054  }
2055  else
2056  {
2057  SCIPerrorMessage("scalar is zero in aggregation\n");
2058  SCIPABORT();
2059  return SCIP_INVALID; /*lint !e527*/
2060  }
2061 
2063  /* handle multi-aggregated variables depending on one variable only (possibly caused by SCIPvarFlattenAggregationGraph()) */
2064  if ( var->data.multaggr.nvars == 1 )
2065  {
2066  assert(var->data.multaggr.vars != NULL);
2067  assert(var->data.multaggr.scalars != NULL);
2068  assert(var->data.multaggr.vars[0] != NULL);
2069 
2070  if( var->data.multaggr.scalars[0] > 0.0 )
2071  {
2072  SCIP_Real lb;
2073 
2074  lb = SCIPgetVarLbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2075 
2076  /* a > 0 -> get lower bound of y */
2077  if( SCIPisInfinity(scip, -lb) )
2078  return -SCIPinfinity(scip);
2079  else if( SCIPisInfinity(scip, lb) )
2080  return SCIPinfinity(scip);
2081  else
2082  return var->data.multaggr.scalars[0] * lb + var->data.multaggr.constant;
2083  }
2084  else if( var->data.multaggr.scalars[0] < 0.0 )
2085  {
2086  SCIP_Real ub;
2087 
2088  ub = SCIPgetVarUbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2089 
2090  /* a < 0 -> get upper bound of y */
2091  if( SCIPisInfinity(scip, -ub) )
2092  return SCIPinfinity(scip);
2093  else if( SCIPisInfinity(scip, ub) )
2094  return -SCIPinfinity(scip);
2095  else
2096  return var->data.multaggr.scalars[0] * ub + var->data.multaggr.constant;
2097  }
2098  else
2099  {
2100  SCIPerrorMessage("scalar is zero in multi-aggregation\n");
2101  SCIPABORT();
2102  return SCIP_INVALID; /*lint !e527*/
2103  }
2104  }
2105  SCIPerrorMessage("cannot get the bounds of a multi-aggregated variable.\n");
2106  SCIPABORT();
2107  return SCIP_INVALID; /*lint !e527*/
2108 
2109  case SCIP_VARSTATUS_NEGATED: /* x' = offset - x -> x = offset - x' */
2110  assert(var->negatedvar != NULL);
2112  assert(var->negatedvar->negatedvar == var);
2113  return var->data.negate.constant - SCIPgetVarUbAtIndex(scip, var->negatedvar, bdchgidx, after);
2114 
2115  default:
2116  SCIPerrorMessage("unknown variable status\n");
2117  SCIPABORT();
2118  return SCIP_INVALID; /*lint !e527*/
2119  }
2120 }
2121 
2122 /** returns upper bound of variable directly before or after the bound change given by the bound change index
2123  * was applied
2124  */
2126  SCIP* scip, /**< SCIP data structure */
2127  SCIP_VAR* var, /**< problem variable */
2128  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2129  SCIP_Bool after /**< should the bound change with given index be included? */
2130  )
2131 {
2132  SCIP_VARSTATUS varstatus;
2133  SCIP_BDCHGINFO* bdchginfo;
2134  assert(var != NULL);
2135 
2136  varstatus = SCIPvarGetStatus(var);
2137 
2138  /* get bounds of attached variables */
2139  switch( varstatus )
2140  {
2142  assert(var->data.original.transvar != NULL);
2143  return SCIPgetVarUbAtIndex(scip, var->data.original.transvar, bdchgidx, after);
2144 
2145  case SCIP_VARSTATUS_COLUMN:
2146  case SCIP_VARSTATUS_LOOSE:
2147  if( bdchgidx == NULL )
2148  return SCIPvarGetUbLocal(var);
2149  else
2150  {
2151  bdchginfo = SCIPvarGetUbchgInfo(var, bdchgidx, after);
2152  if( bdchginfo != NULL )
2153  return SCIPbdchginfoGetNewbound(bdchginfo);
2154  else
2155  return var->glbdom.ub;
2156  }
2157 
2158  case SCIP_VARSTATUS_FIXED:
2159  return var->glbdom.ub;
2160 
2161  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c -> y = (x-c)/a */
2162  assert(var->data.aggregate.var != NULL);
2163  if( var->data.aggregate.scalar > 0.0 )
2164  {
2165  SCIP_Real ub;
2166 
2167  ub = SCIPgetVarUbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2168 
2169  /* a > 0 -> get lower bound of y */
2170  if( SCIPisInfinity(scip, -ub) )
2171  return -SCIPinfinity(scip);
2172  else if( SCIPisInfinity(scip, ub) )
2173  return SCIPinfinity(scip);
2174  else
2175  return var->data.aggregate.scalar * ub + var->data.aggregate.constant;
2176  }
2177  else if( var->data.aggregate.scalar < 0.0 )
2178  {
2179  SCIP_Real lb;
2180 
2181  lb = SCIPgetVarLbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2182 
2183  /* a < 0 -> get upper bound of y */
2184  if ( SCIPisInfinity(scip, -lb) )
2185  return SCIPinfinity(scip);
2186  else if ( SCIPisInfinity(scip, lb) )
2187  return -SCIPinfinity(scip);
2188  else
2189  return var->data.aggregate.scalar * lb + var->data.aggregate.constant;
2190  }
2191  else
2192  {
2193  SCIPerrorMessage("scalar is zero in aggregation\n");
2194  SCIPABORT();
2195  return SCIP_INVALID; /*lint !e527*/
2196  }
2197 
2199  /* handle multi-aggregated variables depending on one variable only (possibly caused by SCIPvarFlattenAggregationGraph()) */
2200  if ( var->data.multaggr.nvars == 1 )
2201  {
2202  assert(var->data.multaggr.vars != NULL);
2203  assert(var->data.multaggr.scalars != NULL);
2204  assert(var->data.multaggr.vars[0] != NULL);
2205 
2206  if( var->data.multaggr.scalars[0] > 0.0 )
2207  {
2208  SCIP_Real ub;
2209 
2210  ub = SCIPgetVarUbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2211 
2212  /* a > 0 -> get lower bound of y */
2213  if ( SCIPisInfinity(scip, -ub) )
2214  return -SCIPinfinity(scip);
2215  else if ( SCIPisInfinity(scip, ub) )
2216  return SCIPinfinity(scip);
2217  else
2218  return var->data.multaggr.scalars[0] * ub + var->data.multaggr.constant;
2219  }
2220  else if( var->data.multaggr.scalars[0] < 0.0 )
2221  {
2222  SCIP_Real lb;
2223 
2224  lb = SCIPgetVarLbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2225 
2226  /* a < 0 -> get upper bound of y */
2227  if ( SCIPisInfinity(scip, -lb) )
2228  return SCIPinfinity(scip);
2229  else if ( SCIPisInfinity(scip, lb) )
2230  return -SCIPinfinity(scip);
2231  else
2232  return var->data.multaggr.scalars[0] * lb + var->data.multaggr.constant;
2233  }
2234  else
2235  {
2236  SCIPerrorMessage("scalar is zero in multi-aggregation\n");
2237  SCIPABORT();
2238  return SCIP_INVALID; /*lint !e527*/
2239  }
2240  }
2241  SCIPerrorMessage("cannot get the bounds of a multiple aggregated variable.\n");
2242  SCIPABORT();
2243  return SCIP_INVALID; /*lint !e527*/
2244 
2245  case SCIP_VARSTATUS_NEGATED: /* x' = offset - x -> x = offset - x' */
2246  assert(var->negatedvar != NULL);
2248  assert(var->negatedvar->negatedvar == var);
2249  return var->data.negate.constant - SCIPgetVarLbAtIndex(scip, var->negatedvar, bdchgidx, after);
2250 
2251  default:
2252  SCIPerrorMessage("unknown variable status\n");
2253  SCIPABORT();
2254  return SCIP_INVALID; /*lint !e527*/
2255  }
2256 }
2257 
2258 /** returns lower or upper bound of variable directly before or after the bound change given by the bound change index
2259  * was applied
2260  */
2262  SCIP* scip, /**< SCIP data structure */
2263  SCIP_VAR* var, /**< problem variable */
2264  SCIP_BOUNDTYPE boundtype, /**< type of bound: lower or upper bound */
2265  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2266  SCIP_Bool after /**< should the bound change with given index be included? */
2267  )
2268 {
2269  if( boundtype == SCIP_BOUNDTYPE_LOWER )
2270  return SCIPgetVarLbAtIndex(scip, var, bdchgidx, after);
2271  else
2272  {
2273  assert(boundtype == SCIP_BOUNDTYPE_UPPER);
2274  return SCIPgetVarUbAtIndex(scip, var, bdchgidx, after);
2275  }
2276 }
2277 
2278 /** returns whether the binary variable was fixed at the time given by the bound change index */
2280  SCIP* scip, /**< SCIP data structure */
2281  SCIP_VAR* var, /**< problem variable */
2282  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2283  SCIP_Bool after /**< should the bound change with given index be included? */
2284  )
2285 {
2286  assert(var != NULL);
2287  assert(SCIPvarIsBinary(var));
2288 
2289  /* check the current bounds first in order to decide at which bound change information we have to look
2290  * (which is expensive because we have to follow the aggregation tree to the active variable)
2291  */
2292  return ((SCIPvarGetLbLocal(var) > 0.5 && SCIPgetVarLbAtIndex(scip, var, bdchgidx, after) > 0.5)
2293  || (SCIPvarGetUbLocal(var) < 0.5 && SCIPgetVarUbAtIndex(scip, var, bdchgidx, after) < 0.5));
2294 }
2295 
2296 /** gets solution value for variable in current node
2297  *
2298  * @return solution value for variable in current node
2299  *
2300  * @pre This method can be called if @p scip is in one of the following stages:
2301  * - \ref SCIP_STAGE_PRESOLVED
2302  * - \ref SCIP_STAGE_SOLVING
2303  */
2305  SCIP* scip, /**< SCIP data structure */
2306  SCIP_VAR* var /**< variable to get solution value for */
2307  )
2308 {
2310  assert( var->scip == scip );
2311 
2312  return SCIPvarGetSol(var, SCIPtreeHasCurrentNodeLP(scip->tree));
2313 }
2314 
2315 /** gets solution values of multiple variables in current node
2316  *
2317  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2318  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2319  *
2320  * @pre This method can be called if @p scip is in one of the following stages:
2321  * - \ref SCIP_STAGE_PRESOLVED
2322  * - \ref SCIP_STAGE_SOLVING
2323  */
2325  SCIP* scip, /**< SCIP data structure */
2326  int nvars, /**< number of variables to get solution value for */
2327  SCIP_VAR** vars, /**< array with variables to get value for */
2328  SCIP_Real* vals /**< array to store solution values of variables */
2329  )
2330 {
2331  int v;
2332 
2333  assert(nvars == 0 || vars != NULL);
2334  assert(nvars == 0 || vals != NULL);
2335 
2336  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarSols", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2337 
2338  if( SCIPtreeHasCurrentNodeLP(scip->tree) )
2339  {
2340  for( v = 0; v < nvars; ++v )
2341  vals[v] = SCIPvarGetLPSol(vars[v]);
2342  }
2343  else
2344  {
2345  for( v = 0; v < nvars; ++v )
2346  vals[v] = SCIPvarGetPseudoSol(vars[v]);
2347  }
2348 
2349  return SCIP_OKAY;
2350 }
2351 
2352 /** sets the solution value of all variables in the global relaxation solution to zero
2353  *
2354  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2355  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2356  *
2357  * @pre This method can be called if @p scip is in one of the following stages:
2358  * - \ref SCIP_STAGE_PRESOLVED
2359  * - \ref SCIP_STAGE_SOLVING
2360  */
2362  SCIP* scip, /**< SCIP data structure */
2363  SCIP_RELAX* relax /**< relaxator data structure */
2364  )
2365 {
2366  SCIP_VAR** vars;
2367  int nvars;
2368  int v;
2369 
2370  assert(scip != NULL);
2371 
2372  SCIP_CALL( SCIPcheckStage(scip, "SCIPclearRelaxSolVals", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2373 
2374  /* update the responsible relax pointer */
2375  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2376 
2377  /* the relaxation solution is already cleared */
2378  if( SCIPrelaxationIsSolZero(scip->relaxation) )
2379  return SCIP_OKAY;
2380 
2381  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
2382 
2383  for( v = 0; v < nvars; v++ )
2384  {
2385  SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, 0.0, FALSE) );
2386  }
2387 
2388  SCIPrelaxationSetSolObj(scip->relaxation, 0.0);
2390 
2391  return SCIP_OKAY;
2392 }
2393 
2394 /** sets the value of the given variable in the global relaxation solution;
2395  * this solution can be filled by the relaxation handlers and can be used by heuristics and for separation;
2396  * You can use SCIPclearRelaxSolVals() to set all values to zero, initially;
2397  * after setting all solution values, you have to call SCIPmarkRelaxSolValid()
2398  * to inform SCIP that the stored solution is valid
2399  *
2400  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2401  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2402  *
2403  * @pre This method can be called if @p scip is in one of the following stages:
2404  * - \ref SCIP_STAGE_PRESOLVED
2405  * - \ref SCIP_STAGE_SOLVING
2406  *
2407  * @note This method incrementally updates the objective value of the relaxation solution. If the whole solution
2408  * should be updated, using SCIPsetRelaxSolVals() instead or calling SCIPclearRelaxSolVals() before setting
2409  * the first value to reset the solution and the objective value to 0 may help the numerics.
2410  */
2412  SCIP* scip, /**< SCIP data structure */
2413  SCIP_RELAX* relax, /**< relaxator data structure */
2414  SCIP_VAR* var, /**< variable to set value for */
2415  SCIP_Real val /**< solution value of variable */
2416  )
2417 {
2418  assert(scip != NULL);
2419 
2420  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolVal", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2421 
2422  SCIP_CALL( SCIPvarSetRelaxSol(var, scip->set, scip->relaxation, val, TRUE) );
2423 
2424  if( val != 0.0 )
2427  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2428 
2429  return SCIP_OKAY;
2430 }
2431 
2432 /** sets the values of the given variables in the global relaxation solution and informs SCIP about the validity
2433  * and whether the solution can be enforced via linear cuts;
2434  * this solution can be filled by the relaxation handlers and can be used by heuristics and for separation;
2435  * the solution is automatically cleared, s.t. all other variables get value 0.0
2436  *
2437  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2438  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2439  *
2440  * @pre This method can be called if @p scip is in one of the following stages:
2441  * - \ref SCIP_STAGE_PRESOLVED
2442  * - \ref SCIP_STAGE_SOLVING
2443  */
2445  SCIP* scip, /**< SCIP data structure */
2446  SCIP_RELAX* relax, /**< relaxator data structure */
2447  int nvars, /**< number of variables to set relaxation solution value for */
2448  SCIP_VAR** vars, /**< array with variables to set value for */
2449  SCIP_Real* vals, /**< array with solution values of variables */
2450  SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2451  )
2452 {
2453  int v;
2454 
2455  assert(scip != NULL);
2456  assert(nvars == 0 || vars != NULL);
2457  assert(nvars == 0 || vals != NULL);
2458 
2459  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolVals", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2460 
2461  SCIP_CALL( SCIPclearRelaxSolVals(scip, relax) );
2462 
2463  for( v = 0; v < nvars; v++ )
2464  {
2465  SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, vals[v], TRUE) );
2466  }
2467 
2469  SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2470  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2471 
2472  return SCIP_OKAY;
2473 }
2474 
2475 /** sets the values of the variables in the global relaxation solution to the values in the given primal solution
2476  * and informs SCIP about the validity and whether the solution can be enforced via linear cuts;
2477  * the relaxation solution can be filled by the relaxation handlers and might be used by heuristics and for separation
2478  *
2479  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2480  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2481  *
2482  * @pre This method can be called if @p scip is in one of the following stages:
2483  * - \ref SCIP_STAGE_PRESOLVED
2484  * - \ref SCIP_STAGE_SOLVING
2485  */
2487  SCIP* scip, /**< SCIP data structure */
2488  SCIP_RELAX* relax, /**< relaxator data structure */
2489  SCIP_SOL* sol, /**< primal relaxation solution */
2490  SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2491  )
2492 {
2493  SCIP_VAR** vars;
2494  SCIP_Real* vals;
2495  int nvars;
2496  int v;
2497 
2498  assert(scip != NULL);
2499 
2500  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolValsSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2501 
2502  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
2503 
2504  /* alloc buffer array for solution values of the variables and get the values */
2505  SCIP_CALL( SCIPallocBufferArray(scip, &vals, nvars) );
2506  SCIP_CALL( SCIPgetSolVals(scip, sol, nvars, vars, vals) );
2507 
2508  SCIP_CALL( SCIPclearRelaxSolVals(scip, relax) );
2509 
2510  for( v = 0; v < nvars; v++ )
2511  {
2512  SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, vals[v], FALSE) );
2513  }
2514 
2515  SCIPrelaxationSetSolObj(scip->relaxation, SCIPsolGetObj(sol, scip->set, scip->transprob, scip->origprob));
2516 
2518  SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2519  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2520 
2521  SCIPfreeBufferArray(scip, &vals);
2522 
2523  return SCIP_OKAY;
2524 }
2525 
2526 /** returns whether the relaxation solution is valid
2527  *
2528  * @return TRUE, if the relaxation solution is valid; FALSE, otherwise
2529  *
2530  * @pre This method can be called if @p scip is in one of the following stages:
2531  * - \ref SCIP_STAGE_PRESOLVED
2532  * - \ref SCIP_STAGE_SOLVING
2533  */
2535  SCIP* scip /**< SCIP data structure */
2536  )
2537 {
2538  assert(scip != NULL);
2539 
2540  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisRelaxSolValid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2541 
2542  return SCIPrelaxationIsSolValid(scip->relaxation);
2543 }
2544 
2545 /** informs SCIP that the relaxation solution is valid and whether the relaxation can be enforced through linear cuts
2546  *
2547  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2548  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2549  *
2550  * @pre This method can be called if @p scip is in one of the following stages:
2551  * - \ref SCIP_STAGE_PRESOLVED
2552  * - \ref SCIP_STAGE_SOLVING
2553  */
2555  SCIP* scip, /**< SCIP data structure */
2556  SCIP_RELAX* relax, /**< relaxator data structure that set the current relaxation solution */
2557  SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2558  )
2559 {
2560  assert(scip != NULL);
2561 
2562  SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkRelaxSolValid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2563 
2564  SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2565  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2566 
2567  return SCIP_OKAY;
2568 }
2569 
2570 /** informs SCIP, that the relaxation solution is invalid
2571  *
2572  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2573  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2574  *
2575  * @pre This method can be called if @p scip is in one of the following stages:
2576  * - \ref SCIP_STAGE_PRESOLVED
2577  * - \ref SCIP_STAGE_SOLVING
2578  */
2580  SCIP* scip /**< SCIP data structure */
2581  )
2582 {
2583  assert(scip != NULL);
2584 
2585  SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkRelaxSolInvalid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2586 
2588 
2589  return SCIP_OKAY;
2590 }
2591 
2592 /** gets the relaxation solution value of the given variable
2593  *
2594  * @return the relaxation solution value of the given variable
2595  *
2596  * @pre This method can be called if @p scip is in one of the following stages:
2597  * - \ref SCIP_STAGE_PRESOLVED
2598  * - \ref SCIP_STAGE_SOLVING
2599  */
2601  SCIP* scip, /**< SCIP data structure */
2602  SCIP_VAR* var /**< variable to get value for */
2603  )
2604 {
2605  assert(scip != NULL);
2606  assert(var != NULL);
2607  assert(var->scip == scip);
2608 
2609  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetRelaxSolVal", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2610 
2611  if( !SCIPrelaxationIsSolValid(scip->relaxation) )
2612  {
2613  SCIPerrorMessage("Relaxation Solution is not valid!\n");
2614  SCIPABORT();
2615  return SCIP_INVALID; /*lint !e527*/
2616  }
2617 
2618  return SCIPvarGetRelaxSol(var, scip->set);
2619 }
2620 
2621 /** gets the relaxation solution objective value
2622  *
2623  * @return the objective value of the relaxation solution
2624  *
2625  * @pre This method can be called if @p scip is in one of the following stages:
2626  * - \ref SCIP_STAGE_PRESOLVED
2627  * - \ref SCIP_STAGE_SOLVING
2628  */
2630  SCIP* scip /**< SCIP data structure */
2631  )
2632 {
2633  assert(scip != NULL);
2634 
2635  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetRelaxSolObj", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2636 
2637  if( !SCIPrelaxationIsSolValid(scip->relaxation) )
2638  {
2639  SCIPerrorMessage("Relaxation Solution is not valid!\n");
2640  SCIPABORT();
2641  return SCIP_INVALID; /*lint !e527*/
2642  }
2643 
2644  return SCIPrelaxationGetSolObj(scip->relaxation);
2645 }
2646 
2647 /** determine which branching direction should be evaluated first by strong branching
2648  *
2649  * @return TRUE iff strong branching should first evaluate the down child
2650  *
2651  */
2653  SCIP* scip, /**< SCIP data structure */
2654  SCIP_VAR* var /**< variable to determine the branching direction on */
2655  )
2656 {
2657  switch( scip->set->branch_firstsbchild )
2658  {
2659  case 'u':
2660  return FALSE;
2661  case 'd':
2662  return TRUE;
2663  case 'a':
2664  return (SCIPvarGetNLocksDown(var) > SCIPvarGetNLocksUp(var));
2665  default:
2666  assert(scip->set->branch_firstsbchild == 'h');
2668  }
2669 }
2670 
2671 /** start strong branching - call before any strong branching
2672  *
2673  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2674  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2675  *
2676  * @pre This method can be called if @p scip is in one of the following stages:
2677  * - \ref SCIP_STAGE_PRESOLVED
2678  * - \ref SCIP_STAGE_SOLVING
2679  *
2680  * @note if propagation is enabled, strong branching is not done directly on the LP, but probing nodes are created
2681  * which allow to perform propagation but also creates some overhead
2682  */
2684  SCIP* scip, /**< SCIP data structure */
2685  SCIP_Bool enablepropagation /**< should propagation be done before solving the strong branching LP? */
2686  )
2687 {
2688  assert( scip != NULL );
2689  SCIP_CALL( SCIPcheckStage(scip, "SCIPstartStrongbranch", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2690 
2691  assert(!SCIPinProbing(scip));
2692 
2693  SCIPdebugMsg(scip, "starting strong branching mode%s: lpcount=%" SCIP_LONGINT_FORMAT "\n", enablepropagation ? " with propagation" : "", scip->stat->lpcount - scip->stat->nsbdivinglps);
2694 
2695  /* start probing mode to allow propagation before solving the strong branching LPs; if no propagation should be done,
2696  * start the strong branching mode in the LP interface
2697  */
2698  if( enablepropagation )
2699  {
2700  if( SCIPtreeProbing(scip->tree) )
2701  {
2702  SCIPerrorMessage("cannot start strong branching with propagation while in probing mode\n");
2703  return SCIP_INVALIDCALL;
2704  }
2705 
2706  if( scip->lp != NULL && SCIPlpDiving(scip->lp) )
2707  {
2708  SCIPerrorMessage("cannot start strong branching with propagation while in diving mode\n");
2709  return SCIP_INVALIDCALL;
2710  }
2711 
2712  /* other then in SCIPstartProbing(), we do not disable collecting variable statistics during strong branching;
2713  * we cannot disable it, because the pseudo costs would not be updated, otherwise,
2714  * and reliability branching would end up doing strong branching all the time
2715  */
2716  SCIP_CALL( SCIPtreeStartProbing(scip->tree, scip->mem->probmem, scip->set, scip->lp, scip->relaxation, scip->transprob, TRUE) );
2717 
2718  /* inform the LP that the current probing mode is used for strong branching */
2720  }
2721  else
2722  {
2724  }
2725 
2726  /* reset local strong branching info */
2728 
2729  return SCIP_OKAY;
2730 }
2731 
2732 /** end strong branching - call after any strong branching
2733  *
2734  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2735  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2736  *
2737  * @pre This method can be called if @p scip is in one of the following stages:
2738  * - \ref SCIP_STAGE_PRESOLVED
2739  * - \ref SCIP_STAGE_SOLVING
2740  */
2742  SCIP* scip /**< SCIP data structure */
2743  )
2744 {
2745  assert( scip != NULL );
2746 
2747  SCIP_CALL( SCIPcheckStage(scip, "SCIPendStrongbranch", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2748 
2749  /* depending on whether the strong branching mode was started with propagation enabled or not, we end the strong
2750  * branching probing mode or the LP strong branching mode
2751  */
2752  if( SCIPtreeProbing(scip->tree) )
2753  {
2754  SCIP_NODE* node;
2755  SCIP_DOMCHG* domchg;
2756  SCIP_VAR** boundchgvars;
2757  SCIP_Real* bounds;
2758  SCIP_BOUNDTYPE* boundtypes;
2759  int nboundchgs;
2760  int nbnds;
2761  int i;
2762 
2763  /* collect all bound changes deducted during probing, which were applied at the probing root and apply them to the
2764  * focusnode
2765  */
2766  node = SCIPgetCurrentNode(scip);
2767  assert(SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE);
2768  assert(SCIPgetProbingDepth(scip) == 0);
2769 
2770  domchg = SCIPnodeGetDomchg(node);
2771  nboundchgs = SCIPdomchgGetNBoundchgs(domchg);
2772 
2773  SCIP_CALL( SCIPallocBufferArray(scip, &boundchgvars, nboundchgs) );
2774  SCIP_CALL( SCIPallocBufferArray(scip, &bounds, nboundchgs) );
2775  SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, nboundchgs) );
2776 
2777  for( i = 0, nbnds = 0; i < nboundchgs; ++i )
2778  {
2779  SCIP_BOUNDCHG* boundchg;
2780 
2781  boundchg = SCIPdomchgGetBoundchg(domchg, i);
2782 
2783  /* ignore redundant bound changes */
2784  if( SCIPboundchgIsRedundant(boundchg) )
2785  continue;
2786 
2787  boundchgvars[nbnds] = SCIPboundchgGetVar(boundchg);
2788  bounds[nbnds] = SCIPboundchgGetNewbound(boundchg);
2789  boundtypes[nbnds] = SCIPboundchgGetBoundtype(boundchg);
2790  ++nbnds;
2791  }
2792 
2793  SCIPdebugMsg(scip, "ending strong branching with probing: %d bound changes collected\n", nbnds);
2794 
2795  /* inform the LP that the probing mode is not used for strong branching anymore */
2797 
2798  /* switch back from probing to normal operation mode and restore variables and constraints to focus node */
2799  SCIP_CALL( SCIPtreeEndProbing(scip->tree, scip->reopt, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
2800  scip->transprob, scip->origprob, scip->lp, scip->relaxation, scip->primal,
2801  scip->branchcand, scip->eventqueue, scip->eventfilter, scip->cliquetable) );
2802 
2803  /* apply the collected bound changes */
2804  for( i = 0; i < nbnds; ++i )
2805  {
2806  if( boundtypes[i] == SCIP_BOUNDTYPE_LOWER )
2807  {
2808  SCIPdebugMsg(scip, "apply probing lower bound change <%s> >= %.9g\n", SCIPvarGetName(boundchgvars[i]), bounds[i]);
2809  SCIP_CALL( SCIPchgVarLb(scip, boundchgvars[i], bounds[i]) );
2810  }
2811  else
2812  {
2813  SCIPdebugMsg(scip, "apply probing upper bound change <%s> <= %.9g\n", SCIPvarGetName(boundchgvars[i]), bounds[i]);
2814  SCIP_CALL( SCIPchgVarUb(scip, boundchgvars[i], bounds[i]) );
2815  }
2816  }
2817 
2818  SCIPfreeBufferArray(scip, &boundtypes);
2819  SCIPfreeBufferArray(scip, &bounds);
2820  SCIPfreeBufferArray(scip, &boundchgvars);
2821  }
2822  else
2823  {
2824  SCIPdebugMsg(scip, "ending strong branching\n");
2825 
2827  }
2828 
2829  return SCIP_OKAY;
2830 }
2831 
2832 /** analyze the strong branching for the given variable; that includes conflict analysis for infeasible branches and
2833  * storing of root reduced cost information
2834  */
2835 static
2837  SCIP* scip, /**< SCIP data structure */
2838  SCIP_VAR* var, /**< variable to analyze */
2839  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
2840  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
2841  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
2842  * infeasible downwards branch, or NULL */
2843  SCIP_Bool* upconflict /**< pointer to store whether a conflict constraint was created for an
2844  * infeasible upwards branch, or NULL */
2845  )
2846 {
2847  SCIP_COL* col;
2848  SCIP_Bool downcutoff;
2849  SCIP_Bool upcutoff;
2850 
2851  col = SCIPvarGetCol(var);
2852  assert(col != NULL);
2853 
2854  downcutoff = col->sbdownvalid && SCIPsetIsGE(scip->set, col->sbdown, scip->lp->cutoffbound);
2855  upcutoff = col->sbupvalid && SCIPsetIsGE(scip->set, col->sbup, scip->lp->cutoffbound);
2856 
2857  if( downinf != NULL )
2858  *downinf = downcutoff;
2859  if( upinf != NULL )
2860  *upinf = upcutoff;
2861 
2862  /* analyze infeasible strong branching sub problems:
2863  * because the strong branching's bound change is necessary for infeasibility, it cannot be undone;
2864  * therefore, infeasible strong branchings on non-binary variables will not produce a valid conflict constraint
2865  */
2866  if( scip->set->conf_enable && scip->set->conf_usesb && scip->set->nconflicthdlrs > 0
2867  && SCIPvarIsBinary(var) && SCIPtreeGetCurrentDepth(scip->tree) > 0 )
2868  {
2869  if( (downcutoff && SCIPsetFeasCeil(scip->set, col->primsol-1.0) >= col->lb - 0.5)
2870  || (upcutoff && SCIPsetFeasFloor(scip->set, col->primsol+1.0) <= col->ub + 0.5) )
2871  {
2872  assert(downconflict != NULL);
2873  assert(upconflict != NULL);
2874  SCIP_CALL( SCIPconflictAnalyzeStrongbranch(scip->conflict, scip->conflictstore, scip->mem->probmem, scip->set, scip->stat,
2875  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, col, downconflict, upconflict) );
2876  }
2877  }
2878 
2879  /* the strong branching results can be used to strengthen the root reduced cost information which is used for example
2880  * to propagate against the cutoff bound
2881  *
2882  * @note Ignore the results if the LP solution of the down (up) branch LP is smaller which should not happened by
2883  * theory but can arise due to numerical issues.
2884  */
2885  if( SCIPtreeGetCurrentDepth(scip->tree) == 0 && SCIPvarIsBinary(var) && SCIPlpIsDualReliable(scip->lp) )
2886  {
2887  SCIP_Real lpobjval;
2888 
2889  assert(SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL);
2890 
2891  lpobjval = SCIPlpGetObjval(scip->lp, scip->set, scip->transprob);
2892 
2893  if( col->sbdownvalid && SCIPsetFeasCeil(scip->set, col->primsol-1.0) >= col->lb - 0.5 && lpobjval < col->sbdown )
2894  SCIPvarUpdateBestRootSol(var, scip->set, SCIPvarGetUbGlobal(var), -(col->sbdown - lpobjval), lpobjval);
2895  if( col->sbupvalid && SCIPsetFeasFloor(scip->set, col->primsol+1.0) <= col->ub + 0.5 && lpobjval < col->sbup )
2896  SCIPvarUpdateBestRootSol(var, scip->set, SCIPvarGetLbGlobal(var), col->sbup - lpobjval, lpobjval);
2897  }
2898 
2899  return SCIP_OKAY;
2900 }
2901 
2902 /** gets strong branching information on column variable with fractional value
2903  *
2904  * Before calling this method, the strong branching mode must have been activated by calling SCIPstartStrongbranch();
2905  * after strong branching was done for all candidate variables, the strong branching mode must be ended by
2906  * SCIPendStrongbranch(). Since this method does not apply domain propagation before strongbranching,
2907  * propagation should not be enabled in the SCIPstartStrongbranch() call.
2908  *
2909  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2910  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2911  *
2912  * @pre This method can be called if @p scip is in one of the following stages:
2913  * - \ref SCIP_STAGE_PRESOLVED
2914  * - \ref SCIP_STAGE_SOLVING
2915  */
2917  SCIP* scip, /**< SCIP data structure */
2918  SCIP_VAR* var, /**< variable to get strong branching values for */
2919  int itlim, /**< iteration limit for strong branchings */
2920  SCIP_Bool idempotent, /**< should scip's state remain the same after the call (statistics, column states...), or should it be updated ? */
2921  SCIP_Real* down, /**< stores dual bound after branching column down */
2922  SCIP_Real* up, /**< stores dual bound after branching column up */
2923  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
2924  * otherwise, it can only be used as an estimate value */
2925  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
2926  * otherwise, it can only be used as an estimate value */
2927  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
2928  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
2929  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
2930  * infeasible downwards branch, or NULL */
2931  SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
2932  * infeasible upwards branch, or NULL */
2933  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
2934  * solving process should be stopped (e.g., due to a time limit) */
2935  )
2936 {
2937  SCIP_COL* col;
2938  SCIP_Real localdown;
2939  SCIP_Real localup;
2940  SCIP_Bool localdownvalid;
2941  SCIP_Bool localupvalid;
2942 
2943  assert(scip != NULL);
2944  assert(var != NULL);
2945  assert(lperror != NULL);
2946  assert(!SCIPtreeProbing(scip->tree)); /* we should not be in strong branching with propagation mode */
2947  assert(var->scip == scip);
2948 
2949  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchFrac", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2950 
2951  if( downvalid != NULL )
2952  *downvalid = FALSE;
2953  if( upvalid != NULL )
2954  *upvalid = FALSE;
2955  if( downinf != NULL )
2956  *downinf = FALSE;
2957  if( upinf != NULL )
2958  *upinf = FALSE;
2959  if( downconflict != NULL )
2960  *downconflict = FALSE;
2961  if( upconflict != NULL )
2962  *upconflict = FALSE;
2963 
2965  {
2966  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
2967  return SCIP_INVALIDDATA;
2968  }
2969 
2970  col = SCIPvarGetCol(var);
2971  assert(col != NULL);
2972 
2973  if( !SCIPcolIsInLP(col) )
2974  {
2975  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
2976  return SCIP_INVALIDDATA;
2977  }
2978 
2979  /* check if the solving process should be aborted */
2980  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
2981  {
2982  /* mark this as if the LP failed */
2983  *lperror = TRUE;
2984  return SCIP_OKAY;
2985  }
2986 
2987  /* call strong branching for column with fractional value */
2988  SCIP_CALL( SCIPcolGetStrongbranch(col, FALSE, scip->set, scip->stat, scip->transprob, scip->lp, itlim, !idempotent, !idempotent,
2989  &localdown, &localup, &localdownvalid, &localupvalid, lperror) );
2990 
2991  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
2992  * declare the sub nodes infeasible
2993  */
2994  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
2995  {
2996  if( !idempotent ) /*lint !e774*/
2997  {
2998  SCIP_CALL( analyzeStrongbranch(scip, var, downinf, upinf, downconflict, upconflict) );
2999  }
3000  else
3001  {
3002  if( downinf != NULL )
3003  *downinf = localdownvalid && SCIPsetIsGE(scip->set, localdown, scip->lp->cutoffbound);
3004  if( upinf != NULL )
3005  *upinf = localupvalid && SCIPsetIsGE(scip->set, localup, scip->lp->cutoffbound);
3006  }
3007  }
3008 
3009  if( down != NULL )
3010  *down = localdown;
3011  if( up != NULL )
3012  *up = localup;
3013  if( downvalid != NULL )
3014  *downvalid = localdownvalid;
3015  if( upvalid != NULL )
3016  *upvalid = localupvalid;
3017 
3018  return SCIP_OKAY;
3019 }
3020 
3021 /** create, solve, and evaluate a single strong branching child (for strong branching with propagation) */
3022 static
3024  SCIP* scip, /**< SCIP data structure */
3025  SCIP_VAR* var, /**< variable to get strong branching values for */
3026  SCIP_Bool down, /**< do we regard the down child? */
3027  SCIP_Bool firstchild, /**< is this the first of the two strong branching children? */
3028  SCIP_Bool propagate, /**< should domain propagation be performed? */
3029  SCIP_Real newbound, /**< new bound to apply at the strong branching child */
3030  int itlim, /**< iteration limit for strong branchings */
3031  int maxproprounds, /**< maximum number of propagation rounds (-1: no limit, -2: parameter
3032  * settings) */
3033  SCIP_Real* value, /**< stores dual bound for strong branching child */
3034  SCIP_Bool* valid, /**< stores whether the returned value is a valid dual bound, or NULL;
3035  * otherwise, it can only be used as an estimate value */
3036  SCIP_Longint* ndomreductions, /**< pointer to store the number of domain reductions found, or NULL */
3037  SCIP_Bool* conflict, /**< pointer to store whether a conflict constraint was created for an
3038  * infeasible strong branching child, or NULL */
3039  SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred or the
3040  * solving process should be stopped (e.g., due to a time limit) */
3041  SCIP_VAR** vars, /**< active problem variables */
3042  int nvars, /**< number of active problem variables */
3043  SCIP_Real* newlbs, /**< array to store valid lower bounds for all active variables, or NULL */
3044  SCIP_Real* newubs, /**< array to store valid upper bounds for all active variables, or NULL */
3045  SCIP_Bool* foundsol, /**< pointer to store whether a primal solution was found during strong branching */
3046  SCIP_Bool* cutoff /**< pointer to store whether the strong branching child is infeasible */
3047  )
3048 {
3049  SCIP_Longint ndomreds;
3050 
3051  assert(value != NULL);
3052  assert(foundsol != NULL);
3053  assert(cutoff != NULL);
3054  assert(lperror != NULL);
3055  assert(valid != NULL ? !(*valid) : TRUE);
3056 
3057  *foundsol = FALSE;
3058  *cutoff = FALSE;
3059  *lperror = FALSE;
3060 
3061  /* check whether the strong branching child is already infeasible due to the bound change */
3062  if( down )
3063  {
3064  /* the down branch is infeasible due to the branching bound change; since this means that solval is not within the
3065  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3066  * are valid for and were already applied at the probing root
3067  */
3068  if( newbound < SCIPvarGetLbLocal(var) - 0.5 )
3069  {
3070  *value = SCIPinfinity(scip);
3071 
3072  if( valid != NULL )
3073  *valid = TRUE;
3074 
3075  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3076  if( conflict != NULL )
3077  *conflict = TRUE;
3078 
3079  *cutoff = TRUE;
3080 
3081  return SCIP_OKAY;
3082  }
3083  }
3084  else
3085  {
3086  /* the up branch is infeasible due to the branching bound change; since this means that solval is not within the
3087  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3088  * are valid for and were already applied at the probing root
3089  */
3090  if( newbound > SCIPvarGetUbLocal(var) + 0.5 )
3091  {
3092  *value = SCIPinfinity(scip);
3093 
3094  if( valid != NULL )
3095  *valid = TRUE;
3096 
3097  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3098  if( conflict != NULL )
3099  *conflict = TRUE;
3100 
3101  *cutoff = TRUE;
3102 
3103  return SCIP_OKAY;
3104  }
3105  }
3106 
3107  /* we need to ensure that we can create at least one new probing node without exceeding the maximal tree depth */
3109  {
3110  /* create a new probing node for the strong branching child and apply the new bound for the variable */
3111  SCIP_CALL( SCIPnewProbingNode(scip) );
3112 
3113  if( down )
3114  {
3115  assert(SCIPisGE(scip, newbound, SCIPvarGetLbLocal(var)));
3116  if( SCIPisLT(scip, newbound, SCIPvarGetUbLocal(var)) )
3117  {
3118  SCIP_CALL( SCIPchgVarUbProbing(scip, var, newbound) );
3119  }
3120  }
3121  else
3122  {
3123  assert(SCIPisLE(scip, newbound, SCIPvarGetUbLocal(var)));
3124  if( SCIPisGT(scip, newbound, SCIPvarGetLbLocal(var)) )
3125  {
3126  SCIP_CALL( SCIPchgVarLbProbing(scip, var, newbound) );
3127  }
3128  }
3129  }
3130  else
3131  {
3132  if( valid != NULL )
3133  *valid = FALSE;
3134 
3135  *cutoff = FALSE;
3136 
3137  if( conflict != NULL )
3138  *conflict = FALSE;
3139 
3140  return SCIP_OKAY;
3141  }
3142 
3143  /* propagate domains at the probing node */
3144  if( propagate )
3145  {
3146  /* start time measuring */
3147  SCIPclockStart(scip->stat->strongpropclock, scip->set);
3148 
3149  ndomreds = 0;
3150  SCIP_CALL( SCIPpropagateProbing(scip, maxproprounds, cutoff, &ndomreds) );
3151 
3152  /* store number of domain reductions in strong branching */
3153  if( down )
3154  SCIPstatAdd(scip->stat, scip->set, nsbdowndomchgs, ndomreds);
3155  else
3156  SCIPstatAdd(scip->stat, scip->set, nsbupdomchgs, ndomreds);
3157 
3158  if( ndomreductions != NULL )
3159  *ndomreductions = ndomreds;
3160 
3161  /* stop time measuring */
3162  SCIPclockStop(scip->stat->strongpropclock, scip->set);
3163 
3164  if( *cutoff )
3165  {
3166  *value = SCIPinfinity(scip);
3167 
3168  if( valid != NULL )
3169  *valid = TRUE;
3170 
3171  SCIPdebugMsg(scip, "%s branch of var <%s> detected infeasible during propagation\n",
3172  down ? "down" : "up", SCIPvarGetName(var));
3173  }
3174  }
3175 
3176  /* if propagation did not already detect infeasibility, solve the probing LP */
3177  if( !(*cutoff) )
3178  {
3179  SCIP_CALL( SCIPsolveProbingLP(scip, itlim, lperror, cutoff) );
3180  assert(SCIPisLPRelax(scip));
3181 
3182  if( *cutoff )
3183  {
3184  assert(!(*lperror));
3185 
3186  *value = SCIPinfinity(scip);
3187 
3188  if( valid != NULL )
3189  *valid = TRUE;
3190 
3191  SCIPdebugMsg(scip, "%s branch of var <%s> detected infeasible in LP solving: status=%d\n",
3192  down ? "down" : "up", SCIPvarGetName(var), SCIPgetLPSolstat(scip));
3193  }
3194  else if( !(*lperror) )
3195  {
3196  /* save the lp solution status */
3197  scip->stat->lastsblpsolstats[down ? 0 : 1] = SCIPgetLPSolstat(scip);
3198 
3199  switch( SCIPgetLPSolstat(scip) )
3200  {
3202  {
3203  *value = SCIPgetLPObjval(scip);
3204  assert(SCIPisLT(scip, *value, SCIPgetCutoffbound(scip)));
3205 
3206  SCIPdebugMsg(scip, "probing LP solved to optimality, objective value: %16.9g\n", *value);
3207 
3208  if( valid != NULL )
3209  *valid = TRUE;
3210 
3211  /* check the strong branching LP solution for feasibility */
3212  SCIP_CALL( SCIPtryStrongbranchLPSol(scip, foundsol, cutoff) );
3213  break;
3214  }
3216  ++scip->stat->nsbtimesiterlimhit;
3217  /*lint -fallthrough*/
3219  {
3220  /* use LP value as estimate */
3221  SCIP_LPI* lpi;
3222  SCIP_Real objval;
3223  SCIP_Real looseobjval;
3224 
3225  SCIPdebugMsg(scip, "probing LP hit %s limit\n", SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_ITERLIMIT ? "iteration" : "time");
3226 
3227  /* we access the LPI directly, because when a time limit was hit, we cannot access objective value and dual
3228  * feasibility using the SCIPlp... methods; we should try to avoid direct calls to the LPI, but this is rather
3229  * uncritical here, because we are immediately after the SCIPsolveProbingLP() call, because we access the LPI
3230  * read-only, and we check SCIPlpiWasSolved() first
3231  */
3232  SCIP_CALL( SCIPgetLPI(scip, &lpi) );
3233 
3234  if( SCIPlpiWasSolved(lpi) )
3235  {
3236  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
3237  looseobjval = SCIPlpGetLooseObjval(scip->lp, scip->set, scip->transprob);
3238 
3239  /* the infinity value in the LPI should not be smaller than SCIP's infinity value */
3240  assert(!SCIPlpiIsInfinity(lpi, objval) || SCIPisInfinity(scip, objval));
3241 
3242  /* we use SCIP's infinity value here because a value larger than this is counted as infeasible by SCIP */
3243  if( SCIPisInfinity(scip, objval) )
3244  *value = SCIPinfinity(scip);
3245  else if( SCIPisInfinity(scip, -looseobjval) )
3246  *value = -SCIPinfinity(scip);
3247  else
3248  *value = objval + looseobjval;
3249 
3250  if( SCIPlpiIsDualFeasible(lpi) )
3251  {
3252  if( valid != NULL )
3253  *valid = TRUE;
3254 
3255  if( SCIPisGE(scip, *value, SCIPgetCutoffbound(scip)) )
3256  *cutoff = TRUE;
3257  }
3258  }
3259  break;
3260  }
3261  case SCIP_LPSOLSTAT_ERROR:
3263  *lperror = TRUE;
3264  break;
3265  case SCIP_LPSOLSTAT_NOTSOLVED: /* should only be the case for *cutoff = TRUE or *lperror = TRUE */
3266  case SCIP_LPSOLSTAT_OBJLIMIT: /* in this case, *cutoff should be TRUE and we should not get here */
3267  case SCIP_LPSOLSTAT_INFEASIBLE: /* in this case, *cutoff should be TRUE and we should not get here */
3268  default:
3269  SCIPerrorMessage("invalid LP solution status <%d>\n", SCIPgetLPSolstat(scip));
3270  return SCIP_INVALIDDATA;
3271  } /*lint !e788*/
3272  }
3273 
3274  /* If columns are missing in the LP, the cutoff flag may be wrong. Therefore, we need to set it and the valid pointer
3275  * to false here.
3276  */
3277  if( (*cutoff) && !SCIPallColsInLP(scip) )
3278  {
3279  *cutoff = FALSE;
3280  }
3281 
3282 #ifndef NDEBUG
3283  if( *lperror )
3284  {
3285  SCIPdebugMsg(scip, "error during strong branching probing LP solving: status=%d\n", SCIPgetLPSolstat(scip));
3286  }
3287 #endif
3288  }
3289 
3290  /* if the subproblem was feasible, we store the local bounds of the variables after propagation and (possibly)
3291  * conflict analysis
3292  * @todo do this after propagation? should be able to get valid bounds more often, but they might be weaker
3293  */
3294  if( !(*cutoff) && newlbs != NULL)
3295  {
3296  int v;
3297 
3298  assert(newubs != NULL);
3299 
3300  /* initialize the newlbs and newubs to the current local bounds */
3301  if( firstchild )
3302  {
3303  for( v = 0; v < nvars; ++v )
3304  {
3305  newlbs[v] = SCIPvarGetLbLocal(vars[v]);
3306  newubs[v] = SCIPvarGetUbLocal(vars[v]);
3307  }
3308  }
3309  /* update newlbs and newubs: take the weaker of the already stored bounds and the current local bounds */
3310  else
3311  {
3312  for( v = 0; v < nvars; ++v )
3313  {
3314  SCIP_Real lb = SCIPvarGetLbLocal(vars[v]);
3315  SCIP_Real ub = SCIPvarGetUbLocal(vars[v]);
3316 
3317  newlbs[v] = MIN(newlbs[v], lb);
3318  newubs[v] = MAX(newubs[v], ub);
3319  }
3320  }
3321  }
3322 
3323  /* revert all changes at the probing node */
3324  SCIP_CALL( SCIPbacktrackProbing(scip, 0) );
3325 
3326  return SCIP_OKAY;
3327 }
3328 
3329 /** gets strong branching information with previous domain propagation on column variable
3330  *
3331  * Before calling this method, the strong branching mode must have been activated by calling SCIPstartStrongbranch();
3332  * after strong branching was done for all candidate variables, the strong branching mode must be ended by
3333  * SCIPendStrongbranch(). Since this method applies domain propagation before strongbranching, propagation has to be be
3334  * enabled in the SCIPstartStrongbranch() call.
3335  *
3336  * Before solving the strong branching LP, domain propagation can be performed. The number of propagation rounds
3337  * can be specified by the parameter @p maxproprounds.
3338  *
3339  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3340  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3341  *
3342  * @pre This method can be called if @p scip is in one of the following stages:
3343  * - \ref SCIP_STAGE_PRESOLVED
3344  * - \ref SCIP_STAGE_SOLVING
3345  *
3346  * @warning When using this method, LP banching candidates and solution values must be copied beforehand, because
3347  * they are updated w.r.t. the strong branching LP solution.
3348  */
3350  SCIP* scip, /**< SCIP data structure */
3351  SCIP_VAR* var, /**< variable to get strong branching values for */
3352  SCIP_Real solval, /**< value of the variable in the current LP solution */
3353  SCIP_Real lpobjval, /**< LP objective value of the current LP solution */
3354  int itlim, /**< iteration limit for strong branchings */
3355  int maxproprounds, /**< maximum number of propagation rounds (-1: no limit, -2: parameter
3356  * settings) */
3357  SCIP_Real* down, /**< stores dual bound after branching column down */
3358  SCIP_Real* up, /**< stores dual bound after branching column up */
3359  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
3360  * otherwise, it can only be used as an estimate value */
3361  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
3362  * otherwise, it can only be used as an estimate value */
3363  SCIP_Longint* ndomredsdown, /**< pointer to store the number of domain reductions down, or NULL */
3364  SCIP_Longint* ndomredsup, /**< pointer to store the number of domain reductions up, or NULL */
3365  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
3366  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
3367  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
3368  * infeasible downwards branch, or NULL */
3369  SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
3370  * infeasible upwards branch, or NULL */
3371  SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred or the
3372  * solving process should be stopped (e.g., due to a time limit) */
3373  SCIP_Real* newlbs, /**< array to store valid lower bounds for all active variables, or NULL */
3374  SCIP_Real* newubs /**< array to store valid upper bounds for all active variables, or NULL */
3375  )
3376 {
3377  SCIP_COL* col;
3378  SCIP_VAR** vars;
3379  SCIP_Longint oldniters;
3380  SCIP_Real newub;
3381  SCIP_Real newlb;
3382  SCIP_Bool propagate;
3383  SCIP_Bool cutoff;
3384  SCIP_Bool downchild;
3385  SCIP_Bool firstchild;
3386  SCIP_Bool foundsol;
3387  SCIP_Bool downvalidlocal;
3388  SCIP_Bool upvalidlocal;
3389  SCIP_Bool allcolsinlp;
3390  SCIP_Bool enabledconflict;
3391  int oldnconflicts;
3392  int nvars;
3393 
3394  assert(scip != NULL);
3395  assert(var != NULL);
3396  assert(SCIPvarIsIntegral(var));
3397  assert(down != NULL);
3398  assert(up != NULL);
3399  assert(lperror != NULL);
3400  assert((newlbs != NULL) == (newubs != NULL));
3401  assert(SCIPinProbing(scip));
3402  assert(var->scip == scip);
3403 
3404  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchWithPropagation", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3405 
3406  /* check whether propagation should be performed */
3407  propagate = (maxproprounds != 0 && maxproprounds != -3);
3408 
3409  /* Check, if all existing columns are in LP.
3410  * If this is not the case, we may still return that the up and down dual bounds are valid, because the branching
3411  * rule should not apply them otherwise.
3412  * However, we must not set the downinf or upinf pointers to TRUE based on the dual bound, because we cannot
3413  * guarantee that this node can be cut off.
3414  */
3415  allcolsinlp = SCIPallColsInLP(scip);
3416 
3417  /* if maxproprounds is -2, change it to 0, which for the following calls means using the parameter settings */
3418  if( maxproprounds == -2 )
3419  maxproprounds = 0;
3420 
3421  *down = lpobjval;
3422  *up = lpobjval;
3423  if( downvalid != NULL )
3424  *downvalid = FALSE;
3425  if( upvalid != NULL )
3426  *upvalid = FALSE;
3427  if( downinf != NULL )
3428  *downinf = FALSE;
3429  if( upinf != NULL )
3430  *upinf = FALSE;
3431  if( downconflict != NULL )
3432  *downconflict = FALSE;
3433  if( upconflict != NULL )
3434  *upconflict = FALSE;
3435  if( ndomredsdown != NULL )
3436  *ndomredsdown = 0;
3437  if( ndomredsup != NULL )
3438  *ndomredsup = 0;
3439 
3440  *lperror = FALSE;
3441 
3442  vars = SCIPgetVars(scip);
3443  nvars = SCIPgetNVars(scip);
3444 
3446 
3447  /* check if the solving process should be aborted */
3448  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3449  {
3450  /* mark this as if the LP failed */
3451  *lperror = TRUE;
3452  return SCIP_OKAY;
3453  }
3454 
3456  {
3457  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3458  return SCIP_INVALIDDATA;
3459  }
3460 
3461  col = SCIPvarGetCol(var);
3462  assert(col != NULL);
3463 
3464  if( !SCIPcolIsInLP(col) )
3465  {
3466  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3467  return SCIP_INVALIDDATA;
3468  }
3469 
3470  newlb = SCIPfeasFloor(scip, solval + 1.0);
3471  newub = SCIPfeasCeil(scip, solval - 1.0);
3472 
3473  SCIPdebugMsg(scip, "strong branching on var <%s>: solval=%g, lb=%g, ub=%g\n", SCIPvarGetName(var), solval,
3475 
3476  /* the up branch is infeasible due to the branching bound change; since this means that solval is not within the
3477  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3478  * are valid for and were already applied at the probing root
3479  */
3480  if( newlb > SCIPvarGetUbLocal(var) + 0.5 )
3481  {
3482  *up = SCIPinfinity(scip);
3483 
3484  if( upinf != NULL )
3485  *upinf = TRUE;
3486 
3487  if( upvalid != NULL )
3488  *upvalid = TRUE;
3489 
3490  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3491  if( upconflict != NULL )
3492  *upconflict = TRUE;
3493 
3494  SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3495  *down, *up, FALSE, TRUE, 0LL, INT_MAX);
3496 
3497  /* we do not regard the down branch; its valid pointer stays set to FALSE */
3498  return SCIP_OKAY;
3499  }
3500 
3501  /* the down branch is infeasible due to the branching bound change; since this means that solval is not within the
3502  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3503  * are valid for and were already applied at the probing root
3504  */
3505  if( newub < SCIPvarGetLbLocal(var) - 0.5 )
3506  {
3507  *down = SCIPinfinity(scip);
3508 
3509  if( downinf != NULL )
3510  *downinf = TRUE;
3511 
3512  if( downvalid != NULL )
3513  *downvalid = TRUE;
3514 
3515  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3516  if( downconflict != NULL )
3517  *downconflict = TRUE;
3518 
3519  SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3520  *down, *up, TRUE, FALSE, 0LL, INT_MAX);
3521 
3522  /* we do not regard the up branch; its valid pointer stays set to FALSE */
3523  return SCIP_OKAY;
3524  }
3525 
3526  /* We now do strong branching by creating the two potential child nodes as probing nodes and solving them one after
3527  * the other. We will stop when the first child is detected infeasible, saving the effort we would need for the
3528  * second child. Since empirically, the up child tends to be infeasible more often, we do strongbranching first on
3529  * the up branch.
3530  */
3531  oldniters = scip->stat->nsbdivinglpiterations;
3532  firstchild = TRUE;
3533  cutoff = FALSE;
3534 
3535  /* switch conflict analysis according to usesb parameter */
3536  enabledconflict = scip->set->conf_enable;
3537  scip->set->conf_enable = (scip->set->conf_enable && scip->set->conf_usesb);
3538 
3539  /* @todo: decide the branch to look at first based on the cutoffs in previous calls? */
3540  downchild = SCIPisStrongbranchDownFirst(scip, var);
3541 
3542  downvalidlocal = FALSE;
3543  upvalidlocal = FALSE;
3544 
3545  do
3546  {
3547  oldnconflicts = SCIPconflictGetNConflicts(scip->conflict);
3548 
3549  if( downchild )
3550  {
3551  SCIP_CALL( performStrongbranchWithPropagation(scip, var, downchild, firstchild, propagate, newub, itlim, maxproprounds,
3552  down, &downvalidlocal, ndomredsdown, downconflict, lperror, vars, nvars, newlbs, newubs, &foundsol, &cutoff) );
3553 
3554  /* check whether a new solutions rendered the previous child infeasible */
3555  if( foundsol && !firstchild && allcolsinlp )
3556  {
3557  if( SCIPisGE(scip, *up, SCIPgetCutoffbound(scip)) )
3558  {
3559  if( upinf != NULL )
3560  *upinf = TRUE;
3561  }
3562  }
3563 
3564  /* check for infeasibility */
3565  if( cutoff )
3566  {
3567  if( downinf != NULL )
3568  *downinf = TRUE;
3569 
3570  if( downconflict != NULL &&
3571  (SCIPvarGetLbLocal(var) > newub + 0.5 || SCIPconflictGetNConflicts(scip->conflict) > oldnconflicts) )
3572  {
3573  *downconflict = TRUE;
3574  }
3575 
3576  if( !scip->set->branch_forceall )
3577  {
3578  /* if this is the first call, we do not regard the up branch, its valid pointer is initially set to FALSE */
3579  break;
3580  }
3581  }
3582  }
3583  else
3584  {
3585  SCIP_CALL( performStrongbranchWithPropagation(scip, var, downchild, firstchild, propagate, newlb, itlim, maxproprounds,
3586  up, &upvalidlocal, ndomredsup, upconflict, lperror, vars, nvars, newlbs, newubs, &foundsol, &cutoff) );
3587 
3588  /* check whether a new solutions rendered the previous child infeasible */
3589  if( foundsol && !firstchild && allcolsinlp )
3590  {
3591  if( SCIPisGE(scip, *down, SCIPgetCutoffbound(scip)) )
3592  {
3593  if( downinf != NULL )
3594  *downinf = TRUE;
3595  }
3596  }
3597 
3598  /* check for infeasibility */
3599  if( cutoff )
3600  {
3601  if( upinf != NULL )
3602  *upinf = TRUE;
3603 
3604  assert(upinf == NULL || (*upinf) == TRUE);
3605 
3606  if( upconflict != NULL &&
3607  (SCIPvarGetUbLocal(var) < newlb - 0.5 || SCIPconflictGetNConflicts(scip->conflict) > oldnconflicts) )
3608  {
3609  *upconflict = TRUE;
3610  }
3611 
3612  if( !scip->set->branch_forceall )
3613  {
3614  /* if this is the first call, we do not regard the down branch, its valid pointer is initially set to FALSE */
3615  break;
3616  }
3617  }
3618  }
3619 
3620  downchild = !downchild;
3621  firstchild = !firstchild;
3622  }
3623  while( !firstchild );
3624 
3625  /* set strong branching information in column */
3626  if( *lperror )
3627  {
3628  SCIPcolInvalidateStrongbranchData(col, scip->set, scip->stat, scip->lp);
3629  }
3630  else
3631  {
3632  SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3633  *down, *up, downvalidlocal, upvalidlocal, scip->stat->nsbdivinglpiterations - oldniters, itlim);
3634  }
3635 
3636  if( downvalid != NULL )
3637  *downvalid = downvalidlocal;
3638  if( upvalid != NULL )
3639  *upvalid = upvalidlocal;
3640 
3641  scip->set->conf_enable = enabledconflict;
3642 
3643  return SCIP_OKAY; /*lint !e438*/
3644 }
3645 
3646 /** gets strong branching information on column variable x with integral LP solution value (val); that is, the down branch
3647  * is (val -1.0) and the up brach ins (val +1.0)
3648  *
3649  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3650  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3651  *
3652  * @pre This method can be called if @p scip is in one of the following stages:
3653  * - \ref SCIP_STAGE_PRESOLVED
3654  * - \ref SCIP_STAGE_SOLVING
3655  *
3656  * @note If the integral LP solution value is the lower or upper bound of the variable, the corresponding branch will be
3657  * marked as infeasible. That is, the valid pointer and the infeasible pointer are set to TRUE.
3658  */
3660  SCIP* scip, /**< SCIP data structure */
3661  SCIP_VAR* var, /**< variable to get strong branching values for */
3662  int itlim, /**< iteration limit for strong branchings */
3663  SCIP_Bool idempotent, /**< should scip's state remain the same after the call (statistics, column states...), or should it be updated ? */
3664  SCIP_Real* down, /**< stores dual bound after branching column down */
3665  SCIP_Real* up, /**< stores dual bound after branching column up */
3666  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
3667  * otherwise, it can only be used as an estimate value */
3668  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
3669  * otherwise, it can only be used as an estimate value */
3670  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
3671  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
3672  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
3673  * infeasible downwards branch, or NULL */
3674  SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
3675  * infeasible upwards branch, or NULL */
3676  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3677  * solving process should be stopped (e.g., due to a time limit) */
3678  )
3679 {
3680  SCIP_COL* col;
3681  SCIP_Real localdown;
3682  SCIP_Real localup;
3683  SCIP_Bool localdownvalid;
3684  SCIP_Bool localupvalid;
3685 
3686  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchInt", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3687 
3688  assert(lperror != NULL);
3689  assert(var->scip == scip);
3690 
3691  if( downvalid != NULL )
3692  *downvalid = FALSE;
3693  if( upvalid != NULL )
3694  *upvalid = FALSE;
3695  if( downinf != NULL )
3696  *downinf = FALSE;
3697  if( upinf != NULL )
3698  *upinf = FALSE;
3699  if( downconflict != NULL )
3700  *downconflict = FALSE;
3701  if( upconflict != NULL )
3702  *upconflict = FALSE;
3703 
3705  {
3706  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3707  return SCIP_INVALIDDATA;
3708  }
3709 
3710  col = SCIPvarGetCol(var);
3711  assert(col != NULL);
3712 
3713  if( !SCIPcolIsInLP(col) )
3714  {
3715  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3716  return SCIP_INVALIDDATA;
3717  }
3718 
3719  /* check if the solving process should be aborted */
3720  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3721  {
3722  /* mark this as if the LP failed */
3723  *lperror = TRUE;
3724  return SCIP_OKAY;
3725  }
3726 
3727  /* call strong branching for column */
3728  SCIP_CALL( SCIPcolGetStrongbranch(col, TRUE, scip->set, scip->stat, scip->transprob, scip->lp, itlim, !idempotent, !idempotent,
3729  &localdown, &localup, &localdownvalid, &localupvalid, lperror) );
3730 
3731  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3732  * declare the sub nodes infeasible
3733  */
3734  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3735  {
3736  if( !idempotent ) /*lint !e774*/
3737  {
3738  SCIP_CALL( analyzeStrongbranch(scip, var, downinf, upinf, downconflict, upconflict) );
3739  }
3740  else
3741  {
3742  if( downinf != NULL )
3743  *downinf = localdownvalid && SCIPsetIsGE(scip->set, localdown, scip->lp->cutoffbound);
3744  if( upinf != NULL )
3745  *upinf = localupvalid && SCIPsetIsGE(scip->set, localup, scip->lp->cutoffbound);
3746  }
3747  }
3748 
3749  if( down != NULL )
3750  *down = localdown;
3751  if( up != NULL )
3752  *up = localup;
3753  if( downvalid != NULL )
3754  *downvalid = localdownvalid;
3755  if( upvalid != NULL )
3756  *upvalid = localupvalid;
3757 
3758  return SCIP_OKAY;
3759 }
3760 
3761 /** gets strong branching information on column variables with fractional values
3762  *
3763  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3764  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3765  *
3766  * @pre This method can be called if @p scip is in one of the following stages:
3767  * - \ref SCIP_STAGE_PRESOLVED
3768  * - \ref SCIP_STAGE_SOLVING
3769  */
3771  SCIP* scip, /**< SCIP data structure */
3772  SCIP_VAR** vars, /**< variables to get strong branching values for */
3773  int nvars, /**< number of variables */
3774  int itlim, /**< iteration limit for strong branchings */
3775  SCIP_Real* down, /**< stores dual bounds after branching variables down */
3776  SCIP_Real* up, /**< stores dual bounds after branching variables up */
3777  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
3778  * otherwise, they can only be used as an estimate value */
3779  SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
3780  * otherwise, they can only be used as an estimate value */
3781  SCIP_Bool* downinf, /**< array to store whether the downward branches are infeasible, or NULL */
3782  SCIP_Bool* upinf, /**< array to store whether the upward branches are infeasible, or NULL */
3783  SCIP_Bool* downconflict, /**< array to store whether conflict constraints were created for
3784  * infeasible downward branches, or NULL */
3785  SCIP_Bool* upconflict, /**< array to store whether conflict constraints were created for
3786  * infeasible upward branches, or NULL */
3787  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3788  * solving process should be stopped (e.g., due to a time limit) */
3789  )
3790 {
3791  SCIP_COL** cols;
3792  int j;
3793 
3794  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarsStrongbranchesFrac", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3795 
3796  assert( lperror != NULL );
3797  assert( vars != NULL );
3798 
3799  /* set up data */
3800  cols = NULL;
3801  SCIP_CALL( SCIPallocBufferArray(scip, &cols, nvars) );
3802  assert(cols != NULL);
3803  for( j = 0; j < nvars; ++j )
3804  {
3805  SCIP_VAR* var;
3806  SCIP_COL* col;
3807 
3808  if( downvalid != NULL )
3809  downvalid[j] = FALSE;
3810  if( upvalid != NULL )
3811  upvalid[j] = FALSE;
3812  if( downinf != NULL )
3813  downinf[j] = FALSE;
3814  if( upinf != NULL )
3815  upinf[j] = FALSE;
3816  if( downconflict != NULL )
3817  downconflict[j] = FALSE;
3818  if( upconflict != NULL )
3819  upconflict[j] = FALSE;
3820 
3821  var = vars[j];
3822  assert( var != NULL );
3824  {
3825  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3826  SCIPfreeBufferArray(scip, &cols);
3827  return SCIP_INVALIDDATA;
3828  }
3829 
3830  col = SCIPvarGetCol(var);
3831  assert(col != NULL);
3832  cols[j] = col;
3833 
3834  if( !SCIPcolIsInLP(col) )
3835  {
3836  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3837  SCIPfreeBufferArray(scip, &cols);
3838  return SCIP_INVALIDDATA;
3839  }
3840  }
3841 
3842  /* check if the solving process should be aborted */
3843  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3844  {
3845  /* mark this as if the LP failed */
3846  *lperror = TRUE;
3847  }
3848  else
3849  {
3850  /* call strong branching for columns with fractional value */
3851  SCIP_CALL( SCIPcolGetStrongbranches(cols, nvars, FALSE, scip->set, scip->stat, scip->transprob, scip->lp, itlim,
3852  down, up, downvalid, upvalid, lperror) );
3853 
3854  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3855  * declare the sub nodes infeasible
3856  */
3857  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3858  {
3859  for( j = 0; j < nvars; ++j )
3860  {
3861  SCIP_CALL( analyzeStrongbranch(scip, vars[j], (downinf != NULL) ? (&(downinf[j])) : NULL,
3862  (upinf != NULL) ? (&(upinf[j])) : NULL, (downconflict != NULL) ? (&(downconflict[j])) : NULL,
3863  (upconflict != NULL) ? (&(upconflict[j])) : NULL) );
3864  }
3865  }
3866  }
3867  SCIPfreeBufferArray(scip, &cols);
3868 
3869  return SCIP_OKAY;
3870 }
3871 
3872 /** gets strong branching information on column variables with integral values
3873  *
3874  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3875  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3876  *
3877  * @pre This method can be called if @p scip is in one of the following stages:
3878  * - \ref SCIP_STAGE_PRESOLVED
3879  * - \ref SCIP_STAGE_SOLVING
3880  */
3882  SCIP* scip, /**< SCIP data structure */
3883  SCIP_VAR** vars, /**< variables to get strong branching values for */
3884  int nvars, /**< number of variables */
3885  int itlim, /**< iteration limit for strong branchings */
3886  SCIP_Real* down, /**< stores dual bounds after branching variables down */
3887  SCIP_Real* up, /**< stores dual bounds after branching variables up */
3888  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
3889  * otherwise, they can only be used as an estimate value */
3890  SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
3891  * otherwise, they can only be used as an estimate value */
3892  SCIP_Bool* downinf, /**< array to store whether the downward branches are infeasible, or NULL */
3893  SCIP_Bool* upinf, /**< array to store whether the upward branches are infeasible, or NULL */
3894  SCIP_Bool* downconflict, /**< array to store whether conflict constraints were created for
3895  * infeasible downward branches, or NULL */
3896  SCIP_Bool* upconflict, /**< array to store whether conflict constraints were created for
3897  * infeasible upward branches, or NULL */
3898  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3899  * solving process should be stopped (e.g., due to a time limit) */
3900  )
3901 {
3902  SCIP_COL** cols;
3903  int j;
3904 
3905  assert(lperror != NULL);
3906 
3907  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarsStrongbranchesInt", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3908 
3909  assert( vars != NULL );
3910 
3911  /* set up data */
3912  cols = NULL;
3913  SCIP_CALL( SCIPallocBufferArray(scip, &cols, nvars) );
3914  assert(cols != NULL);
3915  for( j = 0; j < nvars; ++j )
3916  {
3917  SCIP_VAR* var;
3918  SCIP_COL* col;
3919 
3920  if( downvalid != NULL )
3921  downvalid[j] = FALSE;
3922  if( upvalid != NULL )
3923  upvalid[j] = FALSE;
3924  if( downinf != NULL )
3925  downinf[j] = FALSE;
3926  if( upinf != NULL )
3927  upinf[j] = FALSE;
3928  if( downconflict != NULL )
3929  downconflict[j] = FALSE;
3930  if( upconflict != NULL )
3931  upconflict[j] = FALSE;
3932 
3933  var = vars[j];
3934  assert( var != NULL );
3936  {
3937  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3938  SCIPfreeBufferArray(scip, &cols);
3939  return SCIP_INVALIDDATA;
3940  }
3941 
3942  col = SCIPvarGetCol(var);
3943  assert(col != NULL);
3944  cols[j] = col;
3945 
3946  if( !SCIPcolIsInLP(col) )
3947  {
3948  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3949  SCIPfreeBufferArray(scip, &cols);
3950  return SCIP_INVALIDDATA;
3951  }
3952  }
3953 
3954  /* check if the solving process should be aborted */
3955  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3956  {
3957  /* mark this as if the LP failed */
3958  *lperror = TRUE;
3959  }
3960  else
3961  {
3962  /* call strong branching for columns */
3963  SCIP_CALL( SCIPcolGetStrongbranches(cols, nvars, TRUE, scip->set, scip->stat, scip->transprob, scip->lp, itlim,
3964  down, up, downvalid, upvalid, lperror) );
3965 
3966  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3967  * declare the sub nodes infeasible
3968  */
3969  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3970  {
3971  for( j = 0; j < nvars; ++j )
3972  {
3973  SCIP_CALL( analyzeStrongbranch(scip, vars[j], (downinf != NULL) ? (&(downinf[j])) : NULL,
3974  (upinf != NULL) ? (&(upinf[j])) : NULL, (downconflict != NULL) ? (&(downconflict[j])) : NULL,
3975  (upconflict != NULL) ? (&(upconflict[j])) : NULL) );
3976  }
3977  }
3978  }
3979  SCIPfreeBufferArray(scip, &cols);
3980 
3981  return SCIP_OKAY;
3982 }
3983 
3984 /** get LP solution status of last strong branching call (currently only works for strong branching with propagation) */
3986  SCIP* scip, /**< SCIP data structure */
3987  SCIP_BRANCHDIR branchdir /**< branching direction for which LP solution status is requested */
3988  )
3989 {
3990  assert(NULL != scip);
3991  assert(branchdir == SCIP_BRANCHDIR_DOWNWARDS || branchdir == SCIP_BRANCHDIR_UPWARDS);
3992 
3993  return scip->stat->lastsblpsolstats[branchdir == SCIP_BRANCHDIR_DOWNWARDS ? 0 : 1];
3994 }
3995 
3996 /** gets strong branching information on COLUMN variable of the last SCIPgetVarStrongbranch() call;
3997  * returns values of SCIP_INVALID, if strong branching was not yet called on the given variable;
3998  * keep in mind, that the returned old values may have nothing to do with the current LP solution
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_SOLVING
4005  * - \ref SCIP_STAGE_SOLVED
4006  */
4008  SCIP* scip, /**< SCIP data structure */
4009  SCIP_VAR* var, /**< variable to get last strong branching values for */
4010  SCIP_Real* down, /**< stores dual bound after branching column down */
4011  SCIP_Real* up, /**< stores dual bound after branching column up */
4012  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4013  * otherwise, it can only be used as an estimate value */
4014  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4015  * otherwise, it can only be used as an estimate value */
4016  SCIP_Real* solval, /**< stores LP solution value of variable at the last strong branching call, or NULL */
4017  SCIP_Real* lpobjval /**< stores LP objective value at last strong branching call, or NULL */
4018  )
4019 {
4020  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchLast", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
4021 
4023  {
4024  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable\n");
4025  return SCIP_INVALIDDATA;
4026  }
4027 
4028  SCIPcolGetStrongbranchLast(SCIPvarGetCol(var), down, up, downvalid, upvalid, solval, lpobjval);
4029 
4030  return SCIP_OKAY;
4031 }
4032 
4033 /** sets strong branching information for a column variable
4034  *
4035  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4036  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4037  *
4038  * @pre This method can be called if @p scip is in one of the following stages:
4039  * - \ref SCIP_STAGE_SOLVING
4040  */
4042  SCIP* scip, /**< SCIP data structure */
4043  SCIP_VAR* var, /**< variable to set last strong branching values for */
4044  SCIP_Real lpobjval, /**< objective value of the current LP */
4045  SCIP_Real primsol, /**< primal solution value of the column in the current LP */
4046  SCIP_Real down, /**< dual bound after branching column down */
4047  SCIP_Real up, /**< dual bound after branching column up */
4048  SCIP_Bool downvalid, /**< is the returned down value a valid dual bound? */
4049  SCIP_Bool upvalid, /**< is the returned up value a valid dual bound? */
4050  SCIP_Longint iter, /**< total number of strong branching iterations */
4051  int itlim /**< iteration limit applied to the strong branching call */
4052  )
4053 {
4054  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetVarStrongbranchData", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4055 
4057  {
4058  SCIPerrorMessage("cannot set strong branching information on non-COLUMN variable\n");
4059  return SCIP_INVALIDDATA;
4060  }
4061 
4062  SCIPcolSetStrongbranchData(SCIPvarGetCol(var), scip->set, scip->stat, scip->lp, lpobjval, primsol,
4063  down, up, downvalid, upvalid, iter, itlim);
4064 
4065  return SCIP_OKAY;
4066 }
4067 
4068 /** rounds the current solution and tries it afterwards; if feasible, adds it to storage
4069  *
4070  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4071  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4072  *
4073  * @pre This method can be called if @p scip is in one of the following stages:
4074  * - \ref SCIP_STAGE_SOLVING
4075  */
4077  SCIP* scip, /**< SCIP data structure */
4078  SCIP_Bool* foundsol, /**< stores whether solution was feasible and good enough to keep */
4079  SCIP_Bool* cutoff /**< stores whether solution was cutoff due to exceeding the cutoffbound */
4080  )
4081 {
4082  assert(scip != NULL);
4083  assert(foundsol != NULL);
4084  assert(cutoff != NULL);
4085 
4086  SCIP_CALL( SCIPcheckStage(scip, "SCIPtryStrongbranchLPSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4087 
4088  if( scip->set->branch_checksbsol )
4089  {
4090  SCIP_SOL* sol;
4091  SCIP_Bool rounded = TRUE;
4092  SCIP_Real value = SCIPgetLPObjval(scip);
4093  SCIP_Longint oldnbestsolsfound = scip->primal->nbestsolsfound;
4094 
4095  /* start clock for strong branching solutions */
4096  SCIPclockStart(scip->stat->sbsoltime, scip->set);
4097 
4098  SCIP_CALL( SCIPcreateLPSol(scip, &sol, NULL) );
4100 
4101  /* try to round the strong branching solution */
4102  if( scip->set->branch_roundsbsol )
4103  {
4104  SCIP_CALL( SCIProundSol(scip, sol, &rounded) );
4105  }
4106 
4107  /* check the solution for feasibility if rounding worked well (or was not tried) */
4108  if( rounded )
4109  {
4110  SCIP_CALL( SCIPtrySolFree(scip, &sol, FALSE, FALSE, FALSE, TRUE, FALSE, foundsol) );
4111  }
4112  else
4113  {
4114  SCIP_CALL( SCIPfreeSol(scip, &sol) );
4115  }
4116 
4117  if( *foundsol )
4118  {
4119  SCIPdebugMsg(scip, "found new solution in strong branching\n");
4120 
4121  scip->stat->nsbsolsfound++;
4122 
4123  if( scip->primal->nbestsolsfound != oldnbestsolsfound )
4124  {
4125  scip->stat->nsbbestsolsfound++;
4126  }
4127 
4128  if( SCIPisGE(scip, value, SCIPgetCutoffbound(scip)) )
4129  *cutoff = TRUE;
4130  }
4131 
4132  /* stop clock for strong branching solutions */
4133  SCIPclockStop(scip->stat->sbsoltime, scip->set);
4134  }
4135  return SCIP_OKAY;
4136 }
4137 
4138 
4139 /** gets node number of the last node in current branch and bound run, where strong branching was used on the
4140  * given variable, or -1 if strong branching was never applied to the variable in current run
4141  *
4142  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4143  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4144  *
4145  * @pre This method can be called if @p scip is in one of the following stages:
4146  * - \ref SCIP_STAGE_TRANSFORMING
4147  * - \ref SCIP_STAGE_TRANSFORMED
4148  * - \ref SCIP_STAGE_INITPRESOLVE
4149  * - \ref SCIP_STAGE_PRESOLVING
4150  * - \ref SCIP_STAGE_EXITPRESOLVE
4151  * - \ref SCIP_STAGE_PRESOLVED
4152  * - \ref SCIP_STAGE_INITSOLVE
4153  * - \ref SCIP_STAGE_SOLVING
4154  * - \ref SCIP_STAGE_SOLVED
4155  * - \ref SCIP_STAGE_EXITSOLVE
4156  */
4158  SCIP* scip, /**< SCIP data structure */
4159  SCIP_VAR* var /**< variable to get last strong branching node for */
4160  )
4161 {
4162  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarStrongbranchNode", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4163 
4164  assert( var->scip == scip );
4165 
4167  return -1;
4168 
4170 }
4171 
4172 /** if strong branching was already applied on the variable at the current node, returns the number of LPs solved after
4173  * the LP where the strong branching on this variable was applied;
4174  * if strong branching was not yet applied on the variable at the current node, returns INT_MAX
4175  *
4176  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4177  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4178  *
4179  * @pre This method can be called if @p scip is in one of the following stages:
4180  * - \ref SCIP_STAGE_TRANSFORMING
4181  * - \ref SCIP_STAGE_TRANSFORMED
4182  * - \ref SCIP_STAGE_INITPRESOLVE
4183  * - \ref SCIP_STAGE_PRESOLVING
4184  * - \ref SCIP_STAGE_EXITPRESOLVE
4185  * - \ref SCIP_STAGE_PRESOLVED
4186  * - \ref SCIP_STAGE_INITSOLVE
4187  * - \ref SCIP_STAGE_SOLVING
4188  * - \ref SCIP_STAGE_SOLVED
4189  * - \ref SCIP_STAGE_EXITSOLVE
4190  */
4192  SCIP* scip, /**< SCIP data structure */
4193  SCIP_VAR* var /**< variable to get strong branching LP age for */
4194  )
4195 {
4196  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarStrongbranchLPAge", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4197 
4198  assert( var->scip == scip );
4199 
4201  return SCIP_LONGINT_MAX;
4202 
4203  return SCIPcolGetStrongbranchLPAge(SCIPvarGetCol(var), scip->stat);
4204 }
4205 
4206 /** gets number of times, strong branching was applied in current run on the given variable
4207  *
4208  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4209  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4210  *
4211  * @pre This method can be called if @p scip is in one of the following stages:
4212  * - \ref SCIP_STAGE_TRANSFORMING
4213  * - \ref SCIP_STAGE_TRANSFORMED
4214  * - \ref SCIP_STAGE_INITPRESOLVE
4215  * - \ref SCIP_STAGE_PRESOLVING
4216  * - \ref SCIP_STAGE_EXITPRESOLVE
4217  * - \ref SCIP_STAGE_PRESOLVED
4218  * - \ref SCIP_STAGE_INITSOLVE
4219  * - \ref SCIP_STAGE_SOLVING
4220  * - \ref SCIP_STAGE_SOLVED
4221  * - \ref SCIP_STAGE_EXITSOLVE
4222  */
4224  SCIP* scip, /**< SCIP data structure */
4225  SCIP_VAR* var /**< variable to get last strong branching node for */
4226  )
4227 {
4228  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarNStrongbranchs", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4229 
4230  assert( var->scip == scip );
4231 
4233  return 0;
4234 
4236 }
4237 
4238 /** adds given values to lock numbers of type @p locktype of variable for rounding
4239  *
4240  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4241  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4242  *
4243  * @pre This method can be called if @p scip is in one of the following stages:
4244  * - \ref SCIP_STAGE_PROBLEM
4245  * - \ref SCIP_STAGE_TRANSFORMING
4246  * - \ref SCIP_STAGE_TRANSFORMED
4247  * - \ref SCIP_STAGE_INITPRESOLVE
4248  * - \ref SCIP_STAGE_PRESOLVING
4249  * - \ref SCIP_STAGE_EXITPRESOLVE
4250  * - \ref SCIP_STAGE_PRESOLVED
4251  * - \ref SCIP_STAGE_INITSOLVE
4252  * - \ref SCIP_STAGE_SOLVING
4253  * - \ref SCIP_STAGE_EXITSOLVE
4254  * - \ref SCIP_STAGE_FREETRANS
4255  */
4257  SCIP* scip, /**< SCIP data structure */
4258  SCIP_VAR* var, /**< problem variable */
4259  SCIP_LOCKTYPE locktype, /**< type of the variable locks */
4260  int nlocksdown, /**< modification in number of rounding down locks */
4261  int nlocksup /**< modification in number of rounding up locks */
4262  )
4263 {
4264  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarLocksType", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4265 
4266  assert( var->scip == scip );
4267 
4268  switch( scip->set->stage )
4269  {
4270  case SCIP_STAGE_PROBLEM:
4271  assert(!SCIPvarIsTransformed(var));
4272  /*lint -fallthrough*/
4276  case SCIP_STAGE_PRESOLVING:
4278  case SCIP_STAGE_PRESOLVED:
4279  case SCIP_STAGE_INITSOLVE:
4280  case SCIP_STAGE_SOLVING:
4281  case SCIP_STAGE_EXITSOLVE:
4282  case SCIP_STAGE_FREETRANS:
4283  SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, locktype, nlocksdown, nlocksup) );
4284  return SCIP_OKAY;
4285 
4286  default:
4287  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4288  return SCIP_INVALIDCALL;
4289  } /*lint !e788*/
4290 }
4291 
4292 /** adds given values to lock numbers of variable for rounding
4293  *
4294  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4295  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4296  *
4297  * @pre This method can be called if @p scip is in one of the following stages:
4298  * - \ref SCIP_STAGE_PROBLEM
4299  * - \ref SCIP_STAGE_TRANSFORMING
4300  * - \ref SCIP_STAGE_TRANSFORMED
4301  * - \ref SCIP_STAGE_INITPRESOLVE
4302  * - \ref SCIP_STAGE_PRESOLVING
4303  * - \ref SCIP_STAGE_EXITPRESOLVE
4304  * - \ref SCIP_STAGE_PRESOLVED
4305  * - \ref SCIP_STAGE_INITSOLVE
4306  * - \ref SCIP_STAGE_SOLVING
4307  * - \ref SCIP_STAGE_EXITSOLVE
4308  * - \ref SCIP_STAGE_FREETRANS
4309  *
4310  * @note This method will always add variable locks of type model
4311  *
4312  * @note It is recommented to use SCIPaddVarLocksType()
4313  */
4315  SCIP* scip, /**< SCIP data structure */
4316  SCIP_VAR* var, /**< problem variable */
4317  int nlocksdown, /**< modification in number of rounding down locks */
4318  int nlocksup /**< modification in number of rounding up locks */
4319  )
4320 {
4321  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarLocks", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4322 
4323  SCIP_CALL( SCIPaddVarLocksType(scip, var, SCIP_LOCKTYPE_MODEL, nlocksdown, nlocksup) );
4324 
4325  return SCIP_OKAY;
4326 }
4327 
4328 /** add locks of variable with respect to the lock status of the constraint and its negation;
4329  * this method should be called whenever the lock status of a variable in a constraint changes, for example if
4330  * the coefficient of the variable changed its sign or if the left or right hand sides of the constraint were
4331  * added or removed
4332  *
4333  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4334  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4335  *
4336  * @pre This method can be called if @p scip is in one of the following stages:
4337  * - \ref SCIP_STAGE_PROBLEM
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_INITSOLVE
4344  * - \ref SCIP_STAGE_SOLVING
4345  * - \ref SCIP_STAGE_EXITSOLVE
4346  * - \ref SCIP_STAGE_FREETRANS
4347  */
4349  SCIP* scip, /**< SCIP data structure */
4350  SCIP_VAR* var, /**< problem variable */
4351  SCIP_CONS* cons, /**< constraint */
4352  SCIP_Bool lockdown, /**< should the rounding be locked in downwards direction? */
4353  SCIP_Bool lockup /**< should the rounding be locked in upwards direction? */
4354  )
4355 {
4356  int nlocksdown[NLOCKTYPES];
4357  int nlocksup[NLOCKTYPES];
4358  int i;
4359 
4360  SCIP_CALL( SCIPcheckStage(scip, "SCIPlockVarCons", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4361 
4362  assert( var->scip == scip );
4363 
4364  for( i = 0; i < NLOCKTYPES; i++ )
4365  {
4366  nlocksdown[i] = 0;
4367  nlocksup[i] = 0;
4368 
4369  if( SCIPconsIsLockedTypePos(cons, (SCIP_LOCKTYPE) i) )
4370  {
4371  if( lockdown )
4372  ++nlocksdown[i];
4373  if( lockup )
4374  ++nlocksup[i];
4375  }
4376  if( SCIPconsIsLockedTypeNeg(cons, (SCIP_LOCKTYPE) i) )
4377  {
4378  if( lockdown )
4379  ++nlocksup[i];
4380  if( lockup )
4381  ++nlocksdown[i];
4382  }
4383  }
4384 
4385  switch( scip->set->stage )
4386  {
4387  case SCIP_STAGE_PROBLEM:
4388  assert(!SCIPvarIsTransformed(var));
4389  /*lint -fallthrough*/
4393  case SCIP_STAGE_PRESOLVING:
4395  case SCIP_STAGE_INITSOLVE:
4396  case SCIP_STAGE_SOLVING:
4397  case SCIP_STAGE_EXITSOLVE:
4398  case SCIP_STAGE_FREETRANS:
4399  for( i = 0; i < NLOCKTYPES; i++ )
4400  {
4401  if( nlocksdown[i] == 0 && nlocksup[i] == 0 )
4402  continue;
4403 
4404  SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, (SCIP_LOCKTYPE) i, nlocksdown[i], nlocksup[i]) );
4405  }
4406  return SCIP_OKAY;
4407 
4408  default:
4409  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4410  return SCIP_INVALIDCALL;
4411  } /*lint !e788*/
4412 }
4413 
4414 /** remove locks of type @p locktype of variable with respect to the lock status of the constraint and its negation;
4415  * this method should be called whenever the lock status of a variable in a constraint changes, for example if
4416  * the coefficient of the variable changed its sign or if the left or right hand sides of the constraint were
4417  * added or removed
4418  *
4419  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4420  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4421  *
4422  * @pre This method can be called if @p scip is in one of the following stages:
4423  * - \ref SCIP_STAGE_PROBLEM
4424  * - \ref SCIP_STAGE_TRANSFORMING
4425  * - \ref SCIP_STAGE_TRANSFORMED
4426  * - \ref SCIP_STAGE_INITPRESOLVE
4427  * - \ref SCIP_STAGE_PRESOLVING
4428  * - \ref SCIP_STAGE_EXITPRESOLVE
4429  * - \ref SCIP_STAGE_INITSOLVE
4430  * - \ref SCIP_STAGE_SOLVING
4431  * - \ref SCIP_STAGE_EXITSOLVE
4432  * - \ref SCIP_STAGE_FREETRANS
4433  */
4435  SCIP* scip, /**< SCIP data structure */
4436  SCIP_VAR* var, /**< problem variable */
4437  SCIP_CONS* cons, /**< constraint */
4438  SCIP_Bool lockdown, /**< should the rounding be unlocked in downwards direction? */
4439  SCIP_Bool lockup /**< should the rounding be unlocked in upwards direction? */
4440  )
4441 {
4442  int nlocksdown[NLOCKTYPES];
4443  int nlocksup[NLOCKTYPES];
4444  int i;
4445 
4446  SCIP_CALL( SCIPcheckStage(scip, "SCIPunlockVarCons", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4447 
4448  assert( var->scip == scip );
4449 
4450  for( i = 0; i < NLOCKTYPES; i++ )
4451  {
4452  nlocksdown[i] = 0;
4453  nlocksup[i] = 0;
4454 
4455  if( SCIPconsIsLockedTypePos(cons, (SCIP_LOCKTYPE) i) )
4456  {
4457  if( lockdown )
4458  ++nlocksdown[i];
4459  if( lockup )
4460  ++nlocksup[i];
4461  }
4462  if( SCIPconsIsLockedTypeNeg(cons, (SCIP_LOCKTYPE) i) )
4463  {
4464  if( lockdown )
4465  ++nlocksup[i];
4466  if( lockup )
4467  ++nlocksdown[i];
4468  }
4469  }
4470  switch( scip->set->stage )
4471  {
4472  case SCIP_STAGE_PROBLEM:
4473  assert(!SCIPvarIsTransformed(var));
4474  /*lint -fallthrough*/
4478  case SCIP_STAGE_PRESOLVING:
4480  case SCIP_STAGE_INITSOLVE:
4481  case SCIP_STAGE_SOLVING:
4482  case SCIP_STAGE_EXITSOLVE:
4483  case SCIP_STAGE_FREETRANS:
4484  for( i = 0; i < NLOCKTYPES; i++ )
4485  {
4486  if( nlocksdown[i] == 0 && nlocksup[i] == 0 )
4487  continue;
4488 
4489  SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, (SCIP_LOCKTYPE) i, -nlocksdown[i], -nlocksup[i]) );
4490  }
4491  return SCIP_OKAY;
4492 
4493  default:
4494  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4495  return SCIP_INVALIDCALL;
4496  } /*lint !e788*/
4497 }
4498 
4499 /** changes variable's objective value
4500  *
4501  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4502  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4503  *
4504  * @pre This method can be called if @p scip is in one of the following stages:
4505  * - \ref SCIP_STAGE_PROBLEM
4506  * - \ref SCIP_STAGE_TRANSFORMING
4507  * - \ref SCIP_STAGE_PRESOLVING
4508  * - \ref SCIP_STAGE_PRESOLVED
4509  */
4511  SCIP* scip, /**< SCIP data structure */
4512  SCIP_VAR* var, /**< variable to change the objective value for */
4513  SCIP_Real newobj /**< new objective value */
4514  )
4515 {
4516  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarObj", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
4517 
4518  assert( var->scip == scip );
4519 
4520  /* forbid infinite objective values */
4521  if( SCIPisInfinity(scip, REALABS(newobj)) )
4522  {
4523  SCIPerrorMessage("invalid objective value: objective value is infinite\n");
4524  return SCIP_INVALIDDATA;
4525  }
4526 
4527  switch( scip->set->stage )
4528  {
4529  case SCIP_STAGE_PROBLEM:
4530  assert(!SCIPvarIsTransformed(var));
4531  SCIP_CALL( SCIPvarChgObj(var, scip->mem->probmem, scip->set, scip->origprob, scip->primal, scip->lp, scip->eventqueue, newobj) );
4532  return SCIP_OKAY;
4533 
4536  case SCIP_STAGE_PRESOLVING:
4537  case SCIP_STAGE_PRESOLVED:
4538  SCIP_CALL( SCIPvarChgObj(var, scip->mem->probmem, scip->set, scip->transprob, scip->primal, scip->lp, scip->eventqueue, newobj) );
4539  return SCIP_OKAY;
4540 
4541  default:
4542  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4543  return SCIP_INVALIDCALL;
4544  } /*lint !e788*/
4545 }
4546 
4547 /** adds value to variable's objective value
4548  *
4549  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4550  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4551  *
4552  * @pre This method can be called if @p scip is in one of the following stages:
4553  * - \ref SCIP_STAGE_PROBLEM
4554  * - \ref SCIP_STAGE_TRANSFORMING
4555  * - \ref SCIP_STAGE_PRESOLVING
4556  * - \ref SCIP_STAGE_EXITPRESOLVE
4557  * - \ref SCIP_STAGE_PRESOLVED
4558  */
4560  SCIP* scip, /**< SCIP data structure */
4561  SCIP_VAR* var, /**< variable to change the objective value for */
4562  SCIP_Real addobj /**< additional objective value */
4563  )
4564 {
4565  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarObj", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
4566 
4567  assert( var->scip == scip );
4568 
4569  switch( scip->set->stage )
4570  {
4571  case SCIP_STAGE_PROBLEM:
4572  assert(!SCIPvarIsTransformed(var));
4573  SCIP_CALL( SCIPvarAddObj(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->primal,
4574  scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue, addobj) );
4575  return SCIP_OKAY;
4576 
4578  case SCIP_STAGE_PRESOLVING:
4580  case SCIP_STAGE_PRESOLVED:
4581  SCIP_CALL( SCIPvarAddObj(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->primal,
4582  scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue, addobj) );
4583  return SCIP_OKAY;
4584 
4585  default:
4586  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4587  return SCIP_INVALIDCALL;
4588  } /*lint !e788*/
4589 }
4590 
4591 /** returns the adjusted (i.e. rounded, if the given variable is of integral type) lower bound value;
4592  * does not change the bounds of the variable
4593  *
4594  * @return adjusted lower bound for the given variable; the bound of the variable is not changed
4595  *
4596  * @pre This method can be called if @p scip is in one of the following stages:
4597  * - \ref SCIP_STAGE_PROBLEM
4598  * - \ref SCIP_STAGE_TRANSFORMING
4599  * - \ref SCIP_STAGE_TRANSFORMED
4600  * - \ref SCIP_STAGE_INITPRESOLVE
4601  * - \ref SCIP_STAGE_PRESOLVING
4602  * - \ref SCIP_STAGE_EXITPRESOLVE
4603  * - \ref SCIP_STAGE_PRESOLVED
4604  * - \ref SCIP_STAGE_INITSOLVE
4605  * - \ref SCIP_STAGE_SOLVING
4606  * - \ref SCIP_STAGE_SOLVED
4607  * - \ref SCIP_STAGE_EXITSOLVE
4608  * - \ref SCIP_STAGE_FREETRANS
4609  */
4611  SCIP* scip, /**< SCIP data structure */
4612  SCIP_VAR* var, /**< variable to adjust the bound for */
4613  SCIP_Real lb /**< lower bound value to adjust */
4614  )
4615 {
4616  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPadjustedVarLb", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
4617 
4618  SCIPvarAdjustLb(var, scip->set, &lb);
4619 
4620  return lb;
4621 }
4622 
4623 /** returns the adjusted (i.e. rounded, if the given variable is of integral type) upper bound value;
4624  * does not change the bounds of the variable
4625  *
4626  * @return adjusted upper bound for the given variable; the bound of the variable is not changed
4627  *
4628  * @pre This method can be called if @p scip is in one of the following stages:
4629  * - \ref SCIP_STAGE_PROBLEM
4630  * - \ref SCIP_STAGE_TRANSFORMING
4631  * - \ref SCIP_STAGE_TRANSFORMED
4632  * - \ref SCIP_STAGE_INITPRESOLVE
4633  * - \ref SCIP_STAGE_PRESOLVING
4634  * - \ref SCIP_STAGE_EXITPRESOLVE
4635  * - \ref SCIP_STAGE_PRESOLVED
4636  * - \ref SCIP_STAGE_INITSOLVE
4637  * - \ref SCIP_STAGE_SOLVING
4638  * - \ref SCIP_STAGE_SOLVED
4639  * - \ref SCIP_STAGE_EXITSOLVE
4640  * - \ref SCIP_STAGE_FREETRANS
4641  */
4643  SCIP* scip, /**< SCIP data structure */
4644  SCIP_VAR* var, /**< variable to adjust the bound for */
4645  SCIP_Real ub /**< upper bound value to adjust */
4646  )
4647 {
4648  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPadjustedVarUb", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
4649 
4650  SCIPvarAdjustUb(var, scip->set, &ub);
4651 
4652  return ub;
4653 }
4654 
4655 /** depending on SCIP's stage, changes lower bound of variable in the problem, in preprocessing, or in current node;
4656  * if possible, adjusts bound to integral value; doesn't store any inference information in the bound change, such
4657  * that in conflict analysis, this change is treated like a branching decision
4658  *
4659  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4660  * SCIPgetVars()) gets resorted.
4661  *
4662  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4663  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4664  *
4665  * @pre This method can be called if @p scip is in one of the following stages:
4666  * - \ref SCIP_STAGE_PROBLEM
4667  * - \ref SCIP_STAGE_TRANSFORMING
4668  * - \ref SCIP_STAGE_PRESOLVING
4669  * - \ref SCIP_STAGE_SOLVING
4670  *
4671  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4672  */
4674  SCIP* scip, /**< SCIP data structure */
4675  SCIP_VAR* var, /**< variable to change the bound for */
4676  SCIP_Real newbound /**< new value for bound */
4677  )
4678 {
4679  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLb", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4680 
4681  SCIPvarAdjustLb(var, scip->set, &newbound);
4682 
4683  /* ignore tightenings of lower bounds to +infinity during solving process */
4684  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4685  {
4686 #ifndef NDEBUG
4687  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4688  SCIPvarGetLbLocal(var));
4689 #endif
4690  return SCIP_OKAY;
4691  }
4692 
4693  switch( scip->set->stage )
4694  {
4695  case SCIP_STAGE_PROBLEM:
4696  assert(!SCIPvarIsTransformed(var));
4697  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4698  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4699  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4700  scip->branchcand, scip->eventqueue, newbound) );
4701  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
4702  break;
4703 
4705  case SCIP_STAGE_PRESOLVED:
4706  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4707  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4708  break;
4709 
4710  case SCIP_STAGE_PRESOLVING:
4711  if( !SCIPinProbing(scip) )
4712  {
4713  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4714  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4715 
4716  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4717  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable,
4718  var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
4719 
4721  {
4722  SCIP_Bool infeasible;
4723 
4724  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
4725  assert(!infeasible);
4726  }
4727  break;
4728  }
4729  /*lint -fallthrough*/
4730  case SCIP_STAGE_SOLVING:
4732  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4733  scip->cliquetable, var, newbound,
4735  break;
4736 
4737  default:
4738  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4739  return SCIP_INVALIDCALL;
4740  } /*lint !e788*/
4741 
4742  return SCIP_OKAY;
4743 }
4744 
4745 /** depending on SCIP's stage, changes upper bound of variable in the problem, in preprocessing, or in current node;
4746  * if possible, adjusts bound to integral value; doesn't store any inference information in the bound change, such
4747  * that in conflict analysis, this change is treated like a branching decision
4748  *
4749  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4750  * SCIPgetVars()) gets resorted.
4751  *
4752  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4753  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4754  *
4755  * @pre This method can be called if @p scip is in one of the following stages:
4756  * - \ref SCIP_STAGE_PROBLEM
4757  * - \ref SCIP_STAGE_TRANSFORMING
4758  * - \ref SCIP_STAGE_PRESOLVING
4759  * - \ref SCIP_STAGE_SOLVING
4760  *
4761  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4762  */
4764  SCIP* scip, /**< SCIP data structure */
4765  SCIP_VAR* var, /**< variable to change the bound for */
4766  SCIP_Real newbound /**< new value for bound */
4767  )
4768 {
4769  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUb", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4770 
4771  SCIPvarAdjustUb(var, scip->set, &newbound);
4772 
4773  /* ignore tightenings of upper bounds to -infinity during solving process */
4774  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4775  {
4776 #ifndef NDEBUG
4777  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
4778  SCIPvarGetUbLocal(var));
4779 #endif
4780  return SCIP_OKAY;
4781  }
4782 
4783  switch( scip->set->stage )
4784  {
4785  case SCIP_STAGE_PROBLEM:
4786  assert(!SCIPvarIsTransformed(var));
4787  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4788  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4789  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4790  scip->branchcand, scip->eventqueue, newbound) );
4791  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
4792  break;
4793 
4795  case SCIP_STAGE_PRESOLVED:
4796  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4797  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4798  break;
4799 
4800  case SCIP_STAGE_PRESOLVING:
4801  if( !SCIPinProbing(scip) )
4802  {
4803  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4804  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4805 
4806  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4807  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4808  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
4809 
4811  {
4812  SCIP_Bool infeasible;
4813 
4814  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
4815  assert(!infeasible);
4816  }
4817  break;
4818  }
4819  /*lint -fallthrough*/
4820  case SCIP_STAGE_SOLVING:
4822  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4823  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
4824  break;
4825 
4826  default:
4827  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4828  return SCIP_INVALIDCALL;
4829  } /*lint !e788*/
4830 
4831  return SCIP_OKAY;
4832 }
4833 
4834 /** changes lower bound of variable in the given node; if possible, adjust bound to integral value; doesn't store any
4835  * inference information in the bound change, such that in conflict analysis, this change is treated like a branching
4836  * decision
4837  *
4838  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4839  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4840  *
4841  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
4842  */
4844  SCIP* scip, /**< SCIP data structure */
4845  SCIP_NODE* node, /**< node to change bound at, or NULL for current node */
4846  SCIP_VAR* var, /**< variable to change the bound for */
4847  SCIP_Real newbound /**< new value for bound */
4848  )
4849 {
4850  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbNode", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4851 
4852  if( node == NULL )
4853  {
4854  SCIP_CALL( SCIPchgVarLb(scip, var, newbound) );
4855  }
4856  else
4857  {
4858  SCIPvarAdjustLb(var, scip->set, &newbound);
4859 
4860  /* ignore tightenings of lower bounds to +infinity during solving process */
4861  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4862  {
4863 #ifndef NDEBUG
4864  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4865  SCIPvarGetLbLocal(var));
4866 #endif
4867  return SCIP_OKAY;
4868  }
4869 
4870  SCIP_CALL( SCIPnodeAddBoundchg(node, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
4871  scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4873  }
4874 
4875  return SCIP_OKAY;
4876 }
4877 
4878 /** changes upper bound of variable in the given node; if possible, adjust bound to integral value; doesn't store any
4879  * inference information in the bound change, such that in conflict analysis, this change is treated like a branching
4880  * decision
4881  *
4882  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4883  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4884  *
4885  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
4886  */
4888  SCIP* scip, /**< SCIP data structure */
4889  SCIP_NODE* node, /**< node to change bound at, or NULL for current node */
4890  SCIP_VAR* var, /**< variable to change the bound for */
4891  SCIP_Real newbound /**< new value for bound */
4892  )
4893 {
4894  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbNode", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4895 
4896  if( node == NULL )
4897  {
4898  SCIP_CALL( SCIPchgVarUb(scip, var, newbound) );
4899  }
4900  else
4901  {
4902  SCIPvarAdjustUb(var, scip->set, &newbound);
4903 
4904  /* ignore tightenings of upper bounds to -infinity during solving process */
4905  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4906  {
4907 #ifndef NDEBUG
4908  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
4909  SCIPvarGetUbLocal(var));
4910 #endif
4911  return SCIP_OKAY;
4912  }
4913 
4914  SCIP_CALL( SCIPnodeAddBoundchg(node, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
4915  scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4917  }
4918 
4919  return SCIP_OKAY;
4920 }
4921 
4922 /** changes global lower bound of variable; if possible, adjust bound to integral value; also tightens the local bound,
4923  * if the global bound is better than the local bound
4924  *
4925  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4926  * SCIPgetVars()) gets resorted.
4927  *
4928  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4929  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4930  *
4931  * @pre This method can be called if @p scip is in one of the following stages:
4932  * - \ref SCIP_STAGE_PROBLEM
4933  * - \ref SCIP_STAGE_TRANSFORMING
4934  * - \ref SCIP_STAGE_TRANSFORMED
4935  * - \ref SCIP_STAGE_PRESOLVING
4936  * - \ref SCIP_STAGE_SOLVING
4937  *
4938  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4939  */
4941  SCIP* scip, /**< SCIP data structure */
4942  SCIP_VAR* var, /**< variable to change the bound for */
4943  SCIP_Real newbound /**< new value for bound */
4944  )
4945 {
4946  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbGlobal", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4947 
4948  SCIPvarAdjustLb(var, scip->set, &newbound);
4949 
4950  /* ignore tightenings of lower bounds to +infinity during solving process */
4951  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4952  {
4953 #ifndef NDEBUG
4954  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4955  SCIPvarGetLbLocal(var));
4956 #endif
4957  return SCIP_OKAY;
4958  }
4959 
4960  switch( scip->set->stage )
4961  {
4962  case SCIP_STAGE_PROBLEM:
4963  assert(!SCIPvarIsTransformed(var));
4964  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4965  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4966  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4967  scip->branchcand, scip->eventqueue, newbound) );
4968  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
4969  break;
4970 
4973  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4974  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4975  break;
4976 
4977  case SCIP_STAGE_PRESOLVING:
4978  if( !SCIPinProbing(scip) )
4979  {
4980  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4981  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4982 
4983  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4984  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4986 
4988  {
4989  SCIP_Bool infeasible;
4990 
4991  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
4992  assert(!infeasible);
4993  }
4994  break;
4995  }
4996  /*lint -fallthrough*/
4997  case SCIP_STAGE_SOLVING:
4998  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4999  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5001  break;
5002 
5003  default:
5004  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5005  return SCIP_INVALIDCALL;
5006  } /*lint !e788*/
5007 
5008  return SCIP_OKAY;
5009 }
5010 
5011 /** changes global upper bound of variable; if possible, adjust bound to integral value; also tightens the local bound,
5012  * if the global bound is better than the local bound
5013  *
5014  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5015  * SCIPgetVars()) gets resorted.
5016  *
5017  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5018  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5019  *
5020  * @pre This method can be called if @p scip is in one of the following stages:
5021  * - \ref SCIP_STAGE_PROBLEM
5022  * - \ref SCIP_STAGE_TRANSFORMING
5023  * - \ref SCIP_STAGE_TRANSFORMED
5024  * - \ref SCIP_STAGE_PRESOLVING
5025  * - \ref SCIP_STAGE_SOLVING
5026  *
5027  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5028  */
5030  SCIP* scip, /**< SCIP data structure */
5031  SCIP_VAR* var, /**< variable to change the bound for */
5032  SCIP_Real newbound /**< new value for bound */
5033  )
5034 {
5035  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbGlobal", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5036 
5037  SCIPvarAdjustUb(var, scip->set, &newbound);
5038 
5039  /* ignore tightenings of upper bounds to -infinity during solving process */
5040  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5041  {
5042 #ifndef NDEBUG
5043  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5044  SCIPvarGetUbLocal(var));
5045 #endif
5046  return SCIP_OKAY;
5047  }
5048 
5049  switch( scip->set->stage )
5050  {
5051  case SCIP_STAGE_PROBLEM:
5052  assert(!SCIPvarIsTransformed(var));
5053  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5054  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5055  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5056  scip->branchcand, scip->eventqueue, newbound) );
5057  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
5058  break;
5059 
5062  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5063  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5064  break;
5065 
5066  case SCIP_STAGE_PRESOLVING:
5067  if( !SCIPinProbing(scip) )
5068  {
5069  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5070  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5071 
5072  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5073  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5075 
5077  {
5078  SCIP_Bool infeasible;
5079 
5080  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
5081  assert(!infeasible);
5082  }
5083  break;
5084  }
5085  /*lint -fallthrough*/
5086  case SCIP_STAGE_SOLVING:
5087  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5088  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5090  break;
5091 
5092  default:
5093  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5094  return SCIP_INVALIDCALL;
5095  } /*lint !e788*/
5096 
5097  return SCIP_OKAY;
5098 }
5099 
5100 /** changes lazy lower bound of the variable, this is only possible if the variable is not in the LP yet
5101  *
5102  * Lazy bounds are bounds that are already enforced by constraints and the objective function.
5103  * Setting a lazy lower bound has the consequence that for variables which lower bound equals the lazy lower bound,
5104  * the lower bound does not need to be passed on to the LP solver.
5105  * This is especially useful in a column generation (branch-and-price) setting.
5106  *
5107  * @attention If the variable has a global lower bound below lazylb, then the global lower bound is tightened to
5108  * lazylb by a call to SCIPchgVarLbGlobal().
5109  *
5110  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5111  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5112  *
5113  * @pre This method can be called if @p scip is in one of the following stages:
5114  * - \ref SCIP_STAGE_PROBLEM
5115  * - \ref SCIP_STAGE_TRANSFORMING
5116  * - \ref SCIP_STAGE_TRANSFORMED
5117  * - \ref SCIP_STAGE_PRESOLVING
5118  * - \ref SCIP_STAGE_SOLVING
5119  */
5121  SCIP* scip, /**< SCIP data structure */
5122  SCIP_VAR* var, /**< problem variable */
5123  SCIP_Real lazylb /**< the lazy lower bound to be set */
5124  )
5125 {
5126  assert(scip != NULL);
5127  assert(var != NULL);
5128 
5129  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbLazy", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5130 
5131  if( SCIPisGT(scip, lazylb, SCIPvarGetLbGlobal(var)) )
5132  {
5133  SCIP_CALL( SCIPchgVarLbGlobal(scip, var, lazylb) );
5134  }
5135 
5136  SCIP_CALL( SCIPvarChgLbLazy(var, scip->set, lazylb) );
5137 
5138  return SCIP_OKAY;
5139 }
5140 
5141 /** changes lazy upper bound of the variable, this is only possible if the variable is not in the LP yet
5142  *
5143  * Lazy bounds are bounds that are already enforced by constraints and the objective function.
5144  * Setting a lazy upper bound has the consequence that for variables which upper bound equals the lazy upper bound,
5145  * the upper bound does not need to be passed on to the LP solver.
5146  * This is especially useful in a column generation (branch-and-price) setting.
5147  *
5148  * @attention If the variable has a global upper bound above lazyub, then the global upper bound is tightened to
5149  * lazyub by a call to SCIPchgVarUbGlobal().
5150  *
5151  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5152  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5153  *
5154  * @pre This method can be called if @p scip is in one of the following stages:
5155  * - \ref SCIP_STAGE_PROBLEM
5156  * - \ref SCIP_STAGE_TRANSFORMING
5157  * - \ref SCIP_STAGE_TRANSFORMED
5158  * - \ref SCIP_STAGE_PRESOLVING
5159  * - \ref SCIP_STAGE_SOLVING
5160  */
5162  SCIP* scip, /**< SCIP data structure */
5163  SCIP_VAR* var, /**< problem variable */
5164  SCIP_Real lazyub /**< the lazy lower bound to be set */
5165  )
5166 {
5167  assert(scip != NULL);
5168  assert(var != NULL);
5169 
5170  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbLazy", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5171 
5172  if( SCIPisLT(scip, lazyub, SCIPvarGetUbGlobal(var)) )
5173  {
5174  SCIP_CALL( SCIPchgVarUbGlobal(scip, var, lazyub) );
5175  }
5176 
5177  SCIP_CALL( SCIPvarChgUbLazy(var, scip->set, lazyub) );
5178 
5179  return SCIP_OKAY;
5180 }
5181 
5182 /** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
5183  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5184  * doesn't store any inference information in the bound change, such that in conflict analysis, this change
5185  * is treated like a branching decision
5186  *
5187  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5188  * SCIPgetVars()) gets resorted.
5189  *
5190  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5191  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5192  *
5193  * @pre This method can be called if @p scip is in one of the following stages:
5194  * - \ref SCIP_STAGE_PROBLEM
5195  * - \ref SCIP_STAGE_PRESOLVING
5196  * - \ref SCIP_STAGE_SOLVING
5197  *
5198  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5199  */
5201  SCIP* scip, /**< SCIP data structure */
5202  SCIP_VAR* var, /**< variable to change the bound for */
5203  SCIP_Real newbound, /**< new value for bound */
5204  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5205  SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
5206  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5207  )
5208 {
5209  SCIP_Real lb;
5210  SCIP_Real ub;
5211 
5212  assert(infeasible != NULL);
5213 
5214  SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarLb", FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5215  /** @todo if needed provide pending local/global bound changes that will be flushed after leaving diving mode (as in struct_tree.h) */
5216  assert(SCIPgetStage(scip) == SCIP_STAGE_PROBLEM || !SCIPinDive(scip));
5217 
5218  *infeasible = FALSE;
5219  if( tightened != NULL )
5220  *tightened = FALSE;
5221 
5222  SCIPvarAdjustLb(var, scip->set, &newbound);
5223 
5224  /* ignore tightenings of lower bounds to +infinity during solving process */
5225  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5226  {
5227 #ifndef NDEBUG
5228  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
5229  SCIPvarGetLbLocal(var));
5230 #endif
5231  return SCIP_OKAY;
5232  }
5233 
5234  /* get current bounds */
5235  lb = SCIPcomputeVarLbLocal(scip, var);
5236  ub = SCIPcomputeVarUbLocal(scip, var);
5237  assert(SCIPsetIsLE(scip->set, lb, ub));
5238 
5239  if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
5240  {
5241  *infeasible = TRUE;
5242  return SCIP_OKAY;
5243  }
5244  newbound = MIN(newbound, ub);
5245 
5246  if( (force && SCIPsetIsLE(scip->set, newbound, lb)) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
5247  return SCIP_OKAY;
5248 
5249  switch( scip->set->stage )
5250  {
5251  case SCIP_STAGE_PROBLEM:
5252  assert(!SCIPvarIsTransformed(var));
5253  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5254  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5255  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5256  scip->branchcand, scip->eventqueue, newbound) );
5257  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
5258  break;
5260  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5261  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5262  break;
5263  case SCIP_STAGE_PRESOLVING:
5264  if( !SCIPinProbing(scip) )
5265  {
5266  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5267  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5268 
5269  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5270  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5272 
5274  {
5275  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5276  assert(!(*infeasible));
5277  }
5278  break;
5279  }
5280  /*lint -fallthrough*/
5281  case SCIP_STAGE_SOLVING:
5283  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable,
5284  var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
5285  break;
5286 
5287  default:
5288  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5289  return SCIP_INVALIDCALL;
5290  } /*lint !e788*/
5291 
5292  /* check whether the lower bound improved */
5293  if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
5294  *tightened = TRUE;
5295 
5296  return SCIP_OKAY;
5297 }
5298 
5299 /** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
5300  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5301  * doesn't store any inference information in the bound change, such that in conflict analysis, this change
5302  * is treated like a branching decision
5303  *
5304  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5305  * SCIPgetVars()) gets resorted.
5306  *
5307  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5308  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5309  *
5310  * @pre This method can be called if @p scip is in one of the following stages:
5311  * - \ref SCIP_STAGE_PROBLEM
5312  * - \ref SCIP_STAGE_PRESOLVING
5313  * - \ref SCIP_STAGE_SOLVING
5314  *
5315  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5316  */
5318  SCIP* scip, /**< SCIP data structure */
5319  SCIP_VAR* var, /**< variable to change the bound for */
5320  SCIP_Real newbound, /**< new value for bound */
5321  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5322  SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
5323  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5324  )
5325 {
5326  SCIP_Real lb;
5327  SCIP_Real ub;
5328 
5329  assert(infeasible != NULL);
5330  SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarUb", FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5331 
5332  /** @todo if needed provide pending local/global bound changes that will be flushed after leaving diving mode (as in struct_tree.h) */
5333  assert(SCIPgetStage(scip) == SCIP_STAGE_PROBLEM || !SCIPinDive(scip));
5334 
5335  *infeasible = FALSE;
5336  if( tightened != NULL )
5337  *tightened = FALSE;
5338 
5339  SCIPvarAdjustUb(var, scip->set, &newbound);
5340 
5341  /* ignore tightenings of upper bounds to -infinity during solving process */
5342  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5343  {
5344 #ifndef NDEBUG
5345  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5346  SCIPvarGetUbLocal(var));
5347 #endif
5348  return SCIP_OKAY;
5349  }
5350 
5351  /* get current bounds */
5352  lb = SCIPcomputeVarLbLocal(scip, var);
5353  ub = SCIPcomputeVarUbLocal(scip, var);
5354  assert(SCIPsetIsLE(scip->set, lb, ub));
5355 
5356  if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
5357  {
5358  *infeasible = TRUE;
5359  return SCIP_OKAY;
5360  }
5361  newbound = MAX(newbound, lb);
5362 
5363  if( (force && SCIPsetIsGE(scip->set, newbound, ub)) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
5364  return SCIP_OKAY;
5365 
5366  switch( scip->set->stage )
5367  {
5368  case SCIP_STAGE_PROBLEM:
5369  assert(!SCIPvarIsTransformed(var));
5370  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5371  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5372  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5373  scip->branchcand, scip->eventqueue, newbound) );
5374  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
5375  break;
5377  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5378  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5379  break;
5380  case SCIP_STAGE_PRESOLVING:
5381  if( !SCIPinProbing(scip) )
5382  {
5383  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5384  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5385 
5386  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5387  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5389 
5391  {
5392  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5393  assert(!(*infeasible));
5394  }
5395  break;
5396  }
5397  /*lint -fallthrough*/
5398  case SCIP_STAGE_SOLVING:
5400  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5401  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
5402  break;
5403 
5404  default:
5405  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5406  return SCIP_INVALIDCALL;
5407  } /*lint !e788*/
5408 
5409  /* check whether the upper bound improved */
5410  if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
5411  *tightened = TRUE;
5412 
5413  return SCIP_OKAY;
5414 }
5415 
5416 /** fixes variable in preprocessing or in the current node, if the new bound is tighter (w.r.t. bound strengthening
5417  * epsilon) than the current bound; if possible, adjusts bound to integral value; the given inference constraint is
5418  * stored, such that the conflict analysis is able to find out the reason for the deduction of the bound change
5419  *
5420  * @note In presolving stage when not in probing mode the variable will be fixed directly, otherwise this method
5421  * changes first the lowerbound by calling SCIPinferVarLbCons and second the upperbound by calling
5422  * SCIPinferVarUbCons
5423  *
5424  * @note If SCIP is in presolving stage, it can happen that the internal variable array (which get be accessed via
5425  * SCIPgetVars()) gets resorted.
5426  *
5427  * @note During presolving, an integer variable which bound changes to {0,1} is upgraded to a binary variable.
5428  */
5430  SCIP* scip, /**< SCIP data structure */
5431  SCIP_VAR* var, /**< variable to change the bound for */
5432  SCIP_Real fixedval, /**< new value for fixation */
5433  SCIP_CONS* infercons, /**< constraint that deduced the bound change */
5434  int inferinfo, /**< user information for inference to help resolving the conflict */
5435  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5436  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5437  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5438  )
5439 {
5440  assert(scip != NULL);
5441  assert(var != NULL);
5442  assert(infeasible != NULL);
5443 
5444  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarFixCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5445 
5446  if( tightened != NULL )
5447  *tightened = FALSE;
5448 
5449  /* in presolving case we take the shortcut to directly fix the variables */
5450  if( SCIPgetStage(scip) == SCIP_STAGE_PRESOLVING && SCIPtreeGetCurrentDepth(scip->tree) == 0 )
5451  {
5452  SCIP_Bool fixed;
5453 
5454  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5455  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter,
5456  scip->eventqueue, scip->cliquetable, fixedval, infeasible, &fixed) );
5457 
5458  if( tightened != NULL )
5459  *tightened = fixed;
5460  }
5461  /* otherwise we use the lb and ub methods */
5462  else
5463  {
5464  SCIP_Bool lbtightened;
5465 
5466  SCIP_CALL( SCIPinferVarLbCons(scip, var, fixedval, infercons, inferinfo, force, infeasible, &lbtightened) );
5467 
5468  if( ! (*infeasible) )
5469  {
5470  SCIP_CALL( SCIPinferVarUbCons(scip, var, fixedval, infercons, inferinfo, force, infeasible, tightened) );
5471 
5472  if( tightened != NULL )
5473  *tightened |= lbtightened;
5474  }
5475  }
5476 
5477  return SCIP_OKAY;
5478 }
5479 
5480 /** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
5481  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5482  * the given inference constraint is stored, such that the conflict analysis is able to find out the reason
5483  * for the deduction of the bound change
5484  *
5485  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5486  * SCIPgetVars()) gets resorted.
5487  *
5488  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5489  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5490  *
5491  * @pre This method can be called if @p scip is in one of the following stages:
5492  * - \ref SCIP_STAGE_PROBLEM
5493  * - \ref SCIP_STAGE_PRESOLVING
5494  * - \ref SCIP_STAGE_SOLVING
5495  *
5496  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5497  */
5499  SCIP* scip, /**< SCIP data structure */
5500  SCIP_VAR* var, /**< variable to change the bound for */
5501  SCIP_Real newbound, /**< new value for bound */
5502  SCIP_CONS* infercons, /**< constraint that deduced the bound change */
5503  int inferinfo, /**< user information for inference to help resolving the conflict */
5504  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5505  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5506  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5507  )
5508 {
5509  SCIP_Real lb;
5510  SCIP_Real ub;
5511 
5512  assert(infeasible != NULL);
5513 
5514  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarLbCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5515 
5516  *infeasible = FALSE;
5517  if( tightened != NULL )
5518  *tightened = FALSE;
5519 
5520  SCIPvarAdjustLb(var, scip->set, &newbound);
5521 
5522  /* ignore tightenings of lower bounds to +infinity during solving process */
5523  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5524  {
5525 #ifndef NDEBUG
5526  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
5527  SCIPvarGetLbLocal(var));
5528 #endif
5529  return SCIP_OKAY;
5530  }
5531 
5532  /* get current bounds */
5533  lb = SCIPvarGetLbLocal(var);
5534  ub = SCIPvarGetUbLocal(var);
5535  assert(SCIPsetIsLE(scip->set, lb, ub));
5536 
5537  if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
5538  {
5539  *infeasible = TRUE;
5540  return SCIP_OKAY;
5541  }
5542  newbound = MIN(newbound, ub);
5543 
5544  if( (force && SCIPsetIsLE(scip->set, newbound, lb)) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
5545  return SCIP_OKAY;
5546 
5547  switch( scip->set->stage )
5548  {
5549  case SCIP_STAGE_PROBLEM:
5550  assert(!SCIPvarIsTransformed(var));
5551  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5552  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5553  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5554  scip->branchcand, scip->eventqueue, newbound) );
5555  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
5556  break;
5557 
5558  case SCIP_STAGE_PRESOLVING:
5559  if( !SCIPinProbing(scip) )
5560  {
5561  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5562  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5563 
5564  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5565  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5567 
5569  {
5570  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5571  assert(!(*infeasible));
5572  }
5573  break;
5574  }
5575  /*lint -fallthrough*/
5576  case SCIP_STAGE_SOLVING:
5578  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5579  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, infercons, NULL, inferinfo, FALSE) );
5580  break;
5581 
5582  default:
5583  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5584  return SCIP_INVALIDCALL;
5585  } /*lint !e788*/
5586 
5587  /* check whether the lower bound improved */
5588  if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
5589  *tightened = TRUE;
5590 
5591  return SCIP_OKAY;
5592 }
5593 
5594 /** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
5595  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5596  * the given inference constraint is stored, such that the conflict analysis is able to find out the reason
5597  * for the deduction of the bound change
5598  *
5599  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5600  * SCIPgetVars()) gets resorted.
5601  *
5602  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5603  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5604  *
5605  * @pre This method can be called if @p scip is in one of the following stages:
5606  * - \ref SCIP_STAGE_PROBLEM
5607  * - \ref SCIP_STAGE_PRESOLVING
5608  * - \ref SCIP_STAGE_SOLVING
5609  *
5610  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5611  */
5613  SCIP* scip, /**< SCIP data structure */
5614  SCIP_VAR* var, /**< variable to change the bound for */
5615  SCIP_Real newbound, /**< new value for bound */
5616  SCIP_CONS* infercons, /**< constraint that deduced the bound change */
5617  int inferinfo, /**< user information for inference to help resolving the conflict */
5618  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5619  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5620  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5621  )
5622 {
5623  SCIP_Real lb;
5624  SCIP_Real ub;
5625 
5626  assert(infeasible != NULL);
5627 
5628  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarUbCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5629 
5630  *infeasible = FALSE;
5631  if( tightened != NULL )
5632  *tightened = FALSE;
5633 
5634  SCIPvarAdjustUb(var, scip->set, &newbound);
5635 
5636  /* ignore tightenings of upper bounds to -infinity during solving process */
5637  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5638  {
5639 #ifndef NDEBUG
5640  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5641  SCIPvarGetUbLocal(var));
5642 #endif
5643  return SCIP_OKAY;
5644  }
5645 
5646  /* get current bounds */
5647  lb = SCIPvarGetLbLocal(var);
5648  ub = SCIPvarGetUbLocal(var);
5649  assert(SCIPsetIsLE(scip->set, lb, ub));
5650 
5651  if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
5652  {
5653  *infeasible = TRUE;
5654  return SCIP_OKAY;
5655  }
5656  newbound = MAX(newbound, lb);
5657 
5658  if( (force && SCIPsetIsGE(scip->set, newbound, ub)) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
5659  return SCIP_OKAY;
5660 
5661  switch( scip->set->stage )
5662  {
5663  case SCIP_STAGE_PROBLEM:
5664  assert(!SCIPvarIsTransformed(var));
5665  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5666  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5667  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5668  scip->branchcand, scip->eventqueue, newbound) );
5669  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
5670  break;
5671 
5672  case SCIP_STAGE_PRESOLVING:
5673  if( !SCIPinProbing(scip) )
5674  {
5675  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5676  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5677 
5678  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5679  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5681 
5683  {
5684  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5685  assert(!(*infeasible));
5686  }
5687  break;
5688  }
5689  /*lint -fallthrough*/
5690  case SCIP_STAGE_SOLVING:
5692  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5693  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, infercons, NULL, inferinfo, FALSE) );
5694  break;
5695 
5696  default:
5697  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5698  return SCIP_INVALIDCALL;
5699  } /*lint !e788*/
5700 
5701  /* check whether the upper bound improved */
5702  if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
5703  *tightened = TRUE;
5704 
5705  return SCIP_OKAY;
5706 }
5707 
5708 /** depending on SCIP's stage, fixes binary variable in the problem, in preprocessing, or in current node;
5709  * the given inference constraint is stored, such that the conflict analysis is able to find out the reason for the
5710  * deduction of the fixing
5711  *
5712  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5713  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5714  *
5715  * @pre This method can be called if @p scip is in one of the following stages:
5716  * - \ref SCIP_STAGE_PROBLEM
5717  * - \ref SCIP_STAGE_PRESOLVING
5718  * - \ref SCIP_STAGE_SOLVING
5719  */
5721  SCIP* scip, /**< SCIP data structure */
5722  SCIP_VAR* var, /**< binary variable to fix */
5723  SCIP_Bool fixedval, /**< value to fix binary variable to */
5724  SCIP_CONS* infercons, /**< constraint that deduced the fixing */
5725  int inferinfo, /**< user information for inference to help resolving the conflict */
5726  SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
5727  SCIP_Bool* tightened /**< pointer to store whether the fixing tightened the local bounds, or NULL */
5728  )
5729 {
5730  SCIP_Real lb;
5731  SCIP_Real ub;
5732 
5733  assert(SCIPvarIsBinary(var));
5734  assert(fixedval == TRUE || fixedval == FALSE);
5735  assert(infeasible != NULL);
5736 
5737  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferBinvarCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5738 
5739  *infeasible = FALSE;
5740  if( tightened != NULL )
5741  *tightened = FALSE;
5742 
5743  /* get current bounds */
5744  lb = SCIPvarGetLbLocal(var);
5745  ub = SCIPvarGetUbLocal(var);
5746  assert(SCIPsetIsEQ(scip->set, lb, 0.0) || SCIPsetIsEQ(scip->set, lb, 1.0));
5747  assert(SCIPsetIsEQ(scip->set, ub, 0.0) || SCIPsetIsEQ(scip->set, ub, 1.0));
5748  assert(SCIPsetIsLE(scip->set, lb, ub));
5749 
5750  /* check, if variable is already fixed */
5751  if( (lb > 0.5) || (ub < 0.5) )
5752  {
5753  *infeasible = (fixedval == (lb < 0.5));
5754 
5755  return SCIP_OKAY;
5756  }
5757 
5758  /* apply the fixing */
5759  switch( scip->set->stage )
5760  {
5761  case SCIP_STAGE_PROBLEM:
5762  assert(!SCIPvarIsTransformed(var));
5763  if( fixedval == TRUE )
5764  {
5765  SCIP_CALL( SCIPchgVarLb(scip, var, 1.0) );
5766  }
5767  else
5768  {
5769  SCIP_CALL( SCIPchgVarUb(scip, var, 0.0) );
5770  }
5771  break;
5772 
5773  case SCIP_STAGE_PRESOLVING:
5774  if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
5775  {
5776  SCIP_Bool fixed;
5777 
5778  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5779  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
5780  scip->cliquetable, (SCIP_Real)fixedval, infeasible, &fixed) );
5781  break;
5782  }
5783  /*lint -fallthrough*/
5784  case SCIP_STAGE_SOLVING:
5785  if( fixedval == TRUE )
5786  {
5788  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5789  scip->cliquetable, var, 1.0, SCIP_BOUNDTYPE_LOWER, infercons, NULL, inferinfo, FALSE) );
5790  }
5791  else
5792  {
5794  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5795  scip->cliquetable, var, 0.0, SCIP_BOUNDTYPE_UPPER, infercons, NULL, inferinfo, FALSE) );
5796  }
5797  break;
5798 
5799  default:
5800  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5801  return SCIP_INVALIDCALL;
5802  } /*lint !e788*/
5803 
5804  if( tightened != NULL )
5805  *tightened = TRUE;
5806 
5807  return SCIP_OKAY;
5808 }
5809 
5810 /** fixes variable in preprocessing or in the current node, if the new bound is tighter (w.r.t. bound strengthening
5811  * epsilon) than the current bound; if possible, adjusts bound to integral value; the given inference constraint is
5812  * stored, such that the conflict analysis is able to find out the reason for the deduction of the bound change
5813  *
5814  * @note In presolving stage when not in probing mode the variable will be fixed directly, otherwise this method
5815  * changes first the lowerbound by calling SCIPinferVarLbProp and second the upperbound by calling
5816  * SCIPinferVarUbProp
5817  *
5818  * @note If SCIP is in presolving stage, it can happen that the internal variable array (which get be accessed via
5819  * SCIPgetVars()) gets resorted.
5820  *
5821  * @note During presolving, an integer variable which bound changes to {0,1} is upgraded to a binary variable.
5822  */
5824  SCIP* scip, /**< SCIP data structure */
5825  SCIP_VAR* var, /**< variable to change the bound for */
5826  SCIP_Real fixedval, /**< new value for fixation */
5827  SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
5828  int inferinfo, /**< user information for inference to help resolving the conflict */
5829  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5830  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5831  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5832  )
5833 {
5834  assert(scip != NULL);
5835  assert(var != NULL);
5836  assert(infeasible != NULL);
5837 
5838  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarFixProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5839 
5840  if( tightened != NULL )
5841  *tightened = FALSE;
5842 
5843  /* in presolving case we take the shortcut to directly fix the variables */
5844  if( SCIPgetStage(scip) == SCIP_STAGE_PRESOLVING && SCIPtreeGetCurrentDepth(scip->tree) == 0 )
5845  {
5846  SCIP_Bool fixed;
5847 
5848  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5849  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
5850  scip->cliquetable, fixedval, infeasible, &fixed) );
5851 
5852  if( tightened != NULL )
5853  *tightened = fixed;
5854  }
5855  /* otherwise we use the lb and ub methods */
5856  else
5857  {
5858  SCIP_Bool lbtightened;
5859 
5860  SCIP_CALL( SCIPinferVarLbProp(scip, var, fixedval, inferprop, inferinfo, force, infeasible, &lbtightened) );
5861 
5862  if( ! (*infeasible) )
5863  {
5864  SCIP_CALL( SCIPinferVarUbProp(scip, var, fixedval, inferprop, inferinfo, force, infeasible, tightened) );
5865 
5866  if( tightened != NULL )
5867  *tightened |= lbtightened;
5868  }
5869  }
5870 
5871  return SCIP_OKAY;
5872 }
5873 
5874 /** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
5875  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5876  * the given inference propagator is stored, such that the conflict analysis is able to find out the reason
5877  * for the deduction of the bound change
5878  *
5879  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5880  * SCIPgetVars()) gets resorted.
5881  *
5882  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5883  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5884  *
5885  * @pre This method can be called if @p scip is in one of the following stages:
5886  * - \ref SCIP_STAGE_PROBLEM
5887  * - \ref SCIP_STAGE_PRESOLVING
5888  * - \ref SCIP_STAGE_SOLVING
5889  *
5890  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5891  */
5893  SCIP* scip, /**< SCIP data structure */
5894  SCIP_VAR* var, /**< variable to change the bound for */
5895  SCIP_Real newbound, /**< new value for bound */
5896  SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
5897  int inferinfo, /**< user information for inference to help resolving the conflict */
5898  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5899  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5900  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5901  )
5902 {
5903  SCIP_Real lb;
5904  SCIP_Real ub;
5905 
5906  assert(infeasible != NULL);
5907 
5908  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarLbProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5909 
5910  *infeasible = FALSE;
5911  if( tightened != NULL )
5912  *tightened = FALSE;
5913 
5914  SCIPvarAdjustLb(var, scip->set, &newbound);
5915 
5916  /* ignore tightenings of lower bounds to +infinity during solving process */
5917  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5918  {
5919 #ifndef NDEBUG
5920  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
5921  SCIPvarGetLbLocal(var));
5922 #endif
5923  return SCIP_OKAY;
5924  }
5925 
5926  /* get current bounds */
5927  lb = SCIPvarGetLbLocal(var);
5928  ub = SCIPvarGetUbLocal(var);
5929  assert(SCIPsetIsLE(scip->set, lb, ub));
5930 
5931  if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
5932  {
5933  *infeasible = TRUE;
5934  return SCIP_OKAY;
5935  }
5936  newbound = MIN(newbound, ub);
5937 
5938  if( (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub))
5939  || SCIPsetIsLE(scip->set, newbound, lb) )
5940  return SCIP_OKAY;
5941 
5942  switch( scip->set->stage )
5943  {
5944  case SCIP_STAGE_PROBLEM:
5945  assert(!SCIPvarIsTransformed(var));
5946  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5947  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5948  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5949  scip->branchcand, scip->eventqueue, newbound) );
5950  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
5951  break;
5952 
5953  case SCIP_STAGE_PRESOLVING:
5954  if( !SCIPinProbing(scip) )
5955  {
5956  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5957  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5958 
5959  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5960  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5962 
5964  {
5965  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5966  assert(!(*infeasible));
5967  }
5968  break;
5969  }
5970  /*lint -fallthrough*/
5971  case SCIP_STAGE_SOLVING:
5973  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5974  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, NULL, inferprop, inferinfo, FALSE) );
5975  break;
5976 
5977  default:
5978  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5979  return SCIP_INVALIDCALL;
5980  } /*lint !e788*/
5981 
5982  /* check whether the lower bound improved */
5983  if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
5984  *tightened = TRUE;
5985 
5986  return SCIP_OKAY;
5987 }
5988 
5989 /** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
5990  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5991  * the given inference propagator is stored, such that the conflict analysis is able to find out the reason
5992  * for the deduction of the bound change
5993  *
5994  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5995  * SCIPgetVars()) gets resorted.
5996  *
5997  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5998  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5999  *
6000  * @pre This method can be called if @p scip is in one of the following stages:
6001  * - \ref SCIP_STAGE_PROBLEM
6002  * - \ref SCIP_STAGE_PRESOLVING
6003  * - \ref SCIP_STAGE_SOLVING
6004  *
6005  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6006  */
6008  SCIP* scip, /**< SCIP data structure */
6009  SCIP_VAR* var, /**< variable to change the bound for */
6010  SCIP_Real newbound, /**< new value for bound */
6011  SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
6012  int inferinfo, /**< user information for inference to help resolving the conflict */
6013  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6014  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
6015  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6016  )
6017 {
6018  SCIP_Real lb;
6019  SCIP_Real ub;
6020 
6021  assert(infeasible != NULL);
6022 
6023  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarUbProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6024 
6025  *infeasible = FALSE;
6026  if( tightened != NULL )
6027  *tightened = FALSE;
6028 
6029  SCIPvarAdjustUb(var, scip->set, &newbound);
6030 
6031  /* ignore tightenings of upper bounds to -infinity during solving process */
6032  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6033  {
6034 #ifndef NDEBUG
6035  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
6036  SCIPvarGetUbLocal(var));
6037 #endif
6038  return SCIP_OKAY;
6039  }
6040 
6041  /* get current bounds */
6042  lb = SCIPvarGetLbLocal(var);
6043  ub = SCIPvarGetUbLocal(var);
6044  assert(SCIPsetIsLE(scip->set, lb, ub));
6045 
6046  if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
6047  {
6048  *infeasible = TRUE;
6049  return SCIP_OKAY;
6050  }
6051  newbound = MAX(newbound, lb);
6052 
6053  if( (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub))
6054  || SCIPsetIsGE(scip->set, newbound, ub) )
6055  return SCIP_OKAY;
6056 
6057  switch( scip->set->stage )
6058  {
6059  case SCIP_STAGE_PROBLEM:
6060  assert(!SCIPvarIsTransformed(var));
6061  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6062  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6063  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6064  scip->branchcand, scip->eventqueue, newbound) );
6065  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
6066  break;
6067 
6068  case SCIP_STAGE_PRESOLVING:
6069  if( !SCIPinProbing(scip) )
6070  {
6071  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6072  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6073 
6074  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6075  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6077 
6079  {
6080  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6081  assert(!(*infeasible));
6082  }
6083  break;
6084  }
6085  /*lint -fallthrough*/
6086  case SCIP_STAGE_SOLVING:
6088  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
6089  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, NULL, inferprop, inferinfo, FALSE) );
6090  break;
6091 
6092  default:
6093  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6094  return SCIP_INVALIDCALL;
6095  } /*lint !e788*/
6096 
6097  /* check whether the upper bound improved */
6098  if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
6099  *tightened = TRUE;
6100 
6101  return SCIP_OKAY;
6102 }
6103 
6104 /** depending on SCIP's stage, fixes binary variable in the problem, in preprocessing, or in current node;
6105  * the given inference propagator is stored, such that the conflict analysis is able to find out the reason for the
6106  * deduction of the fixing
6107  *
6108  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6109  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6110  *
6111  * @pre This method can be called if @p scip is in one of the following stages:
6112  * - \ref SCIP_STAGE_PROBLEM
6113  * - \ref SCIP_STAGE_PRESOLVING
6114  * - \ref SCIP_STAGE_PRESOLVED
6115  * - \ref SCIP_STAGE_SOLVING
6116  */
6118  SCIP* scip, /**< SCIP data structure */
6119  SCIP_VAR* var, /**< binary variable to fix */
6120  SCIP_Bool fixedval, /**< value to fix binary variable to */
6121  SCIP_PROP* inferprop, /**< propagator that deduced the fixing */
6122  int inferinfo, /**< user information for inference to help resolving the conflict */
6123  SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
6124  SCIP_Bool* tightened /**< pointer to store whether the fixing tightened the local bounds, or NULL */
6125  )
6126 {
6127  SCIP_Real lb;
6128  SCIP_Real ub;
6129 
6130  assert(SCIPvarIsBinary(var));
6131  assert(fixedval == TRUE || fixedval == FALSE);
6132  assert(infeasible != NULL);
6133 
6134  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferBinvarProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6135 
6136  *infeasible = FALSE;
6137  if( tightened != NULL )
6138  *tightened = FALSE;
6139 
6140  /* get current bounds */
6141  lb = SCIPvarGetLbLocal(var);
6142  ub = SCIPvarGetUbLocal(var);
6143  assert(SCIPsetIsEQ(scip->set, lb, 0.0) || SCIPsetIsEQ(scip->set, lb, 1.0));
6144  assert(SCIPsetIsEQ(scip->set, ub, 0.0) || SCIPsetIsEQ(scip->set, ub, 1.0));
6145  assert(SCIPsetIsLE(scip->set, lb, ub));
6146 
6147  /* check, if variable is already fixed */
6148  if( (lb > 0.5) || (ub < 0.5) )
6149  {
6150  *infeasible = (fixedval == (lb < 0.5));
6151 
6152  return SCIP_OKAY;
6153  }
6154 
6155  /* apply the fixing */
6156  switch( scip->set->stage )
6157  {
6158  case SCIP_STAGE_PROBLEM:
6159  assert(!SCIPvarIsTransformed(var));
6160  if( fixedval == TRUE )
6161  {
6162  SCIP_CALL( SCIPchgVarLb(scip, var, 1.0) );
6163  }
6164  else
6165  {
6166  SCIP_CALL( SCIPchgVarUb(scip, var, 0.0) );
6167  }
6168  break;
6169 
6170  case SCIP_STAGE_PRESOLVING:
6171  if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
6172  {
6173  SCIP_Bool fixed;
6174 
6175  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6176  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
6177  scip->cliquetable, (SCIP_Real)fixedval, infeasible, &fixed) );
6178  break;
6179  }
6180  /*lint -fallthrough*/
6181  case SCIP_STAGE_SOLVING:
6182  if( fixedval == TRUE )
6183  {
6185  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, 1.0,
6186  SCIP_BOUNDTYPE_LOWER, NULL, inferprop, inferinfo, FALSE) );
6187  }
6188  else
6189  {
6191  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, 0.0,
6192  SCIP_BOUNDTYPE_UPPER, NULL, inferprop, inferinfo, FALSE) );
6193  }
6194  break;
6195 
6196  default:
6197  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6198  return SCIP_INVALIDCALL;
6199  } /*lint !e788*/
6200 
6201  if( tightened != NULL )
6202  *tightened = TRUE;
6203 
6204  return SCIP_OKAY;
6205 }
6206 
6207 /** changes global lower bound of variable in preprocessing or in the current node, if the new bound is tighter
6208  * (w.r.t. bound strengthening epsilon) than the current global bound; if possible, adjusts bound to integral value;
6209  * also tightens the local bound, if the global bound is better than the local bound
6210  *
6211  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6212  * SCIPgetVars()) gets resorted.
6213  *
6214  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6215  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6216  *
6217  * @pre This method can be called if @p scip is in one of the following stages:
6218  * - \ref SCIP_STAGE_PROBLEM
6219  * - \ref SCIP_STAGE_TRANSFORMING
6220  * - \ref SCIP_STAGE_PRESOLVING
6221  * - \ref SCIP_STAGE_SOLVING
6222  *
6223  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6224  */
6226  SCIP* scip, /**< SCIP data structure */
6227  SCIP_VAR* var, /**< variable to change the bound for */
6228  SCIP_Real newbound, /**< new value for bound */
6229  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6230  SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
6231  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6232  )
6233 {
6234  SCIP_Real lb;
6235  SCIP_Real ub;
6236 
6237  assert(infeasible != NULL);
6238 
6239  SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarLbGlobal", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6240 
6241  *infeasible = FALSE;
6242  if( tightened != NULL )
6243  *tightened = FALSE;
6244 
6245  SCIPvarAdjustLb(var, scip->set, &newbound);
6246 
6247  /* ignore tightenings of lower bounds to +infinity during solving process */
6248  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6249  {
6250 #ifndef NDEBUG
6251  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
6252  SCIPvarGetLbLocal(var));
6253 #endif
6254  return SCIP_OKAY;
6255  }
6256 
6257  /* get current bounds */
6258  lb = SCIPvarGetLbGlobal(var);
6259  ub = SCIPvarGetUbGlobal(var);
6260  assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPsetIsLE(scip->set, lb, ub));
6261 
6262  if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
6263  {
6264  *infeasible = TRUE;
6265  return SCIP_OKAY;
6266  }
6267  newbound = MIN(newbound, ub);
6268 
6269  /* bound changes of less than epsilon are ignored by SCIPvarChgLb or raise an assert in SCIPnodeAddBoundinfer,
6270  * so don't apply them even if force is set
6271  */
6272  if( SCIPsetIsEQ(scip->set, lb, newbound) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
6273  return SCIP_OKAY;
6274 
6275  switch( scip->set->stage )
6276  {
6277  case SCIP_STAGE_PROBLEM:
6278  assert(!SCIPvarIsTransformed(var));
6279  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6280  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6281  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6282  scip->branchcand, scip->eventqueue, newbound) );
6283  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
6284  break;
6285 
6287  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6288  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6289  break;
6290 
6291  case SCIP_STAGE_PRESOLVING:
6292  if( !SCIPinProbing(scip) )
6293  {
6294  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6295  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6296 
6297  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6298  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6300 
6302  {
6303  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6304  assert(!(*infeasible));
6305  }
6306  break;
6307  }
6308  /*lint -fallthrough*/
6309  case SCIP_STAGE_SOLVING:
6310  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6311  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6313  break;
6314 
6315  default:
6316  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6317  return SCIP_INVALIDCALL;
6318  } /*lint !e788*/
6319 
6320  /* coverity: unreachable code */
6321  if( tightened != NULL && lb < SCIPcomputeVarLbGlobal(scip, var) )
6322  *tightened = TRUE;
6323 
6324  return SCIP_OKAY;
6325 }
6326 
6327 /** changes global upper bound of variable in preprocessing or in the current node, if the new bound is tighter
6328  * (w.r.t. bound strengthening epsilon) than the current global bound; if possible, adjusts bound to integral value;
6329  * also tightens the local bound, if the global bound is better than the local bound
6330  *
6331  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6332  * SCIPgetVars()) gets resorted.
6333  *
6334  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6335  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6336  *
6337  * @pre This method can be called if @p scip is in one of the following stages:
6338  * - \ref SCIP_STAGE_PROBLEM
6339  * - \ref SCIP_STAGE_TRANSFORMING
6340  * - \ref SCIP_STAGE_PRESOLVING
6341  * - \ref SCIP_STAGE_SOLVING
6342  *
6343  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6344  */
6346  SCIP* scip, /**< SCIP data structure */
6347  SCIP_VAR* var, /**< variable to change the bound for */
6348  SCIP_Real newbound, /**< new value for bound */
6349  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6350  SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
6351  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6352  )
6353 {
6354  SCIP_Real lb;
6355  SCIP_Real ub;
6356 
6357  assert(infeasible != NULL);
6358 
6359  SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarUbGlobal", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6360 
6361  *infeasible = FALSE;
6362  if( tightened != NULL )
6363  *tightened = FALSE;
6364 
6365  SCIPvarAdjustUb(var, scip->set, &newbound);
6366 
6367  /* ignore tightenings of upper bounds to -infinity during solving process */
6368  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6369  {
6370 #ifndef NDEBUG
6371  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
6372  SCIPvarGetUbLocal(var));
6373 #endif
6374  return SCIP_OKAY;
6375  }
6376 
6377  /* get current bounds */
6378  lb = SCIPvarGetLbGlobal(var);
6379  ub = SCIPvarGetUbGlobal(var);
6380  assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPsetIsLE(scip->set, lb, ub));
6381 
6382  if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
6383  {
6384  *infeasible = TRUE;
6385  return SCIP_OKAY;
6386  }
6387  newbound = MAX(newbound, lb);
6388 
6389  /* bound changes of less than epsilon are ignored by SCIPvarChgUb or raise an assert in SCIPnodeAddBoundinfer,
6390  * so don't apply them even if force is set
6391  */
6392  if( SCIPsetIsEQ(scip->set, ub, newbound) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
6393  return SCIP_OKAY;
6394 
6395  switch( scip->set->stage )
6396  {
6397  case SCIP_STAGE_PROBLEM:
6398  assert(!SCIPvarIsTransformed(var));
6399  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6400  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6401  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6402  scip->branchcand, scip->eventqueue, newbound) );
6403  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
6404  break;
6405 
6407  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6408  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6409  break;
6410 
6411  case SCIP_STAGE_PRESOLVING:
6412  if( !SCIPinProbing(scip) )
6413  {
6414  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6415  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6416 
6417  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6418  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6420 
6422  {
6423  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6424  assert(!(*infeasible));
6425  }
6426  break;
6427  }
6428  /*lint -fallthrough*/
6429  case SCIP_STAGE_SOLVING:
6430  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6431  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6433  break;
6434 
6435  default:
6436  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6437  return SCIP_INVALIDCALL;
6438  } /*lint !e788*/
6439 
6440  /* coverity: unreachable code */
6441  if( tightened != NULL && ub > SCIPcomputeVarUbGlobal(scip, var) )
6442  *tightened = TRUE;
6443 
6444  return SCIP_OKAY;
6445 }
6446 
6447 /* some simple variable functions implemented as defines */
6448 #undef SCIPcomputeVarLbGlobal
6449 #undef SCIPcomputeVarUbGlobal
6450 #undef SCIPcomputeVarLbLocal
6451 #undef SCIPcomputeVarUbLocal
6452 
6453 /** for a multi-aggregated variable, returns the global lower bound computed by adding the global bounds from all aggregation variables
6454  *
6455  * 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
6456  * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetLbGlobal.
6457  *
6458  * @return the global lower bound computed by adding the global bounds from all aggregation variables
6459  */
6461  SCIP* scip, /**< SCIP data structure */
6462  SCIP_VAR* var /**< variable to compute the bound for */
6463  )
6464 {
6465  assert(scip != NULL);
6466  assert(var != NULL);
6467 
6469  return SCIPvarGetMultaggrLbGlobal(var, scip->set);
6470  else
6471  return SCIPvarGetLbGlobal(var);
6472 }
6473 
6474 /** for a multi-aggregated variable, returns the global upper bound computed by adding the global bounds from all aggregation variables
6475  *
6476  * 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
6477  * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetUbGlobal
6478  *
6479  * @return the global upper bound computed by adding the global bounds from all aggregation variables
6480  */
6482  SCIP* scip, /**< SCIP data structure */
6483  SCIP_VAR* var /**< variable to compute the bound for */
6484  )
6485 {
6486  assert(scip != NULL);
6487  assert(var != NULL);
6488 
6490  return SCIPvarGetMultaggrUbGlobal(var, scip->set);
6491  else
6492  return SCIPvarGetUbGlobal(var);
6493 }
6494 
6495 /** for a multi-aggregated variable, returns the local lower bound computed by adding the local bounds from all aggregation variables
6496  *
6497  * 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
6498  * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetLbLocal.
6499  *
6500  * @return the local lower bound computed by adding the global bounds from all aggregation variables
6501  */
6503  SCIP* scip, /**< SCIP data structure */
6504  SCIP_VAR* var /**< variable to compute the bound for */
6505  )
6506 {
6507  assert(scip != NULL);
6508  assert(var != NULL);
6509 
6511  return SCIPvarGetMultaggrLbLocal(var, scip->set);
6512  else
6513  return SCIPvarGetLbLocal(var);
6514 }
6515 
6516 /** for a multi-aggregated variable, returns the local upper bound computed by adding the local bounds from all aggregation variables
6517  *
6518  * 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
6519  * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetUbLocal.
6520  *
6521  * @return the local upper bound computed by adding the global bounds from all aggregation variables
6522  */
6524  SCIP* scip, /**< SCIP data structure */
6525  SCIP_VAR* var /**< variable to compute the bound for */
6526  )
6527 {
6528  assert(scip != NULL);
6529  assert(var != NULL);
6530 
6532  return SCIPvarGetMultaggrUbLocal(var, scip->set);
6533  else
6534  return SCIPvarGetUbLocal(var);
6535 }
6536 
6537 /** for a multi-aggregated variable, gives the global lower bound computed by adding the global bounds from all
6538  * aggregation variables, this global bound may be tighter than the one given by SCIPvarGetLbGlobal, since the latter is
6539  * not updated if bounds of aggregation variables are changing
6540  *
6541  * calling this function for a non-multi-aggregated variable is not allowed
6542  */
6544  SCIP* scip, /**< SCIP data structure */
6545  SCIP_VAR* var /**< variable to compute the bound for */
6546  )
6547 {
6548  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
6549  return SCIPvarGetMultaggrLbGlobal(var, scip->set);
6550 }
6551 
6552 /** for a multi-aggregated variable, gives the global upper bound computed by adding the global bounds from all
6553  * aggregation variables, this upper bound may be tighter than the one given by SCIPvarGetUbGlobal, since the latter is
6554  * not updated if bounds of aggregation variables are changing
6555  *
6556  * calling this function for a non-multi-aggregated variable is not allowed
6557  */
6559  SCIP* scip, /**< SCIP data structure */
6560  SCIP_VAR* var /**< variable to compute the bound for */
6561  )
6562 {
6563  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
6564  return SCIPvarGetMultaggrUbGlobal(var, scip->set);
6565 }
6566 
6567 /** for a multi-aggregated variable, gives the local lower bound computed by adding the local bounds from all
6568  * aggregation variables, this lower bound may be tighter than the one given by SCIPvarGetLbLocal, since the latter is
6569  * not updated if bounds of aggregation variables are changing
6570  *
6571  * calling this function for a non-multi-aggregated variable is not allowed
6572  */
6574  SCIP* scip, /**< SCIP data structure */
6575  SCIP_VAR* var /**< variable to compute the bound for */
6576  )
6577 {
6578  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
6579  return SCIPvarGetMultaggrLbLocal(var, scip->set);
6580 }
6581 
6582 /** for a multi-aggregated variable, gives the local upper bound computed by adding the local bounds from all
6583  * aggregation variables, this upper bound may be tighter than the one given by SCIPvarGetUbLocal, since the latter is
6584  * not updated if bounds of aggregation variables are changing
6585  *
6586  * calling this function for a non-multi-aggregated variable is not allowed
6587  */
6589  SCIP* scip, /**< SCIP data structure */
6590  SCIP_VAR* var /**< variable to compute the bound for */
6591  )
6592 {
6593  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
6594  return SCIPvarGetMultaggrUbLocal(var, scip->set);
6595 }
6596 
6597 /** returns solution value and index of variable lower bound that is closest to the variable's value in the given primal
6598  * solution or current LP solution if no primal solution is given; returns an index of -1 if no variable lower bound is
6599  * available
6600  *
6601  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6602  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6603  *
6604  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
6605  */
6607  SCIP* scip, /**< SCIP data structure */
6608  SCIP_VAR* var, /**< active problem variable */
6609  SCIP_SOL* sol, /**< primal solution, or NULL for LP solution */
6610  SCIP_Real* closestvlb, /**< pointer to store the value of the closest variable lower bound */
6611  int* closestvlbidx /**< pointer to store the index of the closest variable lower bound */
6612  )
6613 {
6614  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarClosestVlb", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6615 
6616  SCIPvarGetClosestVlb(var, sol, scip->set, scip->stat, closestvlb, closestvlbidx);
6617 
6618  return SCIP_OKAY;
6619 }
6620 
6621 /** returns solution value and index of variable upper bound that is closest to the variable's value in the given primal solution;
6622  * or current LP solution if no primal solution is given; returns an index of -1 if no variable upper bound is available
6623  *
6624  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6625  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6626  *
6627  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
6628  */
6630  SCIP* scip, /**< SCIP data structure */
6631  SCIP_VAR* var, /**< active problem variable */
6632  SCIP_SOL* sol, /**< primal solution, or NULL for LP solution */
6633  SCIP_Real* closestvub, /**< pointer to store the value of the closest variable lower bound */
6634  int* closestvubidx /**< pointer to store the index of the closest variable lower bound */
6635  )
6636 {
6637  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarClosestVub", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6638 
6639  SCIPvarGetClosestVub(var, sol, scip->set, scip->stat, closestvub, closestvubidx);
6640 
6641  return SCIP_OKAY;
6642 }
6643 
6644 /** informs variable x about a globally valid variable lower bound x >= b*z + d with integer variable z;
6645  * if z is binary, the corresponding valid implication for z is also added;
6646  * if z is non-continuous and 1/b not too small, the corresponding valid upper/lower bound
6647  * z <= (x-d)/b or z >= (x-d)/b (depending on the sign of of b) is added, too;
6648  * improves the global bounds of the variable and the vlb variable if possible
6649  *
6650  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6651  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6652  *
6653  * @pre This method can be called if @p scip is in one of the following stages:
6654  * - \ref SCIP_STAGE_PRESOLVING
6655  * - \ref SCIP_STAGE_PRESOLVED
6656  * - \ref SCIP_STAGE_SOLVING
6657  */
6659  SCIP* scip, /**< SCIP data structure */
6660  SCIP_VAR* var, /**< problem variable */
6661  SCIP_VAR* vlbvar, /**< variable z in x >= b*z + d */
6662  SCIP_Real vlbcoef, /**< coefficient b in x >= b*z + d */
6663  SCIP_Real vlbconstant, /**< constant d in x >= b*z + d */
6664  SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6665  int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6666  )
6667 {
6668  int nlocalbdchgs;
6669 
6670  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarVlb", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6671 
6672  SCIP_CALL( SCIPvarAddVlb(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->tree,
6673  scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, vlbvar, vlbcoef, vlbconstant,
6674  TRUE, infeasible, &nlocalbdchgs) );
6675 
6676  *nbdchgs = nlocalbdchgs;
6677 
6678  /* 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
6679  * detected infeasibility
6680  */
6681  if( !(*infeasible) && SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisZero(scip, 1.0/vlbcoef) )
6682  {
6683  if( vlbcoef > 0.0 )
6684  {
6685  /* if b > 0, we have a variable upper bound: x >= b*z + d => z <= (x-d)/b */
6686  SCIP_CALL( SCIPvarAddVub(vlbvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6687  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vlbcoef,
6688  -vlbconstant/vlbcoef, TRUE, infeasible, &nlocalbdchgs) );
6689  }
6690  else
6691  {
6692  /* if b < 0, we have a variable lower bound: x >= b*z + d => z >= (x-d)/b */
6693  SCIP_CALL( SCIPvarAddVlb(vlbvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6694  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vlbcoef,
6695  -vlbconstant/vlbcoef, TRUE, infeasible, &nlocalbdchgs) );
6696  }
6697  *nbdchgs += nlocalbdchgs;
6698  }
6699 
6700  return SCIP_OKAY;
6701 }
6702 
6703 /** informs variable x about a globally valid variable upper bound x <= b*z + d with integer variable z;
6704  * if z is binary, the corresponding valid implication for z is also added;
6705  * if z is non-continuous and 1/b not too small, the corresponding valid lower/upper bound
6706  * z >= (x-d)/b or z <= (x-d)/b (depending on the sign of of b) is added, too;
6707  * improves the global bounds of the variable and the vlb variable if possible
6708  *
6709  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6710  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6711  *
6712  * @pre This method can be called if @p scip is in one of the following stages:
6713  * - \ref SCIP_STAGE_PRESOLVING
6714  * - \ref SCIP_STAGE_PRESOLVED
6715  * - \ref SCIP_STAGE_SOLVING
6716  */
6718  SCIP* scip, /**< SCIP data structure */
6719  SCIP_VAR* var, /**< problem variable */
6720  SCIP_VAR* vubvar, /**< variable z in x <= b*z + d */
6721  SCIP_Real vubcoef, /**< coefficient b in x <= b*z + d */
6722  SCIP_Real vubconstant, /**< constant d in x <= b*z + d */
6723  SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6724  int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6725  )
6726 {
6727  int nlocalbdchgs;
6728 
6729  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarVub", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6730 
6731  SCIP_CALL( SCIPvarAddVub(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->tree,
6732  scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, vubvar, vubcoef, vubconstant, TRUE,
6733  infeasible, &nlocalbdchgs) );
6734 
6735  *nbdchgs = nlocalbdchgs;
6736 
6737  /* 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
6738  * detected infeasibility
6739  */
6740  if( !(*infeasible) && SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisZero(scip, 1.0/vubcoef) )
6741  {
6742  if( vubcoef > 0.0 )
6743  {
6744  /* if b < 0, we have a variable lower bound: x >= b*z + d => z >= (x-d)/b */
6745  SCIP_CALL( SCIPvarAddVlb(vubvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6746  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vubcoef,
6747  -vubconstant/vubcoef, TRUE, infeasible, &nlocalbdchgs) );
6748  }
6749  else
6750  {
6751  /* if b > 0, we have a variable upper bound: x >= b*z + d => z <= (x-d)/b */
6752  SCIP_CALL( SCIPvarAddVub(vubvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6753  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vubcoef,
6754  -vubconstant/vubcoef, TRUE, infeasible, &nlocalbdchgs) );
6755  }
6756  *nbdchgs += nlocalbdchgs;
6757  }
6758 
6759  return SCIP_OKAY;
6760 }
6761 
6762 /** informs binary variable x about a globally valid implication: x == 0 or x == 1 ==> y <= b or y >= b;
6763  * also adds the corresponding implication or variable bound to the implied variable;
6764  * if the implication is conflicting, the variable is fixed to the opposite value;
6765  * if the variable is already fixed to the given value, the implication is performed immediately;
6766  * if the implication is redundant with respect to the variables' global bounds, it is ignored
6767  *
6768  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6769  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6770  *
6771  * @pre This method can be called if @p scip is in one of the following stages:
6772  * - \ref SCIP_STAGE_TRANSFORMED
6773  * - \ref SCIP_STAGE_PRESOLVING
6774  * - \ref SCIP_STAGE_PRESOLVED
6775  * - \ref SCIP_STAGE_SOLVING
6776  */
6778  SCIP* scip, /**< SCIP data structure */
6779  SCIP_VAR* var, /**< problem variable */
6780  SCIP_Bool varfixing, /**< FALSE if y should be added in implications for x == 0, TRUE for x == 1 */
6781  SCIP_VAR* implvar, /**< variable y in implication y <= b or y >= b */
6782  SCIP_BOUNDTYPE impltype, /**< type of implication y <= b (SCIP_BOUNDTYPE_UPPER)
6783  * or y >= b (SCIP_BOUNDTYPE_LOWER) */
6784  SCIP_Real implbound, /**< bound b in implication y <= b or y >= b */
6785  SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6786  int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6787  )
6788 {
6789  SCIP_VAR* implprobvar;
6790 
6791  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarImplication", FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6792 
6793  assert(infeasible != NULL);
6794  *infeasible = FALSE;
6795 
6796  if ( nbdchgs != NULL )
6797  *nbdchgs = 0;
6798 
6799  if( !SCIPvarIsBinary(var) )
6800  {
6801  SCIPerrorMessage("can't add implication for nonbinary variable\n");
6802  return SCIP_INVALIDDATA;
6803  }
6804 
6805  implprobvar = SCIPvarGetProbvar(implvar);
6806  /* transform implication containing two binary variables to a clique; the condition ensures that the active representative
6807  * of implvar is actually binary
6808  */
6809  if( SCIPvarIsBinary(implvar) && (SCIPvarIsActive(implvar) || (implprobvar != NULL && SCIPvarIsBinary(implprobvar))) )
6810  {
6811  assert(SCIPisFeasEQ(scip, implbound, 1.0) || SCIPisFeasZero(scip, implbound));
6812  assert((impltype == SCIP_BOUNDTYPE_UPPER) == SCIPisFeasZero(scip, implbound));
6813 
6814  /* only add clique if implication is not redundant with respect to global bounds of the implication variable */
6815  if( (impltype == SCIP_BOUNDTYPE_LOWER && SCIPvarGetLbGlobal(implvar) < 0.5) ||
6816  (impltype == SCIP_BOUNDTYPE_UPPER && SCIPvarGetUbGlobal(implvar) > 0.5) )
6817  {
6818  SCIP_VAR* vars[2];
6819  SCIP_Bool vals[2];
6820 
6821  vars[0] = var;
6822  vars[1] = implvar;
6823  vals[0] = varfixing;
6824  vals[1] = (impltype == SCIP_BOUNDTYPE_UPPER);
6825 
6826  SCIP_CALL( SCIPaddClique(scip, vars, vals, 2, FALSE, infeasible, nbdchgs) );
6827  }
6828 
6829  return SCIP_OKAY;
6830  }
6831 
6832  /* the implication graph can only handle 'real' binary (SCIP_VARTYPE_BINARY) variables, therefore we transform the
6833  * implication in variable bounds, (lowerbound of y will be abbreviated by lby, upperbound equivlaent) the follwing
6834  * four cases are:
6835  *
6836  * 1. (x >= 1 => y >= b) => y >= (b - lby) * x + lby
6837  * 2. (x >= 1 => y <= b) => y <= (b - uby) * x + uby
6838  * 3. (x <= 0 => y >= b) => y >= (lby - b) * x + b
6839  * 4. (x <= 0 => y <= b) => y <= (uby - b) * x + b
6840  */
6841  if( SCIPvarGetType(var) != SCIP_VARTYPE_BINARY )
6842  {
6843  SCIP_Real lby;
6844  SCIP_Real uby;
6845 
6846  lby = SCIPvarGetLbGlobal(implvar);
6847  uby = SCIPvarGetUbGlobal(implvar);
6848 
6849  if( varfixing == TRUE )
6850  {
6851  if( impltype == SCIP_BOUNDTYPE_LOWER )
6852  {
6853  /* we return if the lower bound is infinity */
6854  if( SCIPisInfinity(scip, -lby) )
6855  return SCIP_OKAY;
6856 
6857  SCIP_CALL( SCIPvarAddVlb(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6858  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6859  implbound - lby, lby, TRUE, infeasible, nbdchgs) );
6860  }
6861  else
6862  {
6863  /* we return if the upper bound is infinity */
6864  if( SCIPisInfinity(scip, uby) )
6865  return SCIP_OKAY;
6866 
6867  SCIP_CALL( SCIPvarAddVub(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6868  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6869  implbound - uby, uby, TRUE, infeasible, nbdchgs) );
6870  }
6871  }
6872  else
6873  {
6874  if( impltype == SCIP_BOUNDTYPE_LOWER )
6875  {
6876  /* we return if the lower bound is infinity */
6877  if( SCIPisInfinity(scip, -lby) )
6878  return SCIP_OKAY;
6879 
6880  SCIP_CALL( SCIPvarAddVlb(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6881  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6882  lby - implbound, implbound, TRUE, infeasible, nbdchgs) );
6883  }
6884  else
6885  {
6886  /* we return if the upper bound is infinity */
6887  if( SCIPisInfinity(scip, uby) )
6888  return SCIP_OKAY;
6889 
6890  SCIP_CALL( SCIPvarAddVub(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6891  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6892  uby - implbound, implbound, TRUE, infeasible, nbdchgs) );
6893  }
6894  }
6895  }
6896  else
6897  {
6898  SCIP_CALL( SCIPvarAddImplic(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6899  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, varfixing, implvar, impltype,
6900  implbound, TRUE, infeasible, nbdchgs) );
6901  }
6902 
6903  return SCIP_OKAY;
6904 }
6905 
6906 /** adds a clique information to SCIP, stating that at most one of the given binary variables can be set to 1;
6907  * if a variable appears twice in the same clique, the corresponding implications are performed
6908  *
6909  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6910  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6911  *
6912  * @pre This method can be called if @p scip is in one of the following stages:
6913  * - \ref SCIP_STAGE_TRANSFORMED
6914  * - \ref SCIP_STAGE_PRESOLVING
6915  * - \ref SCIP_STAGE_PRESOLVED
6916  * - \ref SCIP_STAGE_SOLVING
6917  */
6919  SCIP* scip, /**< SCIP data structure */
6920  SCIP_VAR** vars, /**< binary variables in the clique from which at most one can be set to 1 */
6921  SCIP_Bool* values, /**< values of the variables in the clique; NULL to use TRUE for all vars */
6922  int nvars, /**< number of variables in the clique */
6923  SCIP_Bool isequation, /**< is the clique an equation or an inequality? */
6924  SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6925  int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6926  )
6927 {
6928  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddClique", FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6929 
6930  *infeasible = FALSE;
6931  if( nbdchgs != NULL )
6932  *nbdchgs = 0;
6933 
6934  if( nvars > 1 )
6935  {
6936  /* add the clique to the clique table */
6937  SCIP_CALL( SCIPcliquetableAdd(scip->cliquetable, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6938  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, vars, values, nvars, isequation,
6939  infeasible, nbdchgs) );
6940  }
6941 
6942  return SCIP_OKAY;
6943 }
6944 
6945 /** relabels the given labels in-place in an increasing fashion: the first seen label is 0, the next label 1, etc...
6946  *
6947  * @note every label equal to -1 is treated as a previously unseen, unique label and gets a new ordered label.
6948  */
6949 static
6951  SCIP*const scip, /**< SCIP data structure */
6952  int* labels, /**< current labels that will be overwritten */
6953  int const nlabels, /**< number of variables in the clique */
6954  int* nclasses /**< pointer to store the total number of distinct labels */
6955  )
6956 {
6957  SCIP_HASHMAP* classidx2newlabel;
6958 
6959  int classidx;
6960  int i;
6961 
6962  SCIP_CALL( SCIPhashmapCreate(&classidx2newlabel, SCIPblkmem(scip), nlabels) );
6963 
6964  classidx = 0;
6965 
6966  /* loop over labels to create local class indices that obey the variable order */
6967  for( i = 0; i < nlabels; ++i )
6968  {
6969  int currentlabel = labels[i];
6970  int localclassidx;
6971 
6972  /* labels equal to -1 are stored as singleton classes */
6973  if( currentlabel == -1 )
6974  {
6975  ++classidx;
6976  localclassidx = classidx;
6977  }
6978  else
6979  {
6980  assert(currentlabel >= 0);
6981  /* look up the class index image in the hash map; if it is not stored yet, new class index is created and stored */
6982  if( !SCIPhashmapExists(classidx2newlabel, (void*)(size_t)currentlabel) )
6983  {
6984  ++classidx;
6985  localclassidx = classidx;
6986  SCIP_CALL( SCIPhashmapInsertInt(classidx2newlabel, (void*)(size_t)currentlabel, classidx) ); /*lint !e571*/
6987  }
6988  else
6989  {
6990  localclassidx = SCIPhashmapGetImageInt(classidx2newlabel, (void*)(size_t)currentlabel); /*lint !e571*/
6991  }
6992  }
6993  assert(localclassidx - 1 >= 0);
6994  assert(localclassidx - 1 <= i);
6995 
6996  /* indices start with zero, but we have an offset of 1 because we cannot store 0 in a hashmap */
6997  labels[i] = localclassidx - 1;
6998  }
6999 
7000  assert(classidx > 0);
7001  assert(classidx <= nlabels);
7002  *nclasses = classidx;
7003 
7004  SCIPhashmapFree(&classidx2newlabel);
7005 
7006  return SCIP_OKAY;
7007 }
7008 
7009 /** sort the variables w.r.t. the given labels; thereby ensure the current order of the variables with the same label. */
7010 static
7012  SCIP* scip, /**< SCIP data structure */
7013  SCIP_VAR** vars, /**< variable array */
7014  int* classlabels, /**< array that contains a class label for every variable */
7015  SCIP_VAR** sortedvars, /**< array to store variables after stable sorting */
7016  int* sortedindices, /**< array to store indices of sorted variables in the original vars array */
7017  int* classesstartposs, /**< starting position array for each label class (must have size nclasses + 1) */
7018  int nvars, /**< size of the vars arrays */
7019  int nclasses /**< number of label classes */
7020  )
7021 {
7022  SCIP_VAR*** varpointers;
7023  int** indexpointers;
7024  int* classcount;
7025 
7026  int nextpos;
7027  int c;
7028  int v;
7029 
7030  assert(scip != NULL);
7031  assert(vars != NULL);
7032  assert(sortedindices != NULL);
7033  assert(classesstartposs != NULL);
7034 
7035  assert(nvars == 0 || vars != NULL);
7036 
7037  if( nvars == 0 )
7038  return SCIP_OKAY;
7039 
7040  assert(classlabels != NULL);
7041  assert(nclasses > 0);
7042 
7043  /* we first count all class cardinalities and allocate temporary memory for a bucket sort */
7044  SCIP_CALL( SCIPallocBufferArray(scip, &classcount, nclasses) );
7045  BMSclearMemoryArray(classcount, nclasses);
7046 
7047  /* first we count for each class the number of elements */
7048  for( v = nvars - 1; v >= 0; --v )
7049  {
7050  assert(0 <= classlabels[v] && classlabels[v] < nclasses);
7051  ++(classcount[classlabels[v]]);
7052  }
7053 
7054 #ifndef NDEBUG
7055  BMSclearMemoryArray(sortedvars, nvars);
7056  BMSclearMemoryArray(sortedindices, nvars);
7057 #endif
7058  SCIP_CALL( SCIPallocBufferArray(scip, &varpointers, nclasses) );
7059  SCIP_CALL( SCIPallocBufferArray(scip, &indexpointers, nclasses) );
7060 
7061  nextpos = 0;
7062  /* now we initialize all start pointers for each class, so they will be ordered */
7063  for( c = 0; c < nclasses; ++c )
7064  {
7065  /* to reach the goal that all variables of each class will be standing next to each other we will initialize the
7066  * starting pointers for each class by adding the cardinality of each class to the last class starting pointer
7067  * e.g. class1 has 4 elements and class2 has 3 elements then the starting pointer for class1 will be the pointer
7068  * to sortedvars[0], the starting pointer to class2 will be the pointer to sortedvars[4] and to class3 it will be
7069  * the pointer to sortedvars[7]
7070  */
7071  varpointers[c] = (SCIP_VAR**) (sortedvars + nextpos);
7072  indexpointers[c] = (int*) (sortedindices + nextpos);
7073  classesstartposs[c] = nextpos;
7074  assert(classcount[c] > 0);
7075  nextpos += classcount[c];
7076  assert(nextpos > 0);
7077  }
7078  assert(nextpos == nvars);
7079  classesstartposs[c] = nextpos;
7080 
7081  /* now we copy all variables to the right order */
7082  for( v = 0; v < nvars; ++v )
7083  {
7084  /* copy variable itself to the right position */
7085  *(varpointers[classlabels[v]]) = vars[v]; /*lint !e613*/
7086  ++(varpointers[classlabels[v]]);
7087 
7088  /* copy index */
7089  *(indexpointers[classlabels[v]]) = v;
7090  ++(indexpointers[classlabels[v]]);
7091  }
7092 
7093 /* in debug mode, we ensure the correctness of the mapping */
7094 #ifndef NDEBUG
7095  for( v = 0; v < nvars; ++v )
7096  {
7097  assert(sortedvars[v] != NULL);
7098  assert(sortedindices[v] >= 0);
7099 
7100  /* assert that the sorted indices map back to the correct variable in the original order */
7101  assert(vars[sortedindices[v]] == sortedvars[v]);
7102  }
7103 #endif
7104 
7105  /* free temporary memory */
7106  SCIPfreeBufferArray(scip, &indexpointers);
7107  SCIPfreeBufferArray(scip, &varpointers);
7108  SCIPfreeBufferArray(scip, &classcount);
7109 
7110  return SCIP_OKAY;
7111 }
7112 
7113 
7114 /* calculate clique partition for a maximal amount of comparisons on variables due to expensive algorithm
7115  * @todo: check for a good value, maybe it's better to check parts of variables
7116  */
7117 #define MAXNCLIQUEVARSCOMP 1000000
7118 
7119 /** calculates a partition of the given set of binary variables into cliques;
7120  * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7121  * were assigned to the same clique;
7122  * the first variable is always assigned to clique 0, and a variable can only be assigned to clique i if at least one of
7123  * the preceding variables was assigned to clique i-1;
7124  * for each clique at most 1 variables can be set to TRUE in a feasible solution;
7125  *
7126  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7127  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7128  *
7129  * @pre This method can be called if @p scip is in one of the following stages:
7130  * - \ref SCIP_STAGE_INITPRESOLVE
7131  * - \ref SCIP_STAGE_PRESOLVING
7132  * - \ref SCIP_STAGE_EXITPRESOLVE
7133  * - \ref SCIP_STAGE_PRESOLVED
7134  * - \ref SCIP_STAGE_SOLVING
7135  */
7136 static
7138  SCIP*const scip, /**< SCIP data structure */
7139  SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7140  SCIP_Bool*const values, /**< clique value (TRUE or FALSE) for each variable in the clique */
7141  int const nvars, /**< number of variables in the array */
7142  int*const cliquepartition, /**< array of length nvars to store the clique partition */
7143  int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7144  )
7145 {
7146  SCIP_VAR** cliquevars;
7147  SCIP_Bool* cliquevalues;
7148  int i;
7149  int maxncliquevarscomp;
7150  int ncliquevars;
7151 
7152  /* allocate temporary memory for storing the variables of the current clique */
7153  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &cliquevars, nvars) );
7154  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &cliquevalues, nvars) );
7155 
7156  /* initialize the cliquepartition array with -1 */
7157  for( i = nvars - 1; i >= 0; --i )
7158  cliquepartition[i] = -1;
7159 
7160  maxncliquevarscomp = (int) MIN(nvars * (SCIP_Longint)nvars, MAXNCLIQUEVARSCOMP);
7161  /* calculate the clique partition */
7162  *ncliques = 0;
7163  for( i = 0; i < nvars; ++i )
7164  {
7165  if( cliquepartition[i] == -1 )
7166  {
7167  int j;
7168 
7169  /* variable starts a new clique */
7170  cliquepartition[i] = *ncliques;
7171  cliquevars[0] = vars[i];
7172  cliquevalues[0] = values[i];
7173  ncliquevars = 1;
7174 
7175  /* if variable is not active (multi-aggregated or fixed), it cannot be in any clique */
7176  if( SCIPvarIsActive(vars[i]) && SCIPvarGetNCliques(vars[i], values[i]) > 0 )
7177  {
7178  /* greedily fill up the clique */
7179  for( j = i+1; j < nvars; ++j )
7180  {
7181  /* if variable is not active (multi-aggregated or fixed), it cannot be in any clique */
7182  if( cliquepartition[j] == -1 && SCIPvarIsActive(vars[j]) )
7183  {
7184  int k;
7185 
7186  /* check if every variable in the current clique can be extended by tmpvars[j] */
7187  for( k = ncliquevars - 1; k >= 0; --k )
7188  {
7189  if( !SCIPvarsHaveCommonClique(vars[j], values[j], cliquevars[k], cliquevalues[k], FALSE) )
7190  break;
7191  }
7192 
7193  if( k == -1 )
7194  {
7195  /* put the variable into the same clique */
7196  cliquepartition[j] = cliquepartition[i];
7197  cliquevars[ncliquevars] = vars[j];
7198  cliquevalues[ncliquevars] = values[j];
7199  ++ncliquevars;
7200  }
7201  }
7202  }
7203  }
7204 
7205  /* this clique is finished */
7206  ++(*ncliques);
7207  }
7208  assert(cliquepartition[i] >= 0 && cliquepartition[i] < i+1);
7209 
7210  /* break if we reached the maximal number of comparisons */
7211  if( i * nvars > maxncliquevarscomp )
7212  break;
7213  }
7214  /* if we had to many variables fill up the cliquepartition and put each variable in a separate clique */
7215  for( ; i < nvars; ++i )
7216  {
7217  if( cliquepartition[i] == -1 )
7218  {
7219  cliquepartition[i] = *ncliques;
7220  ++(*ncliques);
7221  }
7222  }
7223 
7224  SCIPsetFreeBufferArray(scip->set, &cliquevalues);
7225  SCIPsetFreeBufferArray(scip->set, &cliquevars);
7226 
7227  return SCIP_OKAY;
7228 }
7229 
7230 /** calculates a partition of the given set of binary variables into cliques; takes into account independent clique components
7231  *
7232  * The algorithm performs the following steps:
7233  * - recomputes connected components of the clique table, if necessary
7234  * - computes a clique partition for every connected component greedily.
7235  * - relabels the resulting clique partition such that it satisfies the description below
7236  *
7237  * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7238  * were assigned to the same clique;
7239  * the first variable is always assigned to clique 0, and a variable can only be assigned to clique i if at least one of
7240  * the preceding variables was assigned to clique i-1;
7241  * for each clique at most 1 variables can be set to TRUE in a feasible solution;
7242  *
7243  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7244  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7245  *
7246  * @pre This method can be called if @p scip is in one of the following stages:
7247  * - \ref SCIP_STAGE_INITPRESOLVE
7248  * - \ref SCIP_STAGE_PRESOLVING
7249  * - \ref SCIP_STAGE_EXITPRESOLVE
7250  * - \ref SCIP_STAGE_PRESOLVED
7251  * - \ref SCIP_STAGE_SOLVING
7252  */
7254  SCIP*const scip, /**< SCIP data structure */
7255  SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7256  int const nvars, /**< number of variables in the clique */
7257  int*const cliquepartition, /**< array of length nvars to store the clique partition */
7258  int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7259  )
7260 {
7261  SCIP_VAR** tmpvars;
7262 
7263  SCIP_VAR** sortedtmpvars;
7264  SCIP_Bool* tmpvalues;
7265  SCIP_Bool* sortedtmpvalues;
7266  int* componentlabels;
7267  int* sortedindices;
7268  int* componentstartposs;
7269  int i;
7270  int c;
7271 
7272  int ncomponents;
7273 
7274  assert(scip != NULL);
7275  assert(nvars == 0 || vars != NULL);
7276  assert(nvars == 0 || cliquepartition != NULL);
7277  assert(ncliques != NULL);
7278 
7279  SCIP_CALL( SCIPcheckStage(scip, "SCIPcalcCliquePartition", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7280 
7281  if( nvars == 0 )
7282  {
7283  *ncliques = 0;
7284  return SCIP_OKAY;
7285  }
7286 
7287  /* early abort if no cliques are present */
7288  if( SCIPgetNCliques(scip) == 0 )
7289  {
7290  for( i = 0; i < nvars; ++i )
7291  cliquepartition[i] = i;
7292 
7293  *ncliques = nvars;
7294 
7295  return SCIP_OKAY;
7296  }
7297 
7298  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &tmpvalues, nvars) );
7299  SCIP_CALL( SCIPsetDuplicateBufferArray(scip->set, &tmpvars, vars, nvars) );
7300  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &componentlabels, nvars) );
7301  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedindices, nvars) );
7302 
7303  /* initialize the tmpvalues array */
7304  for( i = nvars - 1; i >= 0; --i )
7305  {
7306  tmpvalues[i] = TRUE;
7307  cliquepartition[i] = -1;
7308  }
7309 
7310  /* get corresponding active problem variables */
7311  SCIP_CALL( SCIPvarsGetProbvarBinary(&tmpvars, &tmpvalues, nvars) );
7312 
7313  ncomponents = -1;
7314 
7315  /* update clique components if necessary */
7317  {
7318  SCIP_VAR** allvars;
7319  int nallbinvars;
7320  int nallintvars;
7321  int nallimplvars;
7322 
7323  SCIP_CALL( SCIPgetVarsData(scip, &allvars, NULL, &nallbinvars, &nallintvars, &nallimplvars, NULL) );
7324 
7325  SCIP_CALL( SCIPcliquetableComputeCliqueComponents(scip->cliquetable, scip->set, SCIPblkmem(scip), allvars, nallbinvars, nallintvars, nallimplvars) );
7326  }
7327 
7329 
7330  /* store the global clique component labels */
7331  for( i = 0; i < nvars; ++i )
7332  {
7333  if( SCIPvarIsActive(tmpvars[i]) )
7334  componentlabels[i] = SCIPcliquetableGetVarComponentIdx(scip->cliquetable, tmpvars[i]);
7335  else
7336  componentlabels[i] = -1;
7337  }
7338 
7339  /* relabel component labels order consistent as prerequisite for a stable sort */
7340  SCIP_CALL( relabelOrderConsistent(scip, componentlabels, nvars, &ncomponents) );
7341  assert(ncomponents >= 1);
7342  assert(ncomponents <= nvars);
7343 
7344  /* allocate storage array for the starting positions of the components */
7345  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &componentstartposs, ncomponents + 1) );
7346 
7347  /* stable sort the variables w.r.t. the component labels so that we can restrict the quadratic algorithm to the components */
7348  if( ncomponents > 1 )
7349  {
7350  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedtmpvars, nvars) );
7351  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedtmpvalues, nvars) );
7352  SCIP_CALL( labelSortStable(scip, tmpvars, componentlabels, sortedtmpvars, sortedindices, componentstartposs, nvars, ncomponents) );
7353 
7354  /* reassign the tmpvalues with respect to the sorting */
7355  for( i = 0; i < nvars; ++i )
7356  {
7357  assert(tmpvars[sortedindices[i]] == sortedtmpvars[i]);
7358  sortedtmpvalues[i] = tmpvalues[sortedindices[i]];
7359  }
7360  }
7361  else
7362  {
7363  /* if we have only one large connected component, skip the stable sorting and prepare the data differently */
7364  sortedtmpvars = tmpvars;
7365  sortedtmpvalues = tmpvalues;
7366  componentstartposs[0] = 0;
7367  componentstartposs[1] = nvars;
7368 
7369  /* sorted indices are the identity */
7370  for( i = 0; i < nvars; ++i )
7371  sortedindices[i] = i;
7372  }
7373 
7374  *ncliques = 0;
7375  /* calculate a greedy clique partition for each connected component */
7376  for( c = 0; c < ncomponents; ++c )
7377  {
7378  int* localcliquepartition;
7379  int nlocalcliques;
7380  int ncomponentvars;
7381  int l;
7382 
7383  /* extract the number of variables in this connected component */
7384  ncomponentvars = componentstartposs[c + 1] - componentstartposs[c];
7385  nlocalcliques = 0;
7386 
7387  /* allocate necessary memory to hold the intermediate component clique partition */
7388  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &localcliquepartition, ncomponentvars) );
7389 
7390  /* call greedy clique algorithm for all component variables */
7391  SCIP_CALL( calcCliquePartitionGreedy(scip, &(sortedtmpvars[componentstartposs[c]]), &(sortedtmpvalues[componentstartposs[c]]),
7392  ncomponentvars, localcliquepartition, &nlocalcliques) );
7393 
7394  assert(nlocalcliques >= 1);
7395  assert(nlocalcliques <= ncomponentvars);
7396 
7397  /* store the obtained clique partition with an offset of ncliques for the original variables */
7398  for( l = componentstartposs[c]; l < componentstartposs[c + 1]; ++l )
7399  {
7400  int origvaridx = sortedindices[l];
7401  assert(cliquepartition[origvaridx] == -1);
7402  assert(localcliquepartition[l - componentstartposs[c]] <= l - componentstartposs[c]);
7403  cliquepartition[origvaridx] = localcliquepartition[l - componentstartposs[c]] + (*ncliques);
7404  }
7405  *ncliques += nlocalcliques;
7406 
7407  /* free the local clique partition */
7408  SCIPsetFreeBufferArray(scip->set, &localcliquepartition);
7409  }
7410 
7411  /* except in the two trivial cases, we have to ensure the order consistency of the partition indices */
7412  if( ncomponents > 1 && ncomponents < nvars )
7413  {
7414  int partitionsize;
7415  SCIP_CALL( relabelOrderConsistent(scip, cliquepartition, nvars, &partitionsize) );
7416 
7417  assert(partitionsize == *ncliques);
7418  }
7419 
7420  if( ncomponents > 1 )
7421  {
7422  SCIPsetFreeBufferArray(scip->set, &sortedtmpvalues);
7423  SCIPsetFreeBufferArray(scip->set, &sortedtmpvars);
7424  }
7425 
7426  /* use the greedy algorithm as a whole to verify the result on small number of variables */
7427 #ifdef SCIP_DISABLED_CODE
7428  {
7429  int* debugcliquepartition;
7430  int ndebugcliques;
7431 
7432  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &debugcliquepartition, nvars) );
7433 
7434  /* call greedy clique algorithm for all component variables */
7435  SCIP_CALL( calcCliquePartitionGreedy(scip, tmpvars, tmpvalues, nvars, debugcliquepartition, &ndebugcliques) );
7436 
7437  /* loop and compare the traditional greedy clique with */
7438  for( i = 0; i < nvars; ++i )
7439  assert(i * nvars > MAXNCLIQUEVARSCOMP || cliquepartition[i] == debugcliquepartition[i]);
7440 
7441  SCIPsetFreeBufferArray(scip->set, &debugcliquepartition);
7442  }
7443 #endif
7444 
7445  /* free temporary memory */
7446  SCIPsetFreeBufferArray(scip->set, &componentstartposs);
7447  SCIPsetFreeBufferArray(scip->set, &sortedindices);
7448  SCIPsetFreeBufferArray(scip->set, &componentlabels);
7449  SCIPsetFreeBufferArray(scip->set, &tmpvars);
7450  SCIPsetFreeBufferArray(scip->set, &tmpvalues);
7451 
7452  return SCIP_OKAY;
7453 }
7454 
7455 /** calculates a partition of the given set of binary variables into negated cliques;
7456  * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7457  * were assigned to the same negated clique;
7458  * the first variable is always assigned to clique 0 and a variable can only be assigned to clique i if at least one of
7459  * the preceding variables was assigned to clique i-1;
7460  * for each clique with n_c variables at least n_c-1 variables can be set to TRUE in a feasible solution;
7461  *
7462  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7463  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7464  *
7465  * @pre This method can be called if @p scip is in one of the following stages:
7466  * - \ref SCIP_STAGE_INITPRESOLVE
7467  * - \ref SCIP_STAGE_PRESOLVING
7468  * - \ref SCIP_STAGE_EXITPRESOLVE
7469  * - \ref SCIP_STAGE_PRESOLVED
7470  * - \ref SCIP_STAGE_SOLVING
7471  */
7473  SCIP*const scip, /**< SCIP data structure */
7474  SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7475  int const nvars, /**< number of variables in the clique */
7476  int*const cliquepartition, /**< array of length nvars to store the clique partition */
7477  int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7478  )
7479 {
7480  SCIP_VAR** negvars;
7481  int v;
7482 
7483  assert(scip != NULL);
7484  assert(cliquepartition != NULL || nvars == 0);
7485  assert(ncliques != NULL);
7486 
7487  if( nvars == 0 )
7488  {
7489  *ncliques = 0;
7490  return SCIP_OKAY;
7491  }
7492  assert(vars != NULL);
7493 
7494  /* allocate temporary memory */
7495  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &negvars, nvars) );
7496 
7497  /* get all negated variables */
7498  for( v = nvars - 1; v >= 0; --v )
7499  {
7500  SCIP_CALL( SCIPgetNegatedVar(scip, vars[v], &(negvars[v])) );
7501  }
7502 
7503  /* calculate cliques on negated variables, which are "negated" cliques on normal variables array */
7504  SCIP_CALL( SCIPcalcCliquePartition( scip, negvars, nvars, cliquepartition, ncliques) );
7505 
7506  /* free temporary memory */
7507  SCIPsetFreeBufferArray(scip->set, &negvars);
7508 
7509  return SCIP_OKAY;
7510 }
7511 
7512 
7513 /** force SCIP to clean up all cliques; cliques do not get automatically cleaned up after presolving. Use
7514  * this method to prevent inactive variables in cliques when retrieved via SCIPgetCliques()
7515  *
7516  * @return SCIP_OKAY if everything worked, otherwise a suitable error code is passed
7517  *
7518  * @pre This method can be called if @p scip is in one of the following stages:
7519  * - \ref SCIP_STAGE_TRANSFORMED
7520  * - \ref SCIP_STAGE_INITPRESOLVE
7521  * - \ref SCIP_STAGE_PRESOLVING
7522  * - \ref SCIP_STAGE_EXITPRESOLVE
7523  * - \ref SCIP_STAGE_PRESOLVED
7524  * - \ref SCIP_STAGE_INITSOLVE
7525  * - \ref SCIP_STAGE_SOLVING
7526  * - \ref SCIP_STAGE_SOLVED
7527  * - \ref SCIP_STAGE_EXITSOLVE
7528  */
7530  SCIP* scip, /**< SCIP data structure */
7531  SCIP_Bool* infeasible /**< pointer to store if cleanup detected infeasibility */
7532  )
7533 {
7534  int nlocalbdchgs;
7535  SCIP_Bool globalinfeasibility;
7536 
7537  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPcleanupCliques", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7538 
7539  globalinfeasibility = FALSE;
7540  nlocalbdchgs = 0;
7541  SCIP_CALL( SCIPcliquetableCleanup(scip->cliquetable, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
7542  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, &nlocalbdchgs,
7543  &globalinfeasibility) );
7544 
7545  if( infeasible != NULL )
7546  *infeasible = globalinfeasibility;
7547 
7548  if( globalinfeasibility )
7550 
7551  return SCIP_OKAY;
7552 }
7553 
7554 /** gets the number of cliques in the clique table
7555  *
7556  * @return number of cliques in the clique table
7557  *
7558  * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7559  * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
7560  *
7561  * @pre This method can be called if @p scip is in one of the following stages:
7562  * - \ref SCIP_STAGE_TRANSFORMED
7563  * - \ref SCIP_STAGE_INITPRESOLVE
7564  * - \ref SCIP_STAGE_PRESOLVING
7565  * - \ref SCIP_STAGE_EXITPRESOLVE
7566  * - \ref SCIP_STAGE_PRESOLVED
7567  * - \ref SCIP_STAGE_INITSOLVE
7568  * - \ref SCIP_STAGE_SOLVING
7569  * - \ref SCIP_STAGE_SOLVED
7570  * - \ref SCIP_STAGE_EXITSOLVE
7571  */
7573  SCIP* scip /**< SCIP data structure */
7574  )
7575 {
7576  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNCliques", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7577 
7579 }
7580 
7581 /** gets the number of cliques created so far by the cliquetable
7582  *
7583  * @return number of cliques created so far by the cliquetable
7584  *
7585  * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7586  * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
7587  *
7588  * @pre This method can be called if @p scip is in one of the following stages:
7589  * - \ref SCIP_STAGE_TRANSFORMED
7590  * - \ref SCIP_STAGE_INITPRESOLVE
7591  * - \ref SCIP_STAGE_PRESOLVING
7592  * - \ref SCIP_STAGE_EXITPRESOLVE
7593  * - \ref SCIP_STAGE_PRESOLVED
7594  * - \ref SCIP_STAGE_INITSOLVE
7595  * - \ref SCIP_STAGE_SOLVING
7596  * - \ref SCIP_STAGE_SOLVED
7597  * - \ref SCIP_STAGE_EXITSOLVE
7598  */
7600  SCIP* scip /**< SCIP data structure */
7601  )
7602 {
7603  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNCliquesCreated", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7604 
7606 }
7607 
7608 /** gets the array of cliques in the clique table
7609  *
7610  * @return array of cliques in the clique table
7611  *
7612  * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7613  * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
7614  *
7615  * @pre This method can be called if @p scip is in one of the following stages:
7616  * - \ref SCIP_STAGE_TRANSFORMED
7617  * - \ref SCIP_STAGE_INITPRESOLVE
7618  * - \ref SCIP_STAGE_PRESOLVING
7619  * - \ref SCIP_STAGE_EXITPRESOLVE
7620  * - \ref SCIP_STAGE_PRESOLVED
7621  * - \ref SCIP_STAGE_INITSOLVE
7622  * - \ref SCIP_STAGE_SOLVING
7623  * - \ref SCIP_STAGE_SOLVED
7624  * - \ref SCIP_STAGE_EXITSOLVE
7625  */
7627  SCIP* scip /**< SCIP data structure */
7628  )
7629 {
7630  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetCliques", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7631 
7632  return SCIPcliquetableGetCliques(scip->cliquetable);
7633 }
7634 
7635 /** returns whether there is a clique that contains both given variable/value pairs;
7636  * the variables must be active binary variables;
7637  * if regardimplics is FALSE, only the cliques in the clique table are looked at;
7638  * if regardimplics is TRUE, both the cliques and the implications of the implication graph are regarded
7639  *
7640  * @return TRUE, if there is a clique that contains both variable/clique pairs; FALSE, otherwise
7641  *
7642  * @pre This method can be called if @p scip is in one of the following stages:
7643  * - \ref SCIP_STAGE_TRANSFORMED
7644  * - \ref SCIP_STAGE_INITPRESOLVE
7645  * - \ref SCIP_STAGE_PRESOLVING
7646  * - \ref SCIP_STAGE_EXITPRESOLVE
7647  * - \ref SCIP_STAGE_PRESOLVED
7648  * - \ref SCIP_STAGE_INITSOLVE
7649  * - \ref SCIP_STAGE_SOLVING
7650  * - \ref SCIP_STAGE_SOLVED
7651  * - \ref SCIP_STAGE_EXITSOLVE
7652  *
7653  * @note a variable with it's negated variable are NOT! in a clique
7654  * @note a variable with itself are in a clique
7655  */
7657  SCIP* scip, /**< SCIP data structure */
7658  SCIP_VAR* var1, /**< first variable */
7659  SCIP_Bool value1, /**< value of first variable */
7660  SCIP_VAR* var2, /**< second variable */
7661  SCIP_Bool value2, /**< value of second variable */
7662  SCIP_Bool regardimplics /**< should the implication graph also be searched for a clique? */
7663  )
7664 {
7665  assert(scip != NULL);
7666  assert(var1 != NULL);
7667  assert(var2 != NULL);
7668  assert(SCIPvarIsActive(var1));
7669  assert(SCIPvarIsActive(var2));
7670  assert(SCIPvarIsBinary(var1));
7671  assert(SCIPvarIsBinary(var2));
7672 
7673  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPhaveVarsCommonClique", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7674 
7675  /* if both variables together have more cliques then actual cliques exist, then they have a common clique (in debug
7676  * mode we check this for correctness), otherwise we need to call the pairwise comparison method for these variables
7677  */
7678 #ifndef NDEBUG
7679  assert((SCIPvarGetNCliques(var1, value1) + SCIPvarGetNCliques(var2, value2) > SCIPcliquetableGetNCliques(scip->cliquetable)) ? SCIPvarsHaveCommonClique(var1, value1, var2, value2, FALSE) : TRUE);
7680 #endif
7681 
7682  return (SCIPvarGetNCliques(var1, value1) + SCIPvarGetNCliques(var2, value2) > SCIPcliquetableGetNCliques(scip->cliquetable)
7683  || SCIPvarsHaveCommonClique(var1, value1, var2, value2, regardimplics));
7684 }
7685 
7686 /** writes the clique graph to a gml file
7687  *
7688  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7689  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7690  *
7691  * @pre This method can be called if @p scip is in one of the following stages:
7692  * - \ref SCIP_STAGE_TRANSFORMED
7693  * - \ref SCIP_STAGE_INITPRESOLVE
7694  * - \ref SCIP_STAGE_PRESOLVING
7695  * - \ref SCIP_STAGE_EXITPRESOLVE
7696  * - \ref SCIP_STAGE_PRESOLVED
7697  * - \ref SCIP_STAGE_INITSOLVE
7698  * - \ref SCIP_STAGE_SOLVING
7699  * - \ref SCIP_STAGE_SOLVED
7700  * - \ref SCIP_STAGE_EXITSOLVE
7701  *
7702  * @note there can be duplicated arcs in the output file
7703  *
7704  * If @p writenodeweights is true, only nodes corresponding to variables that have a fractional value and only edges
7705  * between such nodes are written.
7706  */
7708  SCIP* scip, /**< SCIP data structure */
7709  const char* fname, /**< name of file */
7710  SCIP_Bool writenodeweights /**< should we write weights of nodes? */
7711  )
7712 {
7713  FILE* gmlfile;
7714  SCIP_HASHMAP* nodehashmap;
7715  SCIP_CLIQUE** cliques;
7716  SCIP_VAR** clqvars;
7717  SCIP_VAR** allvars;
7718  SCIP_Bool* clqvalues;
7719  char nodename[SCIP_MAXSTRLEN];
7720  int nallvars;
7721  int nbinvars;
7722  int nintvars;
7723  int nimplvars;
7724  int ncliques;
7725  int c;
7726  int v1;
7727  int v2;
7728  int id1;
7729  int id2;
7730 
7731  assert(scip != NULL);
7732  assert(fname != NULL);
7733 
7734  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPwriteCliqueGraph", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7735 
7736  /* get all active variables */
7737  SCIP_CALL( SCIPgetVarsData(scip, &allvars, &nallvars, &nbinvars, &nintvars, &nimplvars, NULL) );
7738 
7739  /* no possible variables for cliques exist */
7740  if( nbinvars + nimplvars == 0 )
7741  return SCIP_OKAY;
7742 
7743  ncliques = SCIPgetNCliques(scip);
7744 
7745  /* no cliques and do not wont to check for binary implications */
7746  if( ncliques == 0 )
7747  return SCIP_OKAY;
7748 
7749  /* open gml file */
7750  gmlfile = fopen(fname, "w");
7751 
7752  if( gmlfile == NULL )
7753  {
7754  SCIPerrorMessage("cannot open graph file <%s>\n", fname);
7755  SCIPABORT();
7756  return SCIP_INVALIDDATA; /*lint !e527*/
7757  }
7758 
7759  /* create the hash map */
7760  SCIP_CALL_FINALLY( SCIPhashmapCreate(&nodehashmap, SCIPblkmem(scip), nbinvars+nimplvars), fclose(gmlfile) );
7761 
7762  /* write starting of gml file */
7763  SCIPgmlWriteOpening(gmlfile, TRUE);
7764 
7765  cliques = SCIPgetCliques(scip);
7766 
7767  /* write nodes and arcs for all cliques */
7768  for( c = ncliques - 1; c >= 0; --c )
7769  {
7770  clqvalues = SCIPcliqueGetValues(cliques[c]);
7771  clqvars = SCIPcliqueGetVars(cliques[c]);
7772 
7773  for( v1 = SCIPcliqueGetNVars(cliques[c]) - 1; v1 >= 0; --v1 )
7774  {
7775  id1 = clqvalues[v1] ? SCIPvarGetProbindex(clqvars[v1]) : (nallvars + SCIPvarGetProbindex(clqvars[v1]));
7776 
7777  /* if corresponding node was not added yet, add it */
7778  if( !SCIPhashmapExists(nodehashmap, (void*)(size_t)id1) )
7779  {
7780  assert(id1 >= 0);
7781  SCIP_CALL_FINALLY( SCIPhashmapInsertInt(nodehashmap, (void*)(size_t)id1, 1), fclose(gmlfile) ); /*lint !e571*/
7782 
7783  (void) SCIPsnprintf(nodename, SCIP_MAXSTRLEN, "%s%s", (id1 >= nallvars ? "~" : ""), SCIPvarGetName(clqvars[v1]));
7784 
7785  /* write new gml node for new variable */
7786  if ( writenodeweights )
7787  {
7788  if ( ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v1])) )
7789  SCIPgmlWriteNodeWeight(gmlfile, (unsigned int)id1, nodename, NULL, NULL, NULL, SCIPgetSolVal(scip, NULL, clqvars[v1]));
7790  }
7791  else
7792  {
7793  SCIPgmlWriteNode(gmlfile, (unsigned int)id1, nodename, NULL, NULL, NULL);
7794  }
7795  }
7796 
7797  for( v2 = SCIPcliqueGetNVars(cliques[c]) - 1; v2 >= 0; --v2 )
7798  {
7799  if( v1 == v2 )
7800  continue;
7801 
7802  id2 = clqvalues[v2] ? SCIPvarGetProbindex(clqvars[v2]) : (nallvars + SCIPvarGetProbindex(clqvars[v2]));
7803 
7804  /* if corresponding node was not added yet, add it */
7805  if( !SCIPhashmapExists(nodehashmap, (void*)(size_t)id2) )
7806  {
7807  assert(id2 >= 0);
7808  SCIP_CALL_FINALLY( SCIPhashmapInsertInt(nodehashmap, (void*)(size_t)id2, 1), fclose(gmlfile) ); /*lint !e571*/
7809 
7810  (void) SCIPsnprintf(nodename, SCIP_MAXSTRLEN, "%s%s", (id2 >= nallvars ? "~" : ""), SCIPvarGetName(clqvars[v2]));
7811 
7812  /* write new gml node for new variable */
7813  if ( writenodeweights )
7814  {
7815  if ( ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v2])) )
7816  SCIPgmlWriteNodeWeight(gmlfile, (unsigned int)id2, nodename, NULL, NULL, NULL, SCIPgetSolVal(scip, NULL, clqvars[v2]));
7817  }
7818  else
7819  {
7820  SCIPgmlWriteNode(gmlfile, (unsigned int)id2, nodename, NULL, NULL, NULL);
7821  }
7822  }
7823 
7824  /* write gml arc between resultant and operand */
7825  if ( ! writenodeweights || ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v2])) )
7826  SCIPgmlWriteArc(gmlfile, (unsigned int)id1, (unsigned int)id2, NULL, NULL);
7827  }
7828  }
7829  }
7830 
7831  /* free the hash map */
7832  SCIPhashmapFree(&nodehashmap);
7833 
7834  SCIPgmlWriteClosing(gmlfile);
7835  fclose(gmlfile);
7836 
7837  return SCIP_OKAY;
7838 }
7839 
7840 /** Removes (irrelevant) variable from all its global structures, i.e. cliques, implications and variable bounds.
7841  * This is an advanced method which should be used with care.
7842  *
7843  * @return SCIP_OKAY if everything worked, otherwise a suitable error code is passed
7844  *
7845  * @pre This method can be called if @p scip is in one of the following stages:
7846  * - \ref SCIP_STAGE_TRANSFORMED
7847  * - \ref SCIP_STAGE_INITPRESOLVE
7848  * - \ref SCIP_STAGE_PRESOLVING
7849  * - \ref SCIP_STAGE_EXITPRESOLVE
7850  * - \ref SCIP_STAGE_PRESOLVED
7851  * - \ref SCIP_STAGE_INITSOLVE
7852  * - \ref SCIP_STAGE_SOLVING
7853  * - \ref SCIP_STAGE_SOLVED
7854  * - \ref SCIP_STAGE_EXITSOLVE
7855  */
7857  SCIP* scip, /**< SCIP data structure */
7858  SCIP_VAR* var /**< variable to remove from global structures */
7859  )
7860 {
7861  assert(scip != NULL);
7862 
7863  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPremoveVarFromGlobalStructures", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7864 
7865  /* mark the variable as deletable from global structures - This is necessary for the delayed clean up of cliques */
7867 
7868  /* remove variable from all its cliques, implications, and variable bounds */
7870 
7871  return SCIP_OKAY;
7872 }
7873 
7874 /** sets the branch factor of the variable; this value can be used in the branching methods to scale the score
7875  * values of the variables; higher factor leads to a higher probability that this variable is chosen for branching
7876  *
7877  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7878  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7879  *
7880  * @pre This method can be called if @p scip is in one of the following stages:
7881  * - \ref SCIP_STAGE_PROBLEM
7882  * - \ref SCIP_STAGE_TRANSFORMING
7883  * - \ref SCIP_STAGE_TRANSFORMED
7884  * - \ref SCIP_STAGE_INITPRESOLVE
7885  * - \ref SCIP_STAGE_PRESOLVING
7886  * - \ref SCIP_STAGE_EXITPRESOLVE
7887  * - \ref SCIP_STAGE_PRESOLVED
7888  * - \ref SCIP_STAGE_SOLVING
7889  */
7891  SCIP* scip, /**< SCIP data structure */
7892  SCIP_VAR* var, /**< problem variable */
7893  SCIP_Real branchfactor /**< factor to weigh variable's branching score with */
7894  )
7895 {
7896  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7897 
7898  SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, branchfactor) );
7899 
7900  return SCIP_OKAY;
7901 }
7902 
7903 /** scales the branch factor of the variable with the given value
7904  *
7905  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7906  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7907  *
7908  * @pre This method can be called if @p scip is in one of the following stages:
7909  * - \ref SCIP_STAGE_PROBLEM
7910  * - \ref SCIP_STAGE_TRANSFORMING
7911  * - \ref SCIP_STAGE_TRANSFORMED
7912  * - \ref SCIP_STAGE_INITPRESOLVE
7913  * - \ref SCIP_STAGE_PRESOLVING
7914  * - \ref SCIP_STAGE_EXITPRESOLVE
7915  * - \ref SCIP_STAGE_PRESOLVED
7916  * - \ref SCIP_STAGE_SOLVING
7917  */
7919  SCIP* scip, /**< SCIP data structure */
7920  SCIP_VAR* var, /**< problem variable */
7921  SCIP_Real scale /**< factor to scale variable's branching factor with */
7922  )
7923 {
7924  SCIP_CALL( SCIPcheckStage(scip, "SCIPscaleVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7925 
7926  SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, scale * SCIPvarGetBranchFactor(var)) );
7927 
7928  return SCIP_OKAY;
7929 }
7930 
7931 /** adds the given value to the branch factor of the variable
7932  *
7933  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7934  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7935  *
7936  * @pre This method can be called if @p scip is in one of the following stages:
7937  * - \ref SCIP_STAGE_PROBLEM
7938  * - \ref SCIP_STAGE_TRANSFORMING
7939  * - \ref SCIP_STAGE_TRANSFORMED
7940  * - \ref SCIP_STAGE_INITPRESOLVE
7941  * - \ref SCIP_STAGE_PRESOLVING
7942  * - \ref SCIP_STAGE_EXITPRESOLVE
7943  * - \ref SCIP_STAGE_PRESOLVED
7944  * - \ref SCIP_STAGE_SOLVING
7945  */
7947  SCIP* scip, /**< SCIP data structure */
7948  SCIP_VAR* var, /**< problem variable */
7949  SCIP_Real addfactor /**< value to add to the branch factor of the variable */
7950  )
7951 {
7952  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7953 
7954  SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, addfactor + SCIPvarGetBranchFactor(var)) );
7955 
7956  return SCIP_OKAY;
7957 }
7958 
7959 /** sets the branch priority of the variable; variables with higher branch priority are always preferred to variables
7960  * with lower priority in selection of branching variable
7961  *
7962  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7963  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7964  *
7965  * @pre This method can be called if @p scip is in one of the following stages:
7966  * - \ref SCIP_STAGE_PROBLEM
7967  * - \ref SCIP_STAGE_TRANSFORMING
7968  * - \ref SCIP_STAGE_TRANSFORMED
7969  * - \ref SCIP_STAGE_INITPRESOLVE
7970  * - \ref SCIP_STAGE_PRESOLVING
7971  * - \ref SCIP_STAGE_EXITPRESOLVE
7972  * - \ref SCIP_STAGE_PRESOLVED
7973  * - \ref SCIP_STAGE_SOLVING
7974  *
7975  * @note the default branching priority is 0
7976  */
7978  SCIP* scip, /**< SCIP data structure */
7979  SCIP_VAR* var, /**< problem variable */
7980  int branchpriority /**< branch priority of the variable */
7981  )
7982 {
7983  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7984 
7985  assert( var->scip == scip );
7986 
7987  if( SCIPisTransformed(scip) )
7988  {
7989  assert(scip->branchcand != NULL);
7990 
7991  /* inform the pseudo branch candidates that the branch priority changes and change the branch priority */
7992  SCIP_CALL( SCIPbranchcandUpdateVarBranchPriority(scip->branchcand, scip->set, var, branchpriority) );
7993  }
7994  else
7995  {
7996  /* change the branching priority of the variable */
7997  SCIP_CALL( SCIPvarChgBranchPriority(var, branchpriority) );
7998  }
7999 
8000  return SCIP_OKAY;
8001 }
8002 
8003 /** changes the branch priority of the variable to the given value, if it is larger than the current priority
8004  *
8005  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8006  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8007  *
8008  * @pre This method can be called if @p scip is in one of the following stages:
8009  * - \ref SCIP_STAGE_PROBLEM
8010  * - \ref SCIP_STAGE_TRANSFORMING
8011  * - \ref SCIP_STAGE_TRANSFORMED
8012  * - \ref SCIP_STAGE_INITPRESOLVE
8013  * - \ref SCIP_STAGE_PRESOLVING
8014  * - \ref SCIP_STAGE_EXITPRESOLVE
8015  * - \ref SCIP_STAGE_PRESOLVED
8016  * - \ref SCIP_STAGE_SOLVING
8017  */
8019  SCIP* scip, /**< SCIP data structure */
8020  SCIP_VAR* var, /**< problem variable */
8021  int branchpriority /**< new branch priority of the variable, if it is larger than current priority */
8022  )
8023 {
8024  SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8025 
8026  assert( var->scip == scip );
8027 
8028  if( branchpriority > SCIPvarGetBranchPriority(var) )
8029  {
8030  SCIP_CALL( SCIPvarChgBranchPriority(var, branchpriority) );
8031  }
8032 
8033  return SCIP_OKAY;
8034 }
8035 
8036 /** adds the given value to the branch priority of the variable
8037  *
8038  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8039  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8040  *
8041  * @pre This method can be called if @p scip is in one of the following stages:
8042  * - \ref SCIP_STAGE_PROBLEM
8043  * - \ref SCIP_STAGE_TRANSFORMING
8044  * - \ref SCIP_STAGE_TRANSFORMED
8045  * - \ref SCIP_STAGE_INITPRESOLVE
8046  * - \ref SCIP_STAGE_PRESOLVING
8047  * - \ref SCIP_STAGE_EXITPRESOLVE
8048  * - \ref SCIP_STAGE_PRESOLVED
8049  * - \ref SCIP_STAGE_SOLVING
8050  */
8052  SCIP* scip, /**< SCIP data structure */
8053  SCIP_VAR* var, /**< problem variable */
8054  int addpriority /**< value to add to the branch priority of the variable */
8055  )
8056 {
8057  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8058 
8059  assert( var->scip == scip );
8060 
8061  SCIP_CALL( SCIPvarChgBranchPriority(var, addpriority + SCIPvarGetBranchPriority(var)) );
8062 
8063  return SCIP_OKAY;
8064 }
8065 
8066 /** sets the branch direction of the variable (-1: prefer downwards branch, 0: automatic selection, +1: prefer upwards
8067  * branch)
8068  *
8069  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8070  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8071  *
8072  * @pre This method can be called if @p scip is in one of the following stages:
8073  * - \ref SCIP_STAGE_PROBLEM
8074  * - \ref SCIP_STAGE_TRANSFORMING
8075  * - \ref SCIP_STAGE_TRANSFORMED
8076  * - \ref SCIP_STAGE_INITPRESOLVE
8077  * - \ref SCIP_STAGE_PRESOLVING
8078  * - \ref SCIP_STAGE_EXITPRESOLVE
8079  * - \ref SCIP_STAGE_PRESOLVED
8080  * - \ref SCIP_STAGE_SOLVING
8081  */
8083  SCIP* scip, /**< SCIP data structure */
8084  SCIP_VAR* var, /**< problem variable */
8085  SCIP_BRANCHDIR branchdirection /**< preferred branch direction of the variable (downwards, upwards, auto) */
8086  )
8087 {
8088  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchDirection", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8089 
8090  assert( var->scip == scip );
8091 
8092  SCIP_CALL( SCIPvarChgBranchDirection(var, branchdirection) );
8093 
8094  return SCIP_OKAY;
8095 }
8096 
8097 /** tightens the variable bounds due to a new variable type */
8098 static
8100  SCIP* scip, /**< SCIP data structure */
8101  SCIP_VAR* var, /**< variable to change the bound for */
8102  SCIP_VARTYPE vartype, /**< new type of variable */
8103  SCIP_Bool* infeasible /**< pointer to store whether an infeasibility was detected (, due to
8104  * integrality condition of the new variable type) */
8105  )
8106 {
8107  assert(scip != NULL);
8109  assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPvarIsTransformed(var));
8110  assert(var->scip == scip);
8111 
8112  *infeasible = FALSE;
8113 
8114  /* adjusts bounds if the variable type changed form continuous to non-continuous (integral) */
8116  {
8117  SCIP_Bool tightened;
8118 
8119  /* we adjust variable bounds to integers first, since otherwise a later bound tightening with a fractional old
8120  * bound may give an assert because SCIP expects non-continuous variables to have non-fractional bounds
8121  *
8122  * we adjust bounds with a fractionality within [eps,feastol] only if the resulting bound change is a bound
8123  * tightening, because relaxing bounds may not be allowed
8124  */
8125  if( !SCIPisFeasIntegral(scip, SCIPvarGetLbGlobal(var)) ||
8127  (!SCIPsetIsEQ(scip->set, SCIPvarGetLbGlobal(var), SCIPfeasCeil(scip, SCIPvarGetLbGlobal(var))) &&
8129  )
8130  {
8131  SCIP_CALL( SCIPtightenVarLbGlobal(scip, var, SCIPfeasCeil(scip, SCIPvarGetLbGlobal(var)), TRUE, infeasible, &tightened) );
8132  if( *infeasible )
8133  return SCIP_OKAY;
8134 
8135  /* 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
8136  * 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
8137  */
8138  assert(tightened || SCIPisFeasLE(scip, SCIPvarGetUbGlobal(var), SCIPfeasCeil(scip, SCIPvarGetLbGlobal(var))));
8139  }
8140  if( !SCIPisFeasIntegral(scip, SCIPvarGetUbGlobal(var)) ||
8142  )
8143  {
8144  SCIP_CALL( SCIPtightenVarUbGlobal(scip, var, SCIPfeasFloor(scip, SCIPvarGetUbGlobal(var)), TRUE, infeasible, &tightened) );
8145  if( *infeasible )
8146  return SCIP_OKAY;
8147 
8148  assert(tightened || SCIPisFeasGE(scip, SCIPvarGetLbGlobal(var), SCIPfeasFloor(scip, SCIPvarGetUbGlobal(var))));
8149  }
8150  }
8151 
8152  return SCIP_OKAY;
8153 }
8154 
8155 /** changes type of variable in the problem;
8156  *
8157  * @warning This type change might change the variable array returned from SCIPgetVars() and SCIPgetVarsData();
8158  *
8159  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8160  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8161  *
8162  * @pre This method can be called if @p scip is in one of the following stages:
8163  * - \ref SCIP_STAGE_PROBLEM
8164  * - \ref SCIP_STAGE_TRANSFORMING
8165  * - \ref SCIP_STAGE_PRESOLVING
8166  *
8167  * @note If SCIP is already beyond the SCIP_STAGE_PROBLEM and a original variable is passed, the variable type of the
8168  * corresponding transformed variable is changed; the type of the original variable does not change
8169  *
8170  * @note If the type changes from a continuous variable to a non-continuous variable the bounds of the variable get
8171  * adjusted w.r.t. to integrality information
8172  */
8174  SCIP* scip, /**< SCIP data structure */
8175  SCIP_VAR* var, /**< variable to change the bound for */
8176  SCIP_VARTYPE vartype, /**< new type of variable */
8177  SCIP_Bool* infeasible /**< pointer to store whether an infeasibility was detected (, due to
8178  * integrality condition of the new variable type) */
8179  )
8180 {
8181  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarType", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
8182 
8183  assert(var != NULL);
8184  assert(var->scip == scip);
8185 
8186  if( SCIPvarIsNegated(var) )
8187  {
8188  SCIPdebugMsg(scip, "upgrading type of negated variable <%s> from %d to %d\n", SCIPvarGetName(var), SCIPvarGetType(var), vartype);
8189  var = SCIPvarGetNegationVar(var);
8190  }
8191 #ifndef NDEBUG
8192  else
8193  {
8194  if( SCIPgetStage(scip) > SCIP_STAGE_PROBLEM )
8195  {
8196  SCIPdebugMsg(scip, "upgrading type of variable <%s> from %d to %d\n", SCIPvarGetName(var), SCIPvarGetType(var), vartype);
8197  }
8198  }
8199 #endif
8200 
8201  /* change variable type */
8202  switch( scip->set->stage )
8203  {
8204  case SCIP_STAGE_PROBLEM:
8205  assert(!SCIPvarIsTransformed(var));
8206 
8207  /* first adjust the variable due to new integrality information */
8208  SCIP_CALL( tightenBounds(scip, var, vartype, infeasible) );
8209 
8210  /* second change variable type */
8211  if( SCIPvarGetProbindex(var) >= 0 )
8212  {
8213  SCIP_CALL( SCIPprobChgVarType(scip->origprob, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8214  scip->branchcand, scip->eventqueue, scip->cliquetable, var, vartype) );
8215  }
8216  else
8217  {
8218  SCIP_CALL( SCIPvarChgType(var, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8219  scip->eventqueue, vartype) );
8220  }
8221  break;
8222 
8223  case SCIP_STAGE_PRESOLVING:
8224  if( !SCIPvarIsTransformed(var) )
8225  {
8226  SCIP_VAR* transvar;
8227 
8228  SCIP_CALL( SCIPgetTransformedVar(scip, var, &transvar) );
8229  assert(transvar != NULL);
8230 
8231  /* recall method with transformed variable */
8232  SCIP_CALL( SCIPchgVarType(scip, transvar, vartype, infeasible) );
8233  return SCIP_OKAY;
8234  }
8235 
8236  /* first adjust the variable due to new integrality information */
8237  SCIP_CALL( tightenBounds(scip, var, vartype, infeasible) );
8238 
8239  /* second change variable type */
8240  if( SCIPvarGetProbindex(var) >= 0 )
8241  {
8242  SCIP_CALL( SCIPprobChgVarType(scip->transprob, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8243  scip->branchcand, scip->eventqueue, scip->cliquetable, var, vartype) );
8244  }
8245  else
8246  {
8247  SCIP_CALL( SCIPvarChgType(var, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8248  scip->eventqueue, vartype) );
8249  }
8250  break;
8251 
8252  default:
8253  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
8254  return SCIP_INVALIDCALL;
8255  } /*lint !e788*/
8256 
8257  return SCIP_OKAY;
8258 }
8259 
8260 /** in problem creation and solving stage, both bounds of the variable are set to the given value;
8261  * in presolving stage, the variable is converted into a fixed variable, and bounds are changed respectively;
8262  * conversion into a fixed variable changes the vars array returned from SCIPgetVars() and SCIPgetVarsData(),
8263  * and also renders arrays returned from the SCIPvarGetImpl...() methods invalid
8264  *
8265  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8266  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8267  *
8268  * @pre This method can be called if @p scip is in one of the following stages:
8269  * - \ref SCIP_STAGE_PROBLEM
8270  * - \ref SCIP_STAGE_PRESOLVING
8271  * - \ref SCIP_STAGE_SOLVING
8272  */
8274  SCIP* scip, /**< SCIP data structure */
8275  SCIP_VAR* var, /**< variable to fix */
8276  SCIP_Real fixedval, /**< value to fix variable to */
8277  SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
8278  SCIP_Bool* fixed /**< pointer to store whether the fixing was performed (variable was unfixed) */
8279  )
8280 {
8281  assert(var != NULL);
8282  assert(infeasible != NULL);
8283  assert(fixed != NULL);
8284 
8285  SCIP_CALL( SCIPcheckStage(scip, "SCIPfixVar", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8286 
8287  *infeasible = FALSE;
8288  *fixed = FALSE;
8289 
8290  /* in the problem creation stage, modify the bounds as requested, independently from the current bounds */
8291  if( scip->set->stage != SCIP_STAGE_PROBLEM )
8292  {
8293  if( (SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPsetIsFeasIntegral(scip->set, fixedval))
8294  || SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetLbLocal(var))
8295  || SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8296  {
8297  *infeasible = TRUE;
8298  return SCIP_OKAY;
8299  }
8300  else if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED )
8301  {
8302  *infeasible = !SCIPsetIsFeasEQ(scip->set, fixedval, SCIPvarGetLbLocal(var));
8303  return SCIP_OKAY;
8304  }
8305  }
8306  else
8307  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_ORIGINAL);
8308 
8309  switch( scip->set->stage )
8310  {
8311  case SCIP_STAGE_PROBLEM:
8312  /* in the problem creation stage, modify the bounds as requested, independently from the current bounds;
8313  * we have to make sure, that the order of the bound changes does not intermediately produce an invalid
8314  * interval lb > ub
8315  */
8316  if( fixedval <= SCIPvarGetLbLocal(var) )
8317  {
8318  SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
8319  SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
8320  *fixed = TRUE;
8321  }
8322  else
8323  {
8324  SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
8325  SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
8326  *fixed = TRUE;
8327  }
8328  return SCIP_OKAY;
8329 
8330  case SCIP_STAGE_PRESOLVING:
8331  if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
8332  {
8333  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8334  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8335  scip->cliquetable, fixedval, infeasible, fixed) );
8336  return SCIP_OKAY;
8337  }
8338  /*lint -fallthrough*/
8339  case SCIP_STAGE_SOLVING:
8340  if( SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetLbLocal(var)) )
8341  {
8342  if( SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8343  {
8344  *infeasible = TRUE;
8345  return SCIP_OKAY;
8346  }
8347  else
8348  {
8349  SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
8350  *fixed = TRUE;
8351  }
8352  }
8353  if( SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8354  {
8355  if( SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetLbLocal(var)) )
8356  {
8357  *infeasible = TRUE;
8358  return SCIP_OKAY;
8359  }
8360  else
8361  {
8362  SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
8363  *fixed = TRUE;
8364  }
8365  }
8366  return SCIP_OKAY;
8367 
8368  default:
8369  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
8370  return SCIP_INVALIDCALL;
8371  } /*lint !e788*/
8372 }
8373 
8374 /** From a given equality a*x + b*y == c, aggregates one of the variables and removes it from the set of
8375  * active problem variables. This changes the vars array returned from SCIPgetVars() and SCIPgetVarsData(),
8376  * and also renders the arrays returned from the SCIPvarGetImpl...() methods for the two variables invalid.
8377  * In the first step, the equality is transformed into an equality with active problem variables
8378  * a'*x' + b'*y' == c'. If x' == y', this leads to the detection of redundancy if a' == -b' and c' == 0,
8379  * of infeasibility, if a' == -b' and c' != 0, or to a variable fixing x' == c'/(a'+b') (and possible
8380  * infeasibility) otherwise.
8381  * In the second step, the variable to be aggregated is chosen among x' and y', prefering a less strict variable
8382  * type as aggregation variable (i.e. continuous variables are preferred over implicit integers, implicit integers
8383  * over integers, and integers over binaries). If none of the variables is continuous, it is tried to find an integer
8384  * aggregation (i.e. integral coefficients a'' and b'', such that a''*x' + b''*y' == c''). This can lead to
8385  * the detection of infeasibility (e.g. if c'' is fractional), or to a rejection of the aggregation (denoted by
8386  * aggregated == FALSE), if the resulting integer coefficients are too large and thus numerically instable.
8387  *
8388  * The output flags have the following meaning:
8389  * - infeasible: the problem is infeasible
8390  * - redundant: the equality can be deleted from the constraint set
8391  * - aggregated: the aggregation was successfully performed (the variables were not aggregated before)
8392  *
8393  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8394  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8395  *
8396  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PRESOLVING
8397  */
8399  SCIP* scip, /**< SCIP data structure */
8400  SCIP_VAR* varx, /**< variable x in equality a*x + b*y == c */
8401  SCIP_VAR* vary, /**< variable y in equality a*x + b*y == c */
8402  SCIP_Real scalarx, /**< multiplier a in equality a*x + b*y == c */
8403  SCIP_Real scalary, /**< multiplier b in equality a*x + b*y == c */
8404  SCIP_Real rhs, /**< right hand side c in equality a*x + b*y == c */
8405  SCIP_Bool* infeasible, /**< pointer to store whether the aggregation is infeasible */
8406  SCIP_Bool* redundant, /**< pointer to store whether the equality is (now) redundant */
8407  SCIP_Bool* aggregated /**< pointer to store whether the aggregation was successful */
8408  )
8409 {
8410  SCIP_Real constantx;
8411  SCIP_Real constanty;
8412 
8413  assert(infeasible != NULL);
8414  assert(redundant != NULL);
8415  assert(aggregated != NULL);
8416 
8417  SCIP_CALL( SCIPcheckStage(scip, "SCIPaggregateVars", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
8418 
8419  *infeasible = FALSE;
8420  *redundant = FALSE;
8421  *aggregated = FALSE;
8422 
8423  if( SCIPtreeProbing(scip->tree) )
8424  {
8425  SCIPerrorMessage("cannot aggregate variables during probing\n");
8426  return SCIP_INVALIDCALL;
8427  }
8428  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
8429 
8430  /* do not perform aggregation if it is globally deactivated */
8431  if( scip->set->presol_donotaggr )
8432  return SCIP_OKAY;
8433 
8434  /* get the corresponding equality in active problem variable space:
8435  * transform both expressions "a*x + 0" and "b*y + 0" into problem variable space
8436  */
8437  constantx = 0.0;
8438  constanty = 0.0;
8439  SCIP_CALL( SCIPvarGetProbvarSum(&varx, scip->set, &scalarx, &constantx) );
8440  SCIP_CALL( SCIPvarGetProbvarSum(&vary, scip->set, &scalary, &constanty) );
8441 
8442  /* we cannot aggregate multi-aggregated variables */
8444  return SCIP_OKAY;
8445 
8446  /* move the constant to the right hand side to acquire the form "a'*x' + b'*y' == c'" */
8447  rhs -= (constantx + constanty);
8448 
8449  /* if a scalar is zero, treat the variable as fixed-to-zero variable */
8450  if( SCIPsetIsZero(scip->set, scalarx) )
8451  varx = NULL;
8452  if( SCIPsetIsZero(scip->set, scalary) )
8453  vary = NULL;
8454 
8455  /* capture the special cases that less than two variables are left, due to resolutions to a fixed variable or
8456  * to the same active variable
8457  */
8458  if( varx == NULL && vary == NULL )
8459  {
8460  /* both variables were resolved to fixed variables */
8461  *infeasible = !SCIPsetIsZero(scip->set, rhs);
8462  *redundant = TRUE;
8463  }
8464  else if( varx == NULL )
8465  {
8466  assert(SCIPsetIsZero(scip->set, scalarx));
8467  assert(!SCIPsetIsZero(scip->set, scalary));
8468 
8469  /* variable x was resolved to fixed variable: variable y can be fixed to c'/b' */
8470  SCIP_CALL( SCIPvarFix(vary, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8471  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8472  scip->cliquetable, rhs/scalary, infeasible, aggregated) );
8473  *redundant = TRUE;
8474  }
8475  else if( vary == NULL )
8476  {
8477  assert(SCIPsetIsZero(scip->set, scalary));
8478  assert(!SCIPsetIsZero(scip->set, scalarx));
8479 
8480  /* variable y was resolved to fixed variable: variable x can be fixed to c'/a' */
8481  SCIP_CALL( SCIPvarFix(varx, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8482  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8483  scip->cliquetable, rhs/scalarx, infeasible, aggregated) );
8484  *redundant = TRUE;
8485  }
8486  else if( varx == vary )
8487  {
8488  /* both variables were resolved to the same active problem variable: this variable can be fixed */
8489  scalarx += scalary;
8490  if( SCIPsetIsZero(scip->set, scalarx) )
8491  {
8492  /* left hand side of equality is zero: equality is potentially infeasible */
8493  *infeasible = !SCIPsetIsZero(scip->set, rhs);
8494  }
8495  else
8496  {
8497  /* sum of scalars is not zero: fix variable x' == y' to c'/(a'+b') */
8498  SCIP_CALL( SCIPvarFix(varx, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8499  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8500  scip->cliquetable, rhs/scalarx, infeasible, aggregated) );
8501  }
8502  *redundant = TRUE;
8503  }
8504  else
8505  {
8506  /* both variables are different active problem variables, and both scalars are non-zero: try to aggregate them */
8507  SCIP_CALL( SCIPvarTryAggregateVars(scip->set, scip->mem->probmem, scip->stat, scip->transprob, scip->origprob,
8508  scip->primal, scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventfilter,
8509  scip->eventqueue, varx, vary, scalarx, scalary, rhs, infeasible, aggregated) );
8510  *redundant = *aggregated;
8511  }
8512 
8513  return SCIP_OKAY;
8514 }
8515 
8516 /** converts variable into multi-aggregated variable; this changes the variable array returned from
8517  * SCIPgetVars() and SCIPgetVarsData();
8518  *
8519  * @warning The integrality condition is not checked anymore on the multi-aggregated variable. You must not
8520  * multi-aggregate an integer variable without being sure, that integrality on the aggregation variables
8521  * implies integrality on the aggregated variable.
8522  *
8523  * The output flags have the following meaning:
8524  * - infeasible: the problem is infeasible
8525  * - aggregated: the aggregation was successfully performed (the variables were not aggregated before)
8526  *
8527  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8528  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8529  *
8530  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PRESOLVING
8531  */
8533  SCIP* scip, /**< SCIP data structure */
8534  SCIP_VAR* var, /**< variable x to aggregate */
8535  int naggvars, /**< number n of variables in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8536  SCIP_VAR** aggvars, /**< variables y_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8537  SCIP_Real* scalars, /**< multipliers a_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8538  SCIP_Real constant, /**< constant shift c in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8539  SCIP_Bool* infeasible, /**< pointer to store whether the aggregation is infeasible */
8540  SCIP_Bool* aggregated /**< pointer to store whether the aggregation was successful */
8541  )
8542 {
8543  SCIP_CALL( SCIPcheckStage(scip, "SCIPmultiaggregateVar", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
8544 
8545  assert(var->scip == scip);
8546 
8547  if( SCIPtreeProbing(scip->tree) )
8548  {
8549  SCIPerrorMessage("cannot multi-aggregate variables during probing\n");
8550  return SCIP_INVALIDCALL;
8551  }
8552  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
8553 
8554  SCIP_CALL( SCIPvarMultiaggregate(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8555  scip->primal, scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventfilter,
8556  scip->eventqueue, naggvars, aggvars, scalars, constant, infeasible, aggregated) );
8557 
8558  return SCIP_OKAY;
8559 }
8560 
8561 /** returns whether aggregation of variables is not allowed */
8563  SCIP* scip /**< SCIP data structure */
8564  )
8565 {
8566  assert(scip != NULL);
8567 
8568  return scip->set->presol_donotaggr;
8569 }
8570 
8571 /** returns whether multi-aggregation is disabled */
8573  SCIP* scip /**< SCIP data structure */
8574  )
8575 {
8576  assert(scip != NULL);
8577 
8578  return scip->set->presol_donotmultaggr;
8579 }
8580 
8581 /** returns whether variable is not allowed to be aggregated */
8583  SCIP* scip, /**< SCIP data structure */
8584  SCIP_VAR* var /**< variable x to aggregate */
8585  )
8586 {
8587  assert(scip != NULL);
8588  assert(var != NULL);
8589  assert(var->scip == scip);
8590 
8591  return scip->set->presol_donotaggr || SCIPvarDoNotAggr(var);
8592 }
8593 
8594 /** returns whether variable is not allowed to be multi-aggregated */
8596  SCIP* scip, /**< SCIP data structure */
8597  SCIP_VAR* var /**< variable x to aggregate */
8598  )
8599 {
8600  assert(scip != NULL);
8601  assert(var != NULL);
8602  assert(var->scip == scip);
8603 
8604  return scip->set->presol_donotmultaggr || SCIPvarDoNotMultaggr(var);
8605 }
8606 
8607 /** returns whether dual reductions are allowed during propagation and presolving
8608  *
8609  * @deprecated Please use SCIPallowStrongDualReds()
8610  */
8612  SCIP* scip /**< SCIP data structure */
8613  )
8614 {
8615  assert(scip != NULL);
8616 
8617  return !scip->set->reopt_enable && scip->set->misc_allowstrongdualreds;
8618 }
8619 
8620 /** returns whether strong dual reductions are allowed during propagation and presolving
8621  *
8622  * @note A reduction is called strong dual, if it may discard feasible/optimal solutions, but leaves at least one
8623  * optimal solution intact. Often such reductions are based on analyzing the objective function and variable
8624  * locks.
8625  */
8627  SCIP* scip /**< SCIP data structure */
8628  )
8629 {
8630  assert(scip != NULL);
8631 
8632  return !scip->set->reopt_enable && scip->set->misc_allowstrongdualreds;
8633 }
8634 
8635 /** returns whether propagation w.r.t. current objective is allowed
8636  *
8637  * @deprecated Please use SCIPallowWeakDualReds()
8638  */
8640  SCIP* scip /**< SCIP data structure */
8641  )
8642 {
8643  assert(scip != NULL);
8644 
8645  return !scip->set->reopt_enable && scip->set->misc_allowweakdualreds;
8646 }
8647 
8648 /** returns whether weak dual reductions are allowed during propagation and presolving
8649  *
8650  * @note A reduction is called weak dual, if it may discard feasible solutions, but leaves at all optimal solutions
8651  * intact. Often such reductions are based on analyzing the objective function, reduced costs, and/or dual LPs.
8652  */
8654  SCIP* scip /**< SCIP data structure */
8655  )
8656 {
8657  assert(scip != NULL);
8658 
8659  return !scip->set->reopt_enable && scip->set->misc_allowweakdualreds;
8660 }
8661 
8662 /** marks the variable that it must not be aggregated
8663  *
8664  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8665  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8666  *
8667  * @pre This method can be called if @p scip is in one of the following stages:
8668  * - \ref SCIP_STAGE_INIT
8669  * - \ref SCIP_STAGE_PROBLEM
8670  * - \ref SCIP_STAGE_TRANSFORMING
8671  * - \ref SCIP_STAGE_TRANSFORMED
8672  * - \ref SCIP_STAGE_INITPRESOLVE
8673  * - \ref SCIP_STAGE_PRESOLVING
8674  * - \ref SCIP_STAGE_EXITPRESOLVE
8675  *
8676  * @note There exists no "unmark" method since it has to be ensured that if a plugin requires that a variable is not
8677  * aggregated that this is will be the case.
8678  */
8680  SCIP* scip, /**< SCIP data structure */
8681  SCIP_VAR* var /**< variable to delete */
8682  )
8683 {
8684  assert(scip != NULL);
8685  assert(var != NULL);
8686  assert(var->scip == scip);
8687 
8688  SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkDoNotAggrVar", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE) );
8689 
8691 
8692  return SCIP_OKAY;
8693 }
8694 
8695 /** marks the variable that it must not be multi-aggregated
8696  *
8697  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8698  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8699  *
8700  * @pre This method can be called if @p scip is in one of the following stages:
8701  * - \ref SCIP_STAGE_INIT
8702  * - \ref SCIP_STAGE_PROBLEM
8703  * - \ref SCIP_STAGE_TRANSFORMING
8704  * - \ref SCIP_STAGE_TRANSFORMED
8705  * - \ref SCIP_STAGE_INITPRESOLVE
8706  * - \ref SCIP_STAGE_PRESOLVING
8707  * - \ref SCIP_STAGE_EXITPRESOLVE
8708  *
8709  * @note There exists no "unmark" method since it has to be ensured that if a plugin requires that a variable is not
8710  * multi-aggregated that this is will be the case.
8711  */
8713  SCIP* scip, /**< SCIP data structure */
8714  SCIP_VAR* var /**< variable to delete */
8715  )
8716 {
8717  assert(scip != NULL);
8718  assert(var != NULL);
8719  assert(var->scip == scip);
8720 
8721  SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkDoNotMultaggrVar", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE) );
8722 
8724 
8725  return SCIP_OKAY;
8726 }
8727 
8728 /** enables the collection of statistics for a variable
8729  *
8730  * @pre This method can be called if @p scip is in one of the following stages:
8731  * - \ref SCIP_STAGE_PROBLEM
8732  * - \ref SCIP_STAGE_INITPRESOLVE
8733  * - \ref SCIP_STAGE_PRESOLVING
8734  * - \ref SCIP_STAGE_EXITPRESOLVE
8735  * - \ref SCIP_STAGE_SOLVING
8736  * - \ref SCIP_STAGE_SOLVED
8737  */
8739  SCIP* scip /**< SCIP data structure */
8740  )
8741 {
8742  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPenableVarHistory", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8743 
8745 }
8746 
8747 /** disables the collection of any statistic for a variable
8748  *
8749  * @pre This method can be called if @p scip is in one of the following stages:
8750  * - \ref SCIP_STAGE_PROBLEM
8751  * - \ref SCIP_STAGE_INITPRESOLVE
8752  * - \ref SCIP_STAGE_PRESOLVING
8753  * - \ref SCIP_STAGE_EXITPRESOLVE
8754  * - \ref SCIP_STAGE_SOLVING
8755  * - \ref SCIP_STAGE_SOLVED
8756  */
8758  SCIP* scip /**< SCIP data structure */
8759  )
8760 {
8761  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPdisableVarHistory", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8762 
8764 }
8765 
8766 /** updates the pseudo costs of the given variable and the global pseudo costs after a change of "solvaldelta" in the
8767  * variable's solution value and resulting change of "objdelta" in the in the LP's objective value;
8768  * the update is ignored, if the objective value difference is infinite
8769  *
8770  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8771  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8772  *
8773  * @pre This method can be called if @p scip is in one of the following stages:
8774  * - \ref SCIP_STAGE_SOLVING
8775  * - \ref SCIP_STAGE_SOLVED
8776  */
8778  SCIP* scip, /**< SCIP data structure */
8779  SCIP_VAR* var, /**< problem variable */
8780  SCIP_Real solvaldelta, /**< difference of variable's new LP value - old LP value */
8781  SCIP_Real objdelta, /**< difference of new LP's objective value - old LP's objective value */
8782  SCIP_Real weight /**< weight in (0,1] of this update in pseudo cost sum */
8783  )
8784 {
8785  SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateVarPseudocost", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8786 
8787  if( !SCIPsetIsInfinity(scip->set, 2*objdelta) ) /* differences infinity - eps should also be treated as infinity */
8788  {
8789  if( scip->set->branch_divingpscost || (!scip->lp->diving && !SCIPtreeProbing(scip->tree)) )
8790  {
8791  SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, solvaldelta, objdelta, weight) );
8792  }
8793  }
8794 
8795  return SCIP_OKAY;
8796 }
8797 
8798 /** gets the variable's pseudo cost value for the given change of the variable's LP value
8799  *
8800  * @return the variable's pseudo cost value for the given change of the variable's LP value
8801  *
8802  * @pre This method can be called if @p scip is in one of the following stages:
8803  * - \ref SCIP_STAGE_INITPRESOLVE
8804  * - \ref SCIP_STAGE_PRESOLVING
8805  * - \ref SCIP_STAGE_EXITPRESOLVE
8806  * - \ref SCIP_STAGE_PRESOLVED
8807  * - \ref SCIP_STAGE_INITSOLVE
8808  * - \ref SCIP_STAGE_SOLVING
8809  * - \ref SCIP_STAGE_SOLVED
8810  */
8812  SCIP* scip, /**< SCIP data structure */
8813  SCIP_VAR* var, /**< problem variable */
8814  SCIP_Real solvaldelta /**< difference of variable's new LP value - old LP value */
8815  )
8816 {
8817  assert( var->scip == scip );
8818 
8819  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostVal", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8820 
8821  return SCIPvarGetPseudocost(var, scip->stat, solvaldelta);
8822 }
8823 
8824 /** gets the variable's pseudo cost value for the given change of the variable's LP value,
8825  * only using the pseudo cost information of the current run
8826  *
8827  * @return the variable's pseudo cost value for the given change of the variable's LP value,
8828  * only using the pseudo cost information of the current run
8829  *
8830  * @pre This method can be called if @p scip is in one of the following stages:
8831  * - \ref SCIP_STAGE_INITPRESOLVE
8832  * - \ref SCIP_STAGE_PRESOLVING
8833  * - \ref SCIP_STAGE_EXITPRESOLVE
8834  * - \ref SCIP_STAGE_PRESOLVED
8835  * - \ref SCIP_STAGE_INITSOLVE
8836  * - \ref SCIP_STAGE_SOLVING
8837  * - \ref SCIP_STAGE_SOLVED
8838  */
8840  SCIP* scip, /**< SCIP data structure */
8841  SCIP_VAR* var, /**< problem variable */
8842  SCIP_Real solvaldelta /**< difference of variable's new LP value - old LP value */
8843  )
8844 {
8845  assert( var->scip == scip );
8846 
8847  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostValCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8848 
8849  return SCIPvarGetPseudocostCurrentRun(var, scip->stat, solvaldelta);
8850 }
8851 
8852 /** gets the variable's pseudo cost value for the given direction
8853  *
8854  * @return the variable's pseudo cost value for the given direction
8855  *
8856  * @pre This method can be called if @p scip is in one of the following stages:
8857  * - \ref SCIP_STAGE_INITPRESOLVE
8858  * - \ref SCIP_STAGE_PRESOLVING
8859  * - \ref SCIP_STAGE_EXITPRESOLVE
8860  * - \ref SCIP_STAGE_PRESOLVED
8861  * - \ref SCIP_STAGE_INITSOLVE
8862  * - \ref SCIP_STAGE_SOLVING
8863  * - \ref SCIP_STAGE_SOLVED
8864  */
8866  SCIP* scip, /**< SCIP data structure */
8867  SCIP_VAR* var, /**< problem variable */
8868  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8869  )
8870 {
8871  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocost", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8872  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8873  assert(var->scip == scip);
8874 
8875  return SCIPvarGetPseudocost(var, scip->stat, dir == SCIP_BRANCHDIR_DOWNWARDS ? -1.0 : 1.0);
8876 }
8877 
8878 /** gets the variable's pseudo cost value for the given direction,
8879  * only using the pseudo cost information of the current run
8880  *
8881  * @return the variable's pseudo cost value for the given direction,
8882  * only using the pseudo cost information of the current run
8883  *
8884  * @pre This method can be called if @p scip is in one of the following stages:
8885  * - \ref SCIP_STAGE_INITPRESOLVE
8886  * - \ref SCIP_STAGE_PRESOLVING
8887  * - \ref SCIP_STAGE_EXITPRESOLVE
8888  * - \ref SCIP_STAGE_PRESOLVED
8889  * - \ref SCIP_STAGE_INITSOLVE
8890  * - \ref SCIP_STAGE_SOLVING
8891  * - \ref SCIP_STAGE_SOLVED
8892  */
8894  SCIP* scip, /**< SCIP data structure */
8895  SCIP_VAR* var, /**< problem variable */
8896  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8897  )
8898 {
8899  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8900  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8901  assert(var->scip == scip);
8902 
8903  return SCIPvarGetPseudocostCurrentRun(var, scip->stat, dir == SCIP_BRANCHDIR_DOWNWARDS ? -1.0 : 1.0);
8904 }
8905 
8906 /** gets the variable's (possible fractional) number of pseudo cost updates for the given direction
8907  *
8908  * @return the variable's (possible fractional) number of pseudo cost updates for the given direction
8909  *
8910  * @pre This method can be called if @p scip is in one of the following stages:
8911  * - \ref SCIP_STAGE_INITPRESOLVE
8912  * - \ref SCIP_STAGE_PRESOLVING
8913  * - \ref SCIP_STAGE_EXITPRESOLVE
8914  * - \ref SCIP_STAGE_PRESOLVED
8915  * - \ref SCIP_STAGE_INITSOLVE
8916  * - \ref SCIP_STAGE_SOLVING
8917  * - \ref SCIP_STAGE_SOLVED
8918  */
8920  SCIP* scip, /**< SCIP data structure */
8921  SCIP_VAR* var, /**< problem variable */
8922  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8923  )
8924 {
8925  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCount", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8926  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8927  assert(var->scip == scip);
8928 
8929  return SCIPvarGetPseudocostCount(var, dir);
8930 }
8931 
8932 /** gets the variable's (possible fractional) number of pseudo cost updates for the given direction,
8933  * only using the pseudo cost information of the current run
8934  *
8935  * @return the variable's (possible fractional) number of pseudo cost updates for the given direction,
8936  * only using the pseudo cost information of the current run
8937  *
8938  * @pre This method can be called if @p scip is in one of the following stages:
8939  * - \ref SCIP_STAGE_INITPRESOLVE
8940  * - \ref SCIP_STAGE_PRESOLVING
8941  * - \ref SCIP_STAGE_EXITPRESOLVE
8942  * - \ref SCIP_STAGE_PRESOLVED
8943  * - \ref SCIP_STAGE_INITSOLVE
8944  * - \ref SCIP_STAGE_SOLVING
8945  * - \ref SCIP_STAGE_SOLVED
8946  */
8948  SCIP* scip, /**< SCIP data structure */
8949  SCIP_VAR* var, /**< problem variable */
8950  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8951  )
8952 {
8953  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCountCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8954  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8955  assert(var->scip == scip);
8956 
8957  return SCIPvarGetPseudocostCountCurrentRun(var, dir);
8958 }
8959 
8960 /** get pseudo cost variance of the variable, either for entire solve or only for current branch and bound run
8961  *
8962  * @return returns the (corrected) variance of pseudo code information collected so far.
8963  *
8964  * @pre This method can be called if @p scip is in one of the following stages:
8965  * - \ref SCIP_STAGE_INITPRESOLVE
8966  * - \ref SCIP_STAGE_PRESOLVING
8967  * - \ref SCIP_STAGE_EXITPRESOLVE
8968  * - \ref SCIP_STAGE_PRESOLVED
8969  * - \ref SCIP_STAGE_INITSOLVE
8970  * - \ref SCIP_STAGE_SOLVING
8971  * - \ref SCIP_STAGE_SOLVED
8972  */
8974  SCIP* scip, /**< SCIP data structure */
8975  SCIP_VAR* var, /**< problem variable */
8976  SCIP_BRANCHDIR dir, /**< branching direction (downwards, or upwards) */
8977  SCIP_Bool onlycurrentrun /**< only for pseudo costs of current branch and bound run */
8978  )
8979 {
8980  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostVariance", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8981  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8982  assert(var->scip == scip);
8983 
8984  return SCIPvarGetPseudocostVariance(var, dir, onlycurrentrun);
8985 }
8986 
8987 /** calculates a confidence bound for this variable under the assumption of normally distributed pseudo costs
8988  *
8989  * The confidence bound \f$ \theta \geq 0\f$ denotes the interval borders \f$ [X - \theta, \ X + \theta]\f$, which contains
8990  * the true pseudo costs of the variable, i.e., the expected value of the normal distribution, with a probability
8991  * of 2 * clevel - 1.
8992  *
8993  * @return value of confidence bound for this variable
8994  */
8996  SCIP* scip, /**< SCIP data structure */
8997  SCIP_VAR* var, /**< variable in question */
8998  SCIP_BRANCHDIR dir, /**< the branching direction for the confidence bound */
8999  SCIP_Bool onlycurrentrun, /**< should only the current run be taken into account */
9000  SCIP_CONFIDENCELEVEL clevel /**< confidence level for the interval */
9001  )
9002 {
9003  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPcalculatePscostConfidenceBound", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9004 
9005  return SCIPvarCalcPscostConfidenceBound(var, scip->set, dir, onlycurrentrun, clevel);
9006 }
9007 
9008 /** check if variable pseudo-costs have a significant difference in location. The significance depends on
9009  * the choice of \p clevel and on the kind of tested hypothesis. The one-sided hypothesis, which
9010  * should be rejected, is that fracy * mu_y >= fracx * mu_x, where mu_y and mu_x denote the
9011  * unknown location means of the underlying pseudo-cost distributions of x and y.
9012  *
9013  * This method is applied best if variable x has a better pseudo-cost score than y. The method hypothesizes that y were actually
9014  * better than x (despite the current information), meaning that y can be expected to yield branching
9015  * decisions as least as good as x in the long run. If the method returns TRUE, the current history information is
9016  * sufficient to safely rely on the alternative hypothesis that x yields indeed a better branching score (on average)
9017  * than y.
9018  *
9019  * @note The order of x and y matters for the one-sided hypothesis
9020  *
9021  * @note set \p onesided to FALSE if you are not sure which variable is better. The hypothesis tested then reads
9022  * fracy * mu_y == fracx * mu_x vs the alternative hypothesis fracy * mu_y != fracx * mu_x.
9023  *
9024  * @return TRUE if the hypothesis can be safely rejected at the given confidence level
9025  */
9027  SCIP* scip, /**< SCIP data structure */
9028  SCIP_VAR* varx, /**< variable x */
9029  SCIP_Real fracx, /**< the fractionality of variable x */
9030  SCIP_VAR* vary, /**< variable y */
9031  SCIP_Real fracy, /**< the fractionality of variable y */
9032  SCIP_BRANCHDIR dir, /**< branching direction */
9033  SCIP_CONFIDENCELEVEL clevel, /**< confidence level for rejecting hypothesis */
9034  SCIP_Bool onesided /**< should a one-sided hypothesis y >= x be tested? */
9035  )
9036 {
9037  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPsignificantVarPscostDifference", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9038 
9039  return SCIPvarSignificantPscostDifference(scip->set, scip->stat, varx, fracx, vary, fracy, dir, clevel, onesided);
9040 }
9041 
9042 /** tests at a given confidence level whether the variable pseudo-costs only have a small probability to
9043  * exceed a \p threshold. This is useful to determine if past observations provide enough evidence
9044  * to skip an expensive strong-branching step if there is already a candidate that has been proven to yield an improvement
9045  * of at least \p threshold.
9046  *
9047  * @note use \p clevel to adjust the level of confidence. For SCIP_CONFIDENCELEVEL_MIN, the method returns TRUE if
9048  * the estimated probability to exceed \p threshold is less than 25 %.
9049  *
9050  * @see SCIP_Confidencelevel for a list of available levels. The used probability limits refer to the one-sided levels
9051  * of confidence.
9052  *
9053  * @return TRUE if the variable pseudo-cost probabilistic model is likely to be smaller than \p threshold
9054  * at the given confidence level \p clevel.
9055  */
9057  SCIP* scip, /**< SCIP data structure */
9058  SCIP_VAR* var, /**< variable x */
9059  SCIP_Real frac, /**< the fractionality of variable x */
9060  SCIP_Real threshold, /**< the threshold to test against */
9061  SCIP_BRANCHDIR dir, /**< branching direction */
9062  SCIP_CONFIDENCELEVEL clevel /**< confidence level for rejecting hypothesis */
9063  )
9064 {
9065  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPpscostThresholdProbabilityTest", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9066 
9067  return SCIPvarPscostThresholdProbabilityTest(scip->set, scip->stat, var, frac, threshold, dir, clevel);
9068 }
9069 
9070 /** check if the current pseudo cost relative error in a direction violates the given threshold. The Relative
9071  * Error is calculated at a specific confidence level
9072  *
9073  * @return TRUE if relative error in variable pseudo costs is smaller than \p threshold
9074  */
9076  SCIP* scip, /**< SCIP data structure */
9077  SCIP_VAR* var, /**< variable in question */
9078  SCIP_Real threshold, /**< threshold for relative errors to be considered reliable (enough) */
9079  SCIP_CONFIDENCELEVEL clevel /**< a given confidence level */
9080  )
9081 {
9082  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisVarPscostRelerrorReliable", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9083 
9084  return SCIPvarIsPscostRelerrorReliable(var, scip->set, scip->stat, threshold, clevel);
9085 }
9086 
9087 /** gets the variable's pseudo cost score value for the given LP solution value
9088  *
9089  * @return the variable's pseudo cost score value for the given LP solution value
9090  *
9091  * @pre This method can be called if @p scip is in one of the following stages:
9092  * - \ref SCIP_STAGE_INITPRESOLVE
9093  * - \ref SCIP_STAGE_PRESOLVING
9094  * - \ref SCIP_STAGE_EXITPRESOLVE
9095  * - \ref SCIP_STAGE_PRESOLVED
9096  * - \ref SCIP_STAGE_INITSOLVE
9097  * - \ref SCIP_STAGE_SOLVING
9098  * - \ref SCIP_STAGE_SOLVED
9099  */
9101  SCIP* scip, /**< SCIP data structure */
9102  SCIP_VAR* var, /**< problem variable */
9103  SCIP_Real solval /**< variable's LP solution value */
9104  )
9105 {
9106  SCIP_Real downsol;
9107  SCIP_Real upsol;
9108  SCIP_Real pscostdown;
9109  SCIP_Real pscostup;
9110 
9111  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9112 
9113  assert( var->scip == scip );
9114 
9115  downsol = SCIPsetFeasCeil(scip->set, solval-1.0);
9116  upsol = SCIPsetFeasFloor(scip->set, solval+1.0);
9117  pscostdown = SCIPvarGetPseudocost(var, scip->stat, downsol-solval);
9118  pscostup = SCIPvarGetPseudocost(var, scip->stat, upsol-solval);
9119 
9120  return SCIPbranchGetScore(scip->set, var, pscostdown, pscostup);
9121 }
9122 
9123 /** gets the variable's pseudo cost score value for the given LP solution value,
9124  * only using the pseudo cost information of the current run
9125  *
9126  * @return the variable's pseudo cost score value for the given LP solution value,
9127  * only using the pseudo cost information of the current run
9128  *
9129  * @pre This method can be called if @p scip is in one of the following stages:
9130  * - \ref SCIP_STAGE_INITPRESOLVE
9131  * - \ref SCIP_STAGE_PRESOLVING
9132  * - \ref SCIP_STAGE_EXITPRESOLVE
9133  * - \ref SCIP_STAGE_PRESOLVED
9134  * - \ref SCIP_STAGE_INITSOLVE
9135  * - \ref SCIP_STAGE_SOLVING
9136  * - \ref SCIP_STAGE_SOLVED
9137  */
9139  SCIP* scip, /**< SCIP data structure */
9140  SCIP_VAR* var, /**< problem variable */
9141  SCIP_Real solval /**< variable's LP solution value */
9142  )
9143 {
9144  SCIP_Real downsol;
9145  SCIP_Real upsol;
9146  SCIP_Real pscostdown;
9147  SCIP_Real pscostup;
9148 
9149  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9150 
9151  assert( var->scip == scip );
9152 
9153  downsol = SCIPsetFeasCeil(scip->set, solval-1.0);
9154  upsol = SCIPsetFeasFloor(scip->set, solval+1.0);
9155  pscostdown = SCIPvarGetPseudocostCurrentRun(var, scip->stat, downsol-solval);
9156  pscostup = SCIPvarGetPseudocostCurrentRun(var, scip->stat, upsol-solval);
9157 
9158  return SCIPbranchGetScore(scip->set, var, pscostdown, pscostup);
9159 }
9160 
9161 /** returns the variable's VSIDS value
9162  *
9163  * @return the variable's VSIDS value
9164  *
9165  * @pre This method can be called if @p scip is in one of the following stages:
9166  * - \ref SCIP_STAGE_INITPRESOLVE
9167  * - \ref SCIP_STAGE_PRESOLVING
9168  * - \ref SCIP_STAGE_EXITPRESOLVE
9169  * - \ref SCIP_STAGE_PRESOLVED
9170  * - \ref SCIP_STAGE_INITSOLVE
9171  * - \ref SCIP_STAGE_SOLVING
9172  * - \ref SCIP_STAGE_SOLVED
9173  */
9175  SCIP* scip, /**< SCIP data structure */
9176  SCIP_VAR* var, /**< problem variable */
9177  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9178  )
9179 {
9180  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarVSIDS", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9181 
9182  assert( var->scip == scip );
9183 
9184  if( dir != SCIP_BRANCHDIR_DOWNWARDS && dir != SCIP_BRANCHDIR_UPWARDS )
9185  {
9186  SCIPerrorMessage("invalid branching direction %d when asking for VSIDS value\n", dir);
9187  return SCIP_INVALID;
9188  }
9189 
9190  return SCIPvarGetVSIDS(var, scip->stat, dir);
9191 }
9192 
9193 /** returns the variable's VSIDS value only using conflicts of the current run
9194  *
9195  * @return the variable's VSIDS value only using conflicts of the current run
9196  *
9197  * @pre This method can be called if @p scip is in one of the following stages:
9198  * - \ref SCIP_STAGE_INITPRESOLVE
9199  * - \ref SCIP_STAGE_PRESOLVING
9200  * - \ref SCIP_STAGE_EXITPRESOLVE
9201  * - \ref SCIP_STAGE_PRESOLVED
9202  * - \ref SCIP_STAGE_INITSOLVE
9203  * - \ref SCIP_STAGE_SOLVING
9204  * - \ref SCIP_STAGE_SOLVED
9205  */
9207  SCIP* scip, /**< SCIP data structure */
9208  SCIP_VAR* var, /**< problem variable */
9209  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9210  )
9211 {
9212  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarVSIDSCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9213 
9214  assert( var->scip == scip );
9215 
9216  if( dir != SCIP_BRANCHDIR_DOWNWARDS && dir != SCIP_BRANCHDIR_UPWARDS )
9217  {
9218  SCIPerrorMessage("invalid branching direction %d when asking for VSIDS value\n", dir);
9219  return SCIP_INVALID;
9220  }
9221 
9222  return SCIPvarGetVSIDSCurrentRun(var, scip->stat, dir);
9223 }
9224 
9225 /** returns the variable's conflict score value
9226  *
9227  * @return the variable's conflict score value
9228  *
9229  * @pre This method can be called if @p scip is in one of the following stages:
9230  * - \ref SCIP_STAGE_INITPRESOLVE
9231  * - \ref SCIP_STAGE_PRESOLVING
9232  * - \ref SCIP_STAGE_EXITPRESOLVE
9233  * - \ref SCIP_STAGE_PRESOLVED
9234  * - \ref SCIP_STAGE_INITSOLVE
9235  * - \ref SCIP_STAGE_SOLVING
9236  * - \ref SCIP_STAGE_SOLVED
9237  */
9239  SCIP* scip, /**< SCIP data structure */
9240  SCIP_VAR* var /**< problem variable */
9241  )
9242 {
9243  SCIP_Real downscore;
9244  SCIP_Real upscore;
9245 
9246  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9247 
9248  assert( var->scip == scip );
9249 
9250  downscore = SCIPvarGetVSIDS(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9251  upscore = SCIPvarGetVSIDS(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9252 
9253  return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9254 }
9255 
9256 /** returns the variable's conflict score value only using conflicts of the current run
9257  *
9258  * @return the variable's conflict score value only using conflicts of the current run
9259  *
9260  * @pre This method can be called if @p scip is in one of the following stages:
9261  * - \ref SCIP_STAGE_INITPRESOLVE
9262  * - \ref SCIP_STAGE_PRESOLVING
9263  * - \ref SCIP_STAGE_EXITPRESOLVE
9264  * - \ref SCIP_STAGE_PRESOLVED
9265  * - \ref SCIP_STAGE_INITSOLVE
9266  * - \ref SCIP_STAGE_SOLVING
9267  * - \ref SCIP_STAGE_SOLVED
9268  */
9270  SCIP* scip, /**< SCIP data structure */
9271  SCIP_VAR* var /**< problem variable */
9272  )
9273 {
9274  SCIP_Real downscore;
9275  SCIP_Real upscore;
9276 
9277  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9278 
9279  assert( var->scip == scip );
9280 
9281  downscore = SCIPvarGetVSIDSCurrentRun(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9282  upscore = SCIPvarGetVSIDSCurrentRun(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9283 
9284  return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9285 }
9286 
9287 /** returns the variable's conflict length score
9288  *
9289  * @return the variable's conflict length score
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  )
9304 {
9305  SCIP_Real downscore;
9306  SCIP_Real upscore;
9307 
9308  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictlengthScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9309 
9310  assert( var->scip == scip );
9311 
9314 
9315  return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9316 }
9317 
9318 /** returns the variable's conflict length score only using conflicts of the current run
9319  *
9320  * @return the variable's conflict length score only using conflicts of the current run
9321  *
9322  * @pre This method can be called if @p scip is in one of the following stages:
9323  * - \ref SCIP_STAGE_INITPRESOLVE
9324  * - \ref SCIP_STAGE_PRESOLVING
9325  * - \ref SCIP_STAGE_EXITPRESOLVE
9326  * - \ref SCIP_STAGE_PRESOLVED
9327  * - \ref SCIP_STAGE_INITSOLVE
9328  * - \ref SCIP_STAGE_SOLVING
9329  * - \ref SCIP_STAGE_SOLVED
9330  */
9332  SCIP* scip, /**< SCIP data structure */
9333  SCIP_VAR* var /**< problem variable */
9334  )
9335 {
9336  SCIP_Real downscore;
9337  SCIP_Real upscore;
9338 
9339  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictlengthScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9340 
9341  assert( var->scip == scip );
9342 
9345 
9346  return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9347 }
9348 
9349 /** returns the variable's average conflict length
9350  *
9351  * @return the variable's average conflict length
9352  *
9353  * @pre This method can be called if @p scip is in one of the following stages:
9354  * - \ref SCIP_STAGE_INITPRESOLVE
9355  * - \ref SCIP_STAGE_PRESOLVING
9356  * - \ref SCIP_STAGE_EXITPRESOLVE
9357  * - \ref SCIP_STAGE_PRESOLVED
9358  * - \ref SCIP_STAGE_INITSOLVE
9359  * - \ref SCIP_STAGE_SOLVING
9360  * - \ref SCIP_STAGE_SOLVED
9361  */
9363  SCIP* scip, /**< SCIP data structure */
9364  SCIP_VAR* var, /**< problem variable */
9365  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9366  )
9367 {
9368  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgConflictlength", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9369 
9370  assert( var->scip == scip );
9371 
9372  return SCIPvarGetAvgConflictlength(var, dir);
9373 }
9374 
9375 /** returns the variable's average conflict length only using conflicts of the current run
9376  *
9377  * @return the variable's average conflict length only using conflicts of the current run
9378  *
9379  * @pre This method can be called if @p scip is in one of the following stages:
9380  * - \ref SCIP_STAGE_INITPRESOLVE
9381  * - \ref SCIP_STAGE_PRESOLVING
9382  * - \ref SCIP_STAGE_EXITPRESOLVE
9383  * - \ref SCIP_STAGE_PRESOLVED
9384  * - \ref SCIP_STAGE_INITSOLVE
9385  * - \ref SCIP_STAGE_SOLVING
9386  * - \ref SCIP_STAGE_SOLVED
9387  */
9389  SCIP* scip, /**< SCIP data structure */
9390  SCIP_VAR* var, /**< problem variable */
9391  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9392  )
9393 {
9394  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgConflictlengthCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9395 
9396  assert( var->scip == scip );
9397 
9398  return SCIPvarGetAvgConflictlengthCurrentRun(var, dir);
9399 }
9400 
9401 /** returns the average number of inferences found after branching on the variable in given direction;
9402  * if branching on the variable in the given direction was yet evaluated, the average number of inferences
9403  * over all variables for branching in the given direction is returned
9404  *
9405  * @return the average number of inferences found after branching on the variable in given direction
9406  *
9407  * @pre This method can be called if @p scip is in one of the following stages:
9408  * - \ref SCIP_STAGE_INITPRESOLVE
9409  * - \ref SCIP_STAGE_PRESOLVING
9410  * - \ref SCIP_STAGE_EXITPRESOLVE
9411  * - \ref SCIP_STAGE_PRESOLVED
9412  * - \ref SCIP_STAGE_INITSOLVE
9413  * - \ref SCIP_STAGE_SOLVING
9414  * - \ref SCIP_STAGE_SOLVED
9415  */
9417  SCIP* scip, /**< SCIP data structure */
9418  SCIP_VAR* var, /**< problem variable */
9419  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9420  )
9421 {
9422  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferences", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9423 
9424  assert( var->scip == scip );
9425 
9426  return SCIPvarGetAvgInferences(var, scip->stat, dir);
9427 }
9428 
9429 /** returns the average number of inferences found after branching on the variable in given direction in the current run;
9430  * if branching on the variable in the given direction was yet evaluated, the average number of inferences
9431  * over all variables for branching in the given direction is returned
9432  *
9433  * @return the average number of inferences found after branching on the variable in given direction in the current run
9434  *
9435  * @pre This method can be called if @p scip is in one of the following stages:
9436  * - \ref SCIP_STAGE_INITPRESOLVE
9437  * - \ref SCIP_STAGE_PRESOLVING
9438  * - \ref SCIP_STAGE_EXITPRESOLVE
9439  * - \ref SCIP_STAGE_PRESOLVED
9440  * - \ref SCIP_STAGE_INITSOLVE
9441  * - \ref SCIP_STAGE_SOLVING
9442  * - \ref SCIP_STAGE_SOLVED
9443  */
9445  SCIP* scip, /**< SCIP data structure */
9446  SCIP_VAR* var, /**< problem variable */
9447  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9448  )
9449 {
9450  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferencesCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9451 
9452  assert( var->scip == scip );
9453 
9454  return SCIPvarGetAvgInferencesCurrentRun(var, scip->stat, dir);
9455 }
9456 
9457 /** returns the variable's average inference score value
9458  *
9459  * @return the variable's average inference score value
9460  *
9461  * @pre This method can be called if @p scip is in one of the following stages:
9462  * - \ref SCIP_STAGE_INITPRESOLVE
9463  * - \ref SCIP_STAGE_PRESOLVING
9464  * - \ref SCIP_STAGE_EXITPRESOLVE
9465  * - \ref SCIP_STAGE_PRESOLVED
9466  * - \ref SCIP_STAGE_INITSOLVE
9467  * - \ref SCIP_STAGE_SOLVING
9468  * - \ref SCIP_STAGE_SOLVED
9469  */
9471  SCIP* scip, /**< SCIP data structure */
9472  SCIP_VAR* var /**< problem variable */
9473  )
9474 {
9475  SCIP_Real inferdown;
9476  SCIP_Real inferup;
9477 
9478  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9479 
9480  assert( var->scip == scip );
9481 
9482  inferdown = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9483  inferup = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9484 
9485  return SCIPbranchGetScore(scip->set, var, inferdown, inferup);
9486 }
9487 
9488 /** returns the variable's average inference score value only using inferences of the current run
9489  *
9490  * @return the variable's average inference score value only using inferences of the current run
9491  *
9492  * @pre This method can be called if @p scip is in one of the following stages:
9493  * - \ref SCIP_STAGE_INITPRESOLVE
9494  * - \ref SCIP_STAGE_PRESOLVING
9495  * - \ref SCIP_STAGE_EXITPRESOLVE
9496  * - \ref SCIP_STAGE_PRESOLVED
9497  * - \ref SCIP_STAGE_INITSOLVE
9498  * - \ref SCIP_STAGE_SOLVING
9499  * - \ref SCIP_STAGE_SOLVED
9500  */
9502  SCIP* scip, /**< SCIP data structure */
9503  SCIP_VAR* var /**< problem variable */
9504  )
9505 {
9506  SCIP_Real inferdown;
9507  SCIP_Real inferup;
9508 
9509  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9510 
9511  assert( var->scip == scip );
9512 
9515 
9516  return SCIPbranchGetScore(scip->set, var, inferdown, inferup);
9517 }
9518 
9519 /** initializes the upwards and downwards pseudocosts, conflict scores, conflict lengths, inference scores, cutoff scores
9520  * of a variable to the given values
9521  *
9522  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9523  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9524  *
9525  * @pre This method can be called if @p scip is in one of the following stages:
9526  * - \ref SCIP_STAGE_TRANSFORMED
9527  * - \ref SCIP_STAGE_INITPRESOLVE
9528  * - \ref SCIP_STAGE_PRESOLVING
9529  * - \ref SCIP_STAGE_EXITPRESOLVE
9530  * - \ref SCIP_STAGE_PRESOLVED
9531  * - \ref SCIP_STAGE_INITSOLVE
9532  * - \ref SCIP_STAGE_SOLVING
9533  */
9535  SCIP* scip, /**< SCIP data structure */
9536  SCIP_VAR* var, /**< variable which should be initialized */
9537  SCIP_Real downpscost, /**< value to which pseudocosts for downwards branching should be initialized */
9538  SCIP_Real uppscost, /**< value to which pseudocosts for upwards branching should be initialized */
9539  SCIP_Real downvsids, /**< value to which VSIDS score for downwards branching should be initialized */
9540  SCIP_Real upvsids, /**< value to which VSIDS score for upwards branching should be initialized */
9541  SCIP_Real downconflen, /**< value to which conflict length score for downwards branching should be initialized */
9542  SCIP_Real upconflen, /**< value to which conflict length score for upwards branching should be initialized */
9543  SCIP_Real downinfer, /**< value to which inference counter for downwards branching should be initialized */
9544  SCIP_Real upinfer, /**< value to which inference counter for upwards branching should be initialized */
9545  SCIP_Real downcutoff, /**< value to which cutoff counter for downwards branching should be initialized */
9546  SCIP_Real upcutoff /**< value to which cutoff counter for upwards branching should be initialized */
9547  )
9548 {
9549  SCIP_CALL( SCIPcheckStage(scip, "SCIPinitVarBranchStats", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
9550 
9551  assert(downpscost >= 0.0 && uppscost >= 0.0);
9552  assert(downvsids >= 0.0 && upvsids >= 0.0);
9553  assert(downconflen >= 0.0 && upconflen >= 0.0);
9554  assert(downinfer >= 0.0 && upinfer >= 0.0);
9555  assert(downcutoff >= 0.0 && upcutoff >= 0.0);
9556 
9557  if( !SCIPisFeasZero(scip, downpscost) || !SCIPisFeasZero(scip, downvsids)
9558  || !SCIPisFeasZero(scip, downinfer) || !SCIPisFeasZero(scip, downcutoff) )
9559  {
9561  SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, -1.0, downpscost, 1.0) );
9563  SCIP_CALL( SCIPvarIncVSIDS(var, NULL, scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, SCIP_UNKNOWN, downvsids) );
9565  }
9566 
9567  if( !SCIPisFeasZero(scip, downconflen) )
9568  {
9570  }
9571 
9572  if( !SCIPisFeasZero(scip, uppscost) || !SCIPisFeasZero(scip, upvsids)
9573  || !SCIPisFeasZero(scip, upinfer) || !SCIPisFeasZero(scip, upcutoff) )
9574  {
9576  SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, 1.0, uppscost, 1.0) );
9578  SCIP_CALL( SCIPvarIncVSIDS(var, NULL, scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, SCIP_UNKNOWN, upvsids) );
9580  }
9581 
9582  if( !SCIPisFeasZero(scip, upconflen) )
9583  {
9585  }
9586 
9587  return SCIP_OKAY;
9588 }
9589 
9590 /** initializes the upwards and downwards conflict scores, conflict lengths, inference scores, cutoff scores of a
9591  * variable w.r.t. a value by the given values (SCIP_VALUEHISTORY)
9592  *
9593  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9594  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9595  *
9596  * @pre This method can be called if @p scip is in one of the following stages:
9597  * - \ref SCIP_STAGE_TRANSFORMED
9598  * - \ref SCIP_STAGE_INITPRESOLVE
9599  * - \ref SCIP_STAGE_PRESOLVING
9600  * - \ref SCIP_STAGE_EXITPRESOLVE
9601  * - \ref SCIP_STAGE_PRESOLVED
9602  * - \ref SCIP_STAGE_INITSOLVE
9603  * - \ref SCIP_STAGE_SOLVING
9604  */
9606  SCIP* scip, /**< SCIP data structure */
9607  SCIP_VAR* var, /**< variable which should be initialized */
9608  SCIP_Real value, /**< domain value, or SCIP_UNKNOWN */
9609  SCIP_Real downvsids, /**< value to which VSIDS score for downwards branching should be initialized */
9610  SCIP_Real upvsids, /**< value to which VSIDS score for upwards branching should be initialized */
9611  SCIP_Real downconflen, /**< value to which conflict length score for downwards branching should be initialized */
9612  SCIP_Real upconflen, /**< value to which conflict length score for upwards branching should be initialized */
9613  SCIP_Real downinfer, /**< value to which inference counter for downwards branching should be initialized */
9614  SCIP_Real upinfer, /**< value to which inference counter for upwards branching should be initialized */
9615  SCIP_Real downcutoff, /**< value to which cutoff counter for downwards branching should be initialized */
9616  SCIP_Real upcutoff /**< value to which cutoff counter for upwards branching should be initialized */
9617  )
9618 {
9619  SCIP_CALL( SCIPcheckStage(scip, "SCIPinitVarValueBranchStats", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
9620 
9621  assert(downvsids >= 0.0 && upvsids >= 0.0);
9622  assert(downconflen >= 0.0 && upconflen >= 0.0);
9623  assert(downinfer >= 0.0 && upinfer >= 0.0);
9624  assert(downcutoff >= 0.0 && upcutoff >= 0.0);
9625 
9626  if( !SCIPisFeasZero(scip, downvsids) || !SCIPisFeasZero(scip, downinfer) || !SCIPisFeasZero(scip, downcutoff) )
9627  {
9628  SCIP_CALL( SCIPvarIncNBranchings(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, 1) );
9629  SCIP_CALL( SCIPvarIncInferenceSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downinfer) );
9630  SCIP_CALL( SCIPvarIncVSIDS(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downvsids) );
9631  SCIP_CALL( SCIPvarIncCutoffSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downcutoff) );
9632  }
9633 
9634  if( !SCIPisFeasZero(scip, downconflen) )
9635  {
9636  SCIP_CALL( SCIPvarIncNActiveConflicts(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downconflen) );
9637  }
9638 
9639  if( !SCIPisFeasZero(scip, upvsids) || !SCIPisFeasZero(scip, upinfer) || !SCIPisFeasZero(scip, upcutoff) )
9640  {
9641  SCIP_CALL( SCIPvarIncNBranchings(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, 1) );
9642  SCIP_CALL( SCIPvarIncInferenceSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upinfer) );
9643  SCIP_CALL( SCIPvarIncVSIDS(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upvsids) );
9644  SCIP_CALL( SCIPvarIncCutoffSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upcutoff) );
9645  }
9646 
9647  if( !SCIPisFeasZero(scip, upconflen) )
9648  {
9649  SCIP_CALL( SCIPvarIncNActiveConflicts(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upconflen) );
9650  }
9651 
9652  return SCIP_OKAY;
9653 }
9654 
9655 /** returns the average number of cutoffs found after branching on the variable in given direction;
9656  * if branching on the variable in the given direction was yet evaluated, the average number of cutoffs
9657  * over all variables for branching in the given direction is returned
9658  *
9659  * @return the average number of cutoffs found after branching on the variable in given direction
9660  *
9661  * @pre This method can be called if @p scip is in one of the following stages:
9662  * - \ref SCIP_STAGE_INITPRESOLVE
9663  * - \ref SCIP_STAGE_PRESOLVING
9664  * - \ref SCIP_STAGE_EXITPRESOLVE
9665  * - \ref SCIP_STAGE_PRESOLVED
9666  * - \ref SCIP_STAGE_INITSOLVE
9667  * - \ref SCIP_STAGE_SOLVING
9668  * - \ref SCIP_STAGE_SOLVED
9669  */
9671  SCIP* scip, /**< SCIP data structure */
9672  SCIP_VAR* var, /**< problem variable */
9673  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9674  )
9675 {
9676  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffs", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9677 
9678  assert( var->scip == scip );
9679 
9680  return SCIPvarGetAvgCutoffs(var, scip->stat, dir);
9681 }
9682 
9683 /** returns the average number of cutoffs found after branching on the variable in given direction in the current run;
9684  * if branching on the variable in the given direction was yet evaluated, the average number of cutoffs
9685  * over all variables for branching in the given direction is returned
9686  *
9687  * @return the average number of cutoffs found after branching on the variable in given direction in the current run
9688  *
9689  * @pre This method can be called if @p scip is in one of the following stages:
9690  * - \ref SCIP_STAGE_INITPRESOLVE
9691  * - \ref SCIP_STAGE_PRESOLVING
9692  * - \ref SCIP_STAGE_EXITPRESOLVE
9693  * - \ref SCIP_STAGE_PRESOLVED
9694  * - \ref SCIP_STAGE_INITSOLVE
9695  * - \ref SCIP_STAGE_SOLVING
9696  * - \ref SCIP_STAGE_SOLVED
9697  */
9699  SCIP* scip, /**< SCIP data structure */
9700  SCIP_VAR* var, /**< problem variable */
9701  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9702  )
9703 {
9704  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffsCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9705 
9706  assert( var->scip == scip );
9707 
9708  return SCIPvarGetAvgCutoffsCurrentRun(var, scip->stat, dir);
9709 }
9710 
9711 /** returns the variable's average cutoff score value
9712  *
9713  * @return the variable's average cutoff score value
9714  *
9715  * @pre This method can be called if @p scip is in one of the following stages:
9716  * - \ref SCIP_STAGE_INITPRESOLVE
9717  * - \ref SCIP_STAGE_PRESOLVING
9718  * - \ref SCIP_STAGE_EXITPRESOLVE
9719  * - \ref SCIP_STAGE_PRESOLVED
9720  * - \ref SCIP_STAGE_INITSOLVE
9721  * - \ref SCIP_STAGE_SOLVING
9722  * - \ref SCIP_STAGE_SOLVED
9723  */
9725  SCIP* scip, /**< SCIP data structure */
9726  SCIP_VAR* var /**< problem variable */
9727  )
9728 {
9729  SCIP_Real cutoffdown;
9730  SCIP_Real cutoffup;
9731 
9732  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9733 
9734  assert( var->scip == scip );
9735 
9736  cutoffdown = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9737  cutoffup = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9738 
9739  return SCIPbranchGetScore(scip->set, var, cutoffdown, cutoffup);
9740 }
9741 
9742 /** returns the variable's average cutoff score value, only using cutoffs of the current run
9743  *
9744  * @return the variable's average cutoff score value, only using cutoffs of the current run
9745  *
9746  * @pre This method can be called if @p scip is in one of the following stages:
9747  * - \ref SCIP_STAGE_INITPRESOLVE
9748  * - \ref SCIP_STAGE_PRESOLVING
9749  * - \ref SCIP_STAGE_EXITPRESOLVE
9750  * - \ref SCIP_STAGE_PRESOLVED
9751  * - \ref SCIP_STAGE_INITSOLVE
9752  * - \ref SCIP_STAGE_SOLVING
9753  * - \ref SCIP_STAGE_SOLVED
9754  */
9756  SCIP* scip, /**< SCIP data structure */
9757  SCIP_VAR* var /**< problem variable */
9758  )
9759 {
9760  SCIP_Real cutoffdown;
9761  SCIP_Real cutoffup;
9762 
9763  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9764 
9765  assert( var->scip == scip );
9766 
9769 
9770  return SCIPbranchGetScore(scip->set, var, cutoffdown, cutoffup);
9771 }
9772 
9773 /** returns the variable's average inference/cutoff score value, weighting the cutoffs of the variable with the given
9774  * factor
9775  *
9776  * @return the variable's average inference/cutoff score value
9777  *
9778  * @pre This method can be called if @p scip is in one of the following stages:
9779  * - \ref SCIP_STAGE_INITPRESOLVE
9780  * - \ref SCIP_STAGE_PRESOLVING
9781  * - \ref SCIP_STAGE_EXITPRESOLVE
9782  * - \ref SCIP_STAGE_PRESOLVED
9783  * - \ref SCIP_STAGE_INITSOLVE
9784  * - \ref SCIP_STAGE_SOLVING
9785  * - \ref SCIP_STAGE_SOLVED
9786  */
9788  SCIP* scip, /**< SCIP data structure */
9789  SCIP_VAR* var, /**< problem variable */
9790  SCIP_Real cutoffweight /**< factor to weigh average number of cutoffs in branching score */
9791  )
9792 {
9793  SCIP_Real avginferdown;
9794  SCIP_Real avginferup;
9795  SCIP_Real avginfer;
9796  SCIP_Real inferdown;
9797  SCIP_Real inferup;
9798  SCIP_Real cutoffdown;
9799  SCIP_Real cutoffup;
9800 
9801  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceCutoffScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9802 
9803  assert( var->scip == scip );
9804 
9807  avginfer = (avginferdown + avginferup)/2.0;
9808  inferdown = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9809  inferup = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9810  cutoffdown = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9811  cutoffup = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9812 
9813  return SCIPbranchGetScore(scip->set, var,
9814  inferdown + cutoffweight * avginfer * cutoffdown, inferup + cutoffweight * avginfer * cutoffup);
9815 }
9816 
9817 /** returns the variable's average inference/cutoff score value, weighting the cutoffs of the variable with the given
9818  * factor, only using inferences and cutoffs of the current run
9819  *
9820  * @return the variable's average inference/cutoff score value, only using inferences and cutoffs of the current run
9821  *
9822  * @pre This method can be called if @p scip is in one of the following stages:
9823  * - \ref SCIP_STAGE_INITPRESOLVE
9824  * - \ref SCIP_STAGE_PRESOLVING
9825  * - \ref SCIP_STAGE_EXITPRESOLVE
9826  * - \ref SCIP_STAGE_PRESOLVED
9827  * - \ref SCIP_STAGE_INITSOLVE
9828  * - \ref SCIP_STAGE_SOLVING
9829  * - \ref SCIP_STAGE_SOLVED
9830  */
9832  SCIP* scip, /**< SCIP data structure */
9833  SCIP_VAR* var, /**< problem variable */
9834  SCIP_Real cutoffweight /**< factor to weigh average number of cutoffs in branching score */
9835  )
9836 {
9837  SCIP_Real avginferdown;
9838  SCIP_Real avginferup;
9839  SCIP_Real avginfer;
9840  SCIP_Real inferdown;
9841  SCIP_Real inferup;
9842  SCIP_Real cutoffdown;
9843  SCIP_Real cutoffup;
9844 
9845  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceCutoffScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9846 
9847  assert( var->scip == scip );
9848 
9851  avginfer = (avginferdown + avginferup)/2.0;
9856 
9857  return SCIPbranchGetScore(scip->set, var,
9858  inferdown + cutoffweight * avginfer * cutoffdown, inferup + cutoffweight * avginfer * cutoffup);
9859 }
9860 
9861 /** outputs variable information to file stream via the message system
9862  *
9863  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9864  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9865  *
9866  * @pre This method can be called if @p scip is in one of the following stages:
9867  * - \ref SCIP_STAGE_PROBLEM
9868  * - \ref SCIP_STAGE_TRANSFORMING
9869  * - \ref SCIP_STAGE_TRANSFORMED
9870  * - \ref SCIP_STAGE_INITPRESOLVE
9871  * - \ref SCIP_STAGE_PRESOLVING
9872  * - \ref SCIP_STAGE_EXITPRESOLVE
9873  * - \ref SCIP_STAGE_PRESOLVED
9874  * - \ref SCIP_STAGE_INITSOLVE
9875  * - \ref SCIP_STAGE_SOLVING
9876  * - \ref SCIP_STAGE_SOLVED
9877  * - \ref SCIP_STAGE_EXITSOLVE
9878  * - \ref SCIP_STAGE_FREETRANS
9879  *
9880  * @note If the message handler is set to a NULL pointer nothing will be printed
9881  */
9883  SCIP* scip, /**< SCIP data structure */
9884  SCIP_VAR* var, /**< problem variable */
9885  FILE* file /**< output file (or NULL for standard output) */
9886  )
9887 {
9888  SCIP_CALL( SCIPcheckStage(scip, "SCIPprintVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
9889 
9890  SCIP_CALL( SCIPvarPrint(var, scip->set, scip->messagehdlr, file) );
9891 
9892  return SCIP_OKAY;
9893 }
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:101
SCIP_STAT * stat
Definition: struct_scip.h:70
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
SCIP_Real sbup
Definition: struct_lp.h:145
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip_mem.h:90
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:4701
SCIP_Real SCIPvarGetAvgConflictlengthCurrentRun(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:15403
SCIP_RETCODE SCIPflattenVarAggregationGraph(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1690
SCIP_Bool SCIPsolveIsStopped(SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool checknodelimits)
Definition: solve.c:93
SCIP_Longint nsbdivinglps
Definition: struct_stat.h:200
SCIP_RETCODE SCIPchgVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4940
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6200
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:6857
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:4293
void SCIPvarGetClosestVlb(SCIP_VAR *var, SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real *closestvlb, int *closestvlbidx)
Definition: var.c:14122
SCIP_Real SCIPgetVarAvgInferences(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9416
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_Bool SCIPvarsHaveCommonClique(SCIP_VAR *var1, SCIP_Bool value1, SCIP_VAR *var2, SCIP_Bool value2, SCIP_Bool regardimplics)
Definition: var.c:11474
SCIP_Real SCIPgetVarAvgCutoffs(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9670
SCIP_VAR ** SCIPcliqueGetVars(SCIP_CLIQUE *clique)
Definition: implics.c:3368
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6258
int SCIPcliquetableGetVarComponentIdx(SCIP_CLIQUETABLE *cliquetable, SCIP_VAR *var)
Definition: implics.c:2339
void SCIPstatEnableVarHistory(SCIP_STAT *stat)
Definition: stat.c:157
internal methods for storing primal CIP solutions
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_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5200
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:10461
void SCIPvarUpdateBestRootSol(SCIP_VAR *var, SCIP_SET *set, SCIP_Real rootsol, SCIP_Real rootredcost, SCIP_Real rootlpobjval)
Definition: var.c:13279
SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2125
SCIP_STATUS status
Definition: struct_stat.h:177
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition: lp.c:17780
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition: scip_tree.c:82
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:356
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
Definition: lpi_clp.cpp:3917
SCIP_RETCODE SCIPsetRelaxSolValsSol(SCIP *scip, SCIP_RELAX *relax, SCIP_SOL *sol, SCIP_Bool includeslp)
Definition: scip_var.c:2486
public methods for branch and bound tree
SCIP_Real SCIPrelaxationGetSolObj(SCIP_RELAXATION *relaxation)
Definition: relax.c:824
SCIP_RETCODE SCIPgetBinvarRepresentative(SCIP *scip, SCIP_VAR *var, SCIP_VAR **repvar, SCIP_Bool *negated)
Definition: scip_var.c:1594
SCIP_RETCODE SCIPbacktrackProbing(SCIP *scip, int probingdepth)
Definition: scip_probing.c:216
internal methods for branch and bound tree
SCIP_Real SCIPgetVarAvgInferenceCutoffScore(SCIP *scip, SCIP_VAR *var, SCIP_Real cutoffweight)
Definition: scip_var.c:9787
SCIP_CONFLICT * conflict
Definition: struct_scip.h:87
SCIP_RETCODE SCIPaddVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real addobj)
Definition: scip_var.c:4559
SCIP_Real SCIPvarGetAvgCutoffsCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:16311
SCIP_Real SCIPvarGetBranchFactor(SCIP_VAR *var)
Definition: var.c:18070
SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:1989
void SCIPlpEndStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16291
SCIP_RETCODE SCIPclearRelaxSolVals(SCIP *scip, SCIP_RELAX *relax)
Definition: scip_var.c:2361
public methods for memory management
SCIP_Real SCIPgetVarAvgInferencesCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9444
int SCIPgetProbingDepth(SCIP *scip)
Definition: scip_probing.c:189
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
SCIP_Real SCIPgetVarConflictlengthScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9331
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6598
#define SCIPsetDuplicateBufferArray(set, ptr, source, num)
Definition: set.h:1727
#define SCIP_DECL_VARTRANS(x)
Definition: type_var.h:138
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:7181
SCIP_Bool SCIPvarDoNotMultaggr(SCIP_VAR *var)
Definition: var.c:5876
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:2112
public methods for implications, variable bounds, and cliques
SCIP_Real SCIPvarGetPseudocostCountCurrentRun(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:14617
methods for implications, variable bounds, and cliques
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17910
SCIP_RETCODE SCIPvarGetProbvarBinary(SCIP_VAR **var, SCIP_Bool *negated)
Definition: var.c:12309
SCIP_Bool SCIPvarIsPscostRelerrorReliable(SCIP_VAR *var, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real threshold, SCIP_CONFIDENCELEVEL clevel)
Definition: var.c:14783
#define SCIP_MAXSTRLEN
Definition: def.h:293
SCIP_Bool conf_usesb
Definition: struct_set.h:227
SCIP_Real SCIPgetVarPseudocostVal(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta)
Definition: scip_var.c:8811
void SCIPgmlWriteArc(FILE *file, unsigned int source, unsigned int target, const char *label, const char *color)
Definition: misc.c:629
internal methods for clocks and timing issues
#define SCIP_VARTYPE_INTEGER_CHAR
Definition: def.h:149
SCIP_RETCODE SCIPvarChgLbOriginal(SCIP_VAR *var, SCIP_SET *set, SCIP_Real newbound)
Definition: var.c:6563
SCIP_Longint SCIPcolGetStrongbranchNode(SCIP_COL *col)
Definition: lp.c:17106
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:130
SCIP_Real SCIPgetVarRedcost(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1861
int SCIPtreeGetProbingDepth(SCIP_TREE *tree)
Definition: tree.c:8420
SCIP_RETCODE SCIPgetNegatedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **negvars)
Definition: scip_var.c:1557
SCIP_Bool presol_donotaggr
Definition: struct_set.h:453
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:1803
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17966
SCIP_RETCODE SCIPvarChgLbLazy(SCIP_VAR *var, SCIP_SET *set, SCIP_Real lazylb)
Definition: var.c:7465
#define SCIP_CALL_FINALLY(x, y)
Definition: def.h:426
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:4007
SCIP_Real SCIPgetColRedcost(SCIP *scip, SCIP_COL *col)
Definition: scip_lp.c:1145
SCIP_Real constant
Definition: struct_var.h:184
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_EVENTQUEUE * eventqueue
Definition: struct_scip.h:80
SCIP_Longint nsbtimesiterlimhit
Definition: struct_stat.h:112
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:5892
SCIP_Real SCIPvarGetMultaggrLbGlobal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8562
SCIP_RETCODE SCIPchgVarLbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4843
SCIP_PRIMAL * primal
Definition: struct_scip.h:85
void SCIPstatDisableVarHistory(SCIP_STAT *stat)
Definition: stat.c:147
SCIP_Bool SCIPpscostThresholdProbabilityTest(SCIP *scip, SCIP_VAR *var, SCIP_Real frac, SCIP_Real threshold, SCIP_BRANCHDIR dir, SCIP_CONFIDENCELEVEL clevel)
Definition: scip_var.c:9056
SCIP_RETCODE SCIPvarChgUbOriginal(SCIP_VAR *var, SCIP_SET *set, SCIP_Real newbound)
Definition: var.c:6622
void SCIPgmlWriteNode(FILE *file, unsigned int id, const char *label, const char *nodetype, const char *fillcolor, const char *bordercolor)
Definition: misc.c:487
SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip_var.c:1436
SCIP_RETCODE SCIPparseVarName(SCIP *scip, const char *str, SCIP_VAR **var, char **endptr)
Definition: scip_var.c:524
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:2490
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1245
interface methods for specific LP solvers
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:17431
SCIP_RETCODE SCIPgetLPI(SCIP *scip, SCIP_LPI **lpi)
Definition: scip_lp.c:976
SCIP_Real SCIPvarGetSol(SCIP_VAR *var, SCIP_Bool getlpval)
Definition: var.c:13256
SCIP_RETCODE SCIPchgVarUbLazy(SCIP *scip, SCIP_VAR *var, SCIP_Real lazyub)
Definition: scip_var.c:5161
void SCIPgmlWriteClosing(FILE *file)
Definition: misc.c:689
SCIP_Real SCIPbranchGetScore(SCIP_SET *set, SCIP_VAR *var, SCIP_Real downgain, SCIP_Real upgain)
Definition: branch.c:2181
SCIP_RETCODE SCIPvarMarkDoNotMultaggr(SCIP_VAR *var)
Definition: var.c:6137
SCIP_Real SCIPgetVarPseudocostCountCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:8947
SCIP_BOUNDTYPE SCIPboundchgGetBoundtype(SCIP_BOUNDCHG *boundchg)
Definition: var.c:17178
SCIP_RETCODE SCIPsetRelaxSolVals(SCIP *scip, SCIP_RELAX *relax, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Bool includeslp)
Definition: scip_var.c:2444
SCIP_Real SCIPgetVarPseudocostScoreCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real solval)
Definition: scip_var.c:9138
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_BRANCHCAND * branchcand
Definition: struct_scip.h:81
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition: scip_prob.c:1865
#define NLOCKTYPES
Definition: type_var.h:81
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:351
#define FALSE
Definition: def.h:87
SCIP_Bool SCIPconsIsLockedTypeNeg(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
Definition: cons.c:8466
SCIP_Real SCIPadjustedVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real ub)
Definition: scip_var.c:4642
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3014
SCIP_Bool misc_allowweakdualreds
Definition: struct_set.h:400
SCIP_Bool SCIPsetIsFeasIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6741
SCIP_Real SCIPgetVarVSIDS(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9174
struct SCIP_VarData SCIP_VARDATA
Definition: type_var.h:107
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:6117
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:281
SCIP_Real SCIPgetVarMultaggrUbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6588
SCIP_RETCODE SCIPvarTransform(SCIP_VAR *origvar, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_OBJSENSE objsense, SCIP_VAR **transvar)
Definition: var.c:3455
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Real SCIPgetVarPseudocostValCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta)
Definition: scip_var.c:8839
SCIP_Real constant
Definition: struct_var.h:194
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10755
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6312
SCIP_STAGE stage
Definition: struct_set.h:65
#define TRUE
Definition: def.h:86
SCIP_Real SCIPvarGetAvgConflictlength(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:15359
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
SCIP_RETCODE SCIPaddVarLocks(SCIP *scip, SCIP_VAR *var, int nlocksdown, int nlocksup)
Definition: scip_var.c:4314
SCIP_Longint SCIPgetVarStrongbranchNode(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:4157
SCIP_RETCODE SCIPhashmapInsertInt(SCIP_HASHMAP *hashmap, void *origin, int image)
Definition: misc.c:3132
void SCIPlpStartStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16278
enum SCIP_Varstatus SCIP_VARSTATUS
Definition: type_var.h:48
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1725
int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
Definition: tree.c:8392
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:2069
SCIP_Bool branch_checksbsol
Definition: struct_set.h:198
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17600
SCIP_Bool branch_divingpscost
Definition: struct_set.h:195
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:10908
#define SCIP_DECL_VARCOPY(x)
Definition: type_var.h:181
unsigned int sbdownvalid
Definition: struct_lp.h:179
internal methods for branching rules and branching candidate storage
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:2908
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:7137
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:185
SCIP_Real SCIPgetVarAvgCutoffsCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9698
SCIP_Bool presol_donotmultaggr
Definition: struct_set.h:452
SCIP_Real SCIPgetVarVSIDSCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9206
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:7324
SCIP_Real SCIPgetVarAvgCutoffScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9755
public methods for problem variables
SCIP_Bool SCIPisVarPscostRelerrorReliable(SCIP *scip, SCIP_VAR *var, SCIP_Real threshold, SCIP_CONFIDENCELEVEL clevel)
Definition: scip_var.c:9075
SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5317
SCIP_Real SCIPgetRelaxSolObj(SCIP *scip)
Definition: scip_var.c:2629
SCIP_Bool SCIPgetVarWasFixedAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2279
SCIP_Real SCIPvarGetAvgInferences(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:16066
SCIP_Bool diving
Definition: struct_lp.h:370
SCIP_Real SCIPgetVarPseudocost(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:8865
SCIP_RETCODE SCIPchgVarLbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_probing.c:292
SCIP_RETCODE SCIPvarsGetActiveVars(SCIP_SET *set, SCIP_VAR **vars, int *nvars, int varssize, int *requiredsize)
Definition: var.c:12005
SCIP_RETCODE SCIPchgVarUbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4887
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:395
void SCIPrelaxationSetSolValid(SCIP_RELAXATION *relaxation, SCIP_Bool isvalid, SCIP_Bool includeslp)
Definition: relax.c:780
SCIP_Real SCIPgetVarMultaggrUbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6558
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:7011
SCIP_PROB * transprob
Definition: struct_scip.h:89
SCIP_Bool SCIPrelaxationIsSolValid(SCIP_RELAXATION *relaxation)
Definition: relax.c:793
SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4673
SCIP_Real constant
Definition: struct_var.h:177
SCIP_Bool conf_enable
Definition: struct_set.h:218
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:6658
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:6173
#define SCIP_LONGINT_MAX
Definition: def.h:163
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:1133
SCIP_RETCODE SCIPcreateLPSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip_sol.c:361
SCIP_RETCODE SCIPmarkRelaxSolInvalid(SCIP *scip)
Definition: scip_var.c:2579
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:127
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
#define SCIPsetFreeBufferArray(set, ptr)
Definition: set.h:1732
SCIP_Real SCIPadjustedVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real lb)
Definition: scip_var.c:4610
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition: type_lp.h:42
void SCIPvarAdjustLb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *lb)
Definition: var.c:6513
SCIP_Bool SCIPisTransformed(SCIP *scip)
Definition: scip_general.c:566
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:6717
public methods for SCIP variables
SCIP_RETCODE SCIPvarChgBranchDirection(SCIP_VAR *var, SCIP_BRANCHDIR branchdirection)
Definition: var.c:11817
SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
Definition: var.c:17736
SCIP_Bool branch_forceall
Definition: struct_set.h:196
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:111
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:1601
SCIP_RETCODE SCIPchgVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:5029
#define SCIPdebugMsg
Definition: scip_message.h:69
SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition: scip_var.c:1477
SCIP_Longint SCIPcolGetStrongbranchLPAge(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4733
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:3659
internal methods for LP management
int SCIPvarGetNCliques(SCIP_VAR *var, SCIP_Bool varfixing)
Definition: var.c:18262
SCIP_PROB * origprob
Definition: struct_scip.h:71
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:199
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:700
SCIP_RETCODE SCIPgetVarClosestVlb(SCIP *scip, SCIP_VAR *var, SCIP_SOL *sol, SCIP_Real *closestvlb, int *closestvlbidx)
Definition: scip_var.c:6606
SCIP_VAR ** vars
Definition: struct_var.h:186
SCIP_Real SCIPcomputeVarUbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6481
internal methods for branching and inference history
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPcomputeVarLbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6502
SCIP_Bool SCIPisStrongbranchDownFirst(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:2652
SCIP_RETCODE SCIPtransformVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition: scip_var.c:1386
public methods for numerical tolerances
SCIP_Bool reopt_enable
Definition: struct_set.h:503
SCIP_Real SCIPgetVarPseudocostScore(SCIP *scip, SCIP_VAR *var, SCIP_Real solval)
Definition: scip_var.c:9100
SCIP_RETCODE SCIPscaleVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real scale)
Definition: scip_var.c:7918
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
SCIP_VAR * var
Definition: struct_var.h:178
#define SCIP_DECL_VARDELTRANS(x)
Definition: type_var.h:151
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6294
public methods for querying solving statistics
SCIP_HISTORY * glbhistorycrun
Definition: struct_stat.h:173
int SCIPcliquetableGetNCliquesCreated(SCIP_CLIQUETABLE *cliquetable)
Definition: implics.c:3504
SCIP_RETCODE SCIPtryStrongbranchLPSol(SCIP *scip, SCIP_Bool *foundsol, SCIP_Bool *cutoff)
Definition: scip_var.c:4076
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3363
SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
Definition: scip_var.c:4256
SCIP_Real SCIPvarGetVSIDSCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:15927
SCIP_RETCODE SCIPupdateVarPseudocost(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
Definition: scip_var.c:8777
public methods for the branch-and-bound tree
SCIP_Real SCIPgetVarBdAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2261
enum SCIP_BranchDir SCIP_BRANCHDIR
Definition: type_history.h:39
SCIP_Bool SCIPisLPRelax(SCIP *scip)
Definition: scip_lp.c:216
SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
Definition: scip_prob.c:2684
SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:8173
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:6918
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:7966
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17920
SCIP_VAR * SCIPvarGetProbvar(SCIP_VAR *var)
Definition: var.c:12217
int SCIPcliquetableGetNCliques(SCIP_CLIQUETABLE *cliquetable)
Definition: implics.c:3494
SCIP_CLOCK * strongpropclock
Definition: struct_stat.h:170
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:96
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:8532
SCIP_MEM * mem
Definition: struct_scip.h:62
public methods for managing constraints
SCIP_Bool misc_allowstrongdualreds
Definition: struct_set.h:399
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_Bool SCIPtreeProbing(SCIP_TREE *tree)
Definition: tree.c:8274
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:601
SCIP_Real lb
Definition: struct_lp.h:129
enum SCIP_Confidencelevel SCIP_CONFIDENCELEVEL
Definition: type_misc.h:44
SCIP_RETCODE SCIPvarChgBranchPriority(SCIP_VAR *var, int branchpriority)
Definition: var.c:11686
SCIP_Real SCIPvarGetPseudocost(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real solvaldelta)
Definition: var.c:14476
SCIP_RETCODE SCIPprobRemoveVarName(SCIP_PROB *prob, SCIP_VAR *var)
Definition: prob.c:913
SCIP_AGGREGATE aggregate
Definition: struct_var.h:222
SCIP_RETCODE SCIPmarkDoNotAggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8679
SCIP_Real SCIPsolGetObj(SCIP_SOL *sol, SCIP_SET *set, SCIP_PROB *transprob, SCIP_PROB *origprob)
Definition: sol.c:1537
SCIP_Real sbdown
Definition: struct_lp.h:144
SCIP_RETCODE SCIPvarChgUbLazy(SCIP_VAR *var, SCIP_SET *set, SCIP_Real lazyub)
Definition: var.c:7488
SCIP_Real SCIPgetVarPseudocostVariance(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun)
Definition: scip_var.c:8973
enum SCIP_LockType SCIP_LOCKTYPE
Definition: type_var.h:87
SCIP_RETCODE SCIPgetBinvarRepresentatives(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **repvars, SCIP_Bool *negated)
Definition: scip_var.c:1641
SCIP_Bool SCIPvarDoNotAggr(SCIP_VAR *var)
Definition: var.c:5843
internal methods for storing and manipulating the main problem
#define SCIPerrorMessage
Definition: pub_message.h:55
SCIP_Bool SCIPboundchgIsRedundant(SCIP_BOUNDCHG *boundchg)
Definition: var.c:17188
SCIP_EVENTFILTER * eventfilter
Definition: struct_scip.h:79
SCIP_Bool SCIPlpIsDualReliable(SCIP_LP *lp)
Definition: lp.c:17760
SCIP_Bool SCIPdoNotAggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8582
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 SCIPchgVarLbLazy(SCIP *scip, SCIP_VAR *var, SCIP_Real lazylb)
Definition: scip_var.c:5120
SCIP_Longint lpcount
Definition: struct_stat.h:181
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Longint nbestsolsfound
Definition: struct_primal.h:42
SCIP_Bool SCIPdoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8595
SCIP_RETCODE SCIPpropagateProbing(SCIP *scip, int maxproprounds, SCIP_Bool *cutoff, SCIP_Longint *ndomredsfound)
Definition: scip_probing.c:571
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:6260
SCIP_Bool SCIPrelaxationIsSolZero(SCIP_RELAXATION *relaxation)
Definition: relax.c:770
SCIP_RETCODE SCIPgetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip_sol.c:1389
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:5429
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:9534
SCIP_RETCODE SCIPvarRelease(SCIP_VAR **var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: var.c:2866
SCIP_RETCODE SCIPgetProbvarSum(SCIP *scip, SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: scip_var.c:1791
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:6777
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:2177
unsigned int sbupvalid
Definition: struct_lp.h:181
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:48
SCIP_Real SCIPvarGetPseudocostCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real solvaldelta)
Definition: var.c:14525
void SCIPstrCopySection(const char *str, char startchar, char endchar, char *token, int size, char **endptr)
Definition: misc.c:10886
SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:4434
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:3161
SCIP_LPSOLSTAT lastsblpsolstats[2]
Definition: struct_stat.h:179
SCIP_CONFLICTSTORE * conflictstore
Definition: struct_scip.h:95
SCIP_RETCODE SCIPvarGetTransformed(SCIP_VAR *origvar, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR **transvar)
Definition: var.c:3542
SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4763
SCIP_Real SCIPcalculatePscostConfidenceBound(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun, SCIP_CONFIDENCELEVEL clevel)
Definition: scip_var.c:8995
SCIP_OBJSENSE objsense
Definition: struct_prob.h:77
SCIP_RETCODE SCIPmarkDoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8712
char branch_firstsbchild
Definition: struct_set.h:186
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17251
SCIP_VAR * transvar
Definition: struct_var.h:170
SCIP_REOPT * reopt
Definition: struct_scip.h:76
SCIP_RETCODE SCIPsetRelaxSolVal(SCIP *scip, SCIP_RELAX *relax, SCIP_VAR *var, SCIP_Real val)
Definition: scip_var.c:2411
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:3048
SCIP_Real SCIPsetFeasCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6776
SCIP_RETCODE SCIPtightenVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6225
SCIP_DOMCHG * SCIPnodeGetDomchg(SCIP_NODE *node)
Definition: tree.c:7527
SCIP_Real cutoffbound
Definition: struct_lp.h:274
SCIP_Longint nsbdivinglpiterations
Definition: struct_stat.h:67
#define NULL
Definition: lpi_spx1.cpp:155
void SCIPvarGetClosestVub(SCIP_VAR *var, SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real *closestvub, int *closestvubidx)
Definition: var.c:14197
SCIP_NEGATE negate
Definition: struct_var.h:224
SCIP_Real SCIPgetVarConflictlengthScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9300
SCIP_RETCODE SCIPvarSetRelaxSol(SCIP_VAR *var, SCIP_SET *set, SCIP_RELAXATION *relaxation, SCIP_Real solval, SCIP_Bool updateobj)
Definition: var.c:13861
data structures for branch and bound tree
SCIP_HISTORY * glbhistory
Definition: struct_stat.h:172
SCIP_Real SCIPboundchgGetNewbound(SCIP_BOUNDCHG *boundchg)
Definition: var.c:17148
#define REALABS(x)
Definition: def.h:201
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
Definition: var.c:18284
SCIP_Real SCIPgetVarAvgInferenceScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9501
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:9997
internal methods for global SCIP settings
SCIP_Real SCIPvarCalcPscostConfidenceBound(SCIP_VAR *var, SCIP_SET *set, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun, SCIP_CONFIDENCELEVEL clevel)
Definition: var.c:14745
#define SCIP_CALL(x)
Definition: def.h:384
SCIP_RETCODE SCIPprobAddVarName(SCIP_PROB *prob, SCIP_VAR *var)
Definition: prob.c:897
SCIP main data structure.
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:9026
SCIP_RETCODE SCIPsolveProbingLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition: scip_probing.c:810
SCIP_Real SCIPcomputeVarUbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6523
SCIP_Longint nsbbestsolsfound
Definition: struct_stat.h:99
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:6007
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 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:1735
SCIP_Real SCIPgetVarAvgConflictlength(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9362
SCIP_RETCODE SCIPremoveVarFromGlobalStructures(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:7856
SCIP_RETCODE SCIPgetVarClosestVub(SCIP *scip, SCIP_VAR *var, SCIP_SOL *sol, SCIP_Real *closestvub, int *closestvubidx)
Definition: scip_var.c:6629
SCIP_Longint SCIPgetVarStrongbranchLPAge(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:4191
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPsetIsLbBetter(SCIP_SET *set, SCIP_Real newlb, SCIP_Real oldlb, SCIP_Real oldub)
Definition: set.c:7023
SCIP_Real SCIPvarGetPseudocostCount(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:14572
#define SCIPstatAdd(stat, set, field, val)
Definition: stat.h:271
internal methods for relaxators
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6222
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:8093
SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13097
SCIP_RETCODE SCIPvarPrint(SCIP_VAR *var, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: var.c:3000
SCIP_Real SCIPgetVarPseudocostCount(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:8919
SCIP_RETCODE SCIPlpStartStrongbranch(SCIP_LP *lp)
Definition: lp.c:4174
SCIP_Real SCIPgetVarPseudocostCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:8893
SCIP_CLIQUETABLE * cliquetable
Definition: struct_scip.h:88
SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2372
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:4510
internal methods for problem variables
SCIP_RETCODE SCIPvarChgBranchFactor(SCIP_VAR *var, SCIP_SET *set, SCIP_Real branchfactor)
Definition: var.c:11559
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:5275
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:115
#define SCIP_UNKNOWN
Definition: def.h:198
SCIP_RETCODE SCIPstartStrongbranch(SCIP *scip, SCIP_Bool enablepropagation)
Definition: scip_var.c:2683
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_clp.cpp:2752
public data structures and miscellaneous methods
unsigned int vartype
Definition: struct_var.h:271
SCIP_Bool SCIPcliquetableNeedsComponentUpdate(SCIP_CLIQUETABLE *cliquetable)
Definition: implics.c:3542
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
void SCIPrelaxationSetSolRelax(SCIP_RELAXATION *relaxation, SCIP_RELAX *relax)
Definition: relax.c:865
#define SCIP_Bool
Definition: def.h:84
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:5823
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip_lp.c:159
void SCIPvarCapture(SCIP_VAR *var)
Definition: var.c:2841
SCIP_CLOCK * sbsoltime
Definition: struct_stat.h:166
SCIP_Real ub
Definition: struct_var.h:162
int SCIPgetNCliquesCreated(SCIP *scip)
Definition: scip_var.c:7599
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2595
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:6424
SCIP_RETCODE SCIProundSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
Definition: scip_sol.c:2446
#define MAXNCLIQUEVARSCOMP
Definition: scip_var.c:7117
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:2836
int SCIPvarGetBranchPriority(SCIP_VAR *var)
Definition: var.c:18082
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:3743
SCIP_MULTAGGR multaggr
Definition: struct_var.h:223
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:3349
union SCIP_Var::@21 data
SCIP_RETCODE SCIPmarkRelaxSolValid(SCIP *scip, SCIP_RELAX *relax, SCIP_Bool includeslp)
Definition: scip_var.c:2554
SCIP_Bool branch_roundsbsol
Definition: struct_set.h:199
int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition: var.c:3423
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)
Definition: conflict.c:8971
SCIP_RETCODE SCIPcliquetableComputeCliqueComponents(SCIP_CLIQUETABLE *cliquetable, SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_VAR **vars, int nbinvars, int nintvars, int nimplvars)
Definition: implics.c:3119
#define MAX(x, y)
Definition: tclique_def.h:83
SCIP_Bool SCIPstrToRealValue(const char *str, SCIP_Real *value, char **endptr)
Definition: misc.c:10856
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:3231
SCIP_RETCODE SCIPcalcCliquePartition(SCIP *const scip, SCIP_VAR **const vars, int const nvars, int *const cliquepartition, int *const ncliques)
Definition: scip_var.c:7253
SCIP_VAR * SCIPboundchgGetVar(SCIP_BOUNDCHG *boundchg)
Definition: var.c:17158
methods for debugging
SCIP_Bool * SCIPcliqueGetValues(SCIP_CLIQUE *clique)
Definition: implics.c:3380
SCIP_BOUNDCHG * SCIPdomchgGetBoundchg(SCIP_DOMCHG *domchg, int pos)
Definition: var.c:17206
public methods for LP management
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:4204
datastructures for block memory pools and memory buffers
SCIP_RETCODE SCIPwriteCliqueGraph(SCIP *scip, const char *fname, SCIP_Bool writenodeweights)
Definition: scip_var.c:7707
SCIP_Real SCIPvarGetMultaggrUbGlobal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8628
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip_sol.c:976
SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
Definition: prob.c:2300
void SCIPenableVarHistory(SCIP *scip)
Definition: scip_var.c:8738
SCIP_Real SCIPcomputeVarLbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6460
SCIP_Real SCIPgetVarAvgInferenceCutoffScoreCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real cutoffweight)
Definition: scip_var.c:9831
SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18502
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:3881
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:105
SCIP_RETCODE SCIPvarFlattenAggregationGraph(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: var.c:4408
SCIP_Real SCIPvarGetAvgInferencesCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:16123
SCIP_Bool SCIPtreeHasCurrentNodeLP(SCIP_TREE *tree)
Definition: tree.c:8409
SCIP_Bool SCIPallowWeakDualReds(SCIP *scip)
Definition: scip_var.c:8653
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition: scip_var.c:8273
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:127
SCIP_RETCODE SCIPchgVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition: scip_var.c:7977
SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:4348
int SCIPconflictGetNConflicts(SCIP_CONFLICT *conflict)
Definition: conflict.c:3737
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:17621
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:535
SCIP_Real SCIPvarGetRelaxSol(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:13922
datastructures for problem statistics
int nconflicthdlrs
Definition: struct_set.h:113
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Real ub
Definition: struct_lp.h:130
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6620
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:2367
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:6335
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:5498
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
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:2916
void SCIPrelaxationSetSolObj(SCIP_RELAXATION *relaxation, SCIP_Real obj)
Definition: relax.c:813
#define SCIP_MAXTREEDEPTH
Definition: def.h:320
SCIP * scip
Definition: struct_var.h:279
SCIP_BDCHGINFO * SCIPvarGetLbchgInfo(SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: var.c:16409
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip_probing.c:88
public methods for the LP relaxation, rows and columns
SCIP_BDCHGINFO * SCIPvarGetUbchgInfo(SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: var.c:16465
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:1991
SCIP_Real SCIPgetVarMultaggrLbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6573
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:4478
SCIP_RETCODE SCIPwriteVarsLinearsum(SCIP *scip, FILE *file, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Bool type)
Definition: scip_var.c:334
#define SCIP_DECL_VARDELORIG(x)
Definition: type_var.h:118
SCIP_Real SCIPlpGetLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13136
datastructures for storing and manipulating the main problem
SCIP_Bool SCIPinDive(SCIP *scip)
Definition: scip_lp.c:2760
void SCIPrelaxationSetSolZero(SCIP_RELAXATION *relaxation, SCIP_Bool iszero)
Definition: relax.c:759
SCIP_Real SCIPsetFeasFloor(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6765
SCIP_CLIQUE ** SCIPgetCliques(SCIP *scip)
Definition: scip_var.c:7626
SCIP_Real SCIPgetVarAvgConflictlengthCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9388
SCIP_RETCODE SCIPaddVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real addfactor)
Definition: scip_var.c:7946
SCIP_LPSOLSTAT SCIPgetLastStrongbranchLPSolStat(SCIP *scip, SCIP_BRANCHDIR branchdir)
Definition: scip_var.c:3985
SCIP_Bool misc_exactsolve
Definition: struct_set.h:384
SCIP_RETCODE SCIPwriteVarsList(SCIP *scip, FILE *file, SCIP_VAR **vars, int nvars, SCIP_Bool type, char delimiter)
Definition: scip_var.c:283
#define SCIP_VARTYPE_IMPLINT_CHAR
Definition: def.h:150
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:4041
general public methods
int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition: var.c:3410
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition: scip_lp.c:238
BMS_BLKMEM * probmem
Definition: struct_mem.h:40
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPgetVarImplRedcost(SCIP *scip, SCIP_VAR *var, SCIP_Bool varfixing)
Definition: scip_var.c:1906
public methods for solutions
internal methods for conflict analysis
void SCIPfreeParseVarsPolynomialData(SCIP *scip, SCIP_VAR ****monomialvars, SCIP_Real ***monomialexps, SCIP_Real **monomialcoefs, int **monomialnvars, int nmonomials)
Definition: scip_var.c:1155
static const SCIP_Real scalars[]
Definition: lp.c:5736
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:5441
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:5612
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:3770
internal methods for main solving loop and node processing
SCIP_RETCODE SCIPgetVarSols(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip_var.c:2324
int SCIPdomchgGetNBoundchgs(SCIP_DOMCHG *domchg)
Definition: var.c:17198
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:2078
#define SCIP_VARTYPE_CONTINUOUS_CHAR
Definition: def.h:151
public methods for the probing mode
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:3913
SCIP_NODE * SCIPtreeGetCurrentNode(SCIP_TREE *tree)
Definition: tree.c:8375
SCIP_RETCODE SCIPendStrongbranch(SCIP *scip)
Definition: scip_var.c:2741
SCIP_Bool SCIPisRelaxSolValid(SCIP *scip)
Definition: scip_var.c:2534
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
SCIP_RETCODE SCIPvarMarkDoNotAggr(SCIP_VAR *var)
Definition: var.c:6101
SCIP_Bool SCIPallowDualReds(SCIP *scip)
Definition: scip_var.c:8611
SCIP_SET * set
Definition: struct_scip.h:63
public methods for message output
int SCIPgetNCliques(SCIP *scip)
Definition: scip_var.c:7572
data structures for LP management
SCIP_RETCODE SCIPaddVarBranchPriority(SCIP *scip, SCIP_VAR *var, int addpriority)
Definition: scip_var.c:8051
SCIP_Real * scalars
Definition: struct_var.h:185
datastructures for problem variables
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:1946
int SCIPcolGetNStrongbranchs(SCIP_COL *col)
Definition: lp.c:17116
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17370
SCIP_RETCODE SCIPcalcNegatedCliquePartition(SCIP *const scip, SCIP_VAR **const vars, int const nvars, int *const cliquepartition, int *const ncliques)
Definition: scip_var.c:7472
SCIP_MESSAGEHDLR * messagehdlr
Definition: struct_scip.h:66
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:8398
SCIP_NODETYPE SCIPnodeGetType(SCIP_NODE *node)
Definition: tree.c:7422
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1211
#define SCIP_Real
Definition: def.h:177
internal methods for problem statistics
SCIP_RETCODE SCIPvarsGetProbvarBinary(SCIP_VAR ***vars, SCIP_Bool **negatedarr, int nvars)
Definition: var.c:12277
SCIP_RETCODE SCIPchgVarBranchDirection(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR branchdirection)
Definition: scip_var.c:8082
SCIP_Bool SCIPhaveVarsCommonClique(SCIP *scip, SCIP_VAR *var1, SCIP_Bool value1, SCIP_VAR *var2, SCIP_Bool value2, SCIP_Bool regardimplics)
Definition: scip_var.c:7656
datastructures for collecting primal CIP solutions and primal informations
public methods for message handling
SCIP_Bool SCIPdoNotAggr(SCIP *scip)
Definition: scip_var.c:8562
SCIP_RETCODE SCIPtransformVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip_var.c:1346
SCIP_Real SCIPvarGetVSIDS(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:18375
#define SCIP_INVALID
Definition: def.h:197
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:2554
SCIP_Real primsol
Definition: struct_lp.h:139
#define SCIP_Longint
Definition: def.h:162
SCIP_Bool SCIPallColsInLP(SCIP *scip)
Definition: scip_lp.c:640
SCIP_Real SCIPvarGetAvgCutoffs(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:16264
SCIP_Real lb
Definition: struct_var.h:161
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6664
SCIP_Longint nsbsolsfound
Definition: struct_stat.h:95
SCIP_TREE * tree
Definition: struct_scip.h:86
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17416
#define SCIP_VARTYPE_BINARY_CHAR
Definition: def.h:148
SCIP_Real SCIPvarGetMultaggrUbLocal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8496
SCIP_RETCODE SCIPvarChgName(SCIP_VAR *var, BMS_BLKMEM *blkmem, const char *name)
Definition: var.c:2907
SCIP_RELAXATION * relaxation
Definition: struct_scip.h:84
void SCIPsolSetStrongbranching(SCIP_SOL *sol)
Definition: sol.c:2709
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:3023
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:809
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPdoNotMultaggr(SCIP *scip)
Definition: scip_var.c:8572
SCIP_DOM glbdom
Definition: struct_var.h:216
SCIP_Real SCIPgetVarConflictScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9269
SCIP_Real SCIPhistoryGetAvgInferences(SCIP_HISTORY *history, SCIP_BRANCHDIR dir)
Definition: history.c:649
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
enum SCIP_Vartype SCIP_VARTYPE
Definition: type_var.h:60
SCIP_Bool SCIPconsIsLockedTypePos(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
Definition: cons.c:8454
SCIP_Real SCIPgetVarSol(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:2304
SCIP_VAR * negatedvar
Definition: struct_var.h:233
SCIP_Real SCIPgetColFarkasCoef(SCIP *scip, SCIP_COL *col)
Definition: scip_lp.c:1171
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17976
SCIP_Real SCIPgetVarMultaggrLbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6543
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip_mem.h:102
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
Definition: scip_probing.c:156
int SCIPcliqueGetNVars(SCIP_CLIQUE *clique)
Definition: implics.c:3358
void SCIPgmlWriteOpening(FILE *file, SCIP_Bool directed)
Definition: misc.c:673
void SCIPvarAdjustUb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *ub)
Definition: var.c:6530
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPsetIsUbBetter(SCIP_SET *set, SCIP_Real newub, SCIP_Real oldlb, SCIP_Real oldub)
Definition: set.c:7044
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition: var.c:17393
SCIP_RETCODE SCIPtightenVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6345
static SCIP_RETCODE tightenBounds(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:8099
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:9605
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:123
SCIP_RETCODE SCIPupdateVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition: scip_var.c:8018
void SCIPcolInvalidateStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4258
SCIP_RETCODE SCIPvarGetProbvarSum(SCIP_VAR **var, SCIP_SET *set, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12646
SCIP_NODE * root
Definition: struct_tree.h:177
int SCIPhashmapGetImageInt(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3221
#define SCIP_CALL_ABORT(x)
Definition: def.h:363
SCIP_Real SCIPvarGetPseudoSol(SCIP_VAR *var)
Definition: var.c:18362
SCIP_RETCODE SCIPcleanupCliques(SCIP *scip, SCIP_Bool *infeasible)
Definition: scip_var.c:7529
SCIP_Real SCIPgetVarFarkasCoef(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1951
SCIP_ORIGINAL original
Definition: struct_var.h:220
SCIP_LP * lp
Definition: struct_scip.h:82
#define SCIPABORT()
Definition: def.h:356
SCIP_RETCODE SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
Definition: scip_var.c:221
public methods for global and local (sub)problems
int SCIPgetVarNStrongbranchs(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:4223
SCIP_RETCODE SCIPgetActiveVars(SCIP *scip, SCIP_VAR **vars, int *nvars, int varssize, int *requiredsize)
Definition: scip_var.c:1827
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:17442
SCIP_RETCODE SCIPchgVarUbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_probing.c:336
SCIP_Real SCIPvarGetMultaggrLbLocal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8430
void SCIPdisableVarHistory(SCIP *scip)
Definition: scip_var.c:8757
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1352
SCIP_Real SCIPgetVarAvgInferenceScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9470
datastructures for global SCIP settings
SCIP_RETCODE SCIPlpEndStrongbranch(SCIP_LP *lp)
Definition: lp.c:4189
SCIP_Bool SCIPallowStrongDualReds(SCIP *scip)
Definition: scip_var.c:8626
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:5720
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:465
SCIP_Bool SCIPcolIsInLP(SCIP_COL *col)
Definition: lp.c:17048
SCIP_RETCODE SCIPvarNegate(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR **negvar)
Definition: var.c:5912
SCIP_CLIQUE ** SCIPcliquetableGetCliques(SCIP_CLIQUETABLE *cliquetable)
Definition: implics.c:3514
SCIP_RETCODE SCIPchgVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real branchfactor)
Definition: scip_var.c:7890
SCIP_RETCODE SCIPprintVar(SCIP *scip, SCIP_VAR *var, FILE *file)
Definition: scip_var.c:9882
static SCIP_RETCODE relabelOrderConsistent(SCIP *const scip, int *labels, int const nlabels, int *nclasses)
Definition: scip_var.c:6950
SCIP_Bool SCIPallowObjProp(SCIP *scip)
Definition: scip_var.c:8639
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip_var.c:1524
SCIP_Real SCIPgetVarConflictScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9238
SCIP_RETCODE SCIPbranchcandUpdateVarBranchPriority(SCIP_BRANCHCAND *branchcand, SCIP_SET *set, SCIP_VAR *var, int branchpriority)
Definition: branch.c:1167
SCIP_Real SCIPvarGetPseudocostVariance(SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun)
Definition: var.c:14691
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17580
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:17406
SCIP_Real SCIPgetRelaxSolVal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:2600
SCIP_Real scalar
Definition: struct_var.h:176
void SCIPvarMarkDeleteGlobalStructures(SCIP_VAR *var)
Definition: var.c:17508
SCIP_RETCODE SCIPchgVarName(SCIP *scip, SCIP_VAR *var, const char *name)
Definition: scip_var.c:1296
memory allocation routines
SCIP_Real SCIPgetVarAvgCutoffScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9724