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