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