Scippy

SCIP

Solving Constraint Integer Programs

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