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