Scippy

SCIP

Solving Constraint Integer Programs

scip_var.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2020 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file scip_var.c
17  * @ingroup OTHER_CFILES
18  * @brief public methods for SCIP variables
19  * @author Tobias Achterberg
20  * @author Timo Berthold
21  * @author Gerald Gamrath
22  * @author Leona Gottwald
23  * @author Stefan Heinz
24  * @author Gregor Hendel
25  * @author Thorsten Koch
26  * @author Alexander Martin
27  * @author Marc Pfetsch
28  * @author Michael Winkler
29  * @author Kati Wolter
30  *
31  * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE
32  */
33 
34 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
35 
36 #include "blockmemshell/memory.h"
37 #include "lpi/lpi.h"
38 #include "scip/branch.h"
39 #include "scip/clock.h"
40 #include "scip/conflict.h"
41 #include "scip/debug.h"
42 #include "scip/history.h"
43 #include "scip/implics.h"
44 #include "scip/lp.h"
45 #include "scip/prob.h"
46 #include "scip/pub_cons.h"
47 #include "scip/pub_implics.h"
48 #include "scip/pub_lp.h"
49 #include "scip/pub_message.h"
50 #include "scip/pub_misc.h"
51 #include "scip/pub_tree.h"
52 #include "scip/pub_var.h"
53 #include "scip/relax.h"
54 #include "scip/scip_general.h"
55 #include "scip/scip_lp.h"
56 #include "scip/scip_mem.h"
57 #include "scip/scip_message.h"
58 #include "scip/scip_numerics.h"
59 #include "scip/scip_prob.h"
60 #include "scip/scip_probing.h"
61 #include "scip/scip_sol.h"
62 #include "scip/scip_solvingstats.h"
63 #include "scip/scip_tree.h"
64 #include "scip/scip_var.h"
65 #include "scip/set.h"
66 #include "scip/sol.h"
67 #include "scip/solve.h"
68 #include "scip/stat.h"
69 #include "scip/struct_lp.h"
70 #include "scip/struct_mem.h"
71 #include "scip/struct_primal.h"
72 #include "scip/struct_prob.h"
73 #include "scip/struct_scip.h"
74 #include "scip/struct_set.h"
75 #include "scip/struct_stat.h"
76 #include "scip/struct_tree.h"
77 #include "scip/struct_var.h"
78 #include "scip/tree.h"
79 #include "scip/var.h"
80 #include <ctype.h>
81 
82 
83 /** creates and captures problem variable; if variable is of integral type, fractional bounds are automatically rounded;
84  * an integer variable with bounds zero and one is automatically converted into a binary variable;
85  *
86  * @warning When doing column generation and the original problem is a maximization problem, notice that SCIP will
87  * transform the problem into a minimization problem by multiplying the objective function by -1. Thus, the
88  * original objective function value of variables created during the solving process has to be multiplied by
89  * -1, too.
90  *
91  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
92  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
93  *
94  * @pre This method can be called if @p scip is in one of the following stages:
95  * - \ref SCIP_STAGE_PROBLEM
96  * - \ref SCIP_STAGE_TRANSFORMING
97  * - \ref SCIP_STAGE_INITPRESOLVE
98  * - \ref SCIP_STAGE_PRESOLVING
99  * - \ref SCIP_STAGE_EXITPRESOLVE
100  * - \ref SCIP_STAGE_PRESOLVED
101  * - \ref SCIP_STAGE_SOLVING
102  *
103  * @note the variable gets captured, hence at one point you have to release it using the method SCIPreleaseVar()
104  */
106  SCIP* scip, /**< SCIP data structure */
107  SCIP_VAR** var, /**< pointer to variable object */
108  const char* name, /**< name of variable, or NULL for automatic name creation */
109  SCIP_Real lb, /**< lower bound of variable */
110  SCIP_Real ub, /**< upper bound of variable */
111  SCIP_Real obj, /**< objective function value */
112  SCIP_VARTYPE vartype, /**< type of variable */
113  SCIP_Bool initial, /**< should var's column be present in the initial root LP? */
114  SCIP_Bool removable, /**< is var's column removable from the LP (due to aging or cleanup)? */
115  SCIP_DECL_VARDELORIG ((*vardelorig)), /**< frees user data of original variable, or NULL */
116  SCIP_DECL_VARTRANS ((*vartrans)), /**< creates transformed user data by transforming original user data, or NULL */
117  SCIP_DECL_VARDELTRANS ((*vardeltrans)), /**< frees user data of transformed variable, or NULL */
118  SCIP_DECL_VARCOPY ((*varcopy)), /**< copies variable data if wanted to subscip, or NULL */
119  SCIP_VARDATA* vardata /**< user data for this specific variable */
120  )
121 {
122  assert(var != NULL);
123  assert(lb <= ub);
124 
125  SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateVar", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
126 
127  /* forbid infinite objective function values */
128  if( SCIPisInfinity(scip, REALABS(obj)) )
129  {
130  SCIPerrorMessage("invalid objective function value: value is infinite\n");
131  return SCIP_INVALIDDATA;
132  }
133 
134  switch( scip->set->stage )
135  {
136  case SCIP_STAGE_PROBLEM:
137  SCIP_CALL( SCIPvarCreateOriginal(var, scip->mem->probmem, scip->set, scip->stat,
138  name, lb, ub, obj, vartype, initial, removable, vardelorig, vartrans, vardeltrans, varcopy, vardata) );
139  break;
140 
146  case SCIP_STAGE_SOLVING:
147  SCIP_CALL( SCIPvarCreateTransformed(var, scip->mem->probmem, scip->set, scip->stat,
148  name, lb, ub, obj, vartype, initial, removable, vardelorig, vartrans, vardeltrans, varcopy, vardata) );
149  break;
150 
151  default:
152  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
153  return SCIP_INVALIDCALL;
154  } /*lint !e788*/
155 
156  return SCIP_OKAY;
157 }
158 
159 /** creates and captures problem variable with optional callbacks and variable data set to NULL, which can be set
160  * afterwards using SCIPvarSetDelorigData(), SCIPvarSetTransData(),
161  * SCIPvarSetDeltransData(), SCIPvarSetCopy(), and SCIPvarSetData(); sets variable flags initial=TRUE
162  * and removable = FALSE, which can be adjusted by using SCIPvarSetInitial() and SCIPvarSetRemovable(), resp.;
163  * if variable is of integral type, fractional bounds are automatically rounded;
164  * an integer variable with bounds zero and one is automatically converted into a binary variable;
165  *
166  * @warning When doing column generation and the original problem is a maximization problem, notice that SCIP will
167  * transform the problem into a minimization problem by multiplying the objective function by -1. Thus, the
168  * original objective function value of variables created during the solving process has to be multiplied by
169  * -1, too.
170  *
171  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
172  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
173  *
174  * @pre This method can be called if @p scip is in one of the following stages:
175  * - \ref SCIP_STAGE_PROBLEM
176  * - \ref SCIP_STAGE_TRANSFORMING
177  * - \ref SCIP_STAGE_INITPRESOLVE
178  * - \ref SCIP_STAGE_PRESOLVING
179  * - \ref SCIP_STAGE_EXITPRESOLVE
180  * - \ref SCIP_STAGE_PRESOLVED
181  * - \ref SCIP_STAGE_SOLVING
182  *
183  * @note the variable gets captured, hence at one point you have to release it using the method SCIPreleaseVar()
184  */
186  SCIP* scip, /**< SCIP data structure */
187  SCIP_VAR** var, /**< pointer to variable object */
188  const char* name, /**< name of variable, or NULL for automatic name creation */
189  SCIP_Real lb, /**< lower bound of variable */
190  SCIP_Real ub, /**< upper bound of variable */
191  SCIP_Real obj, /**< objective function value */
192  SCIP_VARTYPE vartype /**< type of variable */
193  )
194 {
195  SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateVarBasic", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
196 
197  SCIP_CALL( SCIPcreateVar(scip, var, name, lb, ub, obj, vartype, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
198 
199  return SCIP_OKAY;
200 }
201 
202 /** outputs the variable name to the file stream
203  *
204  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
205  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
206  *
207  * @pre This method can be called if @p scip is in one of the following stages:
208  * - \ref SCIP_STAGE_PROBLEM
209  * - \ref SCIP_STAGE_TRANSFORMING
210  * - \ref SCIP_STAGE_TRANSFORMED
211  * - \ref SCIP_STAGE_INITPRESOLVE
212  * - \ref SCIP_STAGE_PRESOLVING
213  * - \ref SCIP_STAGE_EXITPRESOLVE
214  * - \ref SCIP_STAGE_PRESOLVED
215  * - \ref SCIP_STAGE_INITSOLVE
216  * - \ref SCIP_STAGE_SOLVING
217  * - \ref SCIP_STAGE_SOLVED
218  * - \ref SCIP_STAGE_EXITSOLVE
219  * - \ref SCIP_STAGE_FREETRANS
220  */
222  SCIP* scip, /**< SCIP data structure */
223  FILE* file, /**< output file, or NULL for stdout */
224  SCIP_VAR* var, /**< variable to output */
225  SCIP_Bool type /**< should the variable type be also posted */
226  )
227 {
228  assert(scip != NULL);
229  assert(var != NULL);
230 
231  SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarName", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
232 
233  /* print variable name */
234  if( SCIPvarIsNegated(var) )
235  {
236  SCIP_VAR* negatedvar;
237 
238  SCIP_CALL( SCIPgetNegatedVar(scip, var, &negatedvar) );
239  SCIPinfoMessage(scip, file, "<~%s>", SCIPvarGetName(negatedvar));
240  }
241  else
242  {
243  SCIPinfoMessage(scip, file, "<%s>", SCIPvarGetName(var));
244  }
245 
246  if( type )
247  {
248  /* print variable type */
249  SCIPinfoMessage(scip, file, "[%c]",
253  }
254 
255  return SCIP_OKAY;
256 }
257 
258 /** print the given list of variables to output stream separated by the given delimiter character;
259  *
260  * i. e. the variables x1, x2, ..., xn with given delimiter ',' are written as: <x1>, <x2>, ..., <xn>;
261  *
262  * the method SCIPparseVarsList() can parse such a string
263  *
264  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
265  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
266  *
267  * @pre This method can be called if @p scip is in one of the following stages:
268  * - \ref SCIP_STAGE_PROBLEM
269  * - \ref SCIP_STAGE_TRANSFORMING
270  * - \ref SCIP_STAGE_TRANSFORMED
271  * - \ref SCIP_STAGE_INITPRESOLVE
272  * - \ref SCIP_STAGE_PRESOLVING
273  * - \ref SCIP_STAGE_EXITPRESOLVE
274  * - \ref SCIP_STAGE_PRESOLVED
275  * - \ref SCIP_STAGE_INITSOLVE
276  * - \ref SCIP_STAGE_SOLVING
277  * - \ref SCIP_STAGE_SOLVED
278  * - \ref SCIP_STAGE_EXITSOLVE
279  * - \ref SCIP_STAGE_FREETRANS
280  *
281  * @note The printing process is done via the message handler system.
282  */
284  SCIP* scip, /**< SCIP data structure */
285  FILE* file, /**< output file, or NULL for stdout */
286  SCIP_VAR** vars, /**< variable array to output */
287  int nvars, /**< number of variables */
288  SCIP_Bool type, /**< should the variable type be also posted */
289  char delimiter /**< character which is used for delimitation */
290  )
291 {
292  int v;
293 
294  SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsList", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
295 
296  for( v = 0; v < nvars; ++v )
297  {
298  if( v > 0 )
299  {
300  SCIPinfoMessage(scip, file, "%c", delimiter);
301  }
302 
303  /* print variable name */
304  SCIP_CALL( SCIPwriteVarName(scip, file, vars[v], type) );
305  }
306 
307  return SCIP_OKAY;
308 }
309 
310 /** print the given variables and coefficients as linear sum in the following form
311  * c1 <x1> + c2 <x2> ... + cn <xn>
312  *
313  * This string can be parsed by the method SCIPparseVarsLinearsum().
314  *
315  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
316  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
317  *
318  * @pre This method can be called if @p scip is in one of the following stages:
319  * - \ref SCIP_STAGE_PROBLEM
320  * - \ref SCIP_STAGE_TRANSFORMING
321  * - \ref SCIP_STAGE_TRANSFORMED
322  * - \ref SCIP_STAGE_INITPRESOLVE
323  * - \ref SCIP_STAGE_PRESOLVING
324  * - \ref SCIP_STAGE_EXITPRESOLVE
325  * - \ref SCIP_STAGE_PRESOLVED
326  * - \ref SCIP_STAGE_INITSOLVE
327  * - \ref SCIP_STAGE_SOLVING
328  * - \ref SCIP_STAGE_SOLVED
329  * - \ref SCIP_STAGE_EXITSOLVE
330  * - \ref SCIP_STAGE_FREETRANS
331  *
332  * @note The printing process is done via the message handler system.
333  */
335  SCIP* scip, /**< SCIP data structure */
336  FILE* file, /**< output file, or NULL for stdout */
337  SCIP_VAR** vars, /**< variable array to output */
338  SCIP_Real* vals, /**< array of coefficients or NULL if all coefficients are 1.0 */
339  int nvars, /**< number of variables */
340  SCIP_Bool type /**< should the variable type be also posted */
341  )
342 {
343  int v;
344 
345  SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsLinearsum", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
346 
347  for( v = 0; v < nvars; ++v )
348  {
349  if( vals != NULL )
350  {
351  if( vals[v] == 1.0 )
352  {
353  if( v > 0 )
354  SCIPinfoMessage(scip, file, " +");
355  }
356  else if( vals[v] == -1.0 )
357  SCIPinfoMessage(scip, file, " -");
358  else
359  SCIPinfoMessage(scip, file, " %+.15g", vals[v]);
360  }
361  else if( nvars > 0 )
362  SCIPinfoMessage(scip, file, " +");
363 
364  /* print variable name */
365  SCIP_CALL( SCIPwriteVarName(scip, file, vars[v], type) );
366  }
367 
368  return SCIP_OKAY;
369 }
370 
371 /** print the given monomials as polynomial in the following form
372  * c1 <x11>^e11 <x12>^e12 ... <x1n>^e1n + c2 <x21>^e21 <x22>^e22 ... + ... + cn <xn1>^en1 ...
373  *
374  * This string can be parsed by the method SCIPparseVarsPolynomial().
375  *
376  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
377  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
378  *
379  * @pre This method can be called if @p scip is in one of the following stages:
380  * - \ref SCIP_STAGE_PROBLEM
381  * - \ref SCIP_STAGE_TRANSFORMING
382  * - \ref SCIP_STAGE_TRANSFORMED
383  * - \ref SCIP_STAGE_INITPRESOLVE
384  * - \ref SCIP_STAGE_PRESOLVING
385  * - \ref SCIP_STAGE_EXITPRESOLVE
386  * - \ref SCIP_STAGE_PRESOLVED
387  * - \ref SCIP_STAGE_INITSOLVE
388  * - \ref SCIP_STAGE_SOLVING
389  * - \ref SCIP_STAGE_SOLVED
390  * - \ref SCIP_STAGE_EXITSOLVE
391  * - \ref SCIP_STAGE_FREETRANS
392  *
393  * @note The printing process is done via the message handler system.
394  */
396  SCIP* scip, /**< SCIP data structure */
397  FILE* file, /**< output file, or NULL for stdout */
398  SCIP_VAR*** monomialvars, /**< arrays with variables for each monomial */
399  SCIP_Real** monomialexps, /**< arrays with variable exponents, or NULL if always 1.0 */
400  SCIP_Real* monomialcoefs, /**< array with monomial coefficients */
401  int* monomialnvars, /**< array with number of variables for each monomial */
402  int nmonomials, /**< number of monomials */
403  SCIP_Bool type /**< should the variable type be also posted */
404  )
405 {
406  int i;
407  int v;
408 
409  assert(scip != NULL);
410  assert(monomialvars != NULL || nmonomials == 0);
411  assert(monomialcoefs != NULL || nmonomials == 0);
412  assert(monomialnvars != NULL || nmonomials == 0);
413 
414  SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsPolynomial", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
415 
416  if( nmonomials == 0 )
417  {
418  SCIPinfoMessage(scip, file, " 0 ");
419  return SCIP_OKAY;
420  }
421 
422  for( i = 0; i < nmonomials; ++i )
423  {
424  if( monomialcoefs[i] == 1.0 ) /*lint !e613*/
425  {
426  if( i > 0 )
427  SCIPinfoMessage(scip, file, " +");
428  }
429  else if( monomialcoefs[i] == -1.0 ) /*lint !e613*/
430  SCIPinfoMessage(scip, file, " -");
431  else
432  SCIPinfoMessage(scip, file, " %+.15g", monomialcoefs[i]); /*lint !e613*/
433 
434  assert(monomialvars[i] != NULL || monomialnvars[i] == 0); /*lint !e613*/
435 
436  for( v = 0; v < monomialnvars[i]; ++v ) /*lint !e613*/
437  {
438  SCIP_CALL( SCIPwriteVarName(scip, file, monomialvars[i][v], type) ); /*lint !e613*/
439  if( monomialexps != NULL && monomialexps[i] != NULL && monomialexps[i][v] != 1.0 )
440  {
441  SCIPinfoMessage(scip, file, "^%.15g", monomialexps[i][v]);
442  }
443  }
444  }
445 
446  return SCIP_OKAY;
447 }
448 
449 /** parses variable information (in cip format) out of a string; if the parsing process was successful a variable is
450  * created and captured; if variable is of integral type, fractional bounds are automatically rounded; an integer
451  * variable with bounds zero and one is automatically converted into a binary variable
452  *
453  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
454  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
455  *
456  * @pre This method can be called if @p scip is in one of the following stages:
457  * - \ref SCIP_STAGE_PROBLEM
458  * - \ref SCIP_STAGE_TRANSFORMING
459  * - \ref SCIP_STAGE_INITPRESOLVE
460  * - \ref SCIP_STAGE_PRESOLVING
461  * - \ref SCIP_STAGE_EXITPRESOLVE
462  * - \ref SCIP_STAGE_PRESOLVED
463  * - \ref SCIP_STAGE_SOLVING
464  */
466  SCIP* scip, /**< SCIP data structure */
467  SCIP_VAR** var, /**< pointer to store the problem variable */
468  const char* str, /**< string to parse */
469  SCIP_Bool initial, /**< should var's column be present in the initial root LP? */
470  SCIP_Bool removable, /**< is var's column removable from the LP (due to aging or cleanup)? */
471  SCIP_DECL_VARCOPY ((*varcopy)), /**< copies variable data if wanted to subscip, or NULL */
472  SCIP_DECL_VARDELORIG ((*vardelorig)), /**< frees user data of original variable */
473  SCIP_DECL_VARTRANS ((*vartrans)), /**< creates transformed user data by transforming original user data */
474  SCIP_DECL_VARDELTRANS ((*vardeltrans)), /**< frees user data of transformed variable */
475  SCIP_VARDATA* vardata, /**< user data for this specific variable */
476  char** endptr, /**< pointer to store the final string position if successful */
477  SCIP_Bool* success /**< pointer store if the paring process was successful */
478  )
479 {
480  assert(var != NULL);
481 
482  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVar", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
483 
484  switch( scip->set->stage )
485  {
486  case SCIP_STAGE_PROBLEM:
487  SCIP_CALL( SCIPvarParseOriginal(var, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
488  str, initial, removable, varcopy, vardelorig, vartrans, vardeltrans, vardata, endptr, success) );
489  break;
490 
496  case SCIP_STAGE_SOLVING:
497  SCIP_CALL( SCIPvarParseTransformed(var, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
498  str, initial, removable, varcopy, vardelorig, vartrans, vardeltrans, vardata, endptr, success) );
499  break;
500 
501  default:
502  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
503  return SCIP_INVALIDCALL;
504  } /*lint !e788*/
505 
506  return SCIP_OKAY;
507 }
508 
509 /** parses the given string for a variable name and stores the variable in the corresponding pointer if such a variable
510  * exits and returns the position where the parsing stopped
511  *
512  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
513  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
514  *
515  * @pre This method can be called if @p scip is in one of the following stages:
516  * - \ref SCIP_STAGE_PROBLEM
517  * - \ref SCIP_STAGE_TRANSFORMING
518  * - \ref SCIP_STAGE_INITPRESOLVE
519  * - \ref SCIP_STAGE_PRESOLVING
520  * - \ref SCIP_STAGE_EXITPRESOLVE
521  * - \ref SCIP_STAGE_PRESOLVED
522  * - \ref SCIP_STAGE_SOLVING
523  */
525  SCIP* scip, /**< SCIP data structure */
526  const char* str, /**< string to parse */
527  SCIP_VAR** var, /**< pointer to store the problem variable, or NULL if it does not exit */
528  char** endptr /**< pointer to store the final string position if successful */
529  )
530 {
531  char varname[SCIP_MAXSTRLEN];
532 
533  assert(str != NULL);
534  assert(var != NULL);
535  assert(endptr != NULL);
536 
537  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarName", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
538 
539  SCIPstrCopySection(str, '<', '>', varname, SCIP_MAXSTRLEN, endptr);
540  assert(*endptr != NULL);
541 
542  if( *varname == '\0' )
543  {
544  SCIPerrorMessage("invalid variable name string given: could not find '<'\n");
545  return SCIP_INVALIDDATA;
546  }
547 
548  /* check if we have a negated variable */
549  if( *varname == '~' )
550  {
551  SCIPdebugMsg(scip, "parsed negated variable name <%s>\n", &varname[1]);
552 
553  /* search for the variable and ignore '~' */
554  (*var) = SCIPfindVar(scip, &varname[1]);
555 
556  if( *var != NULL )
557  {
558  SCIP_CALL( SCIPgetNegatedVar(scip, *var, var) );
559  }
560  }
561  else
562  {
563  SCIPdebugMsg(scip, "parsed variable name <%s>\n", varname);
564 
565  /* search for the variable */
566  (*var) = SCIPfindVar(scip, varname);
567  }
568 
569  str = *endptr;
570 
571  /* skip additional variable type marker */
572  if( *str == '[' && (str[1] == SCIP_VARTYPE_BINARY_CHAR || str[1] == SCIP_VARTYPE_INTEGER_CHAR ||
573  str[1] == SCIP_VARTYPE_IMPLINT_CHAR || str[1] == SCIP_VARTYPE_CONTINUOUS_CHAR ) && str[2] == ']' )
574  (*endptr) += 3;
575 
576  return SCIP_OKAY;
577 }
578 
579 /** parse the given string as variable list (here ',' is the delimiter)) (<x1>, <x2>, ..., <xn>) (see
580  * SCIPwriteVarsList() ); if it was successful, the pointer success is set to TRUE
581  *
582  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
583  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
584  *
585  * @pre This method can be called if @p scip is in one of the following stages:
586  * - \ref SCIP_STAGE_PROBLEM
587  * - \ref SCIP_STAGE_TRANSFORMING
588  * - \ref SCIP_STAGE_INITPRESOLVE
589  * - \ref SCIP_STAGE_PRESOLVING
590  * - \ref SCIP_STAGE_EXITPRESOLVE
591  * - \ref SCIP_STAGE_PRESOLVED
592  * - \ref SCIP_STAGE_SOLVING
593  *
594  * @note The pointer success in only set to FALSE in the case that a variable with a parsed variable name does not exist.
595  *
596  * @note If the number of (parsed) variables is greater than the available slots in the variable array, nothing happens
597  * except that the required size is stored in the corresponding integer; the reason for this approach is that we
598  * cannot reallocate memory, since we do not know how the memory has been allocated (e.g., by a C++ 'new' or SCIP
599  * memory functions).
600  */
602  SCIP* scip, /**< SCIP data structure */
603  const char* str, /**< string to parse */
604  SCIP_VAR** vars, /**< array to store the parsed variable */
605  int* nvars, /**< pointer to store number of parsed variables */
606  int varssize, /**< size of the variable array */
607  int* requiredsize, /**< pointer to store the required array size for the active variables */
608  char** endptr, /**< pointer to store the final string position if successful */
609  char delimiter, /**< character which is used for delimitation */
610  SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
611  )
612 {
613  SCIP_VAR** tmpvars;
614  SCIP_VAR* var;
615  int ntmpvars = 0;
616  int v;
617 
618  assert( nvars != NULL );
619  assert( requiredsize != NULL );
620  assert( endptr != NULL );
621  assert( success != NULL );
622 
623  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsList", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
624 
625  /* allocate buffer memory for temporary storing the parsed variables */
626  SCIP_CALL( SCIPallocBufferArray(scip, &tmpvars, varssize) );
627 
628  (*success) = TRUE;
629 
630  do
631  {
632  *endptr = (char*)str;
633 
634  /* parse variable name */
635  SCIP_CALL( SCIPparseVarName(scip, str, &var, endptr) );
636 
637  if( var == NULL )
638  {
639  SCIPdebugMsg(scip, "variable with name <%s> does not exist\n", SCIPvarGetName(var));
640  (*success) = FALSE;
641  break;
642  }
643 
644  /* store the variable in the tmp array */
645  if( ntmpvars < varssize )
646  tmpvars[ntmpvars] = var;
647 
648  ntmpvars++;
649 
650  str = *endptr;
651 
652  while( isspace((unsigned char)*str) )
653  str++;
654  }
655  while( *str == delimiter );
656 
657  *endptr = (char*)str;
658 
659  /* if all variable name searches were successful and the variable array has enough slots, copy the collected variables */
660  if( (*success) && ntmpvars <= varssize )
661  {
662  for( v = 0; v < ntmpvars; ++v )
663  vars[v] = tmpvars[v];
664 
665  (*nvars) = ntmpvars;
666  }
667  else
668  (*nvars) = 0;
669 
670  (*requiredsize) = ntmpvars;
671 
672  /* free buffer arrays */
673  SCIPfreeBufferArray(scip, &tmpvars);
674 
675  return SCIP_OKAY;
676 }
677 
678 /** parse the given string as linear sum of variables and coefficients (c1 <x1> + c2 <x2> + ... + cn <xn>)
679  * (see SCIPwriteVarsLinearsum() ); if it was successful, the pointer success is set to TRUE
680  *
681  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
682  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
683  *
684  * @pre This method can be called if @p scip is in one of the following stages:
685  * - \ref SCIP_STAGE_PROBLEM
686  * - \ref SCIP_STAGE_TRANSFORMING
687  * - \ref SCIP_STAGE_INITPRESOLVE
688  * - \ref SCIP_STAGE_PRESOLVING
689  * - \ref SCIP_STAGE_EXITPRESOLVE
690  * - \ref SCIP_STAGE_PRESOLVED
691  * - \ref SCIP_STAGE_SOLVING
692  *
693  * @note The pointer success in only set to FALSE in the case that a variable with a parsed variable name does not exist.
694  *
695  * @note If the number of (parsed) variables is greater than the available slots in the variable array, nothing happens
696  * except that the required size is stored in the corresponding integer; the reason for this approach is that we
697  * cannot reallocate memory, since we do not know how the memory has been allocated (e.g., by a C++ 'new' or SCIP
698  * memory functions).
699  */
701  SCIP* scip, /**< SCIP data structure */
702  const char* str, /**< string to parse */
703  SCIP_VAR** vars, /**< array to store the parsed variables */
704  SCIP_Real* vals, /**< array to store the parsed coefficients */
705  int* nvars, /**< pointer to store number of parsed variables */
706  int varssize, /**< size of the variable array */
707  int* requiredsize, /**< pointer to store the required array size for the active variables */
708  char** endptr, /**< pointer to store the final string position if successful */
709  SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
710  )
711 {
712  SCIP_VAR*** monomialvars;
713  SCIP_Real** monomialexps;
714  SCIP_Real* monomialcoefs;
715  int* monomialnvars;
716  int nmonomials;
717 
718  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsLinearsum", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
719 
720  assert(scip != NULL);
721  assert(str != NULL);
722  assert(vars != NULL || varssize == 0);
723  assert(vals != NULL || varssize == 0);
724  assert(nvars != NULL);
725  assert(requiredsize != NULL);
726  assert(endptr != NULL);
727  assert(success != NULL);
728 
729  *requiredsize = 0;
730 
731  SCIP_CALL( SCIPparseVarsPolynomial(scip, str, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, &nmonomials, endptr, success) );
732 
733  if( !*success )
734  {
735  assert(nmonomials == 0); /* SCIPparseVarsPolynomial should have freed all buffers, so no need to call free here */
736  return SCIP_OKAY;
737  }
738 
739  /* check if linear sum is just "0" */
740  if( nmonomials == 1 && monomialnvars[0] == 0 && monomialcoefs[0] == 0.0 )
741  {
742  *nvars = 0;
743  *requiredsize = 0;
744 
745  SCIPfreeParseVarsPolynomialData(scip, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, nmonomials);
746 
747  return SCIP_OKAY;
748  }
749 
750  *nvars = nmonomials;
751  *requiredsize = nmonomials;
752 
753  /* if we have enough slots in the variables array, copy variables over */
754  if( varssize >= nmonomials )
755  {
756  int v;
757 
758  for( v = 0; v < nmonomials; ++v )
759  {
760  if( monomialnvars[v] == 0 )
761  {
762  SCIPerrorMessage("constant in linear sum\n");
763  *success = FALSE;
764  break;
765  }
766  if( monomialnvars[v] > 1 || monomialexps[v][0] != 1.0 )
767  {
768  SCIPerrorMessage("nonlinear monomial in linear sum\n");
769  *success = FALSE;
770  break;
771  }
772  assert(monomialnvars[v] == 1);
773  assert(monomialvars[v][0] != NULL);
774  assert(monomialexps[v][0] == 1.0);
775 
776  vars[v] = monomialvars[v][0]; /*lint !e613*/
777  vals[v] = monomialcoefs[v]; /*lint !e613*/
778  }
779  }
780 
781  SCIPfreeParseVarsPolynomialData(scip, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, nmonomials);
782 
783  return SCIP_OKAY;
784 }
785 
786 /** parse the given string as polynomial of variables and coefficients
787  * (c1 <x11>^e11 <x12>^e12 ... <x1n>^e1n + c2 <x21>^e21 <x22>^e22 ... + ... + cn <xn1>^en1 ...)
788  * (see SCIPwriteVarsPolynomial()); if it was successful, the pointer success is set to TRUE
789  *
790  * The user has to call SCIPfreeParseVarsPolynomialData(scip, monomialvars, monomialexps,
791  * monomialcoefs, monomialnvars, *nmonomials) short after SCIPparseVarsPolynomial to free all the
792  * allocated memory again. Do not keep the arrays created by SCIPparseVarsPolynomial around, since
793  * they use buffer memory that is intended for short term use only.
794  *
795  * Parsing is stopped at the end of string (indicated by the \\0-character) or when no more monomials
796  * are recognized.
797  *
798  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
799  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
800  *
801  * @pre This method can be called if @p scip is in one of the following stages:
802  * - \ref SCIP_STAGE_PROBLEM
803  * - \ref SCIP_STAGE_TRANSFORMING
804  * - \ref SCIP_STAGE_INITPRESOLVE
805  * - \ref SCIP_STAGE_PRESOLVING
806  * - \ref SCIP_STAGE_EXITPRESOLVE
807  * - \ref SCIP_STAGE_PRESOLVED
808  * - \ref SCIP_STAGE_SOLVING
809  */
811  SCIP* scip, /**< SCIP data structure */
812  const char* str, /**< string to parse */
813  SCIP_VAR**** monomialvars, /**< pointer to store arrays with variables for each monomial */
814  SCIP_Real*** monomialexps, /**< pointer to store arrays with variable exponents */
815  SCIP_Real** monomialcoefs, /**< pointer to store array with monomial coefficients */
816  int** monomialnvars, /**< pointer to store array with number of variables for each monomial */
817  int* nmonomials, /**< pointer to store number of parsed monomials */
818  char** endptr, /**< pointer to store the final string position if successful */
819  SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
820  )
821 {
822  typedef enum
823  {
824  SCIPPARSEPOLYNOMIAL_STATE_BEGIN, /* we are at the beginning of a monomial */
825  SCIPPARSEPOLYNOMIAL_STATE_INTERMED, /* we are in between the factors of a monomial */
826  SCIPPARSEPOLYNOMIAL_STATE_COEF, /* we parse the coefficient of a monomial */
827  SCIPPARSEPOLYNOMIAL_STATE_VARS, /* we parse monomial variables */
828  SCIPPARSEPOLYNOMIAL_STATE_EXPONENT, /* we parse the exponent of a variable */
829  SCIPPARSEPOLYNOMIAL_STATE_END, /* we are at the end the polynomial */
830  SCIPPARSEPOLYNOMIAL_STATE_ERROR /* a parsing error occured */
831  } SCIPPARSEPOLYNOMIAL_STATES;
832 
833  SCIPPARSEPOLYNOMIAL_STATES state;
834  int monomialssize;
835 
836  /* data of currently parsed monomial */
837  int varssize;
838  int nvars;
839  SCIP_VAR** vars;
840  SCIP_Real* exponents;
841  SCIP_Real coef;
842 
843  assert(scip != NULL);
844  assert(str != NULL);
845  assert(monomialvars != NULL);
846  assert(monomialexps != NULL);
847  assert(monomialnvars != NULL);
848  assert(monomialcoefs != NULL);
849  assert(nmonomials != NULL);
850  assert(endptr != NULL);
851  assert(success != NULL);
852 
853  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsPolynomial", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
854 
855  *success = FALSE;
856  *nmonomials = 0;
857  monomialssize = 0;
858  *monomialvars = NULL;
859  *monomialexps = NULL;
860  *monomialcoefs = NULL;
861  *monomialnvars = NULL;
862 
863  /* initialize state machine */
864  state = SCIPPARSEPOLYNOMIAL_STATE_BEGIN;
865  varssize = 0;
866  nvars = 0;
867  vars = NULL;
868  exponents = NULL;
869  coef = SCIP_INVALID;
870 
871  SCIPdebugMsg(scip, "parsing polynomial from '%s'\n", str);
872 
873  while( *str && state != SCIPPARSEPOLYNOMIAL_STATE_END && state != SCIPPARSEPOLYNOMIAL_STATE_ERROR )
874  {
875  /* skip white space */
876  while( isspace((unsigned char)*str) )
877  str++;
878 
879  assert(state != SCIPPARSEPOLYNOMIAL_STATE_END);
880 
881  switch( state )
882  {
883  case SCIPPARSEPOLYNOMIAL_STATE_BEGIN:
884  {
885  if( coef != SCIP_INVALID ) /*lint !e777*/
886  {
887  SCIPdebugMsg(scip, "push monomial with coefficient <%g> and <%d> vars\n", coef, nvars);
888  /* push previous monomial */
889  if( monomialssize <= *nmonomials )
890  {
891  monomialssize = SCIPcalcMemGrowSize(scip, *nmonomials+1);
892 
893  SCIP_CALL( SCIPreallocBufferArray(scip, monomialvars, monomialssize) );
894  SCIP_CALL( SCIPreallocBufferArray(scip, monomialexps, monomialssize) );
895  SCIP_CALL( SCIPreallocBufferArray(scip, monomialnvars, monomialssize) );
896  SCIP_CALL( SCIPreallocBufferArray(scip, monomialcoefs, monomialssize) );
897  }
898 
899  if( nvars > 0 )
900  {
901  SCIP_CALL( SCIPduplicateBufferArray(scip, &(*monomialvars)[*nmonomials], vars, nvars) ); /*lint !e866*/
902  SCIP_CALL( SCIPduplicateBufferArray(scip, &(*monomialexps)[*nmonomials], exponents, nvars) ); /*lint !e866*/
903  }
904  else
905  {
906  (*monomialvars)[*nmonomials] = NULL;
907  (*monomialexps)[*nmonomials] = NULL;
908  }
909  (*monomialcoefs)[*nmonomials] = coef;
910  (*monomialnvars)[*nmonomials] = nvars;
911  ++*nmonomials;
912 
913  nvars = 0;
914  coef = SCIP_INVALID;
915  }
916 
917  if( *str == '<' )
918  {
919  /* there seem to come a variable at the beginning of a monomial
920  * so assume the coefficient is 1.0
921  */
922  state = SCIPPARSEPOLYNOMIAL_STATE_VARS;
923  coef = 1.0;
924  break;
925  }
926  if( *str == '-' || *str == '+' || isdigit(*str) )
927  {
928  state = SCIPPARSEPOLYNOMIAL_STATE_COEF;
929  break;
930  }
931 
932  state = SCIPPARSEPOLYNOMIAL_STATE_END;
933 
934  break;
935  }
936 
937  case SCIPPARSEPOLYNOMIAL_STATE_INTERMED:
938  {
939  if( *str == '<' )
940  {
941  /* there seem to come another variable */
942  state = SCIPPARSEPOLYNOMIAL_STATE_VARS;
943  break;
944  }
945 
946  if( *str == '-' || *str == '+' || isdigit(*str) )
947  {
948  /* there seem to come a coefficient, which means the next monomial */
949  state = SCIPPARSEPOLYNOMIAL_STATE_BEGIN;
950  break;
951  }
952 
953  /* since we cannot detect the symbols we stop parsing the polynomial */
954  state = SCIPPARSEPOLYNOMIAL_STATE_END;
955  break;
956  }
957 
958  case SCIPPARSEPOLYNOMIAL_STATE_COEF:
959  {
960  if( *str == '+' && !isdigit(str[1]) )
961  {
962  /* only a plus sign, without number */
963  coef = 1.0;
964  ++str;
965  }
966  else if( *str == '-' && !isdigit(str[1]) )
967  {
968  /* only a minus sign, without number */
969  coef = -1.0;
970  ++str;
971  }
972  else if( SCIPstrToRealValue(str, &coef, endptr) )
973  {
974  str = *endptr;
975  }
976  else
977  {
978  SCIPerrorMessage("could not parse number in the beginning of '%s'\n", str);
979  state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
980  break;
981  }
982 
983  /* after the coefficient we go into the intermediate state, i.e., expecting next variables */
984  state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED;
985 
986  break;
987  }
988 
989  case SCIPPARSEPOLYNOMIAL_STATE_VARS:
990  {
991  SCIP_VAR* var;
992 
993  assert(*str == '<');
994 
995  /* parse variable name */
996  SCIP_CALL( SCIPparseVarName(scip, str, &var, endptr) );
997 
998  /* check if variable name was parsed */
999  if( *endptr == str )
1000  {
1001  state = SCIPPARSEPOLYNOMIAL_STATE_END;
1002  break;
1003  }
1004 
1005  if( var == NULL )
1006  {
1007  SCIPerrorMessage("did not find variable in the beginning of %s\n", str);
1008  state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
1009  break;
1010  }
1011 
1012  /* add variable to vars array */
1013  if( nvars + 1 > varssize )
1014  {
1015  varssize = SCIPcalcMemGrowSize(scip, nvars+1);
1016  SCIP_CALL( SCIPreallocBufferArray(scip, &vars, varssize) );
1017  SCIP_CALL( SCIPreallocBufferArray(scip, &exponents, varssize) );
1018  }
1019  assert(vars != NULL);
1020  assert(exponents != NULL);
1021 
1022  vars[nvars] = var;
1023  exponents[nvars] = 1.0;
1024  ++nvars;
1025 
1026  str = *endptr;
1027 
1028  if( *str == '^' )
1029  state = SCIPPARSEPOLYNOMIAL_STATE_EXPONENT;
1030  else
1031  state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED;
1032 
1033  break;
1034  }
1035 
1036  case SCIPPARSEPOLYNOMIAL_STATE_EXPONENT:
1037  {
1038  assert(*str == '^');
1039  assert(nvars > 0); /* we should be in a monomial that has already a variable */
1040  assert(exponents != NULL);
1041  ++str;
1042 
1043  if( !SCIPstrToRealValue(str, &exponents[nvars-1], endptr) )
1044  {
1045  SCIPerrorMessage("could not parse number in the beginning of '%s'\n", str);
1046  state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
1047  break;
1048  }
1049  str = *endptr;
1050 
1051  /* after the exponent we go into the intermediate state, i.e., expecting next variables */
1052  state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED;
1053  break;
1054  }
1055 
1056  case SCIPPARSEPOLYNOMIAL_STATE_END:
1057  case SCIPPARSEPOLYNOMIAL_STATE_ERROR:
1058  default:
1059  SCIPerrorMessage("unexpected state\n");
1060  return SCIP_READERROR;
1061  }
1062  }
1063 
1064  /* set end pointer */
1065  *endptr = (char*)str;
1066 
1067  /* check state at end of string */
1068  switch( state )
1069  {
1070  case SCIPPARSEPOLYNOMIAL_STATE_BEGIN:
1071  case SCIPPARSEPOLYNOMIAL_STATE_END:
1072  case SCIPPARSEPOLYNOMIAL_STATE_INTERMED:
1073  {
1074  if( coef != SCIP_INVALID ) /*lint !e777*/
1075  {
1076  /* push last monomial */
1077  SCIPdebugMsg(scip, "push monomial with coefficient <%g> and <%d> vars\n", coef, nvars);
1078  if( monomialssize <= *nmonomials )
1079  {
1080  monomialssize = *nmonomials+1;
1081  SCIP_CALL( SCIPreallocBufferArray(scip, monomialvars, monomialssize) );
1082  SCIP_CALL( SCIPreallocBufferArray(scip, monomialexps, monomialssize) );
1083  SCIP_CALL( SCIPreallocBufferArray(scip, monomialnvars, monomialssize) );
1084  SCIP_CALL( SCIPreallocBufferArray(scip, monomialcoefs, monomialssize) );
1085  }
1086 
1087  if( nvars > 0 )
1088  {
1089  /* shrink vars and exponents array to needed size and take over ownership */
1090  SCIP_CALL( SCIPreallocBufferArray(scip, &vars, nvars) );
1091  SCIP_CALL( SCIPreallocBufferArray(scip, &exponents, nvars) );
1092  (*monomialvars)[*nmonomials] = vars;
1093  (*monomialexps)[*nmonomials] = exponents;
1094  vars = NULL;
1095  exponents = NULL;
1096  }
1097  else
1098  {
1099  (*monomialvars)[*nmonomials] = NULL;
1100  (*monomialexps)[*nmonomials] = NULL;
1101  }
1102  (*monomialcoefs)[*nmonomials] = coef;
1103  (*monomialnvars)[*nmonomials] = nvars;
1104  ++*nmonomials;
1105  }
1106 
1107  *success = TRUE;
1108  break;
1109  }
1110 
1111  case SCIPPARSEPOLYNOMIAL_STATE_COEF:
1112  case SCIPPARSEPOLYNOMIAL_STATE_VARS:
1113  case SCIPPARSEPOLYNOMIAL_STATE_EXPONENT:
1114  {
1115  SCIPerrorMessage("unexpected parsing state at end of polynomial string\n");
1116  }
1117  /*lint -fallthrough*/
1118  case SCIPPARSEPOLYNOMIAL_STATE_ERROR:
1119  assert(!*success);
1120  break;
1121  }
1122 
1123  /* free memory to store current monomial, if still existing */
1124  SCIPfreeBufferArrayNull(scip, &vars);
1125  SCIPfreeBufferArrayNull(scip, &exponents);
1126 
1127  if( *success && *nmonomials > 0 )
1128  {
1129  /* shrink arrays to required size, so we do not need to keep monomialssize around */
1130  assert(*nmonomials <= monomialssize);
1131  SCIP_CALL( SCIPreallocBufferArray(scip, monomialvars, *nmonomials) );
1132  SCIP_CALL( SCIPreallocBufferArray(scip, monomialexps, *nmonomials) );
1133  SCIP_CALL( SCIPreallocBufferArray(scip, monomialnvars, *nmonomials) );
1134  SCIP_CALL( SCIPreallocBufferArray(scip, monomialcoefs, *nmonomials) );
1135 
1136  /* SCIPwriteVarsPolynomial(scip, NULL, *monomialvars, *monomialexps, *monomialcoefs, *monomialnvars, *nmonomials, FALSE); */
1137  }
1138  else
1139  {
1140  /* in case of error, cleanup all data here */
1141  SCIPfreeParseVarsPolynomialData(scip, monomialvars, monomialexps, monomialcoefs, monomialnvars, *nmonomials);
1142  *nmonomials = 0;
1143  }
1144 
1145  return SCIP_OKAY;
1146 }
1147 
1148 /** frees memory allocated when parsing a polynomial from a string
1149  *
1150  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1151  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1152  *
1153  * @pre This method can be called if @p scip is in one of the following stages:
1154  * - \ref SCIP_STAGE_PROBLEM
1155  * - \ref SCIP_STAGE_TRANSFORMING
1156  * - \ref SCIP_STAGE_INITPRESOLVE
1157  * - \ref SCIP_STAGE_PRESOLVING
1158  * - \ref SCIP_STAGE_EXITPRESOLVE
1159  * - \ref SCIP_STAGE_PRESOLVED
1160  * - \ref SCIP_STAGE_SOLVING
1161  */
1163  SCIP* scip, /**< SCIP data structure */
1164  SCIP_VAR**** monomialvars, /**< pointer to store arrays with variables for each monomial */
1165  SCIP_Real*** monomialexps, /**< pointer to store arrays with variable exponents */
1166  SCIP_Real** monomialcoefs, /**< pointer to store array with monomial coefficients */
1167  int** monomialnvars, /**< pointer to store array with number of variables for each monomial */
1168  int nmonomials /**< pointer to store number of parsed monomials */
1169  )
1170 {
1171  int i;
1172 
1173  assert(scip != NULL);
1174  assert(monomialvars != NULL);
1175  assert(monomialexps != NULL);
1176  assert(monomialcoefs != NULL);
1177  assert(monomialnvars != NULL);
1178  assert((*monomialvars != NULL) == (nmonomials > 0));
1179  assert((*monomialexps != NULL) == (nmonomials > 0));
1180  assert((*monomialcoefs != NULL) == (nmonomials > 0));
1181  assert((*monomialnvars != NULL) == (nmonomials > 0));
1182 
1183  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPfreeParseVarsPolynomialData", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1184 
1185  if( nmonomials == 0 )
1186  return;
1187 
1188  for( i = nmonomials - 1; i >= 0; --i )
1189  {
1190  SCIPfreeBufferArrayNull(scip, &(*monomialexps)[i]);
1191  SCIPfreeBufferArrayNull(scip, &(*monomialvars)[i]);
1192  }
1193 
1194  SCIPfreeBufferArray(scip, monomialcoefs);
1195  SCIPfreeBufferArray(scip, monomialnvars);
1196  SCIPfreeBufferArray(scip, monomialexps);
1197  SCIPfreeBufferArray(scip, monomialvars);
1198 }
1199 
1200 /** increases usage counter of variable
1201  *
1202  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1203  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1204  *
1205  * @pre This method can be called if @p scip is in one of the following stages:
1206  * - \ref SCIP_STAGE_PROBLEM
1207  * - \ref SCIP_STAGE_TRANSFORMING
1208  * - \ref SCIP_STAGE_TRANSFORMED
1209  * - \ref SCIP_STAGE_INITPRESOLVE
1210  * - \ref SCIP_STAGE_PRESOLVING
1211  * - \ref SCIP_STAGE_EXITPRESOLVE
1212  * - \ref SCIP_STAGE_PRESOLVED
1213  * - \ref SCIP_STAGE_INITSOLVE
1214  * - \ref SCIP_STAGE_SOLVING
1215  * - \ref SCIP_STAGE_SOLVED
1216  * - \ref SCIP_STAGE_EXITSOLVE
1217  */
1219  SCIP* scip, /**< SCIP data structure */
1220  SCIP_VAR* var /**< variable to capture */
1221  )
1222 {
1223  SCIP_CALL( SCIPcheckStage(scip, "SCIPcaptureVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1224  assert(var->scip == scip);
1225 
1226  SCIPvarCapture(var);
1227 
1228  return SCIP_OKAY;
1229 }
1230 
1231 /** decreases usage counter of variable, if the usage pointer reaches zero the variable gets freed
1232  *
1233  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1234  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1235  *
1236  * @pre This method can be called if @p scip is in one of the following stages:
1237  * - \ref SCIP_STAGE_PROBLEM
1238  * - \ref SCIP_STAGE_TRANSFORMING
1239  * - \ref SCIP_STAGE_TRANSFORMED
1240  * - \ref SCIP_STAGE_INITPRESOLVE
1241  * - \ref SCIP_STAGE_PRESOLVING
1242  * - \ref SCIP_STAGE_EXITPRESOLVE
1243  * - \ref SCIP_STAGE_PRESOLVED
1244  * - \ref SCIP_STAGE_INITSOLVE
1245  * - \ref SCIP_STAGE_SOLVING
1246  * - \ref SCIP_STAGE_SOLVED
1247  * - \ref SCIP_STAGE_EXITSOLVE
1248  * - \ref SCIP_STAGE_FREETRANS
1249  *
1250  * @note the pointer of the variable will be NULLed
1251  */
1253  SCIP* scip, /**< SCIP data structure */
1254  SCIP_VAR** var /**< pointer to variable */
1255  )
1256 {
1257  assert(var != NULL);
1258  assert(*var != NULL);
1259  assert((*var)->scip == scip);
1260 
1261  SCIP_CALL( SCIPcheckStage(scip, "SCIPreleaseVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1262 
1263  switch( scip->set->stage )
1264  {
1265  case SCIP_STAGE_PROBLEM:
1266  SCIP_CALL( SCIPvarRelease(var, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp) );
1267  return SCIP_OKAY;
1268 
1272  case SCIP_STAGE_PRESOLVING:
1274  case SCIP_STAGE_PRESOLVED:
1275  case SCIP_STAGE_INITSOLVE:
1276  case SCIP_STAGE_SOLVING:
1277  case SCIP_STAGE_SOLVED:
1278  case SCIP_STAGE_EXITSOLVE:
1279  case SCIP_STAGE_FREETRANS:
1280  if( !SCIPvarIsTransformed(*var) && (*var)->nuses == 1 )
1281  {
1282  SCIPerrorMessage("cannot release last use of original variable while the transformed problem exists\n");
1283  return SCIP_INVALIDCALL;
1284  }
1285  SCIP_CALL( SCIPvarRelease(var, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp) );
1286  return SCIP_OKAY;
1287 
1288  default:
1289  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
1290  return SCIP_INVALIDCALL;
1291  } /*lint !e788*/
1292 }
1293 
1294 /** changes the name of a variable
1295  *
1296  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1297  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1298  *
1299  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PROBLEM
1300  *
1301  * @note to get the current name of a variable, use SCIPvarGetName() from pub_var.h
1302  */
1304  SCIP* scip, /**< SCIP data structure */
1305  SCIP_VAR* var, /**< variable */
1306  const char* name /**< new name of constraint */
1307  )
1308 {
1309  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarName", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
1310  assert( var->scip == scip );
1311 
1312  if( SCIPgetStage(scip) != SCIP_STAGE_PROBLEM )
1313  {
1314  SCIPerrorMessage("variable names can only be changed in problem creation stage\n");
1315  SCIPABORT();
1316  return SCIP_INVALIDCALL; /*lint !e527*/
1317  }
1318 
1319  /* remove variable's name from the namespace if the variable was already added */
1320  if( SCIPvarGetProbindex(var) != -1 )
1321  {
1322  SCIP_CALL( SCIPprobRemoveVarName(scip->origprob, var) );
1323  }
1324 
1325  /* change variable name */
1326  SCIP_CALL( SCIPvarChgName(var, SCIPblkmem(scip), name) );
1327 
1328  /* add variable's name to the namespace if the variable was already added */
1329  if( SCIPvarGetProbindex(var) != -1 )
1330  {
1331  SCIP_CALL( SCIPprobAddVarName(scip->origprob, var) );
1332  }
1333 
1334  return SCIP_OKAY;
1335 }
1336 
1337 /** gets and captures transformed variable of a given variable; if the variable is not yet transformed,
1338  * a new transformed variable for this variable is created
1339  *
1340  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1341  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1342  *
1343  * @pre This method can be called if @p scip is in one of the following stages:
1344  * - \ref SCIP_STAGE_TRANSFORMING
1345  * - \ref SCIP_STAGE_TRANSFORMED
1346  * - \ref SCIP_STAGE_INITPRESOLVE
1347  * - \ref SCIP_STAGE_PRESOLVING
1348  * - \ref SCIP_STAGE_EXITPRESOLVE
1349  * - \ref SCIP_STAGE_PRESOLVED
1350  * - \ref SCIP_STAGE_INITSOLVE
1351  * - \ref SCIP_STAGE_SOLVING
1352  */
1354  SCIP* scip, /**< SCIP data structure */
1355  SCIP_VAR* var, /**< variable to get/create transformed variable for */
1356  SCIP_VAR** transvar /**< pointer to store the transformed variable */
1357  )
1358 {
1359  assert(transvar != NULL);
1360 
1361  SCIP_CALL( SCIPcheckStage(scip, "SCIPtransformVar", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1362 
1363  if( SCIPvarIsTransformed(var) )
1364  {
1365  *transvar = var;
1366  SCIPvarCapture(*transvar);
1367  }
1368  else
1369  {
1370  SCIP_CALL( SCIPvarTransform(var, scip->mem->probmem, scip->set, scip->stat, scip->origprob->objsense, transvar) );
1371  }
1372 
1373  return SCIP_OKAY;
1374 }
1375 
1376 /** gets and captures transformed variables for an array of variables;
1377  * if a variable of the array is not yet transformed, a new transformed variable for this variable is created;
1378  * it is possible to call this method with vars == transvars
1379  *
1380  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1381  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1382  *
1383  * @pre This method can be called if @p scip is in one of the following stages:
1384  * - \ref SCIP_STAGE_TRANSFORMING
1385  * - \ref SCIP_STAGE_TRANSFORMED
1386  * - \ref SCIP_STAGE_INITPRESOLVE
1387  * - \ref SCIP_STAGE_PRESOLVING
1388  * - \ref SCIP_STAGE_EXITPRESOLVE
1389  * - \ref SCIP_STAGE_PRESOLVED
1390  * - \ref SCIP_STAGE_INITSOLVE
1391  * - \ref SCIP_STAGE_SOLVING
1392  */
1394  SCIP* scip, /**< SCIP data structure */
1395  int nvars, /**< number of variables to get/create transformed variables for */
1396  SCIP_VAR** vars, /**< array with variables to get/create transformed variables for */
1397  SCIP_VAR** transvars /**< array to store the transformed variables */
1398  )
1399 {
1400  int v;
1401 
1402  assert(nvars == 0 || vars != NULL);
1403  assert(nvars == 0 || transvars != NULL);
1404 
1405  SCIP_CALL( SCIPcheckStage(scip, "SCIPtransformVars", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1406 
1407  for( v = 0; v < nvars; ++v )
1408  {
1409  if( SCIPvarIsTransformed(vars[v]) )
1410  {
1411  transvars[v] = vars[v];
1412  SCIPvarCapture(transvars[v]);
1413  }
1414  else
1415  {
1416  SCIP_CALL( SCIPvarTransform(vars[v], scip->mem->probmem, scip->set, scip->stat, scip->origprob->objsense,
1417  &transvars[v]) );
1418  }
1419  }
1420 
1421  return SCIP_OKAY;
1422 }
1423 
1424 /** gets corresponding transformed variable of a given variable;
1425  * returns NULL as transvar, if transformed variable is not yet existing
1426  *
1427  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1428  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1429  *
1430  * @pre This method can be called if @p scip is in one of the following stages:
1431  * - \ref SCIP_STAGE_TRANSFORMING
1432  * - \ref SCIP_STAGE_TRANSFORMED
1433  * - \ref SCIP_STAGE_INITPRESOLVE
1434  * - \ref SCIP_STAGE_PRESOLVING
1435  * - \ref SCIP_STAGE_EXITPRESOLVE
1436  * - \ref SCIP_STAGE_PRESOLVED
1437  * - \ref SCIP_STAGE_INITSOLVE
1438  * - \ref SCIP_STAGE_SOLVING
1439  * - \ref SCIP_STAGE_SOLVED
1440  * - \ref SCIP_STAGE_EXITSOLVE
1441  * - \ref SCIP_STAGE_FREETRANS
1442  */
1444  SCIP* scip, /**< SCIP data structure */
1445  SCIP_VAR* var, /**< variable to get transformed variable for */
1446  SCIP_VAR** transvar /**< pointer to store the transformed variable */
1447  )
1448 {
1449  assert(transvar != NULL);
1450 
1451  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetTransformedVar", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1452 
1453  if( SCIPvarIsTransformed(var) )
1454  *transvar = var;
1455  else
1456  {
1457  SCIP_CALL( SCIPvarGetTransformed(var, scip->mem->probmem, scip->set, scip->stat, transvar) );
1458  }
1459 
1460  return SCIP_OKAY;
1461 }
1462 
1463 /** gets corresponding transformed variables for an array of variables;
1464  * stores NULL in a transvars slot, if the transformed variable is not yet existing;
1465  * it is possible to call this method with vars == transvars, but remember that variables that are not
1466  * yet transformed will be replaced with NULL
1467  *
1468  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1469  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1470  *
1471  * @pre This method can be called if @p scip is in one of the following stages:
1472  * - \ref SCIP_STAGE_TRANSFORMING
1473  * - \ref SCIP_STAGE_TRANSFORMED
1474  * - \ref SCIP_STAGE_INITPRESOLVE
1475  * - \ref SCIP_STAGE_PRESOLVING
1476  * - \ref SCIP_STAGE_EXITPRESOLVE
1477  * - \ref SCIP_STAGE_PRESOLVED
1478  * - \ref SCIP_STAGE_INITSOLVE
1479  * - \ref SCIP_STAGE_SOLVING
1480  * - \ref SCIP_STAGE_SOLVED
1481  * - \ref SCIP_STAGE_EXITSOLVE
1482  * - \ref SCIP_STAGE_FREETRANS
1483  */
1485  SCIP* scip, /**< SCIP data structure */
1486  int nvars, /**< number of variables to get transformed variables for */
1487  SCIP_VAR** vars, /**< array with variables to get transformed variables for */
1488  SCIP_VAR** transvars /**< array to store the transformed variables */
1489  )
1490 {
1491  int v;
1492 
1493  assert(nvars == 0 || vars != NULL);
1494  assert(nvars == 0 || transvars != NULL);
1495 
1496  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetTransformedVars", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1497 
1498  for( v = 0; v < nvars; ++v )
1499  {
1500  if( SCIPvarIsTransformed(vars[v]) )
1501  transvars[v] = vars[v];
1502  else
1503  {
1504  SCIP_CALL( SCIPvarGetTransformed(vars[v], scip->mem->probmem, scip->set, scip->stat, &transvars[v]) );
1505  }
1506  }
1507 
1508  return SCIP_OKAY;
1509 }
1510 
1511 /** gets negated variable x' = lb + ub - x of variable x; negated variable is created, if not yet existing;
1512  * in difference to \ref SCIPcreateVar, the negated variable must not be released (unless captured explicitly)
1513  *
1514  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1515  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1516  *
1517  * @pre This method can be called if @p scip is in one of the following stages:
1518  * - \ref SCIP_STAGE_PROBLEM
1519  * - \ref SCIP_STAGE_TRANSFORMING
1520  * - \ref SCIP_STAGE_TRANSFORMED
1521  * - \ref SCIP_STAGE_INITPRESOLVE
1522  * - \ref SCIP_STAGE_PRESOLVING
1523  * - \ref SCIP_STAGE_EXITPRESOLVE
1524  * - \ref SCIP_STAGE_PRESOLVED
1525  * - \ref SCIP_STAGE_INITSOLVE
1526  * - \ref SCIP_STAGE_SOLVING
1527  * - \ref SCIP_STAGE_SOLVED
1528  * - \ref SCIP_STAGE_EXITSOLVE
1529  * - \ref SCIP_STAGE_FREETRANS
1530  */
1532  SCIP* scip, /**< SCIP data structure */
1533  SCIP_VAR* var, /**< variable to get negated variable for */
1534  SCIP_VAR** negvar /**< pointer to store the negated variable */
1535  )
1536 {
1537  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNegatedVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1538  assert( var->scip == scip );
1539 
1540  SCIP_CALL( SCIPvarNegate(var, scip->mem->probmem, scip->set, scip->stat, negvar) );
1541 
1542  return SCIP_OKAY;
1543 }
1544 
1545 /** gets negated variables x' = lb + ub - x of variables x; negated variables are created, if not yet existing
1546  *
1547  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1548  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1549  *
1550  * @pre This method can be called if @p scip is in one of the following stages:
1551  * - \ref SCIP_STAGE_PROBLEM
1552  * - \ref SCIP_STAGE_TRANSFORMING
1553  * - \ref SCIP_STAGE_TRANSFORMED
1554  * - \ref SCIP_STAGE_INITPRESOLVE
1555  * - \ref SCIP_STAGE_PRESOLVING
1556  * - \ref SCIP_STAGE_EXITPRESOLVE
1557  * - \ref SCIP_STAGE_PRESOLVED
1558  * - \ref SCIP_STAGE_INITSOLVE
1559  * - \ref SCIP_STAGE_SOLVING
1560  * - \ref SCIP_STAGE_SOLVED
1561  * - \ref SCIP_STAGE_EXITSOLVE
1562  * - \ref SCIP_STAGE_FREETRANS
1563  */
1565  SCIP* scip, /**< SCIP data structure */
1566  int nvars, /**< number of variables to get negated variables for */
1567  SCIP_VAR** vars, /**< array of variables to get negated variables for */
1568  SCIP_VAR** negvars /**< array to store the negated variables */
1569  )
1570 {
1571  int v;
1572 
1573  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNegatedVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1574 
1575  for( v = 0; v < nvars; ++v )
1576  {
1577  SCIP_CALL( SCIPvarNegate(vars[v], scip->mem->probmem, scip->set, scip->stat, &(negvars[v])) );
1578  }
1579 
1580  return SCIP_OKAY;
1581 }
1582 
1583 /** gets a binary variable that is equal to the given binary variable, and that is either active, fixed, or
1584  * multi-aggregated, or the negated variable of an active, fixed, or multi-aggregated variable
1585  *
1586  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1587  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1588  *
1589  * @pre This method can be called if @p scip is in one of the following stages:
1590  * - \ref SCIP_STAGE_PROBLEM
1591  * - \ref SCIP_STAGE_TRANSFORMED
1592  * - \ref SCIP_STAGE_INITPRESOLVE
1593  * - \ref SCIP_STAGE_PRESOLVING
1594  * - \ref SCIP_STAGE_EXITPRESOLVE
1595  * - \ref SCIP_STAGE_PRESOLVED
1596  * - \ref SCIP_STAGE_INITSOLVE
1597  * - \ref SCIP_STAGE_SOLVING
1598  * - \ref SCIP_STAGE_SOLVED
1599  * - \ref SCIP_STAGE_EXITSOLVE
1600  */
1602  SCIP* scip, /**< SCIP data structure */
1603  SCIP_VAR* var, /**< binary variable to get binary representative for */
1604  SCIP_VAR** repvar, /**< pointer to store the binary representative */
1605  SCIP_Bool* negated /**< pointer to store whether the negation of an active variable was returned */
1606  )
1607 {
1608  assert(scip != NULL);
1609  assert(var != NULL);
1610  assert(repvar != NULL);
1611  assert(negated != NULL);
1612  assert(var->scip == scip);
1613 
1614  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetBinvarRepresentative", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1615 
1616  /* get the active representative of the given variable */
1617  *repvar = var;
1618  *negated = FALSE;
1619  SCIP_CALL( SCIPvarGetProbvarBinary(repvar, negated) );
1620 
1621  /* negate the representative, if it corresponds to the negation of the given variable */
1622  if( *negated )
1623  {
1624  SCIP_CALL( SCIPgetNegatedVar(scip, *repvar, repvar) );
1625  }
1626 
1627  return SCIP_OKAY;
1628 }
1629 
1630 /** gets binary variables that are equal to the given binary variables, and which are either active, fixed, or
1631  * multi-aggregated, or the negated variables of active, fixed, or multi-aggregated variables
1632  *
1633  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1634  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1635  *
1636  * @pre This method can be called if @p scip is in one of the following stages:
1637  * - \ref SCIP_STAGE_PROBLEM
1638  * - \ref SCIP_STAGE_TRANSFORMED
1639  * - \ref SCIP_STAGE_INITPRESOLVE
1640  * - \ref SCIP_STAGE_PRESOLVING
1641  * - \ref SCIP_STAGE_EXITPRESOLVE
1642  * - \ref SCIP_STAGE_PRESOLVED
1643  * - \ref SCIP_STAGE_INITSOLVE
1644  * - \ref SCIP_STAGE_SOLVING
1645  * - \ref SCIP_STAGE_SOLVED
1646  * - \ref SCIP_STAGE_EXITSOLVE
1647  */
1649  SCIP* scip, /**< SCIP data structure */
1650  int nvars, /**< number of binary variables to get representatives for */
1651  SCIP_VAR** vars, /**< binary variables to get binary representatives for */
1652  SCIP_VAR** repvars, /**< array to store the binary representatives */
1653  SCIP_Bool* negated /**< array to store whether the negation of an active variable was returned */
1654  )
1655 {
1656  int v;
1657 
1658  assert(scip != NULL);
1659  assert(vars != NULL || nvars == 0);
1660  assert(repvars != NULL || nvars == 0);
1661  assert(negated != NULL || nvars == 0);
1662 
1663  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetBinvarRepresentatives", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1664 
1665  if( nvars == 0 )
1666  return SCIP_OKAY;
1667 
1668  /* get the active representative of the given variable */
1669  BMScopyMemoryArray(repvars, vars, nvars);
1670  BMSclearMemoryArray(negated, nvars);
1671  SCIP_CALL( SCIPvarsGetProbvarBinary(&repvars, &negated, nvars) );
1672 
1673  /* negate the representatives, if they correspond to the negation of the given variables */
1674  for( v = nvars - 1; v >= 0; --v )
1675  if( negated[v] )
1676  {
1677  SCIP_CALL( SCIPgetNegatedVar(scip, repvars[v], &(repvars[v])) );
1678  }
1679 
1680  return SCIP_OKAY;
1681 }
1682 
1683 /** flattens aggregation graph of multi-aggregated variable in order to avoid exponential recursion later on
1684  *
1685  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1686  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1687  *
1688  * @pre This method can be called if @p scip is in one of the following stages:
1689  * - \ref SCIP_STAGE_INITPRESOLVE
1690  * - \ref SCIP_STAGE_PRESOLVING
1691  * - \ref SCIP_STAGE_EXITPRESOLVE
1692  * - \ref SCIP_STAGE_PRESOLVED
1693  * - \ref SCIP_STAGE_INITSOLVE
1694  * - \ref SCIP_STAGE_SOLVING
1695  * - \ref SCIP_STAGE_SOLVED
1696  */
1698  SCIP* scip, /**< SCIP data structure */
1699  SCIP_VAR* var /**< problem variable */
1700  )
1701 {
1702  assert( scip != NULL );
1703  assert( var != NULL );
1704  SCIP_CALL( SCIPcheckStage(scip, "SCIPflattenVarAggregationGraph", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
1705 
1706  SCIP_CALL( SCIPvarFlattenAggregationGraph(var, scip->mem->probmem, scip->set, scip->eventqueue) );
1707 
1708  return SCIP_OKAY;
1709 }
1710 
1711 /** Transforms a given linear sum of variables, that is a_1*x_1 + ... + a_n*x_n + c into a corresponding linear sum of
1712  * active variables, that is b_1*y_1 + ... + b_m*y_m + d.
1713  *
1714  * If the number of needed active variables is greater than the available slots in the variable array, nothing happens
1715  * except that the required size is stored in the corresponding variable (requiredsize). Otherwise, the active variable
1716  * representation is stored in the variable array, scalar array and constant.
1717  *
1718  * The reason for this approach is that we cannot reallocate memory, since we do not know how the memory has been
1719  * allocated (e.g., by a C++ 'new' or SCIP functions).
1720  *
1721  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1722  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1723  *
1724  * @pre This method can be called if @p scip is in one of the following stages:
1725  * - \ref SCIP_STAGE_TRANSFORMED
1726  * - \ref SCIP_STAGE_INITPRESOLVE
1727  * - \ref SCIP_STAGE_PRESOLVING
1728  * - \ref SCIP_STAGE_EXITPRESOLVE
1729  * - \ref SCIP_STAGE_PRESOLVED
1730  * - \ref SCIP_STAGE_INITSOLVE
1731  * - \ref SCIP_STAGE_SOLVING
1732  * - \ref SCIP_STAGE_SOLVED
1733  * - \ref SCIP_STAGE_EXITSOLVE
1734  * - \ref SCIP_STAGE_FREETRANS
1735  *
1736  * @note The resulting linear sum is stored into the given variable array, scalar array, and constant. That means the
1737  * given entries are overwritten.
1738  *
1739  * @note That method can be used to convert a single variables into variable space of active variables. Therefore call
1740  * the method with the linear sum 1.0*x + 0.0.
1741  */
1743  SCIP* scip, /**< SCIP data structure */
1744  SCIP_VAR** vars, /**< variable array x_1, ..., x_n in the linear sum which will be
1745  * overwritten by the variable array y_1, ..., y_m in the linear sum
1746  * w.r.t. active variables */
1747  SCIP_Real* scalars, /**< scalars a_1, ..., a_n in linear sum which will be overwritten to the
1748  * scalars b_1, ..., b_m in the linear sum of the active variables */
1749  int* nvars, /**< pointer to number of variables in the linear sum which will be
1750  * overwritten by the number of variables in the linear sum corresponding
1751  * to the active variables */
1752  int varssize, /**< available slots in vars and scalars array which is needed to check if
1753  * the array are large enough for the linear sum w.r.t. active
1754  * variables */
1755  SCIP_Real* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c which
1756  * will chnage to constant d in the linear sum b_1*y_1 + ... + b_m*y_m +
1757  * d w.r.t. the active variables */
1758  int* requiredsize, /**< pointer to store the required array size for the linear sum w.r.t. the
1759  * active variables */
1760  SCIP_Bool mergemultiples /**< should multiple occurrences of a var be replaced by a single coeff? */
1761  )
1762 {
1763  assert( scip != NULL );
1764  assert( nvars != NULL );
1765  assert( vars != NULL || *nvars == 0 );
1766  assert( scalars != NULL || *nvars == 0 );
1767  assert( constant != NULL );
1768  assert( requiredsize != NULL );
1769  assert( *nvars <= varssize );
1770 
1771  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetProbvarLinearSum", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1772  SCIP_CALL( SCIPvarGetActiveRepresentatives(scip->set, vars, scalars, nvars, varssize, constant, requiredsize, mergemultiples) );
1773 
1774  return SCIP_OKAY;
1775 }
1776 
1777 /** transforms given variable, scalar and constant to the corresponding active, fixed, or
1778  * multi-aggregated variable, scalar and constant; if the variable resolves to a fixed variable,
1779  * "scalar" will be 0.0 and the value of the sum will be stored in "constant"; a multi-aggregation
1780  * with only one active variable (this can happen due to fixings after the multi-aggregation),
1781  * is treated like an aggregation; if the multi-aggregation constant is infinite, "scalar" will be 0.0
1782  *
1783  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1784  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1785  *
1786  * @pre This method can be called if @p scip is in one of the following stages:
1787  * - \ref SCIP_STAGE_TRANSFORMED
1788  * - \ref SCIP_STAGE_INITPRESOLVE
1789  * - \ref SCIP_STAGE_PRESOLVING
1790  * - \ref SCIP_STAGE_EXITPRESOLVE
1791  * - \ref SCIP_STAGE_PRESOLVED
1792  * - \ref SCIP_STAGE_INITSOLVE
1793  * - \ref SCIP_STAGE_SOLVING
1794  * - \ref SCIP_STAGE_SOLVED
1795  * - \ref SCIP_STAGE_EXITSOLVE
1796  * - \ref SCIP_STAGE_FREETRANS
1797  */
1799  SCIP* scip, /**< SCIP data structure */
1800  SCIP_VAR** var, /**< pointer to problem variable x in sum a*x + c */
1801  SCIP_Real* scalar, /**< pointer to scalar a in sum a*x + c */
1802  SCIP_Real* constant /**< pointer to constant c in sum a*x + c */
1803  )
1804 {
1805  assert(scip != NULL);
1806  assert(var != NULL);
1807  assert(scalar != NULL);
1808  assert(constant != NULL);
1809 
1810  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetProbvarSum", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1811  SCIP_CALL( SCIPvarGetProbvarSum(var, scip->set, scalar, constant) );
1812 
1813  return SCIP_OKAY;
1814 }
1815 
1816 /** return for given variables all their active counterparts; all active variables will be pairwise different
1817  * @note It does not hold that the first output variable is the active variable for the first input variable.
1818  *
1819  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1820  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1821  *
1822  * @pre This method can be called if @p scip is in one of the following stages:
1823  * - \ref SCIP_STAGE_TRANSFORMED
1824  * - \ref SCIP_STAGE_INITPRESOLVE
1825  * - \ref SCIP_STAGE_PRESOLVING
1826  * - \ref SCIP_STAGE_EXITPRESOLVE
1827  * - \ref SCIP_STAGE_PRESOLVED
1828  * - \ref SCIP_STAGE_INITSOLVE
1829  * - \ref SCIP_STAGE_SOLVING
1830  * - \ref SCIP_STAGE_SOLVED
1831  * - \ref SCIP_STAGE_EXITSOLVE
1832  * - \ref SCIP_STAGE_FREETRANS
1833  */
1835  SCIP* scip, /**< SCIP data structure */
1836  SCIP_VAR** vars, /**< variable array with given variables and as output all active
1837  * variables, if enough slots exist
1838  */
1839  int* nvars, /**< number of given variables, and as output number of active variables,
1840  * if enough slots exist
1841  */
1842  int varssize, /**< available slots in vars array */
1843  int* requiredsize /**< pointer to store the required array size for the active variables */
1844  )
1845 {
1846  assert(scip != NULL);
1847  assert(nvars != NULL);
1848  assert(vars != NULL || *nvars == 0);
1849  assert(varssize >= *nvars);
1850  assert(requiredsize != NULL);
1851 
1852  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetActiveVars", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1853  SCIP_CALL( SCIPvarsGetActiveVars(scip->set, vars, nvars, varssize, requiredsize) );
1854 
1855  return SCIP_OKAY;
1856 }
1857 
1858 /** returns the reduced costs of the variable in the current node's LP relaxation;
1859  * the current node has to have a feasible LP.
1860  *
1861  * returns SCIP_INVALID if the variable is active but not in the current LP;
1862  * returns 0 if the variable has been aggregated out or fixed in presolving.
1863  *
1864  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1865  *
1866  * @note The return value of this method should be used carefully if the dual feasibility check was explictely disabled.
1867  */
1869  SCIP* scip, /**< SCIP data structure */
1870  SCIP_VAR* var /**< variable to get reduced costs, should be a column in current node LP */
1871  )
1872 {
1873  assert( scip != NULL );
1874  assert( var != NULL );
1875  assert( var->scip == scip );
1876 
1877  switch( SCIPvarGetStatus(var) )
1878  {
1880  if( var->data.original.transvar == NULL )
1881  return SCIP_INVALID;
1882  return SCIPgetVarRedcost(scip, var->data.original.transvar);
1883 
1884  case SCIP_VARSTATUS_COLUMN:
1885  return SCIPgetColRedcost(scip, SCIPvarGetCol(var));
1886 
1887  case SCIP_VARSTATUS_LOOSE:
1888  return SCIP_INVALID;
1889 
1890  case SCIP_VARSTATUS_FIXED:
1894  return 0.0;
1895 
1896  default:
1897  SCIPerrorMessage("unknown variable status\n");
1898  SCIPABORT();
1899  return 0.0; /*lint !e527*/
1900  }
1901 }
1902 
1903 /** returns the implied reduced costs of the variable in the current node's LP relaxation;
1904  * the current node has to have a feasible LP.
1905  *
1906  * returns SCIP_INVALID if the variable is active but not in the current LP;
1907  * returns 0 if the variable has been aggregated out or fixed in presolving.
1908  *
1909  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1910  *
1911  * @note The return value of this method should be used carefully if the dual feasibility check was explictely disabled.
1912  */
1914  SCIP* scip, /**< SCIP data structure */
1915  SCIP_VAR* var, /**< variable to get reduced costs, should be a column in current node LP */
1916  SCIP_Bool varfixing /**< FALSE if for x == 0, TRUE for x == 1 */
1917  )
1918 {
1919  assert( scip != NULL );
1920  assert( var != NULL );
1921  assert( var->scip == scip );
1922 
1923  switch( SCIPvarGetStatus(var) )
1924  {
1926  if( var->data.original.transvar == NULL )
1927  return SCIP_INVALID;
1928  return SCIPgetVarImplRedcost(scip, var->data.original.transvar, varfixing);
1929 
1930  case SCIP_VARSTATUS_COLUMN:
1931  return SCIPvarGetImplRedcost(var, scip->set, varfixing, scip->stat, scip->transprob, scip->lp);
1932 
1933  case SCIP_VARSTATUS_LOOSE:
1934  return SCIP_INVALID;
1935 
1936  case SCIP_VARSTATUS_FIXED:
1940  return 0.0;
1941 
1942  default:
1943  SCIPerrorMessage("unknown variable status\n");
1944  SCIPABORT();
1945  return 0.0; /*lint !e527*/
1946  }
1947 }
1948 
1949 
1950 /** returns the Farkas coefficient of the variable in the current node's LP relaxation;
1951  * the current node has to have an infeasible LP.
1952  *
1953  * returns SCIP_INVALID if the variable is active but not in the current LP;
1954  * returns 0 if the variable has been aggregated out or fixed in presolving.
1955  *
1956  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1957  */
1959  SCIP* scip, /**< SCIP data structure */
1960  SCIP_VAR* var /**< variable to get reduced costs, should be a column in current node LP */
1961  )
1962 {
1963  assert(scip != NULL);
1964  assert(var != NULL);
1965  assert(var->scip == scip);
1966 
1967  switch( SCIPvarGetStatus(var) )
1968  {
1970  if( var->data.original.transvar == NULL )
1971  return SCIP_INVALID;
1972  return SCIPgetVarFarkasCoef(scip,var->data.original.transvar);
1973 
1974  case SCIP_VARSTATUS_COLUMN:
1975  return SCIPgetColFarkasCoef(scip,SCIPvarGetCol(var));
1976 
1977  case SCIP_VARSTATUS_LOOSE:
1978  return SCIP_INVALID;
1979 
1980  case SCIP_VARSTATUS_FIXED:
1984  return 0.0;
1985 
1986  default:
1987  SCIPerrorMessage("unknown variable status\n");
1988  SCIPABORT();
1989  return 0.0; /*lint !e527*/
1990  }
1991 }
1992 
1993 /** returns lower bound of variable directly before or after the bound change given by the bound change index
1994  * was applied
1995  */
1997  SCIP* scip, /**< SCIP data structure */
1998  SCIP_VAR* var, /**< problem variable */
1999  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2000  SCIP_Bool after /**< should the bound change with given index be included? */
2001  )
2002 {
2003  SCIP_VARSTATUS varstatus;
2004  SCIP_BDCHGINFO* bdchginfo;
2005  assert(var != NULL);
2006 
2007  varstatus = SCIPvarGetStatus(var);
2008 
2009  /* get bounds of attached variables */
2010  switch( varstatus )
2011  {
2013  assert(var->data.original.transvar != NULL);
2014  return SCIPgetVarLbAtIndex(scip, var->data.original.transvar, bdchgidx, after);
2015 
2016  case SCIP_VARSTATUS_COLUMN:
2017  case SCIP_VARSTATUS_LOOSE:
2018  if( bdchgidx == NULL )
2019  return SCIPvarGetLbLocal(var);
2020  else
2021  {
2022  bdchginfo = SCIPvarGetLbchgInfo(var, bdchgidx, after);
2023  if( bdchginfo != NULL )
2024  return SCIPbdchginfoGetNewbound(bdchginfo);
2025  else
2026  return var->glbdom.lb;
2027  }
2028 
2029  case SCIP_VARSTATUS_FIXED:
2030  return var->glbdom.lb;
2031 
2032  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c -> y = (x-c)/a */
2033  assert(var->data.aggregate.var != NULL);
2034  if( var->data.aggregate.scalar > 0.0 )
2035  {
2036  SCIP_Real lb;
2037 
2038  lb = SCIPgetVarLbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2039 
2040  /* a > 0 -> get lower bound of y */
2041  if( SCIPisInfinity(scip, -lb) )
2042  return -SCIPinfinity(scip);
2043  else if( SCIPisInfinity(scip, lb) )
2044  return SCIPinfinity(scip);
2045  else
2046  return var->data.aggregate.scalar * lb + var->data.aggregate.constant;
2047  }
2048  else if( var->data.aggregate.scalar < 0.0 )
2049  {
2050  SCIP_Real ub;
2051 
2052  ub = SCIPgetVarUbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2053 
2054  /* a < 0 -> get upper bound of y */
2055  if( SCIPisInfinity(scip, -ub) )
2056  return SCIPinfinity(scip);
2057  else if( SCIPisInfinity(scip, ub) )
2058  return -SCIPinfinity(scip);
2059  else
2060  return var->data.aggregate.scalar * ub + var->data.aggregate.constant;
2061  }
2062  else
2063  {
2064  SCIPerrorMessage("scalar is zero in aggregation\n");
2065  SCIPABORT();
2066  return SCIP_INVALID; /*lint !e527*/
2067  }
2068 
2070  /* handle multi-aggregated variables depending on one variable only (possibly caused by SCIPvarFlattenAggregationGraph()) */
2071  if ( var->data.multaggr.nvars == 1 )
2072  {
2073  assert(var->data.multaggr.vars != NULL);
2074  assert(var->data.multaggr.scalars != NULL);
2075  assert(var->data.multaggr.vars[0] != NULL);
2076 
2077  if( var->data.multaggr.scalars[0] > 0.0 )
2078  {
2079  SCIP_Real lb;
2080 
2081  lb = SCIPgetVarLbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2082 
2083  /* a > 0 -> get lower bound of y */
2084  if( SCIPisInfinity(scip, -lb) )
2085  return -SCIPinfinity(scip);
2086  else if( SCIPisInfinity(scip, lb) )
2087  return SCIPinfinity(scip);
2088  else
2089  return var->data.multaggr.scalars[0] * lb + var->data.multaggr.constant;
2090  }
2091  else if( var->data.multaggr.scalars[0] < 0.0 )
2092  {
2093  SCIP_Real ub;
2094 
2095  ub = SCIPgetVarUbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2096 
2097  /* a < 0 -> get upper bound of y */
2098  if( SCIPisInfinity(scip, -ub) )
2099  return SCIPinfinity(scip);
2100  else if( SCIPisInfinity(scip, ub) )
2101  return -SCIPinfinity(scip);
2102  else
2103  return var->data.multaggr.scalars[0] * ub + var->data.multaggr.constant;
2104  }
2105  else
2106  {
2107  SCIPerrorMessage("scalar is zero in multi-aggregation\n");
2108  SCIPABORT();
2109  return SCIP_INVALID; /*lint !e527*/
2110  }
2111  }
2112  SCIPerrorMessage("cannot get the bounds of a multi-aggregated variable.\n");
2113  SCIPABORT();
2114  return SCIP_INVALID; /*lint !e527*/
2115 
2116  case SCIP_VARSTATUS_NEGATED: /* x' = offset - x -> x = offset - x' */
2117  assert(var->negatedvar != NULL);
2119  assert(var->negatedvar->negatedvar == var);
2120  return var->data.negate.constant - SCIPgetVarUbAtIndex(scip, var->negatedvar, bdchgidx, after);
2121 
2122  default:
2123  SCIPerrorMessage("unknown variable status\n");
2124  SCIPABORT();
2125  return SCIP_INVALID; /*lint !e527*/
2126  }
2127 }
2128 
2129 /** returns upper bound of variable directly before or after the bound change given by the bound change index
2130  * was applied
2131  */
2133  SCIP* scip, /**< SCIP data structure */
2134  SCIP_VAR* var, /**< problem variable */
2135  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2136  SCIP_Bool after /**< should the bound change with given index be included? */
2137  )
2138 {
2139  SCIP_VARSTATUS varstatus;
2140  SCIP_BDCHGINFO* bdchginfo;
2141  assert(var != NULL);
2142 
2143  varstatus = SCIPvarGetStatus(var);
2144 
2145  /* get bounds of attached variables */
2146  switch( varstatus )
2147  {
2149  assert(var->data.original.transvar != NULL);
2150  return SCIPgetVarUbAtIndex(scip, var->data.original.transvar, bdchgidx, after);
2151 
2152  case SCIP_VARSTATUS_COLUMN:
2153  case SCIP_VARSTATUS_LOOSE:
2154  if( bdchgidx == NULL )
2155  return SCIPvarGetUbLocal(var);
2156  else
2157  {
2158  bdchginfo = SCIPvarGetUbchgInfo(var, bdchgidx, after);
2159  if( bdchginfo != NULL )
2160  return SCIPbdchginfoGetNewbound(bdchginfo);
2161  else
2162  return var->glbdom.ub;
2163  }
2164 
2165  case SCIP_VARSTATUS_FIXED:
2166  return var->glbdom.ub;
2167 
2168  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c -> y = (x-c)/a */
2169  assert(var->data.aggregate.var != NULL);
2170  if( var->data.aggregate.scalar > 0.0 )
2171  {
2172  SCIP_Real ub;
2173 
2174  ub = SCIPgetVarUbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2175 
2176  /* a > 0 -> get lower bound of y */
2177  if( SCIPisInfinity(scip, -ub) )
2178  return -SCIPinfinity(scip);
2179  else if( SCIPisInfinity(scip, ub) )
2180  return SCIPinfinity(scip);
2181  else
2182  return var->data.aggregate.scalar * ub + var->data.aggregate.constant;
2183  }
2184  else if( var->data.aggregate.scalar < 0.0 )
2185  {
2186  SCIP_Real lb;
2187 
2188  lb = SCIPgetVarLbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2189 
2190  /* a < 0 -> get upper bound of y */
2191  if ( SCIPisInfinity(scip, -lb) )
2192  return SCIPinfinity(scip);
2193  else if ( SCIPisInfinity(scip, lb) )
2194  return -SCIPinfinity(scip);
2195  else
2196  return var->data.aggregate.scalar * lb + var->data.aggregate.constant;
2197  }
2198  else
2199  {
2200  SCIPerrorMessage("scalar is zero in aggregation\n");
2201  SCIPABORT();
2202  return SCIP_INVALID; /*lint !e527*/
2203  }
2204 
2206  /* handle multi-aggregated variables depending on one variable only (possibly caused by SCIPvarFlattenAggregationGraph()) */
2207  if ( var->data.multaggr.nvars == 1 )
2208  {
2209  assert(var->data.multaggr.vars != NULL);
2210  assert(var->data.multaggr.scalars != NULL);
2211  assert(var->data.multaggr.vars[0] != NULL);
2212 
2213  if( var->data.multaggr.scalars[0] > 0.0 )
2214  {
2215  SCIP_Real ub;
2216 
2217  ub = SCIPgetVarUbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2218 
2219  /* a > 0 -> get lower bound of y */
2220  if ( SCIPisInfinity(scip, -ub) )
2221  return -SCIPinfinity(scip);
2222  else if ( SCIPisInfinity(scip, ub) )
2223  return SCIPinfinity(scip);
2224  else
2225  return var->data.multaggr.scalars[0] * ub + var->data.multaggr.constant;
2226  }
2227  else if( var->data.multaggr.scalars[0] < 0.0 )
2228  {
2229  SCIP_Real lb;
2230 
2231  lb = SCIPgetVarLbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2232 
2233  /* a < 0 -> get upper bound of y */
2234  if ( SCIPisInfinity(scip, -lb) )
2235  return SCIPinfinity(scip);
2236  else if ( SCIPisInfinity(scip, lb) )
2237  return -SCIPinfinity(scip);
2238  else
2239  return var->data.multaggr.scalars[0] * lb + var->data.multaggr.constant;
2240  }
2241  else
2242  {
2243  SCIPerrorMessage("scalar is zero in multi-aggregation\n");
2244  SCIPABORT();
2245  return SCIP_INVALID; /*lint !e527*/
2246  }
2247  }
2248  SCIPerrorMessage("cannot get the bounds of a multiple aggregated variable.\n");
2249  SCIPABORT();
2250  return SCIP_INVALID; /*lint !e527*/
2251 
2252  case SCIP_VARSTATUS_NEGATED: /* x' = offset - x -> x = offset - x' */
2253  assert(var->negatedvar != NULL);
2255  assert(var->negatedvar->negatedvar == var);
2256  return var->data.negate.constant - SCIPgetVarLbAtIndex(scip, var->negatedvar, bdchgidx, after);
2257 
2258  default:
2259  SCIPerrorMessage("unknown variable status\n");
2260  SCIPABORT();
2261  return SCIP_INVALID; /*lint !e527*/
2262  }
2263 }
2264 
2265 /** returns lower or upper bound of variable directly before or after the bound change given by the bound change index
2266  * was applied
2267  */
2269  SCIP* scip, /**< SCIP data structure */
2270  SCIP_VAR* var, /**< problem variable */
2271  SCIP_BOUNDTYPE boundtype, /**< type of bound: lower or upper bound */
2272  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2273  SCIP_Bool after /**< should the bound change with given index be included? */
2274  )
2275 {
2276  if( boundtype == SCIP_BOUNDTYPE_LOWER )
2277  return SCIPgetVarLbAtIndex(scip, var, bdchgidx, after);
2278  else
2279  {
2280  assert(boundtype == SCIP_BOUNDTYPE_UPPER);
2281  return SCIPgetVarUbAtIndex(scip, var, bdchgidx, after);
2282  }
2283 }
2284 
2285 /** returns whether the binary variable was fixed at the time given by the bound change index */
2287  SCIP* scip, /**< SCIP data structure */
2288  SCIP_VAR* var, /**< problem variable */
2289  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2290  SCIP_Bool after /**< should the bound change with given index be included? */
2291  )
2292 {
2293  assert(var != NULL);
2294  assert(SCIPvarIsBinary(var));
2295 
2296  /* check the current bounds first in order to decide at which bound change information we have to look
2297  * (which is expensive because we have to follow the aggregation tree to the active variable)
2298  */
2299  return ((SCIPvarGetLbLocal(var) > 0.5 && SCIPgetVarLbAtIndex(scip, var, bdchgidx, after) > 0.5)
2300  || (SCIPvarGetUbLocal(var) < 0.5 && SCIPgetVarUbAtIndex(scip, var, bdchgidx, after) < 0.5));
2301 }
2302 
2303 /** gets solution value for variable in current node
2304  *
2305  * @return solution value for variable in current node
2306  *
2307  * @pre This method can be called if @p scip is in one of the following stages:
2308  * - \ref SCIP_STAGE_PRESOLVED
2309  * - \ref SCIP_STAGE_SOLVING
2310  */
2312  SCIP* scip, /**< SCIP data structure */
2313  SCIP_VAR* var /**< variable to get solution value for */
2314  )
2315 {
2317  assert( var->scip == scip );
2318 
2319  return SCIPvarGetSol(var, SCIPtreeHasCurrentNodeLP(scip->tree));
2320 }
2321 
2322 /** gets solution values of multiple variables in current node
2323  *
2324  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2325  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2326  *
2327  * @pre This method can be called if @p scip is in one of the following stages:
2328  * - \ref SCIP_STAGE_PRESOLVED
2329  * - \ref SCIP_STAGE_SOLVING
2330  */
2332  SCIP* scip, /**< SCIP data structure */
2333  int nvars, /**< number of variables to get solution value for */
2334  SCIP_VAR** vars, /**< array with variables to get value for */
2335  SCIP_Real* vals /**< array to store solution values of variables */
2336  )
2337 {
2338  int v;
2339 
2340  assert(nvars == 0 || vars != NULL);
2341  assert(nvars == 0 || vals != NULL);
2342 
2343  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarSols", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2344 
2345  if( SCIPtreeHasCurrentNodeLP(scip->tree) )
2346  {
2347  for( v = 0; v < nvars; ++v )
2348  vals[v] = SCIPvarGetLPSol(vars[v]);
2349  }
2350  else
2351  {
2352  for( v = 0; v < nvars; ++v )
2353  vals[v] = SCIPvarGetPseudoSol(vars[v]);
2354  }
2355 
2356  return SCIP_OKAY;
2357 }
2358 
2359 /** sets the solution value of all variables in the global relaxation solution to zero
2360  *
2361  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2362  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2363  *
2364  * @pre This method can be called if @p scip is in one of the following stages:
2365  * - \ref SCIP_STAGE_PRESOLVED
2366  * - \ref SCIP_STAGE_SOLVING
2367  */
2369  SCIP* scip, /**< SCIP data structure */
2370  SCIP_RELAX* relax /**< relaxator data structure */
2371  )
2372 {
2373  SCIP_VAR** vars;
2374  int nvars;
2375  int v;
2376 
2377  assert(scip != NULL);
2378 
2379  SCIP_CALL( SCIPcheckStage(scip, "SCIPclearRelaxSolVals", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2380 
2381  /* update the responsible relax pointer */
2382  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2383 
2384  /* the relaxation solution is already cleared */
2385  if( SCIPrelaxationIsSolZero(scip->relaxation) )
2386  return SCIP_OKAY;
2387 
2388  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
2389 
2390  for( v = 0; v < nvars; v++ )
2391  {
2392  SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, 0.0, FALSE) );
2393  }
2394 
2395  SCIPrelaxationSetSolObj(scip->relaxation, 0.0);
2397 
2398  return SCIP_OKAY;
2399 }
2400 
2401 /** sets the value of the given variable in the global relaxation solution;
2402  * this solution can be filled by the relaxation handlers and can be used by heuristics and for separation;
2403  * You can use SCIPclearRelaxSolVals() to set all values to zero, initially;
2404  * after setting all solution values, you have to call SCIPmarkRelaxSolValid()
2405  * to inform SCIP that the stored solution is valid
2406  *
2407  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2408  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2409  *
2410  * @pre This method can be called if @p scip is in one of the following stages:
2411  * - \ref SCIP_STAGE_PRESOLVED
2412  * - \ref SCIP_STAGE_SOLVING
2413  *
2414  * @note This method incrementally updates the objective value of the relaxation solution. If the whole solution
2415  * should be updated, using SCIPsetRelaxSolVals() instead or calling SCIPclearRelaxSolVals() before setting
2416  * the first value to reset the solution and the objective value to 0 may help the numerics.
2417  */
2419  SCIP* scip, /**< SCIP data structure */
2420  SCIP_RELAX* relax, /**< relaxator data structure */
2421  SCIP_VAR* var, /**< variable to set value for */
2422  SCIP_Real val /**< solution value of variable */
2423  )
2424 {
2425  assert(scip != NULL);
2426 
2427  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolVal", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2428 
2429  SCIP_CALL( SCIPvarSetRelaxSol(var, scip->set, scip->relaxation, val, TRUE) );
2430 
2431  if( val != 0.0 )
2434  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2435 
2436  return SCIP_OKAY;
2437 }
2438 
2439 /** sets the values of the given variables in the global relaxation solution and informs SCIP about the validity
2440  * and whether the solution can be enforced via linear cuts;
2441  * this solution can be filled by the relaxation handlers and can be used by heuristics and for separation;
2442  * the solution is automatically cleared, s.t. all other variables get value 0.0
2443  *
2444  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2445  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2446  *
2447  * @pre This method can be called if @p scip is in one of the following stages:
2448  * - \ref SCIP_STAGE_PRESOLVED
2449  * - \ref SCIP_STAGE_SOLVING
2450  */
2452  SCIP* scip, /**< SCIP data structure */
2453  SCIP_RELAX* relax, /**< relaxator data structure */
2454  int nvars, /**< number of variables to set relaxation solution value for */
2455  SCIP_VAR** vars, /**< array with variables to set value for */
2456  SCIP_Real* vals, /**< array with solution values of variables */
2457  SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2458  )
2459 {
2460  int v;
2461 
2462  assert(scip != NULL);
2463  assert(nvars == 0 || vars != NULL);
2464  assert(nvars == 0 || vals != NULL);
2465 
2466  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolVals", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2467 
2468  SCIP_CALL( SCIPclearRelaxSolVals(scip, relax) );
2469 
2470  for( v = 0; v < nvars; v++ )
2471  {
2472  SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, vals[v], TRUE) );
2473  }
2474 
2476  SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2477  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2478 
2479  return SCIP_OKAY;
2480 }
2481 
2482 /** sets the values of the variables in the global relaxation solution to the values in the given primal solution
2483  * and informs SCIP about the validity and whether the solution can be enforced via linear cuts;
2484  * the relaxation solution can be filled by the relaxation handlers and might be used by heuristics and for separation
2485  *
2486  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2487  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2488  *
2489  * @pre This method can be called if @p scip is in one of the following stages:
2490  * - \ref SCIP_STAGE_PRESOLVED
2491  * - \ref SCIP_STAGE_SOLVING
2492  */
2494  SCIP* scip, /**< SCIP data structure */
2495  SCIP_RELAX* relax, /**< relaxator data structure */
2496  SCIP_SOL* sol, /**< primal relaxation solution */
2497  SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2498  )
2499 {
2500  SCIP_VAR** vars;
2501  SCIP_Real* vals;
2502  int nvars;
2503  int v;
2504 
2505  assert(scip != NULL);
2506 
2507  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolValsSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2508 
2509  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
2510 
2511  /* alloc buffer array for solution values of the variables and get the values */
2512  SCIP_CALL( SCIPallocBufferArray(scip, &vals, nvars) );
2513  SCIP_CALL( SCIPgetSolVals(scip, sol, nvars, vars, vals) );
2514 
2515  SCIP_CALL( SCIPclearRelaxSolVals(scip, relax) );
2516 
2517  for( v = 0; v < nvars; v++ )
2518  {
2519  SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, vals[v], FALSE) );
2520  }
2521 
2522  SCIPrelaxationSetSolObj(scip->relaxation, SCIPsolGetObj(sol, scip->set, scip->transprob, scip->origprob));
2523 
2525  SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2526  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2527 
2528  SCIPfreeBufferArray(scip, &vals);
2529 
2530  return SCIP_OKAY;
2531 }
2532 
2533 /** returns whether the relaxation solution is valid
2534  *
2535  * @return TRUE, if the relaxation solution is valid; FALSE, otherwise
2536  *
2537  * @pre This method can be called if @p scip is in one of the following stages:
2538  * - \ref SCIP_STAGE_PRESOLVED
2539  * - \ref SCIP_STAGE_SOLVING
2540  */
2542  SCIP* scip /**< SCIP data structure */
2543  )
2544 {
2545  assert(scip != NULL);
2546 
2547  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisRelaxSolValid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2548 
2549  return SCIPrelaxationIsSolValid(scip->relaxation);
2550 }
2551 
2552 /** informs SCIP that the relaxation solution is valid and whether the relaxation can be enforced through linear cuts
2553  *
2554  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2555  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2556  *
2557  * @pre This method can be called if @p scip is in one of the following stages:
2558  * - \ref SCIP_STAGE_PRESOLVED
2559  * - \ref SCIP_STAGE_SOLVING
2560  */
2562  SCIP* scip, /**< SCIP data structure */
2563  SCIP_RELAX* relax, /**< relaxator data structure that set the current relaxation solution */
2564  SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2565  )
2566 {
2567  assert(scip != NULL);
2568 
2569  SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkRelaxSolValid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2570 
2571  SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2572  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2573 
2574  return SCIP_OKAY;
2575 }
2576 
2577 /** informs SCIP, that the relaxation solution is invalid
2578  *
2579  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2580  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2581  *
2582  * @pre This method can be called if @p scip is in one of the following stages:
2583  * - \ref SCIP_STAGE_PRESOLVED
2584  * - \ref SCIP_STAGE_SOLVING
2585  */
2587  SCIP* scip /**< SCIP data structure */
2588  )
2589 {
2590  assert(scip != NULL);
2591 
2592  SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkRelaxSolInvalid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2593 
2595 
2596  return SCIP_OKAY;
2597 }
2598 
2599 /** gets the relaxation solution value of the given variable
2600  *
2601  * @return the relaxation solution value of the given variable
2602  *
2603  * @pre This method can be called if @p scip is in one of the following stages:
2604  * - \ref SCIP_STAGE_PRESOLVED
2605  * - \ref SCIP_STAGE_SOLVING
2606  */
2608  SCIP* scip, /**< SCIP data structure */
2609  SCIP_VAR* var /**< variable to get value for */
2610  )
2611 {
2612  assert(scip != NULL);
2613  assert(var != NULL);
2614  assert(var->scip == scip);
2615 
2616  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetRelaxSolVal", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2617 
2618  if( !SCIPrelaxationIsSolValid(scip->relaxation) )
2619  {
2620  SCIPerrorMessage("Relaxation Solution is not valid!\n");
2621  SCIPABORT();
2622  return SCIP_INVALID; /*lint !e527*/
2623  }
2624 
2625  return SCIPvarGetRelaxSol(var, scip->set);
2626 }
2627 
2628 /** gets the relaxation solution objective value
2629  *
2630  * @return the objective value of the relaxation solution
2631  *
2632  * @pre This method can be called if @p scip is in one of the following stages:
2633  * - \ref SCIP_STAGE_PRESOLVED
2634  * - \ref SCIP_STAGE_SOLVING
2635  */
2637  SCIP* scip /**< SCIP data structure */
2638  )
2639 {
2640  assert(scip != NULL);
2641 
2642  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetRelaxSolObj", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2643 
2644  if( !SCIPrelaxationIsSolValid(scip->relaxation) )
2645  {
2646  SCIPerrorMessage("Relaxation Solution is not valid!\n");
2647  SCIPABORT();
2648  return SCIP_INVALID; /*lint !e527*/
2649  }
2650 
2651  return SCIPrelaxationGetSolObj(scip->relaxation);
2652 }
2653 
2654 /** determine which branching direction should be evaluated first by strong branching
2655  *
2656  * @return TRUE iff strong branching should first evaluate the down child
2657  *
2658  */
2660  SCIP* scip, /**< SCIP data structure */
2661  SCIP_VAR* var /**< variable to determine the branching direction on */
2662  )
2663 {
2664  switch( scip->set->branch_firstsbchild )
2665  {
2666  case 'u':
2667  return FALSE;
2668  case 'd':
2669  return TRUE;
2670  case 'a':
2671  return (SCIPvarGetNLocksDown(var) > SCIPvarGetNLocksUp(var));
2672  default:
2673  assert(scip->set->branch_firstsbchild == 'h');
2675  }
2676 }
2677 
2678 /** start strong branching - call before any strong branching
2679  *
2680  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2681  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2682  *
2683  * @pre This method can be called if @p scip is in one of the following stages:
2684  * - \ref SCIP_STAGE_PRESOLVED
2685  * - \ref SCIP_STAGE_SOLVING
2686  *
2687  * @note if propagation is enabled, strong branching is not done directly on the LP, but probing nodes are created
2688  * which allow to perform propagation but also creates some overhead
2689  */
2691  SCIP* scip, /**< SCIP data structure */
2692  SCIP_Bool enablepropagation /**< should propagation be done before solving the strong branching LP? */
2693  )
2694 {
2695  assert( scip != NULL );
2696  SCIP_CALL( SCIPcheckStage(scip, "SCIPstartStrongbranch", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2697 
2698  assert(!SCIPinProbing(scip));
2699 
2700  SCIPdebugMsg(scip, "starting strong branching mode%s: lpcount=%" SCIP_LONGINT_FORMAT "\n", enablepropagation ? " with propagation" : "", scip->stat->lpcount - scip->stat->nsbdivinglps);
2701 
2702  /* start probing mode to allow propagation before solving the strong branching LPs; if no propagation should be done,
2703  * start the strong branching mode in the LP interface
2704  */
2705  if( enablepropagation )
2706  {
2707  if( SCIPtreeProbing(scip->tree) )
2708  {
2709  SCIPerrorMessage("cannot start strong branching with propagation while in probing mode\n");
2710  return SCIP_INVALIDCALL;
2711  }
2712 
2713  if( scip->lp != NULL && SCIPlpDiving(scip->lp) )
2714  {
2715  SCIPerrorMessage("cannot start strong branching with propagation while in diving mode\n");
2716  return SCIP_INVALIDCALL;
2717  }
2718 
2719  /* other then in SCIPstartProbing(), we do not disable collecting variable statistics during strong branching;
2720  * we cannot disable it, because the pseudo costs would not be updated, otherwise,
2721  * and reliability branching would end up doing strong branching all the time
2722  */
2723  SCIP_CALL( SCIPtreeStartProbing(scip->tree, scip->mem->probmem, scip->set, scip->lp, scip->relaxation, scip->transprob, TRUE) );
2724 
2725  /* inform the LP that the current probing mode is used for strong branching */
2727  }
2728  else
2729  {
2731  }
2732 
2733  /* reset local strong branching info */
2735 
2736  return SCIP_OKAY;
2737 }
2738 
2739 /** end strong branching - call after any strong branching
2740  *
2741  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2742  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2743  *
2744  * @pre This method can be called if @p scip is in one of the following stages:
2745  * - \ref SCIP_STAGE_PRESOLVED
2746  * - \ref SCIP_STAGE_SOLVING
2747  */
2749  SCIP* scip /**< SCIP data structure */
2750  )
2751 {
2752  assert( scip != NULL );
2753 
2754  SCIP_CALL( SCIPcheckStage(scip, "SCIPendStrongbranch", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2755 
2756  /* depending on whether the strong branching mode was started with propagation enabled or not, we end the strong
2757  * branching probing mode or the LP strong branching mode
2758  */
2759  if( SCIPtreeProbing(scip->tree) )
2760  {
2761  SCIP_NODE* node;
2762  SCIP_DOMCHG* domchg;
2763  SCIP_VAR** boundchgvars;
2764  SCIP_Real* bounds;
2765  SCIP_BOUNDTYPE* boundtypes;
2766  int nboundchgs;
2767  int nbnds;
2768  int i;
2769 
2770  /* collect all bound changes deducted during probing, which were applied at the probing root and apply them to the
2771  * focusnode
2772  */
2773  node = SCIPgetCurrentNode(scip);
2774  assert(SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE);
2775  assert(SCIPgetProbingDepth(scip) == 0);
2776 
2777  domchg = SCIPnodeGetDomchg(node);
2778  nboundchgs = SCIPdomchgGetNBoundchgs(domchg);
2779 
2780  SCIP_CALL( SCIPallocBufferArray(scip, &boundchgvars, nboundchgs) );
2781  SCIP_CALL( SCIPallocBufferArray(scip, &bounds, nboundchgs) );
2782  SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, nboundchgs) );
2783 
2784  for( i = 0, nbnds = 0; i < nboundchgs; ++i )
2785  {
2786  SCIP_BOUNDCHG* boundchg;
2787 
2788  boundchg = SCIPdomchgGetBoundchg(domchg, i);
2789 
2790  /* ignore redundant bound changes */
2791  if( SCIPboundchgIsRedundant(boundchg) )
2792  continue;
2793 
2794  boundchgvars[nbnds] = SCIPboundchgGetVar(boundchg);
2795  bounds[nbnds] = SCIPboundchgGetNewbound(boundchg);
2796  boundtypes[nbnds] = SCIPboundchgGetBoundtype(boundchg);
2797  ++nbnds;
2798  }
2799 
2800  SCIPdebugMsg(scip, "ending strong branching with probing: %d bound changes collected\n", nbnds);
2801 
2802  /* inform the LP that the probing mode is not used for strong branching anymore */
2804 
2805  /* switch back from probing to normal operation mode and restore variables and constraints to focus node */
2806  SCIP_CALL( SCIPtreeEndProbing(scip->tree, scip->reopt, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
2807  scip->transprob, scip->origprob, scip->lp, scip->relaxation, scip->primal,
2808  scip->branchcand, scip->eventqueue, scip->eventfilter, scip->cliquetable) );
2809 
2810  /* apply the collected bound changes */
2811  for( i = 0; i < nbnds; ++i )
2812  {
2813  if( boundtypes[i] == SCIP_BOUNDTYPE_LOWER )
2814  {
2815  SCIPdebugMsg(scip, "apply probing lower bound change <%s> >= %.9g\n", SCIPvarGetName(boundchgvars[i]), bounds[i]);
2816  SCIP_CALL( SCIPchgVarLb(scip, boundchgvars[i], bounds[i]) );
2817  }
2818  else
2819  {
2820  SCIPdebugMsg(scip, "apply probing upper bound change <%s> <= %.9g\n", SCIPvarGetName(boundchgvars[i]), bounds[i]);
2821  SCIP_CALL( SCIPchgVarUb(scip, boundchgvars[i], bounds[i]) );
2822  }
2823  }
2824 
2825  SCIPfreeBufferArray(scip, &boundtypes);
2826  SCIPfreeBufferArray(scip, &bounds);
2827  SCIPfreeBufferArray(scip, &boundchgvars);
2828  }
2829  else
2830  {
2831  SCIPdebugMsg(scip, "ending strong branching\n");
2832 
2834  }
2835 
2836  return SCIP_OKAY;
2837 }
2838 
2839 /** analyze the strong branching for the given variable; that includes conflict analysis for infeasible branches and
2840  * storing of root reduced cost information
2841  */
2842 static
2844  SCIP* scip, /**< SCIP data structure */
2845  SCIP_VAR* var, /**< variable to analyze */
2846  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
2847  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
2848  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
2849  * infeasible downwards branch, or NULL */
2850  SCIP_Bool* upconflict /**< pointer to store whether a conflict constraint was created for an
2851  * infeasible upwards branch, or NULL */
2852  )
2853 {
2854  SCIP_COL* col;
2855  SCIP_Bool downcutoff;
2856  SCIP_Bool upcutoff;
2857 
2858  col = SCIPvarGetCol(var);
2859  assert(col != NULL);
2860 
2861  downcutoff = col->sbdownvalid && SCIPsetIsGE(scip->set, col->sbdown, scip->lp->cutoffbound);
2862  upcutoff = col->sbupvalid && SCIPsetIsGE(scip->set, col->sbup, scip->lp->cutoffbound);
2863 
2864  if( downinf != NULL )
2865  *downinf = downcutoff;
2866  if( upinf != NULL )
2867  *upinf = upcutoff;
2868 
2869  /* analyze infeasible strong branching sub problems:
2870  * because the strong branching's bound change is necessary for infeasibility, it cannot be undone;
2871  * therefore, infeasible strong branchings on non-binary variables will not produce a valid conflict constraint
2872  */
2873  if( scip->set->conf_enable && scip->set->conf_usesb && scip->set->nconflicthdlrs > 0
2874  && SCIPvarIsBinary(var) && SCIPtreeGetCurrentDepth(scip->tree) > 0 )
2875  {
2876  if( (downcutoff && SCIPsetFeasCeil(scip->set, col->primsol-1.0) >= col->lb - 0.5)
2877  || (upcutoff && SCIPsetFeasFloor(scip->set, col->primsol+1.0) <= col->ub + 0.5) )
2878  {
2879  assert(downconflict != NULL);
2880  assert(upconflict != NULL);
2881  SCIP_CALL( SCIPconflictAnalyzeStrongbranch(scip->conflict, scip->conflictstore, scip->mem->probmem, scip->set, scip->stat,
2882  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, col, downconflict, upconflict) );
2883  }
2884  }
2885 
2886  /* the strong branching results can be used to strengthen the root reduced cost information which is used for example
2887  * to propagate against the cutoff bound
2888  *
2889  * @note Ignore the results if the LP solution of the down (up) branch LP is smaller which should not happened by
2890  * theory but can arise due to numerical issues.
2891  */
2892  if( SCIPtreeGetCurrentDepth(scip->tree) == 0 && SCIPvarIsBinary(var) && SCIPlpIsDualReliable(scip->lp) )
2893  {
2894  SCIP_Real lpobjval;
2895 
2896  assert(SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL);
2897 
2898  lpobjval = SCIPlpGetObjval(scip->lp, scip->set, scip->transprob);
2899 
2900  if( col->sbdownvalid && SCIPsetFeasCeil(scip->set, col->primsol-1.0) >= col->lb - 0.5 && lpobjval < col->sbdown )
2901  SCIPvarUpdateBestRootSol(var, scip->set, SCIPvarGetUbGlobal(var), -(col->sbdown - lpobjval), lpobjval);
2902  if( col->sbupvalid && SCIPsetFeasFloor(scip->set, col->primsol+1.0) <= col->ub + 0.5 && lpobjval < col->sbup )
2903  SCIPvarUpdateBestRootSol(var, scip->set, SCIPvarGetLbGlobal(var), col->sbup - lpobjval, lpobjval);
2904  }
2905 
2906  return SCIP_OKAY;
2907 }
2908 
2909 /** gets strong branching information on column variable with fractional value
2910  *
2911  * Before calling this method, the strong branching mode must have been activated by calling SCIPstartStrongbranch();
2912  * after strong branching was done for all candidate variables, the strong branching mode must be ended by
2913  * SCIPendStrongbranch(). Since this method does not apply domain propagation before strongbranching,
2914  * propagation should not be enabled in the SCIPstartStrongbranch() call.
2915  *
2916  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2917  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2918  *
2919  * @pre This method can be called if @p scip is in one of the following stages:
2920  * - \ref SCIP_STAGE_PRESOLVED
2921  * - \ref SCIP_STAGE_SOLVING
2922  */
2924  SCIP* scip, /**< SCIP data structure */
2925  SCIP_VAR* var, /**< variable to get strong branching values for */
2926  int itlim, /**< iteration limit for strong branchings */
2927  SCIP_Bool idempotent, /**< should scip's state remain the same after the call (statistics, column states...), or should it be updated ? */
2928  SCIP_Real* down, /**< stores dual bound after branching column down */
2929  SCIP_Real* up, /**< stores dual bound after branching column up */
2930  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
2931  * otherwise, it can only be used as an estimate value */
2932  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
2933  * otherwise, it can only be used as an estimate value */
2934  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
2935  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
2936  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
2937  * infeasible downwards branch, or NULL */
2938  SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
2939  * infeasible upwards branch, or NULL */
2940  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
2941  * solving process should be stopped (e.g., due to a time limit) */
2942  )
2943 {
2944  SCIP_COL* col;
2945  SCIP_Real localdown;
2946  SCIP_Real localup;
2947  SCIP_Bool localdownvalid;
2948  SCIP_Bool localupvalid;
2949 
2950  assert(scip != NULL);
2951  assert(var != NULL);
2952  assert(lperror != NULL);
2953  assert(!SCIPtreeProbing(scip->tree)); /* we should not be in strong branching with propagation mode */
2954  assert(var->scip == scip);
2955 
2956  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchFrac", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2957 
2958  if( downvalid != NULL )
2959  *downvalid = FALSE;
2960  if( upvalid != NULL )
2961  *upvalid = FALSE;
2962  if( downinf != NULL )
2963  *downinf = FALSE;
2964  if( upinf != NULL )
2965  *upinf = FALSE;
2966  if( downconflict != NULL )
2967  *downconflict = FALSE;
2968  if( upconflict != NULL )
2969  *upconflict = FALSE;
2970 
2972  {
2973  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
2974  return SCIP_INVALIDDATA;
2975  }
2976 
2977  col = SCIPvarGetCol(var);
2978  assert(col != NULL);
2979 
2980  if( !SCIPcolIsInLP(col) )
2981  {
2982  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
2983  return SCIP_INVALIDDATA;
2984  }
2985 
2986  /* check if the solving process should be aborted */
2987  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
2988  {
2989  /* mark this as if the LP failed */
2990  *lperror = TRUE;
2991  return SCIP_OKAY;
2992  }
2993 
2994  /* call strong branching for column with fractional value */
2995  SCIP_CALL( SCIPcolGetStrongbranch(col, FALSE, scip->set, scip->stat, scip->transprob, scip->lp, itlim, !idempotent, !idempotent,
2996  &localdown, &localup, &localdownvalid, &localupvalid, lperror) );
2997 
2998  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
2999  * declare the sub nodes infeasible
3000  */
3001  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3002  {
3003  if( !idempotent ) /*lint !e774*/
3004  {
3005  SCIP_CALL( analyzeStrongbranch(scip, var, downinf, upinf, downconflict, upconflict) );
3006  }
3007  else
3008  {
3009  if( downinf != NULL )
3010  *downinf = localdownvalid && SCIPsetIsGE(scip->set, localdown, scip->lp->cutoffbound);
3011  if( upinf != NULL )
3012  *upinf = localupvalid && SCIPsetIsGE(scip->set, localup, scip->lp->cutoffbound);
3013  }
3014  }
3015 
3016  if( down != NULL )
3017  *down = localdown;
3018  if( up != NULL )
3019  *up = localup;
3020  if( downvalid != NULL )
3021  *downvalid = localdownvalid;
3022  if( upvalid != NULL )
3023  *upvalid = localupvalid;
3024 
3025  return SCIP_OKAY;
3026 }
3027 
3028 /** create, solve, and evaluate a single strong branching child (for strong branching with propagation) */
3029 static
3031  SCIP* scip, /**< SCIP data structure */
3032  SCIP_VAR* var, /**< variable to get strong branching values for */
3033  SCIP_Bool down, /**< do we regard the down child? */
3034  SCIP_Bool firstchild, /**< is this the first of the two strong branching children? */
3035  SCIP_Bool propagate, /**< should domain propagation be performed? */
3036  SCIP_Real newbound, /**< new bound to apply at the strong branching child */
3037  int itlim, /**< iteration limit for strong branchings */
3038  int maxproprounds, /**< maximum number of propagation rounds (-1: no limit, -2: parameter
3039  * settings) */
3040  SCIP_Real* value, /**< stores dual bound for strong branching child */
3041  SCIP_Bool* valid, /**< stores whether the returned value is a valid dual bound, or NULL;
3042  * otherwise, it can only be used as an estimate value */
3043  SCIP_Longint* ndomreductions, /**< pointer to store the number of domain reductions found, or NULL */
3044  SCIP_Bool* conflict, /**< pointer to store whether a conflict constraint was created for an
3045  * infeasible strong branching child, or NULL */
3046  SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred or the
3047  * solving process should be stopped (e.g., due to a time limit) */
3048  SCIP_VAR** vars, /**< active problem variables */
3049  int nvars, /**< number of active problem variables */
3050  SCIP_Real* newlbs, /**< array to store valid lower bounds for all active variables, or NULL */
3051  SCIP_Real* newubs, /**< array to store valid upper bounds for all active variables, or NULL */
3052  SCIP_Bool* foundsol, /**< pointer to store whether a primal solution was found during strong branching */
3053  SCIP_Bool* cutoff /**< pointer to store whether the strong branching child is infeasible */
3054  )
3055 {
3056  SCIP_Longint ndomreds;
3057 
3058  assert(value != NULL);
3059  assert(foundsol != NULL);
3060  assert(cutoff != NULL);
3061  assert(lperror != NULL);
3062  assert(valid != NULL ? !(*valid) : TRUE);
3063 
3064  *foundsol = FALSE;
3065  *cutoff = FALSE;
3066  *lperror = FALSE;
3067 
3068  /* check whether the strong branching child is already infeasible due to the bound change */
3069  if( down )
3070  {
3071  /* the down branch is infeasible due to the branching bound change; since this means that solval is not within the
3072  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3073  * are valid for and were already applied at the probing root
3074  */
3075  if( newbound < SCIPvarGetLbLocal(var) - 0.5 )
3076  {
3077  *value = SCIPinfinity(scip);
3078 
3079  if( valid != NULL )
3080  *valid = TRUE;
3081 
3082  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3083  if( conflict != NULL )
3084  *conflict = TRUE;
3085 
3086  *cutoff = TRUE;
3087 
3088  return SCIP_OKAY;
3089  }
3090  }
3091  else
3092  {
3093  /* the up branch is infeasible due to the branching bound change; since this means that solval is not within the
3094  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3095  * are valid for and were already applied at the probing root
3096  */
3097  if( newbound > SCIPvarGetUbLocal(var) + 0.5 )
3098  {
3099  *value = SCIPinfinity(scip);
3100 
3101  if( valid != NULL )
3102  *valid = TRUE;
3103 
3104  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3105  if( conflict != NULL )
3106  *conflict = TRUE;
3107 
3108  *cutoff = TRUE;
3109 
3110  return SCIP_OKAY;
3111  }
3112  }
3113 
3114  /* we need to ensure that we can create at least one new probing node without exceeding the maximal tree depth */
3116  {
3117  /* create a new probing node for the strong branching child and apply the new bound for the variable */
3118  SCIP_CALL( SCIPnewProbingNode(scip) );
3119 
3120  if( down )
3121  {
3122  assert(SCIPisGE(scip, newbound, SCIPvarGetLbLocal(var)));
3123  if( SCIPisLT(scip, newbound, SCIPvarGetUbLocal(var)) )
3124  {
3125  SCIP_CALL( SCIPchgVarUbProbing(scip, var, newbound) );
3126  }
3127  }
3128  else
3129  {
3130  assert(SCIPisLE(scip, newbound, SCIPvarGetUbLocal(var)));
3131  if( SCIPisGT(scip, newbound, SCIPvarGetLbLocal(var)) )
3132  {
3133  SCIP_CALL( SCIPchgVarLbProbing(scip, var, newbound) );
3134  }
3135  }
3136  }
3137  else
3138  {
3139  if( valid != NULL )
3140  *valid = FALSE;
3141 
3142  *cutoff = FALSE;
3143 
3144  if( conflict != NULL )
3145  *conflict = FALSE;
3146 
3147  return SCIP_OKAY;
3148  }
3149 
3150  /* propagate domains at the probing node */
3151  if( propagate )
3152  {
3153  /* start time measuring */
3154  SCIPclockStart(scip->stat->strongpropclock, scip->set);
3155 
3156  ndomreds = 0;
3157  SCIP_CALL( SCIPpropagateProbing(scip, maxproprounds, cutoff, &ndomreds) );
3158 
3159  /* store number of domain reductions in strong branching */
3160  if( down )
3161  SCIPstatAdd(scip->stat, scip->set, nsbdowndomchgs, ndomreds);
3162  else
3163  SCIPstatAdd(scip->stat, scip->set, nsbupdomchgs, ndomreds);
3164 
3165  if( ndomreductions != NULL )
3166  *ndomreductions = ndomreds;
3167 
3168  /* stop time measuring */
3169  SCIPclockStop(scip->stat->strongpropclock, scip->set);
3170 
3171  if( *cutoff )
3172  {
3173  *value = SCIPinfinity(scip);
3174 
3175  if( valid != NULL )
3176  *valid = TRUE;
3177 
3178  SCIPdebugMsg(scip, "%s branch of var <%s> detected infeasible during propagation\n",
3179  down ? "down" : "up", SCIPvarGetName(var));
3180  }
3181  }
3182 
3183  /* if propagation did not already detect infeasibility, solve the probing LP */
3184  if( !(*cutoff) )
3185  {
3186  SCIP_CALL( SCIPsolveProbingLP(scip, itlim, lperror, cutoff) );
3187  assert(SCIPisLPRelax(scip));
3188 
3189  if( *cutoff )
3190  {
3191  assert(!(*lperror));
3192 
3193  *value = SCIPinfinity(scip);
3194 
3195  if( valid != NULL )
3196  *valid = TRUE;
3197 
3198  SCIPdebugMsg(scip, "%s branch of var <%s> detected infeasible in LP solving: status=%d\n",
3199  down ? "down" : "up", SCIPvarGetName(var), SCIPgetLPSolstat(scip));
3200  }
3201  else if( !(*lperror) )
3202  {
3203  /* save the lp solution status */
3204  scip->stat->lastsblpsolstats[down ? 0 : 1] = SCIPgetLPSolstat(scip);
3205 
3206  switch( SCIPgetLPSolstat(scip) )
3207  {
3209  {
3210  *value = SCIPgetLPObjval(scip);
3211  assert(SCIPisLT(scip, *value, SCIPgetCutoffbound(scip)));
3212 
3213  SCIPdebugMsg(scip, "probing LP solved to optimality, objective value: %16.9g\n", *value);
3214 
3215  if( valid != NULL )
3216  *valid = TRUE;
3217 
3218  /* check the strong branching LP solution for feasibility */
3219  SCIP_CALL( SCIPtryStrongbranchLPSol(scip, foundsol, cutoff) );
3220  break;
3221  }
3223  ++scip->stat->nsbtimesiterlimhit;
3224  /*lint -fallthrough*/
3226  {
3227  /* use LP value as estimate */
3228  SCIP_LPI* lpi;
3229  SCIP_Real objval;
3230  SCIP_Real looseobjval;
3231 
3232  SCIPdebugMsg(scip, "probing LP hit %s limit\n", SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_ITERLIMIT ? "iteration" : "time");
3233 
3234  /* we access the LPI directly, because when a time limit was hit, we cannot access objective value and dual
3235  * feasibility using the SCIPlp... methods; we should try to avoid direct calls to the LPI, but this is rather
3236  * uncritical here, because we are immediately after the SCIPsolveProbingLP() call, because we access the LPI
3237  * read-only, and we check SCIPlpiWasSolved() first
3238  */
3239  SCIP_CALL( SCIPgetLPI(scip, &lpi) );
3240 
3241  if( SCIPlpiWasSolved(lpi) )
3242  {
3243  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
3244  looseobjval = SCIPlpGetLooseObjval(scip->lp, scip->set, scip->transprob);
3245 
3246  /* the infinity value in the LPI should not be smaller than SCIP's infinity value */
3247  assert(!SCIPlpiIsInfinity(lpi, objval) || SCIPisInfinity(scip, objval));
3248 
3249  /* we use SCIP's infinity value here because a value larger than this is counted as infeasible by SCIP */
3250  if( SCIPisInfinity(scip, objval) )
3251  *value = SCIPinfinity(scip);
3252  else if( SCIPisInfinity(scip, -looseobjval) )
3253  *value = -SCIPinfinity(scip);
3254  else
3255  *value = objval + looseobjval;
3256 
3257  if( SCIPlpiIsDualFeasible(lpi) )
3258  {
3259  if( valid != NULL )
3260  *valid = TRUE;
3261 
3262  if( SCIPisGE(scip, *value, SCIPgetCutoffbound(scip)) )
3263  *cutoff = TRUE;
3264  }
3265  }
3266  break;
3267  }
3268  case SCIP_LPSOLSTAT_ERROR:
3270  *lperror = TRUE;
3271  break;
3272  case SCIP_LPSOLSTAT_NOTSOLVED: /* should only be the case for *cutoff = TRUE or *lperror = TRUE */
3273  case SCIP_LPSOLSTAT_OBJLIMIT: /* in this case, *cutoff should be TRUE and we should not get here */
3274  case SCIP_LPSOLSTAT_INFEASIBLE: /* in this case, *cutoff should be TRUE and we should not get here */
3275  default:
3276  SCIPerrorMessage("invalid LP solution status <%d>\n", SCIPgetLPSolstat(scip));
3277  return SCIP_INVALIDDATA;
3278  } /*lint !e788*/
3279  }
3280 
3281  /* If columns are missing in the LP, the cutoff flag may be wrong. Therefore, we need to set it and the valid pointer
3282  * to false here.
3283  */
3284  if( (*cutoff) && !SCIPallColsInLP(scip) )
3285  {
3286  *cutoff = FALSE;
3287  }
3288 
3289 #ifndef NDEBUG
3290  if( *lperror )
3291  {
3292  SCIPdebugMsg(scip, "error during strong branching probing LP solving: status=%d\n", SCIPgetLPSolstat(scip));
3293  }
3294 #endif
3295  }
3296 
3297  /* if the subproblem was feasible, we store the local bounds of the variables after propagation and (possibly)
3298  * conflict analysis
3299  * @todo do this after propagation? should be able to get valid bounds more often, but they might be weaker
3300  */
3301  if( !(*cutoff) && newlbs != NULL)
3302  {
3303  int v;
3304 
3305  assert(newubs != NULL);
3306 
3307  /* initialize the newlbs and newubs to the current local bounds */
3308  if( firstchild )
3309  {
3310  for( v = 0; v < nvars; ++v )
3311  {
3312  newlbs[v] = SCIPvarGetLbLocal(vars[v]);
3313  newubs[v] = SCIPvarGetUbLocal(vars[v]);
3314  }
3315  }
3316  /* update newlbs and newubs: take the weaker of the already stored bounds and the current local bounds */
3317  else
3318  {
3319  for( v = 0; v < nvars; ++v )
3320  {
3321  SCIP_Real lb = SCIPvarGetLbLocal(vars[v]);
3322  SCIP_Real ub = SCIPvarGetUbLocal(vars[v]);
3323 
3324  newlbs[v] = MIN(newlbs[v], lb);
3325  newubs[v] = MAX(newubs[v], ub);
3326  }
3327  }
3328  }
3329 
3330  /* revert all changes at the probing node */
3331  SCIP_CALL( SCIPbacktrackProbing(scip, 0) );
3332 
3333  return SCIP_OKAY;
3334 }
3335 
3336 /** gets strong branching information with previous domain propagation on column variable
3337  *
3338  * Before calling this method, the strong branching mode must have been activated by calling SCIPstartStrongbranch();
3339  * after strong branching was done for all candidate variables, the strong branching mode must be ended by
3340  * SCIPendStrongbranch(). Since this method applies domain propagation before strongbranching, propagation has to be be
3341  * enabled in the SCIPstartStrongbranch() call.
3342  *
3343  * Before solving the strong branching LP, domain propagation can be performed. The number of propagation rounds
3344  * can be specified by the parameter @p maxproprounds.
3345  *
3346  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3347  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3348  *
3349  * @pre This method can be called if @p scip is in one of the following stages:
3350  * - \ref SCIP_STAGE_PRESOLVED
3351  * - \ref SCIP_STAGE_SOLVING
3352  *
3353  * @warning When using this method, LP banching candidates and solution values must be copied beforehand, because
3354  * they are updated w.r.t. the strong branching LP solution.
3355  */
3357  SCIP* scip, /**< SCIP data structure */
3358  SCIP_VAR* var, /**< variable to get strong branching values for */
3359  SCIP_Real solval, /**< value of the variable in the current LP solution */
3360  SCIP_Real lpobjval, /**< LP objective value of the current LP solution */
3361  int itlim, /**< iteration limit for strong branchings */
3362  int maxproprounds, /**< maximum number of propagation rounds (-1: no limit, -2: parameter
3363  * settings) */
3364  SCIP_Real* down, /**< stores dual bound after branching column down */
3365  SCIP_Real* up, /**< stores dual bound after branching column up */
3366  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
3367  * otherwise, it can only be used as an estimate value */
3368  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
3369  * otherwise, it can only be used as an estimate value */
3370  SCIP_Longint* ndomredsdown, /**< pointer to store the number of domain reductions down, or NULL */
3371  SCIP_Longint* ndomredsup, /**< pointer to store the number of domain reductions up, or NULL */
3372  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
3373  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
3374  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
3375  * infeasible downwards branch, or NULL */
3376  SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
3377  * infeasible upwards branch, or NULL */
3378  SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred or the
3379  * solving process should be stopped (e.g., due to a time limit) */
3380  SCIP_Real* newlbs, /**< array to store valid lower bounds for all active variables, or NULL */
3381  SCIP_Real* newubs /**< array to store valid upper bounds for all active variables, or NULL */
3382  )
3383 {
3384  SCIP_COL* col;
3385  SCIP_VAR** vars;
3386  SCIP_Longint oldniters;
3387  SCIP_Real newub;
3388  SCIP_Real newlb;
3389  SCIP_Bool propagate;
3390  SCIP_Bool cutoff;
3391  SCIP_Bool downchild;
3392  SCIP_Bool firstchild;
3393  SCIP_Bool foundsol;
3394  SCIP_Bool downvalidlocal;
3395  SCIP_Bool upvalidlocal;
3396  SCIP_Bool allcolsinlp;
3397  SCIP_Bool enabledconflict;
3398  int oldnconflicts;
3399  int nvars;
3400 
3401  assert(scip != NULL);
3402  assert(var != NULL);
3403  assert(SCIPvarIsIntegral(var));
3404  assert(down != NULL);
3405  assert(up != NULL);
3406  assert(lperror != NULL);
3407  assert((newlbs != NULL) == (newubs != NULL));
3408  assert(SCIPinProbing(scip));
3409  assert(var->scip == scip);
3410 
3411  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchWithPropagation", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3412 
3413  /* check whether propagation should be performed */
3414  propagate = (maxproprounds != 0 && maxproprounds != -3);
3415 
3416  /* Check, if all existing columns are in LP.
3417  * If this is not the case, we may still return that the up and down dual bounds are valid, because the branching
3418  * rule should not apply them otherwise.
3419  * However, we must not set the downinf or upinf pointers to TRUE based on the dual bound, because we cannot
3420  * guarantee that this node can be cut off.
3421  */
3422  allcolsinlp = SCIPallColsInLP(scip);
3423 
3424  /* if maxproprounds is -2, change it to 0, which for the following calls means using the parameter settings */
3425  if( maxproprounds == -2 )
3426  maxproprounds = 0;
3427 
3428  *down = lpobjval;
3429  *up = lpobjval;
3430  if( downvalid != NULL )
3431  *downvalid = FALSE;
3432  if( upvalid != NULL )
3433  *upvalid = FALSE;
3434  if( downinf != NULL )
3435  *downinf = FALSE;
3436  if( upinf != NULL )
3437  *upinf = FALSE;
3438  if( downconflict != NULL )
3439  *downconflict = FALSE;
3440  if( upconflict != NULL )
3441  *upconflict = FALSE;
3442  if( ndomredsdown != NULL )
3443  *ndomredsdown = 0;
3444  if( ndomredsup != NULL )
3445  *ndomredsup = 0;
3446 
3447  *lperror = FALSE;
3448 
3449  vars = SCIPgetVars(scip);
3450  nvars = SCIPgetNVars(scip);
3451 
3453 
3454  /* check if the solving process should be aborted */
3455  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3456  {
3457  /* mark this as if the LP failed */
3458  *lperror = TRUE;
3459  return SCIP_OKAY;
3460  }
3461 
3463  {
3464  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3465  return SCIP_INVALIDDATA;
3466  }
3467 
3468  col = SCIPvarGetCol(var);
3469  assert(col != NULL);
3470 
3471  if( !SCIPcolIsInLP(col) )
3472  {
3473  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3474  return SCIP_INVALIDDATA;
3475  }
3476 
3477  newlb = SCIPfeasFloor(scip, solval + 1.0);
3478  newub = SCIPfeasCeil(scip, solval - 1.0);
3479 
3480  SCIPdebugMsg(scip, "strong branching on var <%s>: solval=%g, lb=%g, ub=%g\n", SCIPvarGetName(var), solval,
3482 
3483  /* the up branch is infeasible due to the branching bound change; since this means that solval is not within the
3484  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3485  * are valid for and were already applied at the probing root
3486  */
3487  if( newlb > SCIPvarGetUbLocal(var) + 0.5 )
3488  {
3489  *up = SCIPinfinity(scip);
3490 
3491  if( upinf != NULL )
3492  *upinf = TRUE;
3493 
3494  if( upvalid != NULL )
3495  *upvalid = TRUE;
3496 
3497  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3498  if( upconflict != NULL )
3499  *upconflict = TRUE;
3500 
3501  SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3502  *down, *up, FALSE, TRUE, 0LL, INT_MAX);
3503 
3504  /* we do not regard the down branch; its valid pointer stays set to FALSE */
3505  return SCIP_OKAY;
3506  }
3507 
3508  /* the down branch is infeasible due to the branching bound change; since this means that solval is not within the
3509  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3510  * are valid for and were already applied at the probing root
3511  */
3512  if( newub < SCIPvarGetLbLocal(var) - 0.5 )
3513  {
3514  *down = SCIPinfinity(scip);
3515 
3516  if( downinf != NULL )
3517  *downinf = TRUE;
3518 
3519  if( downvalid != NULL )
3520  *downvalid = TRUE;
3521 
3522  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3523  if( downconflict != NULL )
3524  *downconflict = TRUE;
3525 
3526  SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3527  *down, *up, TRUE, FALSE, 0LL, INT_MAX);
3528 
3529  /* we do not regard the up branch; its valid pointer stays set to FALSE */
3530  return SCIP_OKAY;
3531  }
3532 
3533  /* We now do strong branching by creating the two potential child nodes as probing nodes and solving them one after
3534  * the other. We will stop when the first child is detected infeasible, saving the effort we would need for the
3535  * second child. Since empirically, the up child tends to be infeasible more often, we do strongbranching first on
3536  * the up branch.
3537  */
3538  oldniters = scip->stat->nsbdivinglpiterations;
3539  firstchild = TRUE;
3540  cutoff = FALSE;
3541 
3542  /* switch conflict analysis according to usesb parameter */
3543  enabledconflict = scip->set->conf_enable;
3544  scip->set->conf_enable = (scip->set->conf_enable && scip->set->conf_usesb);
3545 
3546  /* @todo: decide the branch to look at first based on the cutoffs in previous calls? */
3547  downchild = SCIPisStrongbranchDownFirst(scip, var);
3548 
3549  downvalidlocal = FALSE;
3550  upvalidlocal = FALSE;
3551 
3552  do
3553  {
3554  oldnconflicts = SCIPconflictGetNConflicts(scip->conflict);
3555 
3556  if( downchild )
3557  {
3558  SCIP_CALL( performStrongbranchWithPropagation(scip, var, downchild, firstchild, propagate, newub, itlim, maxproprounds,
3559  down, &downvalidlocal, ndomredsdown, downconflict, lperror, vars, nvars, newlbs, newubs, &foundsol, &cutoff) );
3560 
3561  /* check whether a new solutions rendered the previous child infeasible */
3562  if( foundsol && !firstchild && allcolsinlp )
3563  {
3564  if( SCIPisGE(scip, *up, SCIPgetCutoffbound(scip)) )
3565  {
3566  if( upinf != NULL )
3567  *upinf = TRUE;
3568  }
3569  }
3570 
3571  /* check for infeasibility */
3572  if( cutoff )
3573  {
3574  if( downinf != NULL )
3575  *downinf = TRUE;
3576 
3577  if( downconflict != NULL &&
3578  (SCIPvarGetLbLocal(var) > newub + 0.5 || SCIPconflictGetNConflicts(scip->conflict) > oldnconflicts) )
3579  {
3580  *downconflict = TRUE;
3581  }
3582 
3583  if( !scip->set->branch_forceall )
3584  {
3585  /* if this is the first call, we do not regard the up branch, its valid pointer is initially set to FALSE */
3586  break;
3587  }
3588  }
3589  }
3590  else
3591  {
3592  SCIP_CALL( performStrongbranchWithPropagation(scip, var, downchild, firstchild, propagate, newlb, itlim, maxproprounds,
3593  up, &upvalidlocal, ndomredsup, upconflict, lperror, vars, nvars, newlbs, newubs, &foundsol, &cutoff) );
3594 
3595  /* check whether a new solutions rendered the previous child infeasible */
3596  if( foundsol && !firstchild && allcolsinlp )
3597  {
3598  if( SCIPisGE(scip, *down, SCIPgetCutoffbound(scip)) )
3599  {
3600  if( downinf != NULL )
3601  *downinf = TRUE;
3602  }
3603  }
3604 
3605  /* check for infeasibility */
3606  if( cutoff )
3607  {
3608  if( upinf != NULL )
3609  *upinf = TRUE;
3610 
3611  assert(upinf == NULL || (*upinf) == TRUE);
3612 
3613  if( upconflict != NULL &&
3614  (SCIPvarGetUbLocal(var) < newlb - 0.5 || SCIPconflictGetNConflicts(scip->conflict) > oldnconflicts) )
3615  {
3616  *upconflict = TRUE;
3617  }
3618 
3619  if( !scip->set->branch_forceall )
3620  {
3621  /* if this is the first call, we do not regard the down branch, its valid pointer is initially set to FALSE */
3622  break;
3623  }
3624  }
3625  }
3626 
3627  downchild = !downchild;
3628  firstchild = !firstchild;
3629  }
3630  while( !firstchild );
3631 
3632  /* set strong branching information in column */
3633  if( *lperror )
3634  {
3635  SCIPcolInvalidateStrongbranchData(col, scip->set, scip->stat, scip->lp);
3636  }
3637  else
3638  {
3639  SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3640  *down, *up, downvalidlocal, upvalidlocal, scip->stat->nsbdivinglpiterations - oldniters, itlim);
3641  }
3642 
3643  if( downvalid != NULL )
3644  *downvalid = downvalidlocal;
3645  if( upvalid != NULL )
3646  *upvalid = upvalidlocal;
3647 
3648  scip->set->conf_enable = enabledconflict;
3649 
3650  return SCIP_OKAY; /*lint !e438*/
3651 }
3652 
3653 /** gets strong branching information on column variable x with integral LP solution value (val); that is, the down branch
3654  * is (val -1.0) and the up brach ins (val +1.0)
3655  *
3656  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3657  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3658  *
3659  * @pre This method can be called if @p scip is in one of the following stages:
3660  * - \ref SCIP_STAGE_PRESOLVED
3661  * - \ref SCIP_STAGE_SOLVING
3662  *
3663  * @note If the integral LP solution value is the lower or upper bound of the variable, the corresponding branch will be
3664  * marked as infeasible. That is, the valid pointer and the infeasible pointer are set to TRUE.
3665  */
3667  SCIP* scip, /**< SCIP data structure */
3668  SCIP_VAR* var, /**< variable to get strong branching values for */
3669  int itlim, /**< iteration limit for strong branchings */
3670  SCIP_Bool idempotent, /**< should scip's state remain the same after the call (statistics, column states...), or should it be updated ? */
3671  SCIP_Real* down, /**< stores dual bound after branching column down */
3672  SCIP_Real* up, /**< stores dual bound after branching column up */
3673  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
3674  * otherwise, it can only be used as an estimate value */
3675  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
3676  * otherwise, it can only be used as an estimate value */
3677  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
3678  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
3679  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
3680  * infeasible downwards branch, or NULL */
3681  SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
3682  * infeasible upwards branch, or NULL */
3683  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3684  * solving process should be stopped (e.g., due to a time limit) */
3685  )
3686 {
3687  SCIP_COL* col;
3688  SCIP_Real localdown;
3689  SCIP_Real localup;
3690  SCIP_Bool localdownvalid;
3691  SCIP_Bool localupvalid;
3692 
3693  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchInt", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3694 
3695  assert(lperror != NULL);
3696  assert(var->scip == scip);
3697 
3698  if( downvalid != NULL )
3699  *downvalid = FALSE;
3700  if( upvalid != NULL )
3701  *upvalid = FALSE;
3702  if( downinf != NULL )
3703  *downinf = FALSE;
3704  if( upinf != NULL )
3705  *upinf = FALSE;
3706  if( downconflict != NULL )
3707  *downconflict = FALSE;
3708  if( upconflict != NULL )
3709  *upconflict = FALSE;
3710 
3712  {
3713  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3714  return SCIP_INVALIDDATA;
3715  }
3716 
3717  col = SCIPvarGetCol(var);
3718  assert(col != NULL);
3719 
3720  if( !SCIPcolIsInLP(col) )
3721  {
3722  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3723  return SCIP_INVALIDDATA;
3724  }
3725 
3726  /* check if the solving process should be aborted */
3727  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3728  {
3729  /* mark this as if the LP failed */
3730  *lperror = TRUE;
3731  return SCIP_OKAY;
3732  }
3733 
3734  /* call strong branching for column */
3735  SCIP_CALL( SCIPcolGetStrongbranch(col, TRUE, scip->set, scip->stat, scip->transprob, scip->lp, itlim, !idempotent, !idempotent,
3736  &localdown, &localup, &localdownvalid, &localupvalid, lperror) );
3737 
3738  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3739  * declare the sub nodes infeasible
3740  */
3741  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3742  {
3743  if( !idempotent ) /*lint !e774*/
3744  {
3745  SCIP_CALL( analyzeStrongbranch(scip, var, downinf, upinf, downconflict, upconflict) );
3746  }
3747  else
3748  {
3749  if( downinf != NULL )
3750  *downinf = localdownvalid && SCIPsetIsGE(scip->set, localdown, scip->lp->cutoffbound);
3751  if( upinf != NULL )
3752  *upinf = localupvalid && SCIPsetIsGE(scip->set, localup, scip->lp->cutoffbound);
3753  }
3754  }
3755 
3756  if( down != NULL )
3757  *down = localdown;
3758  if( up != NULL )
3759  *up = localup;
3760  if( downvalid != NULL )
3761  *downvalid = localdownvalid;
3762  if( upvalid != NULL )
3763  *upvalid = localupvalid;
3764 
3765  return SCIP_OKAY;
3766 }
3767 
3768 /** gets strong branching information on column variables with fractional values
3769  *
3770  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3771  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3772  *
3773  * @pre This method can be called if @p scip is in one of the following stages:
3774  * - \ref SCIP_STAGE_PRESOLVED
3775  * - \ref SCIP_STAGE_SOLVING
3776  */
3778  SCIP* scip, /**< SCIP data structure */
3779  SCIP_VAR** vars, /**< variables to get strong branching values for */
3780  int nvars, /**< number of variables */
3781  int itlim, /**< iteration limit for strong branchings */
3782  SCIP_Real* down, /**< stores dual bounds after branching variables down */
3783  SCIP_Real* up, /**< stores dual bounds after branching variables up */
3784  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
3785  * otherwise, they can only be used as an estimate value */
3786  SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
3787  * otherwise, they can only be used as an estimate value */
3788  SCIP_Bool* downinf, /**< array to store whether the downward branches are infeasible, or NULL */
3789  SCIP_Bool* upinf, /**< array to store whether the upward branches are infeasible, or NULL */
3790  SCIP_Bool* downconflict, /**< array to store whether conflict constraints were created for
3791  * infeasible downward branches, or NULL */
3792  SCIP_Bool* upconflict, /**< array to store whether conflict constraints were created for
3793  * infeasible upward branches, or NULL */
3794  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3795  * solving process should be stopped (e.g., due to a time limit) */
3796  )
3797 {
3798  SCIP_COL** cols;
3799  int j;
3800 
3801  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarsStrongbranchesFrac", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3802 
3803  assert( lperror != NULL );
3804  assert( vars != NULL );
3805 
3806  /* set up data */
3807  cols = NULL;
3808  SCIP_CALL( SCIPallocBufferArray(scip, &cols, nvars) );
3809  assert(cols != NULL);
3810  for( j = 0; j < nvars; ++j )
3811  {
3812  SCIP_VAR* var;
3813  SCIP_COL* col;
3814 
3815  if( downvalid != NULL )
3816  downvalid[j] = FALSE;
3817  if( upvalid != NULL )
3818  upvalid[j] = FALSE;
3819  if( downinf != NULL )
3820  downinf[j] = FALSE;
3821  if( upinf != NULL )
3822  upinf[j] = FALSE;
3823  if( downconflict != NULL )
3824  downconflict[j] = FALSE;
3825  if( upconflict != NULL )
3826  upconflict[j] = FALSE;
3827 
3828  var = vars[j];
3829  assert( var != NULL );
3831  {
3832  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3833  SCIPfreeBufferArray(scip, &cols);
3834  return SCIP_INVALIDDATA;
3835  }
3836 
3837  col = SCIPvarGetCol(var);
3838  assert(col != NULL);
3839  cols[j] = col;
3840 
3841  if( !SCIPcolIsInLP(col) )
3842  {
3843  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3844  SCIPfreeBufferArray(scip, &cols);
3845  return SCIP_INVALIDDATA;
3846  }
3847  }
3848 
3849  /* check if the solving process should be aborted */
3850  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3851  {
3852  /* mark this as if the LP failed */
3853  *lperror = TRUE;
3854  }
3855  else
3856  {
3857  /* call strong branching for columns with fractional value */
3858  SCIP_CALL( SCIPcolGetStrongbranches(cols, nvars, FALSE, scip->set, scip->stat, scip->transprob, scip->lp, itlim,
3859  down, up, downvalid, upvalid, lperror) );
3860 
3861  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3862  * declare the sub nodes infeasible
3863  */
3864  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3865  {
3866  for( j = 0; j < nvars; ++j )
3867  {
3868  SCIP_CALL( analyzeStrongbranch(scip, vars[j], (downinf != NULL) ? (&(downinf[j])) : NULL,
3869  (upinf != NULL) ? (&(upinf[j])) : NULL, (downconflict != NULL) ? (&(downconflict[j])) : NULL,
3870  (upconflict != NULL) ? (&(upconflict[j])) : NULL) );
3871  }
3872  }
3873  }
3874  SCIPfreeBufferArray(scip, &cols);
3875 
3876  return SCIP_OKAY;
3877 }
3878 
3879 /** gets strong branching information on column variables with integral values
3880  *
3881  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3882  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3883  *
3884  * @pre This method can be called if @p scip is in one of the following stages:
3885  * - \ref SCIP_STAGE_PRESOLVED
3886  * - \ref SCIP_STAGE_SOLVING
3887  */
3889  SCIP* scip, /**< SCIP data structure */
3890  SCIP_VAR** vars, /**< variables to get strong branching values for */
3891  int nvars, /**< number of variables */
3892  int itlim, /**< iteration limit for strong branchings */
3893  SCIP_Real* down, /**< stores dual bounds after branching variables down */
3894  SCIP_Real* up, /**< stores dual bounds after branching variables up */
3895  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
3896  * otherwise, they can only be used as an estimate value */
3897  SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
3898  * otherwise, they can only be used as an estimate value */
3899  SCIP_Bool* downinf, /**< array to store whether the downward branches are infeasible, or NULL */
3900  SCIP_Bool* upinf, /**< array to store whether the upward branches are infeasible, or NULL */
3901  SCIP_Bool* downconflict, /**< array to store whether conflict constraints were created for
3902  * infeasible downward branches, or NULL */
3903  SCIP_Bool* upconflict, /**< array to store whether conflict constraints were created for
3904  * infeasible upward branches, or NULL */
3905  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3906  * solving process should be stopped (e.g., due to a time limit) */
3907  )
3908 {
3909  SCIP_COL** cols;
3910  int j;
3911 
3912  assert(lperror != NULL);
3913 
3914  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarsStrongbranchesInt", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3915 
3916  assert( vars != NULL );
3917 
3918  /* set up data */
3919  cols = NULL;
3920  SCIP_CALL( SCIPallocBufferArray(scip, &cols, nvars) );
3921  assert(cols != NULL);
3922  for( j = 0; j < nvars; ++j )
3923  {
3924  SCIP_VAR* var;
3925  SCIP_COL* col;
3926 
3927  if( downvalid != NULL )
3928  downvalid[j] = FALSE;
3929  if( upvalid != NULL )
3930  upvalid[j] = FALSE;
3931  if( downinf != NULL )
3932  downinf[j] = FALSE;
3933  if( upinf != NULL )
3934  upinf[j] = FALSE;
3935  if( downconflict != NULL )
3936  downconflict[j] = FALSE;
3937  if( upconflict != NULL )
3938  upconflict[j] = FALSE;
3939 
3940  var = vars[j];
3941  assert( var != NULL );
3943  {
3944  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3945  SCIPfreeBufferArray(scip, &cols);
3946  return SCIP_INVALIDDATA;
3947  }
3948 
3949  col = SCIPvarGetCol(var);
3950  assert(col != NULL);
3951  cols[j] = col;
3952 
3953  if( !SCIPcolIsInLP(col) )
3954  {
3955  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3956  SCIPfreeBufferArray(scip, &cols);
3957  return SCIP_INVALIDDATA;
3958  }
3959  }
3960 
3961  /* check if the solving process should be aborted */
3962  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3963  {
3964  /* mark this as if the LP failed */
3965  *lperror = TRUE;
3966  }
3967  else
3968  {
3969  /* call strong branching for columns */
3970  SCIP_CALL( SCIPcolGetStrongbranches(cols, nvars, TRUE, scip->set, scip->stat, scip->transprob, scip->lp, itlim,
3971  down, up, downvalid, upvalid, lperror) );
3972 
3973  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3974  * declare the sub nodes infeasible
3975  */
3976  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3977  {
3978  for( j = 0; j < nvars; ++j )
3979  {
3980  SCIP_CALL( analyzeStrongbranch(scip, vars[j], (downinf != NULL) ? (&(downinf[j])) : NULL,
3981  (upinf != NULL) ? (&(upinf[j])) : NULL, (downconflict != NULL) ? (&(downconflict[j])) : NULL,
3982  (upconflict != NULL) ? (&(upconflict[j])) : NULL) );
3983  }
3984  }
3985  }
3986  SCIPfreeBufferArray(scip, &cols);
3987 
3988  return SCIP_OKAY;
3989 }
3990 
3991 /** get LP solution status of last strong branching call (currently only works for strong branching with propagation) */
3993  SCIP* scip, /**< SCIP data structure */
3994  SCIP_BRANCHDIR branchdir /**< branching direction for which LP solution status is requested */
3995  )
3996 {
3997  assert(NULL != scip);
3998  assert(branchdir == SCIP_BRANCHDIR_DOWNWARDS || branchdir == SCIP_BRANCHDIR_UPWARDS);
3999 
4000  return scip->stat->lastsblpsolstats[branchdir == SCIP_BRANCHDIR_DOWNWARDS ? 0 : 1];
4001 }
4002 
4003 /** gets strong branching information on COLUMN variable of the last SCIPgetVarStrongbranch() call;
4004  * returns values of SCIP_INVALID, if strong branching was not yet called on the given variable;
4005  * keep in mind, that the returned old values may have nothing to do with the current LP solution
4006  *
4007  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4008  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4009  *
4010  * @pre This method can be called if @p scip is in one of the following stages:
4011  * - \ref SCIP_STAGE_SOLVING
4012  * - \ref SCIP_STAGE_SOLVED
4013  */
4015  SCIP* scip, /**< SCIP data structure */
4016  SCIP_VAR* var, /**< variable to get last strong branching values for */
4017  SCIP_Real* down, /**< stores dual bound after branching column down */
4018  SCIP_Real* up, /**< stores dual bound after branching column up */
4019  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4020  * otherwise, it can only be used as an estimate value */
4021  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4022  * otherwise, it can only be used as an estimate value */
4023  SCIP_Real* solval, /**< stores LP solution value of variable at the last strong branching call, or NULL */
4024  SCIP_Real* lpobjval /**< stores LP objective value at last strong branching call, or NULL */
4025  )
4026 {
4027  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchLast", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
4028 
4030  {
4031  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable\n");
4032  return SCIP_INVALIDDATA;
4033  }
4034 
4035  SCIPcolGetStrongbranchLast(SCIPvarGetCol(var), down, up, downvalid, upvalid, solval, lpobjval);
4036 
4037  return SCIP_OKAY;
4038 }
4039 
4040 /** sets strong branching information for a column variable
4041  *
4042  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4043  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4044  *
4045  * @pre This method can be called if @p scip is in one of the following stages:
4046  * - \ref SCIP_STAGE_SOLVING
4047  */
4049  SCIP* scip, /**< SCIP data structure */
4050  SCIP_VAR* var, /**< variable to set last strong branching values for */
4051  SCIP_Real lpobjval, /**< objective value of the current LP */
4052  SCIP_Real primsol, /**< primal solution value of the column in the current LP */
4053  SCIP_Real down, /**< dual bound after branching column down */
4054  SCIP_Real up, /**< dual bound after branching column up */
4055  SCIP_Bool downvalid, /**< is the returned down value a valid dual bound? */
4056  SCIP_Bool upvalid, /**< is the returned up value a valid dual bound? */
4057  SCIP_Longint iter, /**< total number of strong branching iterations */
4058  int itlim /**< iteration limit applied to the strong branching call */
4059  )
4060 {
4061  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetVarStrongbranchData", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4062 
4064  {
4065  SCIPerrorMessage("cannot set strong branching information on non-COLUMN variable\n");
4066  return SCIP_INVALIDDATA;
4067  }
4068 
4069  SCIPcolSetStrongbranchData(SCIPvarGetCol(var), scip->set, scip->stat, scip->lp, lpobjval, primsol,
4070  down, up, downvalid, upvalid, iter, itlim);
4071 
4072  return SCIP_OKAY;
4073 }
4074 
4075 /** rounds the current solution and tries it afterwards; if feasible, adds it to storage
4076  *
4077  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4078  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4079  *
4080  * @pre This method can be called if @p scip is in one of the following stages:
4081  * - \ref SCIP_STAGE_SOLVING
4082  */
4084  SCIP* scip, /**< SCIP data structure */
4085  SCIP_Bool* foundsol, /**< stores whether solution was feasible and good enough to keep */
4086  SCIP_Bool* cutoff /**< stores whether solution was cutoff due to exceeding the cutoffbound */
4087  )
4088 {
4089  assert(scip != NULL);
4090  assert(foundsol != NULL);
4091  assert(cutoff != NULL);
4092 
4093  SCIP_CALL( SCIPcheckStage(scip, "SCIPtryStrongbranchLPSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4094 
4095  if( scip->set->branch_checksbsol )
4096  {
4097  SCIP_SOL* sol;
4098  SCIP_Bool rounded = TRUE;
4099  SCIP_Real value = SCIPgetLPObjval(scip);
4100  SCIP_Longint oldnbestsolsfound = scip->primal->nbestsolsfound;
4101 
4102  /* start clock for strong branching solutions */
4103  SCIPclockStart(scip->stat->sbsoltime, scip->set);
4104 
4105  SCIP_CALL( SCIPcreateLPSol(scip, &sol, NULL) );
4107 
4108  /* try to round the strong branching solution */
4109  if( scip->set->branch_roundsbsol )
4110  {
4111  SCIP_CALL( SCIProundSol(scip, sol, &rounded) );
4112  }
4113 
4114  /* check the solution for feasibility if rounding worked well (or was not tried) */
4115  if( rounded )
4116  {
4117  SCIP_CALL( SCIPtrySolFree(scip, &sol, FALSE, FALSE, FALSE, TRUE, FALSE, foundsol) );
4118  }
4119  else
4120  {
4121  SCIP_CALL( SCIPfreeSol(scip, &sol) );
4122  }
4123 
4124  if( *foundsol )
4125  {
4126  SCIPdebugMsg(scip, "found new solution in strong branching\n");
4127 
4128  scip->stat->nsbsolsfound++;
4129 
4130  if( scip->primal->nbestsolsfound != oldnbestsolsfound )
4131  {
4132  scip->stat->nsbbestsolsfound++;
4133  }
4134 
4135  if( SCIPisGE(scip, value, SCIPgetCutoffbound(scip)) )
4136  *cutoff = TRUE;
4137  }
4138 
4139  /* stop clock for strong branching solutions */
4140  SCIPclockStop(scip->stat->sbsoltime, scip->set);
4141  }
4142  return SCIP_OKAY;
4143 }
4144 
4145 
4146 /** gets node number of the last node in current branch and bound run, where strong branching was used on the
4147  * given variable, or -1 if strong branching was never applied to the variable in current run
4148  *
4149  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4150  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4151  *
4152  * @pre This method can be called if @p scip is in one of the following stages:
4153  * - \ref SCIP_STAGE_TRANSFORMING
4154  * - \ref SCIP_STAGE_TRANSFORMED
4155  * - \ref SCIP_STAGE_INITPRESOLVE
4156  * - \ref SCIP_STAGE_PRESOLVING
4157  * - \ref SCIP_STAGE_EXITPRESOLVE
4158  * - \ref SCIP_STAGE_PRESOLVED
4159  * - \ref SCIP_STAGE_INITSOLVE
4160  * - \ref SCIP_STAGE_SOLVING
4161  * - \ref SCIP_STAGE_SOLVED
4162  * - \ref SCIP_STAGE_EXITSOLVE
4163  */
4165  SCIP* scip, /**< SCIP data structure */
4166  SCIP_VAR* var /**< variable to get last strong branching node for */
4167  )
4168 {
4169  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarStrongbranchNode", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4170 
4171  assert( var->scip == scip );
4172 
4174  return -1;
4175 
4177 }
4178 
4179 /** if strong branching was already applied on the variable at the current node, returns the number of LPs solved after
4180  * the LP where the strong branching on this variable was applied;
4181  * if strong branching was not yet applied on the variable at the current node, returns INT_MAX
4182  *
4183  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4184  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4185  *
4186  * @pre This method can be called if @p scip is in one of the following stages:
4187  * - \ref SCIP_STAGE_TRANSFORMING
4188  * - \ref SCIP_STAGE_TRANSFORMED
4189  * - \ref SCIP_STAGE_INITPRESOLVE
4190  * - \ref SCIP_STAGE_PRESOLVING
4191  * - \ref SCIP_STAGE_EXITPRESOLVE
4192  * - \ref SCIP_STAGE_PRESOLVED
4193  * - \ref SCIP_STAGE_INITSOLVE
4194  * - \ref SCIP_STAGE_SOLVING
4195  * - \ref SCIP_STAGE_SOLVED
4196  * - \ref SCIP_STAGE_EXITSOLVE
4197  */
4199  SCIP* scip, /**< SCIP data structure */
4200  SCIP_VAR* var /**< variable to get strong branching LP age for */
4201  )
4202 {
4203  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarStrongbranchLPAge", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4204 
4205  assert( var->scip == scip );
4206 
4208  return SCIP_LONGINT_MAX;
4209 
4210  return SCIPcolGetStrongbranchLPAge(SCIPvarGetCol(var), scip->stat);
4211 }
4212 
4213 /** gets number of times, strong branching was applied in current run on the given variable
4214  *
4215  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4216  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4217  *
4218  * @pre This method can be called if @p scip is in one of the following stages:
4219  * - \ref SCIP_STAGE_TRANSFORMING
4220  * - \ref SCIP_STAGE_TRANSFORMED
4221  * - \ref SCIP_STAGE_INITPRESOLVE
4222  * - \ref SCIP_STAGE_PRESOLVING
4223  * - \ref SCIP_STAGE_EXITPRESOLVE
4224  * - \ref SCIP_STAGE_PRESOLVED
4225  * - \ref SCIP_STAGE_INITSOLVE
4226  * - \ref SCIP_STAGE_SOLVING
4227  * - \ref SCIP_STAGE_SOLVED
4228  * - \ref SCIP_STAGE_EXITSOLVE
4229  */
4231  SCIP* scip, /**< SCIP data structure */
4232  SCIP_VAR* var /**< variable to get last strong branching node for */
4233  )
4234 {
4235  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarNStrongbranchs", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4236 
4237  assert( var->scip == scip );
4238 
4240  return 0;
4241 
4243 }
4244 
4245 /** adds given values to lock numbers of type @p locktype of variable for rounding
4246  *
4247  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4248  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4249  *
4250  * @pre This method can be called if @p scip is in one of the following stages:
4251  * - \ref SCIP_STAGE_PROBLEM
4252  * - \ref SCIP_STAGE_TRANSFORMING
4253  * - \ref SCIP_STAGE_TRANSFORMED
4254  * - \ref SCIP_STAGE_INITPRESOLVE
4255  * - \ref SCIP_STAGE_PRESOLVING
4256  * - \ref SCIP_STAGE_EXITPRESOLVE
4257  * - \ref SCIP_STAGE_PRESOLVED
4258  * - \ref SCIP_STAGE_INITSOLVE
4259  * - \ref SCIP_STAGE_SOLVING
4260  * - \ref SCIP_STAGE_EXITSOLVE
4261  * - \ref SCIP_STAGE_FREETRANS
4262  */
4264  SCIP* scip, /**< SCIP data structure */
4265  SCIP_VAR* var, /**< problem variable */
4266  SCIP_LOCKTYPE locktype, /**< type of the variable locks */
4267  int nlocksdown, /**< modification in number of rounding down locks */
4268  int nlocksup /**< modification in number of rounding up locks */
4269  )
4270 {
4271  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarLocksType", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4272 
4273  assert( var->scip == scip );
4274 
4275  switch( scip->set->stage )
4276  {
4277  case SCIP_STAGE_PROBLEM:
4278  assert(!SCIPvarIsTransformed(var));
4279  /*lint -fallthrough*/
4283  case SCIP_STAGE_PRESOLVING:
4285  case SCIP_STAGE_PRESOLVED:
4286  case SCIP_STAGE_INITSOLVE:
4287  case SCIP_STAGE_SOLVING:
4288  case SCIP_STAGE_EXITSOLVE:
4289  case SCIP_STAGE_FREETRANS:
4290  SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, locktype, nlocksdown, nlocksup) );
4291  return SCIP_OKAY;
4292 
4293  default:
4294  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4295  return SCIP_INVALIDCALL;
4296  } /*lint !e788*/
4297 }
4298 
4299 /** adds given values to lock numbers of variable for rounding
4300  *
4301  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4302  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4303  *
4304  * @pre This method can be called if @p scip is in one of the following stages:
4305  * - \ref SCIP_STAGE_PROBLEM
4306  * - \ref SCIP_STAGE_TRANSFORMING
4307  * - \ref SCIP_STAGE_TRANSFORMED
4308  * - \ref SCIP_STAGE_INITPRESOLVE
4309  * - \ref SCIP_STAGE_PRESOLVING
4310  * - \ref SCIP_STAGE_EXITPRESOLVE
4311  * - \ref SCIP_STAGE_PRESOLVED
4312  * - \ref SCIP_STAGE_INITSOLVE
4313  * - \ref SCIP_STAGE_SOLVING
4314  * - \ref SCIP_STAGE_EXITSOLVE
4315  * - \ref SCIP_STAGE_FREETRANS
4316  *
4317  * @note This method will always add variable locks of type model
4318  *
4319  * @note It is recommented to use SCIPaddVarLocksType()
4320  */
4322  SCIP* scip, /**< SCIP data structure */
4323  SCIP_VAR* var, /**< problem variable */
4324  int nlocksdown, /**< modification in number of rounding down locks */
4325  int nlocksup /**< modification in number of rounding up locks */
4326  )
4327 {
4328  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarLocks", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4329 
4330  SCIP_CALL( SCIPaddVarLocksType(scip, var, SCIP_LOCKTYPE_MODEL, nlocksdown, nlocksup) );
4331 
4332  return SCIP_OKAY;
4333 }
4334 
4335 /** add locks of variable with respect to the lock status of the constraint and its negation;
4336  * this method should be called whenever the lock status of a variable in a constraint changes, for example if
4337  * the coefficient of the variable changed its sign or if the left or right hand sides of the constraint were
4338  * added or removed
4339  *
4340  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4341  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4342  *
4343  * @pre This method can be called if @p scip is in one of the following stages:
4344  * - \ref SCIP_STAGE_PROBLEM
4345  * - \ref SCIP_STAGE_TRANSFORMING
4346  * - \ref SCIP_STAGE_INITPRESOLVE
4347  * - \ref SCIP_STAGE_PRESOLVING
4348  * - \ref SCIP_STAGE_EXITPRESOLVE
4349  * - \ref SCIP_STAGE_INITSOLVE
4350  * - \ref SCIP_STAGE_SOLVING
4351  * - \ref SCIP_STAGE_EXITSOLVE
4352  * - \ref SCIP_STAGE_FREETRANS
4353  */
4355  SCIP* scip, /**< SCIP data structure */
4356  SCIP_VAR* var, /**< problem variable */
4357  SCIP_CONS* cons, /**< constraint */
4358  SCIP_Bool lockdown, /**< should the rounding be locked in downwards direction? */
4359  SCIP_Bool lockup /**< should the rounding be locked in upwards direction? */
4360  )
4361 {
4362  int nlocksdown[NLOCKTYPES];
4363  int nlocksup[NLOCKTYPES];
4364  int i;
4365 
4366  SCIP_CALL( SCIPcheckStage(scip, "SCIPlockVarCons", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4367 
4368  assert( var->scip == scip );
4369 
4370  for( i = 0; i < NLOCKTYPES; i++ )
4371  {
4372  nlocksdown[i] = 0;
4373  nlocksup[i] = 0;
4374 
4375  if( SCIPconsIsLockedTypePos(cons, (SCIP_LOCKTYPE) i) )
4376  {
4377  if( lockdown )
4378  ++nlocksdown[i];
4379  if( lockup )
4380  ++nlocksup[i];
4381  }
4382  if( SCIPconsIsLockedTypeNeg(cons, (SCIP_LOCKTYPE) i) )
4383  {
4384  if( lockdown )
4385  ++nlocksup[i];
4386  if( lockup )
4387  ++nlocksdown[i];
4388  }
4389  }
4390 
4391  switch( scip->set->stage )
4392  {
4393  case SCIP_STAGE_PROBLEM:
4394  assert(!SCIPvarIsTransformed(var));
4395  /*lint -fallthrough*/
4399  case SCIP_STAGE_PRESOLVING:
4401  case SCIP_STAGE_INITSOLVE:
4402  case SCIP_STAGE_SOLVING:
4403  case SCIP_STAGE_EXITSOLVE:
4404  case SCIP_STAGE_FREETRANS:
4405  for( i = 0; i < NLOCKTYPES; i++ )
4406  {
4407  if( nlocksdown[i] == 0 && nlocksup[i] == 0 )
4408  continue;
4409 
4410  SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, (SCIP_LOCKTYPE) i, nlocksdown[i], nlocksup[i]) );
4411  }
4412  return SCIP_OKAY;
4413 
4414  default:
4415  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4416  return SCIP_INVALIDCALL;
4417  } /*lint !e788*/
4418 }
4419 
4420 /** remove locks of type @p locktype of variable with respect to the lock status of the constraint and its negation;
4421  * this method should be called whenever the lock status of a variable in a constraint changes, for example if
4422  * the coefficient of the variable changed its sign or if the left or right hand sides of the constraint were
4423  * added or removed
4424  *
4425  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4426  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4427  *
4428  * @pre This method can be called if @p scip is in one of the following stages:
4429  * - \ref SCIP_STAGE_PROBLEM
4430  * - \ref SCIP_STAGE_TRANSFORMING
4431  * - \ref SCIP_STAGE_INITPRESOLVE
4432  * - \ref SCIP_STAGE_PRESOLVING
4433  * - \ref SCIP_STAGE_EXITPRESOLVE
4434  * - \ref SCIP_STAGE_INITSOLVE
4435  * - \ref SCIP_STAGE_SOLVING
4436  * - \ref SCIP_STAGE_EXITSOLVE
4437  * - \ref SCIP_STAGE_FREETRANS
4438  */
4440  SCIP* scip, /**< SCIP data structure */
4441  SCIP_VAR* var, /**< problem variable */
4442  SCIP_CONS* cons, /**< constraint */
4443  SCIP_Bool lockdown, /**< should the rounding be unlocked in downwards direction? */
4444  SCIP_Bool lockup /**< should the rounding be unlocked in upwards direction? */
4445  )
4446 {
4447  int nlocksdown[NLOCKTYPES];
4448  int nlocksup[NLOCKTYPES];
4449  int i;
4450 
4451  SCIP_CALL( SCIPcheckStage(scip, "SCIPunlockVarCons", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4452 
4453  assert( var->scip == scip );
4454 
4455  for( i = 0; i < NLOCKTYPES; i++ )
4456  {
4457  nlocksdown[i] = 0;
4458  nlocksup[i] = 0;
4459 
4460  if( SCIPconsIsLockedTypePos(cons, (SCIP_LOCKTYPE) i) )
4461  {
4462  if( lockdown )
4463  ++nlocksdown[i];
4464  if( lockup )
4465  ++nlocksup[i];
4466  }
4467  if( SCIPconsIsLockedTypeNeg(cons, (SCIP_LOCKTYPE) i) )
4468  {
4469  if( lockdown )
4470  ++nlocksup[i];
4471  if( lockup )
4472  ++nlocksdown[i];
4473  }
4474  }
4475  switch( scip->set->stage )
4476  {
4477  case SCIP_STAGE_PROBLEM:
4478  assert(!SCIPvarIsTransformed(var));
4479  /*lint -fallthrough*/
4482  case SCIP_STAGE_PRESOLVING:
4484  case SCIP_STAGE_INITSOLVE:
4485  case SCIP_STAGE_SOLVING:
4486  case SCIP_STAGE_EXITSOLVE:
4487  case SCIP_STAGE_FREETRANS:
4488  for( i = 0; i < NLOCKTYPES; i++ )
4489  {
4490  if( nlocksdown[i] == 0 && nlocksup[i] == 0 )
4491  continue;
4492 
4493  SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, (SCIP_LOCKTYPE) i, -nlocksdown[i], -nlocksup[i]) );
4494  }
4495  return SCIP_OKAY;
4496 
4497  default:
4498  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4499  return SCIP_INVALIDCALL;
4500  } /*lint !e788*/
4501 }
4502 
4503 /** changes variable's objective value
4504  *
4505  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4506  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4507  *
4508  * @pre This method can be called if @p scip is in one of the following stages:
4509  * - \ref SCIP_STAGE_PROBLEM
4510  * - \ref SCIP_STAGE_TRANSFORMING
4511  * - \ref SCIP_STAGE_PRESOLVING
4512  * - \ref SCIP_STAGE_PRESOLVED
4513  */
4515  SCIP* scip, /**< SCIP data structure */
4516  SCIP_VAR* var, /**< variable to change the objective value for */
4517  SCIP_Real newobj /**< new objective value */
4518  )
4519 {
4520  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarObj", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
4521 
4522  assert( var->scip == scip );
4523 
4524  /* forbid infinite objective values */
4525  if( SCIPisInfinity(scip, REALABS(newobj)) )
4526  {
4527  SCIPerrorMessage("invalid objective value: objective value is infinite\n");
4528  return SCIP_INVALIDDATA;
4529  }
4530 
4531  switch( scip->set->stage )
4532  {
4533  case SCIP_STAGE_PROBLEM:
4534  assert(!SCIPvarIsTransformed(var));
4535  SCIP_CALL( SCIPvarChgObj(var, scip->mem->probmem, scip->set, scip->origprob, scip->primal, scip->lp, scip->eventqueue, newobj) );
4536  return SCIP_OKAY;
4537 
4540  case SCIP_STAGE_PRESOLVING:
4541  case SCIP_STAGE_PRESOLVED:
4542  SCIP_CALL( SCIPvarChgObj(var, scip->mem->probmem, scip->set, scip->transprob, scip->primal, scip->lp, scip->eventqueue, newobj) );
4543  return SCIP_OKAY;
4544 
4545  default:
4546  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4547  return SCIP_INVALIDCALL;
4548  } /*lint !e788*/
4549 }
4550 
4551 /** adds value to variable's objective value
4552  *
4553  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4554  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4555  *
4556  * @pre This method can be called if @p scip is in one of the following stages:
4557  * - \ref SCIP_STAGE_PROBLEM
4558  * - \ref SCIP_STAGE_TRANSFORMING
4559  * - \ref SCIP_STAGE_PRESOLVING
4560  * - \ref SCIP_STAGE_EXITPRESOLVE
4561  * - \ref SCIP_STAGE_PRESOLVED
4562  */
4564  SCIP* scip, /**< SCIP data structure */
4565  SCIP_VAR* var, /**< variable to change the objective value for */
4566  SCIP_Real addobj /**< additional objective value */
4567  )
4568 {
4569  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarObj", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
4570 
4571  assert( var->scip == scip );
4572 
4573  switch( scip->set->stage )
4574  {
4575  case SCIP_STAGE_PROBLEM:
4576  assert(!SCIPvarIsTransformed(var));
4577  SCIP_CALL( SCIPvarAddObj(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->primal,
4578  scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue, addobj) );
4579  return SCIP_OKAY;
4580 
4582  case SCIP_STAGE_PRESOLVING:
4584  case SCIP_STAGE_PRESOLVED:
4585  SCIP_CALL( SCIPvarAddObj(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->primal,
4586  scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue, addobj) );
4587  return SCIP_OKAY;
4588 
4589  default:
4590  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4591  return SCIP_INVALIDCALL;
4592  } /*lint !e788*/
4593 }
4594 
4595 /** returns the adjusted (i.e. rounded, if the given variable is of integral type) lower bound value;
4596  * does not change the bounds of the variable
4597  *
4598  * @return adjusted lower bound for the given variable; the bound of the variable is not changed
4599  *
4600  * @pre This method can be called if @p scip is in one of the following stages:
4601  * - \ref SCIP_STAGE_PROBLEM
4602  * - \ref SCIP_STAGE_TRANSFORMING
4603  * - \ref SCIP_STAGE_TRANSFORMED
4604  * - \ref SCIP_STAGE_INITPRESOLVE
4605  * - \ref SCIP_STAGE_PRESOLVING
4606  * - \ref SCIP_STAGE_EXITPRESOLVE
4607  * - \ref SCIP_STAGE_PRESOLVED
4608  * - \ref SCIP_STAGE_INITSOLVE
4609  * - \ref SCIP_STAGE_SOLVING
4610  * - \ref SCIP_STAGE_SOLVED
4611  * - \ref SCIP_STAGE_EXITSOLVE
4612  * - \ref SCIP_STAGE_FREETRANS
4613  */
4615  SCIP* scip, /**< SCIP data structure */
4616  SCIP_VAR* var, /**< variable to adjust the bound for */
4617  SCIP_Real lb /**< lower bound value to adjust */
4618  )
4619 {
4620  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPadjustedVarLb", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
4621 
4622  SCIPvarAdjustLb(var, scip->set, &lb);
4623 
4624  return lb;
4625 }
4626 
4627 /** returns the adjusted (i.e. rounded, if the given variable is of integral type) upper bound value;
4628  * does not change the bounds of the variable
4629  *
4630  * @return adjusted upper bound for the given variable; the bound of the variable is not changed
4631  *
4632  * @pre This method can be called if @p scip is in one of the following stages:
4633  * - \ref SCIP_STAGE_PROBLEM
4634  * - \ref SCIP_STAGE_TRANSFORMING
4635  * - \ref SCIP_STAGE_TRANSFORMED
4636  * - \ref SCIP_STAGE_INITPRESOLVE
4637  * - \ref SCIP_STAGE_PRESOLVING
4638  * - \ref SCIP_STAGE_EXITPRESOLVE
4639  * - \ref SCIP_STAGE_PRESOLVED
4640  * - \ref SCIP_STAGE_INITSOLVE
4641  * - \ref SCIP_STAGE_SOLVING
4642  * - \ref SCIP_STAGE_SOLVED
4643  * - \ref SCIP_STAGE_EXITSOLVE
4644  * - \ref SCIP_STAGE_FREETRANS
4645  */
4647  SCIP* scip, /**< SCIP data structure */
4648  SCIP_VAR* var, /**< variable to adjust the bound for */
4649  SCIP_Real ub /**< upper bound value to adjust */
4650  )
4651 {
4652  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPadjustedVarUb", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
4653 
4654  SCIPvarAdjustUb(var, scip->set, &ub);
4655 
4656  return ub;
4657 }
4658 
4659 /** depending on SCIP's stage, changes lower bound of variable in the problem, in preprocessing, or in current node;
4660  * if possible, adjusts bound to integral value; doesn't store any inference information in the bound change, such
4661  * that in conflict analysis, this change is treated like a branching decision
4662  *
4663  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4664  * SCIPgetVars()) gets resorted.
4665  *
4666  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4667  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4668  *
4669  * @pre This method can be called if @p scip is in one of the following stages:
4670  * - \ref SCIP_STAGE_PROBLEM
4671  * - \ref SCIP_STAGE_TRANSFORMING
4672  * - \ref SCIP_STAGE_PRESOLVING
4673  * - \ref SCIP_STAGE_SOLVING
4674  *
4675  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4676  */
4678  SCIP* scip, /**< SCIP data structure */
4679  SCIP_VAR* var, /**< variable to change the bound for */
4680  SCIP_Real newbound /**< new value for bound */
4681  )
4682 {
4683  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLb", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4684 
4685  SCIPvarAdjustLb(var, scip->set, &newbound);
4686 
4687  /* ignore tightenings of lower bounds to +infinity during solving process */
4688  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4689  {
4690 #ifndef NDEBUG
4691  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4692  SCIPvarGetLbLocal(var));
4693 #endif
4694  return SCIP_OKAY;
4695  }
4696 
4697  switch( scip->set->stage )
4698  {
4699  case SCIP_STAGE_PROBLEM:
4700  assert(!SCIPvarIsTransformed(var));
4701  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4702  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4703  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4704  scip->branchcand, scip->eventqueue, newbound) );
4705  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
4706  break;
4707 
4709  case SCIP_STAGE_PRESOLVED:
4710  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4711  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4712  break;
4713 
4714  case SCIP_STAGE_PRESOLVING:
4715  if( !SCIPinProbing(scip) )
4716  {
4717  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4718  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4719 
4720  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4721  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable,
4722  var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
4723 
4725  {
4726  SCIP_Bool infeasible;
4727 
4728  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
4729  assert(!infeasible);
4730  }
4731  break;
4732  }
4733  /*lint -fallthrough*/
4734  case SCIP_STAGE_SOLVING:
4736  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4737  scip->cliquetable, var, newbound,
4739  break;
4740 
4741  default:
4742  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4743  return SCIP_INVALIDCALL;
4744  } /*lint !e788*/
4745 
4746  return SCIP_OKAY;
4747 }
4748 
4749 /** depending on SCIP's stage, changes upper bound of variable in the problem, in preprocessing, or in current node;
4750  * if possible, adjusts bound to integral value; doesn't store any inference information in the bound change, such
4751  * that in conflict analysis, this change is treated like a branching decision
4752  *
4753  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4754  * SCIPgetVars()) gets resorted.
4755  *
4756  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4757  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4758  *
4759  * @pre This method can be called if @p scip is in one of the following stages:
4760  * - \ref SCIP_STAGE_PROBLEM
4761  * - \ref SCIP_STAGE_TRANSFORMING
4762  * - \ref SCIP_STAGE_PRESOLVING
4763  * - \ref SCIP_STAGE_SOLVING
4764  *
4765  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4766  */
4768  SCIP* scip, /**< SCIP data structure */
4769  SCIP_VAR* var, /**< variable to change the bound for */
4770  SCIP_Real newbound /**< new value for bound */
4771  )
4772 {
4773  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUb", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4774 
4775  SCIPvarAdjustUb(var, scip->set, &newbound);
4776 
4777  /* ignore tightenings of upper bounds to -infinity during solving process */
4778  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4779  {
4780 #ifndef NDEBUG
4781  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
4782  SCIPvarGetUbLocal(var));
4783 #endif
4784  return SCIP_OKAY;
4785  }
4786 
4787  switch( scip->set->stage )
4788  {
4789  case SCIP_STAGE_PROBLEM:
4790  assert(!SCIPvarIsTransformed(var));
4791  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4792  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4793  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4794  scip->branchcand, scip->eventqueue, newbound) );
4795  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
4796  break;
4797 
4799  case SCIP_STAGE_PRESOLVED:
4800  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4801  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4802  break;
4803 
4804  case SCIP_STAGE_PRESOLVING:
4805  if( !SCIPinProbing(scip) )
4806  {
4807  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4808  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4809 
4810  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4811  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4812  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
4813 
4815  {
4816  SCIP_Bool infeasible;
4817 
4818  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
4819  assert(!infeasible);
4820  }
4821  break;
4822  }
4823  /*lint -fallthrough*/
4824  case SCIP_STAGE_SOLVING:
4826  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4827  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
4828  break;
4829 
4830  default:
4831  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4832  return SCIP_INVALIDCALL;
4833  } /*lint !e788*/
4834 
4835  return SCIP_OKAY;
4836 }
4837 
4838 /** changes lower bound of variable in the given node; if possible, adjust bound to integral value; doesn't store any
4839  * inference information in the bound change, such that in conflict analysis, this change is treated like a branching
4840  * decision
4841  *
4842  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4843  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4844  *
4845  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
4846  */
4848  SCIP* scip, /**< SCIP data structure */
4849  SCIP_NODE* node, /**< node to change bound at, or NULL for current node */
4850  SCIP_VAR* var, /**< variable to change the bound for */
4851  SCIP_Real newbound /**< new value for bound */
4852  )
4853 {
4854  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbNode", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4855 
4856  if( node == NULL )
4857  {
4858  SCIP_CALL( SCIPchgVarLb(scip, var, newbound) );
4859  }
4860  else
4861  {
4862  SCIPvarAdjustLb(var, scip->set, &newbound);
4863 
4864  /* ignore tightenings of lower bounds to +infinity during solving process */
4865  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4866  {
4867 #ifndef NDEBUG
4868  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4869  SCIPvarGetLbLocal(var));
4870 #endif
4871  return SCIP_OKAY;
4872  }
4873 
4874  SCIP_CALL( SCIPnodeAddBoundchg(node, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
4875  scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4877  }
4878 
4879  return SCIP_OKAY;
4880 }
4881 
4882 /** changes upper bound of variable in the given node; if possible, adjust bound to integral value; doesn't store any
4883  * inference information in the bound change, such that in conflict analysis, this change is treated like a branching
4884  * decision
4885  *
4886  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4887  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4888  *
4889  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
4890  */
4892  SCIP* scip, /**< SCIP data structure */
4893  SCIP_NODE* node, /**< node to change bound at, or NULL for current node */
4894  SCIP_VAR* var, /**< variable to change the bound for */
4895  SCIP_Real newbound /**< new value for bound */
4896  )
4897 {
4898  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbNode", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4899 
4900  if( node == NULL )
4901  {
4902  SCIP_CALL( SCIPchgVarUb(scip, var, newbound) );
4903  }
4904  else
4905  {
4906  SCIPvarAdjustUb(var, scip->set, &newbound);
4907 
4908  /* ignore tightenings of upper bounds to -infinity during solving process */
4909  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4910  {
4911 #ifndef NDEBUG
4912  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
4913  SCIPvarGetUbLocal(var));
4914 #endif
4915  return SCIP_OKAY;
4916  }
4917 
4918  SCIP_CALL( SCIPnodeAddBoundchg(node, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
4919  scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4921  }
4922 
4923  return SCIP_OKAY;
4924 }
4925 
4926 /** changes global lower bound of variable; if possible, adjust bound to integral value; also tightens the local bound,
4927  * if the global bound is better than the local bound
4928  *
4929  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4930  * SCIPgetVars()) gets resorted.
4931  *
4932  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4933  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4934  *
4935  * @pre This method can be called if @p scip is in one of the following stages:
4936  * - \ref SCIP_STAGE_PROBLEM
4937  * - \ref SCIP_STAGE_TRANSFORMING
4938  * - \ref SCIP_STAGE_PRESOLVING
4939  * - \ref SCIP_STAGE_SOLVING
4940  *
4941  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4942  */
4944  SCIP* scip, /**< SCIP data structure */
4945  SCIP_VAR* var, /**< variable to change the bound for */
4946  SCIP_Real newbound /**< new value for bound */
4947  )
4948 {
4949  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbGlobal", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4950 
4951  SCIPvarAdjustLb(var, scip->set, &newbound);
4952 
4953  /* ignore tightenings of lower bounds to +infinity during solving process */
4954  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4955  {
4956 #ifndef NDEBUG
4957  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4958  SCIPvarGetLbLocal(var));
4959 #endif
4960  return SCIP_OKAY;
4961  }
4962 
4963  switch( scip->set->stage )
4964  {
4965  case SCIP_STAGE_PROBLEM:
4966  assert(!SCIPvarIsTransformed(var));
4967  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4968  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4969  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4970  scip->branchcand, scip->eventqueue, newbound) );
4971  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
4972  break;
4973 
4975  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4976  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4977  break;
4978 
4979  case SCIP_STAGE_PRESOLVING:
4980  if( !SCIPinProbing(scip) )
4981  {
4982  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4983  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4984 
4985  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4986  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4988 
4990  {
4991  SCIP_Bool infeasible;
4992 
4993  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
4994  assert(!infeasible);
4995  }
4996  break;
4997  }
4998  /*lint -fallthrough*/
4999  case SCIP_STAGE_SOLVING:
5000  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5001  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5003  break;
5004 
5005  default:
5006  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5007  return SCIP_INVALIDCALL;
5008  } /*lint !e788*/
5009 
5010  return SCIP_OKAY;
5011 }
5012 
5013 /** changes global upper bound of variable; if possible, adjust bound to integral value; also tightens the local bound,
5014  * if the global bound is better than the local bound
5015  *
5016  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5017  * SCIPgetVars()) gets resorted.
5018  *
5019  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5020  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5021  *
5022  * @pre This method can be called if @p scip is in one of the following stages:
5023  * - \ref SCIP_STAGE_PROBLEM
5024  * - \ref SCIP_STAGE_TRANSFORMING
5025  * - \ref SCIP_STAGE_PRESOLVING
5026  * - \ref SCIP_STAGE_SOLVING
5027  *
5028  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5029  */
5031  SCIP* scip, /**< SCIP data structure */
5032  SCIP_VAR* var, /**< variable to change the bound for */
5033  SCIP_Real newbound /**< new value for bound */
5034  )
5035 {
5036  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbGlobal", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5037 
5038  SCIPvarAdjustUb(var, scip->set, &newbound);
5039