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