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  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1149  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1150  *
1151  * @pre This method can be called if @p scip is in one of the following stages:
1152  * - \ref SCIP_STAGE_PROBLEM
1153  * - \ref SCIP_STAGE_TRANSFORMING
1154  * - \ref SCIP_STAGE_INITPRESOLVE
1155  * - \ref SCIP_STAGE_PRESOLVING
1156  * - \ref SCIP_STAGE_EXITPRESOLVE
1157  * - \ref SCIP_STAGE_PRESOLVED
1158  * - \ref SCIP_STAGE_SOLVING
1159  */
1161  SCIP* scip, /**< SCIP data structure */
1162  SCIP_VAR**** monomialvars, /**< pointer to store arrays with variables for each monomial */
1163  SCIP_Real*** monomialexps, /**< pointer to store arrays with variable exponents */
1164  SCIP_Real** monomialcoefs, /**< pointer to store array with monomial coefficients */
1165  int** monomialnvars, /**< pointer to store array with number of variables for each monomial */
1166  int nmonomials /**< pointer to store number of parsed monomials */
1167  )
1168 {
1169  int i;
1170 
1171  assert(scip != NULL);
1172  assert(monomialvars != NULL);
1173  assert(monomialexps != NULL);
1174  assert(monomialcoefs != NULL);
1175  assert(monomialnvars != NULL);
1176  assert((*monomialvars != NULL) == (nmonomials > 0));
1177  assert((*monomialexps != NULL) == (nmonomials > 0));
1178  assert((*monomialcoefs != NULL) == (nmonomials > 0));
1179  assert((*monomialnvars != NULL) == (nmonomials > 0));
1180 
1181  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPfreeParseVarsPolynomialData", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1182 
1183  if( nmonomials == 0 )
1184  return;
1185 
1186  for( i = nmonomials - 1; i >= 0; --i )
1187  {
1188  SCIPfreeBlockMemoryArrayNull(scip, &(*monomialexps)[i], (*monomialnvars)[i]);
1189  SCIPfreeBlockMemoryArrayNull(scip, &(*monomialvars)[i], (*monomialnvars)[i]);
1190  }
1191 
1192  SCIPfreeBlockMemoryArray(scip, monomialcoefs, nmonomials);
1193  SCIPfreeBlockMemoryArray(scip, monomialnvars, nmonomials);
1194  SCIPfreeBlockMemoryArray(scip, monomialexps, nmonomials);
1195  SCIPfreeBlockMemoryArray(scip, monomialvars, nmonomials);
1196 }
1197 
1198 /** increases usage counter of variable
1199  *
1200  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1201  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1202  *
1203  * @pre This method can be called if @p scip is in one of the following stages:
1204  * - \ref SCIP_STAGE_PROBLEM
1205  * - \ref SCIP_STAGE_TRANSFORMING
1206  * - \ref SCIP_STAGE_TRANSFORMED
1207  * - \ref SCIP_STAGE_INITPRESOLVE
1208  * - \ref SCIP_STAGE_PRESOLVING
1209  * - \ref SCIP_STAGE_EXITPRESOLVE
1210  * - \ref SCIP_STAGE_PRESOLVED
1211  * - \ref SCIP_STAGE_INITSOLVE
1212  * - \ref SCIP_STAGE_SOLVING
1213  * - \ref SCIP_STAGE_SOLVED
1214  * - \ref SCIP_STAGE_EXITSOLVE
1215  */
1217  SCIP* scip, /**< SCIP data structure */
1218  SCIP_VAR* var /**< variable to capture */
1219  )
1220 {
1221  SCIP_CALL( SCIPcheckStage(scip, "SCIPcaptureVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1222  assert(var->scip == scip);
1223 
1224  SCIPvarCapture(var);
1225 
1226  return SCIP_OKAY;
1227 }
1228 
1229 /** decreases usage counter of variable, if the usage pointer reaches zero the variable gets freed
1230  *
1231  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1232  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1233  *
1234  * @pre This method can be called if @p scip is in one of the following stages:
1235  * - \ref SCIP_STAGE_PROBLEM
1236  * - \ref SCIP_STAGE_TRANSFORMING
1237  * - \ref SCIP_STAGE_TRANSFORMED
1238  * - \ref SCIP_STAGE_INITPRESOLVE
1239  * - \ref SCIP_STAGE_PRESOLVING
1240  * - \ref SCIP_STAGE_EXITPRESOLVE
1241  * - \ref SCIP_STAGE_PRESOLVED
1242  * - \ref SCIP_STAGE_INITSOLVE
1243  * - \ref SCIP_STAGE_SOLVING
1244  * - \ref SCIP_STAGE_SOLVED
1245  * - \ref SCIP_STAGE_EXITSOLVE
1246  * - \ref SCIP_STAGE_FREETRANS
1247  *
1248  * @note the pointer of the variable will be NULLed
1249  */
1251  SCIP* scip, /**< SCIP data structure */
1252  SCIP_VAR** var /**< pointer to variable */
1253  )
1254 {
1255  assert(var != NULL);
1256  assert(*var != NULL);
1257  assert((*var)->scip == scip);
1258 
1259  SCIP_CALL( SCIPcheckStage(scip, "SCIPreleaseVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1260 
1261  switch( scip->set->stage )
1262  {
1263  case SCIP_STAGE_PROBLEM:
1264  SCIP_CALL( SCIPvarRelease(var, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp) );
1265  return SCIP_OKAY;
1266 
1270  case SCIP_STAGE_PRESOLVING:
1272  case SCIP_STAGE_PRESOLVED:
1273  case SCIP_STAGE_INITSOLVE:
1274  case SCIP_STAGE_SOLVING:
1275  case SCIP_STAGE_SOLVED:
1276  case SCIP_STAGE_EXITSOLVE:
1277  case SCIP_STAGE_FREETRANS:
1278  if( !SCIPvarIsTransformed(*var) && (*var)->nuses == 1 && (*var)->data.original.transvar != NULL )
1279  {
1280  SCIPerrorMessage("cannot release last use of original variable while associated transformed variable exists\n");
1281  return SCIP_INVALIDCALL;
1282  }
1283  SCIP_CALL( SCIPvarRelease(var, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp) );
1284  return SCIP_OKAY;
1285 
1286  default:
1287  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
1288  return SCIP_INVALIDCALL;
1289  } /*lint !e788*/
1290 }
1291 
1292 /** changes the name of a variable
1293  *
1294  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1295  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1296  *
1297  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PROBLEM
1298  *
1299  * @note to get the current name of a variable, use SCIPvarGetName() from pub_var.h
1300  */
1302  SCIP* scip, /**< SCIP data structure */
1303  SCIP_VAR* var, /**< variable */
1304  const char* name /**< new name of constraint */
1305  )
1306 {
1307  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarName", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
1308  assert( var->scip == scip );
1309 
1310  if( SCIPgetStage(scip) != SCIP_STAGE_PROBLEM )
1311  {
1312  SCIPerrorMessage("variable names can only be changed in problem creation stage\n");
1313  SCIPABORT();
1314  return SCIP_INVALIDCALL; /*lint !e527*/
1315  }
1316 
1317  /* remove variable's name from the namespace if the variable was already added */
1318  if( SCIPvarGetProbindex(var) != -1 )
1319  {
1320  SCIP_CALL( SCIPprobRemoveVarName(scip->origprob, var) );
1321  }
1322 
1323  /* change variable name */
1324  SCIP_CALL( SCIPvarChgName(var, SCIPblkmem(scip), name) );
1325 
1326  /* add variable's name to the namespace if the variable was already added */
1327  if( SCIPvarGetProbindex(var) != -1 )
1328  {
1329  SCIP_CALL( SCIPprobAddVarName(scip->origprob, var) );
1330  }
1331 
1332  return SCIP_OKAY;
1333 }
1334 
1335 /** gets and captures transformed variable of a given variable; if the variable is not yet transformed,
1336  * a new transformed variable for this variable is created
1337  *
1338  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1339  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1340  *
1341  * @pre This method can be called if @p scip is in one of the following stages:
1342  * - \ref SCIP_STAGE_TRANSFORMING
1343  * - \ref SCIP_STAGE_TRANSFORMED
1344  * - \ref SCIP_STAGE_INITPRESOLVE
1345  * - \ref SCIP_STAGE_PRESOLVING
1346  * - \ref SCIP_STAGE_EXITPRESOLVE
1347  * - \ref SCIP_STAGE_PRESOLVED
1348  * - \ref SCIP_STAGE_INITSOLVE
1349  * - \ref SCIP_STAGE_SOLVING
1350  */
1352  SCIP* scip, /**< SCIP data structure */
1353  SCIP_VAR* var, /**< variable to get/create transformed variable for */
1354  SCIP_VAR** transvar /**< pointer to store the transformed variable */
1355  )
1356 {
1357  assert(transvar != NULL);
1358 
1359  SCIP_CALL( SCIPcheckStage(scip, "SCIPtransformVar", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1360 
1361  if( SCIPvarIsTransformed(var) )
1362  {
1363  *transvar = var;
1364  SCIPvarCapture(*transvar);
1365  }
1366  else
1367  {
1368  SCIP_CALL( SCIPvarTransform(var, scip->mem->probmem, scip->set, scip->stat, scip->origprob->objsense, transvar) );
1369  }
1370 
1371  return SCIP_OKAY;
1372 }
1373 
1374 /** gets and captures transformed variables for an array of variables;
1375  * if a variable of the array is not yet transformed, a new transformed variable for this variable is created;
1376  * it is possible to call this method with vars == transvars
1377  *
1378  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1379  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1380  *
1381  * @pre This method can be called if @p scip is in one of the following stages:
1382  * - \ref SCIP_STAGE_TRANSFORMING
1383  * - \ref SCIP_STAGE_TRANSFORMED
1384  * - \ref SCIP_STAGE_INITPRESOLVE
1385  * - \ref SCIP_STAGE_PRESOLVING
1386  * - \ref SCIP_STAGE_EXITPRESOLVE
1387  * - \ref SCIP_STAGE_PRESOLVED
1388  * - \ref SCIP_STAGE_INITSOLVE
1389  * - \ref SCIP_STAGE_SOLVING
1390  */
1392  SCIP* scip, /**< SCIP data structure */
1393  int nvars, /**< number of variables to get/create transformed variables for */
1394  SCIP_VAR** vars, /**< array with variables to get/create transformed variables for */
1395  SCIP_VAR** transvars /**< array to store the transformed variables */
1396  )
1397 {
1398  int v;
1399 
1400  assert(nvars == 0 || vars != NULL);
1401  assert(nvars == 0 || transvars != NULL);
1402 
1403  SCIP_CALL( SCIPcheckStage(scip, "SCIPtransformVars", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1404 
1405  for( v = 0; v < nvars; ++v )
1406  {
1407  if( SCIPvarIsTransformed(vars[v]) )
1408  {
1409  transvars[v] = vars[v];
1410  SCIPvarCapture(transvars[v]);
1411  }
1412  else
1413  {
1414  SCIP_CALL( SCIPvarTransform(vars[v], scip->mem->probmem, scip->set, scip->stat, scip->origprob->objsense,
1415  &transvars[v]) );
1416  }
1417  }
1418 
1419  return SCIP_OKAY;
1420 }
1421 
1422 /** gets corresponding transformed variable of a given variable;
1423  * returns NULL as transvar, if transformed variable is not yet existing
1424  *
1425  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1426  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1427  *
1428  * @pre This method can be called if @p scip is in one of the following stages:
1429  * - \ref SCIP_STAGE_TRANSFORMING
1430  * - \ref SCIP_STAGE_TRANSFORMED
1431  * - \ref SCIP_STAGE_INITPRESOLVE
1432  * - \ref SCIP_STAGE_PRESOLVING
1433  * - \ref SCIP_STAGE_EXITPRESOLVE
1434  * - \ref SCIP_STAGE_PRESOLVED
1435  * - \ref SCIP_STAGE_INITSOLVE
1436  * - \ref SCIP_STAGE_SOLVING
1437  * - \ref SCIP_STAGE_SOLVED
1438  * - \ref SCIP_STAGE_EXITSOLVE
1439  * - \ref SCIP_STAGE_FREETRANS
1440  */
1442  SCIP* scip, /**< SCIP data structure */
1443  SCIP_VAR* var, /**< variable to get transformed variable for */
1444  SCIP_VAR** transvar /**< pointer to store the transformed variable */
1445  )
1446 {
1447  assert(transvar != NULL);
1448 
1449  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetTransformedVar", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1450 
1451  if( SCIPvarIsTransformed(var) )
1452  *transvar = var;
1453  else
1454  {
1455  SCIP_CALL( SCIPvarGetTransformed(var, scip->mem->probmem, scip->set, scip->stat, transvar) );
1456  }
1457 
1458  return SCIP_OKAY;
1459 }
1460 
1461 /** gets corresponding transformed variables for an array of variables;
1462  * stores NULL in a transvars slot, if the transformed variable is not yet existing;
1463  * it is possible to call this method with vars == transvars, but remember that variables that are not
1464  * yet transformed will be replaced with NULL
1465  *
1466  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1467  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1468  *
1469  * @pre This method can be called if @p scip is in one of the following stages:
1470  * - \ref SCIP_STAGE_TRANSFORMING
1471  * - \ref SCIP_STAGE_TRANSFORMED
1472  * - \ref SCIP_STAGE_INITPRESOLVE
1473  * - \ref SCIP_STAGE_PRESOLVING
1474  * - \ref SCIP_STAGE_EXITPRESOLVE
1475  * - \ref SCIP_STAGE_PRESOLVED
1476  * - \ref SCIP_STAGE_INITSOLVE
1477  * - \ref SCIP_STAGE_SOLVING
1478  * - \ref SCIP_STAGE_SOLVED
1479  * - \ref SCIP_STAGE_EXITSOLVE
1480  * - \ref SCIP_STAGE_FREETRANS
1481  */
1483  SCIP* scip, /**< SCIP data structure */
1484  int nvars, /**< number of variables to get transformed variables for */
1485  SCIP_VAR** vars, /**< array with variables to get transformed variables for */
1486  SCIP_VAR** transvars /**< array to store the transformed variables */
1487  )
1488 {
1489  int v;
1490 
1491  assert(nvars == 0 || vars != NULL);
1492  assert(nvars == 0 || transvars != NULL);
1493 
1494  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetTransformedVars", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1495 
1496  for( v = 0; v < nvars; ++v )
1497  {
1498  if( SCIPvarIsTransformed(vars[v]) )
1499  transvars[v] = vars[v];
1500  else
1501  {
1502  SCIP_CALL( SCIPvarGetTransformed(vars[v], scip->mem->probmem, scip->set, scip->stat, &transvars[v]) );
1503  }
1504  }
1505 
1506  return SCIP_OKAY;
1507 }
1508 
1509 /** gets negated variable x' = lb + ub - x of variable x; negated variable is created, if not yet existing;
1510  * in difference to \ref SCIPcreateVar, the negated variable must not be released (unless captured explicitly)
1511  *
1512  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1513  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1514  *
1515  * @pre This method can be called if @p scip is in one of the following stages:
1516  * - \ref SCIP_STAGE_PROBLEM
1517  * - \ref SCIP_STAGE_TRANSFORMING
1518  * - \ref SCIP_STAGE_TRANSFORMED
1519  * - \ref SCIP_STAGE_INITPRESOLVE
1520  * - \ref SCIP_STAGE_PRESOLVING
1521  * - \ref SCIP_STAGE_EXITPRESOLVE
1522  * - \ref SCIP_STAGE_PRESOLVED
1523  * - \ref SCIP_STAGE_INITSOLVE
1524  * - \ref SCIP_STAGE_SOLVING
1525  * - \ref SCIP_STAGE_SOLVED
1526  * - \ref SCIP_STAGE_EXITSOLVE
1527  * - \ref SCIP_STAGE_FREETRANS
1528  */
1530  SCIP* scip, /**< SCIP data structure */
1531  SCIP_VAR* var, /**< variable to get negated variable for */
1532  SCIP_VAR** negvar /**< pointer to store the negated variable */
1533  )
1534 {
1535  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNegatedVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1536  assert( var->scip == scip );
1537 
1538  SCIP_CALL( SCIPvarNegate(var, scip->mem->probmem, scip->set, scip->stat, negvar) );
1539 
1540  return SCIP_OKAY;
1541 }
1542 
1543 /** gets negated variables x' = lb + ub - x of variables x; negated variables are created, if not yet existing
1544  *
1545  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1546  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1547  *
1548  * @pre This method can be called if @p scip is in one of the following stages:
1549  * - \ref SCIP_STAGE_PROBLEM
1550  * - \ref SCIP_STAGE_TRANSFORMING
1551  * - \ref SCIP_STAGE_TRANSFORMED
1552  * - \ref SCIP_STAGE_INITPRESOLVE
1553  * - \ref SCIP_STAGE_PRESOLVING
1554  * - \ref SCIP_STAGE_EXITPRESOLVE
1555  * - \ref SCIP_STAGE_PRESOLVED
1556  * - \ref SCIP_STAGE_INITSOLVE
1557  * - \ref SCIP_STAGE_SOLVING
1558  * - \ref SCIP_STAGE_SOLVED
1559  * - \ref SCIP_STAGE_EXITSOLVE
1560  * - \ref SCIP_STAGE_FREETRANS
1561  */
1563  SCIP* scip, /**< SCIP data structure */
1564  int nvars, /**< number of variables to get negated variables for */
1565  SCIP_VAR** vars, /**< array of variables to get negated variables for */
1566  SCIP_VAR** negvars /**< array to store the negated variables */
1567  )
1568 {
1569  int v;
1570 
1571  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNegatedVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1572 
1573  for( v = 0; v < nvars; ++v )
1574  {
1575  SCIP_CALL( SCIPvarNegate(vars[v], scip->mem->probmem, scip->set, scip->stat, &(negvars[v])) );
1576  }
1577 
1578  return SCIP_OKAY;
1579 }
1580 
1581 /** gets a binary variable that is equal to the given binary variable, and that is either active, fixed, or
1582  * multi-aggregated, or the negated variable of an active, fixed, or multi-aggregated variable
1583  *
1584  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1585  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1586  *
1587  * @pre This method can be called if @p scip is in one of the following stages:
1588  * - \ref SCIP_STAGE_PROBLEM
1589  * - \ref SCIP_STAGE_TRANSFORMED
1590  * - \ref SCIP_STAGE_INITPRESOLVE
1591  * - \ref SCIP_STAGE_PRESOLVING
1592  * - \ref SCIP_STAGE_EXITPRESOLVE
1593  * - \ref SCIP_STAGE_PRESOLVED
1594  * - \ref SCIP_STAGE_INITSOLVE
1595  * - \ref SCIP_STAGE_SOLVING
1596  * - \ref SCIP_STAGE_SOLVED
1597  * - \ref SCIP_STAGE_EXITSOLVE
1598  */
1600  SCIP* scip, /**< SCIP data structure */
1601  SCIP_VAR* var, /**< binary variable to get binary representative for */
1602  SCIP_VAR** repvar, /**< pointer to store the binary representative */
1603  SCIP_Bool* negated /**< pointer to store whether the negation of an active variable was returned */
1604  )
1605 {
1606  assert(scip != NULL);
1607  assert(var != NULL);
1608  assert(repvar != NULL);
1609  assert(negated != NULL);
1610  assert(var->scip == scip);
1611 
1612  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetBinvarRepresentative", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1613 
1614  /* get the active representative of the given variable */
1615  *repvar = var;
1616  *negated = FALSE;
1617  SCIP_CALL( SCIPvarGetProbvarBinary(repvar, negated) );
1618 
1619  /* negate the representative, if it corresponds to the negation of the given variable */
1620  if( *negated )
1621  {
1622  SCIP_CALL( SCIPgetNegatedVar(scip, *repvar, repvar) );
1623  }
1624 
1625  return SCIP_OKAY;
1626 }
1627 
1628 /** gets binary variables that are equal to the given binary variables, and which are either active, fixed, or
1629  * multi-aggregated, or the negated variables of active, fixed, or multi-aggregated variables
1630  *
1631  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1632  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1633  *
1634  * @pre This method can be called if @p scip is in one of the following stages:
1635  * - \ref SCIP_STAGE_PROBLEM
1636  * - \ref SCIP_STAGE_TRANSFORMED
1637  * - \ref SCIP_STAGE_INITPRESOLVE
1638  * - \ref SCIP_STAGE_PRESOLVING
1639  * - \ref SCIP_STAGE_EXITPRESOLVE
1640  * - \ref SCIP_STAGE_PRESOLVED
1641  * - \ref SCIP_STAGE_INITSOLVE
1642  * - \ref SCIP_STAGE_SOLVING
1643  * - \ref SCIP_STAGE_SOLVED
1644  * - \ref SCIP_STAGE_EXITSOLVE
1645  */
1647  SCIP* scip, /**< SCIP data structure */
1648  int nvars, /**< number of binary variables to get representatives for */
1649  SCIP_VAR** vars, /**< binary variables to get binary representatives for */
1650  SCIP_VAR** repvars, /**< array to store the binary representatives */
1651  SCIP_Bool* negated /**< array to store whether the negation of an active variable was returned */
1652  )
1653 {
1654  int v;
1655 
1656  assert(scip != NULL);
1657  assert(vars != NULL || nvars == 0);
1658  assert(repvars != NULL || nvars == 0);
1659  assert(negated != NULL || nvars == 0);
1660 
1661  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetBinvarRepresentatives", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1662 
1663  if( nvars == 0 )
1664  return SCIP_OKAY;
1665 
1666  /* get the active representative of the given variable */
1667  BMScopyMemoryArray(repvars, vars, nvars);
1668  BMSclearMemoryArray(negated, nvars);
1669  SCIP_CALL( SCIPvarsGetProbvarBinary(&repvars, &negated, nvars) );
1670 
1671  /* negate the representatives, if they correspond to the negation of the given variables */
1672  for( v = nvars - 1; v >= 0; --v )
1673  if( negated[v] )
1674  {
1675  SCIP_CALL( SCIPgetNegatedVar(scip, repvars[v], &(repvars[v])) );
1676  }
1677 
1678  return SCIP_OKAY;
1679 }
1680 
1681 /** flattens aggregation graph of multi-aggregated variable in order to avoid exponential recursion later on
1682  *
1683  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1684  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1685  *
1686  * @pre This method can be called if @p scip is in one of the following stages:
1687  * - \ref SCIP_STAGE_INITPRESOLVE
1688  * - \ref SCIP_STAGE_PRESOLVING
1689  * - \ref SCIP_STAGE_EXITPRESOLVE
1690  * - \ref SCIP_STAGE_PRESOLVED
1691  * - \ref SCIP_STAGE_INITSOLVE
1692  * - \ref SCIP_STAGE_SOLVING
1693  * - \ref SCIP_STAGE_SOLVED
1694  */
1696  SCIP* scip, /**< SCIP data structure */
1697  SCIP_VAR* var /**< problem variable */
1698  )
1699 {
1700  assert( scip != NULL );
1701  assert( var != NULL );
1702  SCIP_CALL( SCIPcheckStage(scip, "SCIPflattenVarAggregationGraph", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
1703 
1704  SCIP_CALL( SCIPvarFlattenAggregationGraph(var, scip->mem->probmem, scip->set, scip->eventqueue) );
1705 
1706  return SCIP_OKAY;
1707 }
1708 
1709 /** Transforms a given linear sum of variables, that is a_1*x_1 + ... + a_n*x_n + c into a corresponding linear sum of
1710  * active variables, that is b_1*y_1 + ... + b_m*y_m + d.
1711  *
1712  * If the number of needed active variables is greater than the available slots in the variable array, nothing happens
1713  * except that the required size is stored in the corresponding variable (requiredsize). Otherwise, the active variable
1714  * representation is stored in the variable array, scalar array and constant.
1715  *
1716  * The reason for this approach is that we cannot reallocate memory, since we do not know how the memory has been
1717  * allocated (e.g., by a C++ 'new' or SCIP functions).
1718  *
1719  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1720  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1721  *
1722  * @pre This method can be called if @p scip is in one of the following stages:
1723  * - \ref SCIP_STAGE_TRANSFORMED
1724  * - \ref SCIP_STAGE_INITPRESOLVE
1725  * - \ref SCIP_STAGE_PRESOLVING
1726  * - \ref SCIP_STAGE_EXITPRESOLVE
1727  * - \ref SCIP_STAGE_PRESOLVED
1728  * - \ref SCIP_STAGE_INITSOLVE
1729  * - \ref SCIP_STAGE_SOLVING
1730  * - \ref SCIP_STAGE_SOLVED
1731  * - \ref SCIP_STAGE_EXITSOLVE
1732  * - \ref SCIP_STAGE_FREETRANS
1733  *
1734  * @note The resulting linear sum is stored into the given variable array, scalar array, and constant. That means the
1735  * given entries are overwritten.
1736  *
1737  * @note That method can be used to convert a single variables into variable space of active variables. Therefore call
1738  * the method with the linear sum 1.0*x + 0.0.
1739  */
1741  SCIP* scip, /**< SCIP data structure */
1742  SCIP_VAR** vars, /**< variable array x_1, ..., x_n in the linear sum which will be
1743  * overwritten by the variable array y_1, ..., y_m in the linear sum
1744  * w.r.t. active variables */
1745  SCIP_Real* scalars, /**< scalars a_1, ..., a_n in linear sum which will be overwritten to the
1746  * scalars b_1, ..., b_m in the linear sum of the active variables */
1747  int* nvars, /**< pointer to number of variables in the linear sum which will be
1748  * overwritten by the number of variables in the linear sum corresponding
1749  * to the active variables */
1750  int varssize, /**< available slots in vars and scalars array which is needed to check if
1751  * the array are large enough for the linear sum w.r.t. active
1752  * variables */
1753  SCIP_Real* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c which
1754  * will chnage to constant d in the linear sum b_1*y_1 + ... + b_m*y_m +
1755  * d w.r.t. the active variables */
1756  int* requiredsize, /**< pointer to store the required array size for the linear sum w.r.t. the
1757  * active variables */
1758  SCIP_Bool mergemultiples /**< should multiple occurrences of a var be replaced by a single coeff? */
1759  )
1760 {
1761  assert( scip != NULL );
1762  assert( nvars != NULL );
1763  assert( vars != NULL || *nvars == 0 );
1764  assert( scalars != NULL || *nvars == 0 );
1765  assert( constant != NULL );
1766  assert( requiredsize != NULL );
1767  assert( *nvars <= varssize );
1768 
1769  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetProbvarLinearSum", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1770  SCIP_CALL( SCIPvarGetActiveRepresentatives(scip->set, vars, scalars, nvars, varssize, constant, requiredsize, mergemultiples) );
1771 
1772  return SCIP_OKAY;
1773 }
1774 
1775 /** transforms given variable, scalar and constant to the corresponding active, fixed, or
1776  * multi-aggregated variable, scalar and constant; if the variable resolves to a fixed variable,
1777  * "scalar" will be 0.0 and the value of the sum will be stored in "constant"; a multi-aggregation
1778  * with only one active variable (this can happen due to fixings after the multi-aggregation),
1779  * is treated like an aggregation; if the multi-aggregation constant is infinite, "scalar" will be 0.0
1780  *
1781  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1782  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1783  *
1784  * @pre This method can be called if @p scip is in one of the following stages:
1785  * - \ref SCIP_STAGE_TRANSFORMED
1786  * - \ref SCIP_STAGE_INITPRESOLVE
1787  * - \ref SCIP_STAGE_PRESOLVING
1788  * - \ref SCIP_STAGE_EXITPRESOLVE
1789  * - \ref SCIP_STAGE_PRESOLVED
1790  * - \ref SCIP_STAGE_INITSOLVE
1791  * - \ref SCIP_STAGE_SOLVING
1792  * - \ref SCIP_STAGE_SOLVED
1793  * - \ref SCIP_STAGE_EXITSOLVE
1794  * - \ref SCIP_STAGE_FREETRANS
1795  */
1797  SCIP* scip, /**< SCIP data structure */
1798  SCIP_VAR** var, /**< pointer to problem variable x in sum a*x + c */
1799  SCIP_Real* scalar, /**< pointer to scalar a in sum a*x + c */
1800  SCIP_Real* constant /**< pointer to constant c in sum a*x + c */
1801  )
1802 {
1803  assert(scip != NULL);
1804  assert(var != NULL);
1805  assert(scalar != NULL);
1806  assert(constant != NULL);
1807 
1808  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetProbvarSum", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1809  SCIP_CALL( SCIPvarGetProbvarSum(var, scip->set, scalar, constant) );
1810 
1811  return SCIP_OKAY;
1812 }
1813 
1814 /** return for given variables all their active counterparts; all active variables will be pairwise different
1815  * @note It does not hold that the first output variable is the active variable for the first input variable.
1816  *
1817  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1818  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1819  *
1820  * @pre This method can be called if @p scip is in one of the following stages:
1821  * - \ref SCIP_STAGE_TRANSFORMED
1822  * - \ref SCIP_STAGE_INITPRESOLVE
1823  * - \ref SCIP_STAGE_PRESOLVING
1824  * - \ref SCIP_STAGE_EXITPRESOLVE
1825  * - \ref SCIP_STAGE_PRESOLVED
1826  * - \ref SCIP_STAGE_INITSOLVE
1827  * - \ref SCIP_STAGE_SOLVING
1828  * - \ref SCIP_STAGE_SOLVED
1829  * - \ref SCIP_STAGE_EXITSOLVE
1830  * - \ref SCIP_STAGE_FREETRANS
1831  */
1833  SCIP* scip, /**< SCIP data structure */
1834  SCIP_VAR** vars, /**< variable array with given variables and as output all active
1835  * variables, if enough slots exist
1836  */
1837  int* nvars, /**< number of given variables, and as output number of active variables,
1838  * if enough slots exist
1839  */
1840  int varssize, /**< available slots in vars array */
1841  int* requiredsize /**< pointer to store the required array size for the active variables */
1842  )
1843 {
1844  assert(scip != NULL);
1845  assert(nvars != NULL);
1846  assert(vars != NULL || *nvars == 0);
1847  assert(varssize >= *nvars);
1848  assert(requiredsize != NULL);
1849 
1850  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetActiveVars", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1851  SCIP_CALL( SCIPvarsGetActiveVars(scip->set, vars, nvars, varssize, requiredsize) );
1852 
1853  return SCIP_OKAY;
1854 }
1855 
1856 /** returns the reduced costs of the variable in the current node's LP relaxation;
1857  * the current node has to have a feasible LP.
1858  *
1859  * returns SCIP_INVALID if the variable is active but not in the current LP;
1860  * returns 0 if the variable has been aggregated out or fixed in presolving.
1861  *
1862  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1863  *
1864  * @note The return value of this method should be used carefully if the dual feasibility check was explictely disabled.
1865  */
1867  SCIP* scip, /**< SCIP data structure */
1868  SCIP_VAR* var /**< variable to get reduced costs, should be a column in current node LP */
1869  )
1870 {
1871  assert( scip != NULL );
1872  assert( var != NULL );
1873  assert( var->scip == scip );
1874 
1875  switch( SCIPvarGetStatus(var) )
1876  {
1878  if( var->data.original.transvar == NULL )
1879  return SCIP_INVALID;
1880  return SCIPgetVarRedcost(scip, var->data.original.transvar);
1881 
1882  case SCIP_VARSTATUS_COLUMN:
1883  return SCIPgetColRedcost(scip, SCIPvarGetCol(var));
1884 
1885  case SCIP_VARSTATUS_LOOSE:
1886  return SCIP_INVALID;
1887 
1888  case SCIP_VARSTATUS_FIXED:
1892  return 0.0;
1893 
1894  default:
1895  SCIPerrorMessage("unknown variable status\n");
1896  SCIPABORT();
1897  return 0.0; /*lint !e527*/
1898  }
1899 }
1900 
1901 /** returns the implied reduced costs of the variable in the current node's LP relaxation;
1902  * the current node has to have a feasible LP.
1903  *
1904  * returns SCIP_INVALID if the variable is active but not in the current LP;
1905  * returns 0 if the variable has been aggregated out or fixed in presolving.
1906  *
1907  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1908  *
1909  * @note The return value of this method should be used carefully if the dual feasibility check was explictely disabled.
1910  */
1912  SCIP* scip, /**< SCIP data structure */
1913  SCIP_VAR* var, /**< variable to get reduced costs, should be a column in current node LP */
1914  SCIP_Bool varfixing /**< FALSE if for x == 0, TRUE for x == 1 */
1915  )
1916 {
1917  assert( scip != NULL );
1918  assert( var != NULL );
1919  assert( var->scip == scip );
1920 
1921  switch( SCIPvarGetStatus(var) )
1922  {
1924  if( var->data.original.transvar == NULL )
1925  return SCIP_INVALID;
1926  return SCIPgetVarImplRedcost(scip, var->data.original.transvar, varfixing);
1927 
1928  case SCIP_VARSTATUS_COLUMN:
1929  return SCIPvarGetImplRedcost(var, scip->set, varfixing, scip->stat, scip->transprob, scip->lp);
1930 
1931  case SCIP_VARSTATUS_LOOSE:
1932  return SCIP_INVALID;
1933 
1934  case SCIP_VARSTATUS_FIXED:
1938  return 0.0;
1939 
1940  default:
1941  SCIPerrorMessage("unknown variable status\n");
1942  SCIPABORT();
1943  return 0.0; /*lint !e527*/
1944  }
1945 }
1946 
1947 
1948 /** returns the Farkas coefficient of the variable in the current node's LP relaxation;
1949  * the current node has to have an infeasible LP.
1950  *
1951  * returns SCIP_INVALID if the variable is active but not in the current LP;
1952  * returns 0 if the variable has been aggregated out or fixed in presolving.
1953  *
1954  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1955  */
1957  SCIP* scip, /**< SCIP data structure */
1958  SCIP_VAR* var /**< variable to get reduced costs, should be a column in current node LP */
1959  )
1960 {
1961  assert(scip != NULL);
1962  assert(var != NULL);
1963  assert(var->scip == scip);
1964 
1965  switch( SCIPvarGetStatus(var) )
1966  {
1968  if( var->data.original.transvar == NULL )
1969  return SCIP_INVALID;
1970  return SCIPgetVarFarkasCoef(scip,var->data.original.transvar);
1971 
1972  case SCIP_VARSTATUS_COLUMN:
1973  return SCIPgetColFarkasCoef(scip,SCIPvarGetCol(var));
1974 
1975  case SCIP_VARSTATUS_LOOSE:
1976  return SCIP_INVALID;
1977 
1978  case SCIP_VARSTATUS_FIXED:
1982  return 0.0;
1983 
1984  default:
1985  SCIPerrorMessage("unknown variable status\n");
1986  SCIPABORT();
1987  return 0.0; /*lint !e527*/
1988  }
1989 }
1990 
1991 /** returns lower bound of variable directly before or after the bound change given by the bound change index
1992  * was applied
1993  */
1995  SCIP* scip, /**< SCIP data structure */
1996  SCIP_VAR* var, /**< problem variable */
1997  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
1998  SCIP_Bool after /**< should the bound change with given index be included? */
1999  )
2000 {
2001  SCIP_VARSTATUS varstatus;
2002  SCIP_BDCHGINFO* bdchginfo;
2003  assert(var != NULL);
2004 
2005  varstatus = SCIPvarGetStatus(var);
2006 
2007  /* get bounds of attached variables */
2008  switch( varstatus )
2009  {
2011  assert(var->data.original.transvar != NULL);
2012  return SCIPgetVarLbAtIndex(scip, var->data.original.transvar, bdchgidx, after);
2013 
2014  case SCIP_VARSTATUS_COLUMN:
2015  case SCIP_VARSTATUS_LOOSE:
2016  if( bdchgidx == NULL )
2017  return SCIPvarGetLbLocal(var);
2018  else
2019  {
2020  bdchginfo = SCIPvarGetLbchgInfo(var, bdchgidx, after);
2021  if( bdchginfo != NULL )
2022  return SCIPbdchginfoGetNewbound(bdchginfo);
2023  else
2024  return var->glbdom.lb;
2025  }
2026 
2027  case SCIP_VARSTATUS_FIXED:
2028  return var->glbdom.lb;
2029 
2030  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c -> y = (x-c)/a */
2031  assert(var->data.aggregate.var != NULL);
2032  if( var->data.aggregate.scalar > 0.0 )
2033  {
2034  SCIP_Real lb;
2035 
2036  lb = SCIPgetVarLbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2037 
2038  /* a > 0 -> get lower bound of y */
2039  if( SCIPisInfinity(scip, -lb) )
2040  return -SCIPinfinity(scip);
2041  else if( SCIPisInfinity(scip, lb) )
2042  return SCIPinfinity(scip);
2043  else
2044  return var->data.aggregate.scalar * lb + var->data.aggregate.constant;
2045  }
2046  else if( var->data.aggregate.scalar < 0.0 )
2047  {
2048  SCIP_Real ub;
2049 
2050  ub = SCIPgetVarUbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2051 
2052  /* a < 0 -> get upper bound of y */
2053  if( SCIPisInfinity(scip, -ub) )
2054  return SCIPinfinity(scip);
2055  else if( SCIPisInfinity(scip, ub) )
2056  return -SCIPinfinity(scip);
2057  else
2058  return var->data.aggregate.scalar * ub + var->data.aggregate.constant;
2059  }
2060  else
2061  {
2062  SCIPerrorMessage("scalar is zero in aggregation\n");
2063  SCIPABORT();
2064  return SCIP_INVALID; /*lint !e527*/
2065  }
2066 
2068  /* handle multi-aggregated variables depending on one variable only (possibly caused by SCIPvarFlattenAggregationGraph()) */
2069  if ( var->data.multaggr.nvars == 1 )
2070  {
2071  assert(var->data.multaggr.vars != NULL);
2072  assert(var->data.multaggr.scalars != NULL);
2073  assert(var->data.multaggr.vars[0] != NULL);
2074 
2075  if( var->data.multaggr.scalars[0] > 0.0 )
2076  {
2077  SCIP_Real lb;
2078 
2079  lb = SCIPgetVarLbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2080 
2081  /* a > 0 -> get lower bound of y */
2082  if( SCIPisInfinity(scip, -lb) )
2083  return -SCIPinfinity(scip);
2084  else if( SCIPisInfinity(scip, lb) )
2085  return SCIPinfinity(scip);
2086  else
2087  return var->data.multaggr.scalars[0] * lb + var->data.multaggr.constant;
2088  }
2089  else if( var->data.multaggr.scalars[0] < 0.0 )
2090  {
2091  SCIP_Real ub;
2092 
2093  ub = SCIPgetVarUbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2094 
2095  /* a < 0 -> get upper bound of y */
2096  if( SCIPisInfinity(scip, -ub) )
2097  return SCIPinfinity(scip);
2098  else if( SCIPisInfinity(scip, ub) )
2099  return -SCIPinfinity(scip);
2100  else
2101  return var->data.multaggr.scalars[0] * ub + var->data.multaggr.constant;
2102  }
2103  else
2104  {
2105  SCIPerrorMessage("scalar is zero in multi-aggregation\n");
2106  SCIPABORT();
2107  return SCIP_INVALID; /*lint !e527*/
2108  }
2109  }
2110  SCIPerrorMessage("cannot get the bounds of a multi-aggregated variable.\n");
2111  SCIPABORT();
2112  return SCIP_INVALID; /*lint !e527*/
2113 
2114  case SCIP_VARSTATUS_NEGATED: /* x' = offset - x -> x = offset - x' */
2115  assert(var->negatedvar != NULL);
2117  assert(var->negatedvar->negatedvar == var);
2118  return var->data.negate.constant - SCIPgetVarUbAtIndex(scip, var->negatedvar, bdchgidx, after);
2119 
2120  default:
2121  SCIPerrorMessage("unknown variable status\n");
2122  SCIPABORT();
2123  return SCIP_INVALID; /*lint !e527*/
2124  }
2125 }
2126 
2127 /** returns upper bound of variable directly before or after the bound change given by the bound change index
2128  * was applied
2129  */
2131  SCIP* scip, /**< SCIP data structure */
2132  SCIP_VAR* var, /**< problem variable */
2133  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2134  SCIP_Bool after /**< should the bound change with given index be included? */
2135  )
2136 {
2137  SCIP_VARSTATUS varstatus;
2138  SCIP_BDCHGINFO* bdchginfo;
2139  assert(var != NULL);
2140 
2141  varstatus = SCIPvarGetStatus(var);
2142 
2143  /* get bounds of attached variables */
2144  switch( varstatus )
2145  {
2147  assert(var->data.original.transvar != NULL);
2148  return SCIPgetVarUbAtIndex(scip, var->data.original.transvar, bdchgidx, after);
2149 
2150  case SCIP_VARSTATUS_COLUMN:
2151  case SCIP_VARSTATUS_LOOSE:
2152  if( bdchgidx == NULL )
2153  return SCIPvarGetUbLocal(var);
2154  else
2155  {
2156  bdchginfo = SCIPvarGetUbchgInfo(var, bdchgidx, after);
2157  if( bdchginfo != NULL )
2158  return SCIPbdchginfoGetNewbound(bdchginfo);
2159  else
2160  return var->glbdom.ub;
2161  }
2162 
2163  case SCIP_VARSTATUS_FIXED:
2164  return var->glbdom.ub;
2165 
2166  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c -> y = (x-c)/a */
2167  assert(var->data.aggregate.var != NULL);
2168  if( var->data.aggregate.scalar > 0.0 )
2169  {
2170  SCIP_Real ub;
2171 
2172  ub = SCIPgetVarUbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2173 
2174  /* a > 0 -> get lower bound of y */
2175  if( SCIPisInfinity(scip, -ub) )
2176  return -SCIPinfinity(scip);
2177  else if( SCIPisInfinity(scip, ub) )
2178  return SCIPinfinity(scip);
2179  else
2180  return var->data.aggregate.scalar * ub + var->data.aggregate.constant;
2181  }
2182  else if( var->data.aggregate.scalar < 0.0 )
2183  {
2184  SCIP_Real lb;
2185 
2186  lb = SCIPgetVarLbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2187 
2188  /* a < 0 -> get upper bound of y */
2189  if ( SCIPisInfinity(scip, -lb) )
2190  return SCIPinfinity(scip);
2191  else if ( SCIPisInfinity(scip, lb) )
2192  return -SCIPinfinity(scip);
2193  else
2194  return var->data.aggregate.scalar * lb + var->data.aggregate.constant;
2195  }
2196  else
2197  {
2198  SCIPerrorMessage("scalar is zero in aggregation\n");
2199  SCIPABORT();
2200  return SCIP_INVALID; /*lint !e527*/
2201  }
2202 
2204  /* handle multi-aggregated variables depending on one variable only (possibly caused by SCIPvarFlattenAggregationGraph()) */
2205  if ( var->data.multaggr.nvars == 1 )
2206  {
2207  assert(var->data.multaggr.vars != NULL);
2208  assert(var->data.multaggr.scalars != NULL);
2209  assert(var->data.multaggr.vars[0] != NULL);
2210 
2211  if( var->data.multaggr.scalars[0] > 0.0 )
2212  {
2213  SCIP_Real ub;
2214 
2215  ub = SCIPgetVarUbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2216 
2217  /* a > 0 -> get lower bound of y */
2218  if ( SCIPisInfinity(scip, -ub) )
2219  return -SCIPinfinity(scip);
2220  else if ( SCIPisInfinity(scip, ub) )
2221  return SCIPinfinity(scip);
2222  else
2223  return var->data.multaggr.scalars[0] * ub + var->data.multaggr.constant;
2224  }
2225  else if( var->data.multaggr.scalars[0] < 0.0 )
2226  {
2227  SCIP_Real lb;
2228 
2229  lb = SCIPgetVarLbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2230 
2231  /* a < 0 -> get upper bound of y */
2232  if ( SCIPisInfinity(scip, -lb) )
2233  return SCIPinfinity(scip);
2234  else if ( SCIPisInfinity(scip, lb) )
2235  return -SCIPinfinity(scip);
2236  else
2237  return var->data.multaggr.scalars[0] * lb + var->data.multaggr.constant;
2238  }
2239  else
2240  {
2241  SCIPerrorMessage("scalar is zero in multi-aggregation\n");
2242  SCIPABORT();
2243  return SCIP_INVALID; /*lint !e527*/
2244  }
2245  }
2246  SCIPerrorMessage("cannot get the bounds of a multiple aggregated variable.\n");
2247  SCIPABORT();
2248  return SCIP_INVALID; /*lint !e527*/
2249 
2250  case SCIP_VARSTATUS_NEGATED: /* x' = offset - x -> x = offset - x' */
2251  assert(var->negatedvar != NULL);
2253  assert(var->negatedvar->negatedvar == var);
2254  return var->data.negate.constant - SCIPgetVarLbAtIndex(scip, var->negatedvar, bdchgidx, after);
2255 
2256  default:
2257  SCIPerrorMessage("unknown variable status\n");
2258  SCIPABORT();
2259  return SCIP_INVALID; /*lint !e527*/
2260  }
2261 }
2262 
2263 /** returns lower or upper bound of variable directly before or after the bound change given by the bound change index
2264  * was applied
2265  */
2267  SCIP* scip, /**< SCIP data structure */
2268  SCIP_VAR* var, /**< problem variable */
2269  SCIP_BOUNDTYPE boundtype, /**< type of bound: lower or upper bound */
2270  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2271  SCIP_Bool after /**< should the bound change with given index be included? */
2272  )
2273 {
2274  if( boundtype == SCIP_BOUNDTYPE_LOWER )
2275  return SCIPgetVarLbAtIndex(scip, var, bdchgidx, after);
2276  else
2277  {
2278  assert(boundtype == SCIP_BOUNDTYPE_UPPER);
2279  return SCIPgetVarUbAtIndex(scip, var, bdchgidx, after);
2280  }
2281 }
2282 
2283 /** returns whether the binary variable was fixed at the time given by the bound change index */
2285  SCIP* scip, /**< SCIP data structure */
2286  SCIP_VAR* var, /**< problem variable */
2287  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2288  SCIP_Bool after /**< should the bound change with given index be included? */
2289  )
2290 {
2291  assert(var != NULL);
2292  assert(SCIPvarIsBinary(var));
2293 
2294  /* check the current bounds first in order to decide at which bound change information we have to look
2295  * (which is expensive because we have to follow the aggregation tree to the active variable)
2296  */
2297  return ((SCIPvarGetLbLocal(var) > 0.5 && SCIPgetVarLbAtIndex(scip, var, bdchgidx, after) > 0.5)
2298  || (SCIPvarGetUbLocal(var) < 0.5 && SCIPgetVarUbAtIndex(scip, var, bdchgidx, after) < 0.5));
2299 }
2300 
2301 /** gets solution value for variable in current node
2302  *
2303  * @return solution value for variable in current node
2304  *
2305  * @pre This method can be called if @p scip is in one of the following stages:
2306  * - \ref SCIP_STAGE_PRESOLVED
2307  * - \ref SCIP_STAGE_SOLVING
2308  */
2310  SCIP* scip, /**< SCIP data structure */
2311  SCIP_VAR* var /**< variable to get solution value for */
2312  )
2313 {
2315  assert( var->scip == scip );
2316 
2317  return SCIPvarGetSol(var, SCIPtreeHasCurrentNodeLP(scip->tree));
2318 }
2319 
2320 /** gets solution values of multiple variables in current node
2321  *
2322  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2323  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2324  *
2325  * @pre This method can be called if @p scip is in one of the following stages:
2326  * - \ref SCIP_STAGE_PRESOLVED
2327  * - \ref SCIP_STAGE_SOLVING
2328  */
2330  SCIP* scip, /**< SCIP data structure */
2331  int nvars, /**< number of variables to get solution value for */
2332  SCIP_VAR** vars, /**< array with variables to get value for */
2333  SCIP_Real* vals /**< array to store solution values of variables */
2334  )
2335 {
2336  int v;
2337 
2338  assert(nvars == 0 || vars != NULL);
2339  assert(nvars == 0 || vals != NULL);
2340 
2341  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarSols", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2342 
2343  if( SCIPtreeHasCurrentNodeLP(scip->tree) )
2344  {
2345  for( v = 0; v < nvars; ++v )
2346  vals[v] = SCIPvarGetLPSol(vars[v]);
2347  }
2348  else
2349  {
2350  for( v = 0; v < nvars; ++v )
2351  vals[v] = SCIPvarGetPseudoSol(vars[v]);
2352  }
2353 
2354  return SCIP_OKAY;
2355 }
2356 
2357 /** sets the solution value of all variables in the global relaxation solution to zero
2358  *
2359  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2360  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2361  *
2362  * @pre This method can be called if @p scip is in one of the following stages:
2363  * - \ref SCIP_STAGE_PRESOLVED
2364  * - \ref SCIP_STAGE_SOLVING
2365  */
2367  SCIP* scip, /**< SCIP data structure */
2368  SCIP_RELAX* relax /**< relaxator data structure */
2369  )
2370 {
2371  SCIP_VAR** vars;
2372  int nvars;
2373  int v;
2374 
2375  assert(scip != NULL);
2376 
2377  SCIP_CALL( SCIPcheckStage(scip, "SCIPclearRelaxSolVals", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2378 
2379  /* update the responsible relax pointer */
2380  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2381 
2382  /* the relaxation solution is already cleared */
2383  if( SCIPrelaxationIsSolZero(scip->relaxation) )
2384  return SCIP_OKAY;
2385 
2386  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
2387 
2388  for( v = 0; v < nvars; v++ )
2389  {
2390  SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, 0.0, FALSE) );
2391  }
2392 
2393  SCIPrelaxationSetSolObj(scip->relaxation, 0.0);
2395 
2396  return SCIP_OKAY;
2397 }
2398 
2399 /** sets the value of the given variable in the global relaxation solution;
2400  * this solution can be filled by the relaxation handlers and can be used by heuristics and for separation;
2401  * You can use SCIPclearRelaxSolVals() to set all values to zero, initially;
2402  * after setting all solution values, you have to call SCIPmarkRelaxSolValid()
2403  * to inform SCIP that the stored solution is valid
2404  *
2405  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2406  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2407  *
2408  * @pre This method can be called if @p scip is in one of the following stages:
2409  * - \ref SCIP_STAGE_PRESOLVED
2410  * - \ref SCIP_STAGE_SOLVING
2411  *
2412  * @note This method incrementally updates the objective value of the relaxation solution. If the whole solution
2413  * should be updated, using SCIPsetRelaxSolVals() instead or calling SCIPclearRelaxSolVals() before setting
2414  * the first value to reset the solution and the objective value to 0 may help the numerics.
2415  */
2417  SCIP* scip, /**< SCIP data structure */
2418  SCIP_RELAX* relax, /**< relaxator data structure */
2419  SCIP_VAR* var, /**< variable to set value for */
2420  SCIP_Real val /**< solution value of variable */
2421  )
2422 {
2423  assert(scip != NULL);
2424 
2425  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolVal", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2426 
2427  SCIP_CALL( SCIPvarSetRelaxSol(var, scip->set, scip->relaxation, val, TRUE) );
2428 
2429  if( val != 0.0 )
2432  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2433 
2434  return SCIP_OKAY;
2435 }
2436 
2437 /** sets the values of the given variables in the global relaxation solution and informs SCIP about the validity
2438  * and whether the solution can be enforced via linear cuts;
2439  * this solution can be filled by the relaxation handlers and can be used by heuristics and for separation;
2440  * the solution is automatically cleared, s.t. all other variables get value 0.0
2441  *
2442  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2443  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2444  *
2445  * @pre This method can be called if @p scip is in one of the following stages:
2446  * - \ref SCIP_STAGE_PRESOLVED
2447  * - \ref SCIP_STAGE_SOLVING
2448  */
2450  SCIP* scip, /**< SCIP data structure */
2451  SCIP_RELAX* relax, /**< relaxator data structure */
2452  int nvars, /**< number of variables to set relaxation solution value for */
2453  SCIP_VAR** vars, /**< array with variables to set value for */
2454  SCIP_Real* vals, /**< array with solution values of variables */
2455  SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2456  )
2457 {
2458  int v;
2459 
2460  assert(scip != NULL);
2461  assert(nvars == 0 || vars != NULL);
2462  assert(nvars == 0 || vals != NULL);
2463 
2464  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolVals", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2465 
2466  SCIP_CALL( SCIPclearRelaxSolVals(scip, relax) );
2467 
2468  for( v = 0; v < nvars; v++ )
2469  {
2470  SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, vals[v], TRUE) );
2471  }
2472 
2474  SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2475  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2476 
2477  return SCIP_OKAY;
2478 }
2479 
2480 /** sets the values of the variables in the global relaxation solution to the values in the given primal solution
2481  * and informs SCIP about the validity and whether the solution can be enforced via linear cuts;
2482  * the relaxation solution can be filled by the relaxation handlers and might be used by heuristics and for separation
2483  *
2484  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2485  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2486  *
2487  * @pre This method can be called if @p scip is in one of the following stages:
2488  * - \ref SCIP_STAGE_PRESOLVED
2489  * - \ref SCIP_STAGE_SOLVING
2490  */
2492  SCIP* scip, /**< SCIP data structure */
2493  SCIP_RELAX* relax, /**< relaxator data structure */
2494  SCIP_SOL* sol, /**< primal relaxation solution */
2495  SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2496  )
2497 {
2498  SCIP_VAR** vars;
2499  SCIP_Real* vals;
2500  int nvars;
2501  int v;
2502 
2503  assert(scip != NULL);
2504 
2505  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolValsSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2506 
2507  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
2508 
2509  /* alloc buffer array for solution values of the variables and get the values */
2510  SCIP_CALL( SCIPallocBufferArray(scip, &vals, nvars) );
2511  SCIP_CALL( SCIPgetSolVals(scip, sol, nvars, vars, vals) );
2512 
2513  SCIP_CALL( SCIPclearRelaxSolVals(scip, relax) );
2514 
2515  for( v = 0; v < nvars; v++ )
2516  {
2517  SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, vals[v], FALSE) );
2518  }
2519 
2520  SCIPrelaxationSetSolObj(scip->relaxation, SCIPsolGetObj(sol, scip->set, scip->transprob, scip->origprob));
2521 
2523  SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2524  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2525 
2526  SCIPfreeBufferArray(scip, &vals);
2527 
2528  return SCIP_OKAY;
2529 }
2530 
2531 /** returns whether the relaxation solution is valid
2532  *
2533  * @return TRUE, if the relaxation solution is valid; FALSE, otherwise
2534  *
2535  * @pre This method can be called if @p scip is in one of the following stages:
2536  * - \ref SCIP_STAGE_PRESOLVED
2537  * - \ref SCIP_STAGE_SOLVING
2538  */
2540  SCIP* scip /**< SCIP data structure */
2541  )
2542 {
2543  assert(scip != NULL);
2544 
2545  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisRelaxSolValid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2546 
2547  return SCIPrelaxationIsSolValid(scip->relaxation);
2548 }
2549 
2550 /** informs SCIP that the relaxation solution is valid and whether the relaxation can be enforced through linear cuts
2551  *
2552  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2553  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2554  *
2555  * @pre This method can be called if @p scip is in one of the following stages:
2556  * - \ref SCIP_STAGE_PRESOLVED
2557  * - \ref SCIP_STAGE_SOLVING
2558  */
2560  SCIP* scip, /**< SCIP data structure */
2561  SCIP_RELAX* relax, /**< relaxator data structure that set the current relaxation solution */
2562  SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2563  )
2564 {
2565  assert(scip != NULL);
2566 
2567  SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkRelaxSolValid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2568 
2569  SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2570  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2571 
2572  return SCIP_OKAY;
2573 }
2574 
2575 /** informs SCIP, that the relaxation solution is invalid
2576  *
2577  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2578  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2579  *
2580  * @pre This method can be called if @p scip is in one of the following stages:
2581  * - \ref SCIP_STAGE_PRESOLVED
2582  * - \ref SCIP_STAGE_SOLVING
2583  */
2585  SCIP* scip /**< SCIP data structure */
2586  )
2587 {
2588  assert(scip != NULL);
2589 
2590  SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkRelaxSolInvalid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2591 
2593 
2594  return SCIP_OKAY;
2595 }
2596 
2597 /** gets the relaxation solution value of the given variable
2598  *
2599  * @return the relaxation solution value of the given variable
2600  *
2601  * @pre This method can be called if @p scip is in one of the following stages:
2602  * - \ref SCIP_STAGE_PRESOLVED
2603  * - \ref SCIP_STAGE_SOLVING
2604  */
2606  SCIP* scip, /**< SCIP data structure */
2607  SCIP_VAR* var /**< variable to get value for */
2608  )
2609 {
2610  assert(scip != NULL);
2611  assert(var != NULL);
2612  assert(var->scip == scip);
2613 
2614  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetRelaxSolVal", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2615 
2616  if( !SCIPrelaxationIsSolValid(scip->relaxation) )
2617  {
2618  SCIPerrorMessage("Relaxation Solution is not valid!\n");
2619  SCIPABORT();
2620  return SCIP_INVALID; /*lint !e527*/
2621  }
2622 
2623  return SCIPvarGetRelaxSol(var, scip->set);
2624 }
2625 
2626 /** gets the relaxation solution objective value
2627  *
2628  * @return the objective value of the relaxation solution
2629  *
2630  * @pre This method can be called if @p scip is in one of the following stages:
2631  * - \ref SCIP_STAGE_PRESOLVED
2632  * - \ref SCIP_STAGE_SOLVING
2633  */
2635  SCIP* scip /**< SCIP data structure */
2636  )
2637 {
2638  assert(scip != NULL);
2639 
2640  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetRelaxSolObj", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2641 
2642  if( !SCIPrelaxationIsSolValid(scip->relaxation) )
2643  {
2644  SCIPerrorMessage("Relaxation Solution is not valid!\n");
2645  SCIPABORT();
2646  return SCIP_INVALID; /*lint !e527*/
2647  }
2648 
2649  return SCIPrelaxationGetSolObj(scip->relaxation);
2650 }
2651 
2652 /** determine which branching direction should be evaluated first by strong branching
2653  *
2654  * @return TRUE iff strong branching should first evaluate the down child
2655  *
2656  */
2658  SCIP* scip, /**< SCIP data structure */
2659  SCIP_VAR* var /**< variable to determine the branching direction on */
2660  )
2661 {
2662  switch( scip->set->branch_firstsbchild )
2663  {
2664  case 'u':
2665  return FALSE;
2666  case 'd':
2667  return TRUE;
2668  case 'a':
2669  return (SCIPvarGetNLocksDown(var) > SCIPvarGetNLocksUp(var));
2670  default:
2671  assert(scip->set->branch_firstsbchild == 'h');
2673  }
2674 }
2675 
2676 /** start strong branching - call before any strong branching
2677  *
2678  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2679  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2680  *
2681  * @pre This method can be called if @p scip is in one of the following stages:
2682  * - \ref SCIP_STAGE_PRESOLVED
2683  * - \ref SCIP_STAGE_SOLVING
2684  *
2685  * @note if propagation is enabled, strong branching is not done directly on the LP, but probing nodes are created
2686  * which allow to perform propagation but also creates some overhead
2687  */
2689  SCIP* scip, /**< SCIP data structure */
2690  SCIP_Bool enablepropagation /**< should propagation be done before solving the strong branching LP? */
2691  )
2692 {
2693  assert( scip != NULL );
2694  SCIP_CALL( SCIPcheckStage(scip, "SCIPstartStrongbranch", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2695 
2696  assert(!SCIPinProbing(scip));
2697 
2698  SCIPdebugMsg(scip, "starting strong branching mode%s: lpcount=%" SCIP_LONGINT_FORMAT "\n", enablepropagation ? " with propagation" : "", scip->stat->lpcount - scip->stat->nsbdivinglps);
2699 
2700  /* start probing mode to allow propagation before solving the strong branching LPs; if no propagation should be done,
2701  * start the strong branching mode in the LP interface
2702  */
2703  if( enablepropagation )
2704  {
2705  if( SCIPtreeProbing(scip->tree) )
2706  {
2707  SCIPerrorMessage("cannot start strong branching with propagation while in probing mode\n");
2708  return SCIP_INVALIDCALL;
2709  }
2710 
2711  if( scip->lp != NULL && SCIPlpDiving(scip->lp) )
2712  {
2713  SCIPerrorMessage("cannot start strong branching with propagation while in diving mode\n");
2714  return SCIP_INVALIDCALL;
2715  }
2716 
2717  /* other then in SCIPstartProbing(), we do not disable collecting variable statistics during strong branching;
2718  * we cannot disable it, because the pseudo costs would not be updated, otherwise,
2719  * and reliability branching would end up doing strong branching all the time
2720  */
2721  SCIP_CALL( SCIPtreeStartProbing(scip->tree, scip->mem->probmem, scip->set, scip->lp, scip->relaxation, scip->transprob, TRUE) );
2722 
2723  /* inform the LP that the current probing mode is used for strong branching */
2725  }
2726  else
2727  {
2729  }
2730 
2731  /* reset local strong branching info */
2733 
2734  return SCIP_OKAY;
2735 }
2736 
2737 /** end strong branching - call after any strong branching
2738  *
2739  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2740  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2741  *
2742  * @pre This method can be called if @p scip is in one of the following stages:
2743  * - \ref SCIP_STAGE_PRESOLVED
2744  * - \ref SCIP_STAGE_SOLVING
2745  */
2747  SCIP* scip /**< SCIP data structure */
2748  )
2749 {
2750  assert( scip != NULL );
2751 
2752  SCIP_CALL( SCIPcheckStage(scip, "SCIPendStrongbranch", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2753 
2754  /* depending on whether the strong branching mode was started with propagation enabled or not, we end the strong
2755  * branching probing mode or the LP strong branching mode
2756  */
2757  if( SCIPtreeProbing(scip->tree) )
2758  {
2759  SCIP_NODE* node;
2760  SCIP_DOMCHG* domchg;
2761  SCIP_VAR** boundchgvars;
2762  SCIP_Real* bounds;
2763  SCIP_BOUNDTYPE* boundtypes;
2764  int nboundchgs;
2765  int nbnds;
2766  int i;
2767 
2768  /* collect all bound changes deducted during probing, which were applied at the probing root and apply them to the
2769  * focusnode
2770  */
2771  node = SCIPgetCurrentNode(scip);
2772  assert(SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE);
2773  assert(SCIPgetProbingDepth(scip) == 0);
2774 
2775  domchg = SCIPnodeGetDomchg(node);
2776  nboundchgs = SCIPdomchgGetNBoundchgs(domchg);
2777 
2778  SCIP_CALL( SCIPallocBufferArray(scip, &boundchgvars, nboundchgs) );
2779  SCIP_CALL( SCIPallocBufferArray(scip, &bounds, nboundchgs) );
2780  SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, nboundchgs) );
2781 
2782  for( i = 0, nbnds = 0; i < nboundchgs; ++i )
2783  {
2784  SCIP_BOUNDCHG* boundchg;
2785 
2786  boundchg = SCIPdomchgGetBoundchg(domchg, i);
2787 
2788  /* ignore redundant bound changes */
2789  if( SCIPboundchgIsRedundant(boundchg) )
2790  continue;
2791 
2792  boundchgvars[nbnds] = SCIPboundchgGetVar(boundchg);
2793  bounds[nbnds] = SCIPboundchgGetNewbound(boundchg);
2794  boundtypes[nbnds] = SCIPboundchgGetBoundtype(boundchg);
2795  ++nbnds;
2796  }
2797 
2798  SCIPdebugMsg(scip, "ending strong branching with probing: %d bound changes collected\n", nbnds);
2799 
2800  /* inform the LP that the probing mode is not used for strong branching anymore */
2802 
2803  /* switch back from probing to normal operation mode and restore variables and constraints to focus node */
2804  SCIP_CALL( SCIPtreeEndProbing(scip->tree, scip->reopt, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
2805  scip->transprob, scip->origprob, scip->lp, scip->relaxation, scip->primal,
2806  scip->branchcand, scip->eventqueue, scip->eventfilter, scip->cliquetable) );
2807 
2808  /* apply the collected bound changes */
2809  for( i = 0; i < nbnds; ++i )
2810  {
2811  if( boundtypes[i] == SCIP_BOUNDTYPE_LOWER )
2812  {
2813  SCIPdebugMsg(scip, "apply probing lower bound change <%s> >= %.9g\n", SCIPvarGetName(boundchgvars[i]), bounds[i]);
2814  SCIP_CALL( SCIPchgVarLb(scip, boundchgvars[i], bounds[i]) );
2815  }
2816  else
2817  {
2818  SCIPdebugMsg(scip, "apply probing upper bound change <%s> <= %.9g\n", SCIPvarGetName(boundchgvars[i]), bounds[i]);
2819  SCIP_CALL( SCIPchgVarUb(scip, boundchgvars[i], bounds[i]) );
2820  }
2821  }
2822 
2823  SCIPfreeBufferArray(scip, &boundtypes);
2824  SCIPfreeBufferArray(scip, &bounds);
2825  SCIPfreeBufferArray(scip, &boundchgvars);
2826  }
2827  else
2828  {
2829  SCIPdebugMsg(scip, "ending strong branching\n");
2830 
2832  }
2833 
2834  return SCIP_OKAY;
2835 }
2836 
2837 /** analyze the strong branching for the given variable; that includes conflict analysis for infeasible branches and
2838  * storing of root reduced cost information
2839  */
2840 static
2842  SCIP* scip, /**< SCIP data structure */
2843  SCIP_VAR* var, /**< variable to analyze */
2844  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
2845  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
2846  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
2847  * infeasible downwards branch, or NULL */
2848  SCIP_Bool* upconflict /**< pointer to store whether a conflict constraint was created for an
2849  * infeasible upwards branch, or NULL */
2850  )
2851 {
2852  SCIP_COL* col;
2853  SCIP_Bool downcutoff;
2854  SCIP_Bool upcutoff;
2855 
2856  col = SCIPvarGetCol(var);
2857  assert(col != NULL);
2858 
2859  downcutoff = col->sbdownvalid && SCIPsetIsGE(scip->set, col->sbdown, scip->lp->cutoffbound);
2860  upcutoff = col->sbupvalid && SCIPsetIsGE(scip->set, col->sbup, scip->lp->cutoffbound);
2861 
2862  if( downinf != NULL )
2863  *downinf = downcutoff;
2864  if( upinf != NULL )
2865  *upinf = upcutoff;
2866 
2867  /* analyze infeasible strong branching sub problems:
2868  * because the strong branching's bound change is necessary for infeasibility, it cannot be undone;
2869  * therefore, infeasible strong branchings on non-binary variables will not produce a valid conflict constraint
2870  */
2871  if( scip->set->conf_enable && scip->set->conf_usesb && scip->set->nconflicthdlrs > 0
2872  && SCIPvarIsBinary(var) && SCIPtreeGetCurrentDepth(scip->tree) > 0 )
2873  {
2874  if( (downcutoff && SCIPsetFeasCeil(scip->set, col->primsol-1.0) >= col->lb - 0.5)
2875  || (upcutoff && SCIPsetFeasFloor(scip->set, col->primsol+1.0) <= col->ub + 0.5) )
2876  {
2877  assert(downconflict != NULL);
2878  assert(upconflict != NULL);
2879  SCIP_CALL( SCIPconflictAnalyzeStrongbranch(scip->conflict, scip->conflictstore, scip->mem->probmem, scip->set, scip->stat,
2880  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, col, downconflict, upconflict) );
2881  }
2882  }
2883 
2884  /* the strong branching results can be used to strengthen the root reduced cost information which is used for example
2885  * to propagate against the cutoff bound
2886  *
2887  * @note Ignore the results if the LP solution of the down (up) branch LP is smaller which should not happened by
2888  * theory but can arise due to numerical issues.
2889  */
2890  if( SCIPtreeGetCurrentDepth(scip->tree) == 0 && SCIPvarIsBinary(var) && SCIPlpIsDualReliable(scip->lp) )
2891  {
2892  SCIP_Real lpobjval;
2893 
2894  assert(SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL);
2895 
2896  lpobjval = SCIPlpGetObjval(scip->lp, scip->set, scip->transprob);
2897 
2898  if( col->sbdownvalid && SCIPsetFeasCeil(scip->set, col->primsol-1.0) >= col->lb - 0.5 && lpobjval < col->sbdown )
2899  SCIPvarUpdateBestRootSol(var, scip->set, SCIPvarGetUbGlobal(var), -(col->sbdown - lpobjval), lpobjval);
2900  if( col->sbupvalid && SCIPsetFeasFloor(scip->set, col->primsol+1.0) <= col->ub + 0.5 && lpobjval < col->sbup )
2901  SCIPvarUpdateBestRootSol(var, scip->set, SCIPvarGetLbGlobal(var), col->sbup - lpobjval, lpobjval);
2902  }
2903 
2904  return SCIP_OKAY;
2905 }
2906 
2907 /** gets strong branching information on column variable with fractional value
2908  *
2909  * Before calling this method, the strong branching mode must have been activated by calling SCIPstartStrongbranch();
2910  * after strong branching was done for all candidate variables, the strong branching mode must be ended by
2911  * SCIPendStrongbranch(). Since this method does not apply domain propagation before strongbranching,
2912  * propagation should not be enabled in the SCIPstartStrongbranch() call.
2913  *
2914  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2915  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2916  *
2917  * @pre This method can be called if @p scip is in one of the following stages:
2918  * - \ref SCIP_STAGE_PRESOLVED
2919  * - \ref SCIP_STAGE_SOLVING
2920  */
2922  SCIP* scip, /**< SCIP data structure */
2923  SCIP_VAR* var, /**< variable to get strong branching values for */
2924  int itlim, /**< iteration limit for strong branchings */
2925  SCIP_Bool idempotent, /**< should scip's state remain the same after the call (statistics, column states...), or should it be updated ? */
2926  SCIP_Real* down, /**< stores dual bound after branching column down */
2927  SCIP_Real* up, /**< stores dual bound after branching column up */
2928  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
2929  * otherwise, it can only be used as an estimate value */
2930  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
2931  * otherwise, it can only be used as an estimate value */
2932  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
2933  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
2934  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
2935  * infeasible downwards branch, or NULL */
2936  SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
2937  * infeasible upwards branch, or NULL */
2938  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
2939  * solving process should be stopped (e.g., due to a time limit) */
2940  )
2941 {
2942  SCIP_COL* col;
2943  SCIP_Real localdown;
2944  SCIP_Real localup;
2945  SCIP_Bool localdownvalid;
2946  SCIP_Bool localupvalid;
2947 
2948  assert(scip != NULL);
2949  assert(var != NULL);
2950  assert(lperror != NULL);
2951  assert(!SCIPtreeProbing(scip->tree)); /* we should not be in strong branching with propagation mode */
2952  assert(var->scip == scip);
2953 
2954  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchFrac", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2955 
2956  if( downvalid != NULL )
2957  *downvalid = FALSE;
2958  if( upvalid != NULL )
2959  *upvalid = FALSE;
2960  if( downinf != NULL )
2961  *downinf = FALSE;
2962  if( upinf != NULL )
2963  *upinf = FALSE;
2964  if( downconflict != NULL )
2965  *downconflict = FALSE;
2966  if( upconflict != NULL )
2967  *upconflict = FALSE;
2968 
2970  {
2971  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
2972  return SCIP_INVALIDDATA;
2973  }
2974 
2975  col = SCIPvarGetCol(var);
2976  assert(col != NULL);
2977 
2978  if( !SCIPcolIsInLP(col) )
2979  {
2980  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
2981  return SCIP_INVALIDDATA;
2982  }
2983 
2984  /* check if the solving process should be aborted */
2985  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
2986  {
2987  /* mark this as if the LP failed */
2988  *lperror = TRUE;
2989  return SCIP_OKAY;
2990  }
2991 
2992  /* call strong branching for column with fractional value */
2993  SCIP_CALL( SCIPcolGetStrongbranch(col, FALSE, scip->set, scip->stat, scip->transprob, scip->lp, itlim, !idempotent, !idempotent,
2994  &localdown, &localup, &localdownvalid, &localupvalid, lperror) );
2995 
2996  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
2997  * declare the sub nodes infeasible
2998  */
2999  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3000  {
3001  if( !idempotent ) /*lint !e774*/
3002  {
3003  SCIP_CALL( analyzeStrongbranch(scip, var, downinf, upinf, downconflict, upconflict) );
3004  }
3005  else
3006  {
3007  if( downinf != NULL )
3008  *downinf = localdownvalid && SCIPsetIsGE(scip->set, localdown, scip->lp->cutoffbound);
3009  if( upinf != NULL )
3010  *upinf = localupvalid && SCIPsetIsGE(scip->set, localup, scip->lp->cutoffbound);
3011  }
3012  }
3013 
3014  if( down != NULL )
3015  *down = localdown;
3016  if( up != NULL )
3017  *up = localup;
3018  if( downvalid != NULL )
3019  *downvalid = localdownvalid;
3020  if( upvalid != NULL )
3021  *upvalid = localupvalid;
3022 
3023  return SCIP_OKAY;
3024 }
3025 
3026 /** create, solve, and evaluate a single strong branching child (for strong branching with propagation) */
3027 static
3029  SCIP* scip, /**< SCIP data structure */
3030  SCIP_VAR* var, /**< variable to get strong branching values for */
3031  SCIP_Bool down, /**< do we regard the down child? */
3032  SCIP_Bool firstchild, /**< is this the first of the two strong branching children? */
3033  SCIP_Bool propagate, /**< should domain propagation be performed? */
3034  SCIP_Real newbound, /**< new bound to apply at the strong branching child */
3035  int itlim, /**< iteration limit for strong branchings */
3036  int maxproprounds, /**< maximum number of propagation rounds (-1: no limit, -2: parameter
3037  * settings) */
3038  SCIP_Real* value, /**< stores dual bound for strong branching child */
3039  SCIP_Bool* valid, /**< stores whether the returned value is a valid dual bound, or NULL;
3040  * otherwise, it can only be used as an estimate value */
3041  SCIP_Longint* ndomreductions, /**< pointer to store the number of domain reductions found, or NULL */
3042  SCIP_Bool* conflict, /**< pointer to store whether a conflict constraint was created for an
3043  * infeasible strong branching child, or NULL */
3044  SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred or the
3045  * solving process should be stopped (e.g., due to a time limit) */
3046  SCIP_VAR** vars, /**< active problem variables */
3047  int nvars, /**< number of active problem variables */
3048  SCIP_Real* newlbs, /**< array to store valid lower bounds for all active variables, or NULL */
3049  SCIP_Real* newubs, /**< array to store valid upper bounds for all active variables, or NULL */
3050  SCIP_Bool* foundsol, /**< pointer to store whether a primal solution was found during strong branching */
3051  SCIP_Bool* cutoff /**< pointer to store whether the strong branching child is infeasible */
3052  )
3053 {
3054  SCIP_Longint ndomreds;
3055 
3056  assert(value != NULL);
3057  assert(foundsol != NULL);
3058  assert(cutoff != NULL);
3059  assert(lperror != NULL);
3060  assert(valid != NULL ? !(*valid) : TRUE);
3061 
3062  *foundsol = FALSE;
3063  *cutoff = FALSE;
3064  *lperror = FALSE;
3065 
3066  /* check whether the strong branching child is already infeasible due to the bound change */
3067  if( down )
3068  {
3069  /* the down branch is infeasible due to the branching bound change; since this means that solval is not within the
3070  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3071  * are valid for and were already applied at the probing root
3072  */
3073  if( newbound < SCIPvarGetLbLocal(var) - 0.5 )
3074  {
3075  *value = SCIPinfinity(scip);
3076 
3077  if( valid != NULL )
3078  *valid = TRUE;
3079 
3080  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3081  if( conflict != NULL )
3082  *conflict = TRUE;
3083 
3084  *cutoff = TRUE;
3085 
3086  return SCIP_OKAY;
3087  }
3088  }
3089  else
3090  {
3091  /* the up branch is infeasible due to the branching bound change; since this means that solval is not within the
3092  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3093  * are valid for and were already applied at the probing root
3094  */
3095  if( newbound > SCIPvarGetUbLocal(var) + 0.5 )
3096  {
3097  *value = SCIPinfinity(scip);
3098 
3099  if( valid != NULL )
3100  *valid = TRUE;
3101 
3102  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3103  if( conflict != NULL )
3104  *conflict = TRUE;
3105 
3106  *cutoff = TRUE;
3107 
3108  return SCIP_OKAY;
3109  }
3110  }
3111 
3112  /* we need to ensure that we can create at least one new probing node without exceeding the maximal tree depth */
3114  {
3115  /* create a new probing node for the strong branching child and apply the new bound for the variable */
3116  SCIP_CALL( SCIPnewProbingNode(scip) );
3117 
3118  if( down )
3119  {
3120  assert(SCIPisGE(scip, newbound, SCIPvarGetLbLocal(var)));
3121  if( SCIPisLT(scip, newbound, SCIPvarGetUbLocal(var)) )
3122  {
3123  SCIP_CALL( SCIPchgVarUbProbing(scip, var, newbound) );
3124  }
3125  }
3126  else
3127  {
3128  assert(SCIPisLE(scip, newbound, SCIPvarGetUbLocal(var)));
3129  if( SCIPisGT(scip, newbound, SCIPvarGetLbLocal(var)) )
3130  {
3131  SCIP_CALL( SCIPchgVarLbProbing(scip, var, newbound) );
3132  }
3133  }
3134  }
3135  else
3136  {
3137  if( valid != NULL )
3138  *valid = FALSE;
3139 
3140  *cutoff = FALSE;
3141 
3142  if( conflict != NULL )
3143  *conflict = FALSE;
3144 
3145  return SCIP_OKAY;
3146  }
3147 
3148  /* propagate domains at the probing node */
3149  if( propagate )
3150  {
3151  /* start time measuring */
3152  SCIPclockStart(scip->stat->strongpropclock, scip->set);
3153 
3154  ndomreds = 0;
3155  SCIP_CALL( SCIPpropagateProbing(scip, maxproprounds, cutoff, &ndomreds) );
3156 
3157  /* store number of domain reductions in strong branching */
3158  if( down )
3159  SCIPstatAdd(scip->stat, scip->set, nsbdowndomchgs, ndomreds);
3160  else
3161  SCIPstatAdd(scip->stat, scip->set, nsbupdomchgs, ndomreds);
3162 
3163  if( ndomreductions != NULL )
3164  *ndomreductions = ndomreds;
3165 
3166  /* stop time measuring */
3167  SCIPclockStop(scip->stat->strongpropclock, scip->set);
3168 
3169  if( *cutoff )
3170  {
3171  *value = SCIPinfinity(scip);
3172 
3173  if( valid != NULL )
3174  *valid = TRUE;
3175 
3176  SCIPdebugMsg(scip, "%s branch of var <%s> detected infeasible during propagation\n",
3177  down ? "down" : "up", SCIPvarGetName(var));
3178  }
3179  }
3180 
3181  /* if propagation did not already detect infeasibility, solve the probing LP */
3182  if( !(*cutoff) )
3183  {
3184  SCIP_CALL( SCIPsolveProbingLP(scip, itlim, lperror, cutoff) );
3185  assert(SCIPisLPRelax(scip));
3186 
3187  if( *cutoff )
3188  {
3189  assert(!(*lperror));
3190 
3191  *value = SCIPinfinity(scip);
3192 
3193  if( valid != NULL )
3194  *valid = TRUE;
3195 
3196  SCIPdebugMsg(scip, "%s branch of var <%s> detected infeasible in LP solving: status=%d\n",
3197  down ? "down" : "up", SCIPvarGetName(var), SCIPgetLPSolstat(scip));
3198  }
3199  else if( !(*lperror) )
3200  {
3201  /* save the lp solution status */
3202  scip->stat->lastsblpsolstats[down ? 0 : 1] = SCIPgetLPSolstat(scip);
3203 
3204  switch( SCIPgetLPSolstat(scip) )
3205  {
3207  {
3208  *value = SCIPgetLPObjval(scip);
3209  assert(SCIPisLT(scip, *value, SCIPgetCutoffbound(scip)));
3210 
3211  SCIPdebugMsg(scip, "probing LP solved to optimality, objective value: %16.9g\n", *value);
3212 
3213  if( valid != NULL )
3214  *valid = TRUE;
3215 
3216  /* check the strong branching LP solution for feasibility */
3217  SCIP_CALL( SCIPtryStrongbranchLPSol(scip, foundsol, cutoff) );
3218  break;
3219  }
3221  ++scip->stat->nsbtimesiterlimhit;
3222  /*lint -fallthrough*/
3224  {
3225  /* use LP value as estimate */
3226  SCIP_LPI* lpi;
3227  SCIP_Real objval;
3228  SCIP_Real looseobjval;
3229 
3230  SCIPdebugMsg(scip, "probing LP hit %s limit\n", SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_ITERLIMIT ? "iteration" : "time");
3231 
3232  /* we access the LPI directly, because when a time limit was hit, we cannot access objective value and dual
3233  * feasibility using the SCIPlp... methods; we should try to avoid direct calls to the LPI, but this is rather
3234  * uncritical here, because we are immediately after the SCIPsolveProbingLP() call, because we access the LPI
3235  * read-only, and we check SCIPlpiWasSolved() first
3236  */
3237  SCIP_CALL( SCIPgetLPI(scip, &lpi) );
3238 
3239  if( SCIPlpiWasSolved(lpi) )
3240  {
3241  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
3242  looseobjval = SCIPlpGetLooseObjval(scip->lp, scip->set, scip->transprob);
3243 
3244  /* the infinity value in the LPI should not be smaller than SCIP's infinity value */
3245  assert(!SCIPlpiIsInfinity(lpi, objval) || SCIPisInfinity(scip, objval));
3246 
3247  /* we use SCIP's infinity value here because a value larger than this is counted as infeasible by SCIP */
3248  if( SCIPisInfinity(scip, objval) )
3249  *value = SCIPinfinity(scip);
3250  else if( SCIPisInfinity(scip, -looseobjval) )
3251  *value = -SCIPinfinity(scip);
3252  else
3253  *value = objval + looseobjval;
3254 
3255  if( SCIPlpiIsDualFeasible(lpi) )
3256  {
3257  if( valid != NULL )
3258  *valid = TRUE;
3259 
3260  if( SCIPisGE(scip, *value, SCIPgetCutoffbound(scip)) )
3261  *cutoff = TRUE;
3262  }
3263  }
3264  break;
3265  }
3266  case SCIP_LPSOLSTAT_ERROR:
3268  *lperror = TRUE;
3269  break;
3270  case SCIP_LPSOLSTAT_NOTSOLVED: /* should only be the case for *cutoff = TRUE or *lperror = TRUE */
3271  case SCIP_LPSOLSTAT_OBJLIMIT: /* in this case, *cutoff should be TRUE and we should not get here */
3272  case SCIP_LPSOLSTAT_INFEASIBLE: /* in this case, *cutoff should be TRUE and we should not get here */
3273  default:
3274  SCIPerrorMessage("invalid LP solution status <%d>\n", SCIPgetLPSolstat(scip));
3275  return SCIP_INVALIDDATA;
3276  } /*lint !e788*/
3277  }
3278 
3279  /* If columns are missing in the LP, the cutoff flag may be wrong. Therefore, we need to set it and the valid pointer
3280  * to false here.
3281  */
3282  if( (*cutoff) && !SCIPallColsInLP(scip) )
3283  {
3284  *cutoff = FALSE;
3285  }
3286 
3287 #ifndef NDEBUG
3288  if( *lperror )
3289  {
3290  SCIPdebugMsg(scip, "error during strong branching probing LP solving: status=%d\n", SCIPgetLPSolstat(scip));
3291  }
3292 #endif
3293  }
3294 
3295  /* if the subproblem was feasible, we store the local bounds of the variables after propagation and (possibly)
3296  * conflict analysis
3297  * @todo do this after propagation? should be able to get valid bounds more often, but they might be weaker
3298  */
3299  if( !(*cutoff) && newlbs != NULL)
3300  {
3301  int v;
3302 
3303  assert(newubs != NULL);
3304 
3305  /* initialize the newlbs and newubs to the current local bounds */
3306  if( firstchild )
3307  {
3308  for( v = 0; v < nvars; ++v )
3309  {
3310  newlbs[v] = SCIPvarGetLbLocal(vars[v]);
3311  newubs[v] = SCIPvarGetUbLocal(vars[v]);
3312  }
3313  }
3314  /* update newlbs and newubs: take the weaker of the already stored bounds and the current local bounds */
3315  else
3316  {
3317  for( v = 0; v < nvars; ++v )
3318  {
3319  SCIP_Real lb = SCIPvarGetLbLocal(vars[v]);
3320  SCIP_Real ub = SCIPvarGetUbLocal(vars[v]);
3321 
3322  newlbs[v] = MIN(newlbs[v], lb);
3323  newubs[v] = MAX(newubs[v], ub);
3324  }
3325  }
3326  }
3327 
3328  /* revert all changes at the probing node */
3329  SCIP_CALL( SCIPbacktrackProbing(scip, 0) );
3330 
3331  return SCIP_OKAY;
3332 }
3333 
3334 /** gets strong branching information with previous domain propagation on column variable
3335  *
3336  * Before calling this method, the strong branching mode must have been activated by calling SCIPstartStrongbranch();
3337  * after strong branching was done for all candidate variables, the strong branching mode must be ended by
3338  * SCIPendStrongbranch(). Since this method applies domain propagation before strongbranching, propagation has to be be
3339  * enabled in the SCIPstartStrongbranch() call.
3340  *
3341  * Before solving the strong branching LP, domain propagation can be performed. The number of propagation rounds
3342  * can be specified by the parameter @p maxproprounds.
3343  *
3344  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3345  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3346  *
3347  * @pre This method can be called if @p scip is in one of the following stages:
3348  * - \ref SCIP_STAGE_PRESOLVED
3349  * - \ref SCIP_STAGE_SOLVING
3350  *
3351  * @warning When using this method, LP banching candidates and solution values must be copied beforehand, because
3352  * they are updated w.r.t. the strong branching LP solution.
3353  */
3355  SCIP* scip, /**< SCIP data structure */
3356  SCIP_VAR* var, /**< variable to get strong branching values for */
3357  SCIP_Real solval, /**< value of the variable in the current LP solution */
3358  SCIP_Real lpobjval, /**< LP objective value of the current LP solution */
3359  int itlim, /**< iteration limit for strong branchings */
3360  int maxproprounds, /**< maximum number of propagation rounds (-1: no limit, -2: parameter
3361  * settings) */
3362  SCIP_Real* down, /**< stores dual bound after branching column down */
3363  SCIP_Real* up, /**< stores dual bound after branching column up */
3364  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
3365  * otherwise, it can only be used as an estimate value */
3366  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
3367  * otherwise, it can only be used as an estimate value */
3368  SCIP_Longint* ndomredsdown, /**< pointer to store the number of domain reductions down, or NULL */
3369  SCIP_Longint* ndomredsup, /**< pointer to store the number of domain reductions up, or NULL */
3370  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
3371  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
3372  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
3373  * infeasible downwards branch, or NULL */
3374  SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
3375  * infeasible upwards branch, or NULL */
3376  SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred or the
3377  * solving process should be stopped (e.g., due to a time limit) */
3378  SCIP_Real* newlbs, /**< array to store valid lower bounds for all active variables, or NULL */
3379  SCIP_Real* newubs /**< array to store valid upper bounds for all active variables, or NULL */
3380  )
3381 {
3382  SCIP_COL* col;
3383  SCIP_VAR** vars;
3384  SCIP_Longint oldniters;
3385  SCIP_Real newub;
3386  SCIP_Real newlb;
3387  SCIP_Bool propagate;
3388  SCIP_Bool cutoff;
3389  SCIP_Bool downchild;
3390  SCIP_Bool firstchild;
3391  SCIP_Bool foundsol;
3392  SCIP_Bool downvalidlocal;
3393  SCIP_Bool upvalidlocal;
3394  SCIP_Bool allcolsinlp;
3395  SCIP_Bool enabledconflict;
3396  int oldnconflicts;
3397  int nvars;
3398 
3399  assert(scip != NULL);
3400  assert(var != NULL);
3401  assert(SCIPvarIsIntegral(var));
3402  assert(down != NULL);
3403  assert(up != NULL);
3404  assert(lperror != NULL);
3405  assert((newlbs != NULL) == (newubs != NULL));
3406  assert(SCIPinProbing(scip));
3407  assert(var->scip == scip);
3408 
3409  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchWithPropagation", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3410 
3411  /* check whether propagation should be performed */
3412  propagate = (maxproprounds != 0 && maxproprounds != -3);
3413 
3414  /* Check, if all existing columns are in LP.
3415  * If this is not the case, we may still return that the up and down dual bounds are valid, because the branching
3416  * rule should not apply them otherwise.
3417  * However, we must not set the downinf or upinf pointers to TRUE based on the dual bound, because we cannot
3418  * guarantee that this node can be cut off.
3419  */
3420  allcolsinlp = SCIPallColsInLP(scip);
3421 
3422  /* if maxproprounds is -2, change it to 0, which for the following calls means using the parameter settings */
3423  if( maxproprounds == -2 )
3424  maxproprounds = 0;
3425 
3426  *down = lpobjval;
3427  *up = lpobjval;
3428  if( downvalid != NULL )
3429  *downvalid = FALSE;
3430  if( upvalid != NULL )
3431  *upvalid = FALSE;
3432  if( downinf != NULL )
3433  *downinf = FALSE;
3434  if( upinf != NULL )
3435  *upinf = FALSE;
3436  if( downconflict != NULL )
3437  *downconflict = FALSE;
3438  if( upconflict != NULL )
3439  *upconflict = FALSE;
3440  if( ndomredsdown != NULL )
3441  *ndomredsdown = 0;
3442  if( ndomredsup != NULL )
3443  *ndomredsup = 0;
3444 
3445  *lperror = FALSE;
3446 
3447  vars = SCIPgetVars(scip);
3448  nvars = SCIPgetNVars(scip);
3449 
3451 
3452  /* check if the solving process should be aborted */
3453  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3454  {
3455  /* mark this as if the LP failed */
3456  *lperror = TRUE;
3457  return SCIP_OKAY;
3458  }
3459 
3461  {
3462  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3463  return SCIP_INVALIDDATA;
3464  }
3465 
3466  col = SCIPvarGetCol(var);
3467  assert(col != NULL);
3468 
3469  if( !SCIPcolIsInLP(col) )
3470  {
3471  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3472  return SCIP_INVALIDDATA;
3473  }
3474 
3475  newlb = SCIPfeasFloor(scip, solval + 1.0);
3476  newub = SCIPfeasCeil(scip, solval - 1.0);
3477 
3478  SCIPdebugMsg(scip, "strong branching on var <%s>: solval=%g, lb=%g, ub=%g\n", SCIPvarGetName(var), solval,
3480 
3481  /* the up branch is infeasible due to the branching bound change; since this means that solval is not within the
3482  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3483  * are valid for and were already applied at the probing root
3484  */
3485  if( newlb > SCIPvarGetUbLocal(var) + 0.5 )
3486  {
3487  *up = SCIPinfinity(scip);
3488 
3489  if( upinf != NULL )
3490  *upinf = TRUE;
3491 
3492  if( upvalid != NULL )
3493  *upvalid = TRUE;
3494 
3495  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3496  if( upconflict != NULL )
3497  *upconflict = TRUE;
3498 
3499  SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3500  *down, *up, FALSE, TRUE, 0LL, INT_MAX);
3501 
3502  /* we do not regard the down branch; its valid pointer stays set to FALSE */
3503  return SCIP_OKAY;
3504  }
3505 
3506  /* the down branch is infeasible due to the branching bound change; since this means that solval is not within the
3507  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3508  * are valid for and were already applied at the probing root
3509  */
3510  if( newub < SCIPvarGetLbLocal(var) - 0.5 )
3511  {
3512  *down = SCIPinfinity(scip);
3513 
3514  if( downinf != NULL )
3515  *downinf = TRUE;
3516 
3517  if( downvalid != NULL )
3518  *downvalid = TRUE;
3519 
3520  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3521  if( downconflict != NULL )
3522  *downconflict = TRUE;
3523 
3524  SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3525  *down, *up, TRUE, FALSE, 0LL, INT_MAX);
3526 
3527  /* we do not regard the up branch; its valid pointer stays set to FALSE */
3528  return SCIP_OKAY;
3529  }
3530 
3531  /* We now do strong branching by creating the two potential child nodes as probing nodes and solving them one after
3532  * the other. We will stop when the first child is detected infeasible, saving the effort we would need for the
3533  * second child. Since empirically, the up child tends to be infeasible more often, we do strongbranching first on
3534  * the up branch.
3535  */
3536  oldniters = scip->stat->nsbdivinglpiterations;
3537  firstchild = TRUE;
3538  cutoff = FALSE;
3539 
3540  /* switch conflict analysis according to usesb parameter */
3541  enabledconflict = scip->set->conf_enable;
3542  scip->set->conf_enable = (scip->set->conf_enable && scip->set->conf_usesb);
3543 
3544  /* @todo: decide the branch to look at first based on the cutoffs in previous calls? */
3545  downchild = SCIPisStrongbranchDownFirst(scip, var);
3546 
3547  downvalidlocal = FALSE;
3548  upvalidlocal = FALSE;
3549 
3550  do
3551  {
3552  oldnconflicts = SCIPconflictGetNConflicts(scip->conflict);
3553 
3554  if( downchild )
3555  {
3556  SCIP_CALL( performStrongbranchWithPropagation(scip, var, downchild, firstchild, propagate, newub, itlim, maxproprounds,
3557  down, &downvalidlocal, ndomredsdown, downconflict, lperror, vars, nvars, newlbs, newubs, &foundsol, &cutoff) );
3558 
3559  /* check whether a new solutions rendered the previous child infeasible */
3560  if( foundsol && !firstchild && allcolsinlp )
3561  {
3562  if( SCIPisGE(scip, *up, SCIPgetCutoffbound(scip)) )
3563  {
3564  if( upinf != NULL )
3565  *upinf = TRUE;
3566  }
3567  }
3568 
3569  /* check for infeasibility */
3570  if( cutoff )
3571  {
3572  if( downinf != NULL )
3573  *downinf = TRUE;
3574 
3575  if( downconflict != NULL &&
3576  (SCIPvarGetLbLocal(var) > newub + 0.5 || SCIPconflictGetNConflicts(scip->conflict) > oldnconflicts) )
3577  {
3578  *downconflict = TRUE;
3579  }
3580 
3581  if( !scip->set->branch_forceall )
3582  {
3583  /* if this is the first call, we do not regard the up branch, its valid pointer is initially set to FALSE */
3584  break;
3585  }
3586  }
3587  }
3588  else
3589  {
3590  SCIP_CALL( performStrongbranchWithPropagation(scip, var, downchild, firstchild, propagate, newlb, itlim, maxproprounds,
3591  up, &upvalidlocal, ndomredsup, upconflict, lperror, vars, nvars, newlbs, newubs, &foundsol, &cutoff) );
3592 
3593  /* check whether a new solutions rendered the previous child infeasible */
3594  if( foundsol && !firstchild && allcolsinlp )
3595  {
3596  if( SCIPisGE(scip, *down, SCIPgetCutoffbound(scip)) )
3597  {
3598  if( downinf != NULL )
3599  *downinf = TRUE;
3600  }
3601  }
3602 
3603  /* check for infeasibility */
3604  if( cutoff )
3605  {
3606  if( upinf != NULL )
3607  *upinf = TRUE;
3608 
3609  assert(upinf == NULL || (*upinf) == TRUE);
3610 
3611  if( upconflict != NULL &&
3612  (SCIPvarGetUbLocal(var) < newlb - 0.5 || SCIPconflictGetNConflicts(scip->conflict) > oldnconflicts) )
3613  {
3614  *upconflict = TRUE;
3615  }
3616 
3617  if( !scip->set->branch_forceall )
3618  {
3619  /* if this is the first call, we do not regard the down branch, its valid pointer is initially set to FALSE */
3620  break;
3621  }
3622  }
3623  }
3624 
3625  downchild = !downchild;
3626  firstchild = !firstchild;
3627  }
3628  while( !firstchild );
3629 
3630  /* set strong branching information in column */
3631  if( *lperror )
3632  {
3633  SCIPcolInvalidateStrongbranchData(col, scip->set, scip->stat, scip->lp);
3634  }
3635  else
3636  {
3637  SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3638  *down, *up, downvalidlocal, upvalidlocal, scip->stat->nsbdivinglpiterations - oldniters, itlim);
3639  }
3640 
3641  if( downvalid != NULL )
3642  *downvalid = downvalidlocal;
3643  if( upvalid != NULL )
3644  *upvalid = upvalidlocal;
3645 
3646  scip->set->conf_enable = enabledconflict;
3647 
3648  return SCIP_OKAY; /*lint !e438*/
3649 }
3650 
3651 /** gets strong branching information on column variable x with integral LP solution value (val); that is, the down branch
3652  * is (val -1.0) and the up brach ins (val +1.0)
3653  *
3654  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3655  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3656  *
3657  * @pre This method can be called if @p scip is in one of the following stages:
3658  * - \ref SCIP_STAGE_PRESOLVED
3659  * - \ref SCIP_STAGE_SOLVING
3660  *
3661  * @note If the integral LP solution value is the lower or upper bound of the variable, the corresponding branch will be
3662  * marked as infeasible. That is, the valid pointer and the infeasible pointer are set to TRUE.
3663  */
3665  SCIP* scip, /**< SCIP data structure */
3666  SCIP_VAR* var, /**< variable to get strong branching values for */
3667  int itlim, /**< iteration limit for strong branchings */
3668  SCIP_Bool idempotent, /**< should scip's state remain the same after the call (statistics, column states...), or should it be updated ? */
3669  SCIP_Real* down, /**< stores dual bound after branching column down */
3670  SCIP_Real* up, /**< stores dual bound after branching column up */
3671  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
3672  * otherwise, it can only be used as an estimate value */
3673  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
3674  * otherwise, it can only be used as an estimate value */
3675  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
3676  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
3677  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
3678  * infeasible downwards branch, or NULL */
3679  SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
3680  * infeasible upwards branch, or NULL */
3681  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3682  * solving process should be stopped (e.g., due to a time limit) */
3683  )
3684 {
3685  SCIP_COL* col;
3686  SCIP_Real localdown;
3687  SCIP_Real localup;
3688  SCIP_Bool localdownvalid;
3689  SCIP_Bool localupvalid;
3690 
3691  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchInt", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3692 
3693  assert(lperror != NULL);
3694  assert(var->scip == scip);
3695 
3696  if( downvalid != NULL )
3697  *downvalid = FALSE;
3698  if( upvalid != NULL )
3699  *upvalid = FALSE;
3700  if( downinf != NULL )
3701  *downinf = FALSE;
3702  if( upinf != NULL )
3703  *upinf = FALSE;
3704  if( downconflict != NULL )
3705  *downconflict = FALSE;
3706  if( upconflict != NULL )
3707  *upconflict = FALSE;
3708 
3710  {
3711  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3712  return SCIP_INVALIDDATA;
3713  }
3714 
3715  col = SCIPvarGetCol(var);
3716  assert(col != NULL);
3717 
3718  if( !SCIPcolIsInLP(col) )
3719  {
3720  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3721  return SCIP_INVALIDDATA;
3722  }
3723 
3724  /* check if the solving process should be aborted */
3725  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3726  {
3727  /* mark this as if the LP failed */
3728  *lperror = TRUE;
3729  return SCIP_OKAY;
3730  }
3731 
3732  /* call strong branching for column */
3733  SCIP_CALL( SCIPcolGetStrongbranch(col, TRUE, scip->set, scip->stat, scip->transprob, scip->lp, itlim, !idempotent, !idempotent,
3734  &localdown, &localup, &localdownvalid, &localupvalid, lperror) );
3735 
3736  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3737  * declare the sub nodes infeasible
3738  */
3739  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3740  {
3741  if( !idempotent ) /*lint !e774*/
3742  {
3743  SCIP_CALL( analyzeStrongbranch(scip, var, downinf, upinf, downconflict, upconflict) );
3744  }
3745  else
3746  {
3747  if( downinf != NULL )
3748  *downinf = localdownvalid && SCIPsetIsGE(scip->set, localdown, scip->lp->cutoffbound);
3749  if( upinf != NULL )
3750  *upinf = localupvalid && SCIPsetIsGE(scip->set, localup, scip->lp->cutoffbound);
3751  }
3752  }
3753 
3754  if( down != NULL )
3755  *down = localdown;
3756  if( up != NULL )
3757  *up = localup;
3758  if( downvalid != NULL )
3759  *downvalid = localdownvalid;
3760  if( upvalid != NULL )
3761  *upvalid = localupvalid;
3762 
3763  return SCIP_OKAY;
3764 }
3765 
3766 /** gets strong branching information on column variables with fractional values
3767  *
3768  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3769  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3770  *
3771  * @pre This method can be called if @p scip is in one of the following stages:
3772  * - \ref SCIP_STAGE_PRESOLVED
3773  * - \ref SCIP_STAGE_SOLVING
3774  */
3776  SCIP* scip, /**< SCIP data structure */
3777  SCIP_VAR** vars, /**< variables to get strong branching values for */
3778  int nvars, /**< number of variables */
3779  int itlim, /**< iteration limit for strong branchings */
3780  SCIP_Real* down, /**< stores dual bounds after branching variables down */
3781  SCIP_Real* up, /**< stores dual bounds after branching variables up */
3782  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
3783  * otherwise, they can only be used as an estimate value */
3784  SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
3785  * otherwise, they can only be used as an estimate value */
3786  SCIP_Bool* downinf, /**< array to store whether the downward branches are infeasible, or NULL */
3787  SCIP_Bool* upinf, /**< array to store whether the upward branches are infeasible, or NULL */
3788  SCIP_Bool* downconflict, /**< array to store whether conflict constraints were created for
3789  * infeasible downward branches, or NULL */
3790  SCIP_Bool* upconflict, /**< array to store whether conflict constraints were created for
3791  * infeasible upward branches, or NULL */
3792  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3793  * solving process should be stopped (e.g., due to a time limit) */
3794  )
3795 {
3796  SCIP_COL** cols;
3797  int j;
3798 
3799  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarsStrongbranchesFrac", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3800 
3801  assert( lperror != NULL );
3802  assert( vars != NULL );
3803 
3804  /* set up data */
3805  cols = NULL;
3806  SCIP_CALL( SCIPallocBufferArray(scip, &cols, nvars) );
3807  assert(cols != NULL);
3808  for( j = 0; j < nvars; ++j )
3809  {
3810  SCIP_VAR* var;
3811  SCIP_COL* col;
3812 
3813  if( downvalid != NULL )
3814  downvalid[j] = FALSE;
3815  if( upvalid != NULL )
3816  upvalid[j] = FALSE;
3817  if( downinf != NULL )
3818  downinf[j] = FALSE;
3819  if( upinf != NULL )
3820  upinf[j] = FALSE;
3821  if( downconflict != NULL )
3822  downconflict[j] = FALSE;
3823  if( upconflict != NULL )
3824  upconflict[j] = FALSE;
3825 
3826  var = vars[j];
3827  assert( var != NULL );
3829  {
3830  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3831  SCIPfreeBufferArray(scip, &cols);
3832  return SCIP_INVALIDDATA;
3833  }
3834 
3835  col = SCIPvarGetCol(var);
3836  assert(col != NULL);
3837  cols[j] = col;
3838 
3839  if( !SCIPcolIsInLP(col) )
3840  {
3841  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3842  SCIPfreeBufferArray(scip, &cols);
3843  return SCIP_INVALIDDATA;
3844  }
3845  }
3846 
3847  /* check if the solving process should be aborted */
3848  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3849  {
3850  /* mark this as if the LP failed */
3851  *lperror = TRUE;
3852  }
3853  else
3854  {
3855  /* call strong branching for columns with fractional value */
3856  SCIP_CALL( SCIPcolGetStrongbranches(cols, nvars, FALSE, scip->set, scip->stat, scip->transprob, scip->lp, itlim,
3857  down, up, downvalid, upvalid, lperror) );
3858 
3859  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3860  * declare the sub nodes infeasible
3861  */
3862  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3863  {
3864  for( j = 0; j < nvars; ++j )
3865  {
3866  SCIP_CALL( analyzeStrongbranch(scip, vars[j], (downinf != NULL) ? (&(downinf[j])) : NULL,
3867  (upinf != NULL) ? (&(upinf[j])) : NULL, (downconflict != NULL) ? (&(downconflict[j])) : NULL,
3868  (upconflict != NULL) ? (&(upconflict[j])) : NULL) );
3869  }
3870  }
3871  }
3872  SCIPfreeBufferArray(scip, &cols);
3873 
3874  return SCIP_OKAY;
3875 }
3876 
3877 /** gets strong branching information on column variables with integral values
3878  *
3879  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3880  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3881  *
3882  * @pre This method can be called if @p scip is in one of the following stages:
3883  * - \ref SCIP_STAGE_PRESOLVED
3884  * - \ref SCIP_STAGE_SOLVING
3885  */
3887  SCIP* scip, /**< SCIP data structure */
3888  SCIP_VAR** vars, /**< variables to get strong branching values for */
3889  int nvars, /**< number of variables */
3890  int itlim, /**< iteration limit for strong branchings */
3891  SCIP_Real* down, /**< stores dual bounds after branching variables down */
3892  SCIP_Real* up, /**< stores dual bounds after branching variables up */
3893  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
3894  * otherwise, they can only be used as an estimate value */
3895  SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
3896  * otherwise, they can only be used as an estimate value */
3897  SCIP_Bool* downinf, /**< array to store whether the downward branches are infeasible, or NULL */
3898  SCIP_Bool* upinf, /**< array to store whether the upward branches are infeasible, or NULL */
3899  SCIP_Bool* downconflict, /**< array to store whether conflict constraints were created for
3900  * infeasible downward branches, or NULL */
3901  SCIP_Bool* upconflict, /**< array to store whether conflict constraints were created for
3902  * infeasible upward branches, or NULL */
3903  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3904  * solving process should be stopped (e.g., due to a time limit) */
3905  )
3906 {
3907  SCIP_COL** cols;
3908  int j;
3909 
3910  assert(lperror != NULL);
3911 
3912  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarsStrongbranchesInt", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3913 
3914  assert( vars != NULL );
3915 
3916  /* set up data */
3917  cols = NULL;
3918  SCIP_CALL( SCIPallocBufferArray(scip, &cols, nvars) );
3919  assert(cols != NULL);
3920  for( j = 0; j < nvars; ++j )
3921  {
3922  SCIP_VAR* var;
3923  SCIP_COL* col;
3924 
3925  if( downvalid != NULL )
3926  downvalid[j] = FALSE;
3927  if( upvalid != NULL )
3928  upvalid[j] = FALSE;
3929  if( downinf != NULL )
3930  downinf[j] = FALSE;
3931  if( upinf != NULL )
3932  upinf[j] = FALSE;
3933  if( downconflict != NULL )
3934  downconflict[j] = FALSE;
3935  if( upconflict != NULL )
3936  upconflict[j] = FALSE;
3937 
3938  var = vars[j];
3939  assert( var != NULL );
3941  {
3942  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3943  SCIPfreeBufferArray(scip, &cols);
3944  return SCIP_INVALIDDATA;
3945  }
3946 
3947  col = SCIPvarGetCol(var);
3948  assert(col != NULL);
3949  cols[j] = col;
3950 
3951  if( !SCIPcolIsInLP(col) )
3952  {
3953  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3954  SCIPfreeBufferArray(scip, &cols);
3955  return SCIP_INVALIDDATA;
3956  }
3957  }
3958 
3959  /* check if the solving process should be aborted */
3960  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3961  {
3962  /* mark this as if the LP failed */
3963  *lperror = TRUE;
3964  }
3965  else
3966  {
3967  /* call strong branching for columns */
3968  SCIP_CALL( SCIPcolGetStrongbranches(cols, nvars, TRUE, scip->set, scip->stat, scip->transprob, scip->lp, itlim,
3969  down, up, downvalid, upvalid, lperror) );
3970 
3971  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3972  * declare the sub nodes infeasible
3973  */
3974  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3975  {
3976  for( j = 0; j < nvars; ++j )
3977  {
3978  SCIP_CALL( analyzeStrongbranch(scip, vars[j], (downinf != NULL) ? (&(downinf[j])) : NULL,
3979  (upinf != NULL) ? (&(upinf[j])) : NULL, (downconflict != NULL) ? (&(downconflict[j])) : NULL,
3980  (upconflict != NULL) ? (&(upconflict[j])) : NULL) );
3981  }
3982  }
3983  }
3984  SCIPfreeBufferArray(scip, &cols);
3985 
3986  return SCIP_OKAY;
3987 }
3988 
3989 /** get LP solution status of last strong branching call (currently only works for strong branching with propagation) */
3991  SCIP* scip, /**< SCIP data structure */
3992  SCIP_BRANCHDIR branchdir /**< branching direction for which LP solution status is requested */
3993  )
3994 {
3995  assert(NULL != scip);
3996  assert(branchdir == SCIP_BRANCHDIR_DOWNWARDS || branchdir == SCIP_BRANCHDIR_UPWARDS);
3997 
3998  return scip->stat->lastsblpsolstats[branchdir == SCIP_BRANCHDIR_DOWNWARDS ? 0 : 1];
3999 }
4000 
4001 /** gets strong branching information on COLUMN variable of the last SCIPgetVarStrongbranch() call;
4002  * returns values of SCIP_INVALID, if strong branching was not yet called on the given variable;
4003  * keep in mind, that the returned old values may have nothing to do with the current LP solution
4004  *
4005  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4006  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4007  *
4008  * @pre This method can be called if @p scip is in one of the following stages:
4009  * - \ref SCIP_STAGE_SOLVING
4010  * - \ref SCIP_STAGE_SOLVED
4011  */
4013  SCIP* scip, /**< SCIP data structure */
4014  SCIP_VAR* var, /**< variable to get last strong branching values for */
4015  SCIP_Real* down, /**< stores dual bound after branching column down */
4016  SCIP_Real* up, /**< stores dual bound after branching column up */
4017  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4018  * otherwise, it can only be used as an estimate value */
4019  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4020  * otherwise, it can only be used as an estimate value */
4021  SCIP_Real* solval, /**< stores LP solution value of variable at the last strong branching call, or NULL */
4022  SCIP_Real* lpobjval /**< stores LP objective value at last strong branching call, or NULL */
4023  )
4024 {
4025  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchLast", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
4026 
4028  {
4029  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable\n");
4030  return SCIP_INVALIDDATA;
4031  }
4032 
4033  SCIPcolGetStrongbranchLast(SCIPvarGetCol(var), down, up, downvalid, upvalid, solval, lpobjval);
4034 
4035  return SCIP_OKAY;
4036 }
4037 
4038 /** sets strong branching information for a column variable
4039  *
4040  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4041  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4042  *
4043  * @pre This method can be called if @p scip is in one of the following stages:
4044  * - \ref SCIP_STAGE_SOLVING
4045  */
4047  SCIP* scip, /**< SCIP data structure */
4048  SCIP_VAR* var, /**< variable to set last strong branching values for */
4049  SCIP_Real lpobjval, /**< objective value of the current LP */
4050  SCIP_Real primsol, /**< primal solution value of the column in the current LP */
4051  SCIP_Real down, /**< dual bound after branching column down */
4052  SCIP_Real up, /**< dual bound after branching column up */
4053  SCIP_Bool downvalid, /**< is the returned down value a valid dual bound? */
4054  SCIP_Bool upvalid, /**< is the returned up value a valid dual bound? */
4055  SCIP_Longint iter, /**< total number of strong branching iterations */
4056  int itlim /**< iteration limit applied to the strong branching call */
4057  )
4058 {
4059  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetVarStrongbranchData", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4060 
4062  {
4063  SCIPerrorMessage("cannot set strong branching information on non-COLUMN variable\n");
4064  return SCIP_INVALIDDATA;
4065  }
4066 
4067  SCIPcolSetStrongbranchData(SCIPvarGetCol(var), scip->set, scip->stat, scip->lp, lpobjval, primsol,
4068  down, up, downvalid, upvalid, iter, itlim);
4069 
4070  return SCIP_OKAY;
4071 }
4072 
4073 /** rounds the current solution and tries it afterwards; if feasible, adds it to storage
4074  *
4075  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4076  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4077  *
4078  * @pre This method can be called if @p scip is in one of the following stages:
4079  * - \ref SCIP_STAGE_SOLVING
4080  */
4082  SCIP* scip, /**< SCIP data structure */
4083  SCIP_Bool* foundsol, /**< stores whether solution was feasible and good enough to keep */
4084  SCIP_Bool* cutoff /**< stores whether solution was cutoff due to exceeding the cutoffbound */
4085  )
4086 {
4087  assert(scip != NULL);
4088  assert(foundsol != NULL);
4089  assert(cutoff != NULL);
4090 
4091  SCIP_CALL( SCIPcheckStage(scip, "SCIPtryStrongbranchLPSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4092 
4093  if( scip->set->branch_checksbsol )
4094  {
4095  SCIP_SOL* sol;
4096  SCIP_Bool rounded = TRUE;
4097  SCIP_Real value = SCIPgetLPObjval(scip);
4098  SCIP_Longint oldnbestsolsfound = scip->primal->nbestsolsfound;
4099 
4100  /* start clock for strong branching solutions */
4101  SCIPclockStart(scip->stat->sbsoltime, scip->set);
4102 
4103  SCIP_CALL( SCIPcreateLPSol(scip, &sol, NULL) );
4105 
4106  /* try to round the strong branching solution */
4107  if( scip->set->branch_roundsbsol )
4108  {
4109  SCIP_CALL( SCIProundSol(scip, sol, &rounded) );
4110  }
4111 
4112  /* check the solution for feasibility if rounding worked well (or was not tried) */
4113  if( rounded )
4114  {
4115  SCIP_CALL( SCIPtrySolFree(scip, &sol, FALSE, FALSE, FALSE, TRUE, FALSE, foundsol) );
4116  }
4117  else
4118  {
4119  SCIP_CALL( SCIPfreeSol(scip, &sol) );
4120  }
4121 
4122  if( *foundsol )
4123  {
4124  SCIPdebugMsg(scip, "found new solution in strong branching\n");
4125 
4126  scip->stat->nsbsolsfound++;
4127 
4128  if( scip->primal->nbestsolsfound != oldnbestsolsfound )
4129  {
4130  scip->stat->nsbbestsolsfound++;
4131  }
4132 
4133  if( SCIPisGE(scip, value, SCIPgetCutoffbound(scip)) )
4134  *cutoff = TRUE;
4135  }
4136 
4137  /* stop clock for strong branching solutions */
4138  SCIPclockStop(scip->stat->sbsoltime, scip->set);
4139  }
4140  return SCIP_OKAY;
4141 }
4142 
4143 
4144 /** gets node number of the last node in current branch and bound run, where strong branching was used on the
4145  * given variable, or -1 if strong branching was never applied to the variable in current run
4146  *
4147  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4148  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4149  *
4150  * @pre This method can be called if @p scip is in one of the following stages:
4151  * - \ref SCIP_STAGE_TRANSFORMING
4152  * - \ref SCIP_STAGE_TRANSFORMED
4153  * - \ref SCIP_STAGE_INITPRESOLVE
4154  * - \ref SCIP_STAGE_PRESOLVING
4155  * - \ref SCIP_STAGE_EXITPRESOLVE
4156  * - \ref SCIP_STAGE_PRESOLVED
4157  * - \ref SCIP_STAGE_INITSOLVE
4158  * - \ref SCIP_STAGE_SOLVING
4159  * - \ref SCIP_STAGE_SOLVED
4160  * - \ref SCIP_STAGE_EXITSOLVE
4161  */
4163  SCIP* scip, /**< SCIP data structure */
4164  SCIP_VAR* var /**< variable to get last strong branching node for */
4165  )
4166 {
4167  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarStrongbranchNode", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4168 
4169  assert( var->scip == scip );
4170 
4172  return -1;
4173 
4175 }
4176 
4177 /** if strong branching was already applied on the variable at the current node, returns the number of LPs solved after
4178  * the LP where the strong branching on this variable was applied;
4179  * if strong branching was not yet applied on the variable at the current node, returns INT_MAX
4180  *
4181  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4182  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4183  *
4184  * @pre This method can be called if @p scip is in one of the following stages:
4185  * - \ref SCIP_STAGE_TRANSFORMING
4186  * - \ref SCIP_STAGE_TRANSFORMED
4187  * - \ref SCIP_STAGE_INITPRESOLVE
4188  * - \ref SCIP_STAGE_PRESOLVING
4189  * - \ref SCIP_STAGE_EXITPRESOLVE
4190  * - \ref SCIP_STAGE_PRESOLVED
4191  * - \ref SCIP_STAGE_INITSOLVE
4192  * - \ref SCIP_STAGE_SOLVING
4193  * - \ref SCIP_STAGE_SOLVED
4194  * - \ref SCIP_STAGE_EXITSOLVE
4195  */
4197  SCIP* scip, /**< SCIP data structure */
4198  SCIP_VAR* var /**< variable to get strong branching LP age for */
4199  )
4200 {
4201  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarStrongbranchLPAge", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4202 
4203  assert( var->scip == scip );
4204 
4206  return SCIP_LONGINT_MAX;
4207 
4208  return SCIPcolGetStrongbranchLPAge(SCIPvarGetCol(var), scip->stat);
4209 }
4210 
4211 /** gets number of times, strong branching was applied in current run on the given variable
4212  *
4213  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4214  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4215  *
4216  * @pre This method can be called if @p scip is in one of the following stages:
4217  * - \ref SCIP_STAGE_TRANSFORMING
4218  * - \ref SCIP_STAGE_TRANSFORMED
4219  * - \ref SCIP_STAGE_INITPRESOLVE
4220  * - \ref SCIP_STAGE_PRESOLVING
4221  * - \ref SCIP_STAGE_EXITPRESOLVE
4222  * - \ref SCIP_STAGE_PRESOLVED
4223  * - \ref SCIP_STAGE_INITSOLVE
4224  * - \ref SCIP_STAGE_SOLVING
4225  * - \ref SCIP_STAGE_SOLVED
4226  * - \ref SCIP_STAGE_EXITSOLVE
4227  */
4229  SCIP* scip, /**< SCIP data structure */
4230  SCIP_VAR* var /**< variable to get last strong branching node for */
4231  )
4232 {
4233  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarNStrongbranchs", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4234 
4235  assert( var->scip == scip );
4236 
4238  return 0;
4239 
4241 }
4242 
4243 /** adds given values to lock numbers of type @p locktype of variable for rounding
4244  *
4245  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4246  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4247  *
4248  * @pre This method can be called if @p scip is in one of the following stages:
4249  * - \ref SCIP_STAGE_PROBLEM
4250  * - \ref SCIP_STAGE_TRANSFORMING
4251  * - \ref SCIP_STAGE_TRANSFORMED
4252  * - \ref SCIP_STAGE_INITPRESOLVE
4253  * - \ref SCIP_STAGE_PRESOLVING
4254  * - \ref SCIP_STAGE_EXITPRESOLVE
4255  * - \ref SCIP_STAGE_PRESOLVED
4256  * - \ref SCIP_STAGE_INITSOLVE
4257  * - \ref SCIP_STAGE_SOLVING
4258  * - \ref SCIP_STAGE_EXITSOLVE
4259  * - \ref SCIP_STAGE_FREETRANS
4260  */
4262  SCIP* scip, /**< SCIP data structure */
4263  SCIP_VAR* var, /**< problem variable */
4264  SCIP_LOCKTYPE locktype, /**< type of the variable locks */
4265  int nlocksdown, /**< modification in number of rounding down locks */
4266  int nlocksup /**< modification in number of rounding up locks */
4267  )
4268 {
4269  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarLocksType", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4270 
4271  assert( var->scip == scip );
4272 
4273  switch( scip->set->stage )
4274  {
4275  case SCIP_STAGE_PROBLEM:
4276  assert(!SCIPvarIsTransformed(var));
4277  /*lint -fallthrough*/
4281  case SCIP_STAGE_PRESOLVING:
4283  case SCIP_STAGE_PRESOLVED:
4284  case SCIP_STAGE_INITSOLVE:
4285  case SCIP_STAGE_SOLVING:
4286  case SCIP_STAGE_EXITSOLVE:
4287  case SCIP_STAGE_FREETRANS:
4288  SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, locktype, nlocksdown, nlocksup) );
4289  return SCIP_OKAY;
4290 
4291  default:
4292  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4293  return SCIP_INVALIDCALL;
4294  } /*lint !e788*/
4295 }
4296 
4297 /** adds given values to lock numbers of variable for rounding
4298  *
4299  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4300  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4301  *
4302  * @pre This method can be called if @p scip is in one of the following stages:
4303  * - \ref SCIP_STAGE_PROBLEM
4304  * - \ref SCIP_STAGE_TRANSFORMING
4305  * - \ref SCIP_STAGE_TRANSFORMED
4306  * - \ref SCIP_STAGE_INITPRESOLVE
4307  * - \ref SCIP_STAGE_PRESOLVING
4308  * - \ref SCIP_STAGE_EXITPRESOLVE
4309  * - \ref SCIP_STAGE_PRESOLVED
4310  * - \ref SCIP_STAGE_INITSOLVE
4311  * - \ref SCIP_STAGE_SOLVING
4312  * - \ref SCIP_STAGE_EXITSOLVE
4313  * - \ref SCIP_STAGE_FREETRANS
4314  *
4315  * @note This method will always add variable locks of type model
4316  *
4317  * @note It is recommented to use SCIPaddVarLocksType()
4318  */
4320  SCIP* scip, /**< SCIP data structure */
4321  SCIP_VAR* var, /**< problem variable */
4322  int nlocksdown, /**< modification in number of rounding down locks */
4323  int nlocksup /**< modification in number of rounding up locks */
4324  )
4325 {
4326  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarLocks", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4327 
4328  SCIP_CALL( SCIPaddVarLocksType(scip, var, SCIP_LOCKTYPE_MODEL, nlocksdown, nlocksup) );
4329 
4330  return SCIP_OKAY;
4331 }
4332 
4333 /** add locks of variable with respect to the lock status of the constraint and its negation;
4334  * this method should be called whenever the lock status of a variable in a constraint changes, for example if
4335  * the coefficient of the variable changed its sign or if the left or right hand sides of the constraint were
4336  * added or removed
4337  *
4338  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4339  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4340  *
4341  * @pre This method can be called if @p scip is in one of the following stages:
4342  * - \ref SCIP_STAGE_PROBLEM
4343  * - \ref SCIP_STAGE_TRANSFORMING
4344  * - \ref SCIP_STAGE_TRANSFORMED
4345  * - \ref SCIP_STAGE_INITPRESOLVE
4346  * - \ref SCIP_STAGE_PRESOLVING
4347  * - \ref SCIP_STAGE_EXITPRESOLVE
4348  * - \ref SCIP_STAGE_INITSOLVE
4349  * - \ref SCIP_STAGE_SOLVING
4350  * - \ref SCIP_STAGE_EXITSOLVE
4351  * - \ref SCIP_STAGE_FREETRANS
4352  */
4354  SCIP* scip, /**< SCIP data structure */
4355  SCIP_VAR* var, /**< problem variable */
4356  SCIP_CONS* cons, /**< constraint */
4357  SCIP_Bool lockdown, /**< should the rounding be locked in downwards direction? */
4358  SCIP_Bool lockup /**< should the rounding be locked in upwards direction? */
4359  )
4360 {
4361  int nlocksdown[NLOCKTYPES];
4362  int nlocksup[NLOCKTYPES];
4363  int i;
4364 
4365  SCIP_CALL( SCIPcheckStage(scip, "SCIPlockVarCons", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4366 
4367  assert( var->scip == scip );
4368 
4369  for( i = 0; i < NLOCKTYPES; i++ )
4370  {
4371  nlocksdown[i] = 0;
4372  nlocksup[i] = 0;
4373 
4374  if( SCIPconsIsLockedTypePos(cons, (SCIP_LOCKTYPE) i) )
4375  {
4376  if( lockdown )
4377  ++nlocksdown[i];
4378  if( lockup )
4379  ++nlocksup[i];
4380  }
4381  if( SCIPconsIsLockedTypeNeg(cons, (SCIP_LOCKTYPE) i) )
4382  {
4383  if( lockdown )
4384  ++nlocksup[i];
4385  if( lockup )
4386  ++nlocksdown[i];
4387  }
4388  }
4389 
4390  switch( scip->set->stage )
4391  {
4392  case SCIP_STAGE_PROBLEM:
4393  assert(!SCIPvarIsTransformed(var));
4394  /*lint -fallthrough*/
4398  case SCIP_STAGE_PRESOLVING:
4400  case SCIP_STAGE_INITSOLVE:
4401  case SCIP_STAGE_SOLVING:
4402  case SCIP_STAGE_EXITSOLVE:
4403  case SCIP_STAGE_FREETRANS:
4404  for( i = 0; i < NLOCKTYPES; i++ )
4405  {
4406  if( nlocksdown[i] == 0 && nlocksup[i] == 0 )
4407  continue;
4408 
4409  SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, (SCIP_LOCKTYPE) i, nlocksdown[i], nlocksup[i]) );
4410  }
4411  return SCIP_OKAY;
4412 
4413  default:
4414  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4415  return SCIP_INVALIDCALL;
4416  } /*lint !e788*/
4417 }
4418 
4419 /** remove locks of type @p locktype of variable with respect to the lock status of the constraint and its negation;
4420  * this method should be called whenever the lock status of a variable in a constraint changes, for example if
4421  * the coefficient of the variable changed its sign or if the left or right hand sides of the constraint were
4422  * added or removed
4423  *
4424  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4425  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4426  *
4427  * @pre This method can be called if @p scip is in one of the following stages:
4428  * - \ref SCIP_STAGE_PROBLEM
4429  * - \ref SCIP_STAGE_TRANSFORMING
4430  * - \ref SCIP_STAGE_TRANSFORMED
4431  * - \ref SCIP_STAGE_INITPRESOLVE
4432  * - \ref SCIP_STAGE_PRESOLVING
4433  * - \ref SCIP_STAGE_EXITPRESOLVE
4434  * - \ref SCIP_STAGE_INITSOLVE
4435  * - \ref SCIP_STAGE_SOLVING
4436  * - \ref SCIP_STAGE_EXITSOLVE
4437  * - \ref SCIP_STAGE_FREETRANS
4438  */
4440  SCIP* scip, /**< SCIP data structure */
4441  SCIP_VAR* var, /**< problem variable */
4442  SCIP_CONS* cons, /**< constraint */
4443  SCIP_Bool lockdown, /**< should the rounding be unlocked in downwards direction? */
4444  SCIP_Bool lockup /**< should the rounding be unlocked in upwards direction? */
4445  )
4446 {
4447  int nlocksdown[NLOCKTYPES];
4448  int nlocksup[NLOCKTYPES];
4449  int i;
4450 
4451  SCIP_CALL( SCIPcheckStage(scip, "SCIPunlockVarCons", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4452 
4453  assert( var->scip == scip );
4454 
4455  for( i = 0; i < NLOCKTYPES; i++ )
4456  {
4457  nlocksdown[i] = 0;
4458  nlocksup[i] = 0;
4459 
4460  if( SCIPconsIsLockedTypePos(cons, (SCIP_LOCKTYPE) i) )
4461  {
4462  if( lockdown )
4463  ++nlocksdown[i];
4464  if( lockup )
4465  ++nlocksup[i];
4466  }
4467  if( SCIPconsIsLockedTypeNeg(cons, (SCIP_LOCKTYPE) i) )
4468  {
4469  if( lockdown )
4470  ++nlocksup[i];
4471  if( lockup )
4472  ++nlocksdown[i];
4473  }
4474  }
4475  switch( scip->set->stage )
4476  {
4477  case SCIP_STAGE_PROBLEM:
4478  assert(!SCIPvarIsTransformed(var));
4479  /*lint -fallthrough*/
4483  case SCIP_STAGE_PRESOLVING:
4485  case SCIP_STAGE_INITSOLVE:
4486  case SCIP_STAGE_SOLVING:
4487  case SCIP_STAGE_EXITSOLVE:
4488  case SCIP_STAGE_FREETRANS:
4489  for( i = 0; i < NLOCKTYPES; i++ )
4490  {
4491  if( nlocksdown[i] == 0 && nlocksup[i] == 0 )
4492  continue;
4493 
4494  SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, (SCIP_LOCKTYPE) i, -nlocksdown[i], -nlocksup[i]) );
4495  }
4496  return SCIP_OKAY;
4497 
4498  default:
4499  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4500  return SCIP_INVALIDCALL;
4501  } /*lint !e788*/
4502 }
4503 
4504 /** changes variable's objective value
4505  *
4506  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4507  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4508  *
4509  * @pre This method can be called if @p scip is in one of the following stages:
4510  * - \ref SCIP_STAGE_PROBLEM
4511  * - \ref SCIP_STAGE_TRANSFORMING
4512  * - \ref SCIP_STAGE_PRESOLVING
4513  * - \ref SCIP_STAGE_PRESOLVED
4514  */
4516  SCIP* scip, /**< SCIP data structure */
4517  SCIP_VAR* var, /**< variable to change the objective value for */
4518  SCIP_Real newobj /**< new objective value */
4519  )
4520 {
4521  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarObj", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
4522 
4523  assert( var->scip == scip );
4524 
4525  /* forbid infinite objective values */
4526  if( SCIPisInfinity(scip, REALABS(newobj)) )
4527  {
4528  SCIPerrorMessage("invalid objective value: objective value is infinite\n");
4529  return SCIP_INVALIDDATA;
4530  }
4531 
4532  switch( scip->set->stage )
4533  {
4534  case SCIP_STAGE_PROBLEM:
4535  assert(!SCIPvarIsTransformed(var));
4536  SCIP_CALL( SCIPvarChgObj(var, scip->mem->probmem, scip->set, scip->origprob, scip->primal, scip->lp, scip->eventqueue, newobj) );
4537  return SCIP_OKAY;
4538 
4541  case SCIP_STAGE_PRESOLVING:
4542  case SCIP_STAGE_PRESOLVED:
4543  SCIP_CALL( SCIPvarChgObj(var, scip->mem->probmem, scip->set, scip->transprob, scip->primal, scip->lp, scip->eventqueue, newobj) );
4544  return SCIP_OKAY;
4545 
4546  default:
4547  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4548  return SCIP_INVALIDCALL;
4549  } /*lint !e788*/
4550 }
4551 
4552 /** adds value to variable's objective value
4553  *
4554  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4555  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4556  *
4557  * @pre This method can be called if @p scip is in one of the following stages:
4558  * - \ref SCIP_STAGE_PROBLEM
4559  * - \ref SCIP_STAGE_TRANSFORMING
4560  * - \ref SCIP_STAGE_PRESOLVING
4561  * - \ref SCIP_STAGE_EXITPRESOLVE
4562  * - \ref SCIP_STAGE_PRESOLVED
4563  */
4565  SCIP* scip, /**< SCIP data structure */
4566  SCIP_VAR* var, /**< variable to change the objective value for */
4567  SCIP_Real addobj /**< additional objective value */
4568  )
4569 {
4570  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarObj", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
4571 
4572  assert( var->scip == scip );
4573 
4574  switch( scip->set->stage )
4575  {
4576  case SCIP_STAGE_PROBLEM:
4577  assert(!SCIPvarIsTransformed(var));
4578  SCIP_CALL( SCIPvarAddObj(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->primal,
4579  scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue, addobj) );
4580  return SCIP_OKAY;
4581 
4583  case SCIP_STAGE_PRESOLVING:
4585  case SCIP_STAGE_PRESOLVED:
4586  SCIP_CALL( SCIPvarAddObj(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->primal,
4587  scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue, addobj) );
4588  return SCIP_OKAY;
4589 
4590  default:
4591  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4592  return SCIP_INVALIDCALL;
4593  } /*lint !e788*/
4594 }
4595 
4596 /** returns the adjusted (i.e. rounded, if the given variable is of integral type) lower bound value;
4597  * does not change the bounds of the variable
4598  *
4599  * @return adjusted lower bound for the given variable; the bound of the variable is not changed
4600  *
4601  * @pre This method can be called if @p scip is in one of the following stages:
4602  * - \ref SCIP_STAGE_PROBLEM
4603  * - \ref SCIP_STAGE_TRANSFORMING
4604  * - \ref SCIP_STAGE_TRANSFORMED
4605  * - \ref SCIP_STAGE_INITPRESOLVE
4606  * - \ref SCIP_STAGE_PRESOLVING
4607  * - \ref SCIP_STAGE_EXITPRESOLVE
4608  * - \ref SCIP_STAGE_PRESOLVED
4609  * - \ref SCIP_STAGE_INITSOLVE
4610  * - \ref SCIP_STAGE_SOLVING
4611  * - \ref SCIP_STAGE_SOLVED
4612  * - \ref SCIP_STAGE_EXITSOLVE
4613  * - \ref SCIP_STAGE_FREETRANS
4614  */
4616  SCIP* scip, /**< SCIP data structure */
4617  SCIP_VAR* var, /**< variable to adjust the bound for */
4618  SCIP_Real lb /**< lower bound value to adjust */
4619  )
4620 {
4621  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPadjustedVarLb", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
4622 
4623  SCIPvarAdjustLb(var, scip->set, &lb);
4624 
4625  return lb;
4626 }
4627 
4628 /** returns the adjusted (i.e. rounded, if the given variable is of integral type) upper bound value;
4629  * does not change the bounds of the variable
4630  *
4631  * @return adjusted upper bound for the given variable; the bound of the variable is not changed
4632  *
4633  * @pre This method can be called if @p scip is in one of the following stages:
4634  * - \ref SCIP_STAGE_PROBLEM
4635  * - \ref SCIP_STAGE_TRANSFORMING
4636  * - \ref SCIP_STAGE_TRANSFORMED
4637  * - \ref SCIP_STAGE_INITPRESOLVE
4638  * - \ref SCIP_STAGE_PRESOLVING
4639  * - \ref SCIP_STAGE_EXITPRESOLVE
4640  * - \ref SCIP_STAGE_PRESOLVED
4641  * - \ref SCIP_STAGE_INITSOLVE
4642  * - \ref SCIP_STAGE_SOLVING
4643  * - \ref SCIP_STAGE_SOLVED
4644  * - \ref SCIP_STAGE_EXITSOLVE
4645  * - \ref SCIP_STAGE_FREETRANS
4646  */
4648  SCIP* scip, /**< SCIP data structure */
4649  SCIP_VAR* var, /**< variable to adjust the bound for */
4650  SCIP_Real ub /**< upper bound value to adjust */
4651  )
4652 {
4653  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPadjustedVarUb", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
4654 
4655  SCIPvarAdjustUb(var, scip->set, &ub);
4656 
4657  return ub;
4658 }
4659 
4660 /** depending on SCIP's stage, changes lower bound of variable in the problem, in preprocessing, or in current node;
4661  * if possible, adjusts bound to integral value; doesn't store any inference information in the bound change, such
4662  * that in conflict analysis, this change is treated like a branching decision
4663  *
4664  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4665  * SCIPgetVars()) gets resorted.
4666  *
4667  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4668  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4669  *
4670  * @pre This method can be called if @p scip is in one of the following stages:
4671  * - \ref SCIP_STAGE_PROBLEM
4672  * - \ref SCIP_STAGE_TRANSFORMING
4673  * - \ref SCIP_STAGE_PRESOLVING
4674  * - \ref SCIP_STAGE_SOLVING
4675  *
4676  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4677  */
4679  SCIP* scip, /**< SCIP data structure */
4680  SCIP_VAR* var, /**< variable to change the bound for */
4681  SCIP_Real newbound /**< new value for bound */
4682  )
4683 {
4684  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLb", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4685 
4686  SCIPvarAdjustLb(var, scip->set, &newbound);
4687 
4688  /* ignore tightenings of lower bounds to +infinity during solving process */
4689  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4690  {
4691 #ifndef NDEBUG
4692  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4693  SCIPvarGetLbLocal(var));
4694 #endif
4695  return SCIP_OKAY;
4696  }
4697 
4698  switch( scip->set->stage )
4699  {
4700  case SCIP_STAGE_PROBLEM:
4701  assert(!SCIPvarIsTransformed(var));
4702  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4703  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4704  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4705  scip->branchcand, scip->eventqueue, newbound) );
4706  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
4707  break;
4708 
4710  case SCIP_STAGE_PRESOLVED:
4711  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4712  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4713  break;
4714 
4715  case SCIP_STAGE_PRESOLVING:
4716  if( !SCIPinProbing(scip) )
4717  {
4718  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4719  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4720 
4721  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4722  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable,
4723  var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
4724 
4726  {
4727  SCIP_Bool infeasible;
4728 
4729  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
4730  assert(!infeasible);
4731  }
4732  break;
4733  }
4734  /*lint -fallthrough*/
4735  case SCIP_STAGE_SOLVING:
4737  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4738  scip->cliquetable, var, newbound,
4740  break;
4741 
4742  default:
4743  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4744  return SCIP_INVALIDCALL;
4745  } /*lint !e788*/
4746 
4747  return SCIP_OKAY;
4748 }
4749 
4750 /** depending on SCIP's stage, changes upper bound of variable in the problem, in preprocessing, or in current node;
4751  * if possible, adjusts bound to integral value; doesn't store any inference information in the bound change, such
4752  * that in conflict analysis, this change is treated like a branching decision
4753  *
4754  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4755  * SCIPgetVars()) gets resorted.
4756  *
4757  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4758  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4759  *
4760  * @pre This method can be called if @p scip is in one of the following stages:
4761  * - \ref SCIP_STAGE_PROBLEM
4762  * - \ref SCIP_STAGE_TRANSFORMING
4763  * - \ref SCIP_STAGE_PRESOLVING
4764  * - \ref SCIP_STAGE_SOLVING
4765  *
4766  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4767  */
4769  SCIP* scip, /**< SCIP data structure */
4770  SCIP_VAR* var, /**< variable to change the bound for */
4771  SCIP_Real newbound /**< new value for bound */
4772  )
4773 {
4774  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUb", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4775 
4776  SCIPvarAdjustUb(var, scip->set, &newbound);
4777 
4778  /* ignore tightenings of upper bounds to -infinity during solving process */
4779  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4780  {
4781 #ifndef NDEBUG
4782  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
4783  SCIPvarGetUbLocal(var));
4784 #endif
4785  return SCIP_OKAY;
4786  }
4787 
4788  switch( scip->set->stage )
4789  {
4790  case SCIP_STAGE_PROBLEM:
4791  assert(!SCIPvarIsTransformed(var));
4792  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4793  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4794  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4795  scip->branchcand, scip->eventqueue, newbound) );
4796  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
4797  break;
4798 
4800  case SCIP_STAGE_PRESOLVED:
4801  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4802  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4803  break;
4804 
4805  case SCIP_STAGE_PRESOLVING:
4806  if( !SCIPinProbing(scip) )
4807  {
4808  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4809  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4810 
4811  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4812  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4813  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
4814 
4816  {
4817  SCIP_Bool infeasible;
4818 
4819  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
4820  assert(!infeasible);
4821  }
4822  break;
4823  }
4824  /*lint -fallthrough*/
4825  case SCIP_STAGE_SOLVING:
4827  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4828  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
4829  break;
4830 
4831  default:
4832  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4833  return SCIP_INVALIDCALL;
4834  } /*lint !e788*/
4835 
4836  return SCIP_OKAY;
4837 }
4838 
4839 /** changes lower bound of variable in the given node; if possible, adjust bound to integral value; doesn't store any
4840  * inference information in the bound change, such that in conflict analysis, this change is treated like a branching
4841  * decision
4842  *
4843  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4844  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4845  *
4846  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
4847  */
4849  SCIP* scip, /**< SCIP data structure */
4850  SCIP_NODE* node, /**< node to change bound at, or NULL for current node */
4851  SCIP_VAR* var, /**< variable to change the bound for */
4852  SCIP_Real newbound /**< new value for bound */
4853  )
4854 {
4855  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbNode", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4856 
4857  if( node == NULL )
4858  {
4859  SCIP_CALL( SCIPchgVarLb(scip, var, newbound) );
4860  }
4861  else
4862  {
4863  SCIPvarAdjustLb(var, scip->set, &newbound);
4864 
4865  /* ignore tightenings of lower bounds to +infinity during solving process */
4866  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4867  {
4868 #ifndef NDEBUG
4869  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4870  SCIPvarGetLbLocal(var));
4871 #endif
4872  return SCIP_OKAY;
4873  }
4874 
4875  SCIP_CALL( SCIPnodeAddBoundchg(node, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
4876  scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4878  }
4879 
4880  return SCIP_OKAY;
4881 }
4882 
4883 /** changes upper bound of variable in the given node; if possible, adjust bound to integral value; doesn't store any
4884  * inference information in the bound change, such that in conflict analysis, this change is treated like a branching
4885  * decision
4886  *
4887  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4888  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4889  *
4890  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
4891  */
4893  SCIP* scip, /**< SCIP data structure */
4894  SCIP_NODE* node, /**< node to change bound at, or NULL for current node */
4895  SCIP_VAR* var, /**< variable to change the bound for */
4896  SCIP_Real newbound /**< new value for bound */
4897  )
4898 {
4899  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbNode", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4900 
4901  if( node == NULL )
4902  {
4903  SCIP_CALL( SCIPchgVarUb(scip, var, newbound) );
4904  }
4905  else
4906  {
4907  SCIPvarAdjustUb(var, scip->set, &newbound);
4908 
4909  /* ignore tightenings of upper bounds to -infinity during solving process */
4910  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4911  {
4912 #ifndef NDEBUG
4913  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
4914  SCIPvarGetUbLocal(var));
4915 #endif
4916  return SCIP_OKAY;
4917  }
4918 
4919  SCIP_CALL( SCIPnodeAddBoundchg(node, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
4920  scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4922  }
4923 
4924  return SCIP_OKAY;
4925 }
4926 
4927 /** changes global lower bound of variable; if possible, adjust bound to integral value; also tightens the local bound,
4928  * if the global bound is better than the local bound
4929  *
4930  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4931  * SCIPgetVars()) gets resorted.
4932  *
4933  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4934  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4935  *
4936  * @pre This method can be called if @p scip is in one of the following stages:
4937  * - \ref SCIP_STAGE_PROBLEM
4938  * - \ref SCIP_STAGE_TRANSFORMING
4939  * - \ref SCIP_STAGE_TRANSFORMED
4940  * - \ref SCIP_STAGE_PRESOLVING
4941  * - \ref SCIP_STAGE_SOLVING
4942  *
4943  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4944  */
4946  SCIP* scip, /**< SCIP data structure */
4947  SCIP_VAR* var, /**< variable to change the bound for */
4948  SCIP_Real newbound /**< new value for bound */
4949  )
4950 {
4951  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbGlobal", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4952 
4953  SCIPvarAdjustLb(var, scip->set, &newbound);
4954 
4955  /* ignore tightenings of lower bounds to +infinity during solving process */
4956  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4957  {
4958 #ifndef NDEBUG
4959  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4960  SCIPvarGetLbLocal(var));
4961 #endif
4962  return SCIP_OKAY;
4963  }
4964 
4965  switch( scip->set->stage )
4966  {
4967  case SCIP_STAGE_PROBLEM:
4968  assert(!SCIPvarIsTransformed(var));
4969  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4970  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4971  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4972  scip->branchcand, scip->eventqueue, newbound) );
4973  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
4974  break;
4975 
4978  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4979  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4980  break;
4981 
4982  case SCIP_STAGE_PRESOLVING:
4983  if( !SCIPinProbing(scip) )
4984  {
4985  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4986  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4987 
4988  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4989  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4991 
4993  {
4994  SCIP_Bool infeasible;
4995 
4996  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
4997  assert(!infeasible);
4998  }
4999  break;
5000  }
5001  /*lint -fallthrough*/
5002  case SCIP_STAGE_SOLVING:
5003  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5004  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5006  break;
5007 
5008  default:
5009  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5010  return SCIP_INVALIDCALL;
5011  } /*lint !e788*/
5012 
5013  return SCIP_OKAY;
5014 }
5015 
5016 /** changes global upper bound of variable; if possible, adjust bound to integral value; also tightens the local bound,
5017  * if the global bound is better than the local bound
5018  *
5019  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5020  * SCIPgetVars()) gets resorted.
5021  *
5022  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5023  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5024  *
5025  * @pre This method can be called if @p scip is in one of the following stages:
5026  * - \ref SCIP_STAGE_PROBLEM
5027  * - \ref SCIP_STAGE_TRANSFORMING
5028  * - \ref SCIP_STAGE_TRANSFORMED
5029  * - \ref SCIP_STAGE_PRESOLVING
5030  * - \ref SCIP_STAGE_SOLVING
5031  *
5032  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5033  */
5035  SCIP* scip, /**< SCIP data structure */
5036  SCIP_VAR* var, /**< variable to change the bound for */
5037  SCIP_Real newbound /**< new value for bound */
5038  )
5039 {
5040  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbGlobal", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5041