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