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-2021 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 monomials as polynomial 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 polynomial 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. Do not keep the arrays created by SCIPparseVarsPolynomial around, since
793  * they use buffer memory that is intended for short term use only.
794  *
795  * Parsing is stopped at the end of string (indicated by the \\0-character) or when no more monomials
796  * are recognized.
797  *
798  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
799  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
800  *
801  * @pre This method can be called if @p scip is in one of the following stages:
802  * - \ref SCIP_STAGE_PROBLEM
803  * - \ref SCIP_STAGE_TRANSFORMING
804  * - \ref SCIP_STAGE_INITPRESOLVE
805  * - \ref SCIP_STAGE_PRESOLVING
806  * - \ref SCIP_STAGE_EXITPRESOLVE
807  * - \ref SCIP_STAGE_PRESOLVED
808  * - \ref SCIP_STAGE_SOLVING
809  */
811  SCIP* scip, /**< SCIP data structure */
812  const char* str, /**< string to parse */
813  SCIP_VAR**** monomialvars, /**< pointer to store arrays with variables for each monomial */
814  SCIP_Real*** monomialexps, /**< pointer to store arrays with variable exponents */
815  SCIP_Real** monomialcoefs, /**< pointer to store array with monomial coefficients */
816  int** monomialnvars, /**< pointer to store array with number of variables for each monomial */
817  int* nmonomials, /**< pointer to store number of parsed monomials */
818  char** endptr, /**< pointer to store the final string position if successful */
819  SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
820  )
821 {
822  typedef enum
823  {
824  SCIPPARSEPOLYNOMIAL_STATE_BEGIN, /* we are at the beginning of a monomial */
825  SCIPPARSEPOLYNOMIAL_STATE_INTERMED, /* we are in between the factors of a monomial */
826  SCIPPARSEPOLYNOMIAL_STATE_COEF, /* we parse the coefficient of a monomial */
827  SCIPPARSEPOLYNOMIAL_STATE_VARS, /* we parse monomial variables */
828  SCIPPARSEPOLYNOMIAL_STATE_EXPONENT, /* we parse the exponent of a variable */
829  SCIPPARSEPOLYNOMIAL_STATE_END, /* we are at the end the polynomial */
830  SCIPPARSEPOLYNOMIAL_STATE_ERROR /* a parsing error occured */
831  } SCIPPARSEPOLYNOMIAL_STATES;
832 
833  SCIPPARSEPOLYNOMIAL_STATES state;
834  int monomialssize;
835 
836  /* data of currently parsed monomial */
837  int varssize;
838  int nvars;
839  SCIP_VAR** vars;
840  SCIP_Real* exponents;
841  SCIP_Real coef;
842 
843  assert(scip != NULL);
844  assert(str != NULL);
845  assert(monomialvars != NULL);
846  assert(monomialexps != NULL);
847  assert(monomialnvars != NULL);
848  assert(monomialcoefs != NULL);
849  assert(nmonomials != NULL);
850  assert(endptr != NULL);
851  assert(success != NULL);
852 
853  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsPolynomial", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
854 
855  *success = FALSE;
856  *nmonomials = 0;
857  monomialssize = 0;
858  *monomialvars = NULL;
859  *monomialexps = NULL;
860  *monomialcoefs = NULL;
861  *monomialnvars = NULL;
862 
863  /* initialize state machine */
864  state = SCIPPARSEPOLYNOMIAL_STATE_BEGIN;
865  varssize = 0;
866  nvars = 0;
867  vars = NULL;
868  exponents = NULL;
869  coef = SCIP_INVALID;
870 
871  SCIPdebugMsg(scip, "parsing polynomial from '%s'\n", str);
872 
873  while( *str && state != SCIPPARSEPOLYNOMIAL_STATE_END && state != SCIPPARSEPOLYNOMIAL_STATE_ERROR )
874  {
875  /* skip white space */
876  while( isspace((unsigned char)*str) )
877  str++;
878 
879  assert(state != SCIPPARSEPOLYNOMIAL_STATE_END);
880 
881  switch( state )
882  {
883  case SCIPPARSEPOLYNOMIAL_STATE_BEGIN:
884  {
885  if( coef != SCIP_INVALID ) /*lint !e777*/
886  {
887  SCIPdebugMsg(scip, "push monomial with coefficient <%g> and <%d> vars\n", coef, nvars);
888  /* push previous monomial */
889  if( monomialssize <= *nmonomials )
890  {
891  monomialssize = SCIPcalcMemGrowSize(scip, *nmonomials+1);
892 
893  SCIP_CALL( SCIPreallocBufferArray(scip, monomialvars, monomialssize) );
894  SCIP_CALL( SCIPreallocBufferArray(scip, monomialexps, monomialssize) );
895  SCIP_CALL( SCIPreallocBufferArray(scip, monomialnvars, monomialssize) );
896  SCIP_CALL( SCIPreallocBufferArray(scip, monomialcoefs, monomialssize) );
897  }
898 
899  if( nvars > 0 )
900  {
901  SCIP_CALL( SCIPduplicateBufferArray(scip, &(*monomialvars)[*nmonomials], vars, nvars) ); /*lint !e866*/
902  SCIP_CALL( SCIPduplicateBufferArray(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( SCIPreallocBufferArray(scip, &vars, varssize) );
1010  SCIP_CALL( SCIPreallocBufferArray(scip, &exponents, 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( SCIPreallocBufferArray(scip, monomialvars, monomialssize) );
1075  SCIP_CALL( SCIPreallocBufferArray(scip, monomialexps, monomialssize) );
1076  SCIP_CALL( SCIPreallocBufferArray(scip, monomialnvars, monomialssize) );
1077  SCIP_CALL( SCIPreallocBufferArray(scip, monomialcoefs, monomialssize) );
1078  }
1079 
1080  if( nvars > 0 )
1081  {
1082  /* shrink vars and exponents array to needed size and take over ownership */
1083  SCIP_CALL( SCIPreallocBufferArray(scip, &vars, nvars) );
1084  SCIP_CALL( SCIPreallocBufferArray(scip, &exponents, 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  SCIPfreeBufferArrayNull(scip, &vars);
1118  SCIPfreeBufferArrayNull(scip, &exponents);
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( SCIPreallocBufferArray(scip, monomialvars, *nmonomials) );
1125  SCIP_CALL( SCIPreallocBufferArray(scip, monomialexps, *nmonomials) );
1126  SCIP_CALL( SCIPreallocBufferArray(scip, monomialnvars, *nmonomials) );
1127  SCIP_CALL( SCIPreallocBufferArray(scip, monomialcoefs, *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 polynomial 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  SCIPfreeBufferArrayNull(scip, &(*monomialexps)[i]);
1184  SCIPfreeBufferArrayNull(scip, &(*monomialvars)[i]);
1185  }
1186 
1187  SCIPfreeBufferArray(scip, monomialcoefs);
1188  SCIPfreeBufferArray(scip, monomialnvars);
1189  SCIPfreeBufferArray(scip, monomialexps);
1190  SCIPfreeBufferArray(scip, monomialvars);
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 )
1274  {
1275  SCIPerrorMessage("cannot release last use of original variable while the transformed problem 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_INITPRESOLVE
4340  * - \ref SCIP_STAGE_PRESOLVING
4341  * - \ref SCIP_STAGE_EXITPRESOLVE
4342  * - \ref SCIP_STAGE_INITSOLVE
4343  * - \ref SCIP_STAGE_SOLVING
4344  * - \ref SCIP_STAGE_EXITSOLVE
4345  * - \ref SCIP_STAGE_FREETRANS
4346  */
4348  SCIP* scip, /**< SCIP data structure */
4349  SCIP_VAR* var, /**< problem variable */
4350  SCIP_CONS* cons, /**< constraint */
4351  SCIP_Bool lockdown, /**< should the rounding be locked in downwards direction? */
4352  SCIP_Bool lockup /**< should the rounding be locked in upwards direction? */
4353  )
4354 {
4355  int nlocksdown[NLOCKTYPES];
4356  int nlocksup[NLOCKTYPES];
4357  int i;
4358 
4359  SCIP_CALL( SCIPcheckStage(scip, "SCIPlockVarCons", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4360 
4361  assert( var->scip == scip );
4362 
4363  for( i = 0; i < NLOCKTYPES; i++ )
4364  {
4365  nlocksdown[i] = 0;
4366  nlocksup[i] = 0;
4367 
4368  if( SCIPconsIsLockedTypePos(cons, (SCIP_LOCKTYPE) i) )
4369  {
4370  if( lockdown )
4371  ++nlocksdown[i];
4372  if( lockup )
4373  ++nlocksup[i];
4374  }
4375  if( SCIPconsIsLockedTypeNeg(cons, (SCIP_LOCKTYPE) i) )
4376  {
4377  if( lockdown )
4378  ++nlocksup[i];
4379  if( lockup )
4380  ++nlocksdown[i];
4381  }
4382  }
4383 
4384  switch( scip->set->stage )
4385  {
4386  case SCIP_STAGE_PROBLEM:
4387  assert(!SCIPvarIsTransformed(var));
4388  /*lint -fallthrough*/
4392  case SCIP_STAGE_PRESOLVING:
4394  case SCIP_STAGE_INITSOLVE:
4395  case SCIP_STAGE_SOLVING:
4396  case SCIP_STAGE_EXITSOLVE:
4397  case SCIP_STAGE_FREETRANS:
4398  for( i = 0; i < NLOCKTYPES; i++ )
4399  {
4400  if( nlocksdown[i] == 0 && nlocksup[i] == 0 )
4401  continue;
4402 
4403  SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, (SCIP_LOCKTYPE) i, nlocksdown[i], nlocksup[i]) );
4404  }
4405  return SCIP_OKAY;
4406 
4407  default:
4408  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4409  return SCIP_INVALIDCALL;
4410  } /*lint !e788*/
4411 }
4412 
4413 /** remove locks of type @p locktype of variable with respect to the lock status of the constraint and its negation;
4414  * this method should be called whenever the lock status of a variable in a constraint changes, for example if
4415  * the coefficient of the variable changed its sign or if the left or right hand sides of the constraint were
4416  * added or removed
4417  *
4418  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4419  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4420  *
4421  * @pre This method can be called if @p scip is in one of the following stages:
4422  * - \ref SCIP_STAGE_PROBLEM
4423  * - \ref SCIP_STAGE_TRANSFORMING
4424  * - \ref SCIP_STAGE_INITPRESOLVE
4425  * - \ref SCIP_STAGE_PRESOLVING
4426  * - \ref SCIP_STAGE_EXITPRESOLVE
4427  * - \ref SCIP_STAGE_INITSOLVE
4428  * - \ref SCIP_STAGE_SOLVING
4429  * - \ref SCIP_STAGE_EXITSOLVE
4430  * - \ref SCIP_STAGE_FREETRANS
4431  */
4433  SCIP* scip, /**< SCIP data structure */
4434  SCIP_VAR* var, /**< problem variable */
4435  SCIP_CONS* cons, /**< constraint */
4436  SCIP_Bool lockdown, /**< should the rounding be unlocked in downwards direction? */
4437  SCIP_Bool lockup /**< should the rounding be unlocked in upwards direction? */
4438  )
4439 {
4440  int nlocksdown[NLOCKTYPES];
4441  int nlocksup[NLOCKTYPES];
4442  int i;
4443 
4444  SCIP_CALL( SCIPcheckStage(scip, "SCIPunlockVarCons", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4445 
4446  assert( var->scip == scip );
4447 
4448  for( i = 0; i < NLOCKTYPES; i++ )
4449  {
4450  nlocksdown[i] = 0;
4451  nlocksup[i] = 0;
4452 
4453  if( SCIPconsIsLockedTypePos(cons, (SCIP_LOCKTYPE) i) )
4454  {
4455  if( lockdown )
4456  ++nlocksdown[i];
4457  if( lockup )
4458  ++nlocksup[i];
4459  }
4460  if( SCIPconsIsLockedTypeNeg(cons, (SCIP_LOCKTYPE) i) )
4461  {
4462  if( lockdown )
4463  ++nlocksup[i];
4464  if( lockup )
4465  ++nlocksdown[i];
4466  }
4467  }
4468  switch( scip->set->stage )
4469  {
4470  case SCIP_STAGE_PROBLEM:
4471  assert(!SCIPvarIsTransformed(var));
4472  /*lint -fallthrough*/
4475  case SCIP_STAGE_PRESOLVING:
4477  case SCIP_STAGE_INITSOLVE:
4478  case SCIP_STAGE_SOLVING:
4479  case SCIP_STAGE_EXITSOLVE:
4480  case SCIP_STAGE_FREETRANS:
4481  for( i = 0; i < NLOCKTYPES; i++ )
4482  {
4483  if( nlocksdown[i] == 0 && nlocksup[i] == 0 )
4484  continue;
4485 
4486  SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, (SCIP_LOCKTYPE) i, -nlocksdown[i], -nlocksup[i]) );
4487  }
4488  return SCIP_OKAY;
4489 
4490  default:
4491  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4492  return SCIP_INVALIDCALL;
4493  } /*lint !e788*/
4494 }
4495 
4496 /** changes variable's objective value
4497  *
4498  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4499  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4500  *
4501  * @pre This method can be called if @p scip is in one of the following stages:
4502  * - \ref SCIP_STAGE_PROBLEM
4503  * - \ref SCIP_STAGE_TRANSFORMING
4504  * - \ref SCIP_STAGE_PRESOLVING
4505  * - \ref SCIP_STAGE_PRESOLVED
4506  */
4508  SCIP* scip, /**< SCIP data structure */
4509  SCIP_VAR* var, /**< variable to change the objective value for */
4510  SCIP_Real newobj /**< new objective value */
4511  )
4512 {
4513  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarObj", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
4514 
4515  assert( var->scip == scip );
4516 
4517  /* forbid infinite objective values */
4518  if( SCIPisInfinity(scip, REALABS(newobj)) )
4519  {
4520  SCIPerrorMessage("invalid objective value: objective value is infinite\n");
4521  return SCIP_INVALIDDATA;
4522  }
4523 
4524  switch( scip->set->stage )
4525  {
4526  case SCIP_STAGE_PROBLEM:
4527  assert(!SCIPvarIsTransformed(var));
4528  SCIP_CALL( SCIPvarChgObj(var, scip->mem->probmem, scip->set, scip->origprob, scip->primal, scip->lp, scip->eventqueue, newobj) );
4529  return SCIP_OKAY;
4530 
4533  case SCIP_STAGE_PRESOLVING:
4534  case SCIP_STAGE_PRESOLVED:
4535  SCIP_CALL( SCIPvarChgObj(var, scip->mem->probmem, scip->set, scip->transprob, scip->primal, scip->lp, scip->eventqueue, newobj) );
4536  return SCIP_OKAY;
4537 
4538  default:
4539  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4540  return SCIP_INVALIDCALL;
4541  } /*lint !e788*/
4542 }
4543 
4544 /** adds value to variable's objective value
4545  *
4546  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4547  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4548  *
4549  * @pre This method can be called if @p scip is in one of the following stages:
4550  * - \ref SCIP_STAGE_PROBLEM
4551  * - \ref SCIP_STAGE_TRANSFORMING
4552  * - \ref SCIP_STAGE_PRESOLVING
4553  * - \ref SCIP_STAGE_EXITPRESOLVE
4554  * - \ref SCIP_STAGE_PRESOLVED
4555  */
4557  SCIP* scip, /**< SCIP data structure */
4558  SCIP_VAR* var, /**< variable to change the objective value for */
4559  SCIP_Real addobj /**< additional objective value */
4560  )
4561 {
4562  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarObj", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
4563 
4564  assert( var->scip == scip );
4565 
4566  switch( scip->set->stage )
4567  {
4568  case SCIP_STAGE_PROBLEM:
4569  assert(!SCIPvarIsTransformed(var));
4570  SCIP_CALL( SCIPvarAddObj(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->primal,
4571  scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue, addobj) );
4572  return SCIP_OKAY;
4573 
4575  case SCIP_STAGE_PRESOLVING:
4577  case SCIP_STAGE_PRESOLVED:
4578  SCIP_CALL( SCIPvarAddObj(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->primal,
4579  scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue, addobj) );
4580  return SCIP_OKAY;
4581 
4582  default:
4583  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4584  return SCIP_INVALIDCALL;
4585  } /*lint !e788*/
4586 }
4587 
4588 /** returns the adjusted (i.e. rounded, if the given variable is of integral type) lower bound value;
4589  * does not change the bounds of the variable
4590  *
4591  * @return adjusted lower bound for the given variable; the bound of the variable is not changed
4592  *
4593  * @pre This method can be called if @p scip is in one of the following stages:
4594  * - \ref SCIP_STAGE_PROBLEM
4595  * - \ref SCIP_STAGE_TRANSFORMING
4596  * - \ref SCIP_STAGE_TRANSFORMED
4597  * - \ref SCIP_STAGE_INITPRESOLVE
4598  * - \ref SCIP_STAGE_PRESOLVING
4599  * - \ref SCIP_STAGE_EXITPRESOLVE
4600  * - \ref SCIP_STAGE_PRESOLVED
4601  * - \ref SCIP_STAGE_INITSOLVE
4602  * - \ref SCIP_STAGE_SOLVING
4603  * - \ref SCIP_STAGE_SOLVED
4604  * - \ref SCIP_STAGE_EXITSOLVE
4605  * - \ref SCIP_STAGE_FREETRANS
4606  */
4608  SCIP* scip, /**< SCIP data structure */
4609  SCIP_VAR* var, /**< variable to adjust the bound for */
4610  SCIP_Real lb /**< lower bound value to adjust */
4611  )
4612 {
4613  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPadjustedVarLb", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
4614 
4615  SCIPvarAdjustLb(var, scip->set, &lb);
4616 
4617  return lb;
4618 }
4619 
4620 /** returns the adjusted (i.e. rounded, if the given variable is of integral type) upper bound value;
4621  * does not change the bounds of the variable
4622  *
4623  * @return adjusted upper bound for the given variable; the bound of the variable is not changed
4624  *
4625  * @pre This method can be called if @p scip is in one of the following stages:
4626  * - \ref SCIP_STAGE_PROBLEM
4627  * - \ref SCIP_STAGE_TRANSFORMING
4628  * - \ref SCIP_STAGE_TRANSFORMED
4629  * - \ref SCIP_STAGE_INITPRESOLVE
4630  * - \ref SCIP_STAGE_PRESOLVING
4631  * - \ref SCIP_STAGE_EXITPRESOLVE
4632  * - \ref SCIP_STAGE_PRESOLVED
4633  * - \ref SCIP_STAGE_INITSOLVE
4634  * - \ref SCIP_STAGE_SOLVING
4635  * - \ref SCIP_STAGE_SOLVED
4636  * - \ref SCIP_STAGE_EXITSOLVE
4637  * - \ref SCIP_STAGE_FREETRANS
4638  */
4640  SCIP* scip, /**< SCIP data structure */
4641  SCIP_VAR* var, /**< variable to adjust the bound for */
4642  SCIP_Real ub /**< upper bound value to adjust */
4643  )
4644 {
4645  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPadjustedVarUb", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
4646 
4647  SCIPvarAdjustUb(var, scip->set, &ub);
4648 
4649  return ub;
4650 }
4651 
4652 /** depending on SCIP's stage, changes lower bound of variable in the problem, in preprocessing, or in current node;
4653  * if possible, adjusts bound to integral value; doesn't store any inference information in the bound change, such
4654  * that in conflict analysis, this change is treated like a branching decision
4655  *
4656  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4657  * SCIPgetVars()) gets resorted.
4658  *
4659  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4660  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4661  *
4662  * @pre This method can be called if @p scip is in one of the following stages:
4663  * - \ref SCIP_STAGE_PROBLEM
4664  * - \ref SCIP_STAGE_TRANSFORMING
4665  * - \ref SCIP_STAGE_PRESOLVING
4666  * - \ref SCIP_STAGE_SOLVING
4667  *
4668  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4669  */
4671  SCIP* scip, /**< SCIP data structure */
4672  SCIP_VAR* var, /**< variable to change the bound for */
4673  SCIP_Real newbound /**< new value for bound */
4674  )
4675 {
4676  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLb", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4677 
4678  SCIPvarAdjustLb(var, scip->set, &newbound);
4679 
4680  /* ignore tightenings of lower bounds to +infinity during solving process */
4681  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4682  {
4683 #ifndef NDEBUG
4684  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4685  SCIPvarGetLbLocal(var));
4686 #endif
4687  return SCIP_OKAY;
4688  }
4689 
4690  switch( scip->set->stage )
4691  {
4692  case SCIP_STAGE_PROBLEM:
4693  assert(!SCIPvarIsTransformed(var));
4694  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4695  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4696  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4697  scip->branchcand, scip->eventqueue, newbound) );
4698  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
4699  break;
4700 
4702  case SCIP_STAGE_PRESOLVED:
4703  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4704  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4705  break;
4706 
4707  case SCIP_STAGE_PRESOLVING:
4708  if( !SCIPinProbing(scip) )
4709  {
4710  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4711  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4712 
4713  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4714  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable,
4715  var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
4716 
4718  {
4719  SCIP_Bool infeasible;
4720 
4721  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
4722  assert(!infeasible);
4723  }
4724  break;
4725  }
4726  /*lint -fallthrough*/
4727  case SCIP_STAGE_SOLVING:
4729  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4730  scip->cliquetable, var, newbound,
4732  break;
4733 
4734  default:
4735  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4736  return SCIP_INVALIDCALL;
4737  } /*lint !e788*/
4738 
4739  return SCIP_OKAY;
4740 }
4741 
4742 /** depending on SCIP's stage, changes upper bound of variable in the problem, in preprocessing, or in current node;
4743  * if possible, adjusts bound to integral value; doesn't store any inference information in the bound change, such
4744  * that in conflict analysis, this change is treated like a branching decision
4745  *
4746  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4747  * SCIPgetVars()) gets resorted.
4748  *
4749  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4750  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4751  *
4752  * @pre This method can be called if @p scip is in one of the following stages:
4753  * - \ref SCIP_STAGE_PROBLEM
4754  * - \ref SCIP_STAGE_TRANSFORMING
4755  * - \ref SCIP_STAGE_PRESOLVING
4756  * - \ref SCIP_STAGE_SOLVING
4757  *
4758  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4759  */
4761  SCIP* scip, /**< SCIP data structure */
4762  SCIP_VAR* var, /**< variable to change the bound for */
4763  SCIP_Real newbound /**< new value for bound */
4764  )
4765 {
4766  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUb", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4767 
4768  SCIPvarAdjustUb(var, scip->set, &newbound);
4769 
4770  /* ignore tightenings of upper bounds to -infinity during solving process */
4771  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4772  {
4773 #ifndef NDEBUG
4774  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
4775  SCIPvarGetUbLocal(var));
4776 #endif
4777  return SCIP_OKAY;
4778  }
4779 
4780  switch( scip->set->stage )
4781  {
4782  case SCIP_STAGE_PROBLEM:
4783  assert(!SCIPvarIsTransformed(var));
4784  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4785  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4786  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4787  scip->branchcand, scip->eventqueue, newbound) );
4788  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
4789  break;
4790 
4792  case SCIP_STAGE_PRESOLVED:
4793  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4794  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4795  break;
4796 
4797  case SCIP_STAGE_PRESOLVING:
4798  if( !SCIPinProbing(scip) )
4799  {
4800  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4801  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4802 
4803  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4804  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4805  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
4806 
4808  {
4809  SCIP_Bool infeasible;
4810 
4811  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
4812  assert(!infeasible);
4813  }
4814  break;
4815  }
4816  /*lint -fallthrough*/
4817  case SCIP_STAGE_SOLVING:
4819  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4820  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
4821  break;
4822 
4823  default:
4824  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4825  return SCIP_INVALIDCALL;
4826  } /*lint !e788*/
4827 
4828  return SCIP_OKAY;
4829 }
4830 
4831 /** changes lower bound of variable in the given node; if possible, adjust bound to integral value; doesn't store any
4832  * inference information in the bound change, such that in conflict analysis, this change is treated like a branching
4833  * decision
4834  *
4835  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4836  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4837  *
4838  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
4839  */
4841  SCIP* scip, /**< SCIP data structure */
4842  SCIP_NODE* node, /**< node to change bound at, or NULL for current node */
4843  SCIP_VAR* var, /**< variable to change the bound for */
4844  SCIP_Real newbound /**< new value for bound */
4845  )
4846 {
4847  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbNode", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4848 
4849  if( node == NULL )
4850  {
4851  SCIP_CALL( SCIPchgVarLb(scip, var, newbound) );
4852  }
4853  else
4854  {
4855  SCIPvarAdjustLb(var, scip->set, &newbound);
4856 
4857  /* ignore tightenings of lower bounds to +infinity during solving process */
4858  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4859  {
4860 #ifndef NDEBUG
4861  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4862  SCIPvarGetLbLocal(var));
4863 #endif
4864  return SCIP_OKAY;
4865  }
4866 
4867  SCIP_CALL( SCIPnodeAddBoundchg(node, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
4868  scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4870  }
4871 
4872  return SCIP_OKAY;
4873 }
4874 
4875 /** changes upper bound of variable in the given node; if possible, adjust bound to integral value; doesn't store any
4876  * inference information in the bound change, such that in conflict analysis, this change is treated like a branching
4877  * decision
4878  *
4879  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4880  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4881  *
4882  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
4883  */
4885  SCIP* scip, /**< SCIP data structure */
4886  SCIP_NODE* node, /**< node to change bound at, or NULL for current node */
4887  SCIP_VAR* var, /**< variable to change the bound for */
4888  SCIP_Real newbound /**< new value for bound */
4889  )
4890 {
4891  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbNode", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4892 
4893  if( node == NULL )
4894  {
4895  SCIP_CALL( SCIPchgVarUb(scip, var, newbound) );
4896  }
4897  else
4898  {
4899  SCIPvarAdjustUb(var, scip->set, &newbound);
4900 
4901  /* ignore tightenings of upper bounds to -infinity during solving process */
4902  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4903  {
4904 #ifndef NDEBUG
4905  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
4906  SCIPvarGetUbLocal(var));
4907 #endif
4908  return SCIP_OKAY;
4909  }
4910 
4911  SCIP_CALL( SCIPnodeAddBoundchg(node, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
4912  scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4914  }
4915 
4916  return SCIP_OKAY;
4917 }
4918 
4919 /** changes global lower bound of variable; if possible, adjust bound to integral value; also tightens the local bound,
4920  * if the global bound is better than the local bound
4921  *
4922  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4923  * SCIPgetVars()) gets resorted.
4924  *
4925  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4926  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4927  *
4928  * @pre This method can be called if @p scip is in one of the following stages:
4929  * - \ref SCIP_STAGE_PROBLEM
4930  * - \ref SCIP_STAGE_TRANSFORMING
4931  * - \ref SCIP_STAGE_PRESOLVING
4932  * - \ref SCIP_STAGE_SOLVING
4933  *
4934  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4935  */
4937  SCIP* scip, /**< SCIP data structure */
4938  SCIP_VAR* var, /**< variable to change the bound for */
4939  SCIP_Real newbound /**< new value for bound */
4940  )
4941 {
4942  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbGlobal", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4943 
4944  SCIPvarAdjustLb(var, scip->set, &newbound);
4945 
4946  /* ignore tightenings of lower bounds to +infinity during solving process */
4947  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4948  {
4949 #ifndef NDEBUG
4950  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4951  SCIPvarGetLbLocal(var));
4952 #endif
4953  return SCIP_OKAY;
4954  }
4955 
4956  switch( scip->set->stage )
4957  {
4958  case SCIP_STAGE_PROBLEM:
4959  assert(!SCIPvarIsTransformed(var));
4960  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4961  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4962  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4963  scip->branchcand, scip->eventqueue, newbound) );
4964  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
4965  break;
4966 
4968  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4969  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4970  break;
4971 
4972  case SCIP_STAGE_PRESOLVING:
4973  if( !SCIPinProbing(scip) )
4974  {
4975  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4976  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4977 
4978  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4979  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4981 
4983  {
4984  SCIP_Bool infeasible;
4985 
4986  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
4987  assert(!infeasible);
4988  }
4989  break;
4990  }
4991  /*lint -fallthrough*/
4992  case SCIP_STAGE_SOLVING:
4993  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4994  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4996  break;
4997 
4998  default:
4999  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5000  return SCIP_INVALIDCALL;
5001  } /*lint !e788*/
5002 
5003  return SCIP_OKAY;
5004 }
5005 
5006 /** changes global upper bound of variable; if possible, adjust bound to integral value; also tightens the local bound,
5007  * if the global bound is better than the local bound
5008  *
5009  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5010  * SCIPgetVars()) gets resorted.
5011  *
5012  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5013  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5014  *
5015  * @pre This method can be called if @p scip is in one of the following stages:
5016  * - \ref SCIP_STAGE_PROBLEM
5017  * - \ref SCIP_STAGE_TRANSFORMING
5018  * - \ref SCIP_STAGE_PRESOLVING
5019  * - \ref SCIP_STAGE_SOLVING
5020  *
5021  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5022  */
5024  SCIP* scip, /**< SCIP data structure */
5025  SCIP_VAR* var, /**< variable to change the bound for */
5026  SCIP_Real newbound /**< new value for bound */
5027  )
5028 {
5029  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbGlobal", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5030 
5031  SCIPvarAdjustUb(var, scip->set, &newbound);
5032 
5033  /* ignore tightenings of upper bounds to -infinity during solving process */
5034  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5035  {
5036 #ifndef NDEBUG
5037  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5038  SCIPvarGetUbLocal(var));
5039 #endif
5040  return SCIP_OKAY;
5041  }
5042 
5043  switch( scip->set->stage )
5044  {
5045  case SCIP_STAGE_PROBLEM:
5046  assert(!SCIPvarIsTransformed(var));
5047  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5048  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5049  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5050  scip->branchcand, scip->eventqueue, newbound) );
5051  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
5052  break;
5053 
5055  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5056  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5057  break;
5058 
5059  case SCIP_STAGE_PRESOLVING:
5060  if( !SCIPinProbing(scip) )
5061  {
5062  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5063  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5064 
5065  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5066  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5068 
5070  {
5071  SCIP_Bool infeasible;
5072 
5073  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
5074  assert(!infeasible);
5075  }
5076  break;
5077  }
5078  /*lint -fallthrough*/
5079  case SCIP_STAGE_SOLVING:
5080  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5081  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5083  break;
5084 
5085  default:
5086  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5087  return SCIP_INVALIDCALL;
5088  } /*lint !e788*/
5089 
5090  return SCIP_OKAY;
5091 }
5092 
5093 /** changes lazy lower bound of the variable, this is only possible if the variable is not in the LP yet
5094  *
5095  * lazy bounds are bounds, that are enforced by constraints and the objective function; hence, these bounds do not need
5096  * to be put into the LP explicitly.
5097  *
5098  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5099  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5100  *
5101  * @pre This method can be called if @p scip is in one of the following stages:
5102  * - \ref SCIP_STAGE_PROBLEM
5103  * - \ref SCIP_STAGE_TRANSFORMING
5104  * - \ref SCIP_STAGE_TRANSFORMED
5105  * - \ref SCIP_STAGE_PRESOLVING
5106  * - \ref SCIP_STAGE_SOLVING
5107  *
5108  * @note lazy bounds are useful for branch-and-price since the corresponding variable bounds are not part of the LP
5109  */
5111  SCIP* scip, /**< SCIP data structure */
5112  SCIP_VAR* var, /**< problem variable */
5113  SCIP_Real lazylb /**< the lazy lower bound to be set */
5114  )
5115 {
5116  assert(scip != NULL);
5117  assert(var != NULL);
5118 
5119  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbLazy", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5120 
5121  SCIP_CALL( SCIPvarChgLbLazy(var, scip->set, lazylb) );
5122 
5123  return SCIP_OKAY;
5124 }
5125 
5126 /** changes lazy upper bound of the variable, this is only possible if the variable is not in the LP yet
5127  *
5128  * lazy bounds are bounds, that are enforced by constraints and the objective function; hence, these bounds do not need
5129  * to be put into the LP explicitly.
5130  *
5131  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5132  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5133  *
5134  * @pre This method can be called if @p scip is in one of the following stages:
5135  * - \ref SCIP_STAGE_PROBLEM
5136  * - \ref SCIP_STAGE_TRANSFORMING
5137  * - \ref SCIP_STAGE_TRANSFORMED
5138  * - \ref SCIP_STAGE_PRESOLVING
5139  * - \ref SCIP_STAGE_SOLVING
5140  *
5141  * @note lazy bounds are useful for branch-and-price since the corresponding variable bounds are not part of the LP
5142  */
5144  SCIP* scip, /**< SCIP data structure */
5145  SCIP_VAR* var, /**< problem variable */
5146  SCIP_Real lazyub /**< the lazy lower bound to be set */
5147  )
5148 {
5149  assert(scip != NULL);
5150  assert(var != NULL);
5151 
5152  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbLazy", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5153 
5154  SCIP_CALL( SCIPvarChgUbLazy(var, scip->set, lazyub) );
5155 
5156  return SCIP_OKAY;
5157 }
5158 
5159 /** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
5160  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5161  * doesn't store any inference information in the bound change, such that in conflict analysis, this change
5162  * is treated like a branching decision
5163  *
5164  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5165  * SCIPgetVars()) gets resorted.
5166  *
5167  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5168  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5169  *
5170  * @pre This method can be called if @p scip is in one of the following stages:
5171  * - \ref SCIP_STAGE_PROBLEM
5172  * - \ref SCIP_STAGE_PRESOLVING
5173  * - \ref SCIP_STAGE_SOLVING
5174  *
5175  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5176  */
5178  SCIP* scip, /**< SCIP data structure */
5179  SCIP_VAR* var, /**< variable to change the bound for */
5180  SCIP_Real newbound, /**< new value for bound */
5181  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5182  SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
5183  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5184  )
5185 {
5186  SCIP_Real lb;
5187  SCIP_Real ub;
5188 
5189  assert(infeasible != NULL);
5190 
5191  SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarLb", FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5192  /** @todo if needed provide pending local/global bound changes that will be flushed after leaving diving mode (as in struct_tree.h) */
5193  assert(SCIPgetStage(scip) == SCIP_STAGE_PROBLEM || !SCIPinDive(scip));
5194 
5195  *infeasible = FALSE;
5196  if( tightened != NULL )
5197  *tightened = FALSE;
5198 
5199  SCIPvarAdjustLb(var, scip->set, &newbound);
5200 
5201  /* ignore tightenings of lower bounds to +infinity during solving process */
5202  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5203  {
5204 #ifndef NDEBUG
5205  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
5206  SCIPvarGetLbLocal(var));
5207 #endif
5208  return SCIP_OKAY;
5209  }
5210 
5211  /* get current bounds */
5212  lb = SCIPcomputeVarLbLocal(scip, var);
5213  ub = SCIPcomputeVarUbLocal(scip, var);
5214  assert(SCIPsetIsLE(scip->set, lb, ub));
5215 
5216  if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
5217  {
5218  *infeasible = TRUE;
5219  return SCIP_OKAY;
5220  }
5221  newbound = MIN(newbound, ub);
5222 
5223  if( (force && SCIPsetIsLE(scip->set, newbound, lb)) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
5224  return SCIP_OKAY;
5225 
5226  switch( scip->set->stage )
5227  {
5228  case SCIP_STAGE_PROBLEM:
5229  assert(!SCIPvarIsTransformed(var));
5230  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5231  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5232  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5233  scip->branchcand, scip->eventqueue, newbound) );
5234  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
5235  break;
5237  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5238  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5239  break;
5240  case SCIP_STAGE_PRESOLVING:
5241  if( !SCIPinProbing(scip) )
5242  {
5243  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5244  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5245 
5246  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5247  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5249 
5251  {
5252  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5253  assert(!(*infeasible));
5254  }
5255  break;
5256  }
5257  /*lint -fallthrough*/
5258  case SCIP_STAGE_SOLVING:
5260  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable,
5261  var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
5262  break;
5263 
5264  default:
5265  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5266  return SCIP_INVALIDCALL;
5267  } /*lint !e788*/
5268 
5269  /* check whether the lower bound improved */
5270  if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
5271  *tightened = TRUE;
5272 
5273  return SCIP_OKAY;
5274 }
5275 
5276 /** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
5277  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5278  * doesn't store any inference information in the bound change, such that in conflict analysis, this change
5279  * is treated like a branching decision
5280  *
5281  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5282  * SCIPgetVars()) gets resorted.
5283  *
5284  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5285  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5286  *
5287  * @pre This method can be called if @p scip is in one of the following stages:
5288  * - \ref SCIP_STAGE_PROBLEM
5289  * - \ref SCIP_STAGE_PRESOLVING
5290  * - \ref SCIP_STAGE_SOLVING
5291  *
5292  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5293  */
5295  SCIP* scip, /**< SCIP data structure */
5296  SCIP_VAR* var, /**< variable to change the bound for */
5297  SCIP_Real newbound, /**< new value for bound */
5298  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5299  SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
5300  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5301  )
5302 {
5303  SCIP_Real lb;
5304  SCIP_Real ub;
5305 
5306  assert(infeasible != NULL);
5307  SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarUb", FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5308 
5309  /** @todo if needed provide pending local/global bound changes that will be flushed after leaving diving mode (as in struct_tree.h) */
5310  assert(SCIPgetStage(scip) == SCIP_STAGE_PROBLEM || !SCIPinDive(scip));
5311 
5312  *infeasible = FALSE;
5313  if( tightened != NULL )
5314  *tightened = FALSE;
5315 
5316  SCIPvarAdjustUb(var, scip->set, &newbound);
5317 
5318  /* ignore tightenings of upper bounds to -infinity during solving process */
5319  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5320  {
5321 #ifndef NDEBUG
5322  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5323  SCIPvarGetUbLocal(var));
5324 #endif
5325  return SCIP_OKAY;
5326  }
5327 
5328  /* get current bounds */
5329  lb = SCIPcomputeVarLbLocal(scip, var);
5330  ub = SCIPcomputeVarUbLocal(scip, var);
5331  assert(SCIPsetIsLE(scip->set, lb, ub));
5332 
5333  if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
5334  {
5335  *infeasible = TRUE;
5336  return SCIP_OKAY;
5337  }
5338  newbound = MAX(newbound, lb);
5339 
5340  if( (force && SCIPsetIsGE(scip->set, newbound, ub)) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
5341  return SCIP_OKAY;
5342 
5343  switch( scip->set->stage )
5344  {
5345  case SCIP_STAGE_PROBLEM:
5346  assert(!SCIPvarIsTransformed(var));
5347  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5348  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5349  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5350  scip->branchcand, scip->eventqueue, newbound) );
5351  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
5352  break;
5354  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5355  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5356  break;
5357  case SCIP_STAGE_PRESOLVING:
5358  if( !SCIPinProbing(scip) )
5359  {
5360  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5361  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5362 
5363  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5364  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5366 
5368  {
5369  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5370  assert(!(*infeasible));
5371  }
5372  break;
5373  }
5374  /*lint -fallthrough*/
5375  case SCIP_STAGE_SOLVING:
5377  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5378  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
5379  break;
5380 
5381  default:
5382  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5383  return SCIP_INVALIDCALL;
5384  } /*lint !e788*/
5385 
5386  /* check whether the upper bound improved */
5387  if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
5388  *tightened = TRUE;
5389 
5390  return SCIP_OKAY;
5391 }
5392 
5393 /** fixes variable in preprocessing or in the current node, if the new bound is tighter (w.r.t. bound strengthening
5394  * epsilon) than the current bound; if possible, adjusts bound to integral value; the given inference constraint is
5395  * stored, such that the conflict analysis is able to find out the reason for the deduction of the bound change
5396  *
5397  * @note In presolving stage when not in probing mode the variable will be fixed directly, otherwise this method
5398  * changes first the lowerbound by calling SCIPinferVarLbCons and second the upperbound by calling
5399  * SCIPinferVarUbCons
5400  *
5401  * @note If SCIP is in presolving stage, it can happen that the internal variable array (which get be accessed via
5402  * SCIPgetVars()) gets resorted.
5403  *
5404  * @note During presolving, an integer variable which bound changes to {0,1} is upgraded to a binary variable.
5405  */
5407  SCIP* scip, /**< SCIP data structure */
5408  SCIP_VAR* var, /**< variable to change the bound for */
5409  SCIP_Real fixedval, /**< new value for fixation */
5410  SCIP_CONS* infercons, /**< constraint that deduced the bound change */
5411  int inferinfo, /**< user information for inference to help resolving the conflict */
5412  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5413  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5414  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5415  )
5416 {
5417  assert(scip != NULL);
5418  assert(var != NULL);
5419  assert(infeasible != NULL);
5420 
5421  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarFixCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5422 
5423  if( tightened != NULL )
5424  *tightened = FALSE;
5425 
5426  /* in presolving case we take the shortcut to directly fix the variables */
5427  if( SCIPgetStage(scip) == SCIP_STAGE_PRESOLVING && SCIPtreeGetCurrentDepth(scip->tree) == 0 )
5428  {
5429  SCIP_Bool fixed;
5430 
5431  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5432  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter,
5433  scip->eventqueue, scip->cliquetable, fixedval, infeasible, &fixed) );
5434 
5435  if( tightened != NULL )
5436  *tightened = fixed;
5437  }
5438  /* otherwise we use the lb and ub methods */
5439  else
5440  {
5441  SCIP_Bool lbtightened;
5442 
5443  SCIP_CALL( SCIPinferVarLbCons(scip, var, fixedval, infercons, inferinfo, force, infeasible, &lbtightened) );
5444 
5445  if( ! (*infeasible) )
5446  {
5447  SCIP_CALL( SCIPinferVarUbCons(scip, var, fixedval, infercons, inferinfo, force, infeasible, tightened) );
5448 
5449  if( tightened != NULL )
5450  *tightened |= lbtightened;
5451  }
5452  }
5453 
5454  return SCIP_OKAY;
5455 }
5456 
5457 /** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
5458  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5459  * the given inference constraint is stored, such that the conflict analysis is able to find out the reason
5460  * for the deduction of the bound change
5461  *
5462  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5463  * SCIPgetVars()) gets resorted.
5464  *
5465  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5466  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5467  *
5468  * @pre This method can be called if @p scip is in one of the following stages:
5469  * - \ref SCIP_STAGE_PROBLEM
5470  * - \ref SCIP_STAGE_PRESOLVING
5471  * - \ref SCIP_STAGE_SOLVING
5472  *
5473  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5474  */
5476  SCIP* scip, /**< SCIP data structure */
5477  SCIP_VAR* var, /**< variable to change the bound for */
5478  SCIP_Real newbound, /**< new value for bound */
5479  SCIP_CONS* infercons, /**< constraint that deduced the bound change */
5480  int inferinfo, /**< user information for inference to help resolving the conflict */
5481  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5482  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5483  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5484  )
5485 {
5486  SCIP_Real lb;
5487  SCIP_Real ub;
5488 
5489  assert(infeasible != NULL);
5490 
5491  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarLbCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5492 
5493  *infeasible = FALSE;
5494  if( tightened != NULL )
5495  *tightened = FALSE;
5496 
5497  SCIPvarAdjustLb(var, scip->set, &newbound);
5498 
5499  /* ignore tightenings of lower bounds to +infinity during solving process */
5500  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5501  {
5502 #ifndef NDEBUG
5503  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
5504  SCIPvarGetLbLocal(var));
5505 #endif
5506  return SCIP_OKAY;
5507  }
5508 
5509  /* get current bounds */
5510  lb = SCIPvarGetLbLocal(var);
5511  ub = SCIPvarGetUbLocal(var);
5512  assert(SCIPsetIsLE(scip->set, lb, ub));
5513 
5514  if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
5515  {
5516  *infeasible = TRUE;
5517  return SCIP_OKAY;
5518  }
5519  newbound = MIN(newbound, ub);
5520 
5521  if( (force && SCIPsetIsLE(scip->set, newbound, lb)) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
5522  return SCIP_OKAY;
5523 
5524  switch( scip->set->stage )
5525  {
5526  case SCIP_STAGE_PROBLEM:
5527  assert(!SCIPvarIsTransformed(var));
5528  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5529  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5530  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5531  scip->branchcand, scip->eventqueue, newbound) );
5532  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
5533  break;
5534 
5535  case SCIP_STAGE_PRESOLVING:
5536  if( !SCIPinProbing(scip) )
5537  {
5538  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5539  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5540 
5541  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5542  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5544 
5546  {
5547  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5548  assert(!(*infeasible));
5549  }
5550  break;
5551  }
5552  /*lint -fallthrough*/
5553  case SCIP_STAGE_SOLVING:
5555  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5556  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, infercons, NULL, inferinfo, FALSE) );
5557  break;
5558 
5559  default:
5560  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5561  return SCIP_INVALIDCALL;
5562  } /*lint !e788*/
5563 
5564  /* check whether the lower bound improved */
5565  if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
5566  *tightened = TRUE;
5567 
5568  return SCIP_OKAY;
5569 }
5570 
5571 /** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
5572  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5573  * the given inference constraint is stored, such that the conflict analysis is able to find out the reason
5574  * for the deduction of the bound change
5575  *
5576  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5577  * SCIPgetVars()) gets resorted.
5578  *
5579  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5580  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5581  *
5582  * @pre This method can be called if @p scip is in one of the following stages:
5583  * - \ref SCIP_STAGE_PROBLEM
5584  * - \ref SCIP_STAGE_PRESOLVING
5585  * - \ref SCIP_STAGE_SOLVING
5586  *
5587  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5588  */
5590  SCIP* scip, /**< SCIP data structure */
5591  SCIP_VAR* var, /**< variable to change the bound for */
5592  SCIP_Real newbound, /**< new value for bound */
5593  SCIP_CONS* infercons, /**< constraint that deduced the bound change */
5594  int inferinfo, /**< user information for inference to help resolving the conflict */
5595  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5596  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5597  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5598  )
5599 {
5600  SCIP_Real lb;
5601  SCIP_Real ub;
5602 
5603  assert(infeasible != NULL);
5604 
5605  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarUbCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5606 
5607  *infeasible = FALSE;
5608  if( tightened != NULL )
5609  *tightened = FALSE;
5610 
5611  SCIPvarAdjustUb(var, scip->set, &newbound);
5612 
5613  /* ignore tightenings of upper bounds to -infinity during solving process */
5614  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5615  {
5616 #ifndef NDEBUG
5617  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5618  SCIPvarGetUbLocal(var));
5619 #endif
5620  return SCIP_OKAY;
5621  }
5622 
5623  /* get current bounds */
5624  lb = SCIPvarGetLbLocal(var);
5625  ub = SCIPvarGetUbLocal(var);
5626  assert(SCIPsetIsLE(scip->set, lb, ub));
5627 
5628  if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
5629  {
5630  *infeasible = TRUE;
5631  return SCIP_OKAY;
5632  }
5633  newbound = MAX(newbound, lb);
5634 
5635  if( (force && SCIPsetIsGE(scip->set, newbound, ub)) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
5636  return SCIP_OKAY;
5637 
5638  switch( scip->set->stage )
5639  {
5640  case SCIP_STAGE_PROBLEM:
5641  assert(!SCIPvarIsTransformed(var));
5642  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5643  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5644  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5645  scip->branchcand, scip->eventqueue, newbound) );
5646  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
5647  break;
5648 
5649  case SCIP_STAGE_PRESOLVING:
5650  if( !SCIPinProbing(scip) )
5651  {
5652  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5653  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5654 
5655  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5656  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5658 
5660  {
5661  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5662  assert(!(*infeasible));
5663  }
5664  break;
5665  }
5666  /*lint -fallthrough*/
5667  case SCIP_STAGE_SOLVING:
5669  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5670  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, infercons, NULL, inferinfo, FALSE) );
5671  break;
5672 
5673  default:
5674  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5675  return SCIP_INVALIDCALL;
5676  } /*lint !e788*/
5677 
5678  /* check whether the upper bound improved */
5679  if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
5680  *tightened = TRUE;
5681 
5682  return SCIP_OKAY;
5683 }
5684 
5685 /** depending on SCIP's stage, fixes binary variable in the problem, in preprocessing, or in current node;
5686  * the given inference constraint is stored, such that the conflict analysis is able to find out the reason for the
5687  * deduction of the fixing
5688  *
5689  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5690  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5691  *
5692  * @pre This method can be called if @p scip is in one of the following stages:
5693  * - \ref SCIP_STAGE_PROBLEM
5694  * - \ref SCIP_STAGE_PRESOLVING
5695  * - \ref SCIP_STAGE_SOLVING
5696  */
5698  SCIP* scip, /**< SCIP data structure */
5699  SCIP_VAR* var, /**< binary variable to fix */
5700  SCIP_Bool fixedval, /**< value to fix binary variable to */
5701  SCIP_CONS* infercons, /**< constraint that deduced the fixing */
5702  int inferinfo, /**< user information for inference to help resolving the conflict */
5703  SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
5704  SCIP_Bool* tightened /**< pointer to store whether the fixing tightened the local bounds, or NULL */
5705  )
5706 {
5707  SCIP_Real lb;
5708  SCIP_Real ub;
5709 
5710  assert(SCIPvarIsBinary(var));
5711  assert(fixedval == TRUE || fixedval == FALSE);
5712  assert(infeasible != NULL);
5713 
5714  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferBinvarCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5715 
5716  *infeasible = FALSE;
5717  if( tightened != NULL )
5718  *tightened = FALSE;
5719 
5720  /* get current bounds */
5721  lb = SCIPvarGetLbLocal(var);
5722  ub = SCIPvarGetUbLocal(var);
5723  assert(SCIPsetIsEQ(scip->set, lb, 0.0) || SCIPsetIsEQ(scip->set, lb, 1.0));
5724  assert(SCIPsetIsEQ(scip->set, ub, 0.0) || SCIPsetIsEQ(scip->set, ub, 1.0));
5725  assert(SCIPsetIsLE(scip->set, lb, ub));
5726 
5727  /* check, if variable is already fixed */
5728  if( (lb > 0.5) || (ub < 0.5) )
5729  {
5730  *infeasible = (fixedval == (lb < 0.5));
5731 
5732  return SCIP_OKAY;
5733  }
5734 
5735  /* apply the fixing */
5736  switch( scip->set->stage )
5737  {
5738  case SCIP_STAGE_PROBLEM:
5739  assert(!SCIPvarIsTransformed(var));
5740  if( fixedval == TRUE )
5741  {
5742  SCIP_CALL( SCIPchgVarLb(scip, var, 1.0) );
5743  }
5744  else
5745  {
5746  SCIP_CALL( SCIPchgVarUb(scip, var, 0.0) );
5747  }
5748  break;
5749 
5750  case SCIP_STAGE_PRESOLVING:
5751  if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
5752  {
5753  SCIP_Bool fixed;
5754 
5755  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5756  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
5757  scip->cliquetable, (SCIP_Real)fixedval, infeasible, &fixed) );
5758  break;
5759  }
5760  /*lint -fallthrough*/
5761  case SCIP_STAGE_SOLVING:
5762  if( fixedval == TRUE )
5763  {
5765  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5766  scip->cliquetable, var, 1.0, SCIP_BOUNDTYPE_LOWER, infercons, NULL, inferinfo, FALSE) );
5767  }
5768  else
5769  {
5771  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5772  scip->cliquetable, var, 0.0, SCIP_BOUNDTYPE_UPPER, infercons, NULL, inferinfo, FALSE) );
5773  }
5774  break;
5775 
5776  default:
5777  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5778  return SCIP_INVALIDCALL;
5779  } /*lint !e788*/
5780 
5781  if( tightened != NULL )
5782  *tightened = TRUE;
5783 
5784  return SCIP_OKAY;
5785 }
5786 
5787 /** fixes variable in preprocessing or in the current node, if the new bound is tighter (w.r.t. bound strengthening
5788  * epsilon) than the current bound; if possible, adjusts bound to integral value; the given inference constraint is
5789  * stored, such that the conflict analysis is able to find out the reason for the deduction of the bound change
5790  *
5791  * @note In presolving stage when not in probing mode the variable will be fixed directly, otherwise this method
5792  * changes first the lowerbound by calling SCIPinferVarLbProp and second the upperbound by calling
5793  * SCIPinferVarUbProp
5794  *
5795  * @note If SCIP is in presolving stage, it can happen that the internal variable array (which get be accessed via
5796  * SCIPgetVars()) gets resorted.
5797  *
5798  * @note During presolving, an integer variable which bound changes to {0,1} is upgraded to a binary variable.
5799  */
5801  SCIP* scip, /**< SCIP data structure */
5802  SCIP_VAR* var, /**< variable to change the bound for */
5803  SCIP_Real fixedval, /**< new value for fixation */
5804  SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
5805  int inferinfo, /**< user information for inference to help resolving the conflict */
5806  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5807  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5808  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5809  )
5810 {
5811  assert(scip != NULL);
5812  assert(var != NULL);
5813  assert(infeasible != NULL);
5814 
5815  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarFixProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5816 
5817  if( tightened != NULL )
5818  *tightened = FALSE;
5819 
5820  /* in presolving case we take the shortcut to directly fix the variables */
5821  if( SCIPgetStage(scip) == SCIP_STAGE_PRESOLVING && SCIPtreeGetCurrentDepth(scip->tree) == 0 )
5822  {
5823  SCIP_Bool fixed;
5824 
5825  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5826  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
5827  scip->cliquetable, fixedval, infeasible, &fixed) );
5828 
5829  if( tightened != NULL )
5830  *tightened = fixed;
5831  }
5832  /* otherwise we use the lb and ub methods */
5833  else
5834  {
5835  SCIP_Bool lbtightened;
5836 
5837  SCIP_CALL( SCIPinferVarLbProp(scip, var, fixedval, inferprop, inferinfo, force, infeasible, &lbtightened) );
5838 
5839  if( ! (*infeasible) )
5840  {
5841  SCIP_CALL( SCIPinferVarUbProp(scip, var, fixedval, inferprop, inferinfo, force, infeasible, tightened) );
5842 
5843  if( tightened != NULL )
5844  *tightened |= lbtightened;
5845  }
5846  }
5847 
5848  return SCIP_OKAY;
5849 }
5850 
5851 /** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
5852  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5853  * the given inference propagator is stored, such that the conflict analysis is able to find out the reason
5854  * for the deduction of the bound change
5855  *
5856  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5857  * SCIPgetVars()) gets resorted.
5858  *
5859  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5860  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5861  *
5862  * @pre This method can be called if @p scip is in one of the following stages:
5863  * - \ref SCIP_STAGE_PROBLEM
5864  * - \ref SCIP_STAGE_PRESOLVING
5865  * - \ref SCIP_STAGE_SOLVING
5866  *
5867  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5868  */
5870  SCIP* scip, /**< SCIP data structure */
5871  SCIP_VAR* var, /**< variable to change the bound for */
5872  SCIP_Real newbound, /**< new value for bound */
5873  SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
5874  int inferinfo, /**< user information for inference to help resolving the conflict */
5875  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5876  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5877  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5878  )
5879 {
5880  SCIP_Real lb;
5881  SCIP_Real ub;
5882 
5883  assert(infeasible != NULL);
5884 
5885  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarLbProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5886 
5887  *infeasible = FALSE;
5888  if( tightened != NULL )
5889  *tightened = FALSE;
5890 
5891  SCIPvarAdjustLb(var, scip->set, &newbound);
5892 
5893  /* ignore tightenings of lower bounds to +infinity during solving process */
5894  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5895  {
5896 #ifndef NDEBUG
5897  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
5898  SCIPvarGetLbLocal(var));
5899 #endif
5900  return SCIP_OKAY;
5901  }
5902 
5903  /* get current bounds */
5904  lb = SCIPvarGetLbLocal(var);
5905  ub = SCIPvarGetUbLocal(var);
5906  assert(SCIPsetIsLE(scip->set, lb, ub));
5907 
5908  if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
5909  {
5910  *infeasible = TRUE;
5911  return SCIP_OKAY;
5912  }
5913  newbound = MIN(newbound, ub);
5914 
5915  if( (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub))
5916  || SCIPsetIsLE(scip->set, newbound, lb) )
5917  return SCIP_OKAY;
5918 
5919  switch( scip->set->stage )
5920  {
5921  case SCIP_STAGE_PROBLEM:
5922  assert(!SCIPvarIsTransformed(var));
5923  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5924  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5925  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5926  scip->branchcand, scip->eventqueue, newbound) );
5927  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
5928  break;
5929 
5930  case SCIP_STAGE_PRESOLVING:
5931  if( !SCIPinProbing(scip) )
5932  {
5933  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5934  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5935 
5936  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5937  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5939 
5941  {
5942  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5943  assert(!(*infeasible));
5944  }
5945  break;
5946  }
5947  /*lint -fallthrough*/
5948  case SCIP_STAGE_SOLVING:
5950  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5951  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, NULL, inferprop, inferinfo, FALSE) );
5952  break;
5953 
5954  default:
5955  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5956  return SCIP_INVALIDCALL;
5957  } /*lint !e788*/
5958 
5959  /* check whether the lower bound improved */
5960  if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
5961  *tightened = TRUE;
5962 
5963  return SCIP_OKAY;
5964 }
5965 
5966 /** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
5967  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5968  * the given inference propagator is stored, such that the conflict analysis is able to find out the reason
5969  * for the deduction of the bound change
5970  *
5971  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5972  * SCIPgetVars()) gets resorted.
5973  *
5974  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5975  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5976  *
5977  * @pre This method can be called if @p scip is in one of the following stages:
5978  * - \ref SCIP_STAGE_PROBLEM
5979  * - \ref SCIP_STAGE_PRESOLVING
5980  * - \ref SCIP_STAGE_SOLVING
5981  *
5982  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5983  */
5985  SCIP* scip, /**< SCIP data structure */
5986  SCIP_VAR* var, /**< variable to change the bound for */
5987  SCIP_Real newbound, /**< new value for bound */
5988  SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
5989  int inferinfo, /**< user information for inference to help resolving the conflict */
5990  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5991  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5992  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5993  )
5994 {
5995  SCIP_Real lb;
5996  SCIP_Real ub;
5997 
5998  assert(infeasible != NULL);
5999 
6000  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarUbProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6001 
6002  *infeasible = FALSE;
6003  if( tightened != NULL )
6004  *tightened = FALSE;
6005 
6006  SCIPvarAdjustUb(var, scip->set, &newbound);
6007 
6008  /* ignore tightenings of upper bounds to -infinity during solving process */
6009  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6010  {
6011 #ifndef NDEBUG
6012  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
6013  SCIPvarGetUbLocal(var));
6014 #endif
6015  return SCIP_OKAY;
6016  }
6017 
6018  /* get current bounds */
6019  lb = SCIPvarGetLbLocal(var);
6020  ub = SCIPvarGetUbLocal(var);
6021  assert(SCIPsetIsLE(scip->set, lb, ub));
6022 
6023  if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
6024  {
6025  *infeasible = TRUE;
6026  return SCIP_OKAY;
6027  }
6028  newbound = MAX(newbound, lb);
6029 
6030  if( (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub))
6031  || SCIPsetIsGE(scip->set, newbound, ub) )
6032  return SCIP_OKAY;
6033 
6034  switch( scip->set->stage )
6035  {
6036  case SCIP_STAGE_PROBLEM:
6037  assert(!SCIPvarIsTransformed(var));
6038  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6039  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6040  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6041  scip->branchcand, scip->eventqueue, newbound) );
6042  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
6043  break;
6044 
6045  case SCIP_STAGE_PRESOLVING:
6046  if( !SCIPinProbing(scip) )
6047  {
6048  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6049  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6050 
6051  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6052  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6054 
6056  {
6057  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6058  assert(!(*infeasible));
6059  }
6060  break;
6061  }
6062  /*lint -fallthrough*/
6063  case SCIP_STAGE_SOLVING:
6065  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
6066  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, NULL, inferprop, inferinfo, FALSE) );
6067  break;
6068 
6069  default:
6070  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6071  return SCIP_INVALIDCALL;
6072  } /*lint !e788*/
6073 
6074  /* check whether the upper bound improved */
6075  if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
6076  *tightened = TRUE;
6077 
6078  return SCIP_OKAY;
6079 }
6080 
6081 /** depending on SCIP's stage, fixes binary variable in the problem, in preprocessing, or in current node;
6082  * the given inference propagator is stored, such that the conflict analysis is able to find out the reason for the
6083  * deduction of the fixing
6084  *
6085  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6086  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6087  *
6088  * @pre This method can be called if @p scip is in one of the following stages:
6089  * - \ref SCIP_STAGE_PROBLEM
6090  * - \ref SCIP_STAGE_PRESOLVING
6091  * - \ref SCIP_STAGE_PRESOLVED
6092  * - \ref SCIP_STAGE_SOLVING
6093  */
6095  SCIP* scip, /**< SCIP data structure */
6096  SCIP_VAR* var, /**< binary variable to fix */
6097  SCIP_Bool fixedval, /**< value to fix binary variable to */
6098  SCIP_PROP* inferprop, /**< propagator that deduced the fixing */
6099  int inferinfo, /**< user information for inference to help resolving the conflict */
6100  SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
6101  SCIP_Bool* tightened /**< pointer to store whether the fixing tightened the local bounds, or NULL */
6102  )
6103 {
6104  SCIP_Real lb;
6105  SCIP_Real ub;
6106 
6107  assert(SCIPvarIsBinary(var));
6108  assert(fixedval == TRUE || fixedval == FALSE);
6109  assert(infeasible != NULL);
6110 
6111  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferBinvarProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6112 
6113  *infeasible = FALSE;
6114  if( tightened != NULL )
6115  *tightened = FALSE;
6116 
6117  /* get current bounds */
6118  lb = SCIPvarGetLbLocal(var);
6119  ub = SCIPvarGetUbLocal(var);
6120  assert(SCIPsetIsEQ(scip->set, lb, 0.0) || SCIPsetIsEQ(scip->set, lb, 1.0));
6121  assert(SCIPsetIsEQ(scip->set, ub, 0.0) || SCIPsetIsEQ(scip->set, ub, 1.0));
6122  assert(SCIPsetIsLE(scip->set, lb, ub));
6123 
6124  /* check, if variable is already fixed */
6125  if( (lb > 0.5) || (ub < 0.5) )
6126  {
6127  *infeasible = (fixedval == (lb < 0.5));
6128 
6129  return SCIP_OKAY;
6130  }
6131 
6132  /* apply the fixing */
6133  switch( scip->set->stage )
6134  {
6135  case SCIP_STAGE_PROBLEM:
6136  assert(!SCIPvarIsTransformed(var));
6137  if( fixedval == TRUE )
6138  {
6139  SCIP_CALL( SCIPchgVarLb(scip, var, 1.0) );
6140  }
6141  else
6142  {
6143  SCIP_CALL( SCIPchgVarUb(scip, var, 0.0) );
6144  }
6145  break;
6146 
6147  case SCIP_STAGE_PRESOLVING:
6148  if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
6149  {
6150  SCIP_Bool fixed;
6151 
6152  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6153  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
6154  scip->cliquetable, (SCIP_Real)fixedval, infeasible, &fixed) );
6155  break;
6156  }
6157  /*lint -fallthrough*/
6158  case SCIP_STAGE_SOLVING:
6159  if( fixedval == TRUE )
6160  {
6162  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, 1.0,
6163  SCIP_BOUNDTYPE_LOWER, NULL, inferprop, inferinfo, FALSE) );
6164  }
6165  else
6166  {
6168  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, 0.0,
6169  SCIP_BOUNDTYPE_UPPER, NULL, inferprop, inferinfo, FALSE) );
6170  }
6171  break;
6172 
6173  default:
6174  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6175  return SCIP_INVALIDCALL;
6176  } /*lint !e788*/
6177 
6178  if( tightened != NULL )
6179  *tightened = TRUE;
6180 
6181  return SCIP_OKAY;
6182 }
6183 
6184 /** changes global lower bound of variable in preprocessing or in the current node, if the new bound is tighter
6185  * (w.r.t. bound strengthening epsilon) than the current global bound; if possible, adjusts bound to integral value;
6186  * also tightens the local bound, if the global bound is better than the local bound
6187  *
6188  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6189  * SCIPgetVars()) gets resorted.
6190  *
6191  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6192  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6193  *
6194  * @pre This method can be called if @p scip is in one of the following stages:
6195  * - \ref SCIP_STAGE_PROBLEM
6196  * - \ref SCIP_STAGE_TRANSFORMING
6197  * - \ref SCIP_STAGE_PRESOLVING
6198  * - \ref SCIP_STAGE_SOLVING
6199  *
6200  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6201  */
6203  SCIP* scip, /**< SCIP data structure */
6204  SCIP_VAR* var, /**< variable to change the bound for */
6205  SCIP_Real newbound, /**< new value for bound */
6206  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6207  SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
6208  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6209  )
6210 {
6211  SCIP_Real lb;
6212  SCIP_Real ub;
6213 
6214  assert(infeasible != NULL);
6215 
6216  SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarLbGlobal", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6217 
6218  *infeasible = FALSE;
6219  if( tightened != NULL )
6220  *tightened = FALSE;
6221 
6222  SCIPvarAdjustLb(var, scip->set, &newbound);
6223 
6224  /* ignore tightenings of lower bounds to +infinity during solving process */
6225  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6226  {
6227 #ifndef NDEBUG
6228  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
6229  SCIPvarGetLbLocal(var));
6230 #endif
6231  return SCIP_OKAY;
6232  }
6233 
6234  /* get current bounds */
6235  lb = SCIPvarGetLbGlobal(var);
6236  ub = SCIPvarGetUbGlobal(var);
6237  assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPsetIsLE(scip->set, lb, ub));
6238 
6239  if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
6240  {
6241  *infeasible = TRUE;
6242  return SCIP_OKAY;
6243  }
6244  newbound = MIN(newbound, ub);
6245 
6246  /* bound changes of less than epsilon are ignored by SCIPvarChgLb or raise an assert in SCIPnodeAddBoundinfer,
6247  * so don't apply them even if force is set
6248  */
6249  if( SCIPsetIsEQ(scip->set, lb, newbound) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
6250  return SCIP_OKAY;
6251 
6252  switch( scip->set->stage )
6253  {
6254  case SCIP_STAGE_PROBLEM:
6255  assert(!SCIPvarIsTransformed(var));
6256  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6257  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6258  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6259  scip->branchcand, scip->eventqueue, newbound) );
6260  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
6261  break;
6262 
6264  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6265  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6266  break;
6267 
6268  case SCIP_STAGE_PRESOLVING:
6269  if( !SCIPinProbing(scip) )
6270  {
6271  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6272  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6273 
6274  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6275  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6277 
6279  {
6280  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6281  assert(!(*infeasible));
6282  }
6283  break;
6284  }
6285  /*lint -fallthrough*/
6286  case SCIP_STAGE_SOLVING:
6287  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6288  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6290  break;
6291 
6292  default:
6293  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6294  return SCIP_INVALIDCALL;
6295  } /*lint !e788*/
6296 
6297  /* coverity: unreachable code */
6298  if( tightened != NULL && lb < SCIPcomputeVarLbGlobal(scip, var) )
6299  *tightened = TRUE;
6300 
6301  return SCIP_OKAY;
6302 }
6303 
6304 /** changes global upper bound of variable in preprocessing or in the current node, if the new bound is tighter
6305  * (w.r.t. bound strengthening epsilon) than the current global bound; if possible, adjusts bound to integral value;
6306  * also tightens the local bound, if the global bound is better than the local bound
6307  *
6308  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6309  * SCIPgetVars()) gets resorted.
6310  *
6311  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6312  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6313  *
6314  * @pre This method can be called if @p scip is in one of the following stages:
6315  * - \ref SCIP_STAGE_PROBLEM
6316  * - \ref SCIP_STAGE_TRANSFORMING
6317  * - \ref SCIP_STAGE_PRESOLVING
6318  * - \ref SCIP_STAGE_SOLVING
6319  *
6320  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6321  */
6323  SCIP* scip, /**< SCIP data structure */
6324  SCIP_VAR* var, /**< variable to change the bound for */
6325  SCIP_Real newbound, /**< new value for bound */
6326  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6327  SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
6328  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6329  )
6330 {
6331  SCIP_Real lb;
6332  SCIP_Real ub;
6333 
6334  assert(infeasible != NULL);
6335 
6336  SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarUbGlobal", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6337 
6338  *infeasible = FALSE;
6339  if( tightened != NULL )
6340  *tightened = FALSE;
6341 
6342  SCIPvarAdjustUb(var, scip->set, &newbound);
6343 
6344  /* ignore tightenings of upper bounds to -infinity during solving process */
6345  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6346  {
6347 #ifndef NDEBUG
6348  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
6349  SCIPvarGetUbLocal(var));
6350 #endif
6351  return SCIP_OKAY;
6352  }
6353 
6354  /* get current bounds */
6355  lb = SCIPvarGetLbGlobal(var);
6356  ub = SCIPvarGetUbGlobal(var);
6357  assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPsetIsLE(scip->set, lb, ub));
6358 
6359  if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
6360  {
6361  *infeasible = TRUE;
6362  return SCIP_OKAY;
6363  }
6364  newbound = MAX(newbound, lb);
6365 
6366  /* bound changes of less than epsilon are ignored by SCIPvarChgUb or raise an assert in SCIPnodeAddBoundinfer,
6367  * so don't apply them even if force is set
6368  */
6369  if( SCIPsetIsEQ(scip->set, ub, newbound) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
6370  return SCIP_OKAY;
6371 
6372  switch( scip->set->stage )
6373  {
6374  case SCIP_STAGE_PROBLEM:
6375  assert(!SCIPvarIsTransformed(var));
6376  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6377  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6378  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6379  scip->branchcand, scip->eventqueue, newbound) );
6380  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
6381  break;
6382 
6384  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6385  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6386  break;
6387 
6388  case SCIP_STAGE_PRESOLVING:
6389  if( !SCIPinProbing(scip) )
6390  {
6391  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6392  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6393 
6394  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6395  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6397 
6399  {
6400  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6401  assert(!(*infeasible));
6402  }
6403  break;
6404  }
6405  /*lint -fallthrough*/
6406  case SCIP_STAGE_SOLVING:
6407  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6408  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6410  break;
6411 
6412  default:
6413  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6414  return SCIP_INVALIDCALL;
6415  } /*lint !e788*/
6416 
6417  /* coverity: unreachable code */
6418  if( tightened != NULL && ub > SCIPcomputeVarUbGlobal(scip, var) )
6419  *tightened = TRUE;
6420 
6421  return SCIP_OKAY;
6422 }
6423 
6424 /* some simple variable functions implemented as defines */
6425 #undef SCIPcomputeVarLbGlobal
6426 #undef SCIPcomputeVarUbGlobal
6427 #undef SCIPcomputeVarLbLocal
6428 #undef SCIPcomputeVarUbLocal
6429 
6430 /** for a multi-aggregated variable, returns the global lower bound computed by adding the global bounds from all aggregation variables
6431  *
6432  * 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
6433  * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetLbGlobal.
6434  *
6435  * @return the global lower bound computed by adding the global bounds from all aggregation variables
6436  */
6438  SCIP* scip, /**< SCIP data structure */
6439  SCIP_VAR* var /**< variable to compute the bound for */
6440  )
6441 {
6442  assert(scip != NULL);
6443  assert(var != NULL);
6444 
6446  return SCIPvarGetMultaggrLbGlobal(var, scip->set);
6447  else
6448  return SCIPvarGetLbGlobal(var);
6449 }
6450 
6451 /** for a multi-aggregated variable, returns the global upper bound computed by adding the global bounds from all aggregation variables
6452  *
6453  * 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
6454  * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetUbGlobal
6455  *
6456  * @return the global upper bound computed by adding the global bounds from all aggregation variables
6457  */
6459  SCIP* scip, /**< SCIP data structure */
6460  SCIP_VAR* var /**< variable to compute the bound for */
6461  )
6462 {
6463  assert(scip != NULL);
6464  assert(var != NULL);
6465 
6467  return SCIPvarGetMultaggrUbGlobal(var, scip->set);
6468  else
6469  return SCIPvarGetUbGlobal(var);
6470 }
6471 
6472 /** for a multi-aggregated variable, returns the local lower bound computed by adding the local bounds from all aggregation variables
6473  *
6474  * 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
6475  * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetLbLocal.
6476  *
6477  * @return the local lower bound computed by adding the global bounds from all aggregation variables
6478  */
6480  SCIP* scip, /**< SCIP data structure */
6481  SCIP_VAR* var /**< variable to compute the bound for */
6482  )
6483 {
6484  assert(scip != NULL);
6485  assert(var != NULL);
6486 
6488  return SCIPvarGetMultaggrLbLocal(var, scip->set);
6489  else
6490  return SCIPvarGetLbLocal(var);
6491 }
6492 
6493 /** for a multi-aggregated variable, returns the local upper bound computed by adding the local bounds from all aggregation variables
6494  *
6495  * 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
6496  * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetUbLocal.
6497  *
6498  * @return the local upper bound computed by adding the global bounds from all aggregation variables
6499  */
6501  SCIP* scip, /**< SCIP data structure */
6502  SCIP_VAR* var /**< variable to compute the bound for */
6503  )
6504 {
6505  assert(scip != NULL);
6506  assert(var != NULL);
6507 
6509  return SCIPvarGetMultaggrUbLocal(var, scip->set);
6510  else
6511  return SCIPvarGetUbLocal(var);
6512 }
6513 
6514 /** for a multi-aggregated variable, gives the global lower bound computed by adding the global bounds from all
6515  * aggregation variables, this global bound may be tighter than the one given by SCIPvarGetLbGlobal, since the latter is
6516  * not updated if bounds of aggregation variables are changing
6517  *
6518  * calling this function for a non-multi-aggregated variable is not allowed
6519  */
6521  SCIP* scip, /**< SCIP data structure */
6522  SCIP_VAR* var /**< variable to compute the bound for */
6523  )
6524 {
6525  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
6526  return SCIPvarGetMultaggrLbGlobal(var, scip->set);
6527 }
6528 
6529 /** for a multi-aggregated variable, gives the global upper bound computed by adding the global bounds from all
6530  * aggregation variables, this upper bound may be tighter than the one given by SCIPvarGetUbGlobal, since the latter is
6531  * not updated if bounds of aggregation variables are changing
6532  *
6533  * calling this function for a non-multi-aggregated variable is not allowed
6534  */
6536  SCIP* scip, /**< SCIP data structure */
6537  SCIP_VAR* var /**< variable to compute the bound for */
6538  )
6539 {
6540  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
6541  return SCIPvarGetMultaggrUbGlobal(var, scip->set);
6542 }
6543 
6544 /** for a multi-aggregated variable, gives the local lower bound computed by adding the local bounds from all
6545  * aggregation variables, this lower bound may be tighter than the one given by SCIPvarGetLbLocal, since the latter is
6546  * not updated if bounds of aggregation variables are changing
6547  *
6548  * calling this function for a non-multi-aggregated variable is not allowed
6549  */
6551  SCIP* scip, /**< SCIP data structure */
6552  SCIP_VAR* var /**< variable to compute the bound for */
6553  )
6554 {
6555  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
6556  return SCIPvarGetMultaggrLbLocal(var, scip->set);
6557 }
6558 
6559 /** for a multi-aggregated variable, gives the local upper bound computed by adding the local bounds from all
6560  * aggregation variables, this upper bound may be tighter than the one given by SCIPvarGetUbLocal, since the latter is
6561  * not updated if bounds of aggregation variables are changing
6562  *
6563  * calling this function for a non-multi-aggregated variable is not allowed
6564  */
6566  SCIP* scip, /**< SCIP data structure */
6567  SCIP_VAR* var /**< variable to compute the bound for */
6568  )
6569 {
6570  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
6571  return SCIPvarGetMultaggrUbLocal(var, scip->set);
6572 }
6573 
6574 /** returns solution value and index of variable lower bound that is closest to the variable's value in the given primal
6575  * solution or current LP solution if no primal solution is given; returns an index of -1 if no variable lower bound is
6576  * available
6577  *
6578  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6579  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6580  *
6581  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
6582  */
6584  SCIP* scip, /**< SCIP data structure */
6585  SCIP_VAR* var, /**< active problem variable */
6586  SCIP_SOL* sol, /**< primal solution, or NULL for LP solution */
6587  SCIP_Real* closestvlb, /**< pointer to store the value of the closest variable lower bound */
6588  int* closestvlbidx /**< pointer to store the index of the closest variable lower bound */
6589  )
6590 {
6591  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarClosestVlb", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6592 
6593  SCIPvarGetClosestVlb(var, sol, scip->set, scip->stat, closestvlb, closestvlbidx);
6594 
6595  return SCIP_OKAY;
6596 }
6597 
6598 /** returns solution value and index of variable upper bound that is closest to the variable's value in the given primal solution;
6599  * or current LP solution if no primal solution is given; returns an index of -1 if no variable upper bound is 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* closestvub, /**< pointer to store the value of the closest variable lower bound */
6611  int* closestvubidx /**< pointer to store the index of the closest variable lower bound */
6612  )
6613 {
6614  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarClosestVub", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6615 
6616  SCIPvarGetClosestVub(var, sol, scip->set, scip->stat, closestvub, closestvubidx);
6617 
6618  return SCIP_OKAY;
6619 }
6620 
6621 /** informs variable x about a globally valid variable lower bound x >= b*z + d with integer variable z;
6622  * if z is binary, the corresponding valid implication for z is also added;
6623  * if z is non-continuous and 1/b not too small, the corresponding valid upper/lower bound
6624  * z <= (x-d)/b or z >= (x-d)/b (depending on the sign of of b) is added, too;
6625  * improves the global bounds of the variable and the vlb variable if possible
6626  *
6627  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6628  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6629  *
6630  * @pre This method can be called if @p scip is in one of the following stages:
6631  * - \ref SCIP_STAGE_PRESOLVING
6632  * - \ref SCIP_STAGE_PRESOLVED
6633  * - \ref SCIP_STAGE_SOLVING
6634  */
6636  SCIP* scip, /**< SCIP data structure */
6637  SCIP_VAR* var, /**< problem variable */
6638  SCIP_VAR* vlbvar, /**< variable z in x >= b*z + d */
6639  SCIP_Real vlbcoef, /**< coefficient b in x >= b*z + d */
6640  SCIP_Real vlbconstant, /**< constant d in x >= b*z + d */
6641  SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6642  int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6643  )
6644 {
6645  int nlocalbdchgs;
6646 
6647  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarVlb", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6648 
6649  SCIP_CALL( SCIPvarAddVlb(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->tree,
6650  scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, vlbvar, vlbcoef, vlbconstant,
6651  TRUE, infeasible, &nlocalbdchgs) );
6652 
6653  *nbdchgs = nlocalbdchgs;
6654 
6655  /* 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
6656  * detected infeasibility
6657  */
6658  if( !(*infeasible) && SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisZero(scip, 1.0/vlbcoef) )
6659  {
6660  if( vlbcoef > 0.0 )
6661  {
6662  /* if b > 0, we have a variable upper bound: x >= b*z + d => z <= (x-d)/b */
6663  SCIP_CALL( SCIPvarAddVub(vlbvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6664  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vlbcoef,
6665  -vlbconstant/vlbcoef, TRUE, infeasible, &nlocalbdchgs) );
6666  }
6667  else
6668  {
6669  /* if b < 0, we have a variable lower bound: x >= b*z + d => z >= (x-d)/b */
6670  SCIP_CALL( SCIPvarAddVlb(vlbvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6671  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vlbcoef,
6672  -vlbconstant/vlbcoef, TRUE, infeasible, &nlocalbdchgs) );
6673  }
6674  *nbdchgs += nlocalbdchgs;
6675  }
6676 
6677  return SCIP_OKAY;
6678 }
6679 
6680 /** informs variable x about a globally valid variable upper bound x <= b*z + d with integer variable z;
6681  * if z is binary, the corresponding valid implication for z is also added;
6682  * if z is non-continuous and 1/b not too small, the corresponding valid lower/upper bound
6683  * z >= (x-d)/b or z <= (x-d)/b (depending on the sign of of b) is added, too;
6684  * improves the global bounds of the variable and the vlb variable if possible
6685  *
6686  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6687  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6688  *
6689  * @pre This method can be called if @p scip is in one of the following stages:
6690  * - \ref SCIP_STAGE_PRESOLVING
6691  * - \ref SCIP_STAGE_PRESOLVED
6692  * - \ref SCIP_STAGE_SOLVING
6693  */
6695  SCIP* scip, /**< SCIP data structure */
6696  SCIP_VAR* var, /**< problem variable */
6697  SCIP_VAR* vubvar, /**< variable z in x <= b*z + d */
6698  SCIP_Real vubcoef, /**< coefficient b in x <= b*z + d */
6699  SCIP_Real vubconstant, /**< constant d in x <= b*z + d */
6700  SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6701  int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6702  )
6703 {
6704  int nlocalbdchgs;
6705 
6706  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarVub", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6707 
6708  SCIP_CALL( SCIPvarAddVub(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->tree,
6709  scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, vubvar, vubcoef, vubconstant, TRUE,
6710  infeasible, &nlocalbdchgs) );
6711 
6712  *nbdchgs = nlocalbdchgs;
6713 
6714  /* 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
6715  * detected infeasibility
6716  */
6717  if( !(*infeasible) && SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisZero(scip, 1.0/vubcoef) )
6718  {
6719  if( vubcoef > 0.0 )
6720  {
6721  /* if b < 0, we have a variable lower bound: x >= b*z + d => z >= (x-d)/b */
6722  SCIP_CALL( SCIPvarAddVlb(vubvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6723  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vubcoef,
6724  -vubconstant/vubcoef, TRUE, infeasible, &nlocalbdchgs) );
6725  }
6726  else
6727  {
6728  /* if b > 0, we have a variable upper bound: x >= b*z + d => z <= (x-d)/b */
6729  SCIP_CALL( SCIPvarAddVub(vubvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6730  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vubcoef,
6731  -vubconstant/vubcoef, TRUE, infeasible, &nlocalbdchgs) );
6732  }
6733  *nbdchgs += nlocalbdchgs;
6734  }
6735 
6736  return SCIP_OKAY;
6737 }
6738 
6739 /** informs binary variable x about a globally valid implication: x == 0 or x == 1 ==> y <= b or y >= b;
6740  * also adds the corresponding implication or variable bound to the implied variable;
6741  * if the implication is conflicting, the variable is fixed to the opposite value;
6742  * if the variable is already fixed to the given value, the implication is performed immediately;
6743  * if the implication is redundant with respect to the variables' global bounds, it is ignored
6744  *
6745  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6746  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6747  *
6748  * @pre This method can be called if @p scip is in one of the following stages:
6749  * - \ref SCIP_STAGE_TRANSFORMED
6750  * - \ref SCIP_STAGE_PRESOLVING
6751  * - \ref SCIP_STAGE_PRESOLVED
6752  * - \ref SCIP_STAGE_SOLVING
6753  */
6755  SCIP* scip, /**< SCIP data structure */
6756  SCIP_VAR* var, /**< problem variable */
6757  SCIP_Bool varfixing, /**< FALSE if y should be added in implications for x == 0, TRUE for x == 1 */
6758  SCIP_VAR* implvar, /**< variable y in implication y <= b or y >= b */
6759  SCIP_BOUNDTYPE impltype, /**< type of implication y <= b (SCIP_BOUNDTYPE_UPPER)
6760  * or y >= b (SCIP_BOUNDTYPE_LOWER) */
6761  SCIP_Real implbound, /**< bound b in implication y <= b or y >= b */
6762  SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6763  int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6764  )
6765 {
6766  SCIP_VAR* implprobvar;
6767 
6768  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarImplication", FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6769 
6770  assert(infeasible != NULL);
6771  *infeasible = FALSE;
6772 
6773  if ( nbdchgs != NULL )
6774  *nbdchgs = 0;
6775 
6776  if( !SCIPvarIsBinary(var) )
6777  {
6778  SCIPerrorMessage("can't add implication for nonbinary variable\n");
6779  return SCIP_INVALIDDATA;
6780  }
6781 
6782  implprobvar = SCIPvarGetProbvar(implvar);
6783  /* transform implication containing two binary variables to a clique; the condition ensures that the active representative
6784  * of implvar is actually binary
6785  */
6786  if( SCIPvarIsBinary(implvar) && (SCIPvarIsActive(implvar) || (implprobvar != NULL && SCIPvarIsBinary(implprobvar))) )
6787  {
6788  assert(SCIPisFeasEQ(scip, implbound, 1.0) || SCIPisFeasZero(scip, implbound));
6789  assert((impltype == SCIP_BOUNDTYPE_UPPER) == SCIPisFeasZero(scip, implbound));
6790 
6791  /* only add clique if implication is not redundant with respect to global bounds of the implication variable */
6792  if( (impltype == SCIP_BOUNDTYPE_LOWER && SCIPvarGetLbGlobal(implvar) < 0.5) ||
6793  (impltype == SCIP_BOUNDTYPE_UPPER && SCIPvarGetUbGlobal(implvar) > 0.5) )
6794  {
6795  SCIP_VAR* vars[2];
6796  SCIP_Bool vals[2];
6797 
6798  vars[0] = var;
6799  vars[1] = implvar;
6800  vals[0] = varfixing;
6801  vals[1] = (impltype == SCIP_BOUNDTYPE_UPPER);
6802 
6803  SCIP_CALL( SCIPaddClique(scip, vars, vals, 2, FALSE, infeasible, nbdchgs) );
6804  }
6805 
6806  return SCIP_OKAY;
6807  }
6808 
6809  /* the implication graph can only handle 'real' binary (SCIP_VARTYPE_BINARY) variables, therefore we transform the
6810  * implication in variable bounds, (lowerbound of y will be abbreviated by lby, upperbound equivlaent) the follwing
6811  * four cases are:
6812  *
6813  * 1. (x >= 1 => y >= b) => y >= (b - lby) * x + lby
6814  * 2. (x >= 1 => y <= b) => y <= (b - uby) * x + uby
6815  * 3. (x <= 0 => y >= b) => y >= (lby - b) * x + b
6816  * 4. (x <= 0 => y <= b) => y <= (uby - b) * x + b
6817  */
6818  if( SCIPvarGetType(var) != SCIP_VARTYPE_BINARY )
6819  {
6820  SCIP_Real lby;
6821  SCIP_Real uby;
6822 
6823  lby = SCIPvarGetLbGlobal(implvar);
6824  uby = SCIPvarGetUbGlobal(implvar);
6825 
6826  if( varfixing == TRUE )
6827  {
6828  if( impltype == SCIP_BOUNDTYPE_LOWER )
6829  {
6830  /* we return if the lower bound is infinity */
6831  if( SCIPisInfinity(scip, -lby) )
6832  return SCIP_OKAY;
6833 
6834  SCIP_CALL( SCIPvarAddVlb(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6835  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6836  implbound - lby, lby, TRUE, infeasible, nbdchgs) );
6837  }
6838  else
6839  {
6840  /* we return if the upper bound is infinity */
6841  if( SCIPisInfinity(scip, uby) )
6842  return SCIP_OKAY;
6843 
6844  SCIP_CALL( SCIPvarAddVub(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6845  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6846  implbound - uby, uby, TRUE, infeasible, nbdchgs) );
6847  }
6848  }
6849  else
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  lby - implbound, implbound, 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  uby - implbound, implbound, TRUE, infeasible, nbdchgs) );
6870  }
6871  }
6872  }
6873  else
6874  {
6875  SCIP_CALL( SCIPvarAddImplic(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6876  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, varfixing, implvar, impltype,
6877  implbound, TRUE, infeasible, nbdchgs) );
6878  }
6879 
6880  return SCIP_OKAY;
6881 }
6882 
6883 /** adds a clique information to SCIP, stating that at most one of the given binary variables can be set to 1;
6884  * if a variable appears twice in the same clique, the corresponding implications are performed
6885  *
6886  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6887  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6888  *
6889  * @pre This method can be called if @p scip is in one of the following stages:
6890  * - \ref SCIP_STAGE_TRANSFORMED
6891  * - \ref SCIP_STAGE_PRESOLVING
6892  * - \ref SCIP_STAGE_PRESOLVED
6893  * - \ref SCIP_STAGE_SOLVING
6894  */
6896  SCIP* scip, /**< SCIP data structure */
6897  SCIP_VAR** vars, /**< binary variables in the clique from which at most one can be set to 1 */
6898  SCIP_Bool* values, /**< values of the variables in the clique; NULL to use TRUE for all vars */
6899  int nvars, /**< number of variables in the clique */
6900  SCIP_Bool isequation, /**< is the clique an equation or an inequality? */
6901  SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6902  int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6903  )
6904 {
6905  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddClique", FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6906 
6907  *infeasible = FALSE;
6908  if( nbdchgs != NULL )
6909  *nbdchgs = 0;
6910 
6911  if( nvars > 1 )
6912  {
6913  /* add the clique to the clique table */
6914  SCIP_CALL( SCIPcliquetableAdd(scip->cliquetable, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6915  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, vars, values, nvars, isequation,
6916  infeasible, nbdchgs) );
6917  }
6918 
6919  return SCIP_OKAY;
6920 }
6921 
6922 /** relabels the given labels in-place in an increasing fashion: the first seen label is 0, the next label 1, etc...
6923  *
6924  * @note every label equal to -1 is treated as a previously unseen, unique label and gets a new ordered label.
6925  */
6926 static
6928  SCIP*const scip, /**< SCIP data structure */
6929  int* labels, /**< current labels that will be overwritten */
6930  int const nlabels, /**< number of variables in the clique */
6931  int* nclasses /**< pointer to store the total number of distinct labels */
6932  )
6933 {
6934  SCIP_HASHMAP* classidx2newlabel;
6935 
6936  int classidx;
6937  int i;
6938 
6939  SCIP_CALL( SCIPhashmapCreate(&classidx2newlabel, SCIPblkmem(scip), nlabels) );
6940 
6941  classidx = 0;
6942 
6943  /* loop over labels to create local class indices that obey the variable order */
6944  for( i = 0; i < nlabels; ++i )
6945  {
6946  int currentlabel = labels[i];
6947  int localclassidx;
6948 
6949  /* labels equal to -1 are stored as singleton classes */
6950  if( currentlabel == -1 )
6951  {
6952  ++classidx;
6953  localclassidx = classidx;
6954  }
6955  else
6956  {
6957  assert(currentlabel >= 0);
6958  /* look up the class index image in the hash map; if it is not stored yet, new class index is created and stored */
6959  if( !SCIPhashmapExists(classidx2newlabel, (void*)(size_t)currentlabel) )
6960  {
6961  ++classidx;
6962  localclassidx = classidx;
6963  SCIP_CALL( SCIPhashmapInsertInt(classidx2newlabel, (void*)(size_t)currentlabel, classidx) ); /*lint !e571*/
6964  }
6965  else
6966  {
6967  localclassidx = SCIPhashmapGetImageInt(classidx2newlabel, (void*)(size_t)currentlabel); /*lint !e571*/
6968  }
6969  }
6970  assert(localclassidx - 1 >= 0);
6971  assert(localclassidx - 1 <= i);
6972 
6973  /* indices start with zero, but we have an offset of 1 because we cannot store 0 in a hashmap */
6974  labels[i] = localclassidx - 1;
6975  }
6976 
6977  assert(classidx > 0);
6978  assert(classidx <= nlabels);
6979  *nclasses = classidx;
6980 
6981  SCIPhashmapFree(&classidx2newlabel);
6982 
6983  return SCIP_OKAY;
6984 }
6985 
6986 /** sort the variables w.r.t. the given labels; thereby ensure the current order of the variables with the same label. */
6987 static
6989  SCIP* scip, /**< SCIP data structure */
6990  SCIP_VAR** vars, /**< variable array */
6991  int* classlabels, /**< array that contains a class label for every variable */
6992  SCIP_VAR** sortedvars, /**< array to store variables after stable sorting */
6993  int* sortedindices, /**< array to store indices of sorted variables in the original vars array */
6994  int* classesstartposs, /**< starting position array for each label class (must have size nclasses + 1) */
6995  int nvars, /**< size of the vars arrays */
6996  int nclasses /**< number of label classes */
6997  )
6998 {
6999  SCIP_VAR*** varpointers;
7000  int** indexpointers;
7001  int* classcount;
7002 
7003  int nextpos;
7004  int c;
7005  int v;
7006 
7007  assert(scip != NULL);
7008  assert(vars != NULL);
7009  assert(sortedindices != NULL);
7010  assert(classesstartposs != NULL);
7011 
7012  assert(nvars == 0 || vars != NULL);
7013 
7014  if( nvars == 0 )
7015  return SCIP_OKAY;
7016 
7017  assert(classlabels != NULL);
7018  assert(nclasses > 0);
7019 
7020  /* we first count all class cardinalities and allocate temporary memory for a bucket sort */
7021  SCIP_CALL( SCIPallocBufferArray(scip, &classcount, nclasses) );
7022  BMSclearMemoryArray(classcount, nclasses);
7023 
7024  /* first we count for each class the number of elements */
7025  for( v = nvars - 1; v >= 0; --v )
7026  {
7027  assert(0 <= classlabels[v] && classlabels[v] < nclasses);
7028  ++(classcount[classlabels[v]]);
7029  }
7030 
7031 #ifndef NDEBUG
7032  BMSclearMemoryArray(sortedvars, nvars);
7033  BMSclearMemoryArray(sortedindices, nvars);
7034 #endif
7035  SCIP_CALL( SCIPallocBufferArray(scip, &varpointers, nclasses) );
7036  SCIP_CALL( SCIPallocBufferArray(scip, &indexpointers, nclasses) );
7037 
7038  nextpos = 0;
7039  /* now we initialize all start pointers for each class, so they will be ordered */
7040  for( c = 0; c < nclasses; ++c )
7041  {
7042  /* to reach the goal that all variables of each class will be standing next to each other we will initialize the
7043  * starting pointers for each class by adding the cardinality of each class to the last class starting pointer
7044  * e.g. class1 has 4 elements and class2 has 3 elements then the starting pointer for class1 will be the pointer
7045  * to sortedvars[0], the starting pointer to class2 will be the pointer to sortedvars[4] and to class3 it will be
7046  * the pointer to sortedvars[7]
7047  */
7048  varpointers[c] = (SCIP_VAR**) (sortedvars + nextpos);
7049  indexpointers[c] = (int*) (sortedindices + nextpos);
7050  classesstartposs[c] = nextpos;
7051  assert(classcount[c] > 0);
7052  nextpos += classcount[c];
7053  assert(nextpos > 0);
7054  }
7055  assert(nextpos == nvars);
7056  classesstartposs[c] = nextpos;
7057 
7058  /* now we copy all variables to the right order */
7059  for( v = 0; v < nvars; ++v )
7060  {
7061  /* copy variable itself to the right position */
7062  *(varpointers[classlabels[v]]) = vars[v]; /*lint !e613*/
7063  ++(varpointers[classlabels[v]]);
7064 
7065  /* copy index */
7066  *(indexpointers[classlabels[v]]) = v;
7067  ++(indexpointers[classlabels[v]]);
7068  }
7069 
7070 /* in debug mode, we ensure the correctness of the mapping */
7071 #ifndef NDEBUG
7072  for( v = 0; v < nvars; ++v )
7073  {
7074  assert(sortedvars[v] != NULL);
7075  assert(sortedindices[v] >= 0);
7076 
7077  /* assert that the sorted indices map back to the correct variable in the original order */
7078  assert(vars[sortedindices[v]] == sortedvars[v]);
7079  }
7080 #endif
7081 
7082  /* free temporary memory */
7083  SCIPfreeBufferArray(scip, &indexpointers);
7084  SCIPfreeBufferArray(scip, &varpointers);
7085  SCIPfreeBufferArray(scip, &classcount);
7086 
7087  return SCIP_OKAY;
7088 }
7089 
7090 
7091 /* calculate clique partition for a maximal amount of comparisons on variables due to expensive algorithm
7092  * @todo: check for a good value, maybe it's better to check parts of variables
7093  */
7094 #define MAXNCLIQUEVARSCOMP 1000000
7095 
7096 /** calculates a partition of the given set of binary variables into cliques;
7097  * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7098  * were assigned to the same clique;
7099  * the first variable is always assigned to clique 0, and a variable can only be assigned to clique i if at least one of
7100  * the preceding variables was assigned to clique i-1;
7101  * for each clique at most 1 variables can be set to TRUE in a feasible solution;
7102  *
7103  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7104  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7105  *
7106  * @pre This method can be called if @p scip is in one of the following stages:
7107  * - \ref SCIP_STAGE_INITPRESOLVE
7108  * - \ref SCIP_STAGE_PRESOLVING
7109  * - \ref SCIP_STAGE_EXITPRESOLVE
7110  * - \ref SCIP_STAGE_PRESOLVED
7111  * - \ref SCIP_STAGE_SOLVING
7112  */
7113 static
7115  SCIP*const scip, /**< SCIP data structure */
7116  SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7117  SCIP_Bool*const values, /**< clique value (TRUE or FALSE) for each variable in the clique */
7118  int const nvars, /**< number of variables in the array */
7119  int*const cliquepartition, /**< array of length nvars to store the clique partition */
7120  int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7121  )
7122 {
7123  SCIP_VAR** cliquevars;
7124  SCIP_Bool* cliquevalues;
7125  int i;
7126  int maxncliquevarscomp;
7127  int ncliquevars;
7128 
7129  /* allocate temporary memory for storing the variables of the current clique */
7130  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &cliquevars, nvars) );
7131  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &cliquevalues, nvars) );
7132 
7133  /* initialize the cliquepartition array with -1 */
7134  for( i = nvars - 1; i >= 0; --i )
7135  cliquepartition[i] = -1;
7136 
7137  maxncliquevarscomp = (int) MIN(nvars * (SCIP_Longint)nvars, MAXNCLIQUEVARSCOMP);
7138  /* calculate the clique partition */
7139  *ncliques = 0;
7140  for( i = 0; i < nvars; ++i )
7141  {
7142  if( cliquepartition[i] == -1 )
7143  {
7144  int j;
7145 
7146  /* variable starts a new clique */
7147  cliquepartition[i] = *ncliques;
7148  cliquevars[0] = vars[i];
7149  cliquevalues[0] = values[i];
7150  ncliquevars = 1;
7151 
7152  /* if variable is not active (multi-aggregated or fixed), it cannot be in any clique */
7153  if( SCIPvarIsActive(vars[i]) && SCIPvarGetNCliques(vars[i], values[i]) > 0 )
7154  {
7155  /* greedily fill up the clique */
7156  for( j = i+1; j < nvars; ++j )
7157  {
7158  /* if variable is not active (multi-aggregated or fixed), it cannot be in any clique */
7159  if( cliquepartition[j] == -1 && SCIPvarIsActive(vars[j]) )
7160  {
7161  int k;
7162 
7163  /* check if every variable in the current clique can be extended by tmpvars[j] */
7164  for( k = ncliquevars - 1; k >= 0; --k )
7165  {
7166  if( !SCIPvarsHaveCommonClique(vars[j], values[j], cliquevars[k], cliquevalues[k], FALSE) )
7167  break;
7168  }
7169 
7170  if( k == -1 )
7171  {
7172  /* put the variable into the same clique */
7173  cliquepartition[j] = cliquepartition[i];
7174  cliquevars[ncliquevars] = vars[j];
7175  cliquevalues[ncliquevars] = values[j];
7176  ++ncliquevars;
7177  }
7178  }
7179  }
7180  }
7181 
7182  /* this clique is finished */
7183  ++(*ncliques);
7184  }
7185  assert(cliquepartition[i] >= 0 && cliquepartition[i] < i+1);
7186 
7187  /* break if we reached the maximal number of comparisons */
7188  if( i * nvars > maxncliquevarscomp )
7189  break;
7190  }
7191  /* if we had to many variables fill up the cliquepartition and put each variable in a separate clique */
7192  for( ; i < nvars; ++i )
7193  {
7194  if( cliquepartition[i] == -1 )
7195  {
7196  cliquepartition[i] = *ncliques;
7197  ++(*ncliques);
7198  }
7199  }
7200 
7201  SCIPsetFreeBufferArray(scip->set, &cliquevalues);
7202  SCIPsetFreeBufferArray(scip->set, &cliquevars);
7203 
7204  return SCIP_OKAY;
7205 }
7206 
7207 /** calculates a partition of the given set of binary variables into cliques; takes into account independent clique components
7208  *
7209  * The algorithm performs the following steps:
7210  * - recomputes connected components of the clique table, if necessary
7211  * - computes a clique partition for every connected component greedily.
7212  * - relabels the resulting clique partition such that it satisfies the description below
7213  *
7214  * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7215  * were assigned to the same clique;
7216  * the first variable is always assigned to clique 0, and a variable can only be assigned to clique i if at least one of
7217  * the preceding variables was assigned to clique i-1;
7218  * for each clique at most 1 variables can be set to TRUE in a feasible solution;
7219  *
7220  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7221  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7222  *
7223  * @pre This method can be called if @p scip is in one of the following stages:
7224  * - \ref SCIP_STAGE_INITPRESOLVE
7225  * - \ref SCIP_STAGE_PRESOLVING
7226  * - \ref SCIP_STAGE_EXITPRESOLVE
7227  * - \ref SCIP_STAGE_PRESOLVED
7228  * - \ref SCIP_STAGE_SOLVING
7229  */
7231  SCIP*const scip, /**< SCIP data structure */
7232  SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7233  int const nvars, /**< number of variables in the clique */
7234  int*const cliquepartition, /**< array of length nvars to store the clique partition */
7235  int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7236  )
7237 {
7238  SCIP_VAR** tmpvars;
7239 
7240  SCIP_VAR** sortedtmpvars;
7241  SCIP_Bool* tmpvalues;
7242  SCIP_Bool* sortedtmpvalues;
7243  int* componentlabels;
7244  int* sortedindices;
7245  int* componentstartposs;
7246  int i;
7247  int c;
7248 
7249  int ncomponents;
7250 
7251  assert(scip != NULL);
7252  assert(nvars == 0 || vars != NULL);
7253  assert(nvars == 0 || cliquepartition != NULL);
7254  assert(ncliques != NULL);
7255 
7256  SCIP_CALL( SCIPcheckStage(scip, "SCIPcalcCliquePartition", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7257 
7258  if( nvars == 0 )
7259  {
7260  *ncliques = 0;
7261  return SCIP_OKAY;
7262  }
7263 
7264  /* early abort if no cliques are present */
7265  if( SCIPgetNCliques(scip) == 0 )
7266  {
7267  for( i = 0; i < nvars; ++i )
7268  cliquepartition[i] = i;
7269 
7270  *ncliques = nvars;
7271 
7272  return SCIP_OKAY;
7273  }
7274 
7275  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &tmpvalues, nvars) );
7276  SCIP_CALL( SCIPsetDuplicateBufferArray(scip->set, &tmpvars, vars, nvars) );
7277  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &componentlabels, nvars) );
7278  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedindices, nvars) );
7279 
7280  /* initialize the tmpvalues array */
7281  for( i = nvars - 1; i >= 0; --i )
7282  {
7283  tmpvalues[i] = TRUE;
7284  cliquepartition[i] = -1;
7285  }
7286 
7287  /* get corresponding active problem variables */
7288  SCIP_CALL( SCIPvarsGetProbvarBinary(&tmpvars, &tmpvalues, nvars) );
7289 
7290  ncomponents = -1;
7291 
7292  /* update clique components if necessary */
7294  {
7295  SCIP_VAR** allvars;
7296  int nallbinvars;
7297  int nallintvars;
7298  int nallimplvars;
7299 
7300  SCIP_CALL( SCIPgetVarsData(scip, &allvars, NULL, &nallbinvars, &nallintvars, &nallimplvars, NULL) );
7301 
7302  SCIP_CALL( SCIPcliquetableComputeCliqueComponents(scip->cliquetable, scip->set, SCIPblkmem(scip), allvars, nallbinvars, nallintvars, nallimplvars) );
7303  }
7304 
7306 
7307  /* store the global clique component labels */
7308  for( i = 0; i < nvars; ++i )
7309  {
7310  if( SCIPvarIsActive(tmpvars[i]) )
7311  componentlabels[i] = SCIPcliquetableGetVarComponentIdx(scip->cliquetable, tmpvars[i]);
7312  else
7313  componentlabels[i] = -1;
7314  }
7315 
7316  /* relabel component labels order consistent as prerequisite for a stable sort */
7317  SCIP_CALL( relabelOrderConsistent(scip, componentlabels, nvars, &ncomponents) );
7318  assert(ncomponents >= 1);
7319  assert(ncomponents <= nvars);
7320 
7321  /* allocate storage array for the starting positions of the components */
7322  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &componentstartposs, ncomponents + 1) );
7323 
7324  /* stable sort the variables w.r.t. the component labels so that we can restrict the quadratic algorithm to the components */
7325  if( ncomponents > 1 )
7326  {
7327  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedtmpvars, nvars) );
7328  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedtmpvalues, nvars) );
7329  SCIP_CALL( labelSortStable(scip, tmpvars, componentlabels, sortedtmpvars, sortedindices, componentstartposs, nvars, ncomponents) );
7330 
7331  /* reassign the tmpvalues with respect to the sorting */
7332  for( i = 0; i < nvars; ++i )
7333  {
7334  assert(tmpvars[sortedindices[i]] == sortedtmpvars[i]);
7335  sortedtmpvalues[i] = tmpvalues[sortedindices[i]];
7336  }
7337  }
7338  else
7339  {
7340  /* if we have only one large connected component, skip the stable sorting and prepare the data differently */
7341  sortedtmpvars = tmpvars;
7342  sortedtmpvalues = tmpvalues;
7343  componentstartposs[0] = 0;
7344  componentstartposs[1] = nvars;
7345 
7346  /* sorted indices are the identity */
7347  for( i = 0; i < nvars; ++i )
7348  sortedindices[i] = i;
7349  }
7350 
7351  *ncliques = 0;
7352  /* calculate a greedy clique partition for each connected component */
7353  for( c = 0; c < ncomponents; ++c )
7354  {
7355  int* localcliquepartition;
7356  int nlocalcliques;
7357  int ncomponentvars;
7358  int l;
7359 
7360  /* extract the number of variables in this connected component */
7361  ncomponentvars = componentstartposs[c + 1] - componentstartposs[c];
7362  nlocalcliques = 0;
7363 
7364  /* allocate necessary memory to hold the intermediate component clique partition */
7365  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &localcliquepartition, ncomponentvars) );
7366 
7367  /* call greedy clique algorithm for all component variables */
7368  SCIP_CALL( calcCliquePartitionGreedy(scip, &(sortedtmpvars[componentstartposs[c]]), &(sortedtmpvalues[componentstartposs[c]]),
7369  ncomponentvars, localcliquepartition, &nlocalcliques) );
7370 
7371  assert(nlocalcliques >= 1);
7372  assert(nlocalcliques <= ncomponentvars);
7373 
7374  /* store the obtained clique partition with an offset of ncliques for the original variables */
7375  for( l = componentstartposs[c]; l < componentstartposs[c + 1]; ++l )
7376  {
7377  int origvaridx = sortedindices[l];
7378  assert(cliquepartition[origvaridx] == -1);
7379  assert(localcliquepartition[l - componentstartposs[c]] <= l - componentstartposs[c]);
7380  cliquepartition[origvaridx] = localcliquepartition[l - componentstartposs[c]] + (*ncliques);
7381  }
7382  *ncliques += nlocalcliques;
7383 
7384  /* free the local clique partition */
7385  SCIPsetFreeBufferArray(scip->set, &localcliquepartition);
7386  }
7387 
7388  /* except in the two trivial cases, we have to ensure the order consistency of the partition indices */
7389  if( ncomponents > 1 && ncomponents < nvars )
7390  {
7391  int partitionsize;
7392  SCIP_CALL( relabelOrderConsistent(scip, cliquepartition, nvars, &partitionsize) );
7393 
7394  assert(partitionsize == *ncliques);
7395  }
7396 
7397  if( ncomponents > 1 )
7398  {
7399  SCIPsetFreeBufferArray(scip->set, &sortedtmpvalues);
7400  SCIPsetFreeBufferArray(scip->set, &sortedtmpvars);
7401  }
7402 
7403  /* use the greedy algorithm as a whole to verify the result on small number of variables */
7404 #ifdef SCIP_DISABLED_CODE
7405  {
7406  int* debugcliquepartition;
7407  int ndebugcliques;
7408 
7409  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &debugcliquepartition, nvars) );
7410 
7411  /* call greedy clique algorithm for all component variables */
7412  SCIP_CALL( calcCliquePartitionGreedy(scip, tmpvars, tmpvalues, nvars, debugcliquepartition, &ndebugcliques) );
7413 
7414  /* loop and compare the traditional greedy clique with */
7415  for( i = 0; i < nvars; ++i )
7416  assert(i * nvars > MAXNCLIQUEVARSCOMP || cliquepartition[i] == debugcliquepartition[i]);
7417 
7418  SCIPsetFreeBufferArray(scip->set, &debugcliquepartition);
7419  }
7420 #endif
7421 
7422  /* free temporary memory */
7423  SCIPsetFreeBufferArray(scip->set, &componentstartposs);
7424  SCIPsetFreeBufferArray(scip->set, &sortedindices);
7425  SCIPsetFreeBufferArray(scip->set, &componentlabels);
7426  SCIPsetFreeBufferArray(scip->set, &tmpvars);
7427  SCIPsetFreeBufferArray(scip->set, &tmpvalues);
7428 
7429  return SCIP_OKAY;
7430 }
7431 
7432 /** calculates a partition of the given set of binary variables into negated cliques;
7433  * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7434  * were assigned to the same negated clique;
7435  * the first variable is always assigned to clique 0 and a variable can only be assigned to clique i if at least one of
7436  * the preceding variables was assigned to clique i-1;
7437  * for each clique with n_c variables at least n_c-1 variables can be set to TRUE in a feasible solution;
7438  *
7439  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7440  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7441  *
7442  * @pre This method can be called if @p scip is in one of the following stages:
7443  * - \ref SCIP_STAGE_INITPRESOLVE
7444  * - \ref SCIP_STAGE_PRESOLVING
7445  * - \ref SCIP_STAGE_EXITPRESOLVE
7446  * - \ref SCIP_STAGE_PRESOLVED
7447  * - \ref SCIP_STAGE_SOLVING
7448  */
7450  SCIP*const scip, /**< SCIP data structure */
7451  SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7452  int const nvars, /**< number of variables in the clique */
7453  int*const cliquepartition, /**< array of length nvars to store the clique partition */
7454  int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7455  )
7456 {
7457  SCIP_VAR** negvars;
7458  int v;
7459 
7460  assert(scip != NULL);
7461  assert(cliquepartition != NULL || nvars == 0);
7462  assert(ncliques != NULL);
7463 
7464  if( nvars == 0 )
7465  {
7466  *ncliques = 0;
7467  return SCIP_OKAY;
7468  }
7469  assert(vars != NULL);
7470 
7471  /* allocate temporary memory */
7472  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &negvars, nvars) );
7473 
7474  /* get all negated variables */
7475  for( v = nvars - 1; v >= 0; --v )
7476  {
7477  SCIP_CALL( SCIPgetNegatedVar(scip, vars[v], &(negvars[v])) );
7478  }
7479 
7480  /* calculate cliques on negated variables, which are "negated" cliques on normal variables array */
7481  SCIP_CALL( SCIPcalcCliquePartition( scip, negvars, nvars, cliquepartition, ncliques) );
7482 
7483  /* free temporary memory */
7484  SCIPsetFreeBufferArray(scip->set, &negvars);
7485 
7486  return SCIP_OKAY;
7487 }
7488 
7489 
7490 /** force SCIP to clean up all cliques; cliques do not get automatically cleaned up after presolving. Use
7491  * this method to prevent inactive variables in cliques when retrieved via SCIPgetCliques()
7492  *
7493  * @return SCIP_OKAY if everything worked, otherwise a suitable error code is passed
7494  *
7495  * @pre This method can be called if @p scip is in one of the following stages:
7496  * - \ref SCIP_STAGE_TRANSFORMED
7497  * - \ref SCIP_STAGE_INITPRESOLVE
7498  * - \ref SCIP_STAGE_PRESOLVING
7499  * - \ref SCIP_STAGE_EXITPRESOLVE
7500  * - \ref SCIP_STAGE_PRESOLVED
7501  * - \ref SCIP_STAGE_INITSOLVE
7502  * - \ref SCIP_STAGE_SOLVING
7503  * - \ref SCIP_STAGE_SOLVED
7504  * - \ref SCIP_STAGE_EXITSOLVE
7505  */
7507  SCIP* scip, /**< SCIP data structure */
7508  SCIP_Bool* infeasible /**< pointer to store if cleanup detected infeasibility */
7509  )
7510 {
7511  int nlocalbdchgs;
7512  SCIP_Bool globalinfeasibility;
7513 
7514  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPcleanupCliques", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7515 
7516  globalinfeasibility = FALSE;
7517  nlocalbdchgs = 0;
7518  SCIP_CALL( SCIPcliquetableCleanup(scip->cliquetable, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
7519  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, &nlocalbdchgs,
7520  &globalinfeasibility) );
7521 
7522  if( infeasible != NULL )
7523  *infeasible = globalinfeasibility;
7524 
7525  if( globalinfeasibility )
7527 
7528  return SCIP_OKAY;
7529 }
7530 
7531 /** gets the number of cliques in the clique table
7532  *
7533  * @return number of cliques in the clique table
7534  *
7535  * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7536  * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
7537  *
7538  * @pre This method can be called if @p scip is in one of the following stages:
7539  * - \ref SCIP_STAGE_TRANSFORMED
7540  * - \ref SCIP_STAGE_INITPRESOLVE
7541  * - \ref SCIP_STAGE_PRESOLVING
7542  * - \ref SCIP_STAGE_EXITPRESOLVE
7543  * - \ref SCIP_STAGE_PRESOLVED
7544  * - \ref SCIP_STAGE_INITSOLVE
7545  * - \ref SCIP_STAGE_SOLVING
7546  * - \ref SCIP_STAGE_SOLVED
7547  * - \ref SCIP_STAGE_EXITSOLVE
7548  */
7550  SCIP* scip /**< SCIP data structure */
7551  )
7552 {
7553  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNCliques", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7554 
7556 }
7557 
7558 /** gets the number of cliques created so far by the cliquetable
7559  *
7560  * @return number of cliques created so far by the cliquetable
7561  *
7562  * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7563  * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
7564  *
7565  * @pre This method can be called if @p scip is in one of the following stages:
7566  * - \ref SCIP_STAGE_TRANSFORMED
7567  * - \ref SCIP_STAGE_INITPRESOLVE
7568  * - \ref SCIP_STAGE_PRESOLVING
7569  * - \ref SCIP_STAGE_EXITPRESOLVE
7570  * - \ref SCIP_STAGE_PRESOLVED
7571  * - \ref SCIP_STAGE_INITSOLVE
7572  * - \ref SCIP_STAGE_SOLVING
7573  * - \ref SCIP_STAGE_SOLVED
7574  * - \ref SCIP_STAGE_EXITSOLVE
7575  */
7577  SCIP* scip /**< SCIP data structure */
7578  )
7579 {
7580  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNCliquesCreated", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7581 
7583 }
7584 
7585 /** gets the array of cliques in the clique table
7586  *
7587  * @return array of cliques in the clique table
7588  *
7589  * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7590  * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
7591  *
7592  * @pre This method can be called if @p scip is in one of the following stages:
7593  * - \ref SCIP_STAGE_TRANSFORMED
7594  * - \ref SCIP_STAGE_INITPRESOLVE
7595  * - \ref SCIP_STAGE_PRESOLVING
7596  * - \ref SCIP_STAGE_EXITPRESOLVE
7597  * - \ref SCIP_STAGE_PRESOLVED
7598  * - \ref SCIP_STAGE_INITSOLVE
7599  * - \ref SCIP_STAGE_SOLVING
7600  * - \ref SCIP_STAGE_SOLVED
7601  * - \ref SCIP_STAGE_EXITSOLVE
7602  */
7604  SCIP* scip /**< SCIP data structure */
7605  )
7606 {
7607  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetCliques", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7608 
7609  return SCIPcliquetableGetCliques(scip->cliquetable);
7610 }
7611 
7612 /** returns whether there is a clique that contains both given variable/value pairs;
7613  * the variables must be active binary variables;
7614  * if regardimplics is FALSE, only the cliques in the clique table are looked at;
7615  * if regardimplics is TRUE, both the cliques and the implications of the implication graph are regarded
7616  *
7617  * @return TRUE, if there is a clique that contains both variable/clique pairs; FALSE, otherwise
7618  *
7619  * @pre This method can be called if @p scip is in one of the following stages:
7620  * - \ref SCIP_STAGE_TRANSFORMED
7621  * - \ref SCIP_STAGE_INITPRESOLVE
7622  * - \ref SCIP_STAGE_PRESOLVING
7623  * - \ref SCIP_STAGE_EXITPRESOLVE
7624  * - \ref SCIP_STAGE_PRESOLVED
7625  * - \ref SCIP_STAGE_INITSOLVE
7626  * - \ref SCIP_STAGE_SOLVING
7627  * - \ref SCIP_STAGE_SOLVED
7628  * - \ref SCIP_STAGE_EXITSOLVE
7629  *
7630  * @note a variable with it's negated variable are NOT! in a clique
7631  * @note a variable with itself are in a clique
7632  */
7634  SCIP* scip, /**< SCIP data structure */
7635  SCIP_VAR* var1, /**< first variable */
7636  SCIP_Bool value1, /**< value of first variable */
7637  SCIP_VAR* var2, /**< second variable */
7638  SCIP_Bool value2, /**< value of second variable */
7639  SCIP_Bool regardimplics /**< should the implication graph also be searched for a clique? */
7640  )
7641 {
7642  assert(scip != NULL);
7643  assert(var1 != NULL);
7644  assert(var2 != NULL);
7645  assert(SCIPvarIsActive(var1));
7646  assert(SCIPvarIsActive(var2));
7647  assert(SCIPvarIsBinary(var1));
7648  assert(SCIPvarIsBinary(var2));
7649 
7650  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPhaveVarsCommonClique", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7651 
7652  /* if both variables together have more cliques then actual cliques exist, then they have a common clique (in debug
7653  * mode we check this for correctness), otherwise we need to call the pairwise comparison method for these variables
7654  */
7655 #ifndef NDEBUG
7656  assert((SCIPvarGetNCliques(var1, value1) + SCIPvarGetNCliques(var2, value2) > SCIPcliquetableGetNCliques(scip->cliquetable)) ? SCIPvarsHaveCommonClique(var1, value1, var2, value2, FALSE) : TRUE);
7657 #endif
7658 
7659  return (SCIPvarGetNCliques(var1, value1) + SCIPvarGetNCliques(var2, value2) > SCIPcliquetableGetNCliques(scip->cliquetable)
7660  || SCIPvarsHaveCommonClique(var1, value1, var2, value2, regardimplics));
7661 }
7662 
7663 /** writes the clique graph to a gml file
7664  *
7665  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7666  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7667  *
7668  * @pre This method can be called if @p scip is in one of the following stages:
7669  * - \ref SCIP_STAGE_TRANSFORMED
7670  * - \ref SCIP_STAGE_INITPRESOLVE
7671  * - \ref SCIP_STAGE_PRESOLVING
7672  * - \ref SCIP_STAGE_EXITPRESOLVE
7673  * - \ref SCIP_STAGE_PRESOLVED
7674  * - \ref SCIP_STAGE_INITSOLVE
7675  * - \ref SCIP_STAGE_SOLVING
7676  * - \ref SCIP_STAGE_SOLVED
7677  * - \ref SCIP_STAGE_EXITSOLVE
7678  *
7679  * @note there can be duplicated arcs in the output file
7680  *
7681  * If @p writenodeweights is true, only nodes corresponding to variables that have a fractional value and only edges
7682  * between such nodes are written.
7683  */
7685  SCIP* scip, /**< SCIP data structure */
7686  const char* fname, /**< name of file */
7687  SCIP_Bool writenodeweights /**< should we write weights of nodes? */
7688  )
7689 {
7690  FILE* gmlfile;
7691  SCIP_HASHMAP* nodehashmap;
7692  SCIP_CLIQUE** cliques;
7693  SCIP_VAR** clqvars;
7694  SCIP_VAR** allvars;
7695  SCIP_Bool* clqvalues;
7696  char nodename[SCIP_MAXSTRLEN];
7697  int nallvars;
7698  int nbinvars;
7699  int nintvars;
7700  int nimplvars;
7701  int ncliques;
7702  int c;
7703  int v1;
7704  int v2;
7705  int id1;
7706  int id2;
7707 
7708  assert(scip != NULL);
7709  assert(fname != NULL);
7710 
7711  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPwriteCliqueGraph", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7712 
7713  /* get all active variables */
7714  SCIP_CALL( SCIPgetVarsData(scip, &allvars, &nallvars, &nbinvars, &nintvars, &nimplvars, NULL) );
7715 
7716  /* no possible variables for cliques exist */
7717  if( nbinvars + nimplvars == 0 )
7718  return SCIP_OKAY;
7719 
7720  ncliques = SCIPgetNCliques(scip);
7721 
7722  /* no cliques and do not wont to check for binary implications */
7723  if( ncliques == 0 )
7724  return SCIP_OKAY;
7725 
7726  /* open gml file */
7727  gmlfile = fopen(fname, "w");
7728 
7729  if( gmlfile == NULL )
7730  {
7731  SCIPerrorMessage("cannot open graph file <%s>\n", fname);
7732  SCIPABORT();
7733  return SCIP_INVALIDDATA; /*lint !e527*/
7734  }
7735 
7736  /* create the hash map */
7737  SCIP_CALL_FINALLY( SCIPhashmapCreate(&nodehashmap, SCIPblkmem(scip), nbinvars+nimplvars), fclose(gmlfile) );
7738 
7739  /* write starting of gml file */
7740  SCIPgmlWriteOpening(gmlfile, TRUE);
7741 
7742  cliques = SCIPgetCliques(scip);
7743 
7744  /* write nodes and arcs for all cliques */
7745  for( c = ncliques - 1; c >= 0; --c )
7746  {
7747  clqvalues = SCIPcliqueGetValues(cliques[c]);
7748  clqvars = SCIPcliqueGetVars(cliques[c]);
7749 
7750  for( v1 = SCIPcliqueGetNVars(cliques[c]) - 1; v1 >= 0; --v1 )
7751  {
7752  id1 = clqvalues[v1] ? SCIPvarGetProbindex(clqvars[v1]) : (nallvars + SCIPvarGetProbindex(clqvars[v1]));
7753 
7754  /* if corresponding node was not added yet, add it */
7755  if( !SCIPhashmapExists(nodehashmap, (void*)(size_t)id1) )
7756  {
7757  assert(id1 >= 0);
7758  SCIP_CALL_FINALLY( SCIPhashmapInsertInt(nodehashmap, (void*)(size_t)id1, 1), fclose(gmlfile) ); /*lint !e571*/
7759 
7760  (void) SCIPsnprintf(nodename, SCIP_MAXSTRLEN, "%s%s", (id1 >= nallvars ? "~" : ""), SCIPvarGetName(clqvars[v1]));
7761 
7762  /* write new gml node for new variable */
7763  if ( writenodeweights )
7764  {
7765  if ( ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v1])) )
7766  SCIPgmlWriteNodeWeight(gmlfile, (unsigned int)id1, nodename, NULL, NULL, NULL, SCIPgetSolVal(scip, NULL, clqvars[v1]));
7767  }
7768  else
7769  {
7770  SCIPgmlWriteNode(gmlfile, (unsigned int)id1, nodename, NULL, NULL, NULL);
7771  }
7772  }
7773 
7774  for( v2 = SCIPcliqueGetNVars(cliques[c]) - 1; v2 >= 0; --v2 )
7775  {
7776  if( v1 == v2 )
7777  continue;
7778 
7779  id2 = clqvalues[v2] ? SCIPvarGetProbindex(clqvars[v2]) : (nallvars + SCIPvarGetProbindex(clqvars[v2]));
7780 
7781  /* if corresponding node was not added yet, add it */
7782  if( !SCIPhashmapExists(nodehashmap, (void*)(size_t)id2) )
7783  {
7784  assert(id2 >= 0);
7785  SCIP_CALL_FINALLY( SCIPhashmapInsertInt(nodehashmap, (void*)(size_t)id2, 1), fclose(gmlfile) ); /*lint !e571*/
7786 
7787  (void) SCIPsnprintf(nodename, SCIP_MAXSTRLEN, "%s%s", (id2 >= nallvars ? "~" : ""), SCIPvarGetName(clqvars[v2]));
7788 
7789  /* write new gml node for new variable */
7790  if ( writenodeweights )
7791  {
7792  if ( ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v2])) )
7793  SCIPgmlWriteNodeWeight(gmlfile, (unsigned int)id2, nodename, NULL, NULL, NULL, SCIPgetSolVal(scip, NULL, clqvars[v2]));
7794  }
7795  else
7796  {
7797  SCIPgmlWriteNode(gmlfile, (unsigned int)id2, nodename, NULL, NULL, NULL);
7798  }
7799  }
7800 
7801  /* write gml arc between resultant and operand */
7802  if ( ! writenodeweights || ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v2])) )
7803  SCIPgmlWriteArc(gmlfile, (unsigned int)id1, (unsigned int)id2, NULL, NULL);
7804  }
7805  }
7806  }
7807 
7808  /* free the hash map */
7809  SCIPhashmapFree(&nodehashmap);
7810 
7811  SCIPgmlWriteClosing(gmlfile);
7812  fclose(gmlfile);
7813 
7814  return SCIP_OKAY;
7815 }
7816 
7817 /** Removes (irrelevant) variable from all its global structures, i.e. cliques, implications and variable bounds.
7818  * This is an advanced method which should be used with care.
7819  *
7820  * @return SCIP_OKAY if everything worked, otherwise a suitable error code is passed
7821  *
7822  * @pre This method can be called if @p scip is in one of the following stages:
7823  * - \ref SCIP_STAGE_TRANSFORMED
7824  * - \ref SCIP_STAGE_INITPRESOLVE
7825  * - \ref SCIP_STAGE_PRESOLVING
7826  * - \ref SCIP_STAGE_EXITPRESOLVE
7827  * - \ref SCIP_STAGE_PRESOLVED
7828  * - \ref SCIP_STAGE_INITSOLVE
7829  * - \ref SCIP_STAGE_SOLVING
7830  * - \ref SCIP_STAGE_SOLVED
7831  * - \ref SCIP_STAGE_EXITSOLVE
7832  */
7834  SCIP* scip, /**< SCIP data structure */
7835  SCIP_VAR* var /**< variable to remove from global structures */
7836  )
7837 {
7838  assert(scip != NULL);
7839 
7840  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPremoveVarFromGlobalStructures", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7841 
7842  /* mark the variable as deletable from global structures - This is necessary for the delayed clean up of cliques */
7844 
7845  /* remove variable from all its cliques, implications, and variable bounds */
7847 
7848  return SCIP_OKAY;
7849 }
7850 
7851 /** sets the branch factor of the variable; this value can be used in the branching methods to scale the score
7852  * values of the variables; higher factor leads to a higher probability that this variable is chosen for branching
7853  *
7854  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7855  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7856  *
7857  * @pre This method can be called if @p scip is in one of the following stages:
7858  * - \ref SCIP_STAGE_PROBLEM
7859  * - \ref SCIP_STAGE_TRANSFORMING
7860  * - \ref SCIP_STAGE_TRANSFORMED
7861  * - \ref SCIP_STAGE_INITPRESOLVE
7862  * - \ref SCIP_STAGE_PRESOLVING
7863  * - \ref SCIP_STAGE_EXITPRESOLVE
7864  * - \ref SCIP_STAGE_PRESOLVED
7865  * - \ref SCIP_STAGE_SOLVING
7866  */
7868  SCIP* scip, /**< SCIP data structure */
7869  SCIP_VAR* var, /**< problem variable */
7870  SCIP_Real branchfactor /**< factor to weigh variable's branching score with */
7871  )
7872 {
7873  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7874 
7875  SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, branchfactor) );
7876 
7877  return SCIP_OKAY;
7878 }
7879 
7880 /** scales the branch factor of the variable with the given value
7881  *
7882  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7883  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7884  *
7885  * @pre This method can be called if @p scip is in one of the following stages:
7886  * - \ref SCIP_STAGE_PROBLEM
7887  * - \ref SCIP_STAGE_TRANSFORMING
7888  * - \ref SCIP_STAGE_TRANSFORMED
7889  * - \ref SCIP_STAGE_INITPRESOLVE
7890  * - \ref SCIP_STAGE_PRESOLVING
7891  * - \ref SCIP_STAGE_EXITPRESOLVE
7892  * - \ref SCIP_STAGE_PRESOLVED
7893  * - \ref SCIP_STAGE_SOLVING
7894  */
7896  SCIP* scip, /**< SCIP data structure */
7897  SCIP_VAR* var, /**< problem variable */
7898  SCIP_Real scale /**< factor to scale variable's branching factor with */
7899  )
7900 {
7901  SCIP_CALL( SCIPcheckStage(scip, "SCIPscaleVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7902 
7903  SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, scale * SCIPvarGetBranchFactor(var)) );
7904 
7905  return SCIP_OKAY;
7906 }
7907 
7908 /** adds the given value to the branch factor of the variable
7909  *
7910  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7911  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7912  *
7913  * @pre This method can be called if @p scip is in one of the following stages:
7914  * - \ref SCIP_STAGE_PROBLEM
7915  * - \ref SCIP_STAGE_TRANSFORMING
7916  * - \ref SCIP_STAGE_TRANSFORMED
7917  * - \ref SCIP_STAGE_INITPRESOLVE
7918  * - \ref SCIP_STAGE_PRESOLVING
7919  * - \ref SCIP_STAGE_EXITPRESOLVE
7920  * - \ref SCIP_STAGE_PRESOLVED
7921  * - \ref SCIP_STAGE_SOLVING
7922  */
7924  SCIP* scip, /**< SCIP data structure */
7925  SCIP_VAR* var, /**< problem variable */
7926  SCIP_Real addfactor /**< value to add to the branch factor of the variable */
7927  )
7928 {
7929  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7930 
7931  SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, addfactor + SCIPvarGetBranchFactor(var)) );
7932 
7933  return SCIP_OKAY;
7934 }
7935 
7936 /** sets the branch priority of the variable; variables with higher branch priority are always preferred to variables
7937  * with lower priority in selection of branching variable
7938  *
7939  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7940  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7941  *
7942  * @pre This method can be called if @p scip is in one of the following stages:
7943  * - \ref SCIP_STAGE_PROBLEM
7944  * - \ref SCIP_STAGE_TRANSFORMING
7945  * - \ref SCIP_STAGE_TRANSFORMED
7946  * - \ref SCIP_STAGE_INITPRESOLVE
7947  * - \ref SCIP_STAGE_PRESOLVING
7948  * - \ref SCIP_STAGE_EXITPRESOLVE
7949  * - \ref SCIP_STAGE_PRESOLVED
7950  * - \ref SCIP_STAGE_SOLVING
7951  *
7952  * @note the default branching priority is 0
7953  */
7955  SCIP* scip, /**< SCIP data structure */
7956  SCIP_VAR* var, /**< problem variable */
7957  int branchpriority /**< branch priority of the variable */
7958  )
7959 {
7960  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7961 
7962  assert( var->scip == scip );
7963 
7964  if( SCIPisTransformed(scip) )
7965  {
7966  assert(scip->branchcand != NULL);
7967 
7968  /* inform the pseudo branch candidates that the branch priority changes and change the branch priority */
7969  SCIP_CALL( SCIPbranchcandUpdateVarBranchPriority(scip->branchcand, scip->set, var, branchpriority) );
7970  }
7971  else
7972  {
7973  /* change the branching priority of the variable */
7974  SCIP_CALL( SCIPvarChgBranchPriority(var, branchpriority) );
7975  }
7976 
7977  return SCIP_OKAY;
7978 }
7979 
7980 /** changes the branch priority of the variable to the given value, if it is larger than the current priority
7981  *
7982  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7983  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7984  *
7985  * @pre This method can be called if @p scip is in one of the following stages:
7986  * - \ref SCIP_STAGE_PROBLEM
7987  * - \ref SCIP_STAGE_TRANSFORMING
7988  * - \ref SCIP_STAGE_TRANSFORMED
7989  * - \ref SCIP_STAGE_INITPRESOLVE
7990  * - \ref SCIP_STAGE_PRESOLVING
7991  * - \ref SCIP_STAGE_EXITPRESOLVE
7992  * - \ref SCIP_STAGE_PRESOLVED
7993  * - \ref SCIP_STAGE_SOLVING
7994  */
7996  SCIP* scip, /**< SCIP data structure */
7997  SCIP_VAR* var, /**< problem variable */
7998  int branchpriority /**< new branch priority of the variable, if it is larger than current priority */
7999  )
8000 {
8001  SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8002 
8003  assert( var->scip == scip );
8004 
8005  if( branchpriority > SCIPvarGetBranchPriority(var) )
8006  {
8007  SCIP_CALL( SCIPvarChgBranchPriority(var, branchpriority) );
8008  }
8009 
8010  return SCIP_OKAY;
8011 }
8012 
8013 /** adds the given value to the branch priority of the variable
8014  *
8015  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8016  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8017  *
8018  * @pre This method can be called if @p scip is in one of the following stages:
8019  * - \ref SCIP_STAGE_PROBLEM
8020  * - \ref SCIP_STAGE_TRANSFORMING
8021  * - \ref SCIP_STAGE_TRANSFORMED
8022  * - \ref SCIP_STAGE_INITPRESOLVE
8023  * - \ref SCIP_STAGE_PRESOLVING
8024  * - \ref SCIP_STAGE_EXITPRESOLVE
8025  * - \ref SCIP_STAGE_PRESOLVED
8026  * - \ref SCIP_STAGE_SOLVING
8027  */
8029  SCIP* scip, /**< SCIP data structure */
8030  SCIP_VAR* var, /**< problem variable */
8031  int addpriority /**< value to add to the branch priority of the variable */
8032  )
8033 {
8034  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8035 
8036  assert( var->scip == scip );
8037 
8038  SCIP_CALL( SCIPvarChgBranchPriority(var, addpriority + SCIPvarGetBranchPriority(var)) );
8039 
8040  return SCIP_OKAY;
8041 }
8042 
8043 /** sets the branch direction of the variable (-1: prefer downwards branch, 0: automatic selection, +1: prefer upwards
8044  * branch)
8045  *
8046  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8047  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8048  *
8049  * @pre This method can be called if @p scip is in one of the following stages:
8050  * - \ref SCIP_STAGE_PROBLEM
8051  * - \ref SCIP_STAGE_TRANSFORMING
8052  * - \ref SCIP_STAGE_TRANSFORMED
8053  * - \ref SCIP_STAGE_INITPRESOLVE
8054  * - \ref SCIP_STAGE_PRESOLVING
8055  * - \ref SCIP_STAGE_EXITPRESOLVE
8056  * - \ref SCIP_STAGE_PRESOLVED
8057  * - \ref SCIP_STAGE_SOLVING
8058  */
8060  SCIP* scip, /**< SCIP data structure */
8061  SCIP_VAR* var, /**< problem variable */
8062  SCIP_BRANCHDIR branchdirection /**< preferred branch direction of the variable (downwards, upwards, auto) */
8063  )
8064 {
8065  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchDirection", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8066 
8067  assert( var->scip == scip );
8068 
8069  SCIP_CALL( SCIPvarChgBranchDirection(var, branchdirection) );
8070 
8071  return SCIP_OKAY;
8072 }
8073 
8074 /** tightens the variable bounds due to a new variable type */
8075 static
8077  SCIP* scip, /**< SCIP data structure */
8078  SCIP_VAR* var, /**< variable to change the bound for */
8079  SCIP_VARTYPE vartype, /**< new type of variable */
8080  SCIP_Bool* infeasible /**< pointer to store whether an infeasibility was detected (, due to
8081  * integrality condition of the new variable type) */
8082  )
8083 {
8084  assert(scip != NULL);
8086  assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPvarIsTransformed(var));
8087  assert(var->scip == scip);
8088 
8089  *infeasible = FALSE;
8090 
8091  /* adjusts bounds if the variable type changed form continuous to non-continuous (integral) */
8093  {
8094  SCIP_Bool tightened;
8095 
8096  /* we adjust variable bounds to integers first, since otherwise a later bound tightening with a fractional old
8097  * bound may give an assert because SCIP expects non-continuous variables to have non-fractional bounds
8098  *
8099  * we adjust bounds with a fractionality within [eps,feastol] only if the resulting bound change is a bound
8100  * tightening, because relaxing bounds may not be allowed
8101  */
8102  if( !SCIPisFeasIntegral(scip, SCIPvarGetLbGlobal(var)) ||
8104  (!SCIPsetIsEQ(scip->set, SCIPvarGetLbGlobal(var), SCIPfeasCeil(scip, SCIPvarGetLbGlobal(var))) &&
8106  )
8107  {
8108  SCIP_CALL( SCIPtightenVarLbGlobal(scip, var, SCIPfeasCeil(scip, SCIPvarGetLbGlobal(var)), TRUE, infeasible, &tightened) );
8109  if( *infeasible )
8110  return SCIP_OKAY;
8111 
8112  /* 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
8113  * 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
8114  */
8115  assert(tightened || SCIPisFeasLE(scip, SCIPvarGetUbGlobal(var), SCIPfeasCeil(scip, SCIPvarGetLbGlobal(var))));
8116  }
8117  if( !SCIPisFeasIntegral(scip, SCIPvarGetUbGlobal(var)) ||
8119  )
8120  {
8121  SCIP_CALL( SCIPtightenVarUbGlobal(scip, var, SCIPfeasFloor(scip, SCIPvarGetUbGlobal(var)), TRUE, infeasible, &tightened) );
8122  if( *infeasible )
8123  return SCIP_OKAY;
8124 
8125  assert(tightened || SCIPisFeasGE(scip, SCIPvarGetLbGlobal(var), SCIPfeasFloor(scip, SCIPvarGetUbGlobal(var))));
8126  }
8127  }
8128 
8129  return SCIP_OKAY;
8130 }
8131 
8132 /** changes type of variable in the problem;
8133  *
8134  * @warning This type change might change the variable array returned from SCIPgetVars() and SCIPgetVarsData();
8135  *
8136  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8137  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8138  *
8139  * @pre This method can be called if @p scip is in one of the following stages:
8140  * - \ref SCIP_STAGE_PROBLEM
8141  * - \ref SCIP_STAGE_TRANSFORMING
8142  * - \ref SCIP_STAGE_PRESOLVING
8143  *
8144  * @note If SCIP is already beyond the SCIP_STAGE_PROBLEM and a original variable is passed, the variable type of the
8145  * corresponding transformed variable is changed; the type of the original variable does not change
8146  *
8147  * @note If the type changes from a continuous variable to a non-continuous variable the bounds of the variable get
8148  * adjusted w.r.t. to integrality information
8149  */
8151  SCIP* scip, /**< SCIP data structure */
8152  SCIP_VAR* var, /**< variable to change the bound for */
8153  SCIP_VARTYPE vartype, /**< new type of variable */
8154  SCIP_Bool* infeasible /**< pointer to store whether an infeasibility was detected (, due to
8155  * integrality condition of the new variable type) */
8156  )
8157 {
8158  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarType", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
8159 
8160  assert(var != NULL);
8161  assert(var->scip == scip);
8162 
8163  if( SCIPvarIsNegated(var) )
8164  {
8165  SCIPdebugMsg(scip, "upgrading type of negated variable <%s> from %d to %d\n", SCIPvarGetName(var), SCIPvarGetType(var), vartype);
8166  var = SCIPvarGetNegationVar(var);
8167  }
8168 #ifndef NDEBUG
8169  else
8170  {
8171  if( SCIPgetStage(scip) > SCIP_STAGE_PROBLEM )
8172  {
8173  SCIPdebugMsg(scip, "upgrading type of variable <%s> from %d to %d\n", SCIPvarGetName(var), SCIPvarGetType(var), vartype);
8174  }
8175  }
8176 #endif
8177 
8178  /* change variable type */
8179  switch( scip->set->stage )
8180  {
8181  case SCIP_STAGE_PROBLEM:
8182  assert(!SCIPvarIsTransformed(var));
8183 
8184  /* first adjust the variable due to new integrality information */
8185  SCIP_CALL( tightenBounds(scip, var, vartype, infeasible) );
8186 
8187  /* second change variable type */
8188  if( SCIPvarGetProbindex(var) >= 0 )
8189  {
8190  SCIP_CALL( SCIPprobChgVarType(scip->origprob, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8191  scip->branchcand, scip->eventqueue, scip->cliquetable, var, vartype) );
8192  }
8193  else
8194  {
8195  SCIP_CALL( SCIPvarChgType(var, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8196  scip->eventqueue, vartype) );
8197  }
8198  break;
8199 
8200  case SCIP_STAGE_PRESOLVING:
8201  if( !SCIPvarIsTransformed(var) )
8202  {
8203  SCIP_VAR* transvar;
8204 
8205  SCIP_CALL( SCIPgetTransformedVar(scip, var, &transvar) );
8206  assert(transvar != NULL);
8207 
8208  /* recall method with transformed variable */
8209  SCIP_CALL( SCIPchgVarType(scip, transvar, vartype, infeasible) );
8210  return SCIP_OKAY;
8211  }
8212 
8213  /* first adjust the variable due to new integrality information */
8214  SCIP_CALL( tightenBounds(scip, var, vartype, infeasible) );
8215 
8216  /* second change variable type */
8217  if( SCIPvarGetProbindex(var) >= 0 )
8218  {
8219  SCIP_CALL( SCIPprobChgVarType(scip->transprob, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8220  scip->branchcand, scip->eventqueue, scip->cliquetable, var, vartype) );
8221  }
8222  else
8223  {
8224  SCIP_CALL( SCIPvarChgType(var, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8225  scip->eventqueue, vartype) );
8226  }
8227  break;
8228 
8229  default:
8230  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
8231  return SCIP_INVALIDCALL;
8232  } /*lint !e788*/
8233 
8234  return SCIP_OKAY;
8235 }
8236 
8237 /** in problem creation and solving stage, both bounds of the variable are set to the given value;
8238  * in presolving stage, the variable is converted into a fixed variable, and bounds are changed respectively;
8239  * conversion into a fixed variable changes the vars array returned from SCIPgetVars() and SCIPgetVarsData(),
8240  * and also renders arrays returned from the SCIPvarGetImpl...() methods invalid
8241  *
8242  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8243  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8244  *
8245  * @pre This method can be called if @p scip is in one of the following stages:
8246  * - \ref SCIP_STAGE_PROBLEM
8247  * - \ref SCIP_STAGE_PRESOLVING
8248  * - \ref SCIP_STAGE_SOLVING
8249  */
8251  SCIP* scip, /**< SCIP data structure */
8252  SCIP_VAR* var, /**< variable to fix */
8253  SCIP_Real fixedval, /**< value to fix variable to */
8254  SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
8255  SCIP_Bool* fixed /**< pointer to store whether the fixing was performed (variable was unfixed) */
8256  )
8257 {
8258  assert(var != NULL);
8259  assert(infeasible != NULL);
8260  assert(fixed != NULL);
8261 
8262  SCIP_CALL( SCIPcheckStage(scip, "SCIPfixVar", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8263 
8264  *infeasible = FALSE;
8265  *fixed = FALSE;
8266 
8267  /* in the problem creation stage, modify the bounds as requested, independently from the current bounds */
8268  if( scip->set->stage != SCIP_STAGE_PROBLEM )
8269  {
8270  if( (SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPsetIsFeasIntegral(scip->set, fixedval))
8271  || SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetLbLocal(var))
8272  || SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8273  {
8274  *infeasible = TRUE;
8275  return SCIP_OKAY;
8276  }
8277  else if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED )
8278  {
8279  *infeasible = !SCIPsetIsFeasEQ(scip->set, fixedval, SCIPvarGetLbLocal(var));
8280  return SCIP_OKAY;
8281  }
8282  }
8283  else
8284  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_ORIGINAL);
8285 
8286  switch( scip->set->stage )
8287  {
8288  case SCIP_STAGE_PROBLEM:
8289  /* in the problem creation stage, modify the bounds as requested, independently from the current bounds;
8290  * we have to make sure, that the order of the bound changes does not intermediately produce an invalid
8291  * interval lb > ub
8292  */
8293  if( fixedval <= SCIPvarGetLbLocal(var) )
8294  {
8295  SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
8296  SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
8297  *fixed = TRUE;
8298  }
8299  else
8300  {
8301  SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
8302  SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
8303  *fixed = TRUE;
8304  }
8305  return SCIP_OKAY;
8306 
8307  case SCIP_STAGE_PRESOLVING:
8308  if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
8309  {
8310  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8311  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8312  scip->cliquetable, fixedval, infeasible, fixed) );
8313  return SCIP_OKAY;
8314  }
8315  /*lint -fallthrough*/
8316  case SCIP_STAGE_SOLVING:
8317  if( SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetLbLocal(var)) )
8318  {
8319  if( SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8320  {
8321  *infeasible = TRUE;
8322  return SCIP_OKAY;
8323  }
8324  else
8325  {
8326  SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
8327  *fixed = TRUE;
8328  }
8329  }
8330  if( SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8331  {
8332  if( SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetLbLocal(var)) )
8333  {
8334  *infeasible = TRUE;
8335  return SCIP_OKAY;
8336  }
8337  else
8338  {
8339  SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
8340  *fixed = TRUE;
8341  }
8342  }
8343  return SCIP_OKAY;
8344 
8345  default:
8346  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
8347  return SCIP_INVALIDCALL;
8348  } /*lint !e788*/
8349 }
8350 
8351 /** From a given equality a*x + b*y == c, aggregates one of the variables and removes it from the set of
8352  * active problem variables. This changes the vars array returned from SCIPgetVars() and SCIPgetVarsData(),
8353  * and also renders the arrays returned from the SCIPvarGetImpl...() methods for the two variables invalid.
8354  * In the first step, the equality is transformed into an equality with active problem variables
8355  * a'*x' + b'*y' == c'. If x' == y', this leads to the detection of redundancy if a' == -b' and c' == 0,
8356  * of infeasibility, if a' == -b' and c' != 0, or to a variable fixing x' == c'/(a'+b') (and possible
8357  * infeasibility) otherwise.
8358  * In the second step, the variable to be aggregated is chosen among x' and y', prefering a less strict variable
8359  * type as aggregation variable (i.e. continuous variables are preferred over implicit integers, implicit integers
8360  * over integers, and integers over binaries). If none of the variables is continuous, it is tried to find an integer
8361  * aggregation (i.e. integral coefficients a'' and b'', such that a''*x' + b''*y' == c''). This can lead to
8362  * the detection of infeasibility (e.g. if c'' is fractional), or to a rejection of the aggregation (denoted by
8363  * aggregated == FALSE), if the resulting integer coefficients are too large and thus numerically instable.
8364  *
8365  * The output flags have the following meaning:
8366  * - infeasible: the problem is infeasible
8367  * - redundant: the equality can be deleted from the constraint set
8368  * - aggregated: the aggregation was successfully performed (the variables were not aggregated before)
8369  *
8370  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8371  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8372  *
8373  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PRESOLVING
8374  */
8376  SCIP* scip, /**< SCIP data structure */
8377  SCIP_VAR* varx, /**< variable x in equality a*x + b*y == c */
8378  SCIP_VAR* vary, /**< variable y in equality a*x + b*y == c */
8379  SCIP_Real scalarx, /**< multiplier a in equality a*x + b*y == c */
8380  SCIP_Real scalary, /**< multiplier b in equality a*x + b*y == c */
8381  SCIP_Real rhs, /**< right hand side c in equality a*x + b*y == c */
8382  SCIP_Bool* infeasible, /**< pointer to store whether the aggregation is infeasible */
8383  SCIP_Bool* redundant, /**< pointer to store whether the equality is (now) redundant */
8384  SCIP_Bool* aggregated /**< pointer to store whether the aggregation was successful */
8385  )
8386 {
8387  SCIP_Real constantx;
8388  SCIP_Real constanty;
8389 
8390  assert(infeasible != NULL);
8391  assert(redundant != NULL);
8392  assert(aggregated != NULL);
8393 
8394  SCIP_CALL( SCIPcheckStage(scip, "SCIPaggregateVars", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
8395 
8396  *infeasible = FALSE;
8397  *redundant = FALSE;
8398  *aggregated = FALSE;
8399 
8400  if( SCIPtreeProbing(scip->tree) )
8401  {
8402  SCIPerrorMessage("cannot aggregate variables during probing\n");
8403  return SCIP_INVALIDCALL;
8404  }
8405  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
8406 
8407  /* do not perform aggregation if it is globally deactivated */
8408  if( scip->set->presol_donotaggr )
8409  return SCIP_OKAY;
8410 
8411  /* get the corresponding equality in active problem variable space:
8412  * transform both expressions "a*x + 0" and "b*y + 0" into problem variable space
8413  */
8414  constantx = 0.0;
8415  constanty = 0.0;
8416  SCIP_CALL( SCIPvarGetProbvarSum(&varx, scip->set, &scalarx, &constantx) );
8417  SCIP_CALL( SCIPvarGetProbvarSum(&vary, scip->set, &scalary, &constanty) );
8418 
8419  /* we cannot aggregate multi-aggregated variables */
8421  return SCIP_OKAY;
8422 
8423  /* move the constant to the right hand side to acquire the form "a'*x' + b'*y' == c'" */
8424  rhs -= (constantx + constanty);
8425 
8426  /* if a scalar is zero, treat the variable as fixed-to-zero variable */
8427  if( SCIPsetIsZero(scip->set, scalarx) )
8428  varx = NULL;
8429  if( SCIPsetIsZero(scip->set, scalary) )
8430  vary = NULL;
8431 
8432  /* capture the special cases that less than two variables are left, due to resolutions to a fixed variable or
8433  * to the same active variable
8434  */
8435  if( varx == NULL && vary == NULL )
8436  {
8437  /* both variables were resolved to fixed variables */
8438  *infeasible = !SCIPsetIsZero(scip->set, rhs);
8439  *redundant = TRUE;
8440  }
8441  else if( varx == NULL )
8442  {
8443  assert(SCIPsetIsZero(scip->set, scalarx));
8444  assert(!SCIPsetIsZero(scip->set, scalary));
8445 
8446  /* variable x was resolved to fixed variable: variable y can be fixed to c'/b' */
8447  SCIP_CALL( SCIPvarFix(vary, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8448  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8449  scip->cliquetable, rhs/scalary, infeasible, aggregated) );
8450  *redundant = TRUE;
8451  }
8452  else if( vary == NULL )
8453  {
8454  assert(SCIPsetIsZero(scip->set, scalary));
8455  assert(!SCIPsetIsZero(scip->set, scalarx));
8456 
8457  /* variable y was resolved to fixed variable: variable x can be fixed to c'/a' */
8458  SCIP_CALL( SCIPvarFix(varx, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8459  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8460  scip->cliquetable, rhs/scalarx, infeasible, aggregated) );
8461  *redundant = TRUE;
8462  }
8463  else if( varx == vary )
8464  {
8465  /* both variables were resolved to the same active problem variable: this variable can be fixed */
8466  scalarx += scalary;
8467  if( SCIPsetIsZero(scip->set, scalarx) )
8468  {
8469  /* left hand side of equality is zero: equality is potentially infeasible */
8470  *infeasible = !SCIPsetIsZero(scip->set, rhs);
8471  }
8472  else
8473  {
8474  /* sum of scalars is not zero: fix variable x' == y' to c'/(a'+b') */
8475  SCIP_CALL( SCIPvarFix(varx, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8476  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8477  scip->cliquetable, rhs/scalarx, infeasible, aggregated) );
8478  }
8479  *redundant = TRUE;
8480  }
8481  else
8482  {
8483  /* both variables are different active problem variables, and both scalars are non-zero: try to aggregate them */
8484  SCIP_CALL( SCIPvarTryAggregateVars(scip->set, scip->mem->probmem, scip->stat, scip->transprob, scip->origprob,
8485  scip->primal, scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventfilter,
8486  scip->eventqueue, varx, vary, scalarx, scalary, rhs, infeasible, aggregated) );
8487  *redundant = *aggregated;
8488  }
8489 
8490  return SCIP_OKAY;
8491 }
8492 
8493 /** converts variable into multi-aggregated variable; this changes the variable array returned from
8494  * SCIPgetVars() and SCIPgetVarsData();
8495  *
8496  * @warning The integrality condition is not checked anymore on the multi-aggregated variable. You must not
8497  * multi-aggregate an integer variable without being sure, that integrality on the aggregation variables
8498  * implies integrality on the aggregated variable.
8499  *
8500  * The output flags have the following meaning:
8501  * - infeasible: the problem is infeasible
8502  * - aggregated: the aggregation was successfully performed (the variables were not aggregated before)
8503  *
8504  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8505  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8506  *
8507  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PRESOLVING
8508  */
8510  SCIP* scip, /**< SCIP data structure */
8511  SCIP_VAR* var, /**< variable x to aggregate */
8512  int naggvars, /**< number n of variables in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8513  SCIP_VAR** aggvars, /**< variables y_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8514  SCIP_Real* scalars, /**< multipliers a_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8515  SCIP_Real constant, /**< constant shift c in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8516  SCIP_Bool* infeasible, /**< pointer to store whether the aggregation is infeasible */
8517  SCIP_Bool* aggregated /**< pointer to store whether the aggregation was successful */
8518  )
8519 {
8520  SCIP_CALL( SCIPcheckStage(scip, "SCIPmultiaggregateVar", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
8521 
8522  assert(var->scip == scip);
8523 
8524  if( SCIPtreeProbing(scip->tree) )
8525  {
8526  SCIPerrorMessage("cannot multi-aggregate variables during probing\n");
8527  return SCIP_INVALIDCALL;
8528  }
8529  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
8530 
8531  SCIP_CALL( SCIPvarMultiaggregate(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8532  scip->primal, scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventfilter,
8533  scip->eventqueue, naggvars, aggvars, scalars, constant, infeasible, aggregated) );
8534 
8535  return SCIP_OKAY;
8536 }
8537 
8538 /** returns whether aggregation of variables is not allowed */
8540  SCIP* scip /**< SCIP data structure */
8541  )
8542 {
8543  assert(scip != NULL);
8544 
8545  return scip->set->presol_donotaggr;
8546 }
8547 
8548 /** returns whether multi-aggregation is disabled */
8550  SCIP* scip /**< SCIP data structure */
8551  )
8552 {
8553  assert(scip != NULL);
8554 
8555  return scip->set->presol_donotmultaggr;
8556 }
8557 
8558 /** returns whether variable is not allowed to be multi-aggregated */
8560  SCIP* scip, /**< SCIP data structure */
8561  SCIP_VAR* var /**< variable x to aggregate */
8562  )
8563 {
8564  assert(scip != NULL);
8565  assert(var != NULL);
8566  assert(var->scip == scip);
8567 
8568  return scip->set->presol_donotmultaggr || SCIPvarDoNotMultaggr(var);
8569 }
8570 
8571 /** returns whether dual reductions are allowed during propagation and presolving
8572  *
8573  * @deprecated Please use SCIPallowStrongDualReds()
8574  */
8576  SCIP* scip /**< SCIP data structure */
8577  )
8578 {
8579  assert(scip != NULL);
8580 
8581  return !scip->set->reopt_enable && scip->set->misc_allowstrongdualreds;
8582 }
8583 
8584 /** returns whether strong dual reductions are allowed during propagation and presolving
8585  *
8586  * @note A reduction is called strong dual, if it may discard feasible/optimal solutions, but leaves at least one
8587  * optimal solution intact. Often such reductions are based on analyzing the objective function and variable
8588  * locks.
8589  */
8591  SCIP* scip /**< SCIP data structure */
8592  )
8593 {
8594  assert(scip != NULL);
8595 
8596  return !scip->set->reopt_enable && scip->set->misc_allowstrongdualreds;
8597 }
8598 
8599 /** returns whether propagation w.r.t. current objective is allowed
8600  *
8601  * @deprecated Please use SCIPallowWeakDualReds()
8602  */
8604  SCIP* scip /**< SCIP data structure */
8605  )
8606 {
8607  assert(scip != NULL);
8608 
8609  return !scip->set->reopt_enable && scip->set->misc_allowweakdualreds;
8610 }
8611 
8612 /** returns whether weak dual reductions are allowed during propagation and presolving
8613  *
8614  * @note A reduction is called weak dual, if it may discard feasible solutions, but leaves at all optimal solutions
8615  * intact. Often such reductions are based on analyzing the objective function, reduced costs, and/or dual LPs.
8616  */
8618  SCIP* scip /**< SCIP data structure */
8619  )
8620 {
8621  assert(scip != NULL);
8622 
8623  return !scip->set->reopt_enable && scip->set->misc_allowweakdualreds;
8624 }
8625 
8626 /** marks the variable that it must not be multi-aggregated
8627  *
8628  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8629  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8630  *
8631  * @pre This method can be called if @p scip is in one of the following stages:
8632  * - \ref SCIP_STAGE_INIT
8633  * - \ref SCIP_STAGE_PROBLEM
8634  * - \ref SCIP_STAGE_TRANSFORMING
8635  * - \ref SCIP_STAGE_TRANSFORMED
8636  * - \ref SCIP_STAGE_INITPRESOLVE
8637  * - \ref SCIP_STAGE_PRESOLVING
8638  * - \ref SCIP_STAGE_EXITPRESOLVE
8639  *
8640  * @note There exists no "unmark" method since it has to be ensured that if a plugin requires that a variable is not
8641  * multi-aggregated that this is will be the case.
8642  */
8644  SCIP* scip, /**< SCIP data structure */
8645  SCIP_VAR* var /**< variable to delete */
8646  )
8647 {
8648  assert(scip != NULL);
8649  assert(var != NULL);
8650  assert(var->scip == scip);
8651 
8652  SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkDoNotMultaggrVar", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE) );
8653 
8655 
8656  return SCIP_OKAY;
8657 }
8658 
8659 /** enables the collection of statistics for a variable
8660  *
8661  * @pre This method can be called if @p scip is in one of the following stages:
8662  * - \ref SCIP_STAGE_PROBLEM
8663  * - \ref SCIP_STAGE_INITPRESOLVE
8664  * - \ref SCIP_STAGE_PRESOLVING
8665  * - \ref SCIP_STAGE_EXITPRESOLVE
8666  * - \ref SCIP_STAGE_SOLVING
8667  * - \ref SCIP_STAGE_SOLVED
8668  */
8670  SCIP* scip /**< SCIP data structure */
8671  )
8672 {
8673  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPenableVarHistory", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8674 
8676 }
8677 
8678 /** disables the collection of any statistic for a variable
8679  *
8680  * @pre This method can be called if @p scip is in one of the following stages:
8681  * - \ref SCIP_STAGE_PROBLEM
8682  * - \ref SCIP_STAGE_INITPRESOLVE
8683  * - \ref SCIP_STAGE_PRESOLVING
8684  * - \ref SCIP_STAGE_EXITPRESOLVE
8685  * - \ref SCIP_STAGE_SOLVING
8686  * - \ref SCIP_STAGE_SOLVED
8687  */
8689  SCIP* scip /**< SCIP data structure */
8690  )
8691 {
8692  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPdisableVarHistory", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8693 
8695 }
8696 
8697 /** updates the pseudo costs of the given variable and the global pseudo costs after a change of "solvaldelta" in the
8698  * variable's solution value and resulting change of "objdelta" in the in the LP's objective value;
8699  * the update is ignored, if the objective value difference is infinite
8700  *
8701  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8702  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8703  *
8704  * @pre This method can be called if @p scip is in one of the following stages:
8705  * - \ref SCIP_STAGE_SOLVING
8706  * - \ref SCIP_STAGE_SOLVED
8707  */
8709  SCIP* scip, /**< SCIP data structure */
8710  SCIP_VAR* var, /**< problem variable */
8711  SCIP_Real solvaldelta, /**< difference of variable's new LP value - old LP value */
8712  SCIP_Real objdelta, /**< difference of new LP's objective value - old LP's objective value */
8713  SCIP_Real weight /**< weight in (0,1] of this update in pseudo cost sum */
8714  )
8715 {
8716  SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateVarPseudocost", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8717 
8718  if( !SCIPsetIsInfinity(scip->set, 2*objdelta) ) /* differences infinity - eps should also be treated as infinity */
8719  {
8720  if( scip->set->branch_divingpscost || (!scip->lp->diving && !SCIPtreeProbing(scip->tree)) )
8721  {
8722  SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, solvaldelta, objdelta, weight) );
8723  }
8724  }
8725 
8726  return SCIP_OKAY;
8727 }
8728 
8729 /** gets the variable's pseudo cost value for the given change of the variable's LP value
8730  *
8731  * @return the variable's pseudo cost value for the given change of the variable's LP value
8732  *
8733  * @pre This method can be called if @p scip is in one of the following stages:
8734  * - \ref SCIP_STAGE_INITPRESOLVE
8735  * - \ref SCIP_STAGE_PRESOLVING
8736  * - \ref SCIP_STAGE_EXITPRESOLVE
8737  * - \ref SCIP_STAGE_PRESOLVED
8738  * - \ref SCIP_STAGE_INITSOLVE
8739  * - \ref SCIP_STAGE_SOLVING
8740  * - \ref SCIP_STAGE_SOLVED
8741  */
8743  SCIP* scip, /**< SCIP data structure */
8744  SCIP_VAR* var, /**< problem variable */
8745  SCIP_Real solvaldelta /**< difference of variable's new LP value - old LP value */
8746  )
8747 {
8748  assert( var->scip == scip );
8749 
8750  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostVal", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8751 
8752  return SCIPvarGetPseudocost(var, scip->stat, solvaldelta);
8753 }
8754 
8755 /** gets the variable's pseudo cost value for the given change of the variable's LP value,
8756  * only using the pseudo cost information of the current run
8757  *
8758  * @return the variable's pseudo cost value for the given change of the variable's LP value,
8759  * only using the pseudo cost information of the current run
8760  *
8761  * @pre This method can be called if @p scip is in one of the following stages:
8762  * - \ref SCIP_STAGE_INITPRESOLVE
8763  * - \ref SCIP_STAGE_PRESOLVING
8764  * - \ref SCIP_STAGE_EXITPRESOLVE
8765  * - \ref SCIP_STAGE_PRESOLVED
8766  * - \ref SCIP_STAGE_INITSOLVE
8767  * - \ref SCIP_STAGE_SOLVING
8768  * - \ref SCIP_STAGE_SOLVED
8769  */
8771  SCIP* scip, /**< SCIP data structure */
8772  SCIP_VAR* var, /**< problem variable */
8773  SCIP_Real solvaldelta /**< difference of variable's new LP value - old LP value */
8774  )
8775 {
8776  assert( var->scip == scip );
8777 
8778  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostValCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8779 
8780  return SCIPvarGetPseudocostCurrentRun(var, scip->stat, solvaldelta);
8781 }
8782 
8783 /** gets the variable's pseudo cost value for the given direction
8784  *
8785  * @return the variable's pseudo cost value for the given direction
8786  *
8787  * @pre This method can be called if @p scip is in one of the following stages:
8788  * - \ref SCIP_STAGE_INITPRESOLVE
8789  * - \ref SCIP_STAGE_PRESOLVING
8790  * - \ref SCIP_STAGE_EXITPRESOLVE
8791  * - \ref SCIP_STAGE_PRESOLVED
8792  * - \ref SCIP_STAGE_INITSOLVE
8793  * - \ref SCIP_STAGE_SOLVING
8794  * - \ref SCIP_STAGE_SOLVED
8795  */
8797  SCIP* scip, /**< SCIP data structure */
8798  SCIP_VAR* var, /**< problem variable */
8799  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8800  )
8801 {
8802  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocost", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8803  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8804  assert(var->scip == scip);
8805 
8806  return SCIPvarGetPseudocost(var, scip->stat, dir == SCIP_BRANCHDIR_DOWNWARDS ? -1.0 : 1.0);
8807 }
8808 
8809 /** gets the variable's pseudo cost value for the given direction,
8810  * only using the pseudo cost information of the current run
8811  *
8812  * @return the variable's pseudo cost value for the given direction,
8813  * only using the pseudo cost information of the current run
8814  *
8815  * @pre This method can be called if @p scip is in one of the following stages:
8816  * - \ref SCIP_STAGE_INITPRESOLVE
8817  * - \ref SCIP_STAGE_PRESOLVING
8818  * - \ref SCIP_STAGE_EXITPRESOLVE
8819  * - \ref SCIP_STAGE_PRESOLVED
8820  * - \ref SCIP_STAGE_INITSOLVE
8821  * - \ref SCIP_STAGE_SOLVING
8822  * - \ref SCIP_STAGE_SOLVED
8823  */
8825  SCIP* scip, /**< SCIP data structure */
8826  SCIP_VAR* var, /**< problem variable */
8827  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8828  )
8829 {
8830  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8831  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8832  assert(var->scip == scip);
8833 
8834  return SCIPvarGetPseudocostCurrentRun(var, scip->stat, dir == SCIP_BRANCHDIR_DOWNWARDS ? -1.0 : 1.0);
8835 }
8836 
8837 /** gets the variable's (possible fractional) number of pseudo cost updates for the given direction
8838  *
8839  * @return the variable's (possible fractional) number of pseudo cost updates for the given direction
8840  *
8841  * @pre This method can be called if @p scip is in one of the following stages:
8842  * - \ref SCIP_STAGE_INITPRESOLVE
8843  * - \ref SCIP_STAGE_PRESOLVING
8844  * - \ref SCIP_STAGE_EXITPRESOLVE
8845  * - \ref SCIP_STAGE_PRESOLVED
8846  * - \ref SCIP_STAGE_INITSOLVE
8847  * - \ref SCIP_STAGE_SOLVING
8848  * - \ref SCIP_STAGE_SOLVED
8849  */
8851  SCIP* scip, /**< SCIP data structure */
8852  SCIP_VAR* var, /**< problem variable */
8853  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8854  )
8855 {
8856  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCount", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8857  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8858  assert(var->scip == scip);
8859 
8860  return SCIPvarGetPseudocostCount(var, dir);
8861 }
8862 
8863 /** gets the variable's (possible fractional) number of pseudo cost updates for the given direction,
8864  * only using the pseudo cost information of the current run
8865  *
8866  * @return the variable's (possible fractional) number of pseudo cost updates for the given direction,
8867  * only using the pseudo cost information of the current run
8868  *
8869  * @pre This method can be called if @p scip is in one of the following stages:
8870  * - \ref SCIP_STAGE_INITPRESOLVE
8871  * - \ref SCIP_STAGE_PRESOLVING
8872  * - \ref SCIP_STAGE_EXITPRESOLVE
8873  * - \ref SCIP_STAGE_PRESOLVED
8874  * - \ref SCIP_STAGE_INITSOLVE
8875  * - \ref SCIP_STAGE_SOLVING
8876  * - \ref SCIP_STAGE_SOLVED
8877  */
8879  SCIP* scip, /**< SCIP data structure */
8880  SCIP_VAR* var, /**< problem variable */
8881  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8882  )
8883 {
8884  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCountCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8885  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8886  assert(var->scip == scip);
8887 
8888  return SCIPvarGetPseudocostCountCurrentRun(var, dir);
8889 }
8890 
8891 /** get pseudo cost variance of the variable, either for entire solve or only for current branch and bound run
8892  *
8893  * @return returns the (corrected) variance of pseudo code information collected so far.
8894  *
8895  * @pre This method can be called if @p scip is in one of the following stages:
8896  * - \ref SCIP_STAGE_INITPRESOLVE
8897  * - \ref SCIP_STAGE_PRESOLVING
8898  * - \ref SCIP_STAGE_EXITPRESOLVE
8899  * - \ref SCIP_STAGE_PRESOLVED
8900  * - \ref SCIP_STAGE_INITSOLVE
8901  * - \ref SCIP_STAGE_SOLVING
8902  * - \ref SCIP_STAGE_SOLVED
8903  */
8905  SCIP* scip, /**< SCIP data structure */
8906  SCIP_VAR* var, /**< problem variable */
8907  SCIP_BRANCHDIR dir, /**< branching direction (downwards, or upwards) */
8908  SCIP_Bool onlycurrentrun /**< only for pseudo costs of current branch and bound run */
8909  )
8910 {
8911  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostVariance", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8912  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8913  assert(var->scip == scip);
8914 
8915  return SCIPvarGetPseudocostVariance(var, dir, onlycurrentrun);
8916 }
8917 
8918 /** calculates a confidence bound for this variable under the assumption of normally distributed pseudo costs
8919  *
8920  * The confidence bound \f$ \theta \geq 0\f$ denotes the interval borders \f$ [X - \theta, \ X + \theta]\f$, which contains
8921  * the true pseudo costs of the variable, i.e., the expected value of the normal distribution, with a probability
8922  * of 2 * clevel - 1.
8923  *
8924  * @return value of confidence bound for this variable
8925  */
8927  SCIP* scip, /**< SCIP data structure */
8928  SCIP_VAR* var, /**< variable in question */
8929  SCIP_BRANCHDIR dir, /**< the branching direction for the confidence bound */
8930  SCIP_Bool onlycurrentrun, /**< should only the current run be taken into account */
8931  SCIP_CONFIDENCELEVEL clevel /**< confidence level for the interval */
8932  )
8933 {
8934  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPcalculatePscostConfidenceBound", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8935 
8936  return SCIPvarCalcPscostConfidenceBound(var, scip->set, dir, onlycurrentrun, clevel);
8937 }
8938 
8939 /** check if variable pseudo-costs have a significant difference in location. The significance depends on
8940  * the choice of \p clevel and on the kind of tested hypothesis. The one-sided hypothesis, which
8941  * should be rejected, is that fracy * mu_y >= fracx * mu_x, where mu_y and mu_x denote the
8942  * unknown location means of the underlying pseudo-cost distributions of x and y.
8943  *
8944  * This method is applied best if variable x has a better pseudo-cost score than y. The method hypothesizes that y were actually
8945  * better than x (despite the current information), meaning that y can be expected to yield branching
8946  * decisions as least as good as x in the long run. If the method returns TRUE, the current history information is
8947  * sufficient to safely rely on the alternative hypothesis that x yields indeed a better branching score (on average)
8948  * than y.
8949  *
8950  * @note The order of x and y matters for the one-sided hypothesis
8951  *
8952  * @note set \p onesided to FALSE if you are not sure which variable is better. The hypothesis tested then reads
8953  * fracy * mu_y == fracx * mu_x vs the alternative hypothesis fracy * mu_y != fracx * mu_x.
8954  *
8955  * @return TRUE if the hypothesis can be safely rejected at the given confidence level
8956  */
8958  SCIP* scip, /**< SCIP data structure */
8959  SCIP_VAR* varx, /**< variable x */
8960  SCIP_Real fracx, /**< the fractionality of variable x */
8961  SCIP_VAR* vary, /**< variable y */
8962  SCIP_Real fracy, /**< the fractionality of variable y */
8963  SCIP_BRANCHDIR dir, /**< branching direction */
8964  SCIP_CONFIDENCELEVEL clevel, /**< confidence level for rejecting hypothesis */
8965  SCIP_Bool onesided /**< should a one-sided hypothesis y >= x be tested? */
8966  )
8967 {
8968  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPsignificantVarPscostDifference", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8969 
8970  return SCIPvarSignificantPscostDifference(scip->set, scip->stat, varx, fracx, vary, fracy, dir, clevel, onesided);
8971 }
8972 
8973 /** tests at a given confidence level whether the variable pseudo-costs only have a small probability to
8974  * exceed a \p threshold. This is useful to determine if past observations provide enough evidence
8975  * to skip an expensive strong-branching step if there is already a candidate that has been proven to yield an improvement
8976  * of at least \p threshold.
8977  *
8978  * @note use \p clevel to adjust the level of confidence. For SCIP_CONFIDENCELEVEL_MIN, the method returns TRUE if
8979  * the estimated probability to exceed \p threshold is less than 25 %.
8980  *
8981  * @see SCIP_Confidencelevel for a list of available levels. The used probability limits refer to the one-sided levels
8982  * of confidence.
8983  *
8984  * @return TRUE if the variable pseudo-cost probabilistic model is likely to be smaller than \p threshold
8985  * at the given confidence level \p clevel.
8986  */
8988  SCIP* scip, /**< SCIP data structure */
8989  SCIP_VAR* var, /**< variable x */
8990  SCIP_Real frac, /**< the fractionality of variable x */
8991  SCIP_Real threshold, /**< the threshold to test against */
8992  SCIP_BRANCHDIR dir, /**< branching direction */
8993  SCIP_CONFIDENCELEVEL clevel /**< confidence level for rejecting hypothesis */
8994  )
8995 {
8996  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPpscostThresholdProbabilityTest", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8997 
8998  return SCIPvarPscostThresholdProbabilityTest(scip->set, scip->stat, var, frac, threshold, dir, clevel);
8999 }
9000 
9001 /** check if the current pseudo cost relative error in a direction violates the given threshold. The Relative
9002  * Error is calculated at a specific confidence level
9003  *
9004  * @return TRUE if relative error in variable pseudo costs is smaller than \p threshold
9005  */
9007  SCIP* scip, /**< SCIP data structure */
9008  SCIP_VAR* var, /**< variable in question */
9009  SCIP_Real threshold, /**< threshold for relative errors to be considered reliable (enough) */
9010  SCIP_CONFIDENCELEVEL clevel /**< a given confidence level */
9011  )
9012 {
9013  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisVarPscostRelerrorReliable", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9014 
9015  return SCIPvarIsPscostRelerrorReliable(var, scip->set, scip->stat, threshold, clevel);
9016 }
9017 
9018 /** gets the variable's pseudo cost score value for the given LP solution value
9019  *
9020  * @return the variable's pseudo cost score value for the given LP solution value
9021  *
9022  * @pre This method can be called if @p scip is in one of the following stages:
9023  * - \ref SCIP_STAGE_INITPRESOLVE
9024  * - \ref SCIP_STAGE_PRESOLVING
9025  * - \ref SCIP_STAGE_EXITPRESOLVE
9026  * - \ref SCIP_STAGE_PRESOLVED
9027  * - \ref SCIP_STAGE_INITSOLVE
9028  * - \ref SCIP_STAGE_SOLVING
9029  * - \ref SCIP_STAGE_SOLVED
9030  */
9032  SCIP* scip, /**< SCIP data structure */
9033  SCIP_VAR* var, /**< problem variable */
9034  SCIP_Real solval /**< variable's LP solution value */
9035  )
9036 {
9037  SCIP_Real downsol;
9038  SCIP_Real upsol;
9039  SCIP_Real pscostdown;
9040  SCIP_Real pscostup;
9041 
9042  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9043 
9044  assert( var->scip == scip );
9045 
9046  downsol = SCIPsetFeasCeil(scip->set, solval-1.0);
9047  upsol = SCIPsetFeasFloor(scip->set, solval+1.0);
9048  pscostdown = SCIPvarGetPseudocost(var, scip->stat, downsol-solval);
9049  pscostup = SCIPvarGetPseudocost(var, scip->stat, upsol-solval);
9050 
9051  return SCIPbranchGetScore(scip->set, var, pscostdown, pscostup);
9052 }
9053 
9054 /** gets the variable's pseudo cost score value for the given LP solution value,
9055  * only using the pseudo cost information of the current run
9056  *
9057  * @return the variable's pseudo cost score value for the given LP solution value,
9058  * only using the pseudo cost information of the current run
9059  *
9060  * @pre This method can be called if @p scip is in one of the following stages:
9061  * - \ref SCIP_STAGE_INITPRESOLVE
9062  * - \ref SCIP_STAGE_PRESOLVING
9063  * - \ref SCIP_STAGE_EXITPRESOLVE
9064  * - \ref SCIP_STAGE_PRESOLVED
9065  * - \ref SCIP_STAGE_INITSOLVE
9066  * - \ref SCIP_STAGE_SOLVING
9067  * - \ref SCIP_STAGE_SOLVED
9068  */
9070  SCIP* scip, /**< SCIP data structure */
9071  SCIP_VAR* var, /**< problem variable */
9072  SCIP_Real solval /**< variable's LP solution value */
9073  )
9074 {
9075  SCIP_Real downsol;
9076  SCIP_Real upsol;
9077  SCIP_Real pscostdown;
9078  SCIP_Real pscostup;
9079 
9080  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9081 
9082  assert( var->scip == scip );
9083 
9084  downsol = SCIPsetFeasCeil(scip->set, solval-1.0);
9085  upsol = SCIPsetFeasFloor(scip->set, solval+1.0);
9086  pscostdown = SCIPvarGetPseudocostCurrentRun(var, scip->stat, downsol-solval);
9087  pscostup = SCIPvarGetPseudocostCurrentRun(var, scip->stat, upsol-solval);
9088 
9089  return SCIPbranchGetScore(scip->set, var, pscostdown, pscostup);
9090 }
9091 
9092 /** returns the variable's VSIDS value
9093  *
9094  * @return the variable's VSIDS value
9095  *
9096  * @pre This method can be called if @p scip is in one of the following stages:
9097  * - \ref SCIP_STAGE_INITPRESOLVE
9098  * - \ref SCIP_STAGE_PRESOLVING
9099  * - \ref SCIP_STAGE_EXITPRESOLVE
9100  * - \ref SCIP_STAGE_PRESOLVED
9101  * - \ref SCIP_STAGE_INITSOLVE
9102  * - \ref SCIP_STAGE_SOLVING
9103  * - \ref SCIP_STAGE_SOLVED
9104  */
9106  SCIP* scip, /**< SCIP data structure */
9107  SCIP_VAR* var, /**< problem variable */
9108  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9109  )
9110 {
9111  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarVSIDS", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9112 
9113  assert( var->scip == scip );
9114 
9115  if( dir != SCIP_BRANCHDIR_DOWNWARDS && dir != SCIP_BRANCHDIR_UPWARDS )
9116  {
9117  SCIPerrorMessage("invalid branching direction %d when asking for VSIDS value\n", dir);
9118  return SCIP_INVALID;
9119  }
9120 
9121  return SCIPvarGetVSIDS(var, scip->stat, dir);
9122 }
9123 
9124 /** returns the variable's VSIDS value only using conflicts of the current run
9125  *
9126  * @return the variable's VSIDS value only using conflicts of the current run
9127  *
9128  * @pre This method can be called if @p scip is in one of the following stages:
9129  * - \ref SCIP_STAGE_INITPRESOLVE
9130  * - \ref SCIP_STAGE_PRESOLVING
9131  * - \ref SCIP_STAGE_EXITPRESOLVE
9132  * - \ref SCIP_STAGE_PRESOLVED
9133  * - \ref SCIP_STAGE_INITSOLVE
9134  * - \ref SCIP_STAGE_SOLVING
9135  * - \ref SCIP_STAGE_SOLVED
9136  */
9138  SCIP* scip, /**< SCIP data structure */
9139  SCIP_VAR* var, /**< problem variable */
9140  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9141  )
9142 {
9143  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarVSIDSCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9144 
9145  assert( var->scip == scip );
9146 
9147  if( dir != SCIP_BRANCHDIR_DOWNWARDS && dir != SCIP_BRANCHDIR_UPWARDS )
9148  {
9149  SCIPerrorMessage("invalid branching direction %d when asking for VSIDS value\n", dir);
9150  return SCIP_INVALID;
9151  }
9152 
9153  return SCIPvarGetVSIDSCurrentRun(var, scip->stat, dir);
9154 }
9155 
9156 /** returns the variable's conflict score value
9157  *
9158  * @return the variable's conflict score value
9159  *
9160  * @pre This method can be called if @p scip is in one of the following stages:
9161  * - \ref SCIP_STAGE_INITPRESOLVE
9162  * - \ref SCIP_STAGE_PRESOLVING
9163  * - \ref SCIP_STAGE_EXITPRESOLVE
9164  * - \ref SCIP_STAGE_PRESOLVED
9165  * - \ref SCIP_STAGE_INITSOLVE
9166  * - \ref SCIP_STAGE_SOLVING
9167  * - \ref SCIP_STAGE_SOLVED
9168  */
9170  SCIP* scip, /**< SCIP data structure */
9171  SCIP_VAR* var /**< problem variable */
9172  )
9173 {
9174  SCIP_Real downscore;
9175  SCIP_Real upscore;
9176 
9177  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9178 
9179  assert( var->scip == scip );
9180 
9181  downscore = SCIPvarGetVSIDS(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9182  upscore = SCIPvarGetVSIDS(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9183 
9184  return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9185 }
9186 
9187 /** returns the variable's conflict score value only using conflicts of the current run
9188  *
9189  * @return the variable's conflict score value only using conflicts of the current run
9190  *
9191  * @pre This method can be called if @p scip is in one of the following stages:
9192  * - \ref SCIP_STAGE_INITPRESOLVE
9193  * - \ref SCIP_STAGE_PRESOLVING
9194  * - \ref SCIP_STAGE_EXITPRESOLVE
9195  * - \ref SCIP_STAGE_PRESOLVED
9196  * - \ref SCIP_STAGE_INITSOLVE
9197  * - \ref SCIP_STAGE_SOLVING
9198  * - \ref SCIP_STAGE_SOLVED
9199  */
9201  SCIP* scip, /**< SCIP data structure */
9202  SCIP_VAR* var /**< problem variable */
9203  )
9204 {
9205  SCIP_Real downscore;
9206  SCIP_Real upscore;
9207 
9208  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9209 
9210  assert( var->scip == scip );
9211 
9212  downscore = SCIPvarGetVSIDSCurrentRun(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9213  upscore = SCIPvarGetVSIDSCurrentRun(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9214 
9215  return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9216 }
9217 
9218 /** returns the variable's conflict length score
9219  *
9220  * @return the variable's conflict length score
9221  *
9222  * @pre This method can be called if @p scip is in one of the following stages:
9223  * - \ref SCIP_STAGE_INITPRESOLVE
9224  * - \ref SCIP_STAGE_PRESOLVING
9225  * - \ref SCIP_STAGE_EXITPRESOLVE
9226  * - \ref SCIP_STAGE_PRESOLVED
9227  * - \ref SCIP_STAGE_INITSOLVE
9228  * - \ref SCIP_STAGE_SOLVING
9229  * - \ref SCIP_STAGE_SOLVED
9230  */
9232  SCIP* scip, /**< SCIP data structure */
9233  SCIP_VAR* var /**< problem variable */
9234  )
9235 {
9236  SCIP_Real downscore;
9237  SCIP_Real upscore;
9238 
9239  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictlengthScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9240 
9241  assert( var->scip == scip );
9242 
9245 
9246  return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9247 }
9248 
9249 /** returns the variable's conflict length score only using conflicts of the current run
9250  *
9251  * @return the variable's conflict length score only using conflicts of the current run
9252  *
9253  * @pre This method can be called if @p scip is in one of the following stages:
9254  * - \ref SCIP_STAGE_INITPRESOLVE
9255  * - \ref SCIP_STAGE_PRESOLVING
9256  * - \ref SCIP_STAGE_EXITPRESOLVE
9257  * - \ref SCIP_STAGE_PRESOLVED
9258  * - \ref SCIP_STAGE_INITSOLVE
9259  * - \ref SCIP_STAGE_SOLVING
9260  * - \ref SCIP_STAGE_SOLVED
9261  */
9263  SCIP* scip, /**< SCIP data structure */
9264  SCIP_VAR* var /**< problem variable */
9265  )
9266 {
9267  SCIP_Real downscore;
9268  SCIP_Real upscore;
9269 
9270  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictlengthScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9271 
9272  assert( var->scip == scip );
9273 
9276 
9277  return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9278 }
9279 
9280 /** returns the variable's average conflict length
9281  *
9282  * @return the variable's average conflict length
9283  *
9284  * @pre This method can be called if @p scip is in one of the following stages:
9285  * - \ref SCIP_STAGE_INITPRESOLVE
9286  * - \ref SCIP_STAGE_PRESOLVING
9287  * - \ref SCIP_STAGE_EXITPRESOLVE
9288  * - \ref SCIP_STAGE_PRESOLVED
9289  * - \ref SCIP_STAGE_INITSOLVE
9290  * - \ref SCIP_STAGE_SOLVING
9291  * - \ref SCIP_STAGE_SOLVED
9292  */
9294  SCIP* scip, /**< SCIP data structure */
9295  SCIP_VAR* var, /**< problem variable */
9296  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9297  )
9298 {
9299  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgConflictlength", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9300 
9301  assert( var->scip == scip );
9302 
9303  return SCIPvarGetAvgConflictlength(var, dir);
9304 }
9305 
9306 /** returns the variable's average conflict length only using conflicts of the current run
9307  *
9308  * @return the variable's average conflict length only using conflicts of the current run
9309  *
9310  * @pre This method can be called if @p scip is in one of the following stages:
9311  * - \ref SCIP_STAGE_INITPRESOLVE
9312  * - \ref SCIP_STAGE_PRESOLVING
9313  * - \ref SCIP_STAGE_EXITPRESOLVE
9314  * - \ref SCIP_STAGE_PRESOLVED
9315  * - \ref SCIP_STAGE_INITSOLVE
9316  * - \ref SCIP_STAGE_SOLVING
9317  * - \ref SCIP_STAGE_SOLVED
9318  */
9320  SCIP* scip, /**< SCIP data structure */
9321  SCIP_VAR* var, /**< problem variable */
9322  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9323  )
9324 {
9325  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgConflictlengthCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9326 
9327  assert( var->scip == scip );
9328 
9329  return SCIPvarGetAvgConflictlengthCurrentRun(var, dir);
9330 }
9331 
9332 /** returns the average number of inferences found after branching on the variable in given direction;
9333  * if branching on the variable in the given direction was yet evaluated, the average number of inferences
9334  * over all variables for branching in the given direction is returned
9335  *
9336  * @return the average number of inferences found after branching on the variable in given direction
9337  *
9338  * @pre This method can be called if @p scip is in one of the following stages:
9339  * - \ref SCIP_STAGE_INITPRESOLVE
9340  * - \ref SCIP_STAGE_PRESOLVING
9341  * - \ref SCIP_STAGE_EXITPRESOLVE
9342  * - \ref SCIP_STAGE_PRESOLVED
9343  * - \ref SCIP_STAGE_INITSOLVE
9344  * - \ref SCIP_STAGE_SOLVING
9345  * - \ref SCIP_STAGE_SOLVED
9346  */
9348  SCIP* scip, /**< SCIP data structure */
9349  SCIP_VAR* var, /**< problem variable */
9350  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9351  )
9352 {
9353  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferences", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9354 
9355  assert( var->scip == scip );
9356 
9357  return SCIPvarGetAvgInferences(var, scip->stat, dir);
9358 }
9359 
9360 /** returns the average number of inferences found after branching on the variable in given direction in the current run;
9361  * if branching on the variable in the given direction was yet evaluated, the average number of inferences
9362  * over all variables for branching in the given direction is returned
9363  *
9364  * @return the average number of inferences found after branching on the variable in given direction in the current run
9365  *
9366  * @pre This method can be called if @p scip is in one of the following stages:
9367  * - \ref SCIP_STAGE_INITPRESOLVE
9368  * - \ref SCIP_STAGE_PRESOLVING
9369  * - \ref SCIP_STAGE_EXITPRESOLVE
9370  * - \ref SCIP_STAGE_PRESOLVED
9371  * - \ref SCIP_STAGE_INITSOLVE
9372  * - \ref SCIP_STAGE_SOLVING
9373  * - \ref SCIP_STAGE_SOLVED
9374  */
9376  SCIP* scip, /**< SCIP data structure */
9377  SCIP_VAR* var, /**< problem variable */
9378  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9379  )
9380 {
9381  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferencesCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9382 
9383  assert( var->scip == scip );
9384 
9385  return SCIPvarGetAvgInferencesCurrentRun(var, scip->stat, dir);
9386 }
9387 
9388 /** returns the variable's average inference score value
9389  *
9390  * @return the variable's average inference score value
9391  *
9392  * @pre This method can be called if @p scip is in one of the following stages:
9393  * - \ref SCIP_STAGE_INITPRESOLVE
9394  * - \ref SCIP_STAGE_PRESOLVING
9395  * - \ref SCIP_STAGE_EXITPRESOLVE
9396  * - \ref SCIP_STAGE_PRESOLVED
9397  * - \ref SCIP_STAGE_INITSOLVE
9398  * - \ref SCIP_STAGE_SOLVING
9399  * - \ref SCIP_STAGE_SOLVED
9400  */
9402  SCIP* scip, /**< SCIP data structure */
9403  SCIP_VAR* var /**< problem variable */
9404  )
9405 {
9406  SCIP_Real inferdown;
9407  SCIP_Real inferup;
9408 
9409  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9410 
9411  assert( var->scip == scip );
9412 
9413  inferdown = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9414  inferup = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9415 
9416  return SCIPbranchGetScore(scip->set, var, inferdown, inferup);
9417 }
9418 
9419 /** returns the variable's average inference score value only using inferences of the current run
9420  *
9421  * @return the variable's average inference score value only using inferences of the current run
9422  *
9423  * @pre This method can be called if @p scip is in one of the following stages:
9424  * - \ref SCIP_STAGE_INITPRESOLVE
9425  * - \ref SCIP_STAGE_PRESOLVING
9426  * - \ref SCIP_STAGE_EXITPRESOLVE
9427  * - \ref SCIP_STAGE_PRESOLVED
9428  * - \ref SCIP_STAGE_INITSOLVE
9429  * - \ref SCIP_STAGE_SOLVING
9430  * - \ref SCIP_STAGE_SOLVED
9431  */
9433  SCIP* scip, /**< SCIP data structure */
9434  SCIP_VAR* var /**< problem variable */
9435  )
9436 {
9437  SCIP_Real inferdown;
9438  SCIP_Real inferup;
9439 
9440  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9441 
9442  assert( var->scip == scip );
9443 
9446 
9447  return SCIPbranchGetScore(scip->set, var, inferdown, inferup);
9448 }
9449 
9450 /** initializes the upwards and downwards pseudocosts, conflict scores, conflict lengths, inference scores, cutoff scores
9451  * of a variable to the given values
9452  *
9453  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9454  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9455  *
9456  * @pre This method can be called if @p scip is in one of the following stages:
9457  * - \ref SCIP_STAGE_TRANSFORMED
9458  * - \ref SCIP_STAGE_INITPRESOLVE
9459  * - \ref SCIP_STAGE_PRESOLVING
9460  * - \ref SCIP_STAGE_EXITPRESOLVE
9461  * - \ref SCIP_STAGE_PRESOLVED
9462  * - \ref SCIP_STAGE_INITSOLVE
9463  * - \ref SCIP_STAGE_SOLVING
9464  */
9466  SCIP* scip, /**< SCIP data structure */
9467  SCIP_VAR* var, /**< variable which should be initialized */
9468  SCIP_Real downpscost, /**< value to which pseudocosts for downwards branching should be initialized */
9469  SCIP_Real uppscost, /**< value to which pseudocosts for upwards branching should be initialized */
9470  SCIP_Real downvsids, /**< value to which VSIDS score for downwards branching should be initialized */
9471  SCIP_Real upvsids, /**< value to which VSIDS score for upwards branching should be initialized */
9472  SCIP_Real downconflen, /**< value to which conflict length score for downwards branching should be initialized */
9473  SCIP_Real upconflen, /**< value to which conflict length score for upwards branching should be initialized */
9474  SCIP_Real downinfer, /**< value to which inference counter for downwards branching should be initialized */
9475  SCIP_Real upinfer, /**< value to which inference counter for upwards branching should be initialized */
9476  SCIP_Real downcutoff, /**< value to which cutoff counter for downwards branching should be initialized */
9477  SCIP_Real upcutoff /**< value to which cutoff counter for upwards branching should be initialized */
9478  )
9479 {
9480  SCIP_CALL( SCIPcheckStage(scip, "SCIPinitVarBranchStats", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
9481 
9482  assert(downpscost >= 0.0 && uppscost >= 0.0);
9483  assert(downvsids >= 0.0 && upvsids >= 0.0);
9484  assert(downconflen >= 0.0 && upconflen >= 0.0);
9485  assert(downinfer >= 0.0 && upinfer >= 0.0);
9486  assert(downcutoff >= 0.0 && upcutoff >= 0.0);
9487 
9488  if( !SCIPisFeasZero(scip, downpscost) || !SCIPisFeasZero(scip, downvsids)
9489  || !SCIPisFeasZero(scip, downinfer) || !SCIPisFeasZero(scip, downcutoff) )
9490  {
9492  SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, -1.0, downpscost, 1.0) );
9494  SCIP_CALL( SCIPvarIncVSIDS(var, NULL, scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, SCIP_UNKNOWN, downvsids) );
9496  }
9497 
9498  if( !SCIPisFeasZero(scip, downconflen) )
9499  {
9501  }
9502 
9503  if( !SCIPisFeasZero(scip, uppscost) || !SCIPisFeasZero(scip, upvsids)
9504  || !SCIPisFeasZero(scip, upinfer) || !SCIPisFeasZero(scip, upcutoff) )
9505  {
9507  SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, 1.0, uppscost, 1.0) );
9509  SCIP_CALL( SCIPvarIncVSIDS(var, NULL, scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, SCIP_UNKNOWN, upvsids) );
9511  }
9512 
9513  if( !SCIPisFeasZero(scip, upconflen) )
9514  {
9516  }
9517 
9518  return SCIP_OKAY;
9519 }
9520 
9521 /** initializes the upwards and downwards conflict scores, conflict lengths, inference scores, cutoff scores of a
9522  * variable w.r.t. a value by the given values (SCIP_VALUEHISTORY)
9523  *
9524  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9525  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9526  *
9527  * @pre This method can be called if @p scip is in one of the following stages:
9528  * - \ref SCIP_STAGE_TRANSFORMED
9529  * - \ref SCIP_STAGE_INITPRESOLVE
9530  * - \ref SCIP_STAGE_PRESOLVING
9531  * - \ref SCIP_STAGE_EXITPRESOLVE
9532  * - \ref SCIP_STAGE_PRESOLVED
9533  * - \ref SCIP_STAGE_INITSOLVE
9534  * - \ref SCIP_STAGE_SOLVING
9535  */
9537  SCIP* scip, /**< SCIP data structure */
9538  SCIP_VAR* var, /**< variable which should be initialized */
9539  SCIP_Real value, /**< domain value, or SCIP_UNKNOWN */
9540  SCIP_Real downvsids, /**< value to which VSIDS score for downwards branching should be initialized */
9541  SCIP_Real upvsids, /**< value to which VSIDS score for upwards branching should be initialized */
9542  SCIP_Real downconflen, /**< value to which conflict length score for downwards branching should be initialized */
9543  SCIP_Real upconflen, /**< value to which conflict length score for upwards branching should be initialized */
9544  SCIP_Real downinfer, /**< value to which inference counter for downwards branching should be initialized */
9545  SCIP_Real upinfer, /**< value to which inference counter for upwards branching should be initialized */
9546  SCIP_Real downcutoff, /**< value to which cutoff counter for downwards branching should be initialized */
9547  SCIP_Real upcutoff /**< value to which cutoff counter for upwards branching should be initialized */
9548  )
9549 {
9550  SCIP_CALL( SCIPcheckStage(scip, "SCIPinitVarValueBranchStats", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
9551 
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, downvsids) || !SCIPisFeasZero(scip, downinfer) || !SCIPisFeasZero(scip, downcutoff) )
9558  {
9559  SCIP_CALL( SCIPvarIncNBranchings(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, 1) );
9560  SCIP_CALL( SCIPvarIncInferenceSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downinfer) );
9561  SCIP_CALL( SCIPvarIncVSIDS(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downvsids) );
9562  SCIP_CALL( SCIPvarIncCutoffSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downcutoff) );
9563  }
9564 
9565  if( !SCIPisFeasZero(scip, downconflen) )
9566  {
9567  SCIP_CALL( SCIPvarIncNActiveConflicts(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downconflen) );
9568  }
9569 
9570  if( !SCIPisFeasZero(scip, upvsids) || !SCIPisFeasZero(scip, upinfer) || !SCIPisFeasZero(scip, upcutoff) )
9571  {
9572  SCIP_CALL( SCIPvarIncNBranchings(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, 1) );
9573  SCIP_CALL( SCIPvarIncInferenceSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upinfer) );
9574  SCIP_CALL( SCIPvarIncVSIDS(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upvsids) );
9575  SCIP_CALL( SCIPvarIncCutoffSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upcutoff) );
9576  }
9577 
9578  if( !SCIPisFeasZero(scip, upconflen) )
9579  {
9580  SCIP_CALL( SCIPvarIncNActiveConflicts(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upconflen) );
9581  }
9582 
9583  return SCIP_OKAY;
9584 }
9585 
9586 /** returns the average number of cutoffs found after branching on the variable in given direction;
9587  * if branching on the variable in the given direction was yet evaluated, the average number of cutoffs
9588  * over all variables for branching in the given direction is returned
9589  *
9590  * @return the average number of cutoffs found after branching on the variable in given direction
9591  *
9592  * @pre This method can be called if @p scip is in one of the following stages:
9593  * - \ref SCIP_STAGE_INITPRESOLVE
9594  * - \ref SCIP_STAGE_PRESOLVING
9595  * - \ref SCIP_STAGE_EXITPRESOLVE
9596  * - \ref SCIP_STAGE_PRESOLVED
9597  * - \ref SCIP_STAGE_INITSOLVE
9598  * - \ref SCIP_STAGE_SOLVING
9599  * - \ref SCIP_STAGE_SOLVED
9600  */
9602  SCIP* scip, /**< SCIP data structure */
9603  SCIP_VAR* var, /**< problem variable */
9604  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9605  )
9606 {
9607  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffs", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9608 
9609  assert( var->scip == scip );
9610 
9611  return SCIPvarGetAvgCutoffs(var, scip->stat, dir);
9612 }
9613 
9614 /** returns the average number of cutoffs found after branching on the variable in given direction in the current run;
9615  * if branching on the variable in the given direction was yet evaluated, the average number of cutoffs
9616  * over all variables for branching in the given direction is returned
9617  *
9618  * @return the average number of cutoffs found after branching on the variable in given direction in the current run
9619  *
9620  * @pre This method can be called if @p scip is in one of the following stages:
9621  * - \ref SCIP_STAGE_INITPRESOLVE
9622  * - \ref SCIP_STAGE_PRESOLVING
9623  * - \ref SCIP_STAGE_EXITPRESOLVE
9624  * - \ref SCIP_STAGE_PRESOLVED
9625  * - \ref SCIP_STAGE_INITSOLVE
9626  * - \ref SCIP_STAGE_SOLVING
9627  * - \ref SCIP_STAGE_SOLVED
9628  */
9630  SCIP* scip, /**< SCIP data structure */
9631  SCIP_VAR* var, /**< problem variable */
9632  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9633  )
9634 {
9635  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffsCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9636 
9637  assert( var->scip == scip );
9638 
9639  return SCIPvarGetAvgCutoffsCurrentRun(var, scip->stat, dir);
9640 }
9641 
9642 /** returns the variable's average cutoff score value
9643  *
9644  * @return the variable's average cutoff score value
9645  *
9646  * @pre This method can be called if @p scip is in one of the following stages:
9647  * - \ref SCIP_STAGE_INITPRESOLVE
9648  * - \ref SCIP_STAGE_PRESOLVING
9649  * - \ref SCIP_STAGE_EXITPRESOLVE
9650  * - \ref SCIP_STAGE_PRESOLVED
9651  * - \ref SCIP_STAGE_INITSOLVE
9652  * - \ref SCIP_STAGE_SOLVING
9653  * - \ref SCIP_STAGE_SOLVED
9654  */
9656  SCIP* scip, /**< SCIP data structure */
9657  SCIP_VAR* var /**< problem variable */
9658  )
9659 {
9660  SCIP_Real cutoffdown;
9661  SCIP_Real cutoffup;
9662 
9663  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9664 
9665  assert( var->scip == scip );
9666 
9667  cutoffdown = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9668  cutoffup = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9669 
9670  return SCIPbranchGetScore(scip->set, var, cutoffdown, cutoffup);
9671 }
9672 
9673 /** returns the variable's average cutoff score value, only using cutoffs of the current run
9674  *
9675  * @return the variable's average cutoff score value, only using cutoffs of the current run
9676  *
9677  * @pre This method can be called if @p scip is in one of the following stages:
9678  * - \ref SCIP_STAGE_INITPRESOLVE
9679  * - \ref SCIP_STAGE_PRESOLVING
9680  * - \ref SCIP_STAGE_EXITPRESOLVE
9681  * - \ref SCIP_STAGE_PRESOLVED
9682  * - \ref SCIP_STAGE_INITSOLVE
9683  * - \ref SCIP_STAGE_SOLVING
9684  * - \ref SCIP_STAGE_SOLVED
9685  */
9687  SCIP* scip, /**< SCIP data structure */
9688  SCIP_VAR* var /**< problem variable */
9689  )
9690 {
9691  SCIP_Real cutoffdown;
9692  SCIP_Real cutoffup;
9693 
9694  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9695 
9696  assert( var->scip == scip );
9697 
9700 
9701  return SCIPbranchGetScore(scip->set, var, cutoffdown, cutoffup);
9702 }
9703 
9704 /** returns the variable's average inference/cutoff score value, weighting the cutoffs of the variable with the given
9705  * factor
9706  *
9707  * @return the variable's average inference/cutoff score value
9708  *
9709  * @pre This method can be called if @p scip is in one of the following stages:
9710  * - \ref SCIP_STAGE_INITPRESOLVE
9711  * - \ref SCIP_STAGE_PRESOLVING
9712  * - \ref SCIP_STAGE_EXITPRESOLVE
9713  * - \ref SCIP_STAGE_PRESOLVED
9714  * - \ref SCIP_STAGE_INITSOLVE
9715  * - \ref SCIP_STAGE_SOLVING
9716  * - \ref SCIP_STAGE_SOLVED
9717  */
9719  SCIP* scip, /**< SCIP data structure */
9720  SCIP_VAR* var, /**< problem variable */
9721  SCIP_Real cutoffweight /**< factor to weigh average number of cutoffs in branching score */
9722  )
9723 {
9724  SCIP_Real avginferdown;
9725  SCIP_Real avginferup;
9726  SCIP_Real avginfer;
9727  SCIP_Real inferdown;
9728  SCIP_Real inferup;
9729  SCIP_Real cutoffdown;
9730  SCIP_Real cutoffup;
9731 
9732  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceCutoffScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9733 
9734  assert( var->scip == scip );
9735 
9738  avginfer = (avginferdown + avginferup)/2.0;
9739  inferdown = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9740  inferup = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9741  cutoffdown = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9742  cutoffup = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9743 
9744  return SCIPbranchGetScore(scip->set, var,
9745  inferdown + cutoffweight * avginfer * cutoffdown, inferup + cutoffweight * avginfer * cutoffup);
9746 }
9747 
9748 /** returns the variable's average inference/cutoff score value, weighting the cutoffs of the variable with the given
9749  * factor, only using inferences and cutoffs of the current run
9750  *
9751  * @return the variable's average inference/cutoff score value, only using inferences and cutoffs of the current run
9752  *
9753  * @pre This method can be called if @p scip is in one of the following stages:
9754  * - \ref SCIP_STAGE_INITPRESOLVE
9755  * - \ref SCIP_STAGE_PRESOLVING
9756  * - \ref SCIP_STAGE_EXITPRESOLVE
9757  * - \ref SCIP_STAGE_PRESOLVED
9758  * - \ref SCIP_STAGE_INITSOLVE
9759  * - \ref SCIP_STAGE_SOLVING
9760  * - \ref SCIP_STAGE_SOLVED
9761  */
9763  SCIP* scip, /**< SCIP data structure */
9764  SCIP_VAR* var, /**< problem variable */
9765  SCIP_Real cutoffweight /**< factor to weigh average number of cutoffs in branching score */
9766  )
9767 {
9768  SCIP_Real avginferdown;
9769  SCIP_Real avginferup;
9770  SCIP_Real avginfer;
9771  SCIP_Real inferdown;
9772  SCIP_Real inferup;
9773  SCIP_Real cutoffdown;
9774  SCIP_Real cutoffup;
9775 
9776  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceCutoffScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9777 
9778  assert( var->scip == scip );
9779 
9782  avginfer = (avginferdown + avginferup)/2.0;
9787 
9788  return SCIPbranchGetScore(scip->set, var,
9789  inferdown + cutoffweight * avginfer * cutoffdown, inferup + cutoffweight * avginfer * cutoffup);
9790 }
9791 
9792 /** outputs variable information to file stream via the message system
9793  *
9794  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9795  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9796  *
9797  * @pre This method can be called if @p scip is in one of the following stages:
9798  * - \ref SCIP_STAGE_PROBLEM
9799  * - \ref SCIP_STAGE_TRANSFORMING
9800  * - \ref SCIP_STAGE_TRANSFORMED
9801  * - \ref SCIP_STAGE_INITPRESOLVE
9802  * - \ref SCIP_STAGE_PRESOLVING
9803  * - \ref SCIP_STAGE_EXITPRESOLVE
9804  * - \ref SCIP_STAGE_PRESOLVED
9805  * - \ref SCIP_STAGE_INITSOLVE
9806  * - \ref SCIP_STAGE_SOLVING
9807  * - \ref SCIP_STAGE_SOLVED
9808  * - \ref SCIP_STAGE_EXITSOLVE
9809  * - \ref SCIP_STAGE_FREETRANS
9810  *
9811  * @note If the message handler is set to a NULL pointer nothing will be printed
9812  */
9814  SCIP* scip, /**< SCIP data structure */
9815  SCIP_VAR* var, /**< problem variable */
9816  FILE* file /**< output file (or NULL for standard output) */
9817  )
9818 {
9819  SCIP_CALL( SCIPcheckStage(scip, "SCIPprintVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
9820 
9821  SCIP_CALL( SCIPvarPrint(var, scip->set, scip->messagehdlr, file) );
9822 
9823  return SCIP_OKAY;
9824 }
SCIP_STAT * stat
Definition: struct_scip.h:70
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
SCIP_RETCODE SCIPcalcCliquePartition(SCIP *const scip, SCIP_VAR **const vars, int const nvars, int *const cliquepartition, int *const ncliques)
Definition: scip_var.c:7230
SCIP_Real SCIPgetVarPseudocostVariance(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun)
Definition: scip_var.c:8904
SCIP_Real SCIPgetVarPseudocostCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:8824
SCIP_Real sbup
Definition: struct_lp.h:145
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:4696
SCIP_Real SCIPvarGetAvgConflictlengthCurrentRun(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:15169
SCIP_Bool SCIPsolveIsStopped(SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool checknodelimits)
Definition: solve.c:93
SCIP_Real SCIPgetVarAvgInferenceScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9432
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip_sol.c:977
SCIP_Longint nsbdivinglps
Definition: struct_stat.h:197
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5987
SCIP_EXPORT SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition: var.c:17159
SCIP_EXPORT int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition: var.c:3325
SCIP_Real SCIPgetVarAvgCutoffScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9655
SCIP_RETCODE SCIProundSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
Definition: scip_sol.c:2447
SCIP_Longint SCIPcolGetStrongbranchNode(SCIP_COL *col)
Definition: lp.c:17037
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:6863
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:4288
SCIP_RETCODE SCIPchgVarLbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4840
SCIP_Real SCIPgetVarAvgInferenceCutoffScore(SCIP *scip, SCIP_VAR *var, SCIP_Real cutoffweight)
Definition: scip_var.c:9718
void SCIPvarGetClosestVlb(SCIP_VAR *var, SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real *closestvlb, int *closestvlbidx)
Definition: var.c:13889
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:15296
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
SCIP_VAR ** SCIPcliqueGetVars(SCIP_CLIQUE *clique)
Definition: implics.c:3351
SCIP_EXPORT SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:17172
SCIP_RETCODE SCIPmarkRelaxSolValid(SCIP *scip, SCIP_RELAX *relax, SCIP_Bool includeslp)
Definition: scip_var.c:2554
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6045
int SCIPcliquetableGetVarComponentIdx(SCIP_CLIQUETABLE *cliquetable, SCIP_VAR *var)
Definition: implics.c:2322
SCIP_Bool SCIPhaveVarsCommonClique(SCIP *scip, SCIP_VAR *var1, SCIP_Bool value1, SCIP_VAR *var2, SCIP_Bool value2, SCIP_Bool regardimplics)
Definition: scip_var.c:7633
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:14816
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:10274
void SCIPvarUpdateBestRootSol(SCIP_VAR *var, SCIP_SET *set, SCIP_Real rootsol, SCIP_Real rootredcost, SCIP_Real rootlpobjval)
Definition: var.c:13049
SCIP_STATUS status
Definition: struct_stat.h:174
SCIP_RETCODE SCIPchgVarBranchDirection(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR branchdirection)
Definition: scip_var.c:8059
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition: lp.c:17684
SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:1989
public methods for branch and bound tree
SCIP_Real SCIPrelaxationGetSolObj(SCIP_RELAXATION *relaxation)
Definition: relax.c:824
internal methods for branch and bound tree
SCIP_RETCODE SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
Definition: scip_var.c:221
SCIP_CONFLICT * conflict
Definition: struct_scip.h:87
SCIP_RETCODE SCIPcleanupCliques(SCIP *scip, SCIP_Bool *infeasible)
Definition: scip_var.c:7506
SCIP_Longint SCIPgetVarStrongbranchLPAge(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:4191
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
void SCIPfreeParseVarsPolynomialData(SCIP *scip, SCIP_VAR ****monomialvars, SCIP_Real ***monomialexps, SCIP_Real **monomialcoefs, int **monomialnvars, int nmonomials)
Definition: scip_var.c:1155
SCIP_Real SCIPvarGetAvgCutoffsCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:16077
SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5177
SCIP_Real SCIPgetVarPseudocost(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:8796
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
Definition: scip_probing.c:156
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:6635
SCIP_Real SCIPcomputeVarLbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6479
SCIP_Bool SCIPallowWeakDualReds(SCIP *scip)
Definition: scip_var.c:8617
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:5869
void SCIPlpEndStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16230
public methods for memory management
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6385
#define SCIPsetDuplicateBufferArray(set, ptr, source, num)
Definition: set.h:1687
#define SCIP_DECL_VARTRANS(x)
Definition: type_var.h:138
SCIP_Bool SCIPisStrongbranchDownFirst(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:2652
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:6994
SCIP_Bool SCIPvarDoNotMultaggr(SCIP_VAR *var)
Definition: var.c:5729
SCIP_Real SCIPgetVarRedcost(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1861
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:2046
public methods for implications, variable bounds, and cliques
SCIP_Real SCIPgetVarAvgInferences(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9347
SCIP_Real SCIPvarGetPseudocostCountCurrentRun(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:14383
methods for implications, variable bounds, and cliques
SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
Definition: scip_var.c:4256
SCIP_RETCODE SCIPprintVar(SCIP *scip, SCIP_VAR *var, FILE *file)
Definition: scip_var.c:9813
SCIP_Real SCIPgetRelaxSolObj(SCIP *scip)
Definition: scip_var.c:2629
SCIP_Bool SCIPvarIsPscostRelerrorReliable(SCIP_VAR *var, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real threshold, SCIP_CONFIDENCELEVEL clevel)
Definition: var.c:14549
#define SCIP_MAXSTRLEN
Definition: def.h:279
SCIP_Bool conf_usesb
Definition: struct_set.h:212
SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition: scip_var.c:1477
SCIP_RETCODE SCIPgetNegatedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **negvars)
Definition: scip_var.c:1557
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:123
internal methods for clocks and timing issues
#define SCIP_VARTYPE_INTEGER_CHAR
Definition: def.h:135
SCIP_RETCODE SCIPvarChgLbOriginal(SCIP_VAR *var, SCIP_SET *set, SCIP_Real newbound)
Definition: var.c:6376
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:5697
SCIP_EXPORT SCIP_Real SCIPvarGetBranchFactor(SCIP_VAR *var)
Definition: var.c:17827
int SCIPtreeGetProbingDepth(SCIP_TREE *tree)
Definition: tree.c:8426
SCIP_RETCODE SCIPgetBinvarRepresentative(SCIP *scip, SCIP_VAR *var, SCIP_VAR **repvar, SCIP_Bool *negated)
Definition: scip_var.c:1594
SCIP_Bool presol_donotaggr
Definition: struct_set.h:436
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_RETCODE SCIPvarChgLbLazy(SCIP_VAR *var, SCIP_SET *set, SCIP_Real lazylb)
Definition: var.c:7278
#define SCIP_CALL_FINALLY(x, y)
Definition: def.h:412
SCIP_EXPORT SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
Definition: var.c:18041
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1211
SCIP_Real constant
Definition: struct_var.h:184
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1353
SCIP_EVENTQUEUE * eventqueue
Definition: struct_scip.h:80
SCIP_Longint nsbtimesiterlimhit
Definition: struct_stat.h:112
SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5294
SCIP_Real SCIPvarGetMultaggrLbGlobal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8375
SCIP_PRIMAL * primal
Definition: struct_scip.h:85
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 SCIPstatDisableVarHistory(SCIP_STAT *stat)
Definition: stat.c:147
SCIP_RETCODE SCIPvarChgUbOriginal(SCIP_VAR *var, SCIP_SET *set, SCIP_Real newbound)
Definition: var.c:6435
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:2423
interface methods for specific LP solvers
SCIP_Real SCIPgetVarVSIDSCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9137
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_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:5589
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_RETCODE SCIPhashmapInsertInt(SCIP_HASHMAP *hashmap, void *origin, int image)
Definition: misc.c:3132
SCIP_Real SCIPbranchGetScore(SCIP_SET *set, SCIP_VAR *var, SCIP_Real downgain, SCIP_Real upgain)
Definition: branch.c:2190
SCIP_RETCODE SCIPvarMarkDoNotMultaggr(SCIP_VAR *var)
Definition: var.c:5952
SCIP_EXPORT SCIP_Real SCIPvarGetPseudoSol(SCIP_VAR *var)
Definition: var.c:18119
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition: scip_tree.c:81
SCIP_EXPORT SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:17197
SCIP_BRANCHCAND * branchcand
Definition: struct_scip.h:81
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:1986
#define NLOCKTYPES
Definition: type_var.h:81
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:351
SCIP_EXPORT SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
Definition: lpi_clp.cpp:3905
SCIP_Real SCIPgetVarAvgCutoffsCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9629
#define FALSE
Definition: def.h:73
void SCIPstrCopySection(const char *str, char startchar, char endchar, char *token, int size, char **endptr)
Definition: misc.c:10735
SCIP_Bool misc_allowweakdualreds
Definition: struct_set.h:384
SCIP_Real SCIPgetVarAvgConflictlength(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9293
SCIP_Bool SCIPsetIsFeasIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6528
struct SCIP_VarData SCIP_VARDATA
Definition: type_var.h:107
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:5984
SCIP_EXPORT SCIP_Real SCIPboundchgGetNewbound(SCIP_BOUNDCHG *boundchg)
Definition: var.c:16914
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:281
SCIP_RETCODE SCIPvarTransform(SCIP_VAR *origvar, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_OBJSENSE objsense, SCIP_VAR **transvar)
Definition: var.c:3357
SCIP_RETCODE SCIPaddVarBranchPriority(SCIP *scip, SCIP_VAR *var, int addpriority)
Definition: scip_var.c:8028
SCIP_EXPORT int SCIPdomchgGetNBoundchgs(SCIP_DOMCHG *domchg)
Definition: var.c:16964
SCIP_Real constant
Definition: struct_var.h:194
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6099
SCIP_STAGE stage
Definition: struct_set.h:63
SCIP_EXPORT SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17182
#define TRUE
Definition: def.h:72
SCIP_Real SCIPvarGetAvgConflictlength(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:15125
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
void SCIPlpStartStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16217
enum SCIP_Varstatus SCIP_VARSTATUS
Definition: type_var.h:48
SCIP_RETCODE SCIPparseVarName(SCIP *scip, const char *str, SCIP_VAR **var, char **endptr)
Definition: scip_var.c:524
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1685
int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
Definition: tree.c:8398
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:2003
SCIP_Bool branch_checksbsol
Definition: struct_set.h:183
SCIP_Bool branch_divingpscost
Definition: struct_set.h:180
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:10721
#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:2891
SCIP_Real SCIPgetVarAvgInferenceCutoffScoreCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real cutoffweight)
Definition: scip_var.c:9762
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:7114
SCIP_Bool SCIPpscostThresholdProbabilityTest(SCIP *scip, SCIP_VAR *var, SCIP_Real frac, SCIP_Real threshold, SCIP_BRANCHDIR dir, SCIP_CONFIDENCELEVEL clevel)
Definition: scip_var.c:8987
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool presol_donotmultaggr
Definition: struct_set.h:435
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:7137
SCIP_EXPORT SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17340
public methods for problem variables
SCIP_Real SCIPadjustedVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real ub)
Definition: scip_var.c:4639
SCIP_Real SCIPvarGetAvgInferences(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:15832
SCIP_Bool diving
Definition: struct_lp.h:370
SCIP_RETCODE SCIPvarsGetActiveVars(SCIP_SET *set, SCIP_VAR **vars, int *nvars, int varssize, int *requiredsize)
Definition: var.c:11777
SCIP_EXPORT SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17136
SCIP_Real SCIPgetVarConflictlengthScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9231
SCIP_Real SCIPgetVarPseudocostCountCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:8878
SCIP_RETCODE SCIPaddVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real addobj)
Definition: scip_var.c:4556
void SCIPrelaxationSetSolValid(SCIP_RELAXATION *relaxation, SCIP_Bool isvalid, SCIP_Bool includeslp)
Definition: relax.c:780
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip_mem.h:119
SCIP_Real SCIPgetVarPseudocostScore(SCIP *scip, SCIP_VAR *var, SCIP_Real solval)
Definition: scip_var.c:9031
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:6988
SCIP_RETCODE SCIPtryStrongbranchLPSol(SCIP *scip, SCIP_Bool *foundsol, SCIP_Bool *cutoff)
Definition: scip_var.c:4076
SCIP_PROB * transprob
Definition: struct_scip.h:89
SCIP_Bool SCIPrelaxationIsSolValid(SCIP_RELAXATION *relaxation)
Definition: relax.c:793
SCIP_Real constant
Definition: struct_var.h:177
SCIP_Bool conf_enable
Definition: struct_set.h:203
SCIP_Real SCIPcalculatePscostConfidenceBound(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun, SCIP_CONFIDENCELEVEL clevel)
Definition: scip_var.c:8926
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 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:5987
#define SCIP_LONGINT_MAX
Definition: def.h:149
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 SCIPchgVarUbLazy(SCIP *scip, SCIP_VAR *var, SCIP_Real lazyub)
Definition: scip_var.c:5143
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:123
SCIP_RETCODE SCIPsetRelaxSolVal(SCIP *scip, SCIP_RELAX *relax, SCIP_VAR *var, SCIP_Real val)
Definition: scip_var.c:2411
SCIP_RETCODE SCIPvarUpdatePseudocost(SCIP_VAR *var, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
Definition: var.c:14144
#define SCIPsetFreeBufferArray(set, ptr)
Definition: set.h:1692
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition: type_lp.h:42
void SCIPvarAdjustLb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *lb)
Definition: var.c:6326
public methods for SCIP variables
SCIP_RETCODE SCIPvarChgBranchDirection(SCIP_VAR *var, SCIP_BRANCHDIR branchdirection)
Definition: var.c:11590
SCIP_Bool branch_forceall
Definition: struct_set.h:181
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:1536
#define SCIPdebugMsg
Definition: scip_message.h:69
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Longint SCIPcolGetStrongbranchLPAge(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4728
internal methods for LP management
SCIP_RETCODE SCIPaddVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real addfactor)
Definition: scip_var.c:7923
SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:4347
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip_lp.c:159
SCIP_PROB * origprob
Definition: struct_scip.h:71
SCIP_RETCODE SCIPaddVarLocks(SCIP *scip, SCIP_VAR *var, int nlocksdown, int nlocksup)
Definition: scip_var.c:4314
SCIP_Bool SCIPconsIsLockedTypeNeg(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
Definition: cons.c:8458
SCIP_RETCODE SCIPgetVarClosestVub(SCIP *scip, SCIP_VAR *var, SCIP_SOL *sol, SCIP_Real *closestvub, int *closestvubidx)
Definition: scip_var.c:6606
SCIP_Bool SCIPisTransformed(SCIP *scip)
Definition: scip_general.c:559
SCIP_VAR ** vars
Definition: struct_var.h:186
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
internal methods for branching and inference history
SCIP_Real SCIPgetVarVSIDS(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9105
public methods for numerical tolerances
void SCIPgmlWriteOpening(FILE *file, SCIP_Bool directed)
Definition: misc.c:673
SCIP_Bool reopt_enable
Definition: struct_set.h:485
void SCIPgmlWriteArc(FILE *file, unsigned int source, unsigned int target, const char *label, const char *color)
Definition: misc.c:629
SCIP_Real SCIPgetVarPseudocostScoreCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real solval)
Definition: scip_var.c:9069
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:6081
public methods for querying solving statistics
SCIP_HISTORY * glbhistorycrun
Definition: struct_stat.h:170
int SCIPcliquetableGetNCliquesCreated(SCIP_CLIQUETABLE *cliquetable)
Definition: implics.c:3487
SCIP_Bool SCIPdoNotMultaggr(SCIP *scip)
Definition: scip_var.c:8549
SCIP_Bool SCIPisLPRelax(SCIP *scip)
Definition: scip_lp.c:216
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPgetVarPseudocostValCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta)
Definition: scip_var.c:8770
SCIP_RETCODE SCIPgetVarClosestVlb(SCIP *scip, SCIP_VAR *var, SCIP_SOL *sol, SCIP_Real *closestvlb, int *closestvlbidx)
Definition: scip_var.c:6583
SCIP_Real SCIPvarGetVSIDSCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:15693
int SCIPhashmapGetImageInt(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3221
public methods for the branch-and-bound tree
enum SCIP_BranchDir SCIP_BRANCHDIR
Definition: type_history.h:39
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip_var.c:1524
SCIP_Real SCIPgetVarAvgCutoffs(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9601
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:7779
SCIP_RETCODE SCIPmarkRelaxSolInvalid(SCIP *scip)
Definition: scip_var.c:2579
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3363
int SCIPcliquetableGetNCliques(SCIP_CLIQUETABLE *cliquetable)
Definition: implics.c:3477
SCIP_CLOCK * strongpropclock
Definition: struct_stat.h:167
SCIP_RETCODE SCIPmarkDoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8643
SCIP_MEM * mem
Definition: struct_scip.h:62
public methods for managing constraints
SCIP_Real SCIPgetVarConflictScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9169
SCIP_Bool misc_allowstrongdualreds
Definition: struct_set.h:383
SCIP_Real SCIPvarGetImplRedcost(SCIP_VAR *var, SCIP_SET *set, SCIP_Bool varfixing, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp)
Definition: var.c:13236
SCIP_EXPORT SCIP_Bool SCIPboundchgIsRedundant(SCIP_BOUNDCHG *boundchg)
Definition: var.c:16954
SCIP_Bool SCIPtreeProbing(SCIP_TREE *tree)
Definition: tree.c:8280
SCIP_EXPORT SCIP_BOUNDCHG * SCIPdomchgGetBoundchg(SCIP_DOMCHG *domchg, int pos)
Definition: var.c:16972
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:11460
SCIP_Real SCIPvarGetPseudocost(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real solvaldelta)
Definition: var.c:14242
SCIP_RETCODE SCIPprobRemoveVarName(SCIP_PROB *prob, SCIP_VAR *var)
Definition: prob.c:913
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_AGGREGATE aggregate
Definition: struct_var.h:222
SCIP_EXPORT SCIP_Real SCIPvarGetSol(SCIP_VAR *var, SCIP_Bool getlpval)
Definition: var.c:13026
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_EXPORT SCIP_DOMCHG * SCIPnodeGetDomchg(SCIP_NODE *node)
Definition: tree.c:7533
SCIP_EXPORT const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17017
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:9536
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_RETCODE SCIPvarChgUbLazy(SCIP_VAR *var, SCIP_SET *set, SCIP_Real lazyub)
Definition: var.c:7301
SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4670
enum SCIP_LockType SCIP_LOCKTYPE
Definition: type_var.h:87
SCIP_EXPORT SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:17208
SCIP_Bool SCIPallColsInLP(SCIP *scip)
Definition: scip_lp.c:619
internal methods for storing and manipulating the main problem
#define SCIPerrorMessage
Definition: pub_message.h:55
SCIP_EXPORT SCIP_RETCODE SCIPvarsGetProbvarBinary(SCIP_VAR ***vars, SCIP_Bool **negatedarr, int nvars)
Definition: var.c:12049
SCIP_Bool SCIPstrToRealValue(const char *str, SCIP_Real *value, char **endptr)
Definition: misc.c:10705
SCIP_EVENTFILTER * eventfilter
Definition: struct_scip.h:79
SCIP_Bool SCIPlpIsDualReliable(SCIP_LP *lp)
Definition: lp.c:17664
void SCIPenableVarHistory(SCIP *scip)
Definition: scip_var.c:8669
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:14692
SCIP_Longint lpcount
Definition: struct_stat.h:178
SCIP_Longint nbestsolsfound
Definition: struct_primal.h:42
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:6074
SCIP_CLIQUE ** SCIPgetCliques(SCIP *scip)
Definition: scip_var.c:7603
SCIP_Bool SCIPrelaxationIsSolZero(SCIP_RELAXATION *relaxation)
Definition: relax.c:770
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPchgVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition: scip_var.c:7954
SCIP_EXPORT int SCIPvarGetBranchPriority(SCIP_VAR *var)
Definition: var.c:17839
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:1941
SCIP_RETCODE SCIPvarRelease(SCIP_VAR **var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: var.c:2786
SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip_var.c:1436
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:2152
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition: scip_mem.h:124
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:14291
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:3067
int SCIPgetProbingDepth(SCIP *scip)
Definition: scip_probing.c:189
SCIP_LPSOLSTAT lastsblpsolstats[2]
Definition: struct_stat.h:176
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:3443
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_clp.cpp:2752
SCIP_OBJSENSE objsense
Definition: struct_prob.h:77
char branch_firstsbchild
Definition: struct_set.h:171
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:8509
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPcomputeVarUbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6500
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip_probing.c:88
SCIP_VAR * transvar
Definition: struct_var.h:170
SCIP_REOPT * reopt
Definition: struct_scip.h:76
SCIP_Real SCIPsetFeasCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6563
SCIP_RETCODE SCIPwriteVarsList(SCIP *scip, FILE *file, SCIP_VAR **vars, int nvars, SCIP_Bool type, char delimiter)
Definition: scip_var.c:283
int SCIPgetNCliques(SCIP *scip)
Definition: scip_var.c:7549
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:13964
SCIP_NEGATE negate
Definition: struct_var.h:224
SCIP_Bool SCIPdoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8559
SCIP_RETCODE SCIPvarSetRelaxSol(SCIP_VAR *var, SCIP_SET *set, SCIP_RELAXATION *relaxation, SCIP_Real solval, SCIP_Bool updateobj)
Definition: var.c:13629
data structures for branch and bound tree
SCIP_HISTORY * glbhistory
Definition: struct_stat.h:169
#define REALABS(x)
Definition: def.h:187
SCIP_Real SCIPgetVarMultaggrLbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6520
SCIP_RETCODE SCIPwriteCliqueGraph(SCIP *scip, const char *fname, SCIP_Bool writenodeweights)
Definition: scip_var.c:7684
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:9810
SCIP_EXPORT SCIP_BDCHGINFO * SCIPvarGetUbchgInfo(SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: var.c:16231
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:14511
#define SCIP_CALL(x)
Definition: def.h:370
SCIP_RETCODE SCIPprobAddVarName(SCIP_PROB *prob, SCIP_VAR *var)
Definition: prob.c:897
SCIP main data structure.
SCIP_Longint nsbbestsolsfound
Definition: struct_stat.h:99
SCIP_Real SCIPgetVarAvgCutoffScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9686
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:15212
SCIP_Bool SCIPsetIsLbBetter(SCIP_SET *set, SCIP_Real newlb, SCIP_Real oldlb, SCIP_Real oldub)
Definition: set.c:6810
SCIP_Real SCIPvarGetPseudocostCount(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:14338
#define SCIPstatAdd(stat, set, field, val)
Definition: stat.h:271
SCIP_RETCODE SCIPgetBinvarRepresentatives(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **repvars, SCIP_Bool *negated)
Definition: scip_var.c:1641
SCIP_RETCODE SCIPbacktrackProbing(SCIP *scip, int probingdepth)
Definition: scip_probing.c:216
internal methods for relaxators
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
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6009
SCIP_RETCODE SCIPupdateVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition: scip_var.c:7995
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:7906
SCIP_EXPORT SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2595
SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13063
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
SCIP_RETCODE SCIPcalcNegatedCliquePartition(SCIP *const scip, SCIP_VAR **const vars, int const nvars, int *const cliquepartition, int *const ncliques)
Definition: scip_var.c:7449
SCIP_EXPORT SCIP_BDCHGINFO * SCIPvarGetLbchgInfo(SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: var.c:16175
SCIP_RETCODE SCIPvarPrint(SCIP_VAR *var, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: var.c:2906
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
SCIP_Bool SCIPconsIsLockedTypePos(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
Definition: cons.c:8446
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition: scip_lp.c:238
SCIP_Real SCIPgetVarMultaggrLbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6550
SCIP_RETCODE SCIPlpStartStrongbranch(SCIP_LP *lp)
Definition: lp.c:4169
SCIP_RETCODE SCIPscaleVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real scale)
Definition: scip_var.c:7895
SCIP_CLIQUETABLE * cliquetable
Definition: struct_scip.h:88
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
SCIP_EXPORT SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:17381
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:9465
internal methods for problem variables
SCIP_RETCODE SCIPvarChgBranchFactor(SCIP_VAR *var, SCIP_SET *set, SCIP_Real branchfactor)
Definition: var.c:11334
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:5160
SCIP_RETCODE SCIPchgVarLbLazy(SCIP *scip, SCIP_VAR *var, SCIP_Real lazylb)
Definition: scip_var.c:5110
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:111
#define SCIP_UNKNOWN
Definition: def.h:184
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:130
SCIP_Real SCIPinfinity(SCIP *scip)
public data structures and miscellaneous methods
unsigned int vartype
Definition: struct_var.h:270
int SCIPcolGetNStrongbranchs(SCIP_COL *col)
Definition: lp.c:17047
SCIP_Bool SCIPcliquetableNeedsComponentUpdate(SCIP_CLIQUETABLE *cliquetable)
Definition: implics.c:3525
SCIP_EXPORT SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
Definition: var.c:17493
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:15380
SCIP_Real SCIPgetVarFarkasCoef(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1951
SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:4432
void SCIPrelaxationSetSolRelax(SCIP_RELAXATION *relaxation, SCIP_RELAX *relax)
Definition: relax.c:865
#define SCIP_Bool
Definition: def.h:70
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:5406
void SCIPvarCapture(SCIP_VAR *var)
Definition: var.c:2774
SCIP_CLOCK * sbsoltime
Definition: struct_stat.h:163
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3014
SCIP_Real ub
Definition: struct_var.h:162
SCIP_RETCODE SCIPtransformVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip_var.c:1346
SCIP_EXPORT SCIP_VAR * SCIPvarGetProbvar(SCIP_VAR *var)
Definition: var.c:11989
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:6430
#define MAXNCLIQUEVARSCOMP
Definition: scip_var.c:7094
SCIP_EXPORT SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17677
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
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:3644
SCIP_MULTAGGR multaggr
Definition: struct_var.h:223
SCIP_RETCODE SCIPpropagateProbing(SCIP *scip, int maxproprounds, SCIP_Bool *cutoff, SCIP_Longint *ndomredsfound)
Definition: scip_probing.c:571
SCIP_Bool branch_roundsbsol
Definition: struct_set.h:184
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:3102
#define MAX(x, y)
Definition: tclique_def.h:83
SCIP_RETCODE SCIPcreateLPSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip_sol.c:362
SCIP_Bool SCIPallowDualReds(SCIP *scip)
Definition: scip_var.c:8575
SCIP_Bool SCIPisVarPscostRelerrorReliable(SCIP *scip, SCIP_VAR *var, SCIP_Real threshold, SCIP_CONFIDENCELEVEL clevel)
Definition: scip_var.c:9006
SCIP_RETCODE SCIPendStrongbranch(SCIP *scip)
Definition: scip_var.c:2741
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 SCIPgetActiveVars(SCIP *scip, SCIP_VAR **vars, int *nvars, int varssize, int *requiredsize)
Definition: scip_var.c:1827
methods for debugging
SCIP_Bool * SCIPcliqueGetValues(SCIP_CLIQUE *clique)
Definition: implics.c:3363
public methods for LP management
SCIP_EXPORT void SCIPsolSetStrongbranching(SCIP_SOL *sol)
Definition: sol.c:2709
SCIP_Real SCIPgetRelaxSolVal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:2600
void SCIPgmlWriteClosing(FILE *file)
Definition: misc.c:689
SCIP_Bool SCIPallowObjProp(SCIP *scip)
Definition: scip_var.c:8603
SCIP_EXPORT int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition: var.c:3312
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:4199
datastructures for block memory pools and memory buffers
SCIP_Real SCIPgetVarAvgConflictlengthCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9319
SCIP_Real SCIPvarGetMultaggrUbGlobal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8441
SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
Definition: prob.c:2275
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
SCIP_RETCODE SCIPvarFlattenAggregationGraph(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: var.c:4309
SCIP_Real SCIPvarGetAvgInferencesCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:15889
SCIP_Bool SCIPtreeHasCurrentNodeLP(SCIP_TREE *tree)
Definition: tree.c:8415
SCIP_Real SCIPcomputeVarLbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6437
SCIP_RETCODE SCIPgetLPI(SCIP *scip, SCIP_LPI **lpi)
Definition: scip_lp.c:931
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
int SCIPgetNCliquesCreated(SCIP *scip)
Definition: scip_var.c:7576
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:126
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition: scip_var.c:8250
SCIP_RETCODE SCIPchgVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4936
int SCIPconflictGetNConflicts(SCIP_CONFLICT *conflict)
Definition: conflict.c:3737
SCIP_RETCODE SCIPclearRelaxSolVals(SCIP *scip, SCIP_RELAX *relax)
Definition: scip_var.c:2361
SCIP_Longint SCIPgetVarStrongbranchNode(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:4157
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:6094
SCIP_Real SCIPvarGetRelaxSol(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:13690
datastructures for problem statistics
int nconflicthdlrs
Definition: struct_set.h:104
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real ub
Definition: struct_lp.h:130
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6407
SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4760
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:2350
SCIP_RETCODE SCIPchgVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real branchfactor)
Definition: scip_var.c:7867
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:6149
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:14952
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:6694
SCIP_EXPORT SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17723
void SCIPrelaxationSetSolObj(SCIP_RELAXATION *relaxation, SCIP_Real obj)
Definition: relax.c:813
#define SCIP_MAXTREEDEPTH
Definition: def.h:306
SCIP * scip
Definition: struct_var.h:278
SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
Definition: scip_prob.c:2679
public methods for the LP relaxation, rows and columns
SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2125
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:4473
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:810
#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:13102
SCIP_Bool SCIPinDive(SCIP *scip)
Definition: scip_lp.c:2715
datastructures for storing and manipulating the main problem
SCIP_EXPORT SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17733
void SCIPrelaxationSetSolZero(SCIP_RELAXATION *relaxation, SCIP_Bool iszero)
Definition: relax.c:759
SCIP_RETCODE SCIPgetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip_sol.c:1390
SCIP_Real SCIPsetFeasFloor(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6552
SCIP_Real SCIPcomputeVarUbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6458
SCIP_Bool misc_exactsolve
Definition: struct_set.h:369
SCIP_RETCODE SCIPchgVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:5023
#define SCIP_VARTYPE_IMPLINT_CHAR
Definition: def.h:136
general public methods
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:5475
BMS_BLKMEM * probmem
Definition: struct_mem.h:40
SCIP_RETCODE SCIPstartStrongbranch(SCIP *scip, SCIP_Bool enablepropagation)
Definition: scip_var.c:2683
public methods for solutions
internal methods for conflict analysis
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:4507
static const SCIP_Real scalars[]
Definition: lp.c:5731
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:5326
internal methods for main solving loop and node processing
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:137
SCIP_RETCODE SCIPchgVarName(SCIP *scip, SCIP_VAR *var, const char *name)
Definition: scip_var.c:1296
SCIP_EXPORT SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17667
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:3814
SCIP_NODE * SCIPtreeGetCurrentNode(SCIP_TREE *tree)
Definition: tree.c:8381
SCIP_Bool SCIPcolIsInLP(SCIP_COL *col)
Definition: lp.c:16979
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 SCIPgetColFarkasCoef(SCIP *scip, SCIP_COL *col)
Definition: scip_lp.c:1126
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:14626
SCIP_SET * set
Definition: struct_scip.h:63
public methods for message output
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition: scip_prob.c:1860
data structures for LP management
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:6895
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10604
SCIP_Real * scalars
Definition: struct_var.h:185
SCIP_RETCODE SCIPchgVarLbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_probing.c:292
datastructures for problem variables
SCIP_Real SCIPgetVarAvgInferencesCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9375
SCIP_EXPORT void SCIPvarMarkDeleteGlobalStructures(SCIP_VAR *var)
Definition: var.c:17274
SCIP_RETCODE SCIPsetRelaxSolVals(SCIP *scip, SCIP_RELAX *relax, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Bool includeslp)
Definition: scip_var.c:2444
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:3048
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1245
SCIP_MESSAGEHDLR * messagehdlr
Definition: struct_scip.h:66
SCIP_Real SCIPgetVarPseudocostVal(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta)
Definition: scip_var.c:8742
SCIP_Real SCIPgetVarSol(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:2304
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::@14 data
#define SCIP_Real
Definition: def.h:163
internal methods for problem statistics
int SCIPgetVarNStrongbranchs(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:4223
SCIP_RETCODE SCIPchgVarUbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_probing.c:336
SCIP_EXPORT SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2372
SCIP_Bool SCIPisRelaxSolValid(SCIP *scip)
Definition: scip_var.c:2534
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
datastructures for collecting primal CIP solutions and primal informations
public methods for message handling
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPvarGetVSIDS(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:18132
#define SCIP_INVALID
Definition: def.h:183
SCIP_Real SCIPgetVarImplRedcost(SCIP *scip, SCIP_VAR *var, SCIP_Bool varfixing)
Definition: scip_var.c:1906
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:2487
SCIP_Real primsol
Definition: struct_lp.h:139
SCIP_RETCODE SCIPtightenVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6322
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
SCIP_Real SCIPgetColRedcost(SCIP *scip, SCIP_COL *col)
Definition: scip_lp.c:1100
#define SCIP_Longint
Definition: def.h:148
SCIP_EXPORT SCIP_Bool SCIPvarsHaveCommonClique(SCIP_VAR *var1, SCIP_Bool value1, SCIP_VAR *var2, SCIP_Bool value2, SCIP_Bool regardimplics)
Definition: var.c:11249
SCIP_RETCODE SCIPwriteVarsLinearsum(SCIP *scip, FILE *file, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Bool type)
Definition: scip_var.c:334
SCIP_Real SCIPvarGetAvgCutoffs(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:16030
SCIP_Real lb
Definition: struct_var.h:161
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6451
SCIP_RETCODE SCIPgetProbvarSum(SCIP *scip, SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: scip_var.c:1791
SCIP_Longint nsbsolsfound
Definition: struct_stat.h:95
SCIP_TREE * tree
Definition: struct_scip.h:86
#define SCIP_VARTYPE_BINARY_CHAR
Definition: def.h:134
SCIP_Real SCIPvarGetMultaggrUbLocal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8309
SCIP_RETCODE SCIPvarChgName(SCIP_VAR *var, BMS_BLKMEM *blkmem, const char *name)
Definition: var.c:2813
SCIP_RELAXATION * relaxation
Definition: struct_scip.h:84
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_DOM glbdom
Definition: struct_var.h:216
SCIP_Real SCIPgetVarBdAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2261
SCIP_Real SCIPhistoryGetAvgInferences(SCIP_HISTORY *history, SCIP_BRANCHDIR dir)
Definition: history.c:649
SCIP_EXPORT SCIP_VAR * SCIPboundchgGetVar(SCIP_BOUNDCHG *boundchg)
Definition: var.c:16924
SCIP_EXPORT int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17360
enum SCIP_Vartype SCIP_VARTYPE
Definition: type_var.h:60
SCIP_EXPORT SCIP_RETCODE SCIPvarGetProbvarBinary(SCIP_VAR **var, SCIP_Bool *negated)
Definition: var.c:12081
SCIP_Real SCIPgetVarConflictlengthScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9262
SCIP_VAR * negatedvar
Definition: struct_var.h:233
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:8957
SCIP_EXPORT SCIP_NODETYPE SCIPnodeGetType(SCIP_NODE *node)
Definition: tree.c:7428
int SCIPcliqueGetNVars(SCIP_CLIQUE *clique)
Definition: implics.c:3341
void SCIPvarAdjustUb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *ub)
Definition: var.c:6343
SCIP_Bool SCIPsetIsUbBetter(SCIP_SET *set, SCIP_Real newub, SCIP_Real oldlb, SCIP_Real oldub)
Definition: set.c:6831
SCIP_RETCODE SCIPremoveVarFromGlobalStructures(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:7833
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPgetVarAvgInferenceScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9401
static SCIP_RETCODE tightenBounds(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:8076
SCIP_Bool SCIPallowStrongDualReds(SCIP *scip)
Definition: scip_var.c:8590
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:122
SCIP_Real SCIPgetVarMultaggrUbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6535
SCIP_Real SCIPgetVarMultaggrUbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6565
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:199
SCIP_RETCODE SCIPchgVarUbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4884
SCIP_EXPORT int SCIPvarGetNCliques(SCIP_VAR *var, SCIP_Bool varfixing)
Definition: var.c:18019
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:6754
void SCIPcolInvalidateStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4253
SCIP_RETCODE SCIPvarGetProbvarSum(SCIP_VAR **var, SCIP_SET *set, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12418
SCIP_RETCODE SCIPflattenVarAggregationGraph(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1690
SCIP_EXPORT SCIP_BOUNDTYPE SCIPboundchgGetBoundtype(SCIP_BOUNDCHG *boundchg)
Definition: var.c:16944
SCIP_NODE * root
Definition: struct_tree.h:177
#define SCIP_CALL_ABORT(x)
Definition: def.h:349
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:8375
SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:8150
void SCIPdisableVarHistory(SCIP *scip)
Definition: scip_var.c:8688
void SCIPgmlWriteNode(FILE *file, unsigned int id, const char *label, const char *nodetype, const char *fillcolor, const char *bordercolor)
Definition: misc.c:487
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:356
SCIP_ORIGINAL original
Definition: struct_var.h:220
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:3232
SCIP_LP * lp
Definition: struct_scip.h:82
SCIP_Bool SCIPdoNotAggr(SCIP *scip)
Definition: scip_var.c:8539
#define SCIPABORT()
Definition: def.h:342
public methods for global and local (sub)problems
SCIP_Real SCIPadjustedVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real lb)
Definition: scip_var.c:4607
SCIP_Real SCIPvarGetMultaggrLbLocal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8243
SCIP_RETCODE SCIPgetVarSols(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip_var.c:2324
SCIP_Bool SCIPgetVarWasFixedAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2279
SCIP_RETCODE SCIPupdateVarPseudocost(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
Definition: scip_var.c:8708
datastructures for global SCIP settings
SCIP_RETCODE SCIPlpEndStrongbranch(SCIP_LP *lp)
Definition: lp.c:4184
SCIP_RETCODE SCIPsetRelaxSolValsSol(SCIP *scip, SCIP_RELAX *relax, SCIP_SOL *sol, SCIP_Bool includeslp)
Definition: scip_var.c:2486
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:5800
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_RETCODE SCIPvarNegate(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR **negvar)
Definition: var.c:5764
SCIP_CLIQUE ** SCIPcliquetableGetCliques(SCIP_CLIQUETABLE *cliquetable)
Definition: implics.c:3497
SCIP_LPSOLSTAT SCIPgetLastStrongbranchLPSolStat(SCIP *scip, SCIP_BRANCHDIR branchdir)
Definition: scip_var.c:3985
static SCIP_RETCODE relabelOrderConsistent(SCIP *const scip, int *labels, int const nlabels, int *nclasses)
Definition: scip_var.c:6927
SCIP_EXPORT SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18259
SCIP_Real SCIPgetVarConflictScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9200
SCIP_RETCODE SCIPtightenVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6202
SCIP_RETCODE SCIPsolveProbingLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition: scip_probing.c:810
SCIP_RETCODE SCIPbranchcandUpdateVarBranchPriority(SCIP_BRANCHCAND *branchcand, SCIP_SET *set, SCIP_VAR *var, int branchpriority)
Definition: branch.c:1176
SCIP_Real SCIPvarGetPseudocostVariance(SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun)
Definition: var.c:14457
SCIP_Real scalar
Definition: struct_var.h:176
SCIP_Real SCIPgetVarPseudocostCount(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:8850
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:115
SCIP_RETCODE SCIPtransformVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition: scip_var.c:1386
memory allocation routines