Scippy

SCIP

Solving Constraint Integer Programs

scip_var.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (c) 2002-2023 Zuse Institute Berlin (ZIB) */
7 /* */
8 /* Licensed under the Apache License, Version 2.0 (the "License"); */
9 /* you may not use this file except in compliance with the License. */
10 /* You may obtain a copy of the License at */
11 /* */
12 /* http://www.apache.org/licenses/LICENSE-2.0 */
13 /* */
14 /* Unless required by applicable law or agreed to in writing, software */
15 /* distributed under the License is distributed on an "AS IS" BASIS, */
16 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17 /* See the License for the specific language governing permissions and */
18 /* limitations under the License. */
19 /* */
20 /* You should have received a copy of the Apache-2.0 license */
21 /* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22 /* */
23 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24 
25 /**@file scip_var.c
26  * @ingroup OTHER_CFILES
27  * @brief public methods for SCIP variables
28  * @author Tobias Achterberg
29  * @author Timo Berthold
30  * @author Gerald Gamrath
31  * @author Leona Gottwald
32  * @author Stefan Heinz
33  * @author Gregor Hendel
34  * @author Thorsten Koch
35  * @author Alexander Martin
36  * @author Marc Pfetsch
37  * @author Michael Winkler
38  * @author Kati Wolter
39  *
40  * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE
41  */
42 
43 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
44 
45 #include <ctype.h>
46 #include "blockmemshell/memory.h"
47 #include "lpi/lpi.h"
48 #include "scip/branch.h"
49 #include "scip/clock.h"
50 #include "scip/conflict.h"
51 #include "scip/debug.h"
52 #include "scip/history.h"
53 #include "scip/implics.h"
54 #include "scip/lp.h"
55 #include "scip/prob.h"
56 #include "scip/pub_cons.h"
57 #include "scip/pub_implics.h"
58 #include "scip/pub_lp.h"
59 #include "scip/pub_message.h"
60 #include "scip/pub_misc.h"
61 #include "scip/pub_tree.h"
62 #include "scip/pub_var.h"
63 #include "scip/relax.h"
64 #include "scip/scip_general.h"
65 #include "scip/scip_lp.h"
66 #include "scip/scip_mem.h"
67 #include "scip/scip_message.h"
68 #include "scip/scip_numerics.h"
69 #include "scip/scip_prob.h"
70 #include "scip/scip_probing.h"
71 #include "scip/scip_sol.h"
72 #include "scip/scip_solvingstats.h"
73 #include "scip/scip_tree.h"
74 #include "scip/scip_var.h"
75 #include "scip/set.h"
76 #include "scip/sol.h"
77 #include "scip/solve.h"
78 #include "scip/stat.h"
79 #include "scip/struct_lp.h"
80 #include "scip/struct_mem.h"
81 #include "scip/struct_primal.h"
82 #include "scip/struct_prob.h"
83 #include "scip/struct_scip.h"
84 #include "scip/struct_set.h"
85 #include "scip/struct_stat.h"
86 #include "scip/struct_tree.h"
87 #include "scip/struct_var.h"
88 #include "scip/tree.h"
89 #include "scip/var.h"
90 
91 
92 /** creates and captures problem variable; if variable is of integral type, fractional bounds are automatically rounded;
93  * an integer variable with bounds zero and one is automatically converted into a binary variable;
94  *
95  * @warning When doing column generation and the original problem is a maximization problem, notice that SCIP will
96  * transform the problem into a minimization problem by multiplying the objective function by -1. Thus, the
97  * original objective function value of variables created during the solving process has to be multiplied by
98  * -1, too.
99  *
100  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
101  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
102  *
103  * @pre This method can be called if @p scip is in one of the following stages:
104  * - \ref SCIP_STAGE_PROBLEM
105  * - \ref SCIP_STAGE_TRANSFORMING
106  * - \ref SCIP_STAGE_INITPRESOLVE
107  * - \ref SCIP_STAGE_PRESOLVING
108  * - \ref SCIP_STAGE_EXITPRESOLVE
109  * - \ref SCIP_STAGE_PRESOLVED
110  * - \ref SCIP_STAGE_SOLVING
111  *
112  * @note the variable gets captured, hence at one point you have to release it using the method SCIPreleaseVar()
113  */
115  SCIP* scip, /**< SCIP data structure */
116  SCIP_VAR** var, /**< pointer to variable object */
117  const char* name, /**< name of variable, or NULL for automatic name creation */
118  SCIP_Real lb, /**< lower bound of variable */
119  SCIP_Real ub, /**< upper bound of variable */
120  SCIP_Real obj, /**< objective function value */
121  SCIP_VARTYPE vartype, /**< type of variable */
122  SCIP_Bool initial, /**< should var's column be present in the initial root LP? */
123  SCIP_Bool removable, /**< is var's column removable from the LP (due to aging or cleanup)? */
124  SCIP_DECL_VARDELORIG ((*vardelorig)), /**< frees user data of original variable, or NULL */
125  SCIP_DECL_VARTRANS ((*vartrans)), /**< creates transformed user data by transforming original user data, or NULL */
126  SCIP_DECL_VARDELTRANS ((*vardeltrans)), /**< frees user data of transformed variable, or NULL */
127  SCIP_DECL_VARCOPY ((*varcopy)), /**< copies variable data if wanted to subscip, or NULL */
128  SCIP_VARDATA* vardata /**< user data for this specific variable */
129  )
130 {
131  assert(var != NULL);
132  assert(lb <= ub);
133 
134  SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateVar", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
135 
136  /* forbid infinite objective function values */
137  if( SCIPisInfinity(scip, REALABS(obj)) )
138  {
139  SCIPerrorMessage("invalid objective function value: value is infinite\n");
140  return SCIP_INVALIDDATA;
141  }
142 
143  switch( scip->set->stage )
144  {
145  case SCIP_STAGE_PROBLEM:
146  SCIP_CALL( SCIPvarCreateOriginal(var, scip->mem->probmem, scip->set, scip->stat,
147  name, lb, ub, obj, vartype, initial, removable, vardelorig, vartrans, vardeltrans, varcopy, vardata) );
148  break;
149 
155  case SCIP_STAGE_SOLVING:
156  SCIP_CALL( SCIPvarCreateTransformed(var, scip->mem->probmem, scip->set, scip->stat,
157  name, lb, ub, obj, vartype, initial, removable, vardelorig, vartrans, vardeltrans, varcopy, vardata) );
158  break;
159 
160  default:
161  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
162  return SCIP_INVALIDCALL;
163  } /*lint !e788*/
164 
165  return SCIP_OKAY;
166 }
167 
168 /** creates and captures problem variable with optional callbacks and variable data set to NULL, which can be set
169  * afterwards using SCIPvarSetDelorigData(), SCIPvarSetTransData(),
170  * SCIPvarSetDeltransData(), SCIPvarSetCopy(), and SCIPvarSetData(); sets variable flags initial=TRUE
171  * and removable = FALSE, which can be adjusted by using SCIPvarSetInitial() and SCIPvarSetRemovable(), resp.;
172  * if variable is of integral type, fractional bounds are automatically rounded;
173  * an integer variable with bounds zero and one is automatically converted into a binary variable;
174  *
175  * @warning When doing column generation and the original problem is a maximization problem, notice that SCIP will
176  * transform the problem into a minimization problem by multiplying the objective function by -1. Thus, the
177  * original objective function value of variables created during the solving process has to be multiplied by
178  * -1, too.
179  *
180  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
181  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
182  *
183  * @pre This method can be called if @p scip is in one of the following stages:
184  * - \ref SCIP_STAGE_PROBLEM
185  * - \ref SCIP_STAGE_TRANSFORMING
186  * - \ref SCIP_STAGE_INITPRESOLVE
187  * - \ref SCIP_STAGE_PRESOLVING
188  * - \ref SCIP_STAGE_EXITPRESOLVE
189  * - \ref SCIP_STAGE_PRESOLVED
190  * - \ref SCIP_STAGE_SOLVING
191  *
192  * @note the variable gets captured, hence at one point you have to release it using the method SCIPreleaseVar()
193  */
195  SCIP* scip, /**< SCIP data structure */
196  SCIP_VAR** var, /**< pointer to variable object */
197  const char* name, /**< name of variable, or NULL for automatic name creation */
198  SCIP_Real lb, /**< lower bound of variable */
199  SCIP_Real ub, /**< upper bound of variable */
200  SCIP_Real obj, /**< objective function value */
201  SCIP_VARTYPE vartype /**< type of variable */
202  )
203 {
204  SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateVarBasic", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
205 
206  SCIP_CALL( SCIPcreateVar(scip, var, name, lb, ub, obj, vartype, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
207 
208  return SCIP_OKAY;
209 }
210 
211 /** outputs the variable name to the file stream
212  *
213  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
214  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
215  *
216  * @pre This method can be called if @p scip is in one of the following stages:
217  * - \ref SCIP_STAGE_PROBLEM
218  * - \ref SCIP_STAGE_TRANSFORMING
219  * - \ref SCIP_STAGE_TRANSFORMED
220  * - \ref SCIP_STAGE_INITPRESOLVE
221  * - \ref SCIP_STAGE_PRESOLVING
222  * - \ref SCIP_STAGE_EXITPRESOLVE
223  * - \ref SCIP_STAGE_PRESOLVED
224  * - \ref SCIP_STAGE_INITSOLVE
225  * - \ref SCIP_STAGE_SOLVING
226  * - \ref SCIP_STAGE_SOLVED
227  * - \ref SCIP_STAGE_EXITSOLVE
228  * - \ref SCIP_STAGE_FREETRANS
229  */
231  SCIP* scip, /**< SCIP data structure */
232  FILE* file, /**< output file, or NULL for stdout */
233  SCIP_VAR* var, /**< variable to output */
234  SCIP_Bool type /**< should the variable type be also posted */
235  )
236 {
237  assert(scip != NULL);
238  assert(var != NULL);
239 
240  SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarName", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
241 
242  /* print variable name */
243  if( SCIPvarIsNegated(var) )
244  {
245  SCIP_VAR* negatedvar;
246 
247  SCIP_CALL( SCIPgetNegatedVar(scip, var, &negatedvar) );
248  SCIPinfoMessage(scip, file, "<~%s>", SCIPvarGetName(negatedvar));
249  }
250  else
251  {
252  SCIPinfoMessage(scip, file, "<%s>", SCIPvarGetName(var));
253  }
254 
255  if( type )
256  {
257  /* print variable type */
258  SCIPinfoMessage(scip, file, "[%c]",
262  }
263 
264  return SCIP_OKAY;
265 }
266 
267 /** print the given list of variables to output stream separated by the given delimiter character;
268  *
269  * i. e. the variables x1, x2, ..., xn with given delimiter ',' are written as: <x1>, <x2>, ..., <xn>;
270  *
271  * the method SCIPparseVarsList() can parse such a string
272  *
273  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
274  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
275  *
276  * @pre This method can be called if @p scip is in one of the following stages:
277  * - \ref SCIP_STAGE_PROBLEM
278  * - \ref SCIP_STAGE_TRANSFORMING
279  * - \ref SCIP_STAGE_TRANSFORMED
280  * - \ref SCIP_STAGE_INITPRESOLVE
281  * - \ref SCIP_STAGE_PRESOLVING
282  * - \ref SCIP_STAGE_EXITPRESOLVE
283  * - \ref SCIP_STAGE_PRESOLVED
284  * - \ref SCIP_STAGE_INITSOLVE
285  * - \ref SCIP_STAGE_SOLVING
286  * - \ref SCIP_STAGE_SOLVED
287  * - \ref SCIP_STAGE_EXITSOLVE
288  * - \ref SCIP_STAGE_FREETRANS
289  *
290  * @note The printing process is done via the message handler system.
291  */
293  SCIP* scip, /**< SCIP data structure */
294  FILE* file, /**< output file, or NULL for stdout */
295  SCIP_VAR** vars, /**< variable array to output */
296  int nvars, /**< number of variables */
297  SCIP_Bool type, /**< should the variable type be also posted */
298  char delimiter /**< character which is used for delimitation */
299  )
300 {
301  int v;
302 
303  SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsList", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
304 
305  for( v = 0; v < nvars; ++v )
306  {
307  if( v > 0 )
308  {
309  SCIPinfoMessage(scip, file, "%c", delimiter);
310  }
311 
312  /* print variable name */
313  SCIP_CALL( SCIPwriteVarName(scip, file, vars[v], type) );
314  }
315 
316  return SCIP_OKAY;
317 }
318 
319 /** print the given variables and coefficients as linear sum in the following form
320  * c1 <x1> + c2 <x2> ... + cn <xn>
321  *
322  * This string can be parsed by the method SCIPparseVarsLinearsum().
323  *
324  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
325  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
326  *
327  * @pre This method can be called if @p scip is in one of the following stages:
328  * - \ref SCIP_STAGE_PROBLEM
329  * - \ref SCIP_STAGE_TRANSFORMING
330  * - \ref SCIP_STAGE_TRANSFORMED
331  * - \ref SCIP_STAGE_INITPRESOLVE
332  * - \ref SCIP_STAGE_PRESOLVING
333  * - \ref SCIP_STAGE_EXITPRESOLVE
334  * - \ref SCIP_STAGE_PRESOLVED
335  * - \ref SCIP_STAGE_INITSOLVE
336  * - \ref SCIP_STAGE_SOLVING
337  * - \ref SCIP_STAGE_SOLVED
338  * - \ref SCIP_STAGE_EXITSOLVE
339  * - \ref SCIP_STAGE_FREETRANS
340  *
341  * @note The printing process is done via the message handler system.
342  */
344  SCIP* scip, /**< SCIP data structure */
345  FILE* file, /**< output file, or NULL for stdout */
346  SCIP_VAR** vars, /**< variable array to output */
347  SCIP_Real* vals, /**< array of coefficients or NULL if all coefficients are 1.0 */
348  int nvars, /**< number of variables */
349  SCIP_Bool type /**< should the variable type be also posted */
350  )
351 {
352  int v;
353 
354  SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsLinearsum", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
355 
356  for( v = 0; v < nvars; ++v )
357  {
358  if( vals != NULL )
359  {
360  if( vals[v] == 1.0 )
361  {
362  if( v > 0 )
363  SCIPinfoMessage(scip, file, " +");
364  }
365  else if( vals[v] == -1.0 )
366  SCIPinfoMessage(scip, file, " -");
367  else
368  SCIPinfoMessage(scip, file, " %+.15g", vals[v]);
369  }
370  else if( nvars > 0 )
371  SCIPinfoMessage(scip, file, " +");
372 
373  /* print variable name */
374  SCIP_CALL( SCIPwriteVarName(scip, file, vars[v], type) );
375  }
376 
377  return SCIP_OKAY;
378 }
379 
380 /** print the given terms as signomial in the following form
381  * c1 <x11>^e11 <x12>^e12 ... <x1n>^e1n + c2 <x21>^e21 <x22>^e22 ... + ... + cn <xn1>^en1 ...
382  *
383  * This string can be parsed by the method SCIPparseVarsPolynomial().
384  *
385  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
386  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
387  *
388  * @pre This method can be called if @p scip is in one of the following stages:
389  * - \ref SCIP_STAGE_PROBLEM
390  * - \ref SCIP_STAGE_TRANSFORMING
391  * - \ref SCIP_STAGE_TRANSFORMED
392  * - \ref SCIP_STAGE_INITPRESOLVE
393  * - \ref SCIP_STAGE_PRESOLVING
394  * - \ref SCIP_STAGE_EXITPRESOLVE
395  * - \ref SCIP_STAGE_PRESOLVED
396  * - \ref SCIP_STAGE_INITSOLVE
397  * - \ref SCIP_STAGE_SOLVING
398  * - \ref SCIP_STAGE_SOLVED
399  * - \ref SCIP_STAGE_EXITSOLVE
400  * - \ref SCIP_STAGE_FREETRANS
401  *
402  * @note The printing process is done via the message handler system.
403  */
405  SCIP* scip, /**< SCIP data structure */
406  FILE* file, /**< output file, or NULL for stdout */
407  SCIP_VAR*** monomialvars, /**< arrays with variables for each monomial */
408  SCIP_Real** monomialexps, /**< arrays with variable exponents, or NULL if always 1.0 */
409  SCIP_Real* monomialcoefs, /**< array with monomial coefficients */
410  int* monomialnvars, /**< array with number of variables for each monomial */
411  int nmonomials, /**< number of monomials */
412  SCIP_Bool type /**< should the variable type be also posted */
413  )
414 {
415  int i;
416  int v;
417 
418  assert(scip != NULL);
419  assert(monomialvars != NULL || nmonomials == 0);
420  assert(monomialcoefs != NULL || nmonomials == 0);
421  assert(monomialnvars != NULL || nmonomials == 0);
422 
423  SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsPolynomial", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
424 
425  if( nmonomials == 0 )
426  {
427  SCIPinfoMessage(scip, file, " 0 ");
428  return SCIP_OKAY;
429  }
430 
431  for( i = 0; i < nmonomials; ++i )
432  {
433  if( monomialcoefs[i] == 1.0 ) /*lint !e613*/
434  {
435  if( i > 0 )
436  SCIPinfoMessage(scip, file, " +");
437  }
438  else if( monomialcoefs[i] == -1.0 ) /*lint !e613*/
439  SCIPinfoMessage(scip, file, " -");
440  else
441  SCIPinfoMessage(scip, file, " %+.15g", monomialcoefs[i]); /*lint !e613*/
442 
443  assert(monomialvars[i] != NULL || monomialnvars[i] == 0); /*lint !e613*/
444 
445  for( v = 0; v < monomialnvars[i]; ++v ) /*lint !e613*/
446  {
447  SCIP_CALL( SCIPwriteVarName(scip, file, monomialvars[i][v], type) ); /*lint !e613*/
448  if( monomialexps != NULL && monomialexps[i] != NULL && monomialexps[i][v] != 1.0 )
449  {
450  SCIPinfoMessage(scip, file, "^%.15g", monomialexps[i][v]);
451  }
452  }
453  }
454 
455  return SCIP_OKAY;
456 }
457 
458 /** parses variable information (in cip format) out of a string; if the parsing process was successful a variable is
459  * created and captured; if variable is of integral type, fractional bounds are automatically rounded; an integer
460  * variable with bounds zero and one is automatically converted into a binary variable
461  *
462  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
463  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
464  *
465  * @pre This method can be called if @p scip is in one of the following stages:
466  * - \ref SCIP_STAGE_PROBLEM
467  * - \ref SCIP_STAGE_TRANSFORMING
468  * - \ref SCIP_STAGE_INITPRESOLVE
469  * - \ref SCIP_STAGE_PRESOLVING
470  * - \ref SCIP_STAGE_EXITPRESOLVE
471  * - \ref SCIP_STAGE_PRESOLVED
472  * - \ref SCIP_STAGE_SOLVING
473  */
475  SCIP* scip, /**< SCIP data structure */
476  SCIP_VAR** var, /**< pointer to store the problem variable */
477  const char* str, /**< string to parse */
478  SCIP_Bool initial, /**< should var's column be present in the initial root LP? */
479  SCIP_Bool removable, /**< is var's column removable from the LP (due to aging or cleanup)? */
480  SCIP_DECL_VARCOPY ((*varcopy)), /**< copies variable data if wanted to subscip, or NULL */
481  SCIP_DECL_VARDELORIG ((*vardelorig)), /**< frees user data of original variable */
482  SCIP_DECL_VARTRANS ((*vartrans)), /**< creates transformed user data by transforming original user data */
483  SCIP_DECL_VARDELTRANS ((*vardeltrans)), /**< frees user data of transformed variable */
484  SCIP_VARDATA* vardata, /**< user data for this specific variable */
485  char** endptr, /**< pointer to store the final string position if successful */
486  SCIP_Bool* success /**< pointer store if the paring process was successful */
487  )
488 {
489  assert(var != NULL);
490 
491  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVar", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
492 
493  switch( scip->set->stage )
494  {
495  case SCIP_STAGE_PROBLEM:
496  SCIP_CALL( SCIPvarParseOriginal(var, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
497  str, initial, removable, varcopy, vardelorig, vartrans, vardeltrans, vardata, endptr, success) );
498  break;
499 
505  case SCIP_STAGE_SOLVING:
506  SCIP_CALL( SCIPvarParseTransformed(var, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
507  str, initial, removable, varcopy, vardelorig, vartrans, vardeltrans, vardata, endptr, success) );
508  break;
509 
510  default:
511  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
512  return SCIP_INVALIDCALL;
513  } /*lint !e788*/
514 
515  return SCIP_OKAY;
516 }
517 
518 /** parses the given string for a variable name and stores the variable in the corresponding pointer if such a variable
519  * exits and returns the position where the parsing stopped
520  *
521  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
522  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
523  *
524  * @pre This method can be called if @p scip is in one of the following stages:
525  * - \ref SCIP_STAGE_PROBLEM
526  * - \ref SCIP_STAGE_TRANSFORMING
527  * - \ref SCIP_STAGE_INITPRESOLVE
528  * - \ref SCIP_STAGE_PRESOLVING
529  * - \ref SCIP_STAGE_EXITPRESOLVE
530  * - \ref SCIP_STAGE_PRESOLVED
531  * - \ref SCIP_STAGE_SOLVING
532  */
534  SCIP* scip, /**< SCIP data structure */
535  const char* str, /**< string to parse */
536  SCIP_VAR** var, /**< pointer to store the problem variable, or NULL if it does not exit */
537  char** endptr /**< pointer to store the final string position if successful */
538  )
539 {
540  char varname[SCIP_MAXSTRLEN];
541 
542  assert(str != NULL);
543  assert(var != NULL);
544  assert(endptr != NULL);
545 
546  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarName", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
547 
548  SCIPstrCopySection(str, '<', '>', varname, SCIP_MAXSTRLEN, endptr);
549  assert(*endptr != NULL);
550 
551  if( *endptr == str )
552  {
553  *var = NULL;
554  return SCIP_OKAY;
555  }
556 
557  /* check if we have a negated variable */
558  if( *varname == '~' )
559  {
560  SCIPdebugMsg(scip, "parsed negated variable name <%s>\n", &varname[1]);
561 
562  /* search for the variable and ignore '~' */
563  (*var) = SCIPfindVar(scip, &varname[1]);
564 
565  if( *var != NULL )
566  {
567  SCIP_CALL( SCIPgetNegatedVar(scip, *var, var) );
568  }
569  }
570  else
571  {
572  SCIPdebugMsg(scip, "parsed variable name <%s>\n", varname);
573 
574  /* search for the variable */
575  (*var) = SCIPfindVar(scip, varname);
576  }
577 
578  str = *endptr;
579 
580  /* skip additional variable type marker */
581  if( *str == '[' && (str[1] == SCIP_VARTYPE_BINARY_CHAR || str[1] == SCIP_VARTYPE_INTEGER_CHAR ||
582  str[1] == SCIP_VARTYPE_IMPLINT_CHAR || str[1] == SCIP_VARTYPE_CONTINUOUS_CHAR ) && str[2] == ']' )
583  (*endptr) += 3;
584 
585  return SCIP_OKAY;
586 }
587 
588 /** parse the given string as variable list (here ',' is the delimiter)) (<x1>, <x2>, ..., <xn>) (see
589  * SCIPwriteVarsList() ); if it was successful, the pointer success is set to TRUE
590  *
591  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
592  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
593  *
594  * @pre This method can be called if @p scip is in one of the following stages:
595  * - \ref SCIP_STAGE_PROBLEM
596  * - \ref SCIP_STAGE_TRANSFORMING
597  * - \ref SCIP_STAGE_INITPRESOLVE
598  * - \ref SCIP_STAGE_PRESOLVING
599  * - \ref SCIP_STAGE_EXITPRESOLVE
600  * - \ref SCIP_STAGE_PRESOLVED
601  * - \ref SCIP_STAGE_SOLVING
602  *
603  * @note The pointer success in only set to FALSE in the case that a variable with a parsed variable name does not exist.
604  *
605  * @note If the number of (parsed) variables is greater than the available slots in the variable array, nothing happens
606  * except that the required size is stored in the corresponding integer; the reason for this approach is that we
607  * cannot reallocate memory, since we do not know how the memory has been allocated (e.g., by a C++ 'new' or SCIP
608  * memory functions).
609  */
611  SCIP* scip, /**< SCIP data structure */
612  const char* str, /**< string to parse */
613  SCIP_VAR** vars, /**< array to store the parsed variable */
614  int* nvars, /**< pointer to store number of parsed variables */
615  int varssize, /**< size of the variable array */
616  int* requiredsize, /**< pointer to store the required array size for the active variables */
617  char** endptr, /**< pointer to store the final string position if successful */
618  char delimiter, /**< character which is used for delimitation */
619  SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
620  )
621 {
622  SCIP_VAR** tmpvars;
623  SCIP_VAR* var;
624  int ntmpvars = 0;
625  int v;
626 
627  assert( nvars != NULL );
628  assert( requiredsize != NULL );
629  assert( endptr != NULL );
630  assert( success != NULL );
631 
632  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsList", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
633 
634  /* allocate buffer memory for temporary storing the parsed variables */
635  SCIP_CALL( SCIPallocBufferArray(scip, &tmpvars, varssize) );
636 
637  *success = TRUE;
638 
639  do
640  {
641  *endptr = (char*)str;
642 
643  /* parse variable name */
644  SCIP_CALL( SCIPparseVarName(scip, str, &var, endptr) );
645 
646  if( var == NULL )
647  break;
648 
649  str = *endptr;
650 
651  /* store the variable in the tmp array */
652  if( ntmpvars < varssize )
653  tmpvars[ntmpvars] = var;
654 
655  ntmpvars++;
656 
657  SCIP_CALL( SCIPskipSpace((char**)&str) );
658  }
659  while( *str == delimiter );
660 
661  *endptr = (char*)str;
662 
663  /* if all variable name searches were successful and the variable array has enough slots, copy the collected variables */
664  if( (*success) && ntmpvars <= varssize )
665  {
666  for( v = 0; v < ntmpvars; ++v )
667  vars[v] = tmpvars[v];
668 
669  (*nvars) = ntmpvars;
670  }
671  else
672  (*nvars) = 0;
673 
674  (*requiredsize) = ntmpvars;
675 
676  /* free buffer arrays */
677  SCIPfreeBufferArray(scip, &tmpvars);
678 
679  return SCIP_OKAY;
680 }
681 
682 /** parse the given string as linear sum of variables and coefficients (c1 <x1> + c2 <x2> + ... + cn <xn>)
683  * (see SCIPwriteVarsLinearsum() ); if it was successful, the pointer success is set to TRUE
684  *
685  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
686  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
687  *
688  * @pre This method can be called if @p scip is in one of the following stages:
689  * - \ref SCIP_STAGE_PROBLEM
690  * - \ref SCIP_STAGE_TRANSFORMING
691  * - \ref SCIP_STAGE_INITPRESOLVE
692  * - \ref SCIP_STAGE_PRESOLVING
693  * - \ref SCIP_STAGE_EXITPRESOLVE
694  * - \ref SCIP_STAGE_PRESOLVED
695  * - \ref SCIP_STAGE_SOLVING
696  *
697  * @note The pointer success in only set to FALSE in the case that a variable with a parsed variable name does not exist.
698  *
699  * @note If the number of (parsed) variables is greater than the available slots in the variable array, nothing happens
700  * except that the required size is stored in the corresponding integer; the reason for this approach is that we
701  * cannot reallocate memory, since we do not know how the memory has been allocated (e.g., by a C++ 'new' or SCIP
702  * memory functions).
703  */
705  SCIP* scip, /**< SCIP data structure */
706  const char* str, /**< string to parse */
707  SCIP_VAR** vars, /**< array to store the parsed variables */
708  SCIP_Real* vals, /**< array to store the parsed coefficients */
709  int* nvars, /**< pointer to store number of parsed variables */
710  int varssize, /**< size of the variable array */
711  int* requiredsize, /**< pointer to store the required array size for the active variables */
712  char** endptr, /**< pointer to store the final string position if successful */
713  SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
714  )
715 {
716  SCIP_VAR*** monomialvars;
717  SCIP_Real** monomialexps;
718  SCIP_Real* monomialcoefs;
719  int* monomialnvars;
720  int nmonomials;
721 
722  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsLinearsum", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
723 
724  assert(scip != NULL);
725  assert(str != NULL);
726  assert(vars != NULL || varssize == 0);
727  assert(vals != NULL || varssize == 0);
728  assert(nvars != NULL);
729  assert(requiredsize != NULL);
730  assert(endptr != NULL);
731  assert(success != NULL);
732 
733  *requiredsize = 0;
734 
735  SCIP_CALL( SCIPparseVarsPolynomial(scip, str, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, &nmonomials, endptr, success) );
736 
737  if( !*success )
738  {
739  assert(nmonomials == 0); /* SCIPparseVarsPolynomial should have freed all buffers, so no need to call free here */
740  return SCIP_OKAY;
741  }
742 
743  /* check if linear sum is just "0" */
744  if( nmonomials == 1 && monomialnvars[0] == 0 && monomialcoefs[0] == 0.0 )
745  {
746  *nvars = 0;
747  *requiredsize = 0;
748 
749  SCIPfreeParseVarsPolynomialData(scip, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, nmonomials);
750 
751  return SCIP_OKAY;
752  }
753 
754  *nvars = nmonomials;
755  *requiredsize = nmonomials;
756 
757  /* if we have enough slots in the variables array, copy variables over */
758  if( varssize >= nmonomials )
759  {
760  int v;
761 
762  for( v = 0; v < nmonomials; ++v )
763  {
764  if( monomialnvars[v] == 0 )
765  {
766  SCIPerrorMessage("constant in linear sum\n");
767  *success = FALSE;
768  break;
769  }
770  if( monomialnvars[v] > 1 || monomialexps[v][0] != 1.0 )
771  {
772  SCIPerrorMessage("nonlinear monomial in linear sum\n");
773  *success = FALSE;
774  break;
775  }
776  assert(monomialnvars[v] == 1);
777  assert(monomialvars[v][0] != NULL);
778  assert(monomialexps[v][0] == 1.0);
779 
780  vars[v] = monomialvars[v][0]; /*lint !e613*/
781  vals[v] = monomialcoefs[v]; /*lint !e613*/
782  }
783  }
784 
785  SCIPfreeParseVarsPolynomialData(scip, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, nmonomials);
786 
787  return SCIP_OKAY;
788 }
789 
790 /** parse the given string as signomial of variables and coefficients
791  * (c1 <x11>^e11 <x12>^e12 ... <x1n>^e1n + c2 <x21>^e21 <x22>^e22 ... + ... + cn <xn1>^en1 ...)
792  * (see SCIPwriteVarsPolynomial()); if it was successful, the pointer success is set to TRUE
793  *
794  * The user has to call SCIPfreeParseVarsPolynomialData(scip, monomialvars, monomialexps,
795  * monomialcoefs, monomialnvars, *nmonomials) short after SCIPparseVarsPolynomial to free all the
796  * allocated memory again.
797  *
798  * Parsing is stopped at the end of string (indicated by the \\0-character) or when no more monomials
799  * are recognized.
800  *
801  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
802  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
803  *
804  * @pre This method can be called if @p scip is in one of the following stages:
805  * - \ref SCIP_STAGE_PROBLEM
806  * - \ref SCIP_STAGE_TRANSFORMING
807  * - \ref SCIP_STAGE_INITPRESOLVE
808  * - \ref SCIP_STAGE_PRESOLVING
809  * - \ref SCIP_STAGE_EXITPRESOLVE
810  * - \ref SCIP_STAGE_PRESOLVED
811  * - \ref SCIP_STAGE_SOLVING
812  */
814  SCIP* scip, /**< SCIP data structure */
815  const char* str, /**< string to parse */
816  SCIP_VAR**** monomialvars, /**< pointer to store arrays with variables for each monomial */
817  SCIP_Real*** monomialexps, /**< pointer to store arrays with variable exponents */
818  SCIP_Real** monomialcoefs, /**< pointer to store array with monomial coefficients */
819  int** monomialnvars, /**< pointer to store array with number of variables for each monomial */
820  int* nmonomials, /**< pointer to store number of parsed monomials */
821  char** endptr, /**< pointer to store the final string position if successful */
822  SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
823  )
824 {
825  typedef enum
826  {
827  SCIPPARSEPOLYNOMIAL_STATE_BEGIN, /* we are at the beginning of a monomial */
828  SCIPPARSEPOLYNOMIAL_STATE_INTERMED, /* we are in between the factors of a monomial */
829  SCIPPARSEPOLYNOMIAL_STATE_COEF, /* we parse the coefficient of a monomial */
830  SCIPPARSEPOLYNOMIAL_STATE_VARS, /* we parse monomial variables */
831  SCIPPARSEPOLYNOMIAL_STATE_EXPONENT, /* we parse the exponent of a variable */
832  SCIPPARSEPOLYNOMIAL_STATE_END, /* we are at the end the polynomial */
833  SCIPPARSEPOLYNOMIAL_STATE_ERROR /* a parsing error occured */
834  } SCIPPARSEPOLYNOMIAL_STATES;
835 
836  SCIPPARSEPOLYNOMIAL_STATES state;
837  int monomialssize;
838 
839  /* data of currently parsed monomial */
840  int varssize;
841  int nvars;
842  SCIP_VAR** vars;
843  SCIP_Real* exponents;
844  SCIP_Real coef;
845 
846  assert(scip != NULL);
847  assert(str != NULL);
848  assert(monomialvars != NULL);
849  assert(monomialexps != NULL);
850  assert(monomialnvars != NULL);
851  assert(monomialcoefs != NULL);
852  assert(nmonomials != NULL);
853  assert(endptr != NULL);
854  assert(success != NULL);
855 
856  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsPolynomial", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
857 
858  *success = FALSE;
859  *nmonomials = 0;
860  monomialssize = 0;
861  *monomialvars = NULL;
862  *monomialexps = NULL;
863  *monomialcoefs = NULL;
864  *monomialnvars = NULL;
865 
866  /* initialize state machine */
867  state = SCIPPARSEPOLYNOMIAL_STATE_BEGIN;
868  varssize = 0;
869  nvars = 0;
870  vars = NULL;
871  exponents = NULL;
872  coef = SCIP_INVALID;
873 
874  SCIPdebugMsg(scip, "parsing polynomial from '%s'\n", str);
875 
876  while( *str && state != SCIPPARSEPOLYNOMIAL_STATE_END && state != SCIPPARSEPOLYNOMIAL_STATE_ERROR )
877  {
878  /* skip white space */
879  SCIP_CALL( SCIPskipSpace((char**)&str) );
880 
881  assert(state != SCIPPARSEPOLYNOMIAL_STATE_END);
882 
883  switch( state )
884  {
885  case SCIPPARSEPOLYNOMIAL_STATE_BEGIN:
886  {
887  if( coef != SCIP_INVALID ) /*lint !e777*/
888  {
889  SCIPdebugMsg(scip, "push monomial with coefficient <%g> and <%d> vars\n", coef, nvars);
890 
891  /* push previous monomial */
892  if( monomialssize <= *nmonomials )
893  {
894  monomialssize = SCIPcalcMemGrowSize(scip, *nmonomials+1);
895 
896  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, *nmonomials, monomialssize) );
897  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, *nmonomials, monomialssize) );
898  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, *nmonomials, monomialssize) );
899  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, *nmonomials, monomialssize) );
900  }
901 
902  if( nvars > 0 )
903  {
904  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*monomialvars)[*nmonomials], vars, nvars) ); /*lint !e866*/
905  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*monomialexps)[*nmonomials], exponents, nvars) ); /*lint !e866*/
906  }
907  else
908  {
909  (*monomialvars)[*nmonomials] = NULL;
910  (*monomialexps)[*nmonomials] = NULL;
911  }
912  (*monomialcoefs)[*nmonomials] = coef;
913  (*monomialnvars)[*nmonomials] = nvars;
914  ++*nmonomials;
915 
916  nvars = 0;
917  coef = SCIP_INVALID;
918  }
919 
920  if( *str == '<' )
921  {
922  /* there seem to come a variable at the beginning of a monomial
923  * so assume the coefficient is 1.0
924  */
925  state = SCIPPARSEPOLYNOMIAL_STATE_VARS;
926  coef = 1.0;
927  }
928  else if( *str == '-' || *str == '+' || isdigit(*str) )
929  state = SCIPPARSEPOLYNOMIAL_STATE_COEF;
930  else
931  state = SCIPPARSEPOLYNOMIAL_STATE_END;
932 
933  break;
934  }
935 
936  case SCIPPARSEPOLYNOMIAL_STATE_INTERMED:
937  {
938  if( *str == '<' )
939  {
940  /* there seem to come another variable */
941  state = SCIPPARSEPOLYNOMIAL_STATE_VARS;
942  }
943  else if( *str == '-' || *str == '+' || isdigit(*str) )
944  {
945  /* there seem to come a coefficient, which means the next monomial */
946  state = SCIPPARSEPOLYNOMIAL_STATE_BEGIN;
947  }
948  else /* since we cannot detect the symbols we stop parsing the polynomial */
949  state = SCIPPARSEPOLYNOMIAL_STATE_END;
950 
951  break;
952  }
953 
954  case SCIPPARSEPOLYNOMIAL_STATE_COEF:
955  {
956  if( *str == '+' && !isdigit(str[1]) )
957  {
958  /* only a plus sign, without number */
959  coef = 1.0;
960  ++str;
961  }
962  else if( *str == '-' && !isdigit(str[1]) )
963  {
964  /* only a minus sign, without number */
965  coef = -1.0;
966  ++str;
967  }
968  else if( SCIPstrToRealValue(str, &coef, endptr) )
969  {
970  str = *endptr;
971  }
972  else
973  {
974  SCIPerrorMessage("could not parse number in the beginning of '%s'\n", str);
975  state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
976  break;
977  }
978 
979  /* after the coefficient we go into the intermediate state, i.e., expecting next variables */
980  state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED; /*lint !e838*/
981 
982  break;
983  }
984 
985  case SCIPPARSEPOLYNOMIAL_STATE_VARS:
986  {
987  SCIP_VAR* var;
988 
989  assert(*str == '<');
990 
991  /* parse variable name */
992  SCIP_CALL( SCIPparseVarName(scip, str, &var, endptr) );
993 
994  /* check if variable name was parsed */
995  if( *endptr == str )
996  {
997  state = SCIPPARSEPOLYNOMIAL_STATE_END;
998  break;
999  }
1000 
1001  if( var == NULL )
1002  {
1003  SCIPerrorMessage("did not find variable in the beginning of %s\n", str);
1004  state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
1005  break;
1006  }
1007 
1008  /* add variable to vars array */
1009  if( nvars + 1 > varssize )
1010  {
1011  varssize = SCIPcalcMemGrowSize(scip, nvars+1);
1012  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &vars, nvars, varssize) );
1013  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &exponents, nvars, varssize) );
1014  }
1015  assert(vars != NULL);
1016  assert(exponents != NULL);
1017 
1018  vars[nvars] = var;
1019  exponents[nvars] = 1.0;
1020  ++nvars;
1021 
1022  str = *endptr;
1023 
1024  if( *str == '^' )
1025  state = SCIPPARSEPOLYNOMIAL_STATE_EXPONENT;
1026  else
1027  state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED;
1028 
1029  break;
1030  }
1031 
1032  case SCIPPARSEPOLYNOMIAL_STATE_EXPONENT:
1033  {
1034  assert(*str == '^');
1035  assert(nvars > 0); /* we should be in a monomial that has already a variable */
1036  assert(exponents != NULL);
1037  ++str;
1038 
1039  if( !SCIPstrToRealValue(str, &exponents[nvars-1], endptr) )
1040  {
1041  SCIPerrorMessage("could not parse number in the beginning of '%s'\n", str);
1042  state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
1043  break;
1044  }
1045  str = *endptr;
1046 
1047  /* after the exponent we go into the intermediate state, i.e., expecting next variables */
1048  state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED; /*lint !e838*/
1049  break;
1050  }
1051 
1052  case SCIPPARSEPOLYNOMIAL_STATE_END:
1053  case SCIPPARSEPOLYNOMIAL_STATE_ERROR:
1054  default:
1055  SCIPerrorMessage("unexpected state\n");
1056  return SCIP_READERROR;
1057  }
1058  }
1059 
1060  /* set end pointer */
1061  *endptr = (char*)str;
1062 
1063  /* check state at end of string */
1064  switch( state )
1065  {
1066  case SCIPPARSEPOLYNOMIAL_STATE_BEGIN:
1067  case SCIPPARSEPOLYNOMIAL_STATE_END:
1068  case SCIPPARSEPOLYNOMIAL_STATE_INTERMED:
1069  {
1070  if( coef != SCIP_INVALID ) /*lint !e777*/
1071  {
1072  /* push last monomial */
1073  SCIPdebugMsg(scip, "push monomial with coefficient <%g> and <%d> vars\n", coef, nvars);
1074  if( monomialssize <= *nmonomials )
1075  {
1076  monomialssize = *nmonomials+1;
1077  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, *nmonomials, monomialssize) );
1078  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, *nmonomials, monomialssize) );
1079  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, *nmonomials, monomialssize) );
1080  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, *nmonomials, monomialssize) );
1081  }
1082 
1083  if( nvars > 0 )
1084  {
1085  /* shrink vars and exponents array to needed size and take over ownership */
1086  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &vars, varssize, nvars) );
1087  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &exponents, varssize, nvars) );
1088  (*monomialvars)[*nmonomials] = vars;
1089  (*monomialexps)[*nmonomials] = exponents;
1090  vars = NULL;
1091  exponents = NULL;
1092  }
1093  else
1094  {
1095  (*monomialvars)[*nmonomials] = NULL;
1096  (*monomialexps)[*nmonomials] = NULL;
1097  }
1098  (*monomialcoefs)[*nmonomials] = coef;
1099  (*monomialnvars)[*nmonomials] = nvars;
1100  ++*nmonomials;
1101  }
1102 
1103  *success = TRUE;
1104  break;
1105  }
1106 
1107  case SCIPPARSEPOLYNOMIAL_STATE_COEF:
1108  case SCIPPARSEPOLYNOMIAL_STATE_VARS:
1109  case SCIPPARSEPOLYNOMIAL_STATE_EXPONENT:
1110  {
1111  SCIPerrorMessage("unexpected parsing state at end of polynomial string\n");
1112  }
1113  /*lint -fallthrough*/
1114  case SCIPPARSEPOLYNOMIAL_STATE_ERROR:
1115  assert(!*success);
1116  break;
1117  }
1118 
1119  /* free memory to store current monomial, if still existing */
1120  SCIPfreeBlockMemoryArrayNull(scip, &vars, varssize);
1121  SCIPfreeBlockMemoryArrayNull(scip, &exponents, varssize);
1122 
1123  if( *success && *nmonomials > 0 )
1124  {
1125  /* shrink arrays to required size, so we do not need to keep monomialssize around */
1126  assert(*nmonomials <= monomialssize);
1127  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, monomialssize, *nmonomials) );
1128  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, monomialssize, *nmonomials) );
1129  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, monomialssize, *nmonomials) );
1130  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, monomialssize, *nmonomials) );
1131 
1132  /* SCIPwriteVarsPolynomial(scip, NULL, *monomialvars, *monomialexps, *monomialcoefs, *monomialnvars, *nmonomials, FALSE); */
1133  }
1134  else
1135  {
1136  /* in case of error, cleanup all data here */
1137  SCIPfreeParseVarsPolynomialData(scip, monomialvars, monomialexps, monomialcoefs, monomialnvars, *nmonomials);
1138  *nmonomials = 0;
1139  }
1140 
1141  return SCIP_OKAY;
1142 }
1143 
1144 /** frees memory allocated when parsing a signomial from a string
1145  *
1146  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1147  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1148  *
1149  * @pre This method can be called if @p scip is in one of the following stages:
1150  * - \ref SCIP_STAGE_PROBLEM
1151  * - \ref SCIP_STAGE_TRANSFORMING
1152  * - \ref SCIP_STAGE_INITPRESOLVE
1153  * - \ref SCIP_STAGE_PRESOLVING
1154  * - \ref SCIP_STAGE_EXITPRESOLVE
1155  * - \ref SCIP_STAGE_PRESOLVED
1156  * - \ref SCIP_STAGE_SOLVING
1157  */
1159  SCIP* scip, /**< SCIP data structure */
1160  SCIP_VAR**** monomialvars, /**< pointer to store arrays with variables for each monomial */
1161  SCIP_Real*** monomialexps, /**< pointer to store arrays with variable exponents */
1162  SCIP_Real** monomialcoefs, /**< pointer to store array with monomial coefficients */
1163  int** monomialnvars, /**< pointer to store array with number of variables for each monomial */
1164  int nmonomials /**< pointer to store number of parsed monomials */
1165  )
1166 {
1167  int i;
1168 
1169  assert(scip != NULL);
1170  assert(monomialvars != NULL);
1171  assert(monomialexps != NULL);
1172  assert(monomialcoefs != NULL);
1173  assert(monomialnvars != NULL);
1174  assert((*monomialvars != NULL) == (nmonomials > 0));
1175  assert((*monomialexps != NULL) == (nmonomials > 0));
1176  assert((*monomialcoefs != NULL) == (nmonomials > 0));
1177  assert((*monomialnvars != NULL) == (nmonomials > 0));
1178 
1179  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPfreeParseVarsPolynomialData", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1180 
1181  if( nmonomials == 0 )
1182  return;
1183 
1184  for( i = nmonomials - 1; i >= 0; --i )
1185  {
1186  SCIPfreeBlockMemoryArrayNull(scip, &(*monomialexps)[i], (*monomialnvars)[i]);
1187  SCIPfreeBlockMemoryArrayNull(scip, &(*monomialvars)[i], (*monomialnvars)[i]);
1188  }
1189 
1190  SCIPfreeBlockMemoryArray(scip, monomialcoefs, nmonomials);
1191  SCIPfreeBlockMemoryArray(scip, monomialnvars, nmonomials);
1192  SCIPfreeBlockMemoryArray(scip, monomialexps, nmonomials);
1193  SCIPfreeBlockMemoryArray(scip, monomialvars, nmonomials);
1194 }
1195 
1196 /** increases usage counter of variable
1197  *
1198  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1199  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1200  *
1201  * @pre This method can be called if @p scip is in one of the following stages:
1202  * - \ref SCIP_STAGE_PROBLEM
1203  * - \ref SCIP_STAGE_TRANSFORMING
1204  * - \ref SCIP_STAGE_TRANSFORMED
1205  * - \ref SCIP_STAGE_INITPRESOLVE
1206  * - \ref SCIP_STAGE_PRESOLVING
1207  * - \ref SCIP_STAGE_EXITPRESOLVE
1208  * - \ref SCIP_STAGE_PRESOLVED
1209  * - \ref SCIP_STAGE_INITSOLVE
1210  * - \ref SCIP_STAGE_SOLVING
1211  * - \ref SCIP_STAGE_SOLVED
1212  * - \ref SCIP_STAGE_EXITSOLVE
1213  */
1215  SCIP* scip, /**< SCIP data structure */
1216  SCIP_VAR* var /**< variable to capture */
1217  )
1218 {
1219  SCIP_CALL( SCIPcheckStage(scip, "SCIPcaptureVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1220  assert(var->scip == scip);
1221 
1222  SCIPvarCapture(var);
1223 
1224  return SCIP_OKAY;
1225 }
1226 
1227 /** decreases usage counter of variable, if the usage pointer reaches zero the variable gets freed
1228  *
1229  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1230  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1231  *
1232  * @pre This method can be called if @p scip is in one of the following stages:
1233  * - \ref SCIP_STAGE_PROBLEM
1234  * - \ref SCIP_STAGE_TRANSFORMING
1235  * - \ref SCIP_STAGE_TRANSFORMED
1236  * - \ref SCIP_STAGE_INITPRESOLVE
1237  * - \ref SCIP_STAGE_PRESOLVING
1238  * - \ref SCIP_STAGE_EXITPRESOLVE
1239  * - \ref SCIP_STAGE_PRESOLVED
1240  * - \ref SCIP_STAGE_INITSOLVE
1241  * - \ref SCIP_STAGE_SOLVING
1242  * - \ref SCIP_STAGE_SOLVED
1243  * - \ref SCIP_STAGE_EXITSOLVE
1244  * - \ref SCIP_STAGE_FREETRANS
1245  *
1246  * @note the pointer of the variable will be NULLed
1247  */
1249  SCIP* scip, /**< SCIP data structure */
1250  SCIP_VAR** var /**< pointer to variable */
1251  )
1252 {
1253  assert(var != NULL);
1254  assert(*var != NULL);
1255  assert((*var)->scip == scip);
1256 
1257  SCIP_CALL( SCIPcheckStage(scip, "SCIPreleaseVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1258 
1259  switch( scip->set->stage )
1260  {
1261  case SCIP_STAGE_PROBLEM:
1262  SCIP_CALL( SCIPvarRelease(var, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp) );
1263  return SCIP_OKAY;
1264 
1268  case SCIP_STAGE_PRESOLVING:
1270  case SCIP_STAGE_PRESOLVED:
1271  case SCIP_STAGE_INITSOLVE:
1272  case SCIP_STAGE_SOLVING:
1273  case SCIP_STAGE_SOLVED:
1274  case SCIP_STAGE_EXITSOLVE:
1275  case SCIP_STAGE_FREETRANS:
1276  if( !SCIPvarIsTransformed(*var) && (*var)->nuses == 1 && (*var)->data.original.transvar != NULL )
1277  {
1278  SCIPerrorMessage("cannot release last use of original variable while associated transformed variable exists\n");
1279  return SCIP_INVALIDCALL;
1280  }
1281  SCIP_CALL( SCIPvarRelease(var, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp) );
1282  return SCIP_OKAY;
1283 
1284  default:
1285  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
1286  return SCIP_INVALIDCALL;
1287  } /*lint !e788*/
1288 }
1289 
1290 /** changes the name of a variable
1291  *
1292  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1293  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1294  *
1295  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PROBLEM
1296  *
1297  * @note to get the current name of a variable, use SCIPvarGetName() from pub_var.h
1298  */
1300  SCIP* scip, /**< SCIP data structure */
1301  SCIP_VAR* var, /**< variable */
1302  const char* name /**< new name of constraint */
1303  )
1304 {
1305  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarName", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
1306  assert( var->scip == scip );
1307 
1308  if( SCIPgetStage(scip) != SCIP_STAGE_PROBLEM )
1309  {
1310  SCIPerrorMessage("variable names can only be changed in problem creation stage\n");
1311  SCIPABORT();
1312  return SCIP_INVALIDCALL; /*lint !e527*/
1313  }
1314 
1315  /* remove variable's name from the namespace if the variable was already added */
1316  if( SCIPvarGetProbindex(var) != -1 )
1317  {
1318  SCIP_CALL( SCIPprobRemoveVarName(scip->origprob, var) );
1319  }
1320 
1321  /* change variable name */
1322  SCIP_CALL( SCIPvarChgName(var, SCIPblkmem(scip), name) );
1323 
1324  /* add variable's name to the namespace if the variable was already added */
1325  if( SCIPvarGetProbindex(var) != -1 )
1326  {
1327  SCIP_CALL( SCIPprobAddVarName(scip->origprob, var) );
1328  }
1329 
1330  return SCIP_OKAY;
1331 }
1332 
1333 /** gets and captures transformed variable of a given variable; if the variable is not yet transformed,
1334  * a new transformed variable for this variable is created
1335  *
1336  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1337  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1338  *
1339  * @pre This method can be called if @p scip is in one of the following stages:
1340  * - \ref SCIP_STAGE_TRANSFORMING
1341  * - \ref SCIP_STAGE_TRANSFORMED
1342  * - \ref SCIP_STAGE_INITPRESOLVE
1343  * - \ref SCIP_STAGE_PRESOLVING
1344  * - \ref SCIP_STAGE_EXITPRESOLVE
1345  * - \ref SCIP_STAGE_PRESOLVED
1346  * - \ref SCIP_STAGE_INITSOLVE
1347  * - \ref SCIP_STAGE_SOLVING
1348  */
1350  SCIP* scip, /**< SCIP data structure */
1351  SCIP_VAR* var, /**< variable to get/create transformed variable for */
1352  SCIP_VAR** transvar /**< pointer to store the transformed variable */
1353  )
1354 {
1355  assert(transvar != NULL);
1356 
1357  SCIP_CALL( SCIPcheckStage(scip, "SCIPtransformVar", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1358 
1359  if( SCIPvarIsTransformed(var) )
1360  {
1361  *transvar = var;
1362  SCIPvarCapture(*transvar);
1363  }
1364  else
1365  {
1366  SCIP_CALL( SCIPvarTransform(var, scip->mem->probmem, scip->set, scip->stat, scip->origprob->objsense, transvar) );
1367  }
1368 
1369  return SCIP_OKAY;
1370 }
1371 
1372 /** gets and captures transformed variables for an array of variables;
1373  * if a variable of the array is not yet transformed, a new transformed variable for this variable is created;
1374  * it is possible to call this method with vars == transvars
1375  *
1376  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1377  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1378  *
1379  * @pre This method can be called if @p scip is in one of the following stages:
1380  * - \ref SCIP_STAGE_TRANSFORMING
1381  * - \ref SCIP_STAGE_TRANSFORMED
1382  * - \ref SCIP_STAGE_INITPRESOLVE
1383  * - \ref SCIP_STAGE_PRESOLVING
1384  * - \ref SCIP_STAGE_EXITPRESOLVE
1385  * - \ref SCIP_STAGE_PRESOLVED
1386  * - \ref SCIP_STAGE_INITSOLVE
1387  * - \ref SCIP_STAGE_SOLVING
1388  */
1390  SCIP* scip, /**< SCIP data structure */
1391  int nvars, /**< number of variables to get/create transformed variables for */
1392  SCIP_VAR** vars, /**< array with variables to get/create transformed variables for */
1393  SCIP_VAR** transvars /**< array to store the transformed variables */
1394  )
1395 {
1396  int v;
1397 
1398  assert(nvars == 0 || vars != NULL);
1399  assert(nvars == 0 || transvars != NULL);
1400 
1401  SCIP_CALL( SCIPcheckStage(scip, "SCIPtransformVars", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1402 
1403  for( v = 0; v < nvars; ++v )
1404  {
1405  if( SCIPvarIsTransformed(vars[v]) )
1406  {
1407  transvars[v] = vars[v];
1408  SCIPvarCapture(transvars[v]);
1409  }
1410  else
1411  {
1412  SCIP_CALL( SCIPvarTransform(vars[v], scip->mem->probmem, scip->set, scip->stat, scip->origprob->objsense,
1413  &transvars[v]) );
1414  }
1415  }
1416 
1417  return SCIP_OKAY;
1418 }
1419 
1420 /** gets corresponding transformed variable of a given variable;
1421  * returns NULL as transvar, if transformed variable is not yet existing
1422  *
1423  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1424  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1425  *
1426  * @pre This method can be called if @p scip is in one of the following stages:
1427  * - \ref SCIP_STAGE_TRANSFORMING
1428  * - \ref SCIP_STAGE_TRANSFORMED
1429  * - \ref SCIP_STAGE_INITPRESOLVE
1430  * - \ref SCIP_STAGE_PRESOLVING
1431  * - \ref SCIP_STAGE_EXITPRESOLVE
1432  * - \ref SCIP_STAGE_PRESOLVED
1433  * - \ref SCIP_STAGE_INITSOLVE
1434  * - \ref SCIP_STAGE_SOLVING
1435  * - \ref SCIP_STAGE_SOLVED
1436  * - \ref SCIP_STAGE_EXITSOLVE
1437  * - \ref SCIP_STAGE_FREETRANS
1438  */
1440  SCIP* scip, /**< SCIP data structure */
1441  SCIP_VAR* var, /**< variable to get transformed variable for */
1442  SCIP_VAR** transvar /**< pointer to store the transformed variable */
1443  )
1444 {
1445  assert(transvar != NULL);
1446 
1447  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetTransformedVar", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1448 
1449  if( SCIPvarIsTransformed(var) )
1450  *transvar = var;
1451  else
1452  {
1453  SCIP_CALL( SCIPvarGetTransformed(var, scip->mem->probmem, scip->set, scip->stat, transvar) );
1454  }
1455 
1456  return SCIP_OKAY;
1457 }
1458 
1459 /** gets corresponding transformed variables for an array of variables;
1460  * stores NULL in a transvars slot, if the transformed variable is not yet existing;
1461  * it is possible to call this method with vars == transvars, but remember that variables that are not
1462  * yet transformed will be replaced with NULL
1463  *
1464  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1465  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1466  *
1467  * @pre This method can be called if @p scip is in one of the following stages:
1468  * - \ref SCIP_STAGE_TRANSFORMING
1469  * - \ref SCIP_STAGE_TRANSFORMED
1470  * - \ref SCIP_STAGE_INITPRESOLVE
1471  * - \ref SCIP_STAGE_PRESOLVING
1472  * - \ref SCIP_STAGE_EXITPRESOLVE
1473  * - \ref SCIP_STAGE_PRESOLVED
1474  * - \ref SCIP_STAGE_INITSOLVE
1475  * - \ref SCIP_STAGE_SOLVING
1476  * - \ref SCIP_STAGE_SOLVED
1477  * - \ref SCIP_STAGE_EXITSOLVE
1478  * - \ref SCIP_STAGE_FREETRANS
1479  */
1481  SCIP* scip, /**< SCIP data structure */
1482  int nvars, /**< number of variables to get transformed variables for */
1483  SCIP_VAR** vars, /**< array with variables to get transformed variables for */
1484  SCIP_VAR** transvars /**< array to store the transformed variables */
1485  )
1486 {
1487  int v;
1488 
1489  assert(nvars == 0 || vars != NULL);
1490  assert(nvars == 0 || transvars != NULL);
1491 
1492  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetTransformedVars", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1493 
1494  for( v = 0; v < nvars; ++v )
1495  {
1496  if( SCIPvarIsTransformed(vars[v]) )
1497  transvars[v] = vars[v];
1498  else
1499  {
1500  SCIP_CALL( SCIPvarGetTransformed(vars[v], scip->mem->probmem, scip->set, scip->stat, &transvars[v]) );
1501  }
1502  }
1503 
1504  return SCIP_OKAY;
1505 }
1506 
1507 /** gets negated variable x' = lb + ub - x of variable x; negated variable is created, if not yet existing;
1508  * in difference to \ref SCIPcreateVar, the negated variable must not be released (unless captured explicitly)
1509  *
1510  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1511  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1512  *
1513  * @pre This method can be called if @p scip is in one of the following stages:
1514  * - \ref SCIP_STAGE_PROBLEM
1515  * - \ref SCIP_STAGE_TRANSFORMING
1516  * - \ref SCIP_STAGE_TRANSFORMED
1517  * - \ref SCIP_STAGE_INITPRESOLVE
1518  * - \ref SCIP_STAGE_PRESOLVING
1519  * - \ref SCIP_STAGE_EXITPRESOLVE
1520  * - \ref SCIP_STAGE_PRESOLVED
1521  * - \ref SCIP_STAGE_INITSOLVE
1522  * - \ref SCIP_STAGE_SOLVING
1523  * - \ref SCIP_STAGE_SOLVED
1524  * - \ref SCIP_STAGE_EXITSOLVE
1525  * - \ref SCIP_STAGE_FREETRANS
1526  */
1528  SCIP* scip, /**< SCIP data structure */
1529  SCIP_VAR* var, /**< variable to get negated variable for */
1530  SCIP_VAR** negvar /**< pointer to store the negated variable */
1531  )
1532 {
1533  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNegatedVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1534  assert( var->scip == scip );
1535 
1536  SCIP_CALL( SCIPvarNegate(var, scip->mem->probmem, scip->set, scip->stat, negvar) );
1537 
1538  return SCIP_OKAY;
1539 }
1540 
1541 /** gets negated variables x' = lb + ub - x of variables x; negated variables are created, if not yet existing
1542  *
1543  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1544  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1545  *
1546  * @pre This method can be called if @p scip is in one of the following stages:
1547  * - \ref SCIP_STAGE_PROBLEM
1548  * - \ref SCIP_STAGE_TRANSFORMING
1549  * - \ref SCIP_STAGE_TRANSFORMED
1550  * - \ref SCIP_STAGE_INITPRESOLVE
1551  * - \ref SCIP_STAGE_PRESOLVING
1552  * - \ref SCIP_STAGE_EXITPRESOLVE
1553  * - \ref SCIP_STAGE_PRESOLVED
1554  * - \ref SCIP_STAGE_INITSOLVE
1555  * - \ref SCIP_STAGE_SOLVING
1556  * - \ref SCIP_STAGE_SOLVED
1557  * - \ref SCIP_STAGE_EXITSOLVE
1558  * - \ref SCIP_STAGE_FREETRANS
1559  */
1561  SCIP* scip, /**< SCIP data structure */
1562  int nvars, /**< number of variables to get negated variables for */
1563  SCIP_VAR** vars, /**< array of variables to get negated variables for */
1564  SCIP_VAR** negvars /**< array to store the negated variables */
1565  )
1566 {
1567  int v;
1568 
1569  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNegatedVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1570 
1571  for( v = 0; v < nvars; ++v )
1572  {
1573  SCIP_CALL( SCIPvarNegate(vars[v], scip->mem->probmem, scip->set, scip->stat, &(negvars[v])) );
1574  }
1575 
1576  return SCIP_OKAY;
1577 }
1578 
1579 /** gets a binary variable that is equal to the given binary variable, and that is either active, fixed, or
1580  * multi-aggregated, or the negated variable of an active, fixed, or multi-aggregated variable
1581  *
1582  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1583  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1584  *
1585  * @pre This method can be called if @p scip is in one of the following stages:
1586  * - \ref SCIP_STAGE_PROBLEM
1587  * - \ref SCIP_STAGE_TRANSFORMED
1588  * - \ref SCIP_STAGE_INITPRESOLVE
1589  * - \ref SCIP_STAGE_PRESOLVING
1590  * - \ref SCIP_STAGE_EXITPRESOLVE
1591  * - \ref SCIP_STAGE_PRESOLVED
1592  * - \ref SCIP_STAGE_INITSOLVE
1593  * - \ref SCIP_STAGE_SOLVING
1594  * - \ref SCIP_STAGE_SOLVED
1595  * - \ref SCIP_STAGE_EXITSOLVE
1596  */
1598  SCIP* scip, /**< SCIP data structure */
1599  SCIP_VAR* var, /**< binary variable to get binary representative for */
1600  SCIP_VAR** repvar, /**< pointer to store the binary representative */
1601  SCIP_Bool* negated /**< pointer to store whether the negation of an active variable was returned */
1602  )
1603 {
1604  assert(scip != NULL);
1605  assert(var != NULL);
1606  assert(repvar != NULL);
1607  assert(negated != NULL);
1608  assert(var->scip == scip);
1609 
1610  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetBinvarRepresentative", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1611 
1612  /* get the active representative of the given variable */
1613  *repvar = var;
1614  *negated = FALSE;
1615  SCIP_CALL( SCIPvarGetProbvarBinary(repvar, negated) );
1616 
1617  /* negate the representative, if it corresponds to the negation of the given variable */
1618  if( *negated )
1619  {
1620  SCIP_CALL( SCIPgetNegatedVar(scip, *repvar, repvar) );
1621  }
1622 
1623  return SCIP_OKAY;
1624 }
1625 
1626 /** gets binary variables that are equal to the given binary variables, and which are either active, fixed, or
1627  * multi-aggregated, or the negated variables of active, fixed, or multi-aggregated variables
1628  *
1629  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1630  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1631  *
1632  * @pre This method can be called if @p scip is in one of the following stages:
1633  * - \ref SCIP_STAGE_PROBLEM
1634  * - \ref SCIP_STAGE_TRANSFORMED
1635  * - \ref SCIP_STAGE_INITPRESOLVE
1636  * - \ref SCIP_STAGE_PRESOLVING
1637  * - \ref SCIP_STAGE_EXITPRESOLVE
1638  * - \ref SCIP_STAGE_PRESOLVED
1639  * - \ref SCIP_STAGE_INITSOLVE
1640  * - \ref SCIP_STAGE_SOLVING
1641  * - \ref SCIP_STAGE_SOLVED
1642  * - \ref SCIP_STAGE_EXITSOLVE
1643  */
1645  SCIP* scip, /**< SCIP data structure */
1646  int nvars, /**< number of binary variables to get representatives for */
1647  SCIP_VAR** vars, /**< binary variables to get binary representatives for */
1648  SCIP_VAR** repvars, /**< array to store the binary representatives */
1649  SCIP_Bool* negated /**< array to store whether the negation of an active variable was returned */
1650  )
1651 {
1652  int v;
1653 
1654  assert(scip != NULL);
1655  assert(vars != NULL || nvars == 0);
1656  assert(repvars != NULL || nvars == 0);
1657  assert(negated != NULL || nvars == 0);
1658 
1659  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetBinvarRepresentatives", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1660 
1661  if( nvars == 0 )
1662  return SCIP_OKAY;
1663 
1664  /* get the active representative of the given variable */
1665  BMScopyMemoryArray(repvars, vars, nvars);
1666  BMSclearMemoryArray(negated, nvars);
1667  SCIP_CALL( SCIPvarsGetProbvarBinary(&repvars, &negated, nvars) );
1668 
1669  /* negate the representatives, if they correspond to the negation of the given variables */
1670  for( v = nvars - 1; v >= 0; --v )
1671  if( negated[v] )
1672  {
1673  SCIP_CALL( SCIPgetNegatedVar(scip, repvars[v], &(repvars[v])) );
1674  }
1675 
1676  return SCIP_OKAY;
1677 }
1678 
1679 /** flattens aggregation graph of multi-aggregated variable in order to avoid exponential recursion later on
1680  *
1681  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1682  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1683  *
1684  * @pre This method can be called if @p scip is in one of the following stages:
1685  * - \ref SCIP_STAGE_INITPRESOLVE
1686  * - \ref SCIP_STAGE_PRESOLVING
1687  * - \ref SCIP_STAGE_EXITPRESOLVE
1688  * - \ref SCIP_STAGE_PRESOLVED
1689  * - \ref SCIP_STAGE_INITSOLVE
1690  * - \ref SCIP_STAGE_SOLVING
1691  * - \ref SCIP_STAGE_SOLVED
1692  */
1694  SCIP* scip, /**< SCIP data structure */
1695  SCIP_VAR* var /**< problem variable */
1696  )
1697 {
1698  assert( scip != NULL );
1699  assert( var != NULL );
1700  SCIP_CALL( SCIPcheckStage(scip, "SCIPflattenVarAggregationGraph", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
1701 
1702  SCIP_CALL( SCIPvarFlattenAggregationGraph(var, scip->mem->probmem, scip->set, scip->eventqueue) );
1703 
1704  return SCIP_OKAY;
1705 }
1706 
1707 /** Transforms a given linear sum of variables, that is a_1*x_1 + ... + a_n*x_n + c into a corresponding linear sum of
1708  * active variables, that is b_1*y_1 + ... + b_m*y_m + d.
1709  *
1710  * If the number of needed active variables is greater than the available slots in the variable array, nothing happens
1711  * except that the required size is stored in the corresponding variable (requiredsize). Otherwise, the active variable
1712  * representation is stored in the variable array, scalar array and constant.
1713  *
1714  * The reason for this approach is that we cannot reallocate memory, since we do not know how the memory has been
1715  * allocated (e.g., by a C++ 'new' or SCIP functions).
1716  *
1717  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1718  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1719  *
1720  * @pre This method can be called if @p scip is in one of the following stages:
1721  * - \ref SCIP_STAGE_TRANSFORMED
1722  * - \ref SCIP_STAGE_INITPRESOLVE
1723  * - \ref SCIP_STAGE_PRESOLVING
1724  * - \ref SCIP_STAGE_EXITPRESOLVE
1725  * - \ref SCIP_STAGE_PRESOLVED
1726  * - \ref SCIP_STAGE_INITSOLVE
1727  * - \ref SCIP_STAGE_SOLVING
1728  * - \ref SCIP_STAGE_SOLVED
1729  * - \ref SCIP_STAGE_EXITSOLVE
1730  * - \ref SCIP_STAGE_FREETRANS
1731  *
1732  * @note The resulting linear sum is stored into the given variable array, scalar array, and constant. That means the
1733  * given entries are overwritten.
1734  *
1735  * @note That method can be used to convert a single variables into variable space of active variables. Therefore call
1736  * the method with the linear sum 1.0*x + 0.0.
1737  */
1739  SCIP* scip, /**< SCIP data structure */
1740  SCIP_VAR** vars, /**< variable array x_1, ..., x_n in the linear sum which will be
1741  * overwritten by the variable array y_1, ..., y_m in the linear sum
1742  * w.r.t. active variables */
1743  SCIP_Real* scalars, /**< scalars a_1, ..., a_n in linear sum which will be overwritten to the
1744  * scalars b_1, ..., b_m in the linear sum of the active variables */
1745  int* nvars, /**< pointer to number of variables in the linear sum which will be
1746  * overwritten by the number of variables in the linear sum corresponding
1747  * to the active variables */
1748  int varssize, /**< available slots in vars and scalars array which is needed to check if
1749  * the array are large enough for the linear sum w.r.t. active
1750  * variables */
1751  SCIP_Real* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c which
1752  * will chnage to constant d in the linear sum b_1*y_1 + ... + b_m*y_m +
1753  * d w.r.t. the active variables */
1754  int* requiredsize, /**< pointer to store the required array size for the linear sum w.r.t. the
1755  * active variables */
1756  SCIP_Bool mergemultiples /**< should multiple occurrences of a var be replaced by a single coeff? */
1757  )
1758 {
1759  assert( scip != NULL );
1760  assert( nvars != NULL );
1761  assert( vars != NULL || *nvars == 0 );
1762  assert( scalars != NULL || *nvars == 0 );
1763  assert( constant != NULL );
1764  assert( requiredsize != NULL );
1765  assert( *nvars <= varssize );
1766 
1767  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetProbvarLinearSum", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1768  SCIP_CALL( SCIPvarGetActiveRepresentatives(scip->set, vars, scalars, nvars, varssize, constant, requiredsize, mergemultiples) );
1769 
1770  return SCIP_OKAY;
1771 }
1772 
1773 /** transforms given variable, scalar and constant to the corresponding active, fixed, or
1774  * multi-aggregated variable, scalar and constant; if the variable resolves to a fixed variable,
1775  * "scalar" will be 0.0 and the value of the sum will be stored in "constant"; a multi-aggregation
1776  * with only one active variable (this can happen due to fixings after the multi-aggregation),
1777  * is treated like an aggregation; if the multi-aggregation constant is infinite, "scalar" will be 0.0
1778  *
1779  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1780  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1781  *
1782  * @pre This method can be called if @p scip is in one of the following stages:
1783  * - \ref SCIP_STAGE_TRANSFORMED
1784  * - \ref SCIP_STAGE_INITPRESOLVE
1785  * - \ref SCIP_STAGE_PRESOLVING
1786  * - \ref SCIP_STAGE_EXITPRESOLVE
1787  * - \ref SCIP_STAGE_PRESOLVED
1788  * - \ref SCIP_STAGE_INITSOLVE
1789  * - \ref SCIP_STAGE_SOLVING
1790  * - \ref SCIP_STAGE_SOLVED
1791  * - \ref SCIP_STAGE_EXITSOLVE
1792  * - \ref SCIP_STAGE_FREETRANS
1793  */
1795  SCIP* scip, /**< SCIP data structure */
1796  SCIP_VAR** var, /**< pointer to problem variable x in sum a*x + c */
1797  SCIP_Real* scalar, /**< pointer to scalar a in sum a*x + c */
1798  SCIP_Real* constant /**< pointer to constant c in sum a*x + c */
1799  )
1800 {
1801  assert(scip != NULL);
1802  assert(var != NULL);
1803  assert(scalar != NULL);
1804  assert(constant != NULL);
1805 
1806  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetProbvarSum", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1807  SCIP_CALL( SCIPvarGetProbvarSum(var, scip->set, scalar, constant) );
1808 
1809  return SCIP_OKAY;
1810 }
1811 
1812 /** return for given variables all their active counterparts; all active variables will be pairwise different
1813  * @note It does not hold that the first output variable is the active variable for the first input variable.
1814  *
1815  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1816  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1817  *
1818  * @pre This method can be called if @p scip is in one of the following stages:
1819  * - \ref SCIP_STAGE_TRANSFORMED
1820  * - \ref SCIP_STAGE_INITPRESOLVE
1821  * - \ref SCIP_STAGE_PRESOLVING
1822  * - \ref SCIP_STAGE_EXITPRESOLVE
1823  * - \ref SCIP_STAGE_PRESOLVED
1824  * - \ref SCIP_STAGE_INITSOLVE
1825  * - \ref SCIP_STAGE_SOLVING
1826  * - \ref SCIP_STAGE_SOLVED
1827  * - \ref SCIP_STAGE_EXITSOLVE
1828  * - \ref SCIP_STAGE_FREETRANS
1829  */
1831  SCIP* scip, /**< SCIP data structure */
1832  SCIP_VAR** vars, /**< variable array with given variables and as output all active
1833  * variables, if enough slots exist
1834  */
1835  int* nvars, /**< number of given variables, and as output number of active variables,
1836  * if enough slots exist
1837  */
1838  int varssize, /**< available slots in vars array */
1839  int* requiredsize /**< pointer to store the required array size for the active variables */
1840  )
1841 {
1842  assert(scip != NULL);
1843  assert(nvars != NULL);
1844  assert(vars != NULL || *nvars == 0);
1845  assert(varssize >= *nvars);
1846  assert(requiredsize != NULL);
1847 
1848  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetActiveVars", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1849  SCIP_CALL( SCIPvarsGetActiveVars(scip->set, vars, nvars, varssize, requiredsize) );
1850 
1851  return SCIP_OKAY;
1852 }
1853 
1854 /** returns the reduced costs of the variable in the current node's LP relaxation;
1855  * the current node has to have a feasible LP.
1856  *
1857  * returns SCIP_INVALID if the variable is active but not in the current LP;
1858  * returns 0 if the variable has been aggregated out or fixed in presolving.
1859  *
1860  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1861  *
1862  * @note The return value of this method should be used carefully if the dual feasibility check was explictely disabled.
1863  */
1865  SCIP* scip, /**< SCIP data structure */
1866  SCIP_VAR* var /**< variable to get reduced costs, should be a column in current node LP */
1867  )
1868 {
1869  assert( scip != NULL );
1870  assert( var != NULL );
1871  assert( var->scip == scip );
1872 
1873  switch( SCIPvarGetStatus(var) )
1874  {
1876  if( var->data.original.transvar == NULL )
1877  return SCIP_INVALID;
1878  return SCIPgetVarRedcost(scip, var->data.original.transvar);
1879 
1880  case SCIP_VARSTATUS_COLUMN:
1881  return SCIPgetColRedcost(scip, SCIPvarGetCol(var));
1882 
1883  case SCIP_VARSTATUS_LOOSE:
1884  return SCIP_INVALID;
1885 
1886  case SCIP_VARSTATUS_FIXED:
1890  return 0.0;
1891 
1892  default:
1893  SCIPerrorMessage("unknown variable status\n");
1894  SCIPABORT();
1895  return 0.0; /*lint !e527*/
1896  }
1897 }
1898 
1899 /** returns the implied reduced costs of the variable in the current node's LP relaxation;
1900  * the current node has to have a feasible LP.
1901  *
1902  * returns SCIP_INVALID if the variable is active but not in the current LP;
1903  * returns 0 if the variable has been aggregated out or fixed in presolving.
1904  *
1905  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1906  *
1907  * @note The return value of this method should be used carefully if the dual feasibility check was explictely disabled.
1908  */
1910  SCIP* scip, /**< SCIP data structure */
1911  SCIP_VAR* var, /**< variable to get reduced costs, should be a column in current node LP */
1912  SCIP_Bool varfixing /**< FALSE if for x == 0, TRUE for x == 1 */
1913  )
1914 {
1915  assert( scip != NULL );
1916  assert( var != NULL );
1917  assert( var->scip == scip );
1918 
1919  switch( SCIPvarGetStatus(var) )
1920  {
1922  if( var->data.original.transvar == NULL )
1923  return SCIP_INVALID;
1924  return SCIPgetVarImplRedcost(scip, var->data.original.transvar, varfixing);
1925 
1926  case SCIP_VARSTATUS_COLUMN:
1927  return SCIPvarGetImplRedcost(var, scip->set, varfixing, scip->stat, scip->transprob, scip->lp);
1928 
1929  case SCIP_VARSTATUS_LOOSE:
1930  return SCIP_INVALID;
1931 
1932  case SCIP_VARSTATUS_FIXED:
1936  return 0.0;
1937 
1938  default:
1939  SCIPerrorMessage("unknown variable status\n");
1940  SCIPABORT();
1941  return 0.0; /*lint !e527*/
1942  }
1943 }
1944 
1945 
1946 /** returns the Farkas coefficient of the variable in the current node's LP relaxation;
1947  * the current node has to have an infeasible LP.
1948  *
1949  * returns SCIP_INVALID if the variable is active but not in the current LP;
1950  * returns 0 if the variable has been aggregated out or fixed in presolving.
1951  *
1952  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1953  */
1955  SCIP* scip, /**< SCIP data structure */
1956  SCIP_VAR* var /**< variable to get reduced costs, should be a column in current node LP */
1957  )
1958 {
1959  assert(scip != NULL);
1960  assert(var != NULL);
1961  assert(var->scip == scip);
1962 
1963  switch( SCIPvarGetStatus(var) )
1964  {
1966  if( var->data.original.transvar == NULL )
1967  return SCIP_INVALID;
1968  return SCIPgetVarFarkasCoef(scip,var->data.original.transvar);
1969 
1970  case SCIP_VARSTATUS_COLUMN:
1971  return SCIPgetColFarkasCoef(scip,SCIPvarGetCol(var));
1972 
1973  case SCIP_VARSTATUS_LOOSE:
1974  return SCIP_INVALID;
1975 
1976  case SCIP_VARSTATUS_FIXED:
1980  return 0.0;
1981 
1982  default:
1983  SCIPerrorMessage("unknown variable status\n");
1984  SCIPABORT();
1985  return 0.0; /*lint !e527*/
1986  }
1987 }
1988 
1989 /** returns lower bound of variable directly before or after the bound change given by the bound change index
1990  * was applied
1991  */
1993  SCIP* scip, /**< SCIP data structure */
1994  SCIP_VAR* var, /**< problem variable */
1995  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
1996  SCIP_Bool after /**< should the bound change with given index be included? */
1997  )
1998 {
1999  SCIP_VARSTATUS varstatus;
2000  SCIP_BDCHGINFO* bdchginfo;
2001  assert(var != NULL);
2002 
2003  varstatus = SCIPvarGetStatus(var);
2004 
2005  /* get bounds of attached variables */
2006  switch( varstatus )
2007  {
2009  assert(var->data.original.transvar != NULL);
2010  return SCIPgetVarLbAtIndex(scip, var->data.original.transvar, bdchgidx, after);
2011 
2012  case SCIP_VARSTATUS_COLUMN:
2013  case SCIP_VARSTATUS_LOOSE:
2014  if( bdchgidx == NULL )
2015  return SCIPvarGetLbLocal(var);
2016  else
2017  {
2018  bdchginfo = SCIPvarGetLbchgInfo(var, bdchgidx, after);
2019  if( bdchginfo != NULL )
2020  return SCIPbdchginfoGetNewbound(bdchginfo);
2021  else
2022  return var->glbdom.lb;
2023  }
2024 
2025  case SCIP_VARSTATUS_FIXED:
2026  return var->glbdom.lb;
2027 
2028  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c -> y = (x-c)/a */
2029  assert(var->data.aggregate.var != NULL);
2030  if( var->data.aggregate.scalar > 0.0 )
2031  {
2032  SCIP_Real lb;
2033 
2034  lb = SCIPgetVarLbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2035 
2036  /* a > 0 -> get lower bound of y */
2037  if( SCIPisInfinity(scip, -lb) )
2038  return -SCIPinfinity(scip);
2039  else if( SCIPisInfinity(scip, lb) )
2040  return SCIPinfinity(scip);
2041  else
2042  return var->data.aggregate.scalar * lb + var->data.aggregate.constant;
2043  }
2044  else if( var->data.aggregate.scalar < 0.0 )
2045  {
2046  SCIP_Real ub;
2047 
2048  ub = SCIPgetVarUbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2049 
2050  /* a < 0 -> get upper bound of y */
2051  if( SCIPisInfinity(scip, -ub) )
2052  return SCIPinfinity(scip);
2053  else if( SCIPisInfinity(scip, ub) )
2054  return -SCIPinfinity(scip);
2055  else
2056  return var->data.aggregate.scalar * ub + var->data.aggregate.constant;
2057  }
2058  else
2059  {
2060  SCIPerrorMessage("scalar is zero in aggregation\n");
2061  SCIPABORT();
2062  return SCIP_INVALID; /*lint !e527*/
2063  }
2064 
2066  /* handle multi-aggregated variables depending on one variable only (possibly caused by SCIPvarFlattenAggregationGraph()) */
2067  if ( var->data.multaggr.nvars == 1 )
2068  {
2069  assert(var->data.multaggr.vars != NULL);
2070  assert(var->data.multaggr.scalars != NULL);
2071  assert(var->data.multaggr.vars[0] != NULL);
2072 
2073  if( var->data.multaggr.scalars[0] > 0.0 )
2074  {
2075  SCIP_Real lb;
2076 
2077  lb = SCIPgetVarLbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2078 
2079  /* a > 0 -> get lower bound of y */
2080  if( SCIPisInfinity(scip, -lb) )
2081  return -SCIPinfinity(scip);
2082  else if( SCIPisInfinity(scip, lb) )
2083  return SCIPinfinity(scip);
2084  else
2085  return var->data.multaggr.scalars[0] * lb + var->data.multaggr.constant;
2086  }
2087  else if( var->data.multaggr.scalars[0] < 0.0 )
2088  {
2089  SCIP_Real ub;
2090 
2091  ub = SCIPgetVarUbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2092 
2093  /* a < 0 -> get upper bound of y */
2094  if( SCIPisInfinity(scip, -ub) )
2095  return SCIPinfinity(scip);
2096  else if( SCIPisInfinity(scip, ub) )
2097  return -SCIPinfinity(scip);
2098  else
2099  return var->data.multaggr.scalars[0] * ub + var->data.multaggr.constant;
2100  }
2101  else
2102  {
2103  SCIPerrorMessage("scalar is zero in multi-aggregation\n");
2104  SCIPABORT();
2105  return SCIP_INVALID; /*lint !e527*/
2106  }
2107  }
2108  SCIPerrorMessage("cannot get the bounds of a multi-aggregated variable.\n");
2109  SCIPABORT();
2110  return SCIP_INVALID; /*lint !e527*/
2111 
2112  case SCIP_VARSTATUS_NEGATED: /* x' = offset - x -> x = offset - x' */
2113  assert(var->negatedvar != NULL);
2115  assert(var->negatedvar->negatedvar == var);
2116  return var->data.negate.constant - SCIPgetVarUbAtIndex(scip, var->negatedvar, bdchgidx, after);
2117 
2118  default:
2119  SCIPerrorMessage("unknown variable status\n");
2120  SCIPABORT();
2121  return SCIP_INVALID; /*lint !e527*/
2122  }
2123 }
2124 
2125 /** returns upper bound of variable directly before or after the bound change given by the bound change index
2126  * was applied
2127  */
2129  SCIP* scip, /**< SCIP data structure */
2130  SCIP_VAR* var, /**< problem variable */
2131  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2132  SCIP_Bool after /**< should the bound change with given index be included? */
2133  )
2134 {
2135  SCIP_VARSTATUS varstatus;
2136  SCIP_BDCHGINFO* bdchginfo;
2137  assert(var != NULL);
2138 
2139  varstatus = SCIPvarGetStatus(var);
2140 
2141  /* get bounds of attached variables */
2142  switch( varstatus )
2143  {
2145  assert(var->data.original.transvar != NULL);
2146  return SCIPgetVarUbAtIndex(scip, var->data.original.transvar, bdchgidx, after);
2147 
2148  case SCIP_VARSTATUS_COLUMN:
2149  case SCIP_VARSTATUS_LOOSE:
2150  if( bdchgidx == NULL )
2151  return SCIPvarGetUbLocal(var);
2152  else
2153  {
2154  bdchginfo = SCIPvarGetUbchgInfo(var, bdchgidx, after);
2155  if( bdchginfo != NULL )
2156  return SCIPbdchginfoGetNewbound(bdchginfo);
2157  else
2158  return var->glbdom.ub;
2159  }
2160 
2161  case SCIP_VARSTATUS_FIXED:
2162  return var->glbdom.ub;
2163 
2164  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c -> y = (x-c)/a */
2165  assert(var->data.aggregate.var != NULL);
2166  if( var->data.aggregate.scalar > 0.0 )
2167  {
2168  SCIP_Real ub;
2169 
2170  ub = SCIPgetVarUbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2171 
2172  /* a > 0 -> get lower bound of y */
2173  if( SCIPisInfinity(scip, -ub) )
2174  return -SCIPinfinity(scip);
2175  else if( SCIPisInfinity(scip, ub) )
2176  return SCIPinfinity(scip);
2177  else
2178  return var->data.aggregate.scalar * ub + var->data.aggregate.constant;
2179  }
2180  else if( var->data.aggregate.scalar < 0.0 )
2181  {
2182  SCIP_Real lb;
2183 
2184  lb = SCIPgetVarLbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2185 
2186  /* a < 0 -> get upper bound of y */
2187  if ( SCIPisInfinity(scip, -lb) )
2188  return SCIPinfinity(scip);
2189  else if ( SCIPisInfinity(scip, lb) )
2190  return -SCIPinfinity(scip);
2191  else
2192  return var->data.aggregate.scalar * lb + var->data.aggregate.constant;
2193  }
2194  else
2195  {
2196  SCIPerrorMessage("scalar is zero in aggregation\n");
2197  SCIPABORT();
2198  return SCIP_INVALID; /*lint !e527*/
2199  }
2200 
2202  /* handle multi-aggregated variables depending on one variable only (possibly caused by SCIPvarFlattenAggregationGraph()) */
2203  if ( var->data.multaggr.nvars == 1 )
2204  {
2205  assert(var->data.multaggr.vars != NULL);
2206  assert(var->data.multaggr.scalars != NULL);
2207  assert(var->data.multaggr.vars[0] != NULL);
2208 
2209  if( var->data.multaggr.scalars[0] > 0.0 )
2210  {
2211  SCIP_Real ub;
2212 
2213  ub = SCIPgetVarUbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2214 
2215  /* a > 0 -> get lower bound of y */
2216  if ( SCIPisInfinity(scip, -ub) )
2217  return -SCIPinfinity(scip);
2218  else if ( SCIPisInfinity(scip, ub) )
2219  return SCIPinfinity(scip);
2220  else
2221  return var->data.multaggr.scalars[0] * ub + var->data.multaggr.constant;
2222  }
2223  else if( var->data.multaggr.scalars[0] < 0.0 )
2224  {
2225  SCIP_Real lb;
2226 
2227  lb = SCIPgetVarLbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2228 
2229  /* a < 0 -> get upper bound of y */
2230  if ( SCIPisInfinity(scip, -lb) )
2231  return SCIPinfinity(scip);
2232  else if ( SCIPisInfinity(scip, lb) )
2233  return -SCIPinfinity(scip);
2234  else
2235  return var->data.multaggr.scalars[0] * lb + var->data.multaggr.constant;
2236  }
2237  else
2238  {
2239  SCIPerrorMessage("scalar is zero in multi-aggregation\n");
2240  SCIPABORT();
2241  return SCIP_INVALID; /*lint !e527*/
2242  }
2243  }
2244  SCIPerrorMessage("cannot get the bounds of a multiple aggregated variable.\n");
2245  SCIPABORT();
2246  return SCIP_INVALID; /*lint !e527*/
2247 
2248  case SCIP_VARSTATUS_NEGATED: /* x' = offset - x -> x = offset - x' */
2249  assert(var->negatedvar != NULL);
2251  assert(var->negatedvar->negatedvar == var);
2252  return var->data.negate.constant - SCIPgetVarLbAtIndex(scip, var->negatedvar, bdchgidx, after);
2253 
2254  default:
2255  SCIPerrorMessage("unknown variable status\n");
2256  SCIPABORT();
2257  return SCIP_INVALID; /*lint !e527*/
2258  }
2259 }
2260 
2261 /** returns lower or upper bound of variable directly before or after the bound change given by the bound change index
2262  * was applied
2263  */
2265  SCIP* scip, /**< SCIP data structure */
2266  SCIP_VAR* var, /**< problem variable */
2267  SCIP_BOUNDTYPE boundtype, /**< type of bound: lower or upper bound */
2268  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2269  SCIP_Bool after /**< should the bound change with given index be included? */
2270  )
2271 {
2272  if( boundtype == SCIP_BOUNDTYPE_LOWER )
2273  return SCIPgetVarLbAtIndex(scip, var, bdchgidx, after);
2274  else
2275  {
2276  assert(boundtype == SCIP_BOUNDTYPE_UPPER);
2277  return SCIPgetVarUbAtIndex(scip, var, bdchgidx, after);
2278  }
2279 }
2280 
2281 /** returns whether the binary variable was fixed at the time given by the bound change index */
2283  SCIP* scip, /**< SCIP data structure */
2284  SCIP_VAR* var, /**< problem variable */
2285  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2286  SCIP_Bool after /**< should the bound change with given index be included? */
2287  )
2288 {
2289  assert(var != NULL);
2290  assert(SCIPvarIsBinary(var));
2291 
2292  /* check the current bounds first in order to decide at which bound change information we have to look
2293  * (which is expensive because we have to follow the aggregation tree to the active variable)
2294  */
2295  return ((SCIPvarGetLbLocal(var) > 0.5 && SCIPgetVarLbAtIndex(scip, var, bdchgidx, after) > 0.5)
2296  || (SCIPvarGetUbLocal(var) < 0.5 && SCIPgetVarUbAtIndex(scip, var, bdchgidx, after) < 0.5));
2297 }
2298 
2299 /** gets solution value for variable in current node
2300  *
2301  * @return solution value for variable in current node
2302  *
2303  * @pre This method can be called if @p scip is in one of the following stages:
2304  * - \ref SCIP_STAGE_PRESOLVED
2305  * - \ref SCIP_STAGE_SOLVING
2306  */
2308  SCIP* scip, /**< SCIP data structure */
2309  SCIP_VAR* var /**< variable to get solution value for */
2310  )
2311 {
2313  assert( var->scip == scip );
2314 
2315  return SCIPvarGetSol(var, SCIPtreeHasCurrentNodeLP(scip->tree));
2316 }
2317 
2318 /** gets solution values of multiple variables in current node
2319  *
2320  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2321  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2322  *
2323  * @pre This method can be called if @p scip is in one of the following stages:
2324  * - \ref SCIP_STAGE_PRESOLVED
2325  * - \ref SCIP_STAGE_SOLVING
2326  */
2328  SCIP* scip, /**< SCIP data structure */
2329  int nvars, /**< number of variables to get solution value for */
2330  SCIP_VAR** vars, /**< array with variables to get value for */
2331  SCIP_Real* vals /**< array to store solution values of variables */
2332  )
2333 {
2334  int v;
2335 
2336  assert(nvars == 0 || vars != NULL);
2337  assert(nvars == 0 || vals != NULL);
2338 
2339  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarSols", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2340 
2341  if( SCIPtreeHasCurrentNodeLP(scip->tree) )
2342  {
2343  for( v = 0; v < nvars; ++v )
2344  vals[v] = SCIPvarGetLPSol(vars[v]);
2345  }
2346  else
2347  {
2348  for( v = 0; v < nvars; ++v )
2349  vals[v] = SCIPvarGetPseudoSol(vars[v]);
2350  }
2351 
2352  return SCIP_OKAY;
2353 }
2354 
2355 /** sets the solution value of all variables in the global relaxation solution to zero
2356  *
2357  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2358  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2359  *
2360  * @pre This method can be called if @p scip is in one of the following stages:
2361  * - \ref SCIP_STAGE_PRESOLVED
2362  * - \ref SCIP_STAGE_SOLVING
2363  */
2365  SCIP* scip, /**< SCIP data structure */
2366  SCIP_RELAX* relax /**< relaxator data structure */
2367  )
2368 {
2369  SCIP_VAR** vars;
2370  int nvars;
2371  int v;
2372 
2373  assert(scip != NULL);
2374 
2375  SCIP_CALL( SCIPcheckStage(scip, "SCIPclearRelaxSolVals", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2376 
2377  /* update the responsible relax pointer */
2378  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2379 
2380  /* the relaxation solution is already cleared */
2381  if( SCIPrelaxationIsSolZero(scip->relaxation) )
2382  return SCIP_OKAY;
2383 
2384  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
2385 
2386  for( v = 0; v < nvars; v++ )
2387  {
2388  SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, 0.0, FALSE) );
2389  }
2390 
2391  SCIPrelaxationSetSolObj(scip->relaxation, 0.0);
2393 
2394  return SCIP_OKAY;
2395 }
2396 
2397 /** sets the value of the given variable in the global relaxation solution;
2398  * this solution can be filled by the relaxation handlers and can be used by heuristics and for separation;
2399  * You can use SCIPclearRelaxSolVals() to set all values to zero, initially;
2400  * after setting all solution values, you have to call SCIPmarkRelaxSolValid()
2401  * to inform SCIP that the stored solution is valid
2402  *
2403  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2404  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2405  *
2406  * @pre This method can be called if @p scip is in one of the following stages:
2407  * - \ref SCIP_STAGE_PRESOLVED
2408  * - \ref SCIP_STAGE_SOLVING
2409  *
2410  * @note This method incrementally updates the objective value of the relaxation solution. If the whole solution
2411  * should be updated, using SCIPsetRelaxSolVals() instead or calling SCIPclearRelaxSolVals() before setting
2412  * the first value to reset the solution and the objective value to 0 may help the numerics.
2413  */
2415  SCIP* scip, /**< SCIP data structure */
2416  SCIP_RELAX* relax, /**< relaxator data structure */
2417  SCIP_VAR* var, /**< variable to set value for */
2418  SCIP_Real val /**< solution value of variable */
2419  )
2420 {
2421  assert(scip != NULL);
2422 
2423  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolVal", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2424 
2425  SCIP_CALL( SCIPvarSetRelaxSol(var, scip->set, scip->relaxation, val, TRUE) );
2426 
2427  if( val != 0.0 )
2430  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2431 
2432  return SCIP_OKAY;
2433 }
2434 
2435 /** sets the values of the given variables in the global relaxation solution and informs SCIP about the validity
2436  * and whether the solution can be enforced via linear cuts;
2437  * this solution can be filled by the relaxation handlers and can be used by heuristics and for separation;
2438  * the solution is automatically cleared, s.t. all other variables get value 0.0
2439  *
2440  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2441  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2442  *
2443  * @pre This method can be called if @p scip is in one of the following stages:
2444  * - \ref SCIP_STAGE_PRESOLVED
2445  * - \ref SCIP_STAGE_SOLVING
2446  */
2448  SCIP* scip, /**< SCIP data structure */
2449  SCIP_RELAX* relax, /**< relaxator data structure */
2450  int nvars, /**< number of variables to set relaxation solution value for */
2451  SCIP_VAR** vars, /**< array with variables to set value for */
2452  SCIP_Real* vals, /**< array with solution values of variables */
2453  SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2454  )
2455 {
2456  int v;
2457 
2458  assert(scip != NULL);
2459  assert(nvars == 0 || vars != NULL);
2460  assert(nvars == 0 || vals != NULL);
2461 
2462  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolVals", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2463 
2464  SCIP_CALL( SCIPclearRelaxSolVals(scip, relax) );
2465 
2466  for( v = 0; v < nvars; v++ )
2467  {
2468  SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, vals[v], TRUE) );
2469  }
2470 
2472  SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2473  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2474 
2475  return SCIP_OKAY;
2476 }
2477 
2478 /** sets the values of the variables in the global relaxation solution to the values in the given primal solution
2479  * and informs SCIP about the validity and whether the solution can be enforced via linear cuts;
2480  * the relaxation solution can be filled by the relaxation handlers and might be used by heuristics and for separation
2481  *
2482  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2483  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2484  *
2485  * @pre This method can be called if @p scip is in one of the following stages:
2486  * - \ref SCIP_STAGE_PRESOLVED
2487  * - \ref SCIP_STAGE_SOLVING
2488  */
2490  SCIP* scip, /**< SCIP data structure */
2491  SCIP_RELAX* relax, /**< relaxator data structure */
2492  SCIP_SOL* sol, /**< primal relaxation solution */
2493  SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2494  )
2495 {
2496  SCIP_VAR** vars;
2497  SCIP_Real* vals;
2498  int nvars;
2499  int v;
2500 
2501  assert(scip != NULL);
2502 
2503  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolValsSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2504 
2505  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
2506 
2507  /* alloc buffer array for solution values of the variables and get the values */
2508  SCIP_CALL( SCIPallocBufferArray(scip, &vals, nvars) );
2509  SCIP_CALL( SCIPgetSolVals(scip, sol, nvars, vars, vals) );
2510 
2511  SCIP_CALL( SCIPclearRelaxSolVals(scip, relax) );
2512 
2513  for( v = 0; v < nvars; v++ )
2514  {
2515  SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, vals[v], FALSE) );
2516  }
2517 
2518  SCIPrelaxationSetSolObj(scip->relaxation, SCIPsolGetObj(sol, scip->set, scip->transprob, scip->origprob));
2519 
2521  SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2522  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2523 
2524  SCIPfreeBufferArray(scip, &vals);
2525 
2526  return SCIP_OKAY;
2527 }
2528 
2529 /** returns whether the relaxation solution is valid
2530  *
2531  * @return TRUE, if the relaxation solution is valid; FALSE, otherwise
2532  *
2533  * @pre This method can be called if @p scip is in one of the following stages:
2534  * - \ref SCIP_STAGE_PRESOLVED
2535  * - \ref SCIP_STAGE_SOLVING
2536  */
2538  SCIP* scip /**< SCIP data structure */
2539  )
2540 {
2541  assert(scip != NULL);
2542 
2543  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisRelaxSolValid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2544 
2545  return SCIPrelaxationIsSolValid(scip->relaxation);
2546 }
2547 
2548 /** informs SCIP that the relaxation solution is valid and whether the relaxation can be enforced through linear cuts
2549  *
2550  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2551  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2552  *
2553  * @pre This method can be called if @p scip is in one of the following stages:
2554  * - \ref SCIP_STAGE_PRESOLVED
2555  * - \ref SCIP_STAGE_SOLVING
2556  */
2558  SCIP* scip, /**< SCIP data structure */
2559  SCIP_RELAX* relax, /**< relaxator data structure that set the current relaxation solution */
2560  SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2561  )
2562 {
2563  assert(scip != NULL);
2564 
2565  SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkRelaxSolValid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2566 
2567  SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2568  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2569 
2570  return SCIP_OKAY;
2571 }
2572 
2573 /** informs SCIP, that the relaxation solution is invalid
2574  *
2575  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2576  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2577  *
2578  * @pre This method can be called if @p scip is in one of the following stages:
2579  * - \ref SCIP_STAGE_PRESOLVED
2580  * - \ref SCIP_STAGE_SOLVING
2581  */
2583  SCIP* scip /**< SCIP data structure */
2584  )
2585 {
2586  assert(scip != NULL);
2587 
2588  SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkRelaxSolInvalid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2589 
2591 
2592  return SCIP_OKAY;
2593 }
2594 
2595 /** gets the relaxation solution value of the given variable
2596  *
2597  * @return the relaxation solution value of the given variable
2598  *
2599  * @pre This method can be called if @p scip is in one of the following stages:
2600  * - \ref SCIP_STAGE_PRESOLVED
2601  * - \ref SCIP_STAGE_SOLVING
2602  */
2604  SCIP* scip, /**< SCIP data structure */
2605  SCIP_VAR* var /**< variable to get value for */
2606  )
2607 {
2608  assert(scip != NULL);
2609  assert(var != NULL);
2610  assert(var->scip == scip);
2611 
2612  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetRelaxSolVal", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2613 
2614  if( !SCIPrelaxationIsSolValid(scip->relaxation) )
2615  {
2616  SCIPerrorMessage("Relaxation Solution is not valid!\n");
2617  SCIPABORT();
2618  return SCIP_INVALID; /*lint !e527*/
2619  }
2620 
2621  return SCIPvarGetRelaxSol(var, scip->set);
2622 }
2623 
2624 /** gets the relaxation solution objective value
2625  *
2626  * @return the objective value of the relaxation solution
2627  *
2628  * @pre This method can be called if @p scip is in one of the following stages:
2629  * - \ref SCIP_STAGE_PRESOLVED
2630  * - \ref SCIP_STAGE_SOLVING
2631  */
2633  SCIP* scip /**< SCIP data structure */
2634  )
2635 {
2636  assert(scip != NULL);
2637 
2638  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetRelaxSolObj", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2639 
2640  if( !SCIPrelaxationIsSolValid(scip->relaxation) )
2641  {
2642  SCIPerrorMessage("Relaxation Solution is not valid!\n");
2643  SCIPABORT();
2644  return SCIP_INVALID; /*lint !e527*/
2645  }
2646 
2647  return SCIPrelaxationGetSolObj(scip->relaxation);
2648 }
2649 
2650 /** determine which branching direction should be evaluated first by strong branching
2651  *
2652  * @return TRUE iff strong branching should first evaluate the down child
2653  *
2654  */
2656  SCIP* scip, /**< SCIP data structure */
2657  SCIP_VAR* var /**< variable to determine the branching direction on */
2658  )
2659 {
2660  switch( scip->set->branch_firstsbchild )
2661  {
2662  case 'u':
2663  return FALSE;
2664  case 'd':
2665  return TRUE;
2666  case 'a':
2667  return (SCIPvarGetNLocksDown(var) > SCIPvarGetNLocksUp(var));
2668  default:
2669  assert(scip->set->branch_firstsbchild == 'h');
2671  }
2672 }
2673 
2674 /** start strong branching - call before any strong branching
2675  *
2676  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2677  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2678  *
2679  * @pre This method can be called if @p scip is in one of the following stages:
2680  * - \ref SCIP_STAGE_PRESOLVED
2681  * - \ref SCIP_STAGE_SOLVING
2682  *
2683  * @note if propagation is enabled, strong branching is not done directly on the LP, but probing nodes are created
2684  * which allow to perform propagation but also creates some overhead
2685  */
2687  SCIP* scip, /**< SCIP data structure */
2688  SCIP_Bool enablepropagation /**< should propagation be done before solving the strong branching LP? */
2689  )
2690 {
2691  assert( scip != NULL );
2692  SCIP_CALL( SCIPcheckStage(scip, "SCIPstartStrongbranch", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2693 
2694  assert(!SCIPinProbing(scip));
2695 
2696  SCIPdebugMsg(scip, "starting strong branching mode%s: lpcount=%" SCIP_LONGINT_FORMAT "\n", enablepropagation ? " with propagation" : "", scip->stat->lpcount - scip->stat->nsbdivinglps);
2697 
2698  /* start probing mode to allow propagation before solving the strong branching LPs; if no propagation should be done,
2699  * start the strong branching mode in the LP interface
2700  */
2701  if( enablepropagation )
2702  {
2703  if( SCIPtreeProbing(scip->tree) )
2704  {
2705  SCIPerrorMessage("cannot start strong branching with propagation while in probing mode\n");
2706  return SCIP_INVALIDCALL;
2707  }
2708 
2709  if( scip->lp != NULL && SCIPlpDiving(scip->lp) )
2710  {
2711  SCIPerrorMessage("cannot start strong branching with propagation while in diving mode\n");
2712  return SCIP_INVALIDCALL;
2713  }
2714 
2715  /* other then in SCIPstartProbing(), we do not disable collecting variable statistics during strong branching;
2716  * we cannot disable it, because the pseudo costs would not be updated, otherwise,
2717  * and reliability branching would end up doing strong branching all the time
2718  */
2719  SCIP_CALL( SCIPtreeStartProbing(scip->tree, scip->mem->probmem, scip->set, scip->lp, scip->relaxation, scip->transprob, TRUE) );
2720 
2721  /* inform the LP that the current probing mode is used for strong branching */
2723  }
2724  else
2725  {
2727  }
2728 
2729  /* reset local strong branching info */
2731 
2732  return SCIP_OKAY;
2733 }
2734 
2735 /** end strong branching - call after any strong branching
2736  *
2737  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2738  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2739  *
2740  * @pre This method can be called if @p scip is in one of the following stages:
2741  * - \ref SCIP_STAGE_PRESOLVED
2742  * - \ref SCIP_STAGE_SOLVING
2743  */
2745  SCIP* scip /**< SCIP data structure */
2746  )
2747 {
2748  assert( scip != NULL );
2749 
2750  SCIP_CALL( SCIPcheckStage(scip, "SCIPendStrongbranch", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2751 
2752  /* depending on whether the strong branching mode was started with propagation enabled or not, we end the strong
2753  * branching probing mode or the LP strong branching mode
2754  */
2755  if( SCIPtreeProbing(scip->tree) )
2756  {
2757  SCIP_NODE* node;
2758  SCIP_DOMCHG* domchg;
2759  SCIP_VAR** boundchgvars;
2760  SCIP_Real* bounds;
2761  SCIP_BOUNDTYPE* boundtypes;
2762  int nboundchgs;
2763  int nbnds;
2764  int i;
2765 
2766  /* collect all bound changes deducted during probing, which were applied at the probing root and apply them to the
2767  * focusnode
2768  */
2769  node = SCIPgetCurrentNode(scip);
2770  assert(SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE);
2771  assert(SCIPgetProbingDepth(scip) == 0);
2772 
2773  domchg = SCIPnodeGetDomchg(node);
2774  nboundchgs = SCIPdomchgGetNBoundchgs(domchg);
2775 
2776  SCIP_CALL( SCIPallocBufferArray(scip, &boundchgvars, nboundchgs) );
2777  SCIP_CALL( SCIPallocBufferArray(scip, &bounds, nboundchgs) );
2778  SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, nboundchgs) );
2779 
2780  for( i = 0, nbnds = 0; i < nboundchgs; ++i )
2781  {
2782  SCIP_BOUNDCHG* boundchg;
2783 
2784  boundchg = SCIPdomchgGetBoundchg(domchg, i);
2785 
2786  /* ignore redundant bound changes */
2787  if( SCIPboundchgIsRedundant(boundchg) )
2788  continue;
2789 
2790  boundchgvars[nbnds] = SCIPboundchgGetVar(boundchg);
2791  bounds[nbnds] = SCIPboundchgGetNewbound(boundchg);
2792  boundtypes[nbnds] = SCIPboundchgGetBoundtype(boundchg);
2793  ++nbnds;
2794  }
2795 
2796  SCIPdebugMsg(scip, "ending strong branching with probing: %d bound changes collected\n", nbnds);
2797 
2798  /* inform the LP that the probing mode is not used for strong branching anymore */
2800 
2801  /* switch back from probing to normal operation mode and restore variables and constraints to focus node */
2802  SCIP_CALL( SCIPtreeEndProbing(scip->tree, scip->reopt, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
2803  scip->transprob, scip->origprob, scip->lp, scip->relaxation, scip->primal,
2804  scip->branchcand, scip->eventqueue, scip->eventfilter, scip->cliquetable) );
2805 
2806  /* apply the collected bound changes */
2807  for( i = 0; i < nbnds; ++i )
2808  {
2809  if( boundtypes[i] == SCIP_BOUNDTYPE_LOWER )
2810  {
2811  SCIPdebugMsg(scip, "apply probing lower bound change <%s> >= %.9g\n", SCIPvarGetName(boundchgvars[i]), bounds[i]);
2812  SCIP_CALL( SCIPchgVarLb(scip, boundchgvars[i], bounds[i]) );
2813  }
2814  else
2815  {
2816  SCIPdebugMsg(scip, "apply probing upper bound change <%s> <= %.9g\n", SCIPvarGetName(boundchgvars[i]), bounds[i]);
2817  SCIP_CALL( SCIPchgVarUb(scip, boundchgvars[i], bounds[i]) );
2818  }
2819  }
2820 
2821  SCIPfreeBufferArray(scip, &boundtypes);
2822  SCIPfreeBufferArray(scip, &bounds);
2823  SCIPfreeBufferArray(scip, &boundchgvars);
2824  }
2825  else
2826  {
2827  SCIPdebugMsg(scip, "ending strong branching\n");
2828 
2830  }
2831 
2832  return SCIP_OKAY;
2833 }
2834 
2835 /** analyze the strong branching for the given variable; that includes conflict analysis for infeasible branches and
2836  * storing of root reduced cost information
2837  */
2838 static
2840  SCIP* scip, /**< SCIP data structure */
2841  SCIP_VAR* var, /**< variable to analyze */
2842  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
2843  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
2844  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
2845  * infeasible downwards branch, or NULL */
2846  SCIP_Bool* upconflict /**< pointer to store whether a conflict constraint was created for an
2847  * infeasible upwards branch, or NULL */
2848  )
2849 {
2850  SCIP_COL* col;
2851  SCIP_Bool downcutoff;
2852  SCIP_Bool upcutoff;
2853 
2854  col = SCIPvarGetCol(var);
2855  assert(col != NULL);
2856 
2857  downcutoff = col->sbdownvalid && SCIPsetIsGE(scip->set, col->sbdown, scip->lp->cutoffbound);
2858  upcutoff = col->sbupvalid && SCIPsetIsGE(scip->set, col->sbup, scip->lp->cutoffbound);
2859 
2860  if( downinf != NULL )
2861  *downinf = downcutoff;
2862  if( upinf != NULL )
2863  *upinf = upcutoff;
2864 
2865  /* analyze infeasible strong branching sub problems:
2866  * because the strong branching's bound change is necessary for infeasibility, it cannot be undone;
2867  * therefore, infeasible strong branchings on non-binary variables will not produce a valid conflict constraint
2868  */
2869  if( scip->set->conf_enable && scip->set->conf_usesb && scip->set->nconflicthdlrs > 0
2870  && SCIPvarIsBinary(var) && SCIPtreeGetCurrentDepth(scip->tree) > 0 )
2871  {
2872  if( (downcutoff && SCIPsetFeasCeil(scip->set, col->primsol-1.0) >= col->lb - 0.5)
2873  || (upcutoff && SCIPsetFeasFloor(scip->set, col->primsol+1.0) <= col->ub + 0.5) )
2874  {
2875  assert(downconflict != NULL);
2876  assert(upconflict != NULL);
2877  SCIP_CALL( SCIPconflictAnalyzeStrongbranch(scip->conflict, scip->conflictstore, scip->mem->probmem, scip->set, scip->stat,
2878  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, col, downconflict, upconflict) );
2879  }
2880  }
2881 
2882  /* the strong branching results can be used to strengthen the root reduced cost information which is used for example
2883  * to propagate against the cutoff bound
2884  *
2885  * @note Ignore the results if the LP solution of the down (up) branch LP is smaller which should not happened by
2886  * theory but can arise due to numerical issues.
2887  */
2888  if( SCIPtreeGetCurrentDepth(scip->tree) == 0 && SCIPvarIsBinary(var) && SCIPlpIsDualReliable(scip->lp) )
2889  {
2890  SCIP_Real lpobjval;
2891 
2892  assert(SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL);
2893 
2894  lpobjval = SCIPlpGetObjval(scip->lp, scip->set, scip->transprob);
2895 
2896  if( col->sbdownvalid && SCIPsetFeasCeil(scip->set, col->primsol-1.0) >= col->lb - 0.5 && lpobjval < col->sbdown )
2897  SCIPvarUpdateBestRootSol(var, scip->set, SCIPvarGetUbGlobal(var), -(col->sbdown - lpobjval), lpobjval);
2898  if( col->sbupvalid && SCIPsetFeasFloor(scip->set, col->primsol+1.0) <= col->ub + 0.5 && lpobjval < col->sbup )
2899  SCIPvarUpdateBestRootSol(var, scip->set, SCIPvarGetLbGlobal(var), col->sbup - lpobjval, lpobjval);
2900  }
2901 
2902  return SCIP_OKAY;
2903 }
2904 
2905 /** gets strong branching information on column variable with fractional value
2906  *
2907  * Before calling this method, the strong branching mode must have been activated by calling SCIPstartStrongbranch();
2908  * after strong branching was done for all candidate variables, the strong branching mode must be ended by
2909  * SCIPendStrongbranch(). Since this method does not apply domain propagation before strongbranching,
2910  * propagation should not be enabled in the SCIPstartStrongbranch() call.
2911  *
2912  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2913  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2914  *
2915  * @pre This method can be called if @p scip is in one of the following stages:
2916  * - \ref SCIP_STAGE_PRESOLVED
2917  * - \ref SCIP_STAGE_SOLVING
2918  */
2920  SCIP* scip, /**< SCIP data structure */
2921  SCIP_VAR* var, /**< variable to get strong branching values for */
2922  int itlim, /**< iteration limit for strong branchings */
2923  SCIP_Bool idempotent, /**< should scip's state remain the same after the call (statistics, column states...), or should it be updated ? */
2924  SCIP_Real* down, /**< stores dual bound after branching column down */
2925  SCIP_Real* up, /**< stores dual bound after branching column up */
2926  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
2927  * otherwise, it can only be used as an estimate value */
2928  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
2929  * otherwise, it can only be used as an estimate value */
2930  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
2931  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
2932  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
2933  * infeasible downwards branch, or NULL */
2934  SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
2935  * infeasible upwards branch, or NULL */
2936  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
2937  * solving process should be stopped (e.g., due to a time limit) */
2938  )
2939 {
2940  SCIP_COL* col;
2941  SCIP_Real localdown;
2942  SCIP_Real localup;
2943  SCIP_Bool localdownvalid;
2944  SCIP_Bool localupvalid;
2945 
2946  assert(scip != NULL);
2947  assert(var != NULL);
2948  assert(lperror != NULL);
2949  assert(!SCIPtreeProbing(scip->tree)); /* we should not be in strong branching with propagation mode */
2950  assert(var->scip == scip);
2951 
2952  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchFrac", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2953 
2954  if( downvalid != NULL )
2955  *downvalid = FALSE;
2956  if( upvalid != NULL )
2957  *upvalid = FALSE;
2958  if( downinf != NULL )
2959  *downinf = FALSE;
2960  if( upinf != NULL )
2961  *upinf = FALSE;
2962  if( downconflict != NULL )
2963  *downconflict = FALSE;
2964  if( upconflict != NULL )
2965  *upconflict = FALSE;
2966 
2968  {
2969  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
2970  return SCIP_INVALIDDATA;
2971  }
2972 
2973  col = SCIPvarGetCol(var);
2974  assert(col != NULL);
2975 
2976  if( !SCIPcolIsInLP(col) )
2977  {
2978  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
2979  return SCIP_INVALIDDATA;
2980  }
2981 
2982  /* check if the solving process should be aborted */
2983  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
2984  {
2985  /* mark this as if the LP failed */
2986  *lperror = TRUE;
2987  return SCIP_OKAY;
2988  }
2989 
2990  /* call strong branching for column with fractional value */
2991  SCIP_CALL( SCIPcolGetStrongbranch(col, FALSE, scip->set, scip->stat, scip->transprob, scip->lp, itlim, !idempotent, !idempotent,
2992  &localdown, &localup, &localdownvalid, &localupvalid, lperror) );
2993 
2994  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
2995  * declare the sub nodes infeasible
2996  */
2997  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
2998  {
2999  if( !idempotent ) /*lint !e774*/
3000  {
3001  SCIP_CALL( analyzeStrongbranch(scip, var, downinf, upinf, downconflict, upconflict) );
3002  }
3003  else
3004  {
3005  if( downinf != NULL )
3006  *downinf = localdownvalid && SCIPsetIsGE(scip->set, localdown, scip->lp->cutoffbound);
3007  if( upinf != NULL )
3008  *upinf = localupvalid && SCIPsetIsGE(scip->set, localup, scip->lp->cutoffbound);
3009  }
3010  }
3011 
3012  if( down != NULL )
3013  *down = localdown;
3014  if( up != NULL )
3015  *up = localup;
3016  if( downvalid != NULL )
3017  *downvalid = localdownvalid;
3018  if( upvalid != NULL )
3019  *upvalid = localupvalid;
3020 
3021  return SCIP_OKAY;
3022 }
3023 
3024 /** create, solve, and evaluate a single strong branching child (for strong branching with propagation) */
3025 static
3027  SCIP* scip, /**< SCIP data structure */
3028  SCIP_VAR* var, /**< variable to get strong branching values for */
3029  SCIP_Bool down, /**< do we regard the down child? */
3030  SCIP_Bool firstchild, /**< is this the first of the two strong branching children? */
3031  SCIP_Bool propagate, /**< should domain propagation be performed? */
3032  SCIP_Real newbound, /**< new bound to apply at the strong branching child */
3033  int itlim, /**< iteration limit for strong branchings */
3034  int maxproprounds, /**< maximum number of propagation rounds (-1: no limit, -2: parameter
3035  * settings) */
3036  SCIP_Real* value, /**< stores dual bound for strong branching child */
3037  SCIP_Bool* valid, /**< stores whether the returned value is a valid dual bound, or NULL;
3038  * otherwise, it can only be used as an estimate value */
3039  SCIP_Longint* ndomreductions, /**< pointer to store the number of domain reductions found, or NULL */
3040  SCIP_Bool* conflict, /**< pointer to store whether a conflict constraint was created for an
3041  * infeasible strong branching child, or NULL */
3042  SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred or the
3043  * solving process should be stopped (e.g., due to a time limit) */
3044  SCIP_VAR** vars, /**< active problem variables */
3045  int nvars, /**< number of active problem variables */
3046  SCIP_Real* newlbs, /**< array to store valid lower bounds for all active variables, or NULL */
3047  SCIP_Real* newubs, /**< array to store valid upper bounds for all active variables, or NULL */
3048  SCIP_Bool* foundsol, /**< pointer to store whether a primal solution was found during strong branching */
3049  SCIP_Bool* cutoff /**< pointer to store whether the strong branching child is infeasible */
3050  )
3051 {
3052  SCIP_Longint ndomreds;
3053 
3054  assert(value != NULL);
3055  assert(foundsol != NULL);
3056  assert(cutoff != NULL);
3057  assert(lperror != NULL);
3058  assert(valid != NULL ? !(*valid) : TRUE);
3059 
3060  *foundsol = FALSE;
3061  *cutoff = FALSE;
3062  *lperror = FALSE;
3063 
3064  /* check whether the strong branching child is already infeasible due to the bound change */
3065  if( down )
3066  {
3067  /* the down branch is infeasible due to the branching bound change; since this means that solval is not within the
3068  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3069  * are valid for and were already applied at the probing root
3070  */
3071  if( newbound < SCIPvarGetLbLocal(var) - 0.5 )
3072  {
3073  *value = SCIPinfinity(scip);
3074 
3075  if( valid != NULL )
3076  *valid = TRUE;
3077 
3078  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3079  if( conflict != NULL )
3080  *conflict = TRUE;
3081 
3082  *cutoff = TRUE;
3083 
3084  return SCIP_OKAY;
3085  }
3086  }
3087  else
3088  {
3089  /* the up branch is infeasible due to the branching bound change; since this means that solval is not within the
3090  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3091  * are valid for and were already applied at the probing root
3092  */
3093  if( newbound > SCIPvarGetUbLocal(var) + 0.5 )
3094  {
3095  *value = SCIPinfinity(scip);
3096 
3097  if( valid != NULL )
3098  *valid = TRUE;
3099 
3100  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3101  if( conflict != NULL )
3102  *conflict = TRUE;
3103 
3104  *cutoff = TRUE;
3105 
3106  return SCIP_OKAY;
3107  }
3108  }
3109 
3110  /* we need to ensure that we can create at least one new probing node without exceeding the maximal tree depth */
3112  {
3113  /* create a new probing node for the strong branching child and apply the new bound for the variable */
3114  SCIP_CALL( SCIPnewProbingNode(scip) );
3115 
3116  if( down )
3117  {
3118  assert(SCIPisGE(scip, newbound, SCIPvarGetLbLocal(var)));
3119  if( SCIPisLT(scip, newbound, SCIPvarGetUbLocal(var)) )
3120  {
3121  SCIP_CALL( SCIPchgVarUbProbing(scip, var, newbound) );
3122  }
3123  }
3124  else
3125  {
3126  assert(SCIPisLE(scip, newbound, SCIPvarGetUbLocal(var)));
3127  if( SCIPisGT(scip, newbound, SCIPvarGetLbLocal(var)) )
3128  {
3129  SCIP_CALL( SCIPchgVarLbProbing(scip, var, newbound) );
3130  }
3131  }
3132  }
3133  else
3134  {
3135  if( valid != NULL )
3136  *valid = FALSE;
3137 
3138  *cutoff = FALSE;
3139 
3140  if( conflict != NULL )
3141  *conflict = FALSE;
3142 
3143  return SCIP_OKAY;
3144  }
3145 
3146  /* propagate domains at the probing node */
3147  if( propagate )
3148  {
3149  /* start time measuring */
3150  SCIPclockStart(scip->stat->strongpropclock, scip->set);
3151 
3152  ndomreds = 0;
3153  SCIP_CALL( SCIPpropagateProbing(scip, maxproprounds, cutoff, &ndomreds) );
3154 
3155  /* store number of domain reductions in strong branching */
3156  if( down )
3157  SCIPstatAdd(scip->stat, scip->set, nsbdowndomchgs, ndomreds);
3158  else
3159  SCIPstatAdd(scip->stat, scip->set, nsbupdomchgs, ndomreds);
3160 
3161  if( ndomreductions != NULL )
3162  *ndomreductions = ndomreds;
3163 
3164  /* stop time measuring */
3165  SCIPclockStop(scip->stat->strongpropclock, scip->set);
3166 
3167  if( *cutoff )
3168  {
3169  *value = SCIPinfinity(scip);
3170 
3171  if( valid != NULL )
3172  *valid = TRUE;
3173 
3174  SCIPdebugMsg(scip, "%s branch of var <%s> detected infeasible during propagation\n",
3175  down ? "down" : "up", SCIPvarGetName(var));
3176  }
3177  }
3178 
3179  /* if propagation did not already detect infeasibility, solve the probing LP */
3180  if( !(*cutoff) )
3181  {
3182  SCIP_CALL( SCIPsolveProbingLP(scip, itlim, lperror, cutoff) );
3183  assert(SCIPisLPRelax(scip));
3184 
3185  if( *cutoff )
3186  {
3187  assert(!(*lperror));
3188 
3189  *value = SCIPinfinity(scip);
3190 
3191  if( valid != NULL )
3192  *valid = TRUE;
3193 
3194  SCIPdebugMsg(scip, "%s branch of var <%s> detected infeasible in LP solving: status=%d\n",
3195  down ? "down" : "up", SCIPvarGetName(var), SCIPgetLPSolstat(scip));
3196  }
3197  else if( !(*lperror) )
3198  {
3199  /* save the lp solution status */
3200  scip->stat->lastsblpsolstats[down ? 0 : 1] = SCIPgetLPSolstat(scip);
3201 
3202  switch( SCIPgetLPSolstat(scip) )
3203  {
3205  {
3206  *value = SCIPgetLPObjval(scip);
3207  assert(SCIPisLT(scip, *value, SCIPgetCutoffbound(scip)));
3208 
3209  SCIPdebugMsg(scip, "probing LP solved to optimality, objective value: %16.9g\n", *value);
3210 
3211  if( valid != NULL )
3212  *valid = TRUE;
3213 
3214  /* check the strong branching LP solution for feasibility */
3215  SCIP_CALL( SCIPtryStrongbranchLPSol(scip, foundsol, cutoff) );
3216  break;
3217  }
3219  ++scip->stat->nsbtimesiterlimhit;
3220  /*lint -fallthrough*/
3222  {
3223  /* use LP value as estimate */
3224  SCIP_LPI* lpi;
3225  SCIP_Real objval;
3226  SCIP_Real looseobjval;
3227 
3228  SCIPdebugMsg(scip, "probing LP hit %s limit\n", SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_ITERLIMIT ? "iteration" : "time");
3229 
3230  /* we access the LPI directly, because when a time limit was hit, we cannot access objective value and dual
3231  * feasibility using the SCIPlp... methods; we should try to avoid direct calls to the LPI, but this is rather
3232  * uncritical here, because we are immediately after the SCIPsolveProbingLP() call, because we access the LPI
3233  * read-only, and we check SCIPlpiWasSolved() first
3234  */
3235  SCIP_CALL( SCIPgetLPI(scip, &lpi) );
3236 
3237  if( SCIPlpiWasSolved(lpi) )
3238  {
3239  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
3240  looseobjval = SCIPlpGetLooseObjval(scip->lp, scip->set, scip->transprob);
3241 
3242  /* the infinity value in the LPI should not be smaller than SCIP's infinity value */
3243  assert(!SCIPlpiIsInfinity(lpi, objval) || SCIPisInfinity(scip, objval));
3244 
3245  /* we use SCIP's infinity value here because a value larger than this is counted as infeasible by SCIP */
3246  if( SCIPisInfinity(scip, objval) )
3247  *value = SCIPinfinity(scip);
3248  else if( SCIPisInfinity(scip, -looseobjval) )
3249  *value = -SCIPinfinity(scip);
3250  else
3251  *value = objval + looseobjval;
3252 
3253  if( SCIPlpiIsDualFeasible(lpi) )
3254  {
3255  if( valid != NULL )
3256  *valid = TRUE;
3257 
3258  if( SCIPisGE(scip, *value, SCIPgetCutoffbound(scip)) )
3259  *cutoff = TRUE;
3260  }
3261  }
3262  break;
3263  }
3264  case SCIP_LPSOLSTAT_ERROR:
3266  *lperror = TRUE;
3267  break;
3268  case SCIP_LPSOLSTAT_NOTSOLVED: /* should only be the case for *cutoff = TRUE or *lperror = TRUE */
3269  case SCIP_LPSOLSTAT_OBJLIMIT: /* in this case, *cutoff should be TRUE and we should not get here */
3270  case SCIP_LPSOLSTAT_INFEASIBLE: /* in this case, *cutoff should be TRUE and we should not get here */
3271  default:
3272  SCIPerrorMessage("invalid LP solution status <%d>\n", SCIPgetLPSolstat(scip));
3273  return SCIP_INVALIDDATA;
3274  } /*lint !e788*/
3275  }
3276 
3277  /* If columns are missing in the LP, the cutoff flag may be wrong. Therefore, we need to set it and the valid pointer
3278  * to false here.
3279  */
3280  if( (*cutoff) && !SCIPallColsInLP(scip) )
3281  {
3282  *cutoff = FALSE;
3283  }
3284 
3285 #ifndef NDEBUG
3286  if( *lperror )
3287  {
3288  SCIPdebugMsg(scip, "error during strong branching probing LP solving: status=%d\n", SCIPgetLPSolstat(scip));
3289  }
3290 #endif
3291  }
3292 
3293  /* if the subproblem was feasible, we store the local bounds of the variables after propagation and (possibly)
3294  * conflict analysis
3295  * @todo do this after propagation? should be able to get valid bounds more often, but they might be weaker
3296  */
3297  if( !(*cutoff) && newlbs != NULL)
3298  {
3299  int v;
3300 
3301  assert(newubs != NULL);
3302 
3303  /* initialize the newlbs and newubs to the current local bounds */
3304  if( firstchild )
3305  {
3306  for( v = 0; v < nvars; ++v )
3307  {
3308  newlbs[v] = SCIPvarGetLbLocal(vars[v]);
3309  newubs[v] = SCIPvarGetUbLocal(vars[v]);
3310  }
3311  }
3312  /* update newlbs and newubs: take the weaker of the already stored bounds and the current local bounds */
3313  else
3314  {
3315  for( v = 0; v < nvars; ++v )
3316  {
3317  SCIP_Real lb = SCIPvarGetLbLocal(vars[v]);
3318  SCIP_Real ub = SCIPvarGetUbLocal(vars[v]);
3319 
3320  newlbs[v] = MIN(newlbs[v], lb);
3321  newubs[v] = MAX(newubs[v], ub);
3322  }
3323  }
3324  }
3325 
3326  /* revert all changes at the probing node */
3327  SCIP_CALL( SCIPbacktrackProbing(scip, 0) );
3328 
3329  return SCIP_OKAY;
3330 }
3331 
3332 /** gets strong branching information with previous domain propagation on column variable
3333  *
3334  * Before calling this method, the strong branching mode must have been activated by calling SCIPstartStrongbranch();
3335  * after strong branching was done for all candidate variables, the strong branching mode must be ended by
3336  * SCIPendStrongbranch(). Since this method applies domain propagation before strongbranching, propagation has to be be
3337  * enabled in the SCIPstartStrongbranch() call.
3338  *
3339  * Before solving the strong branching LP, domain propagation can be performed. The number of propagation rounds
3340  * can be specified by the parameter @p maxproprounds.
3341  *
3342  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3343  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3344  *
3345  * @pre This method can be called if @p scip is in one of the following stages:
3346  * - \ref SCIP_STAGE_PRESOLVED
3347  * - \ref SCIP_STAGE_SOLVING
3348  *
3349  * @warning When using this method, LP banching candidates and solution values must be copied beforehand, because
3350  * they are updated w.r.t. the strong branching LP solution.
3351  */
3353  SCIP* scip, /**< SCIP data structure */
3354  SCIP_VAR* var, /**< variable to get strong branching values for */
3355  SCIP_Real solval, /**< value of the variable in the current LP solution */
3356  SCIP_Real lpobjval, /**< LP objective value of the current LP solution */
3357  int itlim, /**< iteration limit for strong branchings */
3358  int maxproprounds, /**< maximum number of propagation rounds (-1: no limit, -2: parameter
3359  * settings) */
3360  SCIP_Real* down, /**< stores dual bound after branching column down */
3361  SCIP_Real* up, /**< stores dual bound after branching column up */
3362  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
3363  * otherwise, it can only be used as an estimate value */
3364  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
3365  * otherwise, it can only be used as an estimate value */
3366  SCIP_Longint* ndomredsdown, /**< pointer to store the number of domain reductions down, or NULL */
3367  SCIP_Longint* ndomredsup, /**< pointer to store the number of domain reductions up, or NULL */
3368  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
3369  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
3370  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
3371  * infeasible downwards branch, or NULL */
3372  SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
3373  * infeasible upwards branch, or NULL */
3374  SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred or the
3375  * solving process should be stopped (e.g., due to a time limit) */
3376  SCIP_Real* newlbs, /**< array to store valid lower bounds for all active variables, or NULL */
3377  SCIP_Real* newubs /**< array to store valid upper bounds for all active variables, or NULL */
3378  )
3379 {
3380  SCIP_COL* col;
3381  SCIP_VAR** vars;
3382  SCIP_Longint oldniters;
3383  SCIP_Real newub;
3384  SCIP_Real newlb;
3385  SCIP_Bool propagate;
3386  SCIP_Bool cutoff;
3387  SCIP_Bool downchild;
3388  SCIP_Bool firstchild;
3389  SCIP_Bool foundsol;
3390  SCIP_Bool downvalidlocal;
3391  SCIP_Bool upvalidlocal;
3392  SCIP_Bool allcolsinlp;
3393  SCIP_Bool enabledconflict;
3394  int oldnconflicts;
3395  int nvars;
3396 
3397  assert(scip != NULL);
3398  assert(var != NULL);
3399  assert(SCIPvarIsIntegral(var));
3400  assert(down != NULL);
3401  assert(up != NULL);
3402  assert(lperror != NULL);
3403  assert((newlbs != NULL) == (newubs != NULL));
3404  assert(SCIPinProbing(scip));
3405  assert(var->scip == scip);
3406 
3407  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchWithPropagation", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3408 
3409  /* check whether propagation should be performed */
3410  propagate = (maxproprounds != 0 && maxproprounds != -3);
3411 
3412  /* Check, if all existing columns are in LP.
3413  * If this is not the case, we may still return that the up and down dual bounds are valid, because the branching
3414  * rule should not apply them otherwise.
3415  * However, we must not set the downinf or upinf pointers to TRUE based on the dual bound, because we cannot
3416  * guarantee that this node can be cut off.
3417  */
3418  allcolsinlp = SCIPallColsInLP(scip);
3419 
3420  /* if maxproprounds is -2, change it to 0, which for the following calls means using the parameter settings */
3421  if( maxproprounds == -2 )
3422  maxproprounds = 0;
3423 
3424  *down = lpobjval;
3425  *up = lpobjval;
3426  if( downvalid != NULL )
3427  *downvalid = FALSE;
3428  if( upvalid != NULL )
3429  *upvalid = FALSE;
3430  if( downinf != NULL )
3431  *downinf = FALSE;
3432  if( upinf != NULL )
3433  *upinf = FALSE;
3434  if( downconflict != NULL )
3435  *downconflict = FALSE;
3436  if( upconflict != NULL )
3437  *upconflict = FALSE;
3438  if( ndomredsdown != NULL )
3439  *ndomredsdown = 0;
3440  if( ndomredsup != NULL )
3441  *ndomredsup = 0;
3442 
3443  *lperror = FALSE;
3444 
3445  vars = SCIPgetVars(scip);
3446  nvars = SCIPgetNVars(scip);
3447 
3449 
3450  /* check if the solving process should be aborted */
3451  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3452  {
3453  /* mark this as if the LP failed */
3454  *lperror = TRUE;
3455  return SCIP_OKAY;
3456  }
3457 
3459  {
3460  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3461  return SCIP_INVALIDDATA;
3462  }
3463 
3464  col = SCIPvarGetCol(var);
3465  assert(col != NULL);
3466 
3467  if( !SCIPcolIsInLP(col) )
3468  {
3469  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3470  return SCIP_INVALIDDATA;
3471  }
3472 
3473  newlb = SCIPfeasFloor(scip, solval + 1.0);
3474  newub = SCIPfeasCeil(scip, solval - 1.0);
3475 
3476  SCIPdebugMsg(scip, "strong branching on var <%s>: solval=%g, lb=%g, ub=%g\n", SCIPvarGetName(var), solval,
3478 
3479  /* the up branch is infeasible due to the branching bound change; since this means that solval is not within the
3480  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3481  * are valid for and were already applied at the probing root
3482  */
3483  if( newlb > SCIPvarGetUbLocal(var) + 0.5 )
3484  {
3485  *up = SCIPinfinity(scip);
3486 
3487  if( upinf != NULL )
3488  *upinf = TRUE;
3489 
3490  if( upvalid != NULL )
3491  *upvalid = TRUE;
3492 
3493  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3494  if( upconflict != NULL )
3495  *upconflict = TRUE;
3496 
3497  SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3498  *down, *up, FALSE, TRUE, 0LL, INT_MAX);
3499 
3500  /* we do not regard the down branch; its valid pointer stays set to FALSE */
3501  return SCIP_OKAY;
3502  }
3503 
3504  /* the down branch is infeasible due to the branching bound change; since this means that solval is not within the
3505  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3506  * are valid for and were already applied at the probing root
3507  */
3508  if( newub < SCIPvarGetLbLocal(var) - 0.5 )
3509  {
3510  *down = SCIPinfinity(scip);
3511 
3512  if( downinf != NULL )
3513  *downinf = TRUE;
3514 
3515  if( downvalid != NULL )
3516  *downvalid = TRUE;
3517 
3518  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3519  if( downconflict != NULL )
3520  *downconflict = TRUE;
3521 
3522  SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3523  *down, *up, TRUE, FALSE, 0LL, INT_MAX);
3524 
3525  /* we do not regard the up branch; its valid pointer stays set to FALSE */
3526  return SCIP_OKAY;
3527  }
3528 
3529  /* We now do strong branching by creating the two potential child nodes as probing nodes and solving them one after
3530  * the other. We will stop when the first child is detected infeasible, saving the effort we would need for the
3531  * second child. Since empirically, the up child tends to be infeasible more often, we do strongbranching first on
3532  * the up branch.
3533  */
3534  oldniters = scip->stat->nsbdivinglpiterations;
3535  firstchild = TRUE;
3536  cutoff = FALSE;
3537 
3538  /* switch conflict analysis according to usesb parameter */
3539  enabledconflict = scip->set->conf_enable;
3540  scip->set->conf_enable = (scip->set->conf_enable && scip->set->conf_usesb);
3541 
3542  /* @todo: decide the branch to look at first based on the cutoffs in previous calls? */
3543  downchild = SCIPisStrongbranchDownFirst(scip, var);
3544 
3545  downvalidlocal = FALSE;
3546  upvalidlocal = FALSE;
3547 
3548  do
3549  {
3550  oldnconflicts = SCIPconflictGetNConflicts(scip->conflict);
3551 
3552  if( downchild )
3553  {
3554  SCIP_CALL( performStrongbranchWithPropagation(scip, var, downchild, firstchild, propagate, newub, itlim, maxproprounds,
3555  down, &downvalidlocal, ndomredsdown, downconflict, lperror, vars, nvars, newlbs, newubs, &foundsol, &cutoff) );
3556 
3557  /* check whether a new solutions rendered the previous child infeasible */
3558  if( foundsol && !firstchild && allcolsinlp )
3559  {
3560  if( SCIPisGE(scip, *up, SCIPgetCutoffbound(scip)) )
3561  {
3562  if( upinf != NULL )
3563  *upinf = TRUE;
3564  }
3565  }
3566 
3567  /* check for infeasibility */
3568  if( cutoff )
3569  {
3570  if( downinf != NULL )
3571  *downinf = TRUE;
3572 
3573  if( downconflict != NULL &&
3574  (SCIPvarGetLbLocal(var) > newub + 0.5 || SCIPconflictGetNConflicts(scip->conflict) > oldnconflicts) )
3575  {
3576  *downconflict = TRUE;
3577  }
3578 
3579  if( !scip->set->branch_forceall )
3580  {
3581  /* if this is the first call, we do not regard the up branch, its valid pointer is initially set to FALSE */
3582  break;
3583  }
3584  }
3585  }
3586  else
3587  {
3588  SCIP_CALL( performStrongbranchWithPropagation(scip, var, downchild, firstchild, propagate, newlb, itlim, maxproprounds,
3589  up, &upvalidlocal, ndomredsup, upconflict, lperror, vars, nvars, newlbs, newubs, &foundsol, &cutoff) );
3590 
3591  /* check whether a new solutions rendered the previous child infeasible */
3592  if( foundsol && !firstchild && allcolsinlp )
3593  {
3594  if( SCIPisGE(scip, *down, SCIPgetCutoffbound(scip)) )
3595  {
3596  if( downinf != NULL )
3597  *downinf = TRUE;
3598  }
3599  }
3600 
3601  /* check for infeasibility */
3602  if( cutoff )
3603  {
3604  if( upinf != NULL )
3605  *upinf = TRUE;
3606 
3607  assert(upinf == NULL || (*upinf) == TRUE);
3608 
3609  if( upconflict != NULL &&
3610  (SCIPvarGetUbLocal(var) < newlb - 0.5 || SCIPconflictGetNConflicts(scip->conflict) > oldnconflicts) )
3611  {
3612  *upconflict = TRUE;
3613  }
3614 
3615  if( !scip->set->branch_forceall )
3616  {
3617  /* if this is the first call, we do not regard the down branch, its valid pointer is initially set to FALSE */
3618  break;
3619  }
3620  }
3621  }
3622 
3623  downchild = !downchild;
3624  firstchild = !firstchild;
3625  }
3626  while( !firstchild );
3627 
3628  /* set strong branching information in column */
3629  if( *lperror )
3630  {
3631  SCIPcolInvalidateStrongbranchData(col, scip->set, scip->stat, scip->lp);
3632  }
3633  else
3634  {
3635  SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3636  *down, *up, downvalidlocal, upvalidlocal, scip->stat->nsbdivinglpiterations - oldniters, itlim);
3637  }
3638 
3639  if( downvalid != NULL )
3640  *downvalid = downvalidlocal;
3641  if( upvalid != NULL )
3642  *upvalid = upvalidlocal;
3643 
3644  scip->set->conf_enable = enabledconflict;
3645 
3646  return SCIP_OKAY; /*lint !e438*/
3647 }
3648 
3649 /** gets strong branching information on column variable x with integral LP solution value (val); that is, the down branch
3650  * is (val -1.0) and the up brach ins (val +1.0)
3651  *
3652  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3653  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3654  *
3655  * @pre This method can be called if @p scip is in one of the following stages:
3656  * - \ref SCIP_STAGE_PRESOLVED
3657  * - \ref SCIP_STAGE_SOLVING
3658  *
3659  * @note If the integral LP solution value is the lower or upper bound of the variable, the corresponding branch will be
3660  * marked as infeasible. That is, the valid pointer and the infeasible pointer are set to TRUE.
3661  */
3663  SCIP* scip, /**< SCIP data structure */
3664  SCIP_VAR* var, /**< variable to get strong branching values for */
3665  int itlim, /**< iteration limit for strong branchings */
3666  SCIP_Bool idempotent, /**< should scip's state remain the same after the call (statistics, column states...), or should it be updated ? */
3667  SCIP_Real* down, /**< stores dual bound after branching column down */
3668  SCIP_Real* up, /**< stores dual bound after branching column up */
3669  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
3670  * otherwise, it can only be used as an estimate value */
3671  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
3672  * otherwise, it can only be used as an estimate value */
3673  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
3674  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
3675  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
3676  * infeasible downwards branch, or NULL */
3677  SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
3678  * infeasible upwards branch, or NULL */
3679  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3680  * solving process should be stopped (e.g., due to a time limit) */
3681  )
3682 {
3683  SCIP_COL* col;
3684  SCIP_Real localdown;
3685  SCIP_Real localup;
3686  SCIP_Bool localdownvalid;
3687  SCIP_Bool localupvalid;
3688 
3689  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchInt", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3690 
3691  assert(lperror != NULL);
3692  assert(var->scip == scip);
3693 
3694  if( downvalid != NULL )
3695  *downvalid = FALSE;
3696  if( upvalid != NULL )
3697  *upvalid = FALSE;
3698  if( downinf != NULL )
3699  *downinf = FALSE;
3700  if( upinf != NULL )
3701  *upinf = FALSE;
3702  if( downconflict != NULL )
3703  *downconflict = FALSE;
3704  if( upconflict != NULL )
3705  *upconflict = FALSE;
3706 
3708  {
3709  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3710  return SCIP_INVALIDDATA;
3711  }
3712 
3713  col = SCIPvarGetCol(var);
3714  assert(col != NULL);
3715 
3716  if( !SCIPcolIsInLP(col) )
3717  {
3718  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3719  return SCIP_INVALIDDATA;
3720  }
3721 
3722  /* check if the solving process should be aborted */
3723  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3724  {
3725  /* mark this as if the LP failed */
3726  *lperror = TRUE;
3727  return SCIP_OKAY;
3728  }
3729 
3730  /* call strong branching for column */
3731  SCIP_CALL( SCIPcolGetStrongbranch(col, TRUE, scip->set, scip->stat, scip->transprob, scip->lp, itlim, !idempotent, !idempotent,
3732  &localdown, &localup, &localdownvalid, &localupvalid, lperror) );
3733 
3734  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3735  * declare the sub nodes infeasible
3736  */
3737  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3738  {
3739  if( !idempotent ) /*lint !e774*/
3740  {
3741  SCIP_CALL( analyzeStrongbranch(scip, var, downinf, upinf, downconflict, upconflict) );
3742  }
3743  else
3744  {
3745  if( downinf != NULL )
3746  *downinf = localdownvalid && SCIPsetIsGE(scip->set, localdown, scip->lp->cutoffbound);
3747  if( upinf != NULL )
3748  *upinf = localupvalid && SCIPsetIsGE(scip->set, localup, scip->lp->cutoffbound);
3749  }
3750  }
3751 
3752  if( down != NULL )
3753  *down = localdown;
3754  if( up != NULL )
3755  *up = localup;
3756  if( downvalid != NULL )
3757  *downvalid = localdownvalid;
3758  if( upvalid != NULL )
3759  *upvalid = localupvalid;
3760 
3761  return SCIP_OKAY;
3762 }
3763 
3764 /** gets strong branching information on column variables with fractional values
3765  *
3766  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3767  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3768  *
3769  * @pre This method can be called if @p scip is in one of the following stages:
3770  * - \ref SCIP_STAGE_PRESOLVED
3771  * - \ref SCIP_STAGE_SOLVING
3772  */
3774  SCIP* scip, /**< SCIP data structure */
3775  SCIP_VAR** vars, /**< variables to get strong branching values for */
3776  int nvars, /**< number of variables */
3777  int itlim, /**< iteration limit for strong branchings */
3778  SCIP_Real* down, /**< stores dual bounds after branching variables down */
3779  SCIP_Real* up, /**< stores dual bounds after branching variables up */
3780  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
3781  * otherwise, they can only be used as an estimate value */
3782  SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
3783  * otherwise, they can only be used as an estimate value */
3784  SCIP_Bool* downinf, /**< array to store whether the downward branches are infeasible, or NULL */
3785  SCIP_Bool* upinf, /**< array to store whether the upward branches are infeasible, or NULL */
3786  SCIP_Bool* downconflict, /**< array to store whether conflict constraints were created for
3787  * infeasible downward branches, or NULL */
3788  SCIP_Bool* upconflict, /**< array to store whether conflict constraints were created for
3789  * infeasible upward branches, or NULL */
3790  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3791  * solving process should be stopped (e.g., due to a time limit) */
3792  )
3793 {
3794  SCIP_COL** cols;
3795  int j;
3796 
3797  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarsStrongbranchesFrac", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3798 
3799  assert( lperror != NULL );
3800  assert( vars != NULL );
3801 
3802  /* set up data */
3803  cols = NULL;
3804  SCIP_CALL( SCIPallocBufferArray(scip, &cols, nvars) );
3805  assert(cols != NULL);
3806  for( j = 0; j < nvars; ++j )
3807  {
3808  SCIP_VAR* var;
3809  SCIP_COL* col;
3810 
3811  if( downvalid != NULL )
3812  downvalid[j] = FALSE;
3813  if( upvalid != NULL )
3814  upvalid[j] = FALSE;
3815  if( downinf != NULL )
3816  downinf[j] = FALSE;
3817  if( upinf != NULL )
3818  upinf[j] = FALSE;
3819  if( downconflict != NULL )
3820  downconflict[j] = FALSE;
3821  if( upconflict != NULL )
3822  upconflict[j] = FALSE;
3823 
3824  var = vars[j];
3825  assert( var != NULL );
3827  {
3828  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3829  SCIPfreeBufferArray(scip, &cols);
3830  return SCIP_INVALIDDATA;
3831  }
3832 
3833  col = SCIPvarGetCol(var);
3834  assert(col != NULL);
3835  cols[j] = col;
3836 
3837  if( !SCIPcolIsInLP(col) )
3838  {
3839  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3840  SCIPfreeBufferArray(scip, &cols);
3841  return SCIP_INVALIDDATA;
3842  }
3843  }
3844 
3845  /* check if the solving process should be aborted */
3846  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3847  {
3848  /* mark this as if the LP failed */
3849  *lperror = TRUE;
3850  }
3851  else
3852  {
3853  /* call strong branching for columns with fractional value */
3854  SCIP_CALL( SCIPcolGetStrongbranches(cols, nvars, FALSE, scip->set, scip->stat, scip->transprob, scip->lp, itlim,
3855  down, up, downvalid, upvalid, lperror) );
3856 
3857  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3858  * declare the sub nodes infeasible
3859  */
3860  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3861  {
3862  for( j = 0; j < nvars; ++j )
3863  {
3864  SCIP_CALL( analyzeStrongbranch(scip, vars[j], (downinf != NULL) ? (&(downinf[j])) : NULL,
3865  (upinf != NULL) ? (&(upinf[j])) : NULL, (downconflict != NULL) ? (&(downconflict[j])) : NULL,
3866  (upconflict != NULL) ? (&(upconflict[j])) : NULL) );
3867  }
3868  }
3869  }
3870  SCIPfreeBufferArray(scip, &cols);
3871 
3872  return SCIP_OKAY;
3873 }
3874 
3875 /** gets strong branching information on column variables with integral values
3876  *
3877  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3878  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3879  *
3880  * @pre This method can be called if @p scip is in one of the following stages:
3881  * - \ref SCIP_STAGE_PRESOLVED
3882  * - \ref SCIP_STAGE_SOLVING
3883  */
3885  SCIP* scip, /**< SCIP data structure */
3886  SCIP_VAR** vars, /**< variables to get strong branching values for */
3887  int nvars, /**< number of variables */
3888  int itlim, /**< iteration limit for strong branchings */
3889  SCIP_Real* down, /**< stores dual bounds after branching variables down */
3890  SCIP_Real* up, /**< stores dual bounds after branching variables up */
3891  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
3892  * otherwise, they can only be used as an estimate value */
3893  SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
3894  * otherwise, they can only be used as an estimate value */
3895  SCIP_Bool* downinf, /**< array to store whether the downward branches are infeasible, or NULL */
3896  SCIP_Bool* upinf, /**< array to store whether the upward branches are infeasible, or NULL */
3897  SCIP_Bool* downconflict, /**< array to store whether conflict constraints were created for
3898  * infeasible downward branches, or NULL */
3899  SCIP_Bool* upconflict, /**< array to store whether conflict constraints were created for
3900  * infeasible upward branches, or NULL */
3901  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3902  * solving process should be stopped (e.g., due to a time limit) */
3903  )
3904 {
3905  SCIP_COL** cols;
3906  int j;
3907 
3908  assert(lperror != NULL);
3909 
3910  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarsStrongbranchesInt", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3911 
3912  assert( vars != NULL );
3913 
3914  /* set up data */
3915  cols = NULL;
3916  SCIP_CALL( SCIPallocBufferArray(scip, &cols, nvars) );
3917  assert(cols != NULL);
3918  for( j = 0; j < nvars; ++j )
3919  {
3920  SCIP_VAR* var;
3921  SCIP_COL* col;
3922 
3923  if( downvalid != NULL )
3924  downvalid[j] = FALSE;
3925  if( upvalid != NULL )
3926  upvalid[j] = FALSE;
3927  if( downinf != NULL )
3928  downinf[j] = FALSE;
3929  if( upinf != NULL )
3930  upinf[j] = FALSE;
3931  if( downconflict != NULL )
3932  downconflict[j] = FALSE;
3933  if( upconflict != NULL )
3934  upconflict[j] = FALSE;
3935 
3936  var = vars[j];
3937  assert( var != NULL );
3939  {
3940  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3941  SCIPfreeBufferArray(scip, &cols);
3942  return SCIP_INVALIDDATA;
3943  }
3944 
3945  col = SCIPvarGetCol(var);
3946  assert(col != NULL);
3947  cols[j] = col;
3948 
3949  if( !SCIPcolIsInLP(col) )
3950  {
3951  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3952  SCIPfreeBufferArray(scip, &cols);
3953  return SCIP_INVALIDDATA;
3954  }
3955  }
3956 
3957  /* check if the solving process should be aborted */
3958  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3959  {
3960  /* mark this as if the LP failed */
3961  *lperror = TRUE;
3962  }
3963  else
3964  {
3965  /* call strong branching for columns */
3966  SCIP_CALL( SCIPcolGetStrongbranches(cols, nvars, TRUE, scip->set, scip->stat, scip->transprob, scip->lp, itlim,
3967  down, up, downvalid, upvalid, lperror) );
3968 
3969  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3970  * declare the sub nodes infeasible
3971  */
3972  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3973  {
3974  for( j = 0; j < nvars; ++j )
3975  {
3976  SCIP_CALL( analyzeStrongbranch(scip, vars[j], (downinf != NULL) ? (&(downinf[j])) : NULL,
3977  (upinf != NULL) ? (&(upinf[j])) : NULL, (downconflict != NULL) ? (&(downconflict[j])) : NULL,
3978  (upconflict != NULL) ? (&(upconflict[j])) : NULL) );
3979  }
3980  }
3981  }
3982  SCIPfreeBufferArray(scip, &cols);
3983 
3984  return SCIP_OKAY;
3985 }
3986 
3987 /** get LP solution status of last strong branching call (currently only works for strong branching with propagation) */
3989  SCIP* scip, /**< SCIP data structure */
3990  SCIP_BRANCHDIR branchdir /**< branching direction for which LP solution status is requested */
3991  )
3992 {
3993  assert(NULL != scip);
3994  assert(branchdir == SCIP_BRANCHDIR_DOWNWARDS || branchdir == SCIP_BRANCHDIR_UPWARDS);
3995 
3996  return scip->stat->lastsblpsolstats[branchdir == SCIP_BRANCHDIR_DOWNWARDS ? 0 : 1];
3997 }
3998 
3999 /** gets strong branching information on COLUMN variable of the last SCIPgetVarStrongbranch() call;
4000  * returns values of SCIP_INVALID, if strong branching was not yet called on the given variable;
4001  * keep in mind, that the returned old values may have nothing to do with the current LP solution
4002  *
4003  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4004  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4005  *
4006  * @pre This method can be called if @p scip is in one of the following stages:
4007  * - \ref SCIP_STAGE_SOLVING
4008  * - \ref SCIP_STAGE_SOLVED
4009  */
4011  SCIP* scip, /**< SCIP data structure */
4012  SCIP_VAR* var, /**< variable to get last strong branching values for */
4013  SCIP_Real* down, /**< stores dual bound after branching column down */
4014  SCIP_Real* up, /**< stores dual bound after branching column up */
4015  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4016  * otherwise, it can only be used as an estimate value */
4017  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4018  * otherwise, it can only be used as an estimate value */
4019  SCIP_Real* solval, /**< stores LP solution value of variable at the last strong branching call, or NULL */
4020  SCIP_Real* lpobjval /**< stores LP objective value at last strong branching call, or NULL */
4021  )
4022 {
4023  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchLast", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
4024 
4026  {
4027  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable\n");
4028  return SCIP_INVALIDDATA;
4029  }
4030 
4031  SCIPcolGetStrongbranchLast(SCIPvarGetCol(var), down, up, downvalid, upvalid, solval, lpobjval);
4032 
4033  return SCIP_OKAY;
4034 }
4035 
4036 /** sets strong branching information for a column variable
4037  *
4038  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4039  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4040  *
4041  * @pre This method can be called if @p scip is in one of the following stages:
4042  * - \ref SCIP_STAGE_SOLVING
4043  */
4045  SCIP* scip, /**< SCIP data structure */
4046  SCIP_VAR* var, /**< variable to set last strong branching values for */
4047  SCIP_Real lpobjval, /**< objective value of the current LP */
4048  SCIP_Real primsol, /**< primal solution value of the column in the current LP */
4049  SCIP_Real down, /**< dual bound after branching column down */
4050  SCIP_Real up, /**< dual bound after branching column up */
4051  SCIP_Bool downvalid, /**< is the returned down value a valid dual bound? */
4052  SCIP_Bool upvalid, /**< is the returned up value a valid dual bound? */
4053  SCIP_Longint iter, /**< total number of strong branching iterations */
4054  int itlim /**< iteration limit applied to the strong branching call */
4055  )
4056 {
4057  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetVarStrongbranchData", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4058 
4060  {
4061  SCIPerrorMessage("cannot set strong branching information on non-COLUMN variable\n");
4062  return SCIP_INVALIDDATA;
4063  }
4064 
4065  SCIPcolSetStrongbranchData(SCIPvarGetCol(var), scip->set, scip->stat, scip->lp, lpobjval, primsol,
4066  down, up, downvalid, upvalid, iter, itlim);
4067 
4068  return SCIP_OKAY;
4069 }
4070 
4071 /** rounds the current solution and tries it afterwards; if feasible, adds it to storage
4072  *
4073  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4074  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4075  *
4076  * @pre This method can be called if @p scip is in one of the following stages:
4077  * - \ref SCIP_STAGE_SOLVING
4078  */
4080  SCIP* scip, /**< SCIP data structure */
4081  SCIP_Bool* foundsol, /**< stores whether solution was feasible and good enough to keep */
4082  SCIP_Bool* cutoff /**< stores whether solution was cutoff due to exceeding the cutoffbound */
4083  )
4084 {
4085  assert(scip != NULL);
4086  assert(foundsol != NULL);
4087  assert(cutoff != NULL);
4088 
4089  SCIP_CALL( SCIPcheckStage(scip, "SCIPtryStrongbranchLPSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4090 
4091  if( scip->set->branch_checksbsol )
4092  {
4093  SCIP_SOL* sol;
4094  SCIP_Bool rounded = TRUE;
4095  SCIP_Real value = SCIPgetLPObjval(scip);
4096  SCIP_Longint oldnbestsolsfound = scip->primal->nbestsolsfound;
4097 
4098  /* start clock for strong branching solutions */
4099  SCIPclockStart(scip->stat->sbsoltime, scip->set);
4100 
4101  SCIP_CALL( SCIPcreateLPSol(scip, &sol, NULL) );
4103 
4104  /* try to round the strong branching solution */
4105  if( scip->set->branch_roundsbsol )
4106  {
4107  SCIP_CALL( SCIProundSol(scip, sol, &rounded) );
4108  }
4109 
4110  /* check the solution for feasibility if rounding worked well (or was not tried) */
4111  if( rounded )
4112  {
4113  SCIP_CALL( SCIPtrySolFree(scip, &sol, FALSE, FALSE, FALSE, TRUE, FALSE, foundsol) );
4114  }
4115  else
4116  {
4117  SCIP_CALL( SCIPfreeSol(scip, &sol) );
4118  }
4119 
4120  if( *foundsol )
4121  {
4122  SCIPdebugMsg(scip, "found new solution in strong branching\n");
4123 
4124  scip->stat->nsbsolsfound++;
4125 
4126  if( scip->primal->nbestsolsfound != oldnbestsolsfound )
4127  {
4128  scip->stat->nsbbestsolsfound++;
4129  }
4130 
4131  if( SCIPisGE(scip, value, SCIPgetCutoffbound(scip)) )
4132  *cutoff = TRUE;
4133  }
4134 
4135  /* stop clock for strong branching solutions */
4136  SCIPclockStop(scip->stat->sbsoltime, scip->set);
4137  }
4138  return SCIP_OKAY;
4139 }
4140 
4141 
4142 /** gets node number of the last node in current branch and bound run, where strong branching was used on the
4143  * given variable, or -1 if strong branching was never applied to the variable in current run
4144  *
4145  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4146  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4147  *
4148  * @pre This method can be called if @p scip is in one of the following stages:
4149  * - \ref SCIP_STAGE_TRANSFORMING
4150  * - \ref SCIP_STAGE_TRANSFORMED
4151  * - \ref SCIP_STAGE_INITPRESOLVE
4152  * - \ref SCIP_STAGE_PRESOLVING
4153  * - \ref SCIP_STAGE_EXITPRESOLVE
4154  * - \ref SCIP_STAGE_PRESOLVED
4155  * - \ref SCIP_STAGE_INITSOLVE
4156  * - \ref SCIP_STAGE_SOLVING
4157  * - \ref SCIP_STAGE_SOLVED
4158  * - \ref SCIP_STAGE_EXITSOLVE
4159  */
4161  SCIP* scip, /**< SCIP data structure */
4162  SCIP_VAR* var /**< variable to get last strong branching node for */
4163  )
4164 {
4165  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarStrongbranchNode", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4166 
4167  assert( var->scip == scip );
4168 
4170  return -1;
4171 
4173 }
4174 
4175 /** if strong branching was already applied on the variable at the current node, returns the number of LPs solved after
4176  * the LP where the strong branching on this variable was applied;
4177  * if strong branching was not yet applied on the variable at the current node, returns INT_MAX
4178  *
4179  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4180  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4181  *
4182  * @pre This method can be called if @p scip is in one of the following stages:
4183  * - \ref SCIP_STAGE_TRANSFORMING
4184  * - \ref SCIP_STAGE_TRANSFORMED
4185  * - \ref SCIP_STAGE_INITPRESOLVE
4186  * - \ref SCIP_STAGE_PRESOLVING
4187  * - \ref SCIP_STAGE_EXITPRESOLVE
4188  * - \ref SCIP_STAGE_PRESOLVED
4189  * - \ref SCIP_STAGE_INITSOLVE
4190  * - \ref SCIP_STAGE_SOLVING
4191  * - \ref SCIP_STAGE_SOLVED
4192  * - \ref SCIP_STAGE_EXITSOLVE
4193  */
4195  SCIP* scip, /**< SCIP data structure */
4196  SCIP_VAR* var /**< variable to get strong branching LP age for */
4197  )
4198 {
4199  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarStrongbranchLPAge", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4200 
4201  assert( var->scip == scip );
4202 
4204  return SCIP_LONGINT_MAX;
4205 
4206  return SCIPcolGetStrongbranchLPAge(SCIPvarGetCol(var), scip->stat);
4207 }
4208 
4209 /** gets number of times, strong branching was applied in current run on the given variable
4210  *
4211  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4212  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4213  *
4214  * @pre This method can be called if @p scip is in one of the following stages:
4215  * - \ref SCIP_STAGE_TRANSFORMING
4216  * - \ref SCIP_STAGE_TRANSFORMED
4217  * - \ref SCIP_STAGE_INITPRESOLVE
4218  * - \ref SCIP_STAGE_PRESOLVING
4219  * - \ref SCIP_STAGE_EXITPRESOLVE
4220  * - \ref SCIP_STAGE_PRESOLVED
4221  * - \ref SCIP_STAGE_INITSOLVE
4222  * - \ref SCIP_STAGE_SOLVING
4223  * - \ref SCIP_STAGE_SOLVED
4224  * - \ref SCIP_STAGE_EXITSOLVE
4225  */
4227  SCIP* scip, /**< SCIP data structure */
4228  SCIP_VAR* var /**< variable to get last strong branching node for */
4229  )
4230 {
4231  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarNStrongbranchs", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4232 
4233  assert( var->scip == scip );
4234 
4236  return 0;
4237 
4239 }
4240 
4241 /** adds given values to lock numbers of type @p locktype of variable for rounding
4242  *
4243  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4244  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4245  *
4246  * @pre This method can be called if @p scip is in one of the following stages:
4247  * - \ref SCIP_STAGE_PROBLEM
4248  * - \ref SCIP_STAGE_TRANSFORMING
4249  * - \ref SCIP_STAGE_TRANSFORMED
4250  * - \ref SCIP_STAGE_INITPRESOLVE
4251  * - \ref SCIP_STAGE_PRESOLVING
4252  * - \ref SCIP_STAGE_EXITPRESOLVE
4253  * - \ref SCIP_STAGE_PRESOLVED
4254  * - \ref SCIP_STAGE_INITSOLVE
4255  * - \ref SCIP_STAGE_SOLVING
4256  * - \ref SCIP_STAGE_EXITSOLVE
4257  * - \ref SCIP_STAGE_FREETRANS
4258  */
4260  SCIP* scip, /**< SCIP data structure */
4261  SCIP_VAR* var, /**< problem variable */
4262  SCIP_LOCKTYPE locktype, /**< type of the variable locks */
4263  int nlocksdown, /**< modification in number of rounding down locks */
4264  int nlocksup /**< modification in number of rounding up locks */
4265  )
4266 {
4267  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarLocksType", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4268 
4269  assert( var->scip == scip );
4270 
4271  switch( scip->set->stage )
4272  {
4273  case SCIP_STAGE_PROBLEM:
4274  assert(!SCIPvarIsTransformed(var));
4275  /*lint -fallthrough*/
4279  case SCIP_STAGE_PRESOLVING:
4281  case SCIP_STAGE_PRESOLVED:
4282  case SCIP_STAGE_INITSOLVE:
4283  case SCIP_STAGE_SOLVING:
4284  case SCIP_STAGE_EXITSOLVE:
4285  case SCIP_STAGE_FREETRANS:
4286  SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, locktype, nlocksdown, nlocksup) );
4287  return SCIP_OKAY;
4288 
4289  default:
4290  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4291  return SCIP_INVALIDCALL;
4292  } /*lint !e788*/
4293 }
4294 
4295 /** adds given values to lock numbers of variable for rounding
4296  *
4297  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4298  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4299  *
4300  * @pre This method can be called if @p scip is in one of the following stages:
4301  * - \ref SCIP_STAGE_PROBLEM
4302  * - \ref SCIP_STAGE_TRANSFORMING
4303  * - \ref SCIP_STAGE_TRANSFORMED
4304  * - \ref SCIP_STAGE_INITPRESOLVE
4305  * - \ref SCIP_STAGE_PRESOLVING
4306  * - \ref SCIP_STAGE_EXITPRESOLVE
4307  * - \ref SCIP_STAGE_PRESOLVED
4308  * - \ref SCIP_STAGE_INITSOLVE
4309  * - \ref SCIP_STAGE_SOLVING
4310  * - \ref SCIP_STAGE_EXITSOLVE
4311  * - \ref SCIP_STAGE_FREETRANS
4312  *
4313  * @note This method will always add variable locks of type model
4314  *
4315  * @note It is recommented to use SCIPaddVarLocksType()
4316  */
4318  SCIP* scip, /**< SCIP data structure */
4319  SCIP_VAR* var, /**< problem variable */
4320  int nlocksdown, /**< modification in number of rounding down locks */
4321  int nlocksup /**< modification in number of rounding up locks */
4322  )
4323 {
4324  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarLocks", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4325 
4326  SCIP_CALL( SCIPaddVarLocksType(scip, var, SCIP_LOCKTYPE_MODEL, nlocksdown, nlocksup) );
4327 
4328  return SCIP_OKAY;
4329 }
4330 
4331 /** add locks of variable with respect to the lock status of the constraint and its negation;
4332  * this method should be called whenever the lock status of a variable in a constraint changes, for example if
4333  * the coefficient of the variable changed its sign or if the left or right hand sides of the constraint were
4334  * added or removed
4335  *
4336  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4337  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4338  *
4339  * @pre This method can be called if @p scip is in one of the following stages:
4340  * - \ref SCIP_STAGE_PROBLEM
4341  * - \ref SCIP_STAGE_TRANSFORMING
4342  * - \ref SCIP_STAGE_TRANSFORMED
4343  * - \ref SCIP_STAGE_INITPRESOLVE
4344  * - \ref SCIP_STAGE_PRESOLVING
4345  * - \ref SCIP_STAGE_EXITPRESOLVE
4346  * - \ref SCIP_STAGE_INITSOLVE
4347  * - \ref SCIP_STAGE_SOLVING
4348  * - \ref SCIP_STAGE_EXITSOLVE
4349  * - \ref SCIP_STAGE_FREETRANS
4350  */
4352  SCIP* scip, /**< SCIP data structure */
4353  SCIP_VAR* var, /**< problem variable */
4354  SCIP_CONS* cons, /**< constraint */
4355  SCIP_Bool lockdown, /**< should the rounding be locked in downwards direction? */
4356  SCIP_Bool lockup /**< should the rounding be locked in upwards direction? */
4357  )
4358 {
4359  int nlocksdown[NLOCKTYPES];
4360  int nlocksup[NLOCKTYPES];
4361  int i;
4362 
4363  SCIP_CALL( SCIPcheckStage(scip, "SCIPlockVarCons", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4364 
4365  assert( var->scip == scip );
4366 
4367  for( i = 0; i < NLOCKTYPES; i++ )
4368  {
4369  nlocksdown[i] = 0;
4370  nlocksup[i] = 0;
4371 
4372  if( SCIPconsIsLockedTypePos(cons, (SCIP_LOCKTYPE) i) )
4373  {
4374  if( lockdown )
4375  ++nlocksdown[i];
4376  if( lockup )
4377  ++nlocksup[i];
4378  }
4379  if( SCIPconsIsLockedTypeNeg(cons, (SCIP_LOCKTYPE) i) )
4380  {
4381  if( lockdown )
4382  ++nlocksup[i];
4383  if( lockup )
4384  ++nlocksdown[i];
4385  }
4386  }
4387 
4388  switch( scip->set->stage )
4389  {
4390  case SCIP_STAGE_PROBLEM:
4391  assert(!SCIPvarIsTransformed(var));
4392  /*lint -fallthrough*/
4396  case SCIP_STAGE_PRESOLVING:
4398  case SCIP_STAGE_INITSOLVE:
4399  case SCIP_STAGE_SOLVING:
4400  case SCIP_STAGE_EXITSOLVE:
4401  case SCIP_STAGE_FREETRANS:
4402  for( i = 0; i < NLOCKTYPES; i++ )
4403  {
4404  if( nlocksdown[i] == 0 && nlocksup[i] == 0 )
4405  continue;
4406 
4407  SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, (SCIP_LOCKTYPE) i, nlocksdown[i], nlocksup[i]) );
4408  }
4409  return SCIP_OKAY;
4410 
4411  default:
4412  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4413  return SCIP_INVALIDCALL;
4414  } /*lint !e788*/
4415 }
4416 
4417 /** remove locks of type @p locktype of variable with respect to the lock status of the constraint and its negation;
4418  * this method should be called whenever the lock status of a variable in a constraint changes, for example if
4419  * the coefficient of the variable changed its sign or if the left or right hand sides of the constraint were
4420  * added or removed
4421  *
4422  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4423  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4424  *
4425  * @pre This method can be called if @p scip is in one of the following stages:
4426  * - \ref SCIP_STAGE_PROBLEM
4427  * - \ref SCIP_STAGE_TRANSFORMING
4428  * - \ref SCIP_STAGE_TRANSFORMED
4429  * - \ref SCIP_STAGE_INITPRESOLVE
4430  * - \ref SCIP_STAGE_PRESOLVING
4431  * - \ref SCIP_STAGE_EXITPRESOLVE
4432  * - \ref SCIP_STAGE_INITSOLVE
4433  * - \ref SCIP_STAGE_SOLVING
4434  * - \ref SCIP_STAGE_EXITSOLVE
4435  * - \ref SCIP_STAGE_FREETRANS
4436  */
4438  SCIP* scip, /**< SCIP data structure */
4439  SCIP_VAR* var, /**< problem variable */
4440  SCIP_CONS* cons, /**< constraint */
4441  SCIP_Bool lockdown, /**< should the rounding be unlocked in downwards direction? */
4442  SCIP_Bool lockup /**< should the rounding be unlocked in upwards direction? */
4443  )
4444 {
4445  int nlocksdown[NLOCKTYPES];
4446  int nlocksup[NLOCKTYPES];
4447  int i;
4448 
4449  SCIP_CALL( SCIPcheckStage(scip, "SCIPunlockVarCons", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4450 
4451  assert( var->scip == scip );
4452 
4453  for( i = 0; i < NLOCKTYPES; i++ )
4454  {
4455  nlocksdown[i] = 0;
4456  nlocksup[i] = 0;
4457 
4458  if( SCIPconsIsLockedTypePos(cons, (SCIP_LOCKTYPE) i) )
4459  {
4460  if( lockdown )
4461  ++nlocksdown[i];
4462  if( lockup )
4463  ++nlocksup[i];
4464  }
4465  if( SCIPconsIsLockedTypeNeg(cons, (SCIP_LOCKTYPE) i) )
4466  {
4467  if( lockdown )
4468  ++nlocksup[i];
4469  if( lockup )
4470  ++nlocksdown[i];
4471  }
4472  }
4473  switch( scip->set->stage )
4474  {
4475  case SCIP_STAGE_PROBLEM:
4476  assert(!SCIPvarIsTransformed(var));
4477  /*lint -fallthrough*/
4481  case SCIP_STAGE_PRESOLVING:
4483  case SCIP_STAGE_INITSOLVE:
4484  case SCIP_STAGE_SOLVING:
4485  case SCIP_STAGE_EXITSOLVE:
4486  case SCIP_STAGE_FREETRANS:
4487  for( i = 0; i < NLOCKTYPES; i++ )
4488  {
4489  if( nlocksdown[i] == 0 && nlocksup[i] == 0 )
4490  continue;
4491 
4492  SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, (SCIP_LOCKTYPE) i, -nlocksdown[i], -nlocksup[i]) );
4493  }
4494  return SCIP_OKAY;
4495 
4496  default:
4497  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4498  return SCIP_INVALIDCALL;
4499  } /*lint !e788*/
4500 }
4501 
4502 /** changes variable's objective value
4503  *
4504  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4505  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4506  *
4507  * @pre This method can be called if @p scip is in one of the following stages:
4508  * - \ref SCIP_STAGE_PROBLEM
4509  * - \ref SCIP_STAGE_TRANSFORMING
4510  * - \ref SCIP_STAGE_PRESOLVING
4511  * - \ref SCIP_STAGE_PRESOLVED
4512  */
4514  SCIP* scip, /**< SCIP data structure */
4515  SCIP_VAR* var, /**< variable to change the objective value for */
4516  SCIP_Real newobj /**< new objective value */
4517  )
4518 {
4519  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarObj", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
4520 
4521  assert( var->scip == scip );
4522 
4523  /* forbid infinite objective values */
4524  if( SCIPisInfinity(scip, REALABS(newobj)) )
4525  {
4526  SCIPerrorMessage("invalid objective value: objective value is infinite\n");
4527  return SCIP_INVALIDDATA;
4528  }
4529 
4530  switch( scip->set->stage )
4531  {
4532  case SCIP_STAGE_PROBLEM:
4533  assert(!SCIPvarIsTransformed(var));
4534  SCIP_CALL( SCIPvarChgObj(var, scip->mem->probmem, scip->set, scip->origprob, scip->primal, scip->lp, scip->eventqueue, newobj) );
4535  return SCIP_OKAY;
4536 
4539  case SCIP_STAGE_PRESOLVING:
4540  case SCIP_STAGE_PRESOLVED:
4541  SCIP_CALL( SCIPvarChgObj(var, scip->mem->probmem, scip->set, scip->transprob, scip->primal, scip->lp, scip->eventqueue, newobj) );
4542  return SCIP_OKAY;
4543 
4544  default:
4545  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4546  return SCIP_INVALIDCALL;
4547  } /*lint !e788*/
4548 }
4549 
4550 /** adds value to variable's objective value
4551  *
4552  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4553  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4554  *
4555  * @pre This method can be called if @p scip is in one of the following stages:
4556  * - \ref SCIP_STAGE_PROBLEM
4557  * - \ref SCIP_STAGE_TRANSFORMING
4558  * - \ref SCIP_STAGE_PRESOLVING
4559  * - \ref SCIP_STAGE_EXITPRESOLVE
4560  * - \ref SCIP_STAGE_PRESOLVED
4561  */
4563  SCIP* scip, /**< SCIP data structure */
4564  SCIP_VAR* var, /**< variable to change the objective value for */
4565  SCIP_Real addobj /**< additional objective value */
4566  )
4567 {
4568  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarObj", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
4569 
4570  assert( var->scip == scip );
4571 
4572  switch( scip->set->stage )
4573  {
4574  case SCIP_STAGE_PROBLEM:
4575  assert(!SCIPvarIsTransformed(var));
4576  SCIP_CALL( SCIPvarAddObj(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->primal,
4577  scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue, addobj) );
4578  return SCIP_OKAY;
4579 
4581  case SCIP_STAGE_PRESOLVING:
4583  case SCIP_STAGE_PRESOLVED:
4584  SCIP_CALL( SCIPvarAddObj(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->primal,
4585  scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue, addobj) );
4586  return SCIP_OKAY;
4587 
4588  default:
4589  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4590  return SCIP_INVALIDCALL;
4591  } /*lint !e788*/
4592 }
4593 
4594 /** returns the adjusted (i.e. rounded, if the given variable is of integral type) lower bound value;
4595  * does not change the bounds of the variable
4596  *
4597  * @return adjusted lower bound for the given variable; the bound of the variable is not changed
4598  *
4599  * @pre This method can be called if @p scip is in one of the following stages:
4600  * - \ref SCIP_STAGE_PROBLEM
4601  * - \ref SCIP_STAGE_TRANSFORMING
4602  * - \ref SCIP_STAGE_TRANSFORMED
4603  * - \ref SCIP_STAGE_INITPRESOLVE
4604  * - \ref SCIP_STAGE_PRESOLVING
4605  * - \ref SCIP_STAGE_EXITPRESOLVE
4606  * - \ref SCIP_STAGE_PRESOLVED
4607  * - \ref SCIP_STAGE_INITSOLVE
4608  * - \ref SCIP_STAGE_SOLVING
4609  * - \ref SCIP_STAGE_SOLVED
4610  * - \ref SCIP_STAGE_EXITSOLVE
4611  * - \ref SCIP_STAGE_FREETRANS
4612  */
4614  SCIP* scip, /**< SCIP data structure */
4615  SCIP_VAR* var, /**< variable to adjust the bound for */
4616  SCIP_Real lb /**< lower bound value to adjust */
4617  )
4618 {
4619  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPadjustedVarLb", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
4620 
4621  SCIPvarAdjustLb(var, scip->set, &lb);
4622 
4623  return lb;
4624 }
4625 
4626 /** returns the adjusted (i.e. rounded, if the given variable is of integral type) upper bound value;
4627  * does not change the bounds of the variable
4628  *
4629  * @return adjusted upper bound for the given variable; the bound of the variable is not changed
4630  *
4631  * @pre This method can be called if @p scip is in one of the following stages:
4632  * - \ref SCIP_STAGE_PROBLEM
4633  * - \ref SCIP_STAGE_TRANSFORMING
4634  * - \ref SCIP_STAGE_TRANSFORMED
4635  * - \ref SCIP_STAGE_INITPRESOLVE
4636  * - \ref SCIP_STAGE_PRESOLVING
4637  * - \ref SCIP_STAGE_EXITPRESOLVE
4638  * - \ref SCIP_STAGE_PRESOLVED
4639  * - \ref SCIP_STAGE_INITSOLVE
4640  * - \ref SCIP_STAGE_SOLVING
4641  * - \ref SCIP_STAGE_SOLVED
4642  * - \ref SCIP_STAGE_EXITSOLVE
4643  * - \ref SCIP_STAGE_FREETRANS
4644  */
4646  SCIP* scip, /**< SCIP data structure */
4647  SCIP_VAR* var, /**< variable to adjust the bound for */
4648  SCIP_Real ub /**< upper bound value to adjust */
4649  )
4650 {
4651  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPadjustedVarUb", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
4652 
4653  SCIPvarAdjustUb(var, scip->set, &ub);
4654 
4655  return ub;
4656 }
4657 
4658 /** depending on SCIP's stage, changes lower bound of variable in the problem, in preprocessing, or in current node;
4659  * if possible, adjusts bound to integral value; doesn't store any inference information in the bound change, such
4660  * that in conflict analysis, this change is treated like a branching decision
4661  *
4662  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4663  * SCIPgetVars()) gets resorted.
4664  *
4665  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4666  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4667  *
4668  * @pre This method can be called if @p scip is in one of the following stages:
4669  * - \ref SCIP_STAGE_PROBLEM
4670  * - \ref SCIP_STAGE_TRANSFORMING
4671  * - \ref SCIP_STAGE_PRESOLVING
4672  * - \ref SCIP_STAGE_SOLVING
4673  *
4674  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4675  */
4677  SCIP* scip, /**< SCIP data structure */
4678  SCIP_VAR* var, /**< variable to change the bound for */
4679  SCIP_Real newbound /**< new value for bound */
4680  )
4681 {
4682  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLb", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4683 
4684  SCIPvarAdjustLb(var, scip->set, &newbound);
4685 
4686  /* ignore tightenings of lower bounds to +infinity during solving process */
4687  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4688  {
4689 #ifndef NDEBUG
4690  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4691  SCIPvarGetLbLocal(var));
4692 #endif
4693  return SCIP_OKAY;
4694  }
4695 
4696  switch( scip->set->stage )
4697  {
4698  case SCIP_STAGE_PROBLEM:
4699  assert(!SCIPvarIsTransformed(var));
4700  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4701  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4702  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4703  scip->branchcand, scip->eventqueue, newbound) );
4704  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
4705  break;
4706 
4708  case SCIP_STAGE_PRESOLVED:
4709  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4710  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4711  break;
4712 
4713  case SCIP_STAGE_PRESOLVING:
4714  if( !SCIPinProbing(scip) )
4715  {
4716  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4717  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4718 
4719  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4720  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable,
4721  var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
4722 
4724  {
4725  SCIP_Bool infeasible;
4726 
4727  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
4728  assert(!infeasible);
4729  }
4730  break;
4731  }
4732  /*lint -fallthrough*/
4733  case SCIP_STAGE_SOLVING:
4735  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4736  scip->cliquetable, var, newbound,
4738  break;
4739 
4740  default:
4741  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4742  return SCIP_INVALIDCALL;
4743  } /*lint !e788*/
4744 
4745  return SCIP_OKAY;
4746 }
4747 
4748 /** depending on SCIP's stage, changes upper bound of variable in the problem, in preprocessing, or in current node;
4749  * if possible, adjusts bound to integral value; doesn't store any inference information in the bound change, such
4750  * that in conflict analysis, this change is treated like a branching decision
4751  *
4752  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4753  * SCIPgetVars()) gets resorted.
4754  *
4755  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4756  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4757  *
4758  * @pre This method can be called if @p scip is in one of the following stages:
4759  * - \ref SCIP_STAGE_PROBLEM
4760  * - \ref SCIP_STAGE_TRANSFORMING
4761  * - \ref SCIP_STAGE_PRESOLVING
4762  * - \ref SCIP_STAGE_SOLVING
4763  *
4764  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4765  */
4767  SCIP* scip, /**< SCIP data structure */
4768  SCIP_VAR* var, /**< variable to change the bound for */
4769  SCIP_Real newbound /**< new value for bound */
4770  )
4771 {
4772  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUb", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4773 
4774  SCIPvarAdjustUb(var, scip->set, &newbound);
4775 
4776  /* ignore tightenings of upper bounds to -infinity during solving process */
4777  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4778  {
4779 #ifndef NDEBUG
4780  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
4781  SCIPvarGetUbLocal(var));
4782 #endif
4783  return SCIP_OKAY;
4784  }
4785 
4786  switch( scip->set->stage )
4787  {
4788  case SCIP_STAGE_PROBLEM:
4789  assert(!SCIPvarIsTransformed(var));
4790  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4791  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4792  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4793  scip->branchcand, scip->eventqueue, newbound) );
4794  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
4795  break;
4796 
4798  case SCIP_STAGE_PRESOLVED:
4799  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4800  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4801  break;
4802 
4803  case SCIP_STAGE_PRESOLVING:
4804  if( !SCIPinProbing(scip) )
4805  {
4806  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4807  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4808 
4809  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4810  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4811  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
4812 
4814  {
4815  SCIP_Bool infeasible;
4816 
4817  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
4818  assert(!infeasible);
4819  }
4820  break;
4821  }
4822  /*lint -fallthrough*/
4823  case SCIP_STAGE_SOLVING:
4825  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4826  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
4827  break;
4828 
4829  default:
4830  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4831  return SCIP_INVALIDCALL;
4832  } /*lint !e788*/
4833 
4834  return SCIP_OKAY;
4835 }
4836 
4837 /** changes lower bound of variable in the given node; if possible, adjust bound to integral value; doesn't store any
4838  * inference information in the bound change, such that in conflict analysis, this change is treated like a branching
4839  * decision
4840  *
4841  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4842  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4843  *
4844  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
4845  */
4847  SCIP* scip, /**< SCIP data structure */
4848  SCIP_NODE* node, /**< node to change bound at, or NULL for current node */
4849  SCIP_VAR* var, /**< variable to change the bound for */
4850  SCIP_Real newbound /**< new value for bound */
4851  )
4852 {
4853  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbNode", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4854 
4855  if( node == NULL )
4856  {
4857  SCIP_CALL( SCIPchgVarLb(scip, var, newbound) );
4858  }
4859  else
4860  {
4861  SCIPvarAdjustLb(var, scip->set, &newbound);
4862 
4863  /* ignore tightenings of lower bounds to +infinity during solving process */
4864  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4865  {
4866 #ifndef NDEBUG
4867  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4868  SCIPvarGetLbLocal(var));
4869 #endif
4870  return SCIP_OKAY;
4871  }
4872 
4873  SCIP_CALL( SCIPnodeAddBoundchg(node, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
4874  scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4876  }
4877 
4878  return SCIP_OKAY;
4879 }
4880 
4881 /** changes upper bound of variable in the given node; if possible, adjust bound to integral value; doesn't store any
4882  * inference information in the bound change, such that in conflict analysis, this change is treated like a branching
4883  * decision
4884  *
4885  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4886  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4887  *
4888  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
4889  */
4891  SCIP* scip, /**< SCIP data structure */
4892  SCIP_NODE* node, /**< node to change bound at, or NULL for current node */
4893  SCIP_VAR* var, /**< variable to change the bound for */
4894  SCIP_Real newbound /**< new value for bound */
4895  )
4896 {
4897  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbNode", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4898 
4899  if( node == NULL )
4900  {
4901  SCIP_CALL( SCIPchgVarUb(scip, var, newbound) );
4902  }
4903  else
4904  {
4905  SCIPvarAdjustUb(var, scip->set, &newbound);
4906 
4907  /* ignore tightenings of upper bounds to -infinity during solving process */
4908  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4909  {
4910 #ifndef NDEBUG
4911  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
4912  SCIPvarGetUbLocal(var));
4913 #endif
4914  return SCIP_OKAY;
4915  }
4916 
4917  SCIP_CALL( SCIPnodeAddBoundchg(node, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
4918  scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4920  }
4921 
4922  return SCIP_OKAY;
4923 }
4924 
4925 /** changes global lower bound of variable; if possible, adjust bound to integral value; also tightens the local bound,
4926  * if the global bound is better than the local bound
4927  *
4928  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4929  * SCIPgetVars()) gets resorted.
4930  *
4931  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4932  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4933  *
4934  * @pre This method can be called if @p scip is in one of the following stages:
4935  * - \ref SCIP_STAGE_PROBLEM
4936  * - \ref SCIP_STAGE_TRANSFORMING
4937  * - \ref SCIP_STAGE_TRANSFORMED
4938  * - \ref SCIP_STAGE_PRESOLVING
4939  * - \ref SCIP_STAGE_SOLVING
4940  *
4941  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4942  */
4944  SCIP* scip, /**< SCIP data structure */
4945  SCIP_VAR* var, /**< variable to change the bound for */
4946  SCIP_Real newbound /**< new value for bound */
4947  )
4948 {
4949  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbGlobal", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4950 
4951  SCIPvarAdjustLb(var, scip->set, &newbound);
4952 
4953  /* ignore tightenings of lower bounds to +infinity during solving process */
4954  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4955  {
4956 #ifndef NDEBUG
4957  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4958  SCIPvarGetLbLocal(var));
4959 #endif
4960  return SCIP_OKAY;
4961  }
4962 
4963  switch( scip->set->stage )
4964  {
4965  case SCIP_STAGE_PROBLEM:
4966  assert(!SCIPvarIsTransformed(var));
4967  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4968  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4969  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4970  scip->branchcand, scip->eventqueue, newbound) );
4971  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
4972  break;
4973 
4976  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4977  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4978  break;
4979 
4980  case SCIP_STAGE_PRESOLVING:
4981  if( !SCIPinProbing(scip) )
4982  {
4983  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4984  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4985 
4986  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4987  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4989 
4991  {
4992  SCIP_Bool infeasible;
4993 
4994  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
4995  assert(!infeasible);
4996  }
4997  break;
4998  }
4999  /*lint -fallthrough*/
5000  case SCIP_STAGE_SOLVING:
5001  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5002  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5004  break;
5005 
5006  default:
5007  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5008  return SCIP_INVALIDCALL;
5009  } /*lint !e788*/
5010 
5011  return SCIP_OKAY;
5012 }
5013 
5014 /** changes global upper bound of variable; if possible, adjust bound to integral value; also tightens the local bound,
5015  * if the global bound is better than the local bound
5016  *
5017  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5018  * SCIPgetVars()) gets resorted.
5019  *
5020  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5021  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5022  *
5023  * @pre This method can be called if @p scip is in one of the following stages:
5024  * - \ref SCIP_STAGE_PROBLEM
5025  * - \ref SCIP_STAGE_TRANSFORMING
5026  * - \ref SCIP_STAGE_TRANSFORMED
5027  * - \ref SCIP_STAGE_PRESOLVING
5028  * - \ref SCIP_STAGE_SOLVING
5029  *
5030  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5031  */
5033  SCIP* scip, /**< SCIP data structure */
5034  SCIP_VAR* var, /**< variable to change the bound for */
5035  SCIP_Real newbound /**< new value for bound */
5036  )
5037 {
5038  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbGlobal", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5039 
5040  SCIPvarAdjustUb(var, scip->set, &newbound);
5041 
5042  /* ignore tightenings of upper bounds to -infinity during solving process */
5043  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5044  {
5045 #ifndef NDEBUG
5046  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5047  SCIPvarGetUbLocal(var));
5048 #endif
5049  return SCIP_OKAY;
5050  }
5051 
5052  switch( scip->set->stage )
5053  {
5054  case SCIP_STAGE_PROBLEM:
5055  assert(!SCIPvarIsTransformed(var));
5056  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5057  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5058  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5059  scip->branchcand, scip->eventqueue, newbound) );
5060  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
5061  break;
5062 
5065  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5066  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5067  break;
5068 
5069  case SCIP_STAGE_PRESOLVING:
5070  if( !SCIPinProbing(scip) )
5071  {
5072  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5073  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5074 
5075  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5076  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5078 
5080  {
5081  SCIP_Bool infeasible;
5082 
5083  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
5084  assert(!infeasible);
5085  }
5086  break;
5087  }
5088  /*lint -fallthrough*/
5089  case SCIP_STAGE_SOLVING:
5090  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5091  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5093  break;
5094 
5095  default:
5096  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5097  return SCIP_INVALIDCALL;
5098  } /*lint !e788*/
5099 
5100  return SCIP_OKAY;
5101 }
5102 
5103 /** changes lazy lower bound of the variable, this is only possible if the variable is not in the LP yet
5104  *
5105  * Lazy bounds are bounds that are already enforced by constraints and the objective function.
5106  * Setting a lazy lower bound has the consequence that for variables which lower bound equals the lazy lower bound,
5107  * the lower bound does not need to be passed on to the LP solver.
5108  * This is especially useful in a column generation (branch-and-price) setting.
5109  *
5110  * @attention If the variable has a global lower bound below lazylb, then the global lower bound is tightened to
5111  * lazylb by a call to SCIPchgVarLbGlobal().
5112  *
5113  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5114  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5115  *
5116  * @pre This method can be called if @p scip is in one of the following stages:
5117  * - \ref SCIP_STAGE_PROBLEM
5118  * - \ref SCIP_STAGE_TRANSFORMING
5119  * - \ref SCIP_STAGE_TRANSFORMED
5120  * - \ref SCIP_STAGE_PRESOLVING
5121  * - \ref SCIP_STAGE_SOLVING
5122  */
5124  SCIP* scip, /**< SCIP data structure */
5125  SCIP_VAR* var, /**< problem variable */
5126  SCIP_Real lazylb /**< the lazy lower bound to be set */
5127  )
5128 {
5129  assert(scip != NULL);
5130  assert(var != NULL);
5131 
5132  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbLazy", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5133 
5134  if( SCIPisGT(scip, lazylb, SCIPvarGetLbGlobal(var)) )
5135  {
5136  SCIP_CALL( SCIPchgVarLbGlobal(scip, var, lazylb) );
5137  }
5138 
5139  SCIP_CALL( SCIPvarChgLbLazy(var, scip->set, lazylb) );
5140 
5141  return SCIP_OKAY;
5142 }
5143 
5144 /** changes lazy upper bound of the variable, this is only possible if the variable is not in the LP yet
5145  *
5146  * Lazy bounds are bounds that are already enforced by constraints and the objective function.
5147  * Setting a lazy upper bound has the consequence that for variables which upper bound equals the lazy upper bound,
5148  * the upper bound does not need to be passed on to the LP solver.
5149  * This is especially useful in a column generation (branch-and-price) setting.
5150  *
5151  * @attention If the variable has a global upper bound above lazyub, then the global upper bound is tightened to
5152  * lazyub by a call to SCIPchgVarUbGlobal().
5153  *
5154  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5155  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5156  *
5157  * @pre This method can be called if @p scip is in one of the following stages:
5158  * - \ref SCIP_STAGE_PROBLEM
5159  * - \ref SCIP_STAGE_TRANSFORMING
5160  * - \ref SCIP_STAGE_TRANSFORMED
5161  * - \ref SCIP_STAGE_PRESOLVING
5162  * - \ref SCIP_STAGE_SOLVING
5163  */
5165  SCIP* scip, /**< SCIP data structure */
5166  SCIP_VAR* var, /**< problem variable */
5167  SCIP_Real lazyub /**< the lazy lower bound to be set */
5168  )
5169 {
5170  assert(scip != NULL);
5171  assert(var != NULL);
5172 
5173  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbLazy", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5174 
5175  if( SCIPisLT(scip, lazyub, SCIPvarGetUbGlobal(var)) )
5176  {
5177  SCIP_CALL( SCIPchgVarUbGlobal(scip, var, lazyub) );
5178  }
5179 
5180  SCIP_CALL( SCIPvarChgUbLazy(var, scip->set, lazyub) );
5181 
5182  return SCIP_OKAY;
5183 }
5184 
5185 /** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
5186  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5187  * doesn't store any inference information in the bound change, such that in conflict analysis, this change
5188  * is treated like a branching decision
5189  *
5190  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5191  * SCIPgetVars()) gets resorted.
5192  *
5193  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5194  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5195  *
5196  * @pre This method can be called if @p scip is in one of the following stages:
5197  * - \ref SCIP_STAGE_PROBLEM
5198  * - \ref SCIP_STAGE_PRESOLVING
5199  * - \ref SCIP_STAGE_SOLVING
5200  *
5201  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5202  */
5204  SCIP* scip, /**< SCIP data structure */
5205  SCIP_VAR* var, /**< variable to change the bound for */
5206  SCIP_Real newbound, /**< new value for bound */
5207  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5208  SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
5209  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5210  )
5211 {
5212  SCIP_Real lb;
5213  SCIP_Real ub;
5214 
5215  assert(infeasible != NULL);
5216 
5217  SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarLb", FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5218  /** @todo if needed provide pending local/global bound changes that will be flushed after leaving diving mode (as in struct_tree.h) */
5219  assert(SCIPgetStage(scip) == SCIP_STAGE_PROBLEM || !SCIPinDive(scip));
5220 
5221  *infeasible = FALSE;
5222  if( tightened != NULL )
5223  *tightened = FALSE;
5224 
5225  SCIPvarAdjustLb(var, scip->set, &newbound);
5226 
5227  /* ignore tightenings of lower bounds to +infinity during solving process */
5228  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5229  {
5230 #ifndef NDEBUG
5231  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
5232  SCIPvarGetLbLocal(var));
5233 #endif
5234  return SCIP_OKAY;
5235  }
5236 
5237  /* get current bounds */
5238  lb = SCIPcomputeVarLbLocal(scip, var);
5239  ub = SCIPcomputeVarUbLocal(scip, var);
5240  assert(SCIPsetIsLE(scip->set, lb, ub));
5241 
5242  if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
5243  {
5244  *infeasible = TRUE;
5245  return SCIP_OKAY;
5246  }
5247  newbound = MIN(newbound, ub);
5248 
5249  if( (force && SCIPsetIsLE(scip->set, newbound, lb)) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
5250  return SCIP_OKAY;
5251 
5252  switch( scip->set->stage )
5253  {
5254  case SCIP_STAGE_PROBLEM:
5255  assert(!SCIPvarIsTransformed(var));
5256  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5257  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5258  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5259  scip->branchcand, scip->eventqueue, newbound) );
5260  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
5261  break;
5263  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5264  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5265  break;
5266  case SCIP_STAGE_PRESOLVING:
5267  if( !SCIPinProbing(scip) )
5268  {
5269  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5270  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5271 
5272  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5273  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5275 
5277  {
5278  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5279  assert(!(*infeasible));
5280  }
5281  break;
5282  }
5283  /*lint -fallthrough*/
5284  case SCIP_STAGE_SOLVING:
5286  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable,
5287  var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
5288  break;
5289 
5290  default:
5291  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5292  return SCIP_INVALIDCALL;
5293  } /*lint !e788*/
5294 
5295  /* check whether the lower bound improved */
5296  if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
5297  *tightened = TRUE;
5298 
5299  return SCIP_OKAY;
5300 }
5301 
5302 /** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
5303  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5304  * doesn't store any inference information in the bound change, such that in conflict analysis, this change
5305  * is treated like a branching decision
5306  *
5307  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5308  * SCIPgetVars()) gets resorted.
5309  *
5310  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5311  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5312  *
5313  * @pre This method can be called if @p scip is in one of the following stages:
5314  * - \ref SCIP_STAGE_PROBLEM
5315  * - \ref SCIP_STAGE_PRESOLVING
5316  * - \ref SCIP_STAGE_SOLVING
5317  *
5318  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5319  */
5321  SCIP* scip, /**< SCIP data structure */
5322  SCIP_VAR* var, /**< variable to change the bound for */
5323  SCIP_Real newbound, /**< new value for bound */
5324  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5325  SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
5326  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5327  )
5328 {
5329  SCIP_Real lb;
5330  SCIP_Real ub;
5331 
5332  assert(infeasible != NULL);
5333  SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarUb", FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5334 
5335  /** @todo if needed provide pending local/global bound changes that will be flushed after leaving diving mode (as in struct_tree.h) */
5336  assert(SCIPgetStage(scip) == SCIP_STAGE_PROBLEM || !SCIPinDive(scip));
5337 
5338  *infeasible = FALSE;
5339  if( tightened != NULL )
5340  *tightened = FALSE;
5341 
5342  SCIPvarAdjustUb(var, scip->set, &newbound);
5343 
5344  /* ignore tightenings of upper bounds to -infinity during solving process */
5345  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5346  {
5347 #ifndef NDEBUG
5348  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5349  SCIPvarGetUbLocal(var));
5350 #endif
5351  return SCIP_OKAY;
5352  }
5353 
5354  /* get current bounds */
5355  lb = SCIPcomputeVarLbLocal(scip, var);
5356  ub = SCIPcomputeVarUbLocal(scip, var);
5357  assert(SCIPsetIsLE(scip->set, lb, ub));
5358 
5359  if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
5360  {
5361  *infeasible = TRUE;
5362  return SCIP_OKAY;
5363  }
5364  newbound = MAX(newbound, lb);
5365 
5366  if( (force && SCIPsetIsGE(scip->set, newbound, ub)) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
5367  return SCIP_OKAY;
5368 
5369  switch( scip->set->stage )
5370  {
5371  case SCIP_STAGE_PROBLEM:
5372  assert(!SCIPvarIsTransformed(var));
5373  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5374  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5375  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5376  scip->branchcand, scip->eventqueue, newbound) );
5377  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
5378  break;
5380  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5381  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5382  break;
5383  case SCIP_STAGE_PRESOLVING:
5384  if( !SCIPinProbing(scip) )
5385  {
5386  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5387  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5388 
5389  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5390  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5392 
5394  {
5395  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5396  assert(!(*infeasible));
5397  }
5398  break;
5399  }
5400  /*lint -fallthrough*/
5401  case SCIP_STAGE_SOLVING:
5403  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5404  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
5405  break;
5406 
5407  default:
5408  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5409  return SCIP_INVALIDCALL;
5410  } /*lint !e788*/
5411 
5412  /* check whether the upper bound improved */
5413  if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
5414  *tightened = TRUE;
5415 
5416  return SCIP_OKAY;
5417 }
5418 
5419 /** fixes variable in preprocessing or in the current node, if the new bound is tighter (w.r.t. bound strengthening
5420  * epsilon) than the current bound; if possible, adjusts bound to integral value; the given inference constraint is
5421  * stored, such that the conflict analysis is able to find out the reason for the deduction of the bound change
5422  *
5423  * @note In presolving stage when not in probing mode the variable will be fixed directly, otherwise this method
5424  * changes first the lowerbound by calling SCIPinferVarLbCons and second the upperbound by calling
5425  * SCIPinferVarUbCons
5426  *
5427  * @note If SCIP is in presolving stage, it can happen that the internal variable array (which get be accessed via
5428  * SCIPgetVars()) gets resorted.
5429  *
5430  * @note During presolving, an integer variable which bound changes to {0,1} is upgraded to a binary variable.
5431  */
5433  SCIP* scip, /**< SCIP data structure */
5434  SCIP_VAR* var, /**< variable to change the bound for */
5435  SCIP_Real fixedval, /**< new value for fixation */
5436  SCIP_CONS* infercons, /**< constraint that deduced the bound change */
5437  int inferinfo, /**< user information for inference to help resolving the conflict */
5438  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5439  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5440  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5441  )
5442 {
5443  assert(scip != NULL);
5444  assert(var != NULL);
5445  assert(infeasible != NULL);
5446 
5447  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarFixCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5448 
5449  if( tightened != NULL )
5450  *tightened = FALSE;
5451 
5452  /* in presolving case we take the shortcut to directly fix the variables */
5453  if( SCIPgetStage(scip) == SCIP_STAGE_PRESOLVING && SCIPtreeGetCurrentDepth(scip->tree) == 0 )
5454  {
5455  SCIP_Bool fixed;
5456 
5457  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5458  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter,
5459  scip->eventqueue, scip->cliquetable, fixedval, infeasible, &fixed) );
5460 
5461  if( tightened != NULL )
5462  *tightened = fixed;
5463  }
5464  /* otherwise we use the lb and ub methods */
5465  else
5466  {
5467  SCIP_Bool lbtightened;
5468 
5469  SCIP_CALL( SCIPinferVarLbCons(scip, var, fixedval, infercons, inferinfo, force, infeasible, &lbtightened) );
5470 
5471  if( ! (*infeasible) )
5472  {
5473  SCIP_CALL( SCIPinferVarUbCons(scip, var, fixedval, infercons, inferinfo, force, infeasible, tightened) );
5474 
5475  if( tightened != NULL )
5476  *tightened |= lbtightened;
5477  }
5478  }
5479 
5480  return SCIP_OKAY;
5481 }
5482 
5483 /** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
5484  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5485  * the given inference constraint is stored, such that the conflict analysis is able to find out the reason
5486  * for the deduction of the bound change
5487  *
5488  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5489  * SCIPgetVars()) gets resorted.
5490  *
5491  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5492  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5493  *
5494  * @pre This method can be called if @p scip is in one of the following stages:
5495  * - \ref SCIP_STAGE_PROBLEM
5496  * - \ref SCIP_STAGE_PRESOLVING
5497  * - \ref SCIP_STAGE_SOLVING
5498  *
5499  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5500  */
5502  SCIP* scip, /**< SCIP data structure */
5503  SCIP_VAR* var, /**< variable to change the bound for */
5504  SCIP_Real newbound, /**< new value for bound */
5505  SCIP_CONS* infercons, /**< constraint that deduced the bound change */
5506  int inferinfo, /**< user information for inference to help resolving the conflict */
5507  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5508  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5509  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5510  )
5511 {
5512  SCIP_Real lb;
5513  SCIP_Real ub;
5514 
5515  assert(infeasible != NULL);
5516 
5517  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarLbCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5518 
5519  *infeasible = FALSE;
5520  if( tightened != NULL )
5521  *tightened = FALSE;
5522 
5523  SCIPvarAdjustLb(var, scip->set, &newbound);
5524 
5525  /* ignore tightenings of lower bounds to +infinity during solving process */
5526  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5527  {
5528 #ifndef NDEBUG
5529  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
5530  SCIPvarGetLbLocal(var));
5531 #endif
5532  return SCIP_OKAY;
5533  }
5534 
5535  /* get current bounds */
5536  lb = SCIPvarGetLbLocal(var);
5537  ub = SCIPvarGetUbLocal(var);
5538  assert(SCIPsetIsLE(scip->set, lb, ub));
5539 
5540  if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
5541  {
5542  *infeasible = TRUE;
5543  return SCIP_OKAY;
5544  }
5545  newbound = MIN(newbound, ub);
5546 
5547  if( (force && SCIPsetIsLE(scip->set, newbound, lb)) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
5548  return SCIP_OKAY;
5549 
5550  switch( scip->set->stage )
5551  {
5552  case SCIP_STAGE_PROBLEM:
5553  assert(!SCIPvarIsTransformed(var));
5554  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5555  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5556  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5557  scip->branchcand, scip->eventqueue, newbound) );
5558  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
5559  break;
5560 
5561  case SCIP_STAGE_PRESOLVING:
5562  if( !SCIPinProbing(scip) )
5563  {
5564  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5565  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5566 
5567  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5568  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5570 
5572  {
5573  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5574  assert(!(*infeasible));
5575  }
5576  break;
5577  }
5578  /*lint -fallthrough*/
5579  case SCIP_STAGE_SOLVING:
5581  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5582  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, infercons, NULL, inferinfo, FALSE) );
5583  break;
5584 
5585  default:
5586  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5587  return SCIP_INVALIDCALL;
5588  } /*lint !e788*/
5589 
5590  /* check whether the lower bound improved */
5591  if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
5592  *tightened = TRUE;
5593 
5594  return SCIP_OKAY;
5595 }
5596 
5597 /** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
5598  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5599  * the given inference constraint is stored, such that the conflict analysis is able to find out the reason
5600  * for the deduction of the bound change
5601  *
5602  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5603  * SCIPgetVars()) gets resorted.
5604  *
5605  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5606  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5607  *
5608  * @pre This method can be called if @p scip is in one of the following stages:
5609  * - \ref SCIP_STAGE_PROBLEM
5610  * - \ref SCIP_STAGE_PRESOLVING
5611  * - \ref SCIP_STAGE_SOLVING
5612  *
5613  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5614  */
5616  SCIP* scip, /**< SCIP data structure */
5617  SCIP_VAR* var, /**< variable to change the bound for */
5618  SCIP_Real newbound, /**< new value for bound */
5619  SCIP_CONS* infercons, /**< constraint that deduced the bound change */
5620  int inferinfo, /**< user information for inference to help resolving the conflict */
5621  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5622  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5623  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5624  )
5625 {
5626  SCIP_Real lb;
5627  SCIP_Real ub;
5628 
5629  assert(infeasible != NULL);
5630 
5631  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarUbCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5632 
5633  *infeasible = FALSE;
5634  if( tightened != NULL )
5635  *tightened = FALSE;
5636 
5637  SCIPvarAdjustUb(var, scip->set, &newbound);
5638 
5639  /* ignore tightenings of upper bounds to -infinity during solving process */
5640  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5641  {
5642 #ifndef NDEBUG
5643  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5644  SCIPvarGetUbLocal(var));
5645 #endif
5646  return SCIP_OKAY;
5647  }
5648 
5649  /* get current bounds */
5650  lb = SCIPvarGetLbLocal(var);
5651  ub = SCIPvarGetUbLocal(var);
5652  assert(SCIPsetIsLE(scip->set, lb, ub));
5653 
5654  if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
5655  {
5656  *infeasible = TRUE;
5657  return SCIP_OKAY;
5658  }
5659  newbound = MAX(newbound, lb);
5660 
5661  if( (force && SCIPsetIsGE(scip->set, newbound, ub)) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
5662  return SCIP_OKAY;
5663 
5664  switch( scip->set->stage )
5665  {
5666  case SCIP_STAGE_PROBLEM:
5667  assert(!SCIPvarIsTransformed(var));
5668  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5669  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5670  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5671  scip->branchcand, scip->eventqueue, newbound) );
5672  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
5673  break;
5674 
5675  case SCIP_STAGE_PRESOLVING:
5676  if( !SCIPinProbing(scip) )
5677  {
5678  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5679  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5680 
5681  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5682  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5684 
5686  {
5687  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5688  assert(!(*infeasible));
5689  }
5690  break;
5691  }
5692  /*lint -fallthrough*/
5693  case SCIP_STAGE_SOLVING:
5695  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5696  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, infercons, NULL, inferinfo, FALSE) );
5697  break;
5698 
5699  default:
5700  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5701  return SCIP_INVALIDCALL;
5702  } /*lint !e788*/
5703 
5704  /* check whether the upper bound improved */
5705  if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
5706  *tightened = TRUE;
5707 
5708  return SCIP_OKAY;
5709 }
5710 
5711 /** depending on SCIP's stage, fixes binary variable in the problem, in preprocessing, or in current node;
5712  * the given inference constraint is stored, such that the conflict analysis is able to find out the reason for the
5713  * deduction of the fixing
5714  *
5715  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5716  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5717  *
5718  * @pre This method can be called if @p scip is in one of the following stages:
5719  * - \ref SCIP_STAGE_PROBLEM
5720  * - \ref SCIP_STAGE_PRESOLVING
5721  * - \ref SCIP_STAGE_SOLVING
5722  */
5724  SCIP* scip, /**< SCIP data structure */
5725  SCIP_VAR* var, /**< binary variable to fix */
5726  SCIP_Bool fixedval, /**< value to fix binary variable to */
5727  SCIP_CONS* infercons, /**< constraint that deduced the fixing */
5728  int inferinfo, /**< user information for inference to help resolving the conflict */
5729  SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
5730  SCIP_Bool* tightened /**< pointer to store whether the fixing tightened the local bounds, or NULL */
5731  )
5732 {
5733  SCIP_Real lb;
5734  SCIP_Real ub;
5735 
5736  assert(SCIPvarIsBinary(var));
5737  assert(fixedval == TRUE || fixedval == FALSE);
5738  assert(infeasible != NULL);
5739 
5740  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferBinvarCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5741 
5742  *infeasible = FALSE;
5743  if( tightened != NULL )
5744  *tightened = FALSE;
5745 
5746  /* get current bounds */
5747  lb = SCIPvarGetLbLocal(var);
5748  ub = SCIPvarGetUbLocal(var);
5749  assert(SCIPsetIsEQ(scip->set, lb, 0.0) || SCIPsetIsEQ(scip->set, lb, 1.0));
5750  assert(SCIPsetIsEQ(scip->set, ub, 0.0) || SCIPsetIsEQ(scip->set, ub, 1.0));
5751  assert(SCIPsetIsLE(scip->set, lb, ub));
5752 
5753  /* check, if variable is already fixed */
5754  if( (lb > 0.5) || (ub < 0.5) )
5755  {
5756  *infeasible = (fixedval == (lb < 0.5));
5757 
5758  return SCIP_OKAY;
5759  }
5760 
5761  /* apply the fixing */
5762  switch( scip->set->stage )
5763  {
5764  case SCIP_STAGE_PROBLEM:
5765  assert(!SCIPvarIsTransformed(var));
5766  if( fixedval == TRUE )
5767  {
5768  SCIP_CALL( SCIPchgVarLb(scip, var, 1.0) );
5769  }
5770  else
5771  {
5772  SCIP_CALL( SCIPchgVarUb(scip, var, 0.0) );
5773  }
5774  break;
5775 
5776  case SCIP_STAGE_PRESOLVING:
5777  if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
5778  {
5779  SCIP_Bool fixed;
5780 
5781  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5782  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
5783  scip->cliquetable, (SCIP_Real)fixedval, infeasible, &fixed) );
5784  break;
5785  }
5786  /*lint -fallthrough*/
5787  case SCIP_STAGE_SOLVING:
5788  if( fixedval == TRUE )
5789  {
5791  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5792  scip->cliquetable, var, 1.0, SCIP_BOUNDTYPE_LOWER, infercons, NULL, inferinfo, FALSE) );
5793  }
5794  else
5795  {
5797  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5798  scip->cliquetable, var, 0.0, SCIP_BOUNDTYPE_UPPER, infercons, NULL, inferinfo, FALSE) );
5799  }
5800  break;
5801 
5802  default:
5803  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5804  return SCIP_INVALIDCALL;
5805  } /*lint !e788*/
5806 
5807  if( tightened != NULL )
5808  *tightened = TRUE;
5809 
5810  return SCIP_OKAY;
5811 }
5812 
5813 /** fixes variable in preprocessing or in the current node, if the new bound is tighter (w.r.t. bound strengthening
5814  * epsilon) than the current bound; if possible, adjusts bound to integral value; the given inference constraint is
5815  * stored, such that the conflict analysis is able to find out the reason for the deduction of the bound change
5816  *
5817  * @note In presolving stage when not in probing mode the variable will be fixed directly, otherwise this method
5818  * changes first the lowerbound by calling SCIPinferVarLbProp and second the upperbound by calling
5819  * SCIPinferVarUbProp
5820  *
5821  * @note If SCIP is in presolving stage, it can happen that the internal variable array (which get be accessed via
5822  * SCIPgetVars()) gets resorted.
5823  *
5824  * @note During presolving, an integer variable which bound changes to {0,1} is upgraded to a binary variable.
5825  */
5827  SCIP* scip, /**< SCIP data structure */
5828  SCIP_VAR* var, /**< variable to change the bound for */
5829  SCIP_Real fixedval, /**< new value for fixation */
5830  SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
5831  int inferinfo, /**< user information for inference to help resolving the conflict */
5832  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5833  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5834  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5835  )
5836 {
5837  assert(scip != NULL);
5838  assert(var != NULL);
5839  assert(infeasible != NULL);
5840 
5841  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarFixProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5842 
5843  if( tightened != NULL )
5844  *tightened = FALSE;
5845 
5846  /* in presolving case we take the shortcut to directly fix the variables */
5847  if( SCIPgetStage(scip) == SCIP_STAGE_PRESOLVING && SCIPtreeGetCurrentDepth(scip->tree) == 0 )
5848  {
5849  SCIP_Bool fixed;
5850 
5851  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5852  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
5853  scip->cliquetable, fixedval, infeasible, &fixed) );
5854 
5855  if( tightened != NULL )
5856  *tightened = fixed;
5857  }
5858  /* otherwise we use the lb and ub methods */
5859  else
5860  {
5861  SCIP_Bool lbtightened;
5862 
5863  SCIP_CALL( SCIPinferVarLbProp(scip, var, fixedval, inferprop, inferinfo, force, infeasible, &lbtightened) );
5864 
5865  if( ! (*infeasible) )
5866  {
5867  SCIP_CALL( SCIPinferVarUbProp(scip, var, fixedval, inferprop, inferinfo, force, infeasible, tightened) );
5868 
5869  if( tightened != NULL )
5870  *tightened |= lbtightened;
5871  }
5872  }
5873 
5874  return SCIP_OKAY;
5875 }
5876 
5877 /** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
5878  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5879  * the given inference propagator is stored, such that the conflict analysis is able to find out the reason
5880  * for the deduction of the bound change
5881  *
5882  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5883  * SCIPgetVars()) gets resorted.
5884  *
5885  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5886  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5887  *
5888  * @pre This method can be called if @p scip is in one of the following stages:
5889  * - \ref SCIP_STAGE_PROBLEM
5890  * - \ref SCIP_STAGE_PRESOLVING
5891  * - \ref SCIP_STAGE_SOLVING
5892  *
5893  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5894  */
5896  SCIP* scip, /**< SCIP data structure */
5897  SCIP_VAR* var, /**< variable to change the bound for */
5898  SCIP_Real newbound, /**< new value for bound */
5899  SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
5900  int inferinfo, /**< user information for inference to help resolving the conflict */
5901  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5902  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5903  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5904  )
5905 {
5906  SCIP_Real lb;
5907  SCIP_Real ub;
5908 
5909  assert(infeasible != NULL);
5910 
5911  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarLbProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5912 
5913  *infeasible = FALSE;
5914  if( tightened != NULL )
5915  *tightened = FALSE;
5916 
5917  SCIPvarAdjustLb(var, scip->set, &newbound);
5918 
5919  /* ignore tightenings of lower bounds to +infinity during solving process */
5920  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5921  {
5922 #ifndef NDEBUG
5923  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
5924  SCIPvarGetLbLocal(var));
5925 #endif
5926  return SCIP_OKAY;
5927  }
5928 
5929  /* get current bounds */
5930  lb = SCIPvarGetLbLocal(var);
5931  ub = SCIPvarGetUbLocal(var);
5932  assert(SCIPsetIsLE(scip->set, lb, ub));
5933 
5934  if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
5935  {
5936  *infeasible = TRUE;
5937  return SCIP_OKAY;
5938  }
5939  newbound = MIN(newbound, ub);
5940 
5941  if( (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub))
5942  || SCIPsetIsLE(scip->set, newbound, lb) )
5943  return SCIP_OKAY;
5944 
5945  switch( scip->set->stage )
5946  {
5947  case SCIP_STAGE_PROBLEM:
5948  assert(!SCIPvarIsTransformed(var));
5949  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5950  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5951  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5952  scip->branchcand, scip->eventqueue, newbound) );
5953  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
5954  break;
5955 
5956  case SCIP_STAGE_PRESOLVING:
5957  if( !SCIPinProbing(scip) )
5958  {
5959  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5960  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5961 
5962  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5963  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5965 
5967  {
5968  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5969  assert(!(*infeasible));
5970  }
5971  break;
5972  }
5973  /*lint -fallthrough*/
5974  case SCIP_STAGE_SOLVING:
5976  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5977  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, NULL, inferprop, inferinfo, FALSE) );
5978  break;
5979 
5980  default:
5981  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5982  return SCIP_INVALIDCALL;
5983  } /*lint !e788*/
5984 
5985  /* check whether the lower bound improved */
5986  if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
5987  *tightened = TRUE;
5988 
5989  return SCIP_OKAY;
5990 }
5991 
5992 /** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
5993  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5994  * the given inference propagator is stored, such that the conflict analysis is able to find out the reason
5995  * for the deduction of the bound change
5996  *
5997  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5998  * SCIPgetVars()) gets resorted.
5999  *
6000  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6001  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6002  *
6003  * @pre This method can be called if @p scip is in one of the following stages:
6004  * - \ref SCIP_STAGE_PROBLEM
6005  * - \ref SCIP_STAGE_PRESOLVING
6006  * - \ref SCIP_STAGE_SOLVING
6007  *
6008  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6009  */
6011  SCIP* scip, /**< SCIP data structure */
6012  SCIP_VAR* var, /**< variable to change the bound for */
6013  SCIP_Real newbound, /**< new value for bound */
6014  SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
6015  int inferinfo, /**< user information for inference to help resolving the conflict */
6016  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6017  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
6018  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6019  )
6020 {
6021  SCIP_Real lb;
6022  SCIP_Real ub;
6023 
6024  assert(infeasible != NULL);
6025 
6026  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarUbProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6027 
6028  *infeasible = FALSE;
6029  if( tightened != NULL )
6030  *tightened = FALSE;
6031 
6032  SCIPvarAdjustUb(var, scip->set, &newbound);
6033 
6034  /* ignore tightenings of upper bounds to -infinity during solving process */
6035  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6036  {
6037 #ifndef NDEBUG
6038  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
6039  SCIPvarGetUbLocal(var));
6040 #endif
6041  return SCIP_OKAY;
6042  }
6043 
6044  /* get current bounds */
6045  lb = SCIPvarGetLbLocal(var);
6046  ub = SCIPvarGetUbLocal(var);
6047  assert(SCIPsetIsLE(scip->set, lb, ub));
6048 
6049  if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
6050  {
6051  *infeasible = TRUE;
6052  return SCIP_OKAY;
6053  }
6054  newbound = MAX(newbound, lb);
6055 
6056  if( (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub))
6057  || SCIPsetIsGE(scip->set, newbound, ub) )
6058  return SCIP_OKAY;
6059 
6060  switch( scip->set->stage )
6061  {
6062  case SCIP_STAGE_PROBLEM:
6063  assert(!SCIPvarIsTransformed(var));
6064  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6065  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6066  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6067  scip->branchcand, scip->eventqueue, newbound) );
6068  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
6069  break;
6070 
6071  case SCIP_STAGE_PRESOLVING:
6072  if( !SCIPinProbing(scip) )
6073  {
6074  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6075  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6076 
6077  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6078  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6080 
6082  {
6083  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6084  assert(!(*infeasible));
6085  }
6086  break;
6087  }
6088  /*lint -fallthrough*/
6089  case SCIP_STAGE_SOLVING:
6091  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
6092  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, NULL, inferprop, inferinfo, FALSE) );
6093  break;
6094 
6095  default:
6096  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6097  return SCIP_INVALIDCALL;
6098  } /*lint !e788*/
6099 
6100  /* check whether the upper bound improved */
6101  if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
6102  *tightened = TRUE;
6103 
6104  return SCIP_OKAY;
6105 }
6106 
6107 /** depending on SCIP's stage, fixes binary variable in the problem, in preprocessing, or in current node;
6108  * the given inference propagator is stored, such that the conflict analysis is able to find out the reason for the
6109  * deduction of the fixing
6110  *
6111  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6112  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6113  *
6114  * @pre This method can be called if @p scip is in one of the following stages:
6115  * - \ref SCIP_STAGE_PROBLEM
6116  * - \ref SCIP_STAGE_PRESOLVING
6117  * - \ref SCIP_STAGE_PRESOLVED
6118  * - \ref SCIP_STAGE_SOLVING
6119  */
6121  SCIP* scip, /**< SCIP data structure */
6122  SCIP_VAR* var, /**< binary variable to fix */
6123  SCIP_Bool fixedval, /**< value to fix binary variable to */
6124  SCIP_PROP* inferprop, /**< propagator that deduced the fixing */
6125  int inferinfo, /**< user information for inference to help resolving the conflict */
6126  SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
6127  SCIP_Bool* tightened /**< pointer to store whether the fixing tightened the local bounds, or NULL */
6128  )
6129 {
6130  SCIP_Real lb;
6131  SCIP_Real ub;
6132 
6133  assert(SCIPvarIsBinary(var));
6134  assert(fixedval == TRUE || fixedval == FALSE);
6135  assert(infeasible != NULL);
6136 
6137  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferBinvarProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6138 
6139  *infeasible = FALSE;
6140  if( tightened != NULL )
6141  *tightened = FALSE;
6142 
6143  /* get current bounds */
6144  lb = SCIPvarGetLbLocal(var);
6145  ub = SCIPvarGetUbLocal(var);
6146  assert(SCIPsetIsEQ(scip->set, lb, 0.0) || SCIPsetIsEQ(scip->set, lb, 1.0));
6147  assert(SCIPsetIsEQ(scip->set, ub, 0.0) || SCIPsetIsEQ(scip->set, ub, 1.0));
6148  assert(SCIPsetIsLE(scip->set, lb, ub));
6149 
6150  /* check, if variable is already fixed */
6151  if( (lb > 0.5) || (ub < 0.5) )
6152  {
6153  *infeasible = (fixedval == (lb < 0.5));
6154 
6155  return SCIP_OKAY;
6156  }
6157 
6158  /* apply the fixing */
6159  switch( scip->set->stage )
6160  {
6161  case SCIP_STAGE_PROBLEM:
6162  assert(!SCIPvarIsTransformed(var));
6163  if( fixedval == TRUE )
6164  {
6165  SCIP_CALL( SCIPchgVarLb(scip, var, 1.0) );
6166  }
6167  else
6168  {
6169  SCIP_CALL( SCIPchgVarUb(scip, var, 0.0) );
6170  }
6171  break;
6172 
6173  case SCIP_STAGE_PRESOLVING:
6174  if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
6175  {
6176  SCIP_Bool fixed;
6177 
6178  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6179  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
6180  scip->cliquetable, (SCIP_Real)fixedval, infeasible, &fixed) );
6181  break;
6182  }
6183  /*lint -fallthrough*/
6184  case SCIP_STAGE_SOLVING:
6185  if( fixedval == TRUE )
6186  {
6188  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, 1.0,
6189  SCIP_BOUNDTYPE_LOWER, NULL, inferprop, inferinfo, FALSE) );
6190  }
6191  else
6192  {
6194  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, 0.0,
6195  SCIP_BOUNDTYPE_UPPER, NULL, inferprop, inferinfo, FALSE) );
6196  }
6197  break;
6198 
6199  default:
6200  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6201  return SCIP_INVALIDCALL;
6202  } /*lint !e788*/
6203 
6204  if( tightened != NULL )
6205  *tightened = TRUE;
6206 
6207  return SCIP_OKAY;
6208 }
6209 
6210 /** changes global lower bound of variable in preprocessing or in the current node, if the new bound is tighter
6211  * (w.r.t. bound strengthening epsilon) than the current global bound; if possible, adjusts bound to integral value;
6212  * also tightens the local bound, if the global bound is better than the local bound
6213  *
6214  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6215  * SCIPgetVars()) gets resorted.
6216  *
6217  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6218  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6219  *
6220  * @pre This method can be called if @p scip is in one of the following stages:
6221  * - \ref SCIP_STAGE_PROBLEM
6222  * - \ref SCIP_STAGE_TRANSFORMING
6223  * - \ref SCIP_STAGE_PRESOLVING
6224  * - \ref SCIP_STAGE_SOLVING
6225  *
6226  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6227  */
6229  SCIP* scip, /**< SCIP data structure */
6230  SCIP_VAR* var, /**< variable to change the bound for */
6231  SCIP_Real newbound, /**< new value for bound */
6232  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6233  SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
6234  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6235  )
6236 {
6237  SCIP_Real lb;
6238  SCIP_Real ub;
6239 
6240  assert(infeasible != NULL);
6241 
6242  SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarLbGlobal", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6243 
6244  *infeasible = FALSE;
6245  if( tightened != NULL )
6246  *tightened = FALSE;
6247 
6248  SCIPvarAdjustLb(var, scip->set, &newbound);
6249 
6250  /* ignore tightenings of lower bounds to +infinity during solving process */
6251  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6252  {
6253 #ifndef NDEBUG
6254  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
6255  SCIPvarGetLbLocal(var));
6256 #endif
6257  return SCIP_OKAY;
6258  }
6259 
6260  /* get current bounds */
6261  lb = SCIPvarGetLbGlobal(var);
6262  ub = SCIPvarGetUbGlobal(var);
6263  assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPsetIsLE(scip->set, lb, ub));
6264 
6265  if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
6266  {
6267  *infeasible = TRUE;
6268  return SCIP_OKAY;
6269  }
6270  newbound = MIN(newbound, ub);
6271 
6272  /* bound changes of less than epsilon are ignored by SCIPvarChgLb or raise an assert in SCIPnodeAddBoundinfer,
6273  * so don't apply them even if force is set
6274  */
6275  if( SCIPsetIsEQ(scip->set, lb, newbound) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
6276  return SCIP_OKAY;
6277 
6278  switch( scip->set->stage )
6279  {
6280  case SCIP_STAGE_PROBLEM:
6281  assert(!SCIPvarIsTransformed(var));
6282  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6283  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6284  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6285  scip->branchcand, scip->eventqueue, newbound) );
6286  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
6287  break;
6288 
6290  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6291  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6292  break;
6293 
6294  case SCIP_STAGE_PRESOLVING:
6295  if( !SCIPinProbing(scip) )
6296  {
6297  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6298  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6299 
6300  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6301  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6303 
6305  {
6306  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6307  assert(!(*infeasible));
6308  }
6309  break;
6310  }
6311  /*lint -fallthrough*/
6312  case SCIP_STAGE_SOLVING:
6313  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6314  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6316  break;
6317 
6318  default:
6319  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6320  return SCIP_INVALIDCALL;
6321  } /*lint !e788*/
6322 
6323  /* coverity: unreachable code */
6324  if( tightened != NULL && lb < SCIPcomputeVarLbGlobal(scip, var) )
6325  *tightened = TRUE;
6326 
6327  return SCIP_OKAY;
6328 }
6329 
6330 /** changes global upper bound of variable in preprocessing or in the current node, if the new bound is tighter
6331  * (w.r.t. bound strengthening epsilon) than the current global bound; if possible, adjusts bound to integral value;
6332  * also tightens the local bound, if the global bound is better than the local bound
6333  *
6334  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6335  * SCIPgetVars()) gets resorted.
6336  *
6337  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6338  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6339  *
6340  * @pre This method can be called if @p scip is in one of the following stages:
6341  * - \ref SCIP_STAGE_PROBLEM
6342  * - \ref SCIP_STAGE_TRANSFORMING
6343  * - \ref SCIP_STAGE_PRESOLVING
6344  * - \ref SCIP_STAGE_SOLVING
6345  *
6346  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6347  */
6349  SCIP* scip, /**< SCIP data structure */
6350  SCIP_VAR* var, /**< variable to change the bound for */
6351  SCIP_Real newbound, /**< new value for bound */
6352  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6353  SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
6354  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6355  )
6356 {
6357  SCIP_Real lb;
6358  SCIP_Real ub;
6359 
6360  assert(infeasible != NULL);
6361 
6362  SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarUbGlobal", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6363 
6364  *infeasible = FALSE;
6365  if( tightened != NULL )
6366  *tightened = FALSE;
6367 
6368  SCIPvarAdjustUb(var, scip->set, &newbound);
6369 
6370  /* ignore tightenings of upper bounds to -infinity during solving process */
6371  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6372  {
6373 #ifndef NDEBUG
6374  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
6375  SCIPvarGetUbLocal(var));
6376 #endif
6377  return SCIP_OKAY;
6378  }
6379 
6380  /* get current bounds */
6381  lb = SCIPvarGetLbGlobal(var);
6382  ub = SCIPvarGetUbGlobal(var);
6383  assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPsetIsLE(scip->set, lb, ub));
6384 
6385  if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
6386  {
6387  *infeasible = TRUE;
6388  return SCIP_OKAY;
6389  }
6390  newbound = MAX(newbound, lb);
6391 
6392  /* bound changes of less than epsilon are ignored by SCIPvarChgUb or raise an assert in SCIPnodeAddBoundinfer,
6393  * so don't apply them even if force is set
6394  */
6395  if( SCIPsetIsEQ(scip->set, ub, newbound) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
6396  return SCIP_OKAY;
6397 
6398  switch( scip->set->stage )
6399  {
6400  case SCIP_STAGE_PROBLEM:
6401  assert(!SCIPvarIsTransformed(var));
6402  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6403  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6404  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6405  scip->branchcand, scip->eventqueue, newbound) );
6406  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
6407  break;
6408 
6410  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6411  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6412  break;
6413 
6414  case SCIP_STAGE_PRESOLVING:
6415  if( !SCIPinProbing(scip) )
6416  {
6417  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6418  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6419 
6420  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6421  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6423 
6425  {
6426  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6427  assert(!(*infeasible));
6428  }
6429  break;
6430  }
6431  /*lint -fallthrough*/
6432  case SCIP_STAGE_SOLVING:
6433  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6434  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6436  break;
6437 
6438  default:
6439  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6440  return SCIP_INVALIDCALL;
6441  } /*lint !e788*/
6442 
6443  /* coverity: unreachable code */
6444  if( tightened != NULL && ub > SCIPcomputeVarUbGlobal(scip, var) )
6445  *tightened = TRUE;
6446 
6447  return SCIP_OKAY;
6448 }
6449 
6450 /* some simple variable functions implemented as defines */
6451 #undef SCIPcomputeVarLbGlobal
6452 #undef SCIPcomputeVarUbGlobal
6453 #undef SCIPcomputeVarLbLocal
6454 #undef SCIPcomputeVarUbLocal
6455 
6456 /** for a multi-aggregated variable, returns the global lower bound computed by adding the global bounds from all aggregation variables
6457  *
6458  * This global bound may be tighter than the one given by SCIPvarGetLbGlobal, since the latter is not updated if bounds of aggregation variables are changing
6459  * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetLbGlobal.
6460  *
6461  * @return the global lower bound computed by adding the global bounds from all aggregation variables
6462  */
6464  SCIP* scip, /**< SCIP data structure */
6465  SCIP_VAR* var /**< variable to compute the bound for */
6466  )
6467 {
6468  assert(scip != NULL);
6469  assert(var != NULL);
6470 
6472  return SCIPvarGetMultaggrLbGlobal(var, scip->set);
6473  else
6474  return SCIPvarGetLbGlobal(var);
6475 }
6476 
6477 /** for a multi-aggregated variable, returns the global upper bound computed by adding the global bounds from all aggregation variables
6478  *
6479  * This global bound may be tighter than the one given by SCIPvarGetUbGlobal, since the latter is not updated if bounds of aggregation variables are changing
6480  * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetUbGlobal
6481  *
6482  * @return the global upper bound computed by adding the global bounds from all aggregation variables
6483  */
6485  SCIP* scip, /**< SCIP data structure */
6486  SCIP_VAR* var /**< variable to compute the bound for */
6487  )
6488 {
6489  assert(scip != NULL);
6490  assert(var != NULL);
6491 
6493  return SCIPvarGetMultaggrUbGlobal(var, scip->set);
6494  else
6495  return SCIPvarGetUbGlobal(var);
6496 }
6497 
6498 /** for a multi-aggregated variable, returns the local lower bound computed by adding the local bounds from all aggregation variables
6499  *
6500  * This local bound may be tighter than the one given by SCIPvarGetLbLocal, since the latter is not updated if bounds of aggregation variables are changing
6501  * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetLbLocal.
6502  *
6503  * @return the local lower bound computed by adding the global bounds from all aggregation variables
6504  */
6506  SCIP* scip, /**< SCIP data structure */
6507  SCIP_VAR* var /**< variable to compute the bound for */
6508  )
6509 {
6510  assert(scip != NULL);
6511  assert(var != NULL);
6512 
6514  return SCIPvarGetMultaggrLbLocal(var, scip->set);
6515  else
6516  return SCIPvarGetLbLocal(var);
6517 }
6518 
6519 /** for a multi-aggregated variable, returns the local upper bound computed by adding the local bounds from all aggregation variables
6520  *
6521  * This local bound may be tighter than the one given by SCIPvarGetUbLocal, since the latter is not updated if bounds of aggregation variables are changing
6522  * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetUbLocal.
6523  *
6524  * @return the local upper bound computed by adding the global bounds from all aggregation variables
6525  */
6527  SCIP* scip, /**< SCIP data structure */
6528  SCIP_VAR* var /**< variable to compute the bound for */
6529  )
6530 {
6531  assert(scip != NULL);
6532  assert(var != NULL);
6533 
6535  return SCIPvarGetMultaggrUbLocal(var, scip->set);
6536  else
6537  return SCIPvarGetUbLocal(var);
6538 }
6539 
6540 /** for a multi-aggregated variable, gives the global lower bound computed by adding the global bounds from all
6541  * aggregation variables, this global bound may be tighter than the one given by SCIPvarGetLbGlobal, since the latter is
6542  * not updated if bounds of aggregation variables are changing
6543  *
6544  * calling this function for a non-multi-aggregated variable is not allowed
6545  */
6547  SCIP* scip, /**< SCIP data structure */
6548  SCIP_VAR* var /**< variable to compute the bound for */
6549  )
6550 {
6551  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
6552  return SCIPvarGetMultaggrLbGlobal(var, scip->set);
6553 }
6554 
6555 /** for a multi-aggregated variable, gives the global upper bound computed by adding the global bounds from all
6556  * aggregation variables, this upper bound may be tighter than the one given by SCIPvarGetUbGlobal, since the latter is
6557  * not updated if bounds of aggregation variables are changing
6558  *
6559  * calling this function for a non-multi-aggregated variable is not allowed
6560  */
6562  SCIP* scip, /**< SCIP data structure */
6563  SCIP_VAR* var /**< variable to compute the bound for */
6564  )
6565 {
6566  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
6567  return SCIPvarGetMultaggrUbGlobal(var, scip->set);
6568 }
6569 
6570 /** for a multi-aggregated variable, gives the local lower bound computed by adding the local bounds from all
6571  * aggregation variables, this lower bound may be tighter than the one given by SCIPvarGetLbLocal, since the latter is
6572  * not updated if bounds of aggregation variables are changing
6573  *
6574  * calling this function for a non-multi-aggregated variable is not allowed
6575  */
6577  SCIP* scip, /**< SCIP data structure */
6578  SCIP_VAR* var /**< variable to compute the bound for */
6579  )
6580 {
6581  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
6582  return SCIPvarGetMultaggrLbLocal(var, scip->set);
6583 }
6584 
6585 /** for a multi-aggregated variable, gives the local upper bound computed by adding the local bounds from all
6586  * aggregation variables, this upper bound may be tighter than the one given by SCIPvarGetUbLocal, since the latter is
6587  * not updated if bounds of aggregation variables are changing
6588  *
6589  * calling this function for a non-multi-aggregated variable is not allowed
6590  */
6592  SCIP* scip, /**< SCIP data structure */
6593  SCIP_VAR* var /**< variable to compute the bound for */
6594  )
6595 {
6596  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
6597  return SCIPvarGetMultaggrUbLocal(var, scip->set);
6598 }
6599 
6600 /** returns solution value and index of variable lower bound that is closest to the variable's value in the given primal
6601  * solution or current LP solution if no primal solution is given; returns an index of -1 if no variable lower bound is
6602  * available
6603  *
6604  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6605  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6606  *
6607  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
6608  */
6610  SCIP* scip, /**< SCIP data structure */
6611  SCIP_VAR* var, /**< active problem variable */
6612  SCIP_SOL* sol, /**< primal solution, or NULL for LP solution */
6613  SCIP_Real* closestvlb, /**< pointer to store the value of the closest variable lower bound */
6614  int* closestvlbidx /**< pointer to store the index of the closest variable lower bound */
6615  )
6616 {
6617  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarClosestVlb", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6618 
6619  SCIPvarGetClosestVlb(var, sol, scip->set, scip->stat, closestvlb, closestvlbidx);
6620 
6621  return SCIP_OKAY;
6622 }
6623 
6624 /** returns solution value and index of variable upper bound that is closest to the variable's value in the given primal solution;
6625  * or current LP solution if no primal solution is given; returns an index of -1 if no variable upper bound is available
6626  *
6627  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6628  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6629  *
6630  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
6631  */
6633  SCIP* scip, /**< SCIP data structure */
6634  SCIP_VAR* var, /**< active problem variable */
6635  SCIP_SOL* sol, /**< primal solution, or NULL for LP solution */
6636  SCIP_Real* closestvub, /**< pointer to store the value of the closest variable lower bound */
6637  int* closestvubidx /**< pointer to store the index of the closest variable lower bound */
6638  )
6639 {
6640  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarClosestVub", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6641 
6642  SCIPvarGetClosestVub(var, sol, scip->set, scip->stat, closestvub, closestvubidx);
6643 
6644  return SCIP_OKAY;
6645 }
6646 
6647 /** informs variable x about a globally valid variable lower bound x >= b*z + d with integer variable z;
6648  * if z is binary, the corresponding valid implication for z is also added;
6649  * if z is non-continuous and 1/b not too small, the corresponding valid upper/lower bound
6650  * z <= (x-d)/b or z >= (x-d)/b (depending on the sign of of b) is added, too;
6651  * improves the global bounds of the variable and the vlb variable if possible
6652  *
6653  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6654  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6655  *
6656  * @pre This method can be called if @p scip is in one of the following stages:
6657  * - \ref SCIP_STAGE_PRESOLVING
6658  * - \ref SCIP_STAGE_PRESOLVED
6659  * - \ref SCIP_STAGE_SOLVING
6660  */
6662  SCIP* scip, /**< SCIP data structure */
6663  SCIP_VAR* var, /**< problem variable */
6664  SCIP_VAR* vlbvar, /**< variable z in x >= b*z + d */
6665  SCIP_Real vlbcoef, /**< coefficient b in x >= b*z + d */
6666  SCIP_Real vlbconstant, /**< constant d in x >= b*z + d */
6667  SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6668  int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6669  )
6670 {
6671  int nlocalbdchgs;
6672 
6673  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarVlb", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6674 
6675  SCIP_CALL( SCIPvarAddVlb(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->tree,
6676  scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, vlbvar, vlbcoef, vlbconstant,
6677  TRUE, infeasible, &nlocalbdchgs) );
6678 
6679  *nbdchgs = nlocalbdchgs;
6680 
6681  /* if x is not continuous we add a variable bound for z; do not add it if cofficient would be too small or we already
6682  * detected infeasibility
6683  */
6684  if( !(*infeasible) && SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisZero(scip, 1.0/vlbcoef) )
6685  {
6686  if( vlbcoef > 0.0 )
6687  {
6688  /* if b > 0, we have a variable upper bound: x >= b*z + d => z <= (x-d)/b */
6689  SCIP_CALL( SCIPvarAddVub(vlbvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6690  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vlbcoef,
6691  -vlbconstant/vlbcoef, TRUE, infeasible, &nlocalbdchgs) );
6692  }
6693  else
6694  {
6695  /* if b < 0, we have a variable lower bound: x >= b*z + d => z >= (x-d)/b */
6696  SCIP_CALL( SCIPvarAddVlb(vlbvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6697  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vlbcoef,
6698  -vlbconstant/vlbcoef, TRUE, infeasible, &nlocalbdchgs) );
6699  }
6700  *nbdchgs += nlocalbdchgs;
6701  }
6702 
6703  return SCIP_OKAY;
6704 }
6705 
6706 /** informs variable x about a globally valid variable upper bound x <= b*z + d with integer variable z;
6707  * if z is binary, the corresponding valid implication for z is also added;
6708  * if z is non-continuous and 1/b not too small, the corresponding valid lower/upper bound
6709  * z >= (x-d)/b or z <= (x-d)/b (depending on the sign of of b) is added, too;
6710  * improves the global bounds of the variable and the vlb variable if possible
6711  *
6712  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6713  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6714  *
6715  * @pre This method can be called if @p scip is in one of the following stages:
6716  * - \ref SCIP_STAGE_PRESOLVING
6717  * - \ref SCIP_STAGE_PRESOLVED
6718  * - \ref SCIP_STAGE_SOLVING
6719  */
6721  SCIP* scip, /**< SCIP data structure */
6722  SCIP_VAR* var, /**< problem variable */
6723  SCIP_VAR* vubvar, /**< variable z in x <= b*z + d */
6724  SCIP_Real vubcoef, /**< coefficient b in x <= b*z + d */
6725  SCIP_Real vubconstant, /**< constant d in x <= b*z + d */
6726  SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6727  int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6728  )
6729 {
6730  int nlocalbdchgs;
6731 
6732  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarVub", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6733 
6734  SCIP_CALL( SCIPvarAddVub(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->tree,
6735  scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, vubvar, vubcoef, vubconstant, TRUE,
6736  infeasible, &nlocalbdchgs) );
6737 
6738  *nbdchgs = nlocalbdchgs;
6739 
6740  /* if x is not continuous we add a variable bound for z; do not add it if cofficient would be too small or we already
6741  * detected infeasibility
6742  */
6743  if( !(*infeasible) && SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisZero(scip, 1.0/vubcoef) )
6744  {
6745  if( vubcoef > 0.0 )
6746  {
6747  /* if b < 0, we have a variable lower bound: x >= b*z + d => z >= (x-d)/b */
6748  SCIP_CALL( SCIPvarAddVlb(vubvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6749  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vubcoef,
6750  -vubconstant/vubcoef, TRUE, infeasible, &nlocalbdchgs) );
6751  }
6752  else
6753  {
6754  /* if b > 0, we have a variable upper bound: x >= b*z + d => z <= (x-d)/b */
6755  SCIP_CALL( SCIPvarAddVub(vubvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6756  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vubcoef,
6757  -vubconstant/vubcoef, TRUE, infeasible, &nlocalbdchgs) );
6758  }
6759  *nbdchgs += nlocalbdchgs;
6760  }
6761 
6762  return SCIP_OKAY;
6763 }
6764 
6765 /** informs binary variable x about a globally valid implication: x == 0 or x == 1 ==> y <= b or y >= b;
6766  * also adds the corresponding implication or variable bound to the implied variable;
6767  * if the implication is conflicting, the variable is fixed to the opposite value;
6768  * if the variable is already fixed to the given value, the implication is performed immediately;
6769  * if the implication is redundant with respect to the variables' global bounds, it is ignored
6770  *
6771  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6772  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6773  *
6774  * @pre This method can be called if @p scip is in one of the following stages:
6775  * - \ref SCIP_STAGE_TRANSFORMED
6776  * - \ref SCIP_STAGE_PRESOLVING
6777  * - \ref SCIP_STAGE_PRESOLVED
6778  * - \ref SCIP_STAGE_SOLVING
6779  */
6781  SCIP* scip, /**< SCIP data structure */
6782  SCIP_VAR* var, /**< problem variable */
6783  SCIP_Bool varfixing, /**< FALSE if y should be added in implications for x == 0, TRUE for x == 1 */
6784  SCIP_VAR* implvar, /**< variable y in implication y <= b or y >= b */
6785  SCIP_BOUNDTYPE impltype, /**< type of implication y <= b (SCIP_BOUNDTYPE_UPPER)
6786  * or y >= b (SCIP_BOUNDTYPE_LOWER) */
6787  SCIP_Real implbound, /**< bound b in implication y <= b or y >= b */
6788  SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6789  int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6790  )
6791 {
6792  SCIP_VAR* implprobvar;
6793 
6794  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarImplication", FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6795 
6796  assert(infeasible != NULL);
6797  *infeasible = FALSE;
6798 
6799  if ( nbdchgs != NULL )
6800  *nbdchgs = 0;
6801 
6802  if( !SCIPvarIsBinary(var) )
6803  {
6804  SCIPerrorMessage("can't add implication for nonbinary variable\n");
6805  return SCIP_INVALIDDATA;
6806  }
6807 
6808  implprobvar = SCIPvarGetProbvar(implvar);
6809  /* transform implication containing two binary variables to a clique; the condition ensures that the active representative
6810  * of implvar is actually binary
6811  */
6812  if( SCIPvarIsBinary(implvar) && (SCIPvarIsActive(implvar) || (implprobvar != NULL && SCIPvarIsBinary(implprobvar))) )
6813  {
6814  assert(SCIPisFeasEQ(scip, implbound, 1.0) || SCIPisFeasZero(scip, implbound));
6815  assert((impltype == SCIP_BOUNDTYPE_UPPER) == SCIPisFeasZero(scip, implbound));
6816 
6817  /* only add clique if implication is not redundant with respect to global bounds of the implication variable */
6818  if( (impltype == SCIP_BOUNDTYPE_LOWER && SCIPvarGetLbGlobal(implvar) < 0.5) ||
6819  (impltype == SCIP_BOUNDTYPE_UPPER && SCIPvarGetUbGlobal(implvar) > 0.5) )
6820  {
6821  SCIP_VAR* vars[2];
6822  SCIP_Bool vals[2];
6823 
6824  vars[0] = var;
6825  vars[1] = implvar;
6826  vals[0] = varfixing;
6827  vals[1] = (impltype == SCIP_BOUNDTYPE_UPPER);
6828 
6829  SCIP_CALL( SCIPaddClique(scip, vars, vals, 2, FALSE, infeasible, nbdchgs) );
6830  }
6831 
6832  return SCIP_OKAY;
6833  }
6834 
6835  /* the implication graph can only handle 'real' binary (SCIP_VARTYPE_BINARY) variables, therefore we transform the
6836  * implication in variable bounds, (lowerbound of y will be abbreviated by lby, upperbound equivlaent) the follwing
6837  * four cases are:
6838  *
6839  * 1. (x >= 1 => y >= b) => y >= (b - lby) * x + lby
6840  * 2. (x >= 1 => y <= b) => y <= (b - uby) * x + uby
6841  * 3. (x <= 0 => y >= b) => y >= (lby - b) * x + b
6842  * 4. (x <= 0 => y <= b) => y <= (uby - b) * x + b
6843  */
6844  if( SCIPvarGetType(var) != SCIP_VARTYPE_BINARY )
6845  {
6846  SCIP_Real lby;
6847  SCIP_Real uby;
6848 
6849  lby = SCIPvarGetLbGlobal(implvar);
6850  uby = SCIPvarGetUbGlobal(implvar);
6851 
6852  if( varfixing == TRUE )
6853  {
6854  if( impltype == SCIP_BOUNDTYPE_LOWER )
6855  {
6856  /* we return if the lower bound is infinity */
6857  if( SCIPisInfinity(scip, -lby) )
6858  return SCIP_OKAY;
6859 
6860  SCIP_CALL( SCIPvarAddVlb(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6861  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6862  implbound - lby, lby, TRUE, infeasible, nbdchgs) );
6863  }
6864  else
6865  {
6866  /* we return if the upper bound is infinity */
6867  if( SCIPisInfinity(scip, uby) )
6868  return SCIP_OKAY;
6869 
6870  SCIP_CALL( SCIPvarAddVub(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6871  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6872  implbound - uby, uby, TRUE, infeasible, nbdchgs) );
6873  }
6874  }
6875  else
6876  {
6877  if( impltype == SCIP_BOUNDTYPE_LOWER )
6878  {
6879  /* we return if the lower bound is infinity */
6880  if( SCIPisInfinity(scip, -lby) )
6881  return SCIP_OKAY;
6882 
6883  SCIP_CALL( SCIPvarAddVlb(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6884  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6885  lby - implbound, implbound, TRUE, infeasible, nbdchgs) );
6886  }
6887  else
6888  {
6889  /* we return if the upper bound is infinity */
6890  if( SCIPisInfinity(scip, uby) )
6891  return SCIP_OKAY;
6892 
6893  SCIP_CALL( SCIPvarAddVub(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6894  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6895  uby - implbound, implbound, TRUE, infeasible, nbdchgs) );
6896  }
6897  }
6898  }
6899  else
6900  {
6901  SCIP_CALL( SCIPvarAddImplic(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6902  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, varfixing, implvar, impltype,
6903  implbound, TRUE, infeasible, nbdchgs) );
6904  }
6905 
6906  return SCIP_OKAY;
6907 }
6908 
6909 /** adds a clique information to SCIP, stating that at most one of the given binary variables can be set to 1;
6910  * if a variable appears twice in the same clique, the corresponding implications are performed
6911  *
6912  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6913  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6914  *
6915  * @pre This method can be called if @p scip is in one of the following stages:
6916  * - \ref SCIP_STAGE_TRANSFORMED
6917  * - \ref SCIP_STAGE_PRESOLVING
6918  * - \ref SCIP_STAGE_PRESOLVED
6919  * - \ref SCIP_STAGE_SOLVING
6920  */
6922  SCIP* scip, /**< SCIP data structure */
6923  SCIP_VAR** vars, /**< binary variables in the clique from which at most one can be set to 1 */
6924  SCIP_Bool* values, /**< values of the variables in the clique; NULL to use TRUE for all vars */
6925  int nvars, /**< number of variables in the clique */
6926  SCIP_Bool isequation, /**< is the clique an equation or an inequality? */
6927  SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6928  int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6929  )
6930 {
6931  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddClique", FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6932 
6933  *infeasible = FALSE;
6934  if( nbdchgs != NULL )
6935  *nbdchgs = 0;
6936 
6937  if( nvars > 1 )
6938  {
6939  /* add the clique to the clique table */
6940  SCIP_CALL( SCIPcliquetableAdd(scip->cliquetable, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6941  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, vars, values, nvars, isequation,
6942  infeasible, nbdchgs) );
6943  }
6944 
6945  return SCIP_OKAY;
6946 }
6947 
6948 /** relabels the given labels in-place in an increasing fashion: the first seen label is 0, the next label 1, etc...
6949  *
6950  * @note every label equal to -1 is treated as a previously unseen, unique label and gets a new ordered label.
6951  */
6952 static
6954  SCIP*const scip, /**< SCIP data structure */
6955  int* labels, /**< current labels that will be overwritten */
6956  int const nlabels, /**< number of variables in the clique */
6957  int* nclasses /**< pointer to store the total number of distinct labels */
6958  )
6959 {
6960  SCIP_HASHMAP* classidx2newlabel;
6961 
6962  int classidx;
6963  int i;
6964 
6965  SCIP_CALL( SCIPhashmapCreate(&classidx2newlabel, SCIPblkmem(scip), nlabels) );
6966 
6967  classidx = 0;
6968 
6969  /* loop over labels to create local class indices that obey the variable order */
6970  for( i = 0; i < nlabels; ++i )
6971  {
6972  int currentlabel = labels[i];
6973  int localclassidx;
6974 
6975  /* labels equal to -1 are stored as singleton classes */
6976  if( currentlabel == -1 )
6977  {
6978  ++classidx;
6979  localclassidx = classidx;
6980  }
6981  else
6982  {
6983  assert(currentlabel >= 0);
6984  /* look up the class index image in the hash map; if it is not stored yet, new class index is created and stored */
6985  if( !SCIPhashmapExists(classidx2newlabel, (void*)(size_t)currentlabel) )
6986  {
6987  ++classidx;
6988  localclassidx = classidx;
6989  SCIP_CALL( SCIPhashmapInsertInt(classidx2newlabel, (void*)(size_t)currentlabel, classidx) ); /*lint !e571*/
6990  }
6991  else
6992  {
6993  localclassidx = SCIPhashmapGetImageInt(classidx2newlabel, (void*)(size_t)currentlabel); /*lint !e571*/
6994  }
6995  }
6996  assert(localclassidx - 1 >= 0);
6997  assert(localclassidx - 1 <= i);
6998 
6999  /* indices start with zero, but we have an offset of 1 because we cannot store 0 in a hashmap */
7000  labels[i] = localclassidx - 1;
7001  }
7002 
7003  assert(classidx > 0);
7004  assert(classidx <= nlabels);
7005  *nclasses = classidx;
7006 
7007  SCIPhashmapFree(&classidx2newlabel);
7008 
7009  return SCIP_OKAY;
7010 }
7011 
7012 /** sort the variables w.r.t. the given labels; thereby ensure the current order of the variables with the same label. */
7013 static
7015  SCIP* scip, /**< SCIP data structure */
7016  SCIP_VAR** vars, /**< variable array */
7017  int* classlabels, /**< array that contains a class label for every variable */
7018  SCIP_VAR** sortedvars, /**< array to store variables after stable sorting */
7019  int* sortedindices, /**< array to store indices of sorted variables in the original vars array */
7020  int* classesstartposs, /**< starting position array for each label class (must have size nclasses + 1) */
7021  int nvars, /**< size of the vars arrays */
7022  int nclasses /**< number of label classes */
7023  )
7024 {
7025  SCIP_VAR*** varpointers;
7026  int** indexpointers;
7027  int* classcount;
7028 
7029  int nextpos;
7030  int c;
7031  int v;
7032 
7033  assert(scip != NULL);
7034  assert(vars != NULL);
7035  assert(sortedindices != NULL);
7036  assert(classesstartposs != NULL);
7037 
7038  assert(nvars == 0 || vars != NULL);
7039 
7040  if( nvars == 0 )
7041  return SCIP_OKAY;
7042 
7043  assert(classlabels != NULL);
7044  assert(nclasses > 0);
7045 
7046  /* we first count all class cardinalities and allocate temporary memory for a bucket sort */
7047  SCIP_CALL( SCIPallocBufferArray(scip, &classcount, nclasses) );
7048  BMSclearMemoryArray(classcount, nclasses);
7049 
7050  /* first we count for each class the number of elements */
7051  for( v = nvars - 1; v >= 0; --v )
7052  {
7053  assert(0 <= classlabels[v] && classlabels[v] < nclasses);
7054  ++(classcount[classlabels[v]]);
7055  }
7056 
7057 #ifndef NDEBUG
7058  BMSclearMemoryArray(sortedvars, nvars);
7059  BMSclearMemoryArray(sortedindices, nvars);
7060 #endif
7061  SCIP_CALL( SCIPallocBufferArray(scip, &varpointers, nclasses) );
7062  SCIP_CALL( SCIPallocBufferArray(scip, &indexpointers, nclasses) );
7063 
7064  nextpos = 0;
7065  /* now we initialize all start pointers for each class, so they will be ordered */
7066  for( c = 0; c < nclasses; ++c )
7067  {
7068  /* to reach the goal that all variables of each class will be standing next to each other we will initialize the
7069  * starting pointers for each class by adding the cardinality of each class to the last class starting pointer
7070  * e.g. class1 has 4 elements and class2 has 3 elements then the starting pointer for class1 will be the pointer
7071  * to sortedvars[0], the starting pointer to class2 will be the pointer to sortedvars[4] and to class3 it will be
7072  * the pointer to sortedvars[7]
7073  */
7074  varpointers[c] = (SCIP_VAR**) (sortedvars + nextpos);
7075  indexpointers[c] = (int*) (sortedindices + nextpos);
7076  classesstartposs[c] = nextpos;
7077  assert(classcount[c] > 0);
7078  nextpos += classcount[c];
7079  assert(nextpos > 0);
7080  }
7081  assert(nextpos == nvars);
7082  classesstartposs[c] = nextpos;
7083 
7084  /* now we copy all variables to the right order */
7085  for( v = 0; v < nvars; ++v )
7086  {
7087  /* copy variable itself to the right position */
7088  *(varpointers[classlabels[v]]) = vars[v]; /*lint !e613*/
7089  ++(varpointers[classlabels[v]]);
7090 
7091  /* copy index */
7092  *(indexpointers[classlabels[v]]) = v;
7093  ++(indexpointers[classlabels[v]]);
7094  }
7095 
7096 /* in debug mode, we ensure the correctness of the mapping */
7097 #ifndef NDEBUG
7098  for( v = 0; v < nvars; ++v )
7099  {
7100  assert(sortedvars[v] != NULL);
7101  assert(sortedindices[v] >= 0);
7102 
7103  /* assert that the sorted indices map back to the correct variable in the original order */
7104  assert(vars[sortedindices[v]] == sortedvars[v]);
7105  }
7106 #endif
7107 
7108  /* free temporary memory */
7109  SCIPfreeBufferArray(scip, &indexpointers);
7110  SCIPfreeBufferArray(scip, &varpointers);
7111  SCIPfreeBufferArray(scip, &classcount);
7112 
7113  return SCIP_OKAY;
7114 }
7115 
7116 
7117 /* calculate clique partition for a maximal amount of comparisons on variables due to expensive algorithm
7118  * @todo: check for a good value, maybe it's better to check parts of variables
7119  */
7120 #define MAXNCLIQUEVARSCOMP 1000000
7121 
7122 /** calculates a partition of the given set of binary variables into cliques;
7123  * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7124  * were assigned to the same clique;
7125  * the first variable is always assigned to clique 0, and a variable can only be assigned to clique i if at least one of
7126  * the preceding variables was assigned to clique i-1;
7127  * for each clique at most 1 variables can be set to TRUE in a feasible solution;
7128  *
7129  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7130  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7131  *
7132  * @pre This method can be called if @p scip is in one of the following stages:
7133  * - \ref SCIP_STAGE_INITPRESOLVE
7134  * - \ref SCIP_STAGE_PRESOLVING
7135  * - \ref SCIP_STAGE_EXITPRESOLVE
7136  * - \ref SCIP_STAGE_PRESOLVED
7137  * - \ref SCIP_STAGE_SOLVING
7138  */
7139 static
7141  SCIP*const scip, /**< SCIP data structure */
7142  SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7143  SCIP_Bool*const values, /**< clique value (TRUE or FALSE) for each variable in the clique */
7144  int const nvars, /**< number of variables in the array */
7145  int*const cliquepartition, /**< array of length nvars to store the clique partition */
7146  int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7147  )
7148 {
7149  SCIP_VAR** cliquevars;
7150  SCIP_Bool* cliquevalues;
7151  int i;
7152  int maxncliquevarscomp;
7153  int ncliquevars;
7154 
7155  /* allocate temporary memory for storing the variables of the current clique */
7156  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &cliquevars, nvars) );
7157  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &cliquevalues, nvars) );
7158 
7159  /* initialize the cliquepartition array with -1 */
7160  for( i = nvars - 1; i >= 0; --i )
7161  cliquepartition[i] = -1;
7162 
7163  maxncliquevarscomp = (int) MIN(nvars * (SCIP_Longint)nvars, MAXNCLIQUEVARSCOMP);
7164  /* calculate the clique partition */
7165  *ncliques = 0;
7166  for( i = 0; i < nvars; ++i )
7167  {
7168  if( cliquepartition[i] == -1 )
7169  {
7170  int j;
7171 
7172  /* variable starts a new clique */
7173  cliquepartition[i] = *ncliques;
7174  cliquevars[0] = vars[i];
7175  cliquevalues[0] = values[i];
7176  ncliquevars = 1;
7177 
7178  /* if variable is not active (multi-aggregated or fixed), it cannot be in any clique */
7179  if( SCIPvarIsActive(vars[i]) && SCIPvarGetNCliques(vars[i], values[i]) > 0 )
7180  {
7181  /* greedily fill up the clique */
7182  for( j = i+1; j < nvars; ++j )
7183  {
7184  /* if variable is not active (multi-aggregated or fixed), it cannot be in any clique */
7185  if( cliquepartition[j] == -1 && SCIPvarIsActive(vars[j]) )
7186  {
7187  int k;
7188 
7189  /* check if every variable in the current clique can be extended by tmpvars[j] */
7190  for( k = ncliquevars - 1; k >= 0; --k )
7191  {
7192  if( !SCIPvarsHaveCommonClique(vars[j], values[j], cliquevars[k], cliquevalues[k], FALSE) )
7193  break;
7194  }
7195 
7196  if( k == -1 )
7197  {
7198  /* put the variable into the same clique */
7199  cliquepartition[j] = cliquepartition[i];
7200  cliquevars[ncliquevars] = vars[j];
7201  cliquevalues[ncliquevars] = values[j];
7202  ++ncliquevars;
7203  }
7204  }
7205  }
7206  }
7207 
7208  /* this clique is finished */
7209  ++(*ncliques);
7210  }
7211  assert(cliquepartition[i] >= 0 && cliquepartition[i] < i+1);
7212 
7213  /* break if we reached the maximal number of comparisons */
7214  if( i * nvars > maxncliquevarscomp )
7215  break;
7216  }
7217  /* if we had to many variables fill up the cliquepartition and put each variable in a separate clique */
7218  for( ; i < nvars; ++i )
7219  {
7220  if( cliquepartition[i] == -1 )
7221  {
7222  cliquepartition[i] = *ncliques;
7223  ++(*ncliques);
7224  }
7225  }
7226 
7227  SCIPsetFreeBufferArray(scip->set, &cliquevalues);
7228  SCIPsetFreeBufferArray(scip->set, &cliquevars);
7229 
7230  return SCIP_OKAY;
7231 }
7232 
7233 /** calculates a partition of the given set of binary variables into cliques; takes into account independent clique components
7234  *
7235  * The algorithm performs the following steps:
7236  * - recomputes connected components of the clique table, if necessary
7237  * - computes a clique partition for every connected component greedily.
7238  * - relabels the resulting clique partition such that it satisfies the description below
7239  *
7240  * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7241  * were assigned to the same clique;
7242  * the first variable is always assigned to clique 0, and a variable can only be assigned to clique i if at least one of
7243  * the preceding variables was assigned to clique i-1;
7244  * for each clique at most 1 variables can be set to TRUE in a feasible solution;
7245  *
7246  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7247  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7248  *
7249  * @pre This method can be called if @p scip is in one of the following stages:
7250  * - \ref SCIP_STAGE_INITPRESOLVE
7251  * - \ref SCIP_STAGE_PRESOLVING
7252  * - \ref SCIP_STAGE_EXITPRESOLVE
7253  * - \ref SCIP_STAGE_PRESOLVED
7254  * - \ref SCIP_STAGE_SOLVING
7255  */
7257  SCIP*const scip, /**< SCIP data structure */
7258  SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7259  int const nvars, /**< number of variables in the clique */
7260  int*const cliquepartition, /**< array of length nvars to store the clique partition */
7261  int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7262  )
7263 {
7264  SCIP_VAR** tmpvars;
7265 
7266  SCIP_VAR** sortedtmpvars;
7267  SCIP_Bool* tmpvalues;
7268  SCIP_Bool* sortedtmpvalues;
7269  int* componentlabels;
7270  int* sortedindices;
7271  int* componentstartposs;
7272  int i;
7273  int c;
7274 
7275  int ncomponents;
7276 
7277  assert(scip != NULL);
7278  assert(nvars == 0 || vars != NULL);
7279  assert(nvars == 0 || cliquepartition != NULL);
7280  assert(ncliques != NULL);
7281 
7282  SCIP_CALL( SCIPcheckStage(scip, "SCIPcalcCliquePartition", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7283 
7284  if( nvars == 0 )
7285  {
7286  *ncliques = 0;
7287  return SCIP_OKAY;
7288  }
7289 
7290  /* early abort if no cliques are present */
7291  if( SCIPgetNCliques(scip) == 0 )
7292  {
7293  for( i = 0; i < nvars; ++i )
7294  cliquepartition[i] = i;
7295 
7296  *ncliques = nvars;
7297 
7298  return SCIP_OKAY;
7299  }
7300 
7301  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &tmpvalues, nvars) );
7302  SCIP_CALL( SCIPsetDuplicateBufferArray(scip->set, &tmpvars, vars, nvars) );
7303  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &componentlabels, nvars) );
7304  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedindices, nvars) );
7305 
7306  /* initialize the tmpvalues array */
7307  for( i = nvars - 1; i >= 0; --i )
7308  {
7309  tmpvalues[i] = TRUE;
7310  cliquepartition[i] = -1;
7311  }
7312 
7313  /* get corresponding active problem variables */
7314  SCIP_CALL( SCIPvarsGetProbvarBinary(&tmpvars, &tmpvalues, nvars) );
7315 
7316  ncomponents = -1;
7317 
7318  /* update clique components if necessary */
7320  {
7321  SCIP_VAR** allvars;
7322  int nallbinvars;
7323  int nallintvars;
7324  int nallimplvars;
7325 
7326  SCIP_CALL( SCIPgetVarsData(scip, &allvars, NULL, &nallbinvars, &nallintvars, &nallimplvars, NULL) );
7327 
7328  SCIP_CALL( SCIPcliquetableComputeCliqueComponents(scip->cliquetable, scip->set, SCIPblkmem(scip), allvars, nallbinvars, nallintvars, nallimplvars) );
7329  }
7330 
7332 
7333  /* store the global clique component labels */
7334  for( i = 0; i < nvars; ++i )
7335  {
7336  if( SCIPvarIsActive(tmpvars[i]) )
7337  componentlabels[i] = SCIPcliquetableGetVarComponentIdx(scip->cliquetable, tmpvars[i]);
7338  else
7339  componentlabels[i] = -1;
7340  }
7341 
7342  /* relabel component labels order consistent as prerequisite for a stable sort */
7343  SCIP_CALL( relabelOrderConsistent(scip, componentlabels, nvars, &ncomponents) );
7344  assert(ncomponents >= 1);
7345  assert(ncomponents <= nvars);
7346 
7347  /* allocate storage array for the starting positions of the components */
7348  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &componentstartposs, ncomponents + 1) );
7349 
7350  /* stable sort the variables w.r.t. the component labels so that we can restrict the quadratic algorithm to the components */
7351  if( ncomponents > 1 )
7352  {
7353  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedtmpvars, nvars) );
7354  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedtmpvalues, nvars) );
7355  SCIP_CALL( labelSortStable(scip, tmpvars, componentlabels, sortedtmpvars, sortedindices, componentstartposs, nvars, ncomponents) );
7356 
7357  /* reassign the tmpvalues with respect to the sorting */
7358  for( i = 0; i < nvars; ++i )
7359  {
7360  assert(tmpvars[sortedindices[i]] == sortedtmpvars[i]);
7361  sortedtmpvalues[i] = tmpvalues[sortedindices[i]];
7362  }
7363  }
7364  else
7365  {
7366  /* if we have only one large connected component, skip the stable sorting and prepare the data differently */
7367  sortedtmpvars = tmpvars;
7368  sortedtmpvalues = tmpvalues;
7369  componentstartposs[0] = 0;
7370  componentstartposs[1] = nvars;
7371 
7372  /* sorted indices are the identity */
7373  for( i = 0; i < nvars; ++i )
7374  sortedindices[i] = i;
7375  }
7376 
7377  *ncliques = 0;
7378  /* calculate a greedy clique partition for each connected component */
7379  for( c = 0; c < ncomponents; ++c )
7380  {
7381  int* localcliquepartition;
7382  int nlocalcliques;
7383  int ncomponentvars;
7384  int l;
7385 
7386  /* extract the number of variables in this connected component */
7387  ncomponentvars = componentstartposs[c + 1] - componentstartposs[c];
7388  nlocalcliques = 0;
7389 
7390  /* allocate necessary memory to hold the intermediate component clique partition */
7391  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &localcliquepartition, ncomponentvars) );
7392 
7393  /* call greedy clique algorithm for all component variables */
7394  SCIP_CALL( calcCliquePartitionGreedy(scip, &(sortedtmpvars[componentstartposs[c]]), &(sortedtmpvalues[componentstartposs[c]]),
7395  ncomponentvars, localcliquepartition, &nlocalcliques) );
7396 
7397  assert(nlocalcliques >= 1);
7398  assert(nlocalcliques <= ncomponentvars);
7399 
7400  /* store the obtained clique partition with an offset of ncliques for the original variables */
7401  for( l = componentstartposs[c]; l < componentstartposs[c + 1]; ++l )
7402  {
7403  int origvaridx = sortedindices[l];
7404  assert(cliquepartition[origvaridx] == -1);
7405  assert(localcliquepartition[l - componentstartposs[c]] <= l - componentstartposs[c]);
7406  cliquepartition[origvaridx] = localcliquepartition[l - componentstartposs[c]] + (*ncliques);
7407  }
7408  *ncliques += nlocalcliques;
7409 
7410  /* free the local clique partition */
7411  SCIPsetFreeBufferArray(scip->set, &localcliquepartition);
7412  }
7413 
7414  /* except in the two trivial cases, we have to ensure the order consistency of the partition indices */
7415  if( ncomponents > 1 && ncomponents < nvars )
7416  {
7417  int partitionsize;
7418  SCIP_CALL( relabelOrderConsistent(scip, cliquepartition, nvars, &partitionsize) );
7419 
7420  assert(partitionsize == *ncliques);
7421  }
7422 
7423  if( ncomponents > 1 )
7424  {
7425  SCIPsetFreeBufferArray(scip->set, &sortedtmpvalues);
7426  SCIPsetFreeBufferArray(scip->set, &sortedtmpvars);
7427  }
7428 
7429  /* use the greedy algorithm as a whole to verify the result on small number of variables */
7430 #ifdef SCIP_DISABLED_CODE
7431  {
7432  int* debugcliquepartition;
7433  int ndebugcliques;
7434 
7435  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &debugcliquepartition, nvars) );
7436 
7437  /* call greedy clique algorithm for all component variables */
7438  SCIP_CALL( calcCliquePartitionGreedy(scip, tmpvars, tmpvalues, nvars, debugcliquepartition, &ndebugcliques) );
7439 
7440  /* loop and compare the traditional greedy clique with */
7441  for( i = 0; i < nvars; ++i )
7442  assert(i * nvars > MAXNCLIQUEVARSCOMP || cliquepartition[i] == debugcliquepartition[i]);
7443 
7444  SCIPsetFreeBufferArray(scip->set, &debugcliquepartition);
7445  }
7446 #endif
7447 
7448  /* free temporary memory */
7449  SCIPsetFreeBufferArray(scip->set, &componentstartposs);
7450  SCIPsetFreeBufferArray(scip->set, &sortedindices);
7451  SCIPsetFreeBufferArray(scip->set, &componentlabels);
7452  SCIPsetFreeBufferArray(scip->set, &tmpvars);
7453  SCIPsetFreeBufferArray(scip->set, &tmpvalues);
7454 
7455  return SCIP_OKAY;
7456 }
7457 
7458 /** calculates a partition of the given set of binary variables into negated cliques;
7459  * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7460  * were assigned to the same negated clique;
7461  * the first variable is always assigned to clique 0 and a variable can only be assigned to clique i if at least one of
7462  * the preceding variables was assigned to clique i-1;
7463  * for each clique with n_c variables at least n_c-1 variables can be set to TRUE in a feasible solution;
7464  *
7465  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7466  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7467  *
7468  * @pre This method can be called if @p scip is in one of the following stages:
7469  * - \ref SCIP_STAGE_INITPRESOLVE
7470  * - \ref SCIP_STAGE_PRESOLVING
7471  * - \ref SCIP_STAGE_EXITPRESOLVE
7472  * - \ref SCIP_STAGE_PRESOLVED
7473  * - \ref SCIP_STAGE_SOLVING
7474  */
7476  SCIP*const scip, /**< SCIP data structure */
7477  SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7478  int const nvars, /**< number of variables in the clique */
7479  int*const cliquepartition, /**< array of length nvars to store the clique partition */
7480  int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7481  )
7482 {
7483  SCIP_VAR** negvars;
7484  int v;
7485 
7486  assert(scip != NULL);
7487  assert(cliquepartition != NULL || nvars == 0);
7488  assert(ncliques != NULL);
7489 
7490  if( nvars == 0 )
7491  {
7492  *ncliques = 0;
7493  return SCIP_OKAY;
7494  }
7495  assert(vars != NULL);
7496 
7497  /* allocate temporary memory */
7498  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &negvars, nvars) );
7499 
7500  /* get all negated variables */
7501  for( v = nvars - 1; v >= 0; --v )
7502  {
7503  SCIP_CALL( SCIPgetNegatedVar(scip, vars[v], &(negvars[v])) );
7504  }
7505 
7506  /* calculate cliques on negated variables, which are "negated" cliques on normal variables array */
7507  SCIP_CALL( SCIPcalcCliquePartition( scip, negvars, nvars, cliquepartition, ncliques) );
7508 
7509  /* free temporary memory */
7510  SCIPsetFreeBufferArray(scip->set, &negvars);
7511 
7512  return SCIP_OKAY;
7513 }
7514 
7515 
7516 /** force SCIP to clean up all cliques; cliques do not get automatically cleaned up after presolving. Use
7517  * this method to prevent inactive variables in cliques when retrieved via SCIPgetCliques()
7518  *
7519  * @return SCIP_OKAY if everything worked, otherwise a suitable error code is passed
7520  *
7521  * @pre This method can be called if @p scip is in one of the following stages:
7522  * - \ref SCIP_STAGE_TRANSFORMED
7523  * - \ref SCIP_STAGE_INITPRESOLVE
7524  * - \ref SCIP_STAGE_PRESOLVING
7525  * - \ref SCIP_STAGE_EXITPRESOLVE
7526  * - \ref SCIP_STAGE_PRESOLVED
7527  * - \ref SCIP_STAGE_INITSOLVE
7528  * - \ref SCIP_STAGE_SOLVING
7529  * - \ref SCIP_STAGE_SOLVED
7530  * - \ref SCIP_STAGE_EXITSOLVE
7531  */
7533  SCIP* scip, /**< SCIP data structure */
7534  SCIP_Bool* infeasible /**< pointer to store if cleanup detected infeasibility */
7535  )
7536 {
7537  int nlocalbdchgs;
7538  SCIP_Bool globalinfeasibility;
7539 
7540  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPcleanupCliques", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7541 
7542  globalinfeasibility = FALSE;
7543  nlocalbdchgs = 0;
7544  SCIP_CALL( SCIPcliquetableCleanup(scip->cliquetable, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
7545  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, &nlocalbdchgs,
7546  &globalinfeasibility) );
7547 
7548  if( infeasible != NULL )
7549  *infeasible = globalinfeasibility;
7550 
7551  if( globalinfeasibility )
7553 
7554  return SCIP_OKAY;
7555 }
7556 
7557 /** gets the number of cliques in the clique table
7558  *
7559  * @return number of cliques in the clique table
7560  *
7561  * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7562  * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
7563  *
7564  * @pre This method can be called if @p scip is in one of the following stages:
7565  * - \ref SCIP_STAGE_TRANSFORMED
7566  * - \ref SCIP_STAGE_INITPRESOLVE
7567  * - \ref SCIP_STAGE_PRESOLVING
7568  * - \ref SCIP_STAGE_EXITPRESOLVE
7569  * - \ref SCIP_STAGE_PRESOLVED
7570  * - \ref SCIP_STAGE_INITSOLVE
7571  * - \ref SCIP_STAGE_SOLVING
7572  * - \ref SCIP_STAGE_SOLVED
7573  * - \ref SCIP_STAGE_EXITSOLVE
7574  */
7576  SCIP* scip /**< SCIP data structure */
7577  )
7578 {
7579  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNCliques", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7580 
7582 }
7583 
7584 /** gets the number of cliques created so far by the cliquetable
7585  *
7586  * @return number of cliques created so far by the cliquetable
7587  *
7588  * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7589  * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
7590  *
7591  * @pre This method can be called if @p scip is in one of the following stages:
7592  * - \ref SCIP_STAGE_TRANSFORMED
7593  * - \ref SCIP_STAGE_INITPRESOLVE
7594  * - \ref SCIP_STAGE_PRESOLVING
7595  * - \ref SCIP_STAGE_EXITPRESOLVE
7596  * - \ref SCIP_STAGE_PRESOLVED
7597  * - \ref SCIP_STAGE_INITSOLVE
7598  * - \ref SCIP_STAGE_SOLVING
7599  * - \ref SCIP_STAGE_SOLVED
7600  * - \ref SCIP_STAGE_EXITSOLVE
7601  */
7603  SCIP* scip /**< SCIP data structure */
7604  )
7605 {
7606  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNCliquesCreated", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7607 
7609 }
7610 
7611 /** gets the array of cliques in the clique table
7612  *
7613  * @return array of cliques in the clique table
7614  *
7615  * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7616  * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
7617  *
7618  * @pre This method can be called if @p scip is in one of the following stages:
7619  * - \ref SCIP_STAGE_TRANSFORMED
7620  * - \ref SCIP_STAGE_INITPRESOLVE
7621  * - \ref SCIP_STAGE_PRESOLVING
7622  * - \ref SCIP_STAGE_EXITPRESOLVE
7623  * - \ref SCIP_STAGE_PRESOLVED
7624  * - \ref SCIP_STAGE_INITSOLVE
7625  * - \ref SCIP_STAGE_SOLVING
7626  * - \ref SCIP_STAGE_SOLVED
7627  * - \ref SCIP_STAGE_EXITSOLVE
7628  */
7630  SCIP* scip /**< SCIP data structure */
7631  )
7632 {
7633  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetCliques", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7634 
7635  return SCIPcliquetableGetCliques(scip->cliquetable);
7636 }
7637 
7638 /** returns whether there is a clique that contains both given variable/value pairs;
7639  * the variables must be active binary variables;
7640  * if regardimplics is FALSE, only the cliques in the clique table are looked at;
7641  * if regardimplics is TRUE, both the cliques and the implications of the implication graph are regarded
7642  *
7643  * @return TRUE, if there is a clique that contains both variable/clique pairs; FALSE, otherwise
7644  *
7645  * @pre This method can be called if @p scip is in one of the following stages:
7646  * - \ref SCIP_STAGE_TRANSFORMED
7647  * - \ref SCIP_STAGE_INITPRESOLVE
7648  * - \ref SCIP_STAGE_PRESOLVING
7649  * - \ref SCIP_STAGE_EXITPRESOLVE
7650  * - \ref SCIP_STAGE_PRESOLVED
7651  * - \ref SCIP_STAGE_INITSOLVE
7652  * - \ref SCIP_STAGE_SOLVING
7653  * - \ref SCIP_STAGE_SOLVED
7654  * - \ref SCIP_STAGE_EXITSOLVE
7655  *
7656  * @note a variable with it's negated variable are NOT! in a clique
7657  * @note a variable with itself are in a clique
7658  */
7660  SCIP* scip, /**< SCIP data structure */
7661  SCIP_VAR* var1, /**< first variable */
7662  SCIP_Bool value1, /**< value of first variable */
7663  SCIP_VAR* var2, /**< second variable */
7664  SCIP_Bool value2, /**< value of second variable */
7665  SCIP_Bool regardimplics /**< should the implication graph also be searched for a clique? */
7666  )
7667 {
7668  assert(scip != NULL);
7669  assert(var1 != NULL);
7670  assert(var2 != NULL);
7671  assert(SCIPvarIsActive(var1));
7672  assert(SCIPvarIsActive(var2));
7673  assert(SCIPvarIsBinary(var1));
7674  assert(SCIPvarIsBinary(var2));
7675 
7676  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPhaveVarsCommonClique", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7677 
7678  /* if both variables together have more cliques then actual cliques exist, then they have a common clique (in debug
7679  * mode we check this for correctness), otherwise we need to call the pairwise comparison method for these variables
7680  */
7681 #ifndef NDEBUG
7682  assert((SCIPvarGetNCliques(var1, value1) + SCIPvarGetNCliques(var2, value2) > SCIPcliquetableGetNCliques(scip->cliquetable)) ? SCIPvarsHaveCommonClique(var1, value1, var2, value2, FALSE) : TRUE);
7683 #endif
7684 
7685  return (SCIPvarGetNCliques(var1, value1) + SCIPvarGetNCliques(var2, value2) > SCIPcliquetableGetNCliques(scip->cliquetable)
7686  || SCIPvarsHaveCommonClique(var1, value1, var2, value2, regardimplics));
7687 }
7688 
7689 /** writes the clique graph to a gml file
7690  *
7691  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7692  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7693  *
7694  * @pre This method can be called if @p scip is in one of the following stages:
7695  * - \ref SCIP_STAGE_TRANSFORMED
7696  * - \ref SCIP_STAGE_INITPRESOLVE
7697  * - \ref SCIP_STAGE_PRESOLVING
7698  * - \ref SCIP_STAGE_EXITPRESOLVE
7699  * - \ref SCIP_STAGE_PRESOLVED
7700  * - \ref SCIP_STAGE_INITSOLVE
7701  * - \ref SCIP_STAGE_SOLVING
7702  * - \ref SCIP_STAGE_SOLVED
7703  * - \ref SCIP_STAGE_EXITSOLVE
7704  *
7705  * @note there can be duplicated arcs in the output file
7706  *
7707  * If @p writenodeweights is true, only nodes corresponding to variables that have a fractional value and only edges
7708  * between such nodes are written.
7709  */
7711  SCIP* scip, /**< SCIP data structure */
7712  const char* fname, /**< name of file */
7713  SCIP_Bool writenodeweights /**< should we write weights of nodes? */
7714  )
7715 {
7716  FILE* gmlfile;
7717  SCIP_HASHMAP* nodehashmap;
7718  SCIP_CLIQUE** cliques;
7719  SCIP_VAR** clqvars;
7720  SCIP_VAR** allvars;
7721  SCIP_Bool* clqvalues;
7722  char nodename[SCIP_MAXSTRLEN];
7723  int nallvars;
7724  int nbinvars;
7725  int nintvars;
7726  int nimplvars;
7727  int ncliques;
7728  int c;
7729  int v1;
7730  int v2;
7731  int id1;
7732  int id2;
7733 
7734  assert(scip != NULL);
7735  assert(fname != NULL);
7736 
7737  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPwriteCliqueGraph", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7738 
7739  /* get all active variables */
7740  SCIP_CALL( SCIPgetVarsData(scip, &allvars, &nallvars, &nbinvars, &nintvars, &nimplvars, NULL) );
7741 
7742  /* no possible variables for cliques exist */
7743  if( nbinvars + nimplvars == 0 )
7744  return SCIP_OKAY;
7745 
7746  ncliques = SCIPgetNCliques(scip);
7747 
7748  /* no cliques and do not wont to check for binary implications */
7749  if( ncliques == 0 )
7750  return SCIP_OKAY;
7751 
7752  /* open gml file */
7753  gmlfile = fopen(fname, "w");
7754 
7755  if( gmlfile == NULL )
7756  {
7757  SCIPerrorMessage("cannot open graph file <%s>\n", fname);
7758  SCIPABORT();
7759  return SCIP_INVALIDDATA; /*lint !e527*/
7760  }
7761 
7762  /* create the hash map */
7763  SCIP_CALL_FINALLY( SCIPhashmapCreate(&nodehashmap, SCIPblkmem(scip), nbinvars+nimplvars), fclose(gmlfile) );
7764 
7765  /* write starting of gml file */
7766  SCIPgmlWriteOpening(gmlfile, TRUE);
7767 
7768  cliques = SCIPgetCliques(scip);
7769 
7770  /* write nodes and arcs for all cliques */
7771  for( c = ncliques - 1; c >= 0; --c )
7772  {
7773  clqvalues = SCIPcliqueGetValues(cliques[c]);
7774  clqvars = SCIPcliqueGetVars(cliques[c]);
7775 
7776  for( v1 = SCIPcliqueGetNVars(cliques[c]) - 1; v1 >= 0; --v1 )
7777  {
7778  id1 = clqvalues[v1] ? SCIPvarGetProbindex(clqvars[v1]) : (nallvars + SCIPvarGetProbindex(clqvars[v1]));
7779 
7780  /* if corresponding node was not added yet, add it */
7781  if( !SCIPhashmapExists(nodehashmap, (void*)(size_t)id1) )
7782  {
7783  assert(id1 >= 0);
7784  SCIP_CALL_FINALLY( SCIPhashmapInsertInt(nodehashmap, (void*)(size_t)id1, 1), fclose(gmlfile) ); /*lint !e571*/
7785 
7786  (void) SCIPsnprintf(nodename, SCIP_MAXSTRLEN, "%s%s", (id1 >= nallvars ? "~" : ""), SCIPvarGetName(clqvars[v1]));
7787 
7788  /* write new gml node for new variable */
7789  if ( writenodeweights )
7790  {
7791  if ( ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v1])) )
7792  SCIPgmlWriteNodeWeight(gmlfile, (unsigned int)id1, nodename, NULL, NULL, NULL, SCIPgetSolVal(scip, NULL, clqvars[v1]));
7793  }
7794  else
7795  {
7796  SCIPgmlWriteNode(gmlfile, (unsigned int)id1, nodename, NULL, NULL, NULL);
7797  }
7798  }
7799 
7800  for( v2 = SCIPcliqueGetNVars(cliques[c]) - 1; v2 >= 0; --v2 )
7801  {
7802  if( v1 == v2 )
7803  continue;
7804 
7805  id2 = clqvalues[v2] ? SCIPvarGetProbindex(clqvars[v2]) : (nallvars + SCIPvarGetProbindex(clqvars[v2]));
7806 
7807  /* if corresponding node was not added yet, add it */
7808  if( !SCIPhashmapExists(nodehashmap, (void*)(size_t)id2) )
7809  {
7810  assert(id2 >= 0);
7811  SCIP_CALL_FINALLY( SCIPhashmapInsertInt(nodehashmap, (void*)(size_t)id2, 1), fclose(gmlfile) ); /*lint !e571*/
7812 
7813  (void) SCIPsnprintf(nodename, SCIP_MAXSTRLEN, "%s%s", (id2 >= nallvars ? "~" : ""), SCIPvarGetName(clqvars[v2]));
7814 
7815  /* write new gml node for new variable */
7816  if ( writenodeweights )
7817  {
7818  if ( ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v2])) )
7819  SCIPgmlWriteNodeWeight(gmlfile, (unsigned int)id2, nodename, NULL, NULL, NULL, SCIPgetSolVal(scip, NULL, clqvars[v2]));
7820  }
7821  else
7822  {
7823  SCIPgmlWriteNode(gmlfile, (unsigned int)id2, nodename, NULL, NULL, NULL);
7824  }
7825  }
7826 
7827  /* write gml arc between resultant and operand */
7828  if ( ! writenodeweights || ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v2])) )
7829  SCIPgmlWriteArc(gmlfile, (unsigned int)id1, (unsigned int)id2, NULL, NULL);
7830  }
7831  }
7832  }
7833 
7834  /* free the hash map */
7835  SCIPhashmapFree(&nodehashmap);
7836 
7837  SCIPgmlWriteClosing(gmlfile);
7838  fclose(gmlfile);
7839 
7840  return SCIP_OKAY;
7841 }
7842 
7843 /** Removes (irrelevant) variable from all its global structures, i.e. cliques, implications and variable bounds.
7844  * This is an advanced method which should be used with care.
7845  *
7846  * @return SCIP_OKAY if everything worked, otherwise a suitable error code is passed
7847  *
7848  * @pre This method can be called if @p scip is in one of the following stages:
7849  * - \ref SCIP_STAGE_TRANSFORMED
7850  * - \ref SCIP_STAGE_INITPRESOLVE
7851  * - \ref SCIP_STAGE_PRESOLVING
7852  * - \ref SCIP_STAGE_EXITPRESOLVE
7853  * - \ref SCIP_STAGE_PRESOLVED
7854  * - \ref SCIP_STAGE_INITSOLVE
7855  * - \ref SCIP_STAGE_SOLVING
7856  * - \ref SCIP_STAGE_SOLVED
7857  * - \ref SCIP_STAGE_EXITSOLVE
7858  */
7860  SCIP* scip, /**< SCIP data structure */
7861  SCIP_VAR* var /**< variable to remove from global structures */
7862  )
7863 {
7864  assert(scip != NULL);
7865 
7866  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPremoveVarFromGlobalStructures", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7867 
7868  /* mark the variable as deletable from global structures - This is necessary for the delayed clean up of cliques */
7870 
7871  /* remove variable from all its cliques, implications, and variable bounds */
7873 
7874  return SCIP_OKAY;
7875 }
7876 
7877 /** sets the branch factor of the variable; this value can be used in the branching methods to scale the score
7878  * values of the variables; higher factor leads to a higher probability that this variable is chosen for branching
7879  *
7880  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7881  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7882  *
7883  * @pre This method can be called if @p scip is in one of the following stages:
7884  * - \ref SCIP_STAGE_PROBLEM
7885  * - \ref SCIP_STAGE_TRANSFORMING
7886  * - \ref SCIP_STAGE_TRANSFORMED
7887  * - \ref SCIP_STAGE_INITPRESOLVE
7888  * - \ref SCIP_STAGE_PRESOLVING
7889  * - \ref SCIP_STAGE_EXITPRESOLVE
7890  * - \ref SCIP_STAGE_PRESOLVED
7891  * - \ref SCIP_STAGE_SOLVING
7892  */
7894  SCIP* scip, /**< SCIP data structure */
7895  SCIP_VAR* var, /**< problem variable */
7896  SCIP_Real branchfactor /**< factor to weigh variable's branching score with */
7897  )
7898 {
7899  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7900 
7901  SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, branchfactor) );
7902 
7903  return SCIP_OKAY;
7904 }
7905 
7906 /** scales the branch factor of the variable with the given value
7907  *
7908  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7909  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7910  *
7911  * @pre This method can be called if @p scip is in one of the following stages:
7912  * - \ref SCIP_STAGE_PROBLEM
7913  * - \ref SCIP_STAGE_TRANSFORMING
7914  * - \ref SCIP_STAGE_TRANSFORMED
7915  * - \ref SCIP_STAGE_INITPRESOLVE
7916  * - \ref SCIP_STAGE_PRESOLVING
7917  * - \ref SCIP_STAGE_EXITPRESOLVE
7918  * - \ref SCIP_STAGE_PRESOLVED
7919  * - \ref SCIP_STAGE_SOLVING
7920  */
7922  SCIP* scip, /**< SCIP data structure */
7923  SCIP_VAR* var, /**< problem variable */
7924  SCIP_Real scale /**< factor to scale variable's branching factor with */
7925  )
7926 {
7927  SCIP_CALL( SCIPcheckStage(scip, "SCIPscaleVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7928 
7929  SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, scale * SCIPvarGetBranchFactor(var)) );
7930 
7931  return SCIP_OKAY;
7932 }
7933 
7934 /** adds the given value to the branch factor of the variable
7935  *
7936  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7937  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7938  *
7939  * @pre This method can be called if @p scip is in one of the following stages:
7940  * - \ref SCIP_STAGE_PROBLEM
7941  * - \ref SCIP_STAGE_TRANSFORMING
7942  * - \ref SCIP_STAGE_TRANSFORMED
7943  * - \ref SCIP_STAGE_INITPRESOLVE
7944  * - \ref SCIP_STAGE_PRESOLVING
7945  * - \ref SCIP_STAGE_EXITPRESOLVE
7946  * - \ref SCIP_STAGE_PRESOLVED
7947  * - \ref SCIP_STAGE_SOLVING
7948  */
7950  SCIP* scip, /**< SCIP data structure */
7951  SCIP_VAR* var, /**< problem variable */
7952  SCIP_Real addfactor /**< value to add to the branch factor of the variable */
7953  )
7954 {
7955  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7956 
7957  SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, addfactor + SCIPvarGetBranchFactor(var)) );
7958 
7959  return SCIP_OKAY;
7960 }
7961 
7962 /** sets the branch priority of the variable; variables with higher branch priority are always preferred to variables
7963  * with lower priority in selection of branching variable
7964  *
7965  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7966  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7967  *
7968  * @pre This method can be called if @p scip is in one of the following stages:
7969  * - \ref SCIP_STAGE_PROBLEM
7970  * - \ref SCIP_STAGE_TRANSFORMING
7971  * - \ref SCIP_STAGE_TRANSFORMED
7972  * - \ref SCIP_STAGE_INITPRESOLVE
7973  * - \ref SCIP_STAGE_PRESOLVING
7974  * - \ref SCIP_STAGE_EXITPRESOLVE
7975  * - \ref SCIP_STAGE_PRESOLVED
7976  * - \ref SCIP_STAGE_SOLVING
7977  *
7978  * @note the default branching priority is 0
7979  */
7981  SCIP* scip, /**< SCIP data structure */
7982  SCIP_VAR* var, /**< problem variable */
7983  int branchpriority /**< branch priority of the variable */
7984  )
7985 {
7986  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7987 
7988  assert( var->scip == scip );
7989 
7990  if( SCIPisTransformed(scip) )
7991  {
7992  assert(scip->branchcand != NULL);
7993 
7994  /* inform the pseudo branch candidates that the branch priority changes and change the branch priority */
7995  SCIP_CALL( SCIPbranchcandUpdateVarBranchPriority(scip->branchcand, scip->set, var, branchpriority) );
7996  }
7997  else
7998  {
7999  /* change the branching priority of the variable */
8000  SCIP_CALL( SCIPvarChgBranchPriority(var, branchpriority) );
8001  }
8002 
8003  return SCIP_OKAY;
8004 }
8005 
8006 /** changes the branch priority of the variable to the given value, if it is larger than the current priority
8007  *
8008  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8009  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8010  *
8011  * @pre This method can be called if @p scip is in one of the following stages:
8012  * - \ref SCIP_STAGE_PROBLEM
8013  * - \ref SCIP_STAGE_TRANSFORMING
8014  * - \ref SCIP_STAGE_TRANSFORMED
8015  * - \ref SCIP_STAGE_INITPRESOLVE
8016  * - \ref SCIP_STAGE_PRESOLVING
8017  * - \ref SCIP_STAGE_EXITPRESOLVE
8018  * - \ref SCIP_STAGE_PRESOLVED
8019  * - \ref SCIP_STAGE_SOLVING
8020  */
8022  SCIP* scip, /**< SCIP data structure */
8023  SCIP_VAR* var, /**< problem variable */
8024  int branchpriority /**< new branch priority of the variable, if it is larger than current priority */
8025  )
8026 {
8027  SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8028 
8029  assert( var->scip == scip );
8030 
8031  if( branchpriority > SCIPvarGetBranchPriority(var) )
8032  {
8033  SCIP_CALL( SCIPvarChgBranchPriority(var, branchpriority) );
8034  }
8035 
8036  return SCIP_OKAY;
8037 }
8038 
8039 /** adds the given value to the branch priority of the variable
8040  *
8041  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8042  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8043  *
8044  * @pre This method can be called if @p scip is in one of the following stages:
8045  * - \ref SCIP_STAGE_PROBLEM
8046  * - \ref SCIP_STAGE_TRANSFORMING
8047  * - \ref SCIP_STAGE_TRANSFORMED
8048  * - \ref SCIP_STAGE_INITPRESOLVE
8049  * - \ref SCIP_STAGE_PRESOLVING
8050  * - \ref SCIP_STAGE_EXITPRESOLVE
8051  * - \ref SCIP_STAGE_PRESOLVED
8052  * - \ref SCIP_STAGE_SOLVING
8053  */
8055  SCIP* scip, /**< SCIP data structure */
8056  SCIP_VAR* var, /**< problem variable */
8057  int addpriority /**< value to add to the branch priority of the variable */
8058  )
8059 {
8060  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8061 
8062  assert( var->scip == scip );
8063 
8064  SCIP_CALL( SCIPvarChgBranchPriority(var, addpriority + SCIPvarGetBranchPriority(var)) );
8065 
8066  return SCIP_OKAY;
8067 }
8068 
8069 /** sets the branch direction of the variable (-1: prefer downwards branch, 0: automatic selection, +1: prefer upwards
8070  * branch)
8071  *
8072  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8073  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8074  *
8075  * @pre This method can be called if @p scip is in one of the following stages:
8076  * - \ref SCIP_STAGE_PROBLEM
8077  * - \ref SCIP_STAGE_TRANSFORMING
8078  * - \ref SCIP_STAGE_TRANSFORMED
8079  * - \ref SCIP_STAGE_INITPRESOLVE
8080  * - \ref SCIP_STAGE_PRESOLVING
8081  * - \ref SCIP_STAGE_EXITPRESOLVE
8082  * - \ref SCIP_STAGE_PRESOLVED
8083  * - \ref SCIP_STAGE_SOLVING
8084  */
8086  SCIP* scip, /**< SCIP data structure */
8087  SCIP_VAR* var, /**< problem variable */
8088  SCIP_BRANCHDIR branchdirection /**< preferred branch direction of the variable (downwards, upwards, auto) */
8089  )
8090 {
8091  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchDirection", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8092 
8093  assert( var->scip == scip );
8094 
8095  SCIP_CALL( SCIPvarChgBranchDirection(var, branchdirection) );
8096 
8097  return SCIP_OKAY;
8098 }
8099 
8100 /** tightens the variable bounds due to a new variable type */
8101 static
8103  SCIP* scip, /**< SCIP data structure */
8104  SCIP_VAR* var, /**< variable to change the bound for */
8105  SCIP_VARTYPE vartype, /**< new type of variable */
8106  SCIP_Bool* infeasible /**< pointer to store whether an infeasibility was detected (, due to
8107  * integrality condition of the new variable type) */
8108  )
8109 {
8110  assert(scip != NULL);
8112  assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPvarIsTransformed(var));
8113  assert(var->scip == scip);
8114 
8115  *infeasible = FALSE;
8116 
8117  /* adjusts bounds if the variable type changed form continuous to non-continuous (integral) */
8119  {
8120  SCIP_Bool tightened;
8121 
8122  /* we adjust variable bounds to integers first, since otherwise a later bound tightening with a fractional old
8123  * bound may give an assert because SCIP expects non-continuous variables to have non-fractional bounds
8124  *
8125  * we adjust bounds with a fractionality within [eps,feastol] only if the resulting bound change is a bound
8126  * tightening, because relaxing bounds may not be allowed
8127  */
8128  if( !SCIPisFeasIntegral(scip, SCIPvarGetLbGlobal(var)) ||
8130  (!SCIPsetIsEQ(scip->set, SCIPvarGetLbGlobal(var), SCIPfeasCeil(scip, SCIPvarGetLbGlobal(var))) &&
8132  )
8133  {
8134  SCIP_CALL( SCIPtightenVarLbGlobal(scip, var, SCIPfeasCeil(scip, SCIPvarGetLbGlobal(var)), TRUE, infeasible, &tightened) );
8135  if( *infeasible )
8136  return SCIP_OKAY;
8137 
8138  /* the only reason for not applying a forced boundchange is when the new bound is reduced because the variables upper bound is below the new bound
8139  * in a concrete case, lb == ub == 100.99999001; even though within feastol of 101, the lower bound cannot be tighented to 101 due to the upper bound
8140  */
8141  assert(tightened || SCIPisFeasLE(scip, SCIPvarGetUbGlobal(var), SCIPfeasCeil(scip, SCIPvarGetLbGlobal(var))));
8142  }
8143  if( !SCIPisFeasIntegral(scip, SCIPvarGetUbGlobal(var)) ||
8145  )
8146  {
8147  SCIP_CALL( SCIPtightenVarUbGlobal(scip, var, SCIPfeasFloor(scip, SCIPvarGetUbGlobal(var)), TRUE, infeasible, &tightened) );
8148  if( *infeasible )
8149  return SCIP_OKAY;
8150 
8151  assert(tightened || SCIPisFeasGE(scip, SCIPvarGetLbGlobal(var), SCIPfeasFloor(scip, SCIPvarGetUbGlobal(var))));
8152  }
8153  }
8154 
8155  return SCIP_OKAY;
8156 }
8157 
8158 /** changes type of variable in the problem;
8159  *
8160  * @warning This type change might change the variable array returned from SCIPgetVars() and SCIPgetVarsData();
8161  *
8162  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8163  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8164  *
8165  * @pre This method can be called if @p scip is in one of the following stages:
8166  * - \ref SCIP_STAGE_PROBLEM
8167  * - \ref SCIP_STAGE_TRANSFORMING
8168  * - \ref SCIP_STAGE_PRESOLVING
8169  *
8170  * @note If SCIP is already beyond the SCIP_STAGE_PROBLEM and a original variable is passed, the variable type of the
8171  * corresponding transformed variable is changed; the type of the original variable does not change
8172  *
8173  * @note If the type changes from a continuous variable to a non-continuous variable the bounds of the variable get
8174  * adjusted w.r.t. to integrality information
8175  */
8177  SCIP* scip, /**< SCIP data structure */
8178  SCIP_VAR* var, /**< variable to change the bound for */
8179  SCIP_VARTYPE vartype, /**< new type of variable */
8180  SCIP_Bool* infeasible /**< pointer to store whether an infeasibility was detected (, due to
8181  * integrality condition of the new variable type) */
8182  )
8183 {
8184  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarType", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
8185 
8186  assert(var != NULL);
8187  assert(var->scip == scip);
8188 
8189  if( SCIPvarIsNegated(var) )
8190  {
8191  SCIPdebugMsg(scip, "upgrading type of negated variable <%s> from %d to %d\n", SCIPvarGetName(var), SCIPvarGetType(var), vartype);
8192  var = SCIPvarGetNegationVar(var);
8193  }
8194 #ifndef NDEBUG
8195  else
8196  {
8197  if( SCIPgetStage(scip) > SCIP_STAGE_PROBLEM )
8198  {
8199  SCIPdebugMsg(scip, "upgrading type of variable <%s> from %d to %d\n", SCIPvarGetName(var), SCIPvarGetType(var), vartype);
8200  }
8201  }
8202 #endif
8203 
8204  /* change variable type */
8205  switch( scip->set->stage )
8206  {
8207  case SCIP_STAGE_PROBLEM:
8208  assert(!SCIPvarIsTransformed(var));
8209 
8210  /* first adjust the variable due to new integrality information */
8211  SCIP_CALL( tightenBounds(scip, var, vartype, infeasible) );
8212 
8213  /* second change variable type */
8214  if( SCIPvarGetProbindex(var) >= 0 )
8215  {
8216  SCIP_CALL( SCIPprobChgVarType(scip->origprob, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8217  scip->branchcand, scip->eventqueue, scip->cliquetable, var, vartype) );
8218  }
8219  else
8220  {
8221  SCIP_CALL( SCIPvarChgType(var, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8222  scip->eventqueue, vartype) );
8223  }
8224  break;
8225 
8226  case SCIP_STAGE_PRESOLVING:
8227  if( !SCIPvarIsTransformed(var) )
8228  {
8229  SCIP_VAR* transvar;
8230 
8231  SCIP_CALL( SCIPgetTransformedVar(scip, var, &transvar) );
8232  assert(transvar != NULL);
8233 
8234  /* recall method with transformed variable */
8235  SCIP_CALL( SCIPchgVarType(scip, transvar, vartype, infeasible) );
8236  return SCIP_OKAY;
8237  }
8238 
8239  /* first adjust the variable due to new integrality information */
8240  SCIP_CALL( tightenBounds(scip, var, vartype, infeasible) );
8241 
8242  /* second change variable type */
8243  if( SCIPvarGetProbindex(var) >= 0 )
8244  {
8245  SCIP_CALL( SCIPprobChgVarType(scip->transprob, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8246  scip->branchcand, scip->eventqueue, scip->cliquetable, var, vartype) );
8247  }
8248  else
8249  {
8250  SCIP_CALL( SCIPvarChgType(var, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8251  scip->eventqueue, vartype) );
8252  }
8253  break;
8254 
8255  default:
8256  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
8257  return SCIP_INVALIDCALL;
8258  } /*lint !e788*/
8259 
8260  return SCIP_OKAY;
8261 }
8262 
8263 /** in problem creation and solving stage, both bounds of the variable are set to the given value;
8264  * in presolving stage, the variable is converted into a fixed variable, and bounds are changed respectively;
8265  * conversion into a fixed variable changes the vars array returned from SCIPgetVars() and SCIPgetVarsData(),
8266  * and also renders arrays returned from the SCIPvarGetImpl...() methods invalid
8267  *
8268  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8269  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8270  *
8271  * @pre This method can be called if @p scip is in one of the following stages:
8272  * - \ref SCIP_STAGE_PROBLEM
8273  * - \ref SCIP_STAGE_PRESOLVING
8274  * - \ref SCIP_STAGE_SOLVING
8275  */
8277  SCIP* scip, /**< SCIP data structure */
8278  SCIP_VAR* var, /**< variable to fix */
8279  SCIP_Real fixedval, /**< value to fix variable to */
8280  SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
8281  SCIP_Bool* fixed /**< pointer to store whether the fixing was performed (variable was unfixed) */
8282  )
8283 {
8284  assert(var != NULL);
8285  assert(infeasible != NULL);
8286  assert(fixed != NULL);
8287 
8288  SCIP_CALL( SCIPcheckStage(scip, "SCIPfixVar", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8289 
8290  *infeasible = FALSE;
8291  *fixed = FALSE;
8292 
8293  /* in the problem creation stage, modify the bounds as requested, independently from the current bounds */
8294  if( scip->set->stage != SCIP_STAGE_PROBLEM )
8295  {
8296  if( (SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPsetIsFeasIntegral(scip->set, fixedval))
8297  || SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetLbLocal(var))
8298  || SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8299  {
8300  *infeasible = TRUE;
8301  return SCIP_OKAY;
8302  }
8303  else if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED )
8304  {
8305  *infeasible = !SCIPsetIsFeasEQ(scip->set, fixedval, SCIPvarGetLbLocal(var));
8306  return SCIP_OKAY;
8307  }
8308  }
8309  else
8310  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_ORIGINAL);
8311 
8312  switch( scip->set->stage )
8313  {
8314  case SCIP_STAGE_PROBLEM:
8315  /* in the problem creation stage, modify the bounds as requested, independently from the current bounds;
8316  * we have to make sure, that the order of the bound changes does not intermediately produce an invalid
8317  * interval lb > ub
8318  */
8319  if( fixedval <= SCIPvarGetLbLocal(var) )
8320  {
8321  SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
8322  SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
8323  *fixed = TRUE;
8324  }
8325  else
8326  {
8327  SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
8328  SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
8329  *fixed = TRUE;
8330  }
8331  return SCIP_OKAY;
8332 
8333  case SCIP_STAGE_PRESOLVING:
8334  if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
8335  {
8336  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8337  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8338  scip->cliquetable, fixedval, infeasible, fixed) );
8339  return SCIP_OKAY;
8340  }
8341  /*lint -fallthrough*/
8342  case SCIP_STAGE_SOLVING:
8343  if( SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetLbLocal(var)) )
8344  {
8345  if( SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8346  {
8347  *infeasible = TRUE;
8348  return SCIP_OKAY;
8349  }
8350  else
8351  {
8352  SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
8353  *fixed = TRUE;
8354  }
8355  }
8356  if( SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8357  {
8358  if( SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetLbLocal(var)) )
8359  {
8360  *infeasible = TRUE;
8361  return SCIP_OKAY;
8362  }
8363  else
8364  {
8365  SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
8366  *fixed = TRUE;
8367  }
8368  }
8369  return SCIP_OKAY;
8370 
8371  default:
8372  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
8373  return SCIP_INVALIDCALL;
8374  } /*lint !e788*/
8375 }
8376 
8377 /** From a given equality a*x + b*y == c, aggregates one of the variables and removes it from the set of
8378  * active problem variables. This changes the vars array returned from SCIPgetVars() and SCIPgetVarsData(),
8379  * and also renders the arrays returned from the SCIPvarGetImpl...() methods for the two variables invalid.
8380  * In the first step, the equality is transformed into an equality with active problem variables
8381  * a'*x' + b'*y' == c'. If x' == y', this leads to the detection of redundancy if a' == -b' and c' == 0,
8382  * of infeasibility, if a' == -b' and c' != 0, or to a variable fixing x' == c'/(a'+b') (and possible
8383  * infeasibility) otherwise.
8384  * In the second step, the variable to be aggregated is chosen among x' and y', prefering a less strict variable
8385  * type as aggregation variable (i.e. continuous variables are preferred over implicit integers, implicit integers
8386  * over integers, and integers over binaries). If none of the variables is continuous, it is tried to find an integer
8387  * aggregation (i.e. integral coefficients a'' and b'', such that a''*x' + b''*y' == c''). This can lead to
8388  * the detection of infeasibility (e.g. if c'' is fractional), or to a rejection of the aggregation (denoted by
8389  * aggregated == FALSE), if the resulting integer coefficients are too large and thus numerically instable.
8390  *
8391  * The output flags have the following meaning:
8392  * - infeasible: the problem is infeasible
8393  * - redundant: the equality can be deleted from the constraint set
8394  * - aggregated: the aggregation was successfully performed (the variables were not aggregated before)
8395  *
8396  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8397  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8398  *
8399  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PRESOLVING
8400  */
8402  SCIP* scip, /**< SCIP data structure */
8403  SCIP_VAR* varx, /**< variable x in equality a*x + b*y == c */
8404  SCIP_VAR* vary, /**< variable y in equality a*x + b*y == c */
8405  SCIP_Real scalarx, /**< multiplier a in equality a*x + b*y == c */
8406  SCIP_Real scalary, /**< multiplier b in equality a*x + b*y == c */
8407  SCIP_Real rhs, /**< right hand side c in equality a*x + b*y == c */
8408  SCIP_Bool* infeasible, /**< pointer to store whether the aggregation is infeasible */
8409  SCIP_Bool* redundant, /**< pointer to store whether the equality is (now) redundant */
8410  SCIP_Bool* aggregated /**< pointer to store whether the aggregation was successful */
8411  )
8412 {
8413  SCIP_Real constantx;
8414  SCIP_Real constanty;
8415 
8416  assert(infeasible != NULL);
8417  assert(redundant != NULL);
8418  assert(aggregated != NULL);
8419 
8420  SCIP_CALL( SCIPcheckStage(scip, "SCIPaggregateVars", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
8421 
8422  *infeasible = FALSE;
8423  *redundant = FALSE;
8424  *aggregated = FALSE;
8425 
8426  if( SCIPtreeProbing(scip->tree) )
8427  {
8428  SCIPerrorMessage("cannot aggregate variables during probing\n");
8429  return SCIP_INVALIDCALL;
8430  }
8431  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
8432 
8433  /* do not perform aggregation if it is globally deactivated */
8434  if( scip->set->presol_donotaggr )
8435  return SCIP_OKAY;
8436 
8437  /* get the corresponding equality in active problem variable space:
8438  * transform both expressions "a*x + 0" and "b*y + 0" into problem variable space
8439  */
8440  constantx = 0.0;
8441  constanty = 0.0;
8442  SCIP_CALL( SCIPvarGetProbvarSum(&varx, scip->set, &scalarx, &constantx) );
8443  SCIP_CALL( SCIPvarGetProbvarSum(&vary, scip->set, &scalary, &constanty) );
8444 
8445  /* we cannot aggregate multi-aggregated variables */
8447  return SCIP_OKAY;
8448 
8449  /* move the constant to the right hand side to acquire the form "a'*x' + b'*y' == c'" */
8450  rhs -= (constantx + constanty);
8451 
8452  /* if a scalar is zero, treat the variable as fixed-to-zero variable */
8453  if( SCIPsetIsZero(scip->set, scalarx) )
8454  varx = NULL;
8455  if( SCIPsetIsZero(scip->set, scalary) )
8456  vary = NULL;
8457 
8458  /* capture the special cases that less than two variables are left, due to resolutions to a fixed variable or
8459  * to the same active variable
8460  */
8461  if( varx == NULL && vary == NULL )
8462  {
8463  /* both variables were resolved to fixed variables */
8464  *infeasible = !SCIPsetIsZero(scip->set, rhs);
8465  *redundant = TRUE;
8466  }
8467  else if( varx == NULL )
8468  {
8469  assert(SCIPsetIsZero(scip->set, scalarx));
8470  assert(!SCIPsetIsZero(scip->set, scalary));
8471 
8472  /* variable x was resolved to fixed variable: variable y can be fixed to c'/b' */
8473  SCIP_CALL( SCIPvarFix(vary, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8474  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8475  scip->cliquetable, rhs/scalary, infeasible, aggregated) );
8476  *redundant = TRUE;
8477  }
8478  else if( vary == NULL )
8479  {
8480  assert(SCIPsetIsZero(scip->set, scalary));
8481  assert(!SCIPsetIsZero(scip->set, scalarx));
8482 
8483  /* variable y was resolved to fixed variable: variable x can be fixed to c'/a' */
8484  SCIP_CALL( SCIPvarFix(varx, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8485  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8486  scip->cliquetable, rhs/scalarx, infeasible, aggregated) );
8487  *redundant = TRUE;
8488  }
8489  else if( varx == vary )
8490  {
8491  /* both variables were resolved to the same active problem variable: this variable can be fixed */
8492  scalarx += scalary;
8493  if( SCIPsetIsZero(scip->set, scalarx) )
8494  {
8495  /* left hand side of equality is zero: equality is potentially infeasible */
8496  *infeasible = !SCIPsetIsZero(scip->set, rhs);
8497  }
8498  else
8499  {
8500  /* sum of scalars is not zero: fix variable x' == y' to c'/(a'+b') */
8501  SCIP_CALL( SCIPvarFix(varx, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8502  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8503  scip->cliquetable, rhs/scalarx, infeasible, aggregated) );
8504  }
8505  *redundant = TRUE;
8506  }
8507  else
8508  {
8509  /* both variables are different active problem variables, and both scalars are non-zero: try to aggregate them */
8510  SCIP_CALL( SCIPvarTryAggregateVars(scip->set, scip->mem->probmem, scip->stat, scip->transprob, scip->origprob,
8511  scip->primal, scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventfilter,
8512  scip->eventqueue, varx, vary, scalarx, scalary, rhs, infeasible, aggregated) );
8513  *redundant = *aggregated;
8514  }
8515 
8516  return SCIP_OKAY;
8517 }
8518 
8519 /** converts variable into multi-aggregated variable; this changes the variable array returned from
8520  * SCIPgetVars() and SCIPgetVarsData();
8521  *
8522  * @warning The integrality condition is not checked anymore on the multi-aggregated variable. You must not
8523  * multi-aggregate an integer variable without being sure, that integrality on the aggregation variables
8524  * implies integrality on the aggregated variable.
8525  *
8526  * The output flags have the following meaning:
8527  * - infeasible: the problem is infeasible
8528  * - aggregated: the aggregation was successfully performed (the variables were not aggregated before)
8529  *
8530  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8531  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8532  *
8533  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PRESOLVING
8534  */
8536  SCIP* scip, /**< SCIP data structure */
8537  SCIP_VAR* var, /**< variable x to aggregate */
8538  int naggvars, /**< number n of variables in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8539  SCIP_VAR** aggvars, /**< variables y_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8540  SCIP_Real* scalars, /**< multipliers a_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8541  SCIP_Real constant, /**< constant shift c in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8542  SCIP_Bool* infeasible, /**< pointer to store whether the aggregation is infeasible */
8543  SCIP_Bool* aggregated /**< pointer to store whether the aggregation was successful */
8544  )
8545 {
8546  SCIP_CALL( SCIPcheckStage(scip, "SCIPmultiaggregateVar", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
8547 
8548  assert(var->scip == scip);
8549 
8550  if( SCIPtreeProbing(scip->tree) )
8551  {
8552  SCIPerrorMessage("cannot multi-aggregate variables during probing\n");
8553  return SCIP_INVALIDCALL;
8554  }
8555  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
8556 
8557  SCIP_CALL( SCIPvarMultiaggregate(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8558  scip->primal, scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventfilter,
8559  scip->eventqueue, naggvars, aggvars, scalars, constant, infeasible, aggregated) );
8560 
8561  return SCIP_OKAY;
8562 }
8563 
8564 /** returns whether aggregation of variables is not allowed */
8566  SCIP* scip /**< SCIP data structure */
8567  )
8568 {
8569  assert(scip != NULL);
8570 
8571  return scip->set->presol_donotaggr;
8572 }
8573 
8574 /** returns whether multi-aggregation is disabled */
8576  SCIP* scip /**< SCIP data structure */
8577  )
8578 {
8579  assert(scip != NULL);
8580 
8581  return scip->set->presol_donotmultaggr;
8582 }
8583 
8584 /** returns whether variable is not allowed to be aggregated */
8586  SCIP* scip, /**< SCIP data structure */
8587  SCIP_VAR* var /**< variable x to aggregate */
8588  )
8589 {
8590  assert(scip != NULL);
8591  assert(var != NULL);
8592  assert(var->scip == scip);
8593 
8594  return scip->set->presol_donotaggr || SCIPvarDoNotAggr(var);
8595 }
8596 
8597 /** returns whether variable is not allowed to be multi-aggregated */
8599  SCIP* scip, /**< SCIP data structure */
8600  SCIP_VAR* var /**< variable x to aggregate */
8601  )
8602 {
8603  assert(scip != NULL);
8604  assert(var != NULL);
8605  assert(var->scip == scip);
8606 
8607  return scip->set->presol_donotmultaggr || SCIPvarDoNotMultaggr(var);
8608 }
8609 
8610 /** returns whether dual reductions are allowed during propagation and presolving
8611  *
8612  * @deprecated Please use SCIPallowStrongDualReds()
8613  */
8615  SCIP* scip /**< SCIP data structure */
8616  )
8617 {
8618  assert(scip != NULL);
8619 
8620  return !scip->set->reopt_enable && scip->set->misc_allowstrongdualreds;
8621 }
8622 
8623 /** returns whether strong dual reductions are allowed during propagation and presolving
8624  *
8625  * @note A reduction is called strong dual, if it may discard feasible/optimal solutions, but leaves at least one
8626  * optimal solution intact. Often such reductions are based on analyzing the objective function and variable
8627  * locks.
8628  */
8630  SCIP* scip /**< SCIP data structure */
8631  )
8632 {
8633  assert(scip != NULL);
8634 
8635  return !scip->set->reopt_enable && scip->set->misc_allowstrongdualreds;
8636 }
8637 
8638 /** returns whether propagation w.r.t. current objective is allowed
8639  *
8640  * @deprecated Please use SCIPallowWeakDualReds()
8641  */
8643  SCIP* scip /**< SCIP data structure */
8644  )
8645 {
8646  assert(scip != NULL);
8647 
8648  return !scip->set->reopt_enable && scip->set->misc_allowweakdualreds;
8649 }
8650 
8651 /** returns whether weak dual reductions are allowed during propagation and presolving
8652  *
8653  * @note A reduction is called weak dual, if it may discard feasible solutions, but leaves at all optimal solutions
8654  * intact. Often such reductions are based on analyzing the objective function, reduced costs, and/or dual LPs.
8655  */
8657  SCIP* scip /**< SCIP data structure */
8658  )
8659 {
8660  assert(scip != NULL);
8661 
8662  return !scip->set->reopt_enable && scip->set->misc_allowweakdualreds;
8663 }
8664 
8665 /** marks the variable that it must not be aggregated
8666  *
8667  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8668  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8669  *
8670  * @pre This method can be called if @p scip is in one of the following stages:
8671  * - \ref SCIP_STAGE_INIT
8672  * - \ref SCIP_STAGE_PROBLEM
8673  * - \ref SCIP_STAGE_TRANSFORMING
8674  * - \ref SCIP_STAGE_TRANSFORMED
8675  * - \ref SCIP_STAGE_INITPRESOLVE
8676  * - \ref SCIP_STAGE_PRESOLVING
8677  * - \ref SCIP_STAGE_EXITPRESOLVE
8678  *
8679  * @note There exists no "unmark" method since it has to be ensured that if a plugin requires that a variable is not
8680  * aggregated that this is will be the case.
8681  */
8683  SCIP* scip, /**< SCIP data structure */
8684  SCIP_VAR* var /**< variable to delete */
8685  )
8686 {
8687  assert(scip != NULL);
8688  assert(var != NULL);
8689  assert(var->scip == scip);
8690 
8691  SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkDoNotAggrVar", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE) );
8692 
8694 
8695  return SCIP_OKAY;
8696 }
8697 
8698 /** marks the variable that it must not be multi-aggregated
8699  *
8700  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8701  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8702  *
8703  * @pre This method can be called if @p scip is in one of the following stages:
8704  * - \ref SCIP_STAGE_INIT
8705  * - \ref SCIP_STAGE_PROBLEM
8706  * - \ref SCIP_STAGE_TRANSFORMING
8707  * - \ref SCIP_STAGE_TRANSFORMED
8708  * - \ref SCIP_STAGE_INITPRESOLVE
8709  * - \ref SCIP_STAGE_PRESOLVING
8710  * - \ref SCIP_STAGE_EXITPRESOLVE
8711  *
8712  * @note There exists no "unmark" method since it has to be ensured that if a plugin requires that a variable is not
8713  * multi-aggregated that this is will be the case.
8714  */
8716  SCIP* scip, /**< SCIP data structure */
8717  SCIP_VAR* var /**< variable to delete */
8718  )
8719 {
8720  assert(scip != NULL);
8721  assert(var != NULL);
8722  assert(var->scip == scip);
8723 
8724  SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkDoNotMultaggrVar", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE) );
8725 
8727 
8728  return SCIP_OKAY;
8729 }
8730 
8731 /** enables the collection of statistics for a variable
8732  *
8733  * @pre This method can be called if @p scip is in one of the following stages:
8734  * - \ref SCIP_STAGE_PROBLEM
8735  * - \ref SCIP_STAGE_INITPRESOLVE
8736  * - \ref SCIP_STAGE_PRESOLVING
8737  * - \ref SCIP_STAGE_EXITPRESOLVE
8738  * - \ref SCIP_STAGE_SOLVING
8739  * - \ref SCIP_STAGE_SOLVED
8740  */
8742  SCIP* scip /**< SCIP data structure */
8743  )
8744 {
8745  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPenableVarHistory", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8746 
8748 }
8749 
8750 /** disables the collection of any statistic for a variable
8751  *
8752  * @pre This method can be called if @p scip is in one of the following stages:
8753  * - \ref SCIP_STAGE_PROBLEM
8754  * - \ref SCIP_STAGE_INITPRESOLVE
8755  * - \ref SCIP_STAGE_PRESOLVING
8756  * - \ref SCIP_STAGE_EXITPRESOLVE
8757  * - \ref SCIP_STAGE_SOLVING
8758  * - \ref SCIP_STAGE_SOLVED
8759  */
8761  SCIP* scip /**< SCIP data structure */
8762  )
8763 {
8764  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPdisableVarHistory", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8765 
8767 }
8768 
8769 /** updates the pseudo costs of the given variable and the global pseudo costs after a change of "solvaldelta" in the
8770  * variable's solution value and resulting change of "objdelta" in the in the LP's objective value;
8771  * the update is ignored, if the objective value difference is infinite
8772  *
8773  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8774  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8775  *
8776  * @pre This method can be called if @p scip is in one of the following stages:
8777  * - \ref SCIP_STAGE_SOLVING
8778  * - \ref SCIP_STAGE_SOLVED
8779  */
8781  SCIP* scip, /**< SCIP data structure */
8782  SCIP_VAR* var, /**< problem variable */
8783  SCIP_Real solvaldelta, /**< difference of variable's new LP value - old LP value */
8784  SCIP_Real objdelta, /**< difference of new LP's objective value - old LP's objective value */
8785  SCIP_Real weight /**< weight in (0,1] of this update in pseudo cost sum */
8786  )
8787 {
8788  SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateVarPseudocost", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8789 
8790  if( !SCIPsetIsInfinity(scip->set, 2*objdelta) ) /* differences infinity - eps should also be treated as infinity */
8791  {
8792  if( scip->set->branch_divingpscost || (!scip->lp->diving && !SCIPtreeProbing(scip->tree)) )
8793  {
8794  SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, solvaldelta, objdelta, weight) );
8795  }
8796  }
8797 
8798  return SCIP_OKAY;
8799 }
8800 
8801 /** gets the variable's pseudo cost value for the given change of the variable's LP value
8802  *
8803  * @return the variable's pseudo cost value for the given change of the variable's LP value
8804  *
8805  * @pre This method can be called if @p scip is in one of the following stages:
8806  * - \ref SCIP_STAGE_INITPRESOLVE
8807  * - \ref SCIP_STAGE_PRESOLVING
8808  * - \ref SCIP_STAGE_EXITPRESOLVE
8809  * - \ref SCIP_STAGE_PRESOLVED
8810  * - \ref SCIP_STAGE_INITSOLVE
8811  * - \ref SCIP_STAGE_SOLVING
8812  * - \ref SCIP_STAGE_SOLVED
8813  */
8815  SCIP* scip, /**< SCIP data structure */
8816  SCIP_VAR* var, /**< problem variable */
8817  SCIP_Real solvaldelta /**< difference of variable's new LP value - old LP value */
8818  )
8819 {
8820  assert( var->scip == scip );
8821 
8822  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostVal", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8823 
8824  return SCIPvarGetPseudocost(var, scip->stat, solvaldelta);
8825 }
8826 
8827 /** gets the variable's pseudo cost value for the given change of the variable's LP value,
8828  * only using the pseudo cost information of the current run
8829  *
8830  * @return the variable's pseudo cost value for the given change of the variable's LP value,
8831  * only using the pseudo cost information of the current run
8832  *
8833  * @pre This method can be called if @p scip is in one of the following stages:
8834  * - \ref SCIP_STAGE_INITPRESOLVE
8835  * - \ref SCIP_STAGE_PRESOLVING
8836  * - \ref SCIP_STAGE_EXITPRESOLVE
8837  * - \ref SCIP_STAGE_PRESOLVED
8838  * - \ref SCIP_STAGE_INITSOLVE
8839  * - \ref SCIP_STAGE_SOLVING
8840  * - \ref SCIP_STAGE_SOLVED
8841  */
8843  SCIP* scip, /**< SCIP data structure */
8844  SCIP_VAR* var, /**< problem variable */
8845  SCIP_Real solvaldelta /**< difference of variable's new LP value - old LP value */
8846  )
8847 {
8848  assert( var->scip == scip );
8849 
8850  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostValCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8851 
8852  return SCIPvarGetPseudocostCurrentRun(var, scip->stat, solvaldelta);
8853 }
8854 
8855 /** gets the variable's pseudo cost value for the given direction
8856  *
8857  * @return the variable's pseudo cost value for the given direction
8858  *
8859  * @pre This method can be called if @p scip is in one of the following stages:
8860  * - \ref SCIP_STAGE_INITPRESOLVE
8861  * - \ref SCIP_STAGE_PRESOLVING
8862  * - \ref SCIP_STAGE_EXITPRESOLVE
8863  * - \ref SCIP_STAGE_PRESOLVED
8864  * - \ref SCIP_STAGE_INITSOLVE
8865  * - \ref SCIP_STAGE_SOLVING
8866  * - \ref SCIP_STAGE_SOLVED
8867  */
8869  SCIP* scip, /**< SCIP data structure */
8870  SCIP_VAR* var, /**< problem variable */
8871  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8872  )
8873 {
8874  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocost", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8875  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8876  assert(var->scip == scip);
8877 
8878  return SCIPvarGetPseudocost(var, scip->stat, dir == SCIP_BRANCHDIR_DOWNWARDS ? -1.0 : 1.0);
8879 }
8880 
8881 /** gets the variable's pseudo cost value for the given direction,
8882  * only using the pseudo cost information of the current run
8883  *
8884  * @return the variable's pseudo cost value for the given direction,
8885  * only using the pseudo cost information of the current run
8886  *
8887  * @pre This method can be called if @p scip is in one of the following stages:
8888  * - \ref SCIP_STAGE_INITPRESOLVE
8889  * - \ref SCIP_STAGE_PRESOLVING
8890  * - \ref SCIP_STAGE_EXITPRESOLVE
8891  * - \ref SCIP_STAGE_PRESOLVED
8892  * - \ref SCIP_STAGE_INITSOLVE
8893  * - \ref SCIP_STAGE_SOLVING
8894  * - \ref SCIP_STAGE_SOLVED
8895  */
8897  SCIP* scip, /**< SCIP data structure */
8898  SCIP_VAR* var, /**< problem variable */
8899  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8900  )
8901 {
8902  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8903  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8904  assert(var->scip == scip);
8905 
8906  return SCIPvarGetPseudocostCurrentRun(var, scip->stat, dir == SCIP_BRANCHDIR_DOWNWARDS ? -1.0 : 1.0);
8907 }
8908 
8909 /** gets the variable's (possible fractional) number of pseudo cost updates for the given direction
8910  *
8911  * @return the variable's (possible fractional) number of pseudo cost updates for the given direction
8912  *
8913  * @pre This method can be called if @p scip is in one of the following stages:
8914  * - \ref SCIP_STAGE_INITPRESOLVE
8915  * - \ref SCIP_STAGE_PRESOLVING
8916  * - \ref SCIP_STAGE_EXITPRESOLVE
8917  * - \ref SCIP_STAGE_PRESOLVED
8918  * - \ref SCIP_STAGE_INITSOLVE
8919  * - \ref SCIP_STAGE_SOLVING
8920  * - \ref SCIP_STAGE_SOLVED
8921  */
8923  SCIP* scip, /**< SCIP data structure */
8924  SCIP_VAR* var, /**< problem variable */
8925  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8926  )
8927 {
8928  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCount", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8929  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8930  assert(var->scip == scip);
8931 
8932  return SCIPvarGetPseudocostCount(var, dir);
8933 }
8934 
8935 /** gets the variable's (possible fractional) number of pseudo cost updates for the given direction,
8936  * only using the pseudo cost information of the current run
8937  *
8938  * @return the variable's (possible fractional) number of pseudo cost updates for the given direction,
8939  * only using the pseudo cost information of the current run
8940  *
8941  * @pre This method can be called if @p scip is in one of the following stages:
8942  * - \ref SCIP_STAGE_INITPRESOLVE
8943  * - \ref SCIP_STAGE_PRESOLVING
8944  * - \ref SCIP_STAGE_EXITPRESOLVE
8945  * - \ref SCIP_STAGE_PRESOLVED
8946  * - \ref SCIP_STAGE_INITSOLVE
8947  * - \ref SCIP_STAGE_SOLVING
8948  * - \ref SCIP_STAGE_SOLVED
8949  */
8951  SCIP* scip, /**< SCIP data structure */
8952  SCIP_VAR* var, /**< problem variable */
8953  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8954  )
8955 {
8956  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCountCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8957  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8958  assert(var->scip == scip);
8959 
8960  return SCIPvarGetPseudocostCountCurrentRun(var, dir);
8961 }
8962 
8963 /** get pseudo cost variance of the variable, either for entire solve or only for current branch and bound run
8964  *
8965  * @return returns the (corrected) variance of pseudo code information collected so far.
8966  *
8967  * @pre This method can be called if @p scip is in one of the following stages:
8968  * - \ref SCIP_STAGE_INITPRESOLVE
8969  * - \ref SCIP_STAGE_PRESOLVING
8970  * - \ref SCIP_STAGE_EXITPRESOLVE
8971  * - \ref SCIP_STAGE_PRESOLVED
8972  * - \ref SCIP_STAGE_INITSOLVE
8973  * - \ref SCIP_STAGE_SOLVING
8974  * - \ref SCIP_STAGE_SOLVED
8975  */
8977  SCIP* scip, /**< SCIP data structure */
8978  SCIP_VAR* var, /**< problem variable */
8979  SCIP_BRANCHDIR dir, /**< branching direction (downwards, or upwards) */
8980  SCIP_Bool onlycurrentrun /**< only for pseudo costs of current branch and bound run */
8981  )
8982 {
8983  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostVariance", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8984  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8985  assert(var->scip == scip);
8986 
8987  return SCIPvarGetPseudocostVariance(var, dir, onlycurrentrun);
8988 }
8989 
8990 /** calculates a confidence bound for this variable under the assumption of normally distributed pseudo costs
8991  *
8992  * The confidence bound \f$ \theta \geq 0\f$ denotes the interval borders \f$ [X - \theta, \ X + \theta]\f$, which contains
8993  * the true pseudo costs of the variable, i.e., the expected value of the normal distribution, with a probability
8994  * of 2 * clevel - 1.
8995  *
8996  * @return value of confidence bound for this variable
8997  */
8999  SCIP* scip, /**< SCIP data structure */
9000  SCIP_VAR* var, /**< variable in question */
9001  SCIP_BRANCHDIR dir, /**< the branching direction for the confidence bound */
9002  SCIP_Bool onlycurrentrun, /**< should only the current run be taken into account */
9003  SCIP_CONFIDENCELEVEL clevel /**< confidence level for the interval */
9004  )
9005 {
9006  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPcalculatePscostConfidenceBound", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9007 
9008  return SCIPvarCalcPscostConfidenceBound(var, scip->set, dir, onlycurrentrun, clevel);
9009 }
9010 
9011 /** check if variable pseudo-costs have a significant difference in location. The significance depends on
9012  * the choice of \p clevel and on the kind of tested hypothesis. The one-sided hypothesis, which
9013  * should be rejected, is that fracy * mu_y >= fracx * mu_x, where mu_y and mu_x denote the
9014  * unknown location means of the underlying pseudo-cost distributions of x and y.
9015  *
9016  * This method is applied best if variable x has a better pseudo-cost score than y. The method hypothesizes that y were actually
9017  * better than x (despite the current information), meaning that y can be expected to yield branching
9018  * decisions as least as good as x in the long run. If the method returns TRUE, the current history information is
9019  * sufficient to safely rely on the alternative hypothesis that x yields indeed a better branching score (on average)
9020  * than y.
9021  *
9022  * @note The order of x and y matters for the one-sided hypothesis
9023  *
9024  * @note set \p onesided to FALSE if you are not sure which variable is better. The hypothesis tested then reads
9025  * fracy * mu_y == fracx * mu_x vs the alternative hypothesis fracy * mu_y != fracx * mu_x.
9026  *
9027  * @return TRUE if the hypothesis can be safely rejected at the given confidence level
9028  */
9030  SCIP* scip, /**< SCIP data structure */
9031  SCIP_VAR* varx, /**< variable x */
9032  SCIP_Real fracx, /**< the fractionality of variable x */
9033  SCIP_VAR* vary, /**< variable y */
9034  SCIP_Real fracy, /**< the fractionality of variable y */
9035  SCIP_BRANCHDIR dir, /**< branching direction */
9036  SCIP_CONFIDENCELEVEL clevel, /**< confidence level for rejecting hypothesis */
9037  SCIP_Bool onesided /**< should a one-sided hypothesis y >= x be tested? */
9038  )
9039 {
9040  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPsignificantVarPscostDifference", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9041 
9042  return SCIPvarSignificantPscostDifference(scip->set, scip->stat, varx, fracx, vary, fracy, dir, clevel, onesided);
9043 }
9044 
9045 /** tests at a given confidence level whether the variable pseudo-costs only have a small probability to
9046  * exceed a \p threshold. This is useful to determine if past observations provide enough evidence
9047  * to skip an expensive strong-branching step if there is already a candidate that has been proven to yield an improvement
9048  * of at least \p threshold.
9049  *
9050  * @note use \p clevel to adjust the level of confidence. For SCIP_CONFIDENCELEVEL_MIN, the method returns TRUE if
9051  * the estimated probability to exceed \p threshold is less than 25 %.
9052  *
9053  * @see SCIP_Confidencelevel for a list of available levels. The used probability limits refer to the one-sided levels
9054  * of confidence.
9055  *
9056  * @return TRUE if the variable pseudo-cost probabilistic model is likely to be smaller than \p threshold
9057  * at the given confidence level \p clevel.
9058  */
9060  SCIP* scip, /**< SCIP data structure */
9061  SCIP_VAR* var, /**< variable x */
9062  SCIP_Real frac, /**< the fractionality of variable x */
9063  SCIP_Real threshold, /**< the threshold to test against */
9064  SCIP_BRANCHDIR dir, /**< branching direction */
9065  SCIP_CONFIDENCELEVEL clevel /**< confidence level for rejecting hypothesis */
9066  )
9067 {
9068  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPpscostThresholdProbabilityTest", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9069 
9070  return SCIPvarPscostThresholdProbabilityTest(scip->set, scip->stat, var, frac, threshold, dir, clevel);
9071 }
9072 
9073 /** check if the current pseudo cost relative error in a direction violates the given threshold. The Relative
9074  * Error is calculated at a specific confidence level
9075  *
9076  * @return TRUE if relative error in variable pseudo costs is smaller than \p threshold
9077  */
9079  SCIP* scip, /**< SCIP data structure */
9080  SCIP_VAR* var, /**< variable in question */
9081  SCIP_Real threshold, /**< threshold for relative errors to be considered reliable (enough) */
9082  SCIP_CONFIDENCELEVEL clevel /**< a given confidence level */
9083  )
9084 {
9085  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisVarPscostRelerrorReliable", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9086 
9087  return SCIPvarIsPscostRelerrorReliable(var, scip->set, scip->stat, threshold, clevel);
9088 }
9089 
9090 /** gets the variable's pseudo cost score value for the given LP solution value
9091  *
9092  * @return the variable's pseudo cost score value for the given LP solution value
9093  *
9094  * @pre This method can be called if @p scip is in one of the following stages:
9095  * - \ref SCIP_STAGE_INITPRESOLVE
9096  * - \ref SCIP_STAGE_PRESOLVING
9097  * - \ref SCIP_STAGE_EXITPRESOLVE
9098  * - \ref SCIP_STAGE_PRESOLVED
9099  * - \ref SCIP_STAGE_INITSOLVE
9100  * - \ref SCIP_STAGE_SOLVING
9101  * - \ref SCIP_STAGE_SOLVED
9102  */
9104  SCIP* scip, /**< SCIP data structure */
9105  SCIP_VAR* var, /**< problem variable */
9106  SCIP_Real solval /**< variable's LP solution value */
9107  )
9108 {
9109  SCIP_Real downsol;
9110  SCIP_Real upsol;
9111  SCIP_Real pscostdown;
9112  SCIP_Real pscostup;
9113 
9114  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9115 
9116  assert( var->scip == scip );
9117 
9118  downsol = SCIPsetFeasCeil(scip->set, solval-1.0);
9119  upsol = SCIPsetFeasFloor(scip->set, solval+1.0);
9120  pscostdown = SCIPvarGetPseudocost(var, scip->stat, downsol-solval);
9121  pscostup = SCIPvarGetPseudocost(var, scip->stat, upsol-solval);
9122 
9123  return SCIPbranchGetScore(scip->set, var, pscostdown, pscostup);
9124 }
9125 
9126 /** gets the variable's pseudo cost score value for the given LP solution value,
9127  * only using the pseudo cost information of the current run
9128  *
9129  * @return the variable's pseudo cost score value for the given LP solution value,
9130  * only using the pseudo cost information of the current run
9131  *
9132  * @pre This method can be called if @p scip is in one of the following stages:
9133  * - \ref SCIP_STAGE_INITPRESOLVE
9134  * - \ref SCIP_STAGE_PRESOLVING
9135  * - \ref SCIP_STAGE_EXITPRESOLVE
9136  * - \ref SCIP_STAGE_PRESOLVED
9137  * - \ref SCIP_STAGE_INITSOLVE
9138  * - \ref SCIP_STAGE_SOLVING
9139  * - \ref SCIP_STAGE_SOLVED
9140  */
9142  SCIP* scip, /**< SCIP data structure */
9143  SCIP_VAR* var, /**< problem variable */
9144  SCIP_Real solval /**< variable's LP solution value */
9145  )
9146 {
9147  SCIP_Real downsol;
9148  SCIP_Real upsol;
9149  SCIP_Real pscostdown;
9150  SCIP_Real pscostup;
9151 
9152  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9153 
9154  assert( var->scip == scip );
9155 
9156  downsol = SCIPsetFeasCeil(scip->set, solval-1.0);
9157  upsol = SCIPsetFeasFloor(scip->set, solval+1.0);
9158  pscostdown = SCIPvarGetPseudocostCurrentRun(var, scip->stat, downsol-solval);
9159  pscostup = SCIPvarGetPseudocostCurrentRun(var, scip->stat, upsol-solval);
9160 
9161  return SCIPbranchGetScore(scip->set, var, pscostdown, pscostup);
9162 }
9163 
9164 /** returns the variable's VSIDS value
9165  *
9166  * @return the variable's VSIDS value
9167  *
9168  * @pre This method can be called if @p scip is in one of the following stages:
9169  * - \ref SCIP_STAGE_INITPRESOLVE
9170  * - \ref SCIP_STAGE_PRESOLVING
9171  * - \ref SCIP_STAGE_EXITPRESOLVE
9172  * - \ref SCIP_STAGE_PRESOLVED
9173  * - \ref SCIP_STAGE_INITSOLVE
9174  * - \ref SCIP_STAGE_SOLVING
9175  * - \ref SCIP_STAGE_SOLVED
9176  */
9178  SCIP* scip, /**< SCIP data structure */
9179  SCIP_VAR* var, /**< problem variable */
9180  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9181  )
9182 {
9183  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarVSIDS", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9184 
9185  assert( var->scip == scip );
9186 
9187  if( dir != SCIP_BRANCHDIR_DOWNWARDS && dir != SCIP_BRANCHDIR_UPWARDS )
9188  {
9189  SCIPerrorMessage("invalid branching direction %d when asking for VSIDS value\n", dir);
9190  return SCIP_INVALID;
9191  }
9192 
9193  return SCIPvarGetVSIDS(var, scip->stat, dir);
9194 }
9195 
9196 /** returns the variable's VSIDS value only using conflicts of the current run
9197  *
9198  * @return the variable's VSIDS value only using conflicts of the current run
9199  *
9200  * @pre This method can be called if @p scip is in one of the following stages:
9201  * - \ref SCIP_STAGE_INITPRESOLVE
9202  * - \ref SCIP_STAGE_PRESOLVING
9203  * - \ref SCIP_STAGE_EXITPRESOLVE
9204  * - \ref SCIP_STAGE_PRESOLVED
9205  * - \ref SCIP_STAGE_INITSOLVE
9206  * - \ref SCIP_STAGE_SOLVING
9207  * - \ref SCIP_STAGE_SOLVED
9208  */
9210  SCIP* scip, /**< SCIP data structure */
9211  SCIP_VAR* var, /**< problem variable */
9212  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9213  )
9214 {
9215  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarVSIDSCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9216 
9217  assert( var->scip == scip );
9218 
9219  if( dir != SCIP_BRANCHDIR_DOWNWARDS && dir != SCIP_BRANCHDIR_UPWARDS )
9220  {
9221  SCIPerrorMessage("invalid branching direction %d when asking for VSIDS value\n", dir);
9222  return SCIP_INVALID;
9223  }
9224 
9225  return SCIPvarGetVSIDSCurrentRun(var, scip->stat, dir);
9226 }
9227 
9228 /** returns the variable's conflict score value
9229  *
9230  * @return the variable's conflict score value
9231  *
9232  * @pre This method can be called if @p scip is in one of the following stages:
9233  * - \ref SCIP_STAGE_INITPRESOLVE
9234  * - \ref SCIP_STAGE_PRESOLVING
9235  * - \ref SCIP_STAGE_EXITPRESOLVE
9236  * - \ref SCIP_STAGE_PRESOLVED
9237  * - \ref SCIP_STAGE_INITSOLVE
9238  * - \ref SCIP_STAGE_SOLVING
9239  * - \ref SCIP_STAGE_SOLVED
9240  */
9242  SCIP* scip, /**< SCIP data structure */
9243  SCIP_VAR* var /**< problem variable */
9244  )
9245 {
9246  SCIP_Real downscore;
9247  SCIP_Real upscore;
9248 
9249  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9250 
9251  assert( var->scip == scip );
9252 
9253  downscore = SCIPvarGetVSIDS(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9254  upscore = SCIPvarGetVSIDS(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9255 
9256  return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9257 }
9258 
9259 /** returns the variable's conflict score value only using conflicts of the current run
9260  *
9261  * @return the variable's conflict score value only using conflicts of the current run
9262  *
9263  * @pre This method can be called if @p scip is in one of the following stages:
9264  * - \ref SCIP_STAGE_INITPRESOLVE
9265  * - \ref SCIP_STAGE_PRESOLVING
9266  * - \ref SCIP_STAGE_EXITPRESOLVE
9267  * - \ref SCIP_STAGE_PRESOLVED
9268  * - \ref SCIP_STAGE_INITSOLVE
9269  * - \ref SCIP_STAGE_SOLVING
9270  * - \ref SCIP_STAGE_SOLVED
9271  */
9273  SCIP* scip, /**< SCIP data structure */
9274  SCIP_VAR* var /**< problem variable */
9275  )
9276 {
9277  SCIP_Real downscore;
9278  SCIP_Real upscore;
9279 
9280  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9281 
9282  assert( var->scip == scip );
9283 
9284  downscore = SCIPvarGetVSIDSCurrentRun(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9285  upscore = SCIPvarGetVSIDSCurrentRun(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9286 
9287  return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9288 }
9289 
9290 /** returns the variable's conflict length score
9291  *
9292  * @return the variable's conflict length score
9293  *
9294  * @pre This method can be called if @p scip is in one of the following stages:
9295  * - \ref SCIP_STAGE_INITPRESOLVE
9296  * - \ref SCIP_STAGE_PRESOLVING
9297  * - \ref SCIP_STAGE_EXITPRESOLVE
9298  * - \ref SCIP_STAGE_PRESOLVED
9299  * - \ref SCIP_STAGE_INITSOLVE
9300  * - \ref SCIP_STAGE_SOLVING
9301  * - \ref SCIP_STAGE_SOLVED
9302  */
9304  SCIP* scip, /**< SCIP data structure */
9305  SCIP_VAR* var /**< problem variable */
9306  )
9307 {
9308  SCIP_Real downscore;
9309  SCIP_Real upscore;
9310 
9311  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictlengthScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9312 
9313  assert( var->scip == scip );
9314 
9317 
9318  return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9319 }
9320 
9321 /** returns the variable's conflict length score only using conflicts of the current run
9322  *
9323  * @return the variable's conflict length score only using conflicts of the current run
9324  *
9325  * @pre This method can be called if @p scip is in one of the following stages:
9326  * - \ref SCIP_STAGE_INITPRESOLVE
9327  * - \ref SCIP_STAGE_PRESOLVING
9328  * - \ref SCIP_STAGE_EXITPRESOLVE
9329  * - \ref SCIP_STAGE_PRESOLVED
9330  * - \ref SCIP_STAGE_INITSOLVE
9331  * - \ref SCIP_STAGE_SOLVING
9332  * - \ref SCIP_STAGE_SOLVED
9333  */
9335  SCIP* scip, /**< SCIP data structure */
9336  SCIP_VAR* var /**< problem variable */
9337  )
9338 {
9339  SCIP_Real downscore;
9340  SCIP_Real upscore;
9341 
9342  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictlengthScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9343 
9344  assert( var->scip == scip );
9345 
9348 
9349  return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9350 }
9351 
9352 /** returns the variable's average conflict length
9353  *
9354  * @return the variable's average conflict length
9355  *
9356  * @pre This method can be called if @p scip is in one of the following stages:
9357  * - \ref SCIP_STAGE_INITPRESOLVE
9358  * - \ref SCIP_STAGE_PRESOLVING
9359  * - \ref SCIP_STAGE_EXITPRESOLVE
9360  * - \ref SCIP_STAGE_PRESOLVED
9361  * - \ref SCIP_STAGE_INITSOLVE
9362  * - \ref SCIP_STAGE_SOLVING
9363  * - \ref SCIP_STAGE_SOLVED
9364  */
9366  SCIP* scip, /**< SCIP data structure */
9367  SCIP_VAR* var, /**< problem variable */
9368  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9369  )
9370 {
9371  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgConflictlength", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9372 
9373  assert( var->scip == scip );
9374 
9375  return SCIPvarGetAvgConflictlength(var, dir);
9376 }
9377 
9378 /** returns the variable's average conflict length only using conflicts of the current run
9379  *
9380  * @return the variable's average conflict length only using conflicts of the current run
9381  *
9382  * @pre This method can be called if @p scip is in one of the following stages:
9383  * - \ref SCIP_STAGE_INITPRESOLVE
9384  * - \ref SCIP_STAGE_PRESOLVING
9385  * - \ref SCIP_STAGE_EXITPRESOLVE
9386  * - \ref SCIP_STAGE_PRESOLVED
9387  * - \ref SCIP_STAGE_INITSOLVE
9388  * - \ref SCIP_STAGE_SOLVING
9389  * - \ref SCIP_STAGE_SOLVED
9390  */
9392  SCIP* scip, /**< SCIP data structure */
9393  SCIP_VAR* var, /**< problem variable */
9394  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9395  )
9396 {
9397  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgConflictlengthCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9398 
9399  assert( var->scip == scip );
9400 
9401  return SCIPvarGetAvgConflictlengthCurrentRun(var, dir);
9402 }
9403 
9404 /** returns the average number of inferences found after branching on the variable in given direction;
9405  * if branching on the variable in the given direction was yet evaluated, the average number of inferences
9406  * over all variables for branching in the given direction is returned
9407  *
9408  * @return the average number of inferences found after branching on the variable in given direction
9409  *
9410  * @pre This method can be called if @p scip is in one of the following stages:
9411  * - \ref SCIP_STAGE_INITPRESOLVE
9412  * - \ref SCIP_STAGE_PRESOLVING
9413  * - \ref SCIP_STAGE_EXITPRESOLVE
9414  * - \ref SCIP_STAGE_PRESOLVED
9415  * - \ref SCIP_STAGE_INITSOLVE
9416  * - \ref SCIP_STAGE_SOLVING
9417  * - \ref SCIP_STAGE_SOLVED
9418  */
9420  SCIP* scip, /**< SCIP data structure */
9421  SCIP_VAR* var, /**< problem variable */
9422  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9423  )
9424 {
9425  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferences", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9426 
9427  assert( var->scip == scip );
9428 
9429  return SCIPvarGetAvgInferences(var, scip->stat, dir);
9430 }
9431 
9432 /** returns the average number of inferences found after branching on the variable in given direction in the current run;
9433  * if branching on the variable in the given direction was yet evaluated, the average number of inferences
9434  * over all variables for branching in the given direction is returned
9435  *
9436  * @return the average number of inferences found after branching on the variable in given direction in the current run
9437  *
9438  * @pre This method can be called if @p scip is in one of the following stages:
9439  * - \ref SCIP_STAGE_INITPRESOLVE
9440  * - \ref SCIP_STAGE_PRESOLVING
9441  * - \ref SCIP_STAGE_EXITPRESOLVE
9442  * - \ref SCIP_STAGE_PRESOLVED
9443  * - \ref SCIP_STAGE_INITSOLVE
9444  * - \ref SCIP_STAGE_SOLVING
9445  * - \ref SCIP_STAGE_SOLVED
9446  */
9448  SCIP* scip, /**< SCIP data structure */
9449  SCIP_VAR* var, /**< problem variable */
9450  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9451  )
9452 {
9453  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferencesCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9454 
9455  assert( var->scip == scip );
9456 
9457  return SCIPvarGetAvgInferencesCurrentRun(var, scip->stat, dir);
9458 }
9459 
9460 /** returns the variable's average inference score value
9461  *
9462  * @return the variable's average inference score value
9463  *
9464  * @pre This method can be called if @p scip is in one of the following stages:
9465  * - \ref SCIP_STAGE_INITPRESOLVE
9466  * - \ref SCIP_STAGE_PRESOLVING
9467  * - \ref SCIP_STAGE_EXITPRESOLVE
9468  * - \ref SCIP_STAGE_PRESOLVED
9469  * - \ref SCIP_STAGE_INITSOLVE
9470  * - \ref SCIP_STAGE_SOLVING
9471  * - \ref SCIP_STAGE_SOLVED
9472  */
9474  SCIP* scip, /**< SCIP data structure */
9475  SCIP_VAR* var /**< problem variable */
9476  )
9477 {
9478  SCIP_Real inferdown;
9479  SCIP_Real inferup;
9480 
9481  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9482 
9483  assert( var->scip == scip );
9484 
9485  inferdown = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9486  inferup = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9487 
9488  return SCIPbranchGetScore(scip->set, var, inferdown, inferup);
9489 }
9490 
9491 /** returns the variable's average inference score value only using inferences of the current run
9492  *
9493  * @return the variable's average inference score value only using inferences of the current run
9494  *
9495  * @pre This method can be called if @p scip is in one of the following stages:
9496  * - \ref SCIP_STAGE_INITPRESOLVE
9497  * - \ref SCIP_STAGE_PRESOLVING
9498  * - \ref SCIP_STAGE_EXITPRESOLVE
9499  * - \ref SCIP_STAGE_PRESOLVED
9500  * - \ref SCIP_STAGE_INITSOLVE
9501  * - \ref SCIP_STAGE_SOLVING
9502  * - \ref SCIP_STAGE_SOLVED
9503  */
9505  SCIP* scip, /**< SCIP data structure */
9506  SCIP_VAR* var /**< problem variable */
9507  )
9508 {
9509  SCIP_Real inferdown;
9510  SCIP_Real inferup;
9511 
9512  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9513 
9514  assert( var->scip == scip );
9515 
9518 
9519  return SCIPbranchGetScore(scip->set, var, inferdown, inferup);
9520 }
9521 
9522 /** initializes the upwards and downwards pseudocosts, conflict scores, conflict lengths, inference scores, cutoff scores
9523  * of a variable to the given values
9524  *
9525  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9526  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9527  *
9528  * @pre This method can be called if @p scip is in one of the following stages:
9529  * - \ref SCIP_STAGE_TRANSFORMED
9530  * - \ref SCIP_STAGE_INITPRESOLVE
9531  * - \ref SCIP_STAGE_PRESOLVING
9532  * - \ref SCIP_STAGE_EXITPRESOLVE
9533  * - \ref SCIP_STAGE_PRESOLVED
9534  * - \ref SCIP_STAGE_INITSOLVE
9535  * - \ref SCIP_STAGE_SOLVING
9536  */
9538  SCIP* scip, /**< SCIP data structure */
9539  SCIP_VAR* var, /**< variable which should be initialized */
9540  SCIP_Real downpscost, /**< value to which pseudocosts for downwards branching should be initialized */
9541  SCIP_Real uppscost, /**< value to which pseudocosts for upwards branching should be initialized */
9542  SCIP_Real downvsids, /**< value to which VSIDS score for downwards branching should be initialized */
9543  SCIP_Real upvsids, /**< value to which VSIDS score for upwards branching should be initialized */
9544  SCIP_Real downconflen, /**< value to which conflict length score for downwards branching should be initialized */
9545  SCIP_Real upconflen, /**< value to which conflict length score for upwards branching should be initialized */
9546  SCIP_Real downinfer, /**< value to which inference counter for downwards branching should be initialized */
9547  SCIP_Real upinfer, /**< value to which inference counter for upwards branching should be initialized */
9548  SCIP_Real downcutoff, /**< value to which cutoff counter for downwards branching should be initialized */
9549  SCIP_Real upcutoff /**< value to which cutoff counter for upwards branching should be initialized */
9550  )
9551 {
9552  SCIP_CALL( SCIPcheckStage(scip, "SCIPinitVarBranchStats", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
9553 
9554  assert(downpscost >= 0.0 && uppscost >= 0.0);
9555  assert(downvsids >= 0.0 && upvsids >= 0.0);
9556  assert(downconflen >= 0.0 && upconflen >= 0.0);
9557  assert(downinfer >= 0.0 && upinfer >= 0.0);
9558  assert(downcutoff >= 0.0 && upcutoff >= 0.0);
9559 
9560  if( !SCIPisFeasZero(scip, downpscost) || !SCIPisFeasZero(scip, downvsids)
9561  || !SCIPisFeasZero(scip, downinfer) || !SCIPisFeasZero(scip, downcutoff) )
9562  {
9564  SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, -1.0, downpscost, 1.0) );
9566  SCIP_CALL( SCIPvarIncVSIDS(var, NULL, scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, SCIP_UNKNOWN, downvsids) );
9568  }
9569 
9570  if( !SCIPisFeasZero(scip, downconflen) )
9571  {
9573  }
9574 
9575  if( !SCIPisFeasZero(scip, uppscost) || !SCIPisFeasZero(scip, upvsids)
9576  || !SCIPisFeasZero(scip, upinfer) || !SCIPisFeasZero(scip, upcutoff) )
9577  {
9579  SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, 1.0, uppscost, 1.0) );
9581  SCIP_CALL( SCIPvarIncVSIDS(var, NULL, scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, SCIP_UNKNOWN, upvsids) );
9583  }
9584 
9585  if( !SCIPisFeasZero(scip, upconflen) )
9586  {
9588  }
9589 
9590  return SCIP_OKAY;
9591 }
9592 
9593 /** initializes the upwards and downwards conflict scores, conflict lengths, inference scores, cutoff scores of a
9594  * variable w.r.t. a value by the given values (SCIP_VALUEHISTORY)
9595  *
9596  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9597  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9598  *
9599  * @pre This method can be called if @p scip is in one of the following stages:
9600  * - \ref SCIP_STAGE_TRANSFORMED
9601  * - \ref SCIP_STAGE_INITPRESOLVE
9602  * - \ref SCIP_STAGE_PRESOLVING
9603  * - \ref SCIP_STAGE_EXITPRESOLVE
9604  * - \ref SCIP_STAGE_PRESOLVED
9605  * - \ref SCIP_STAGE_INITSOLVE
9606  * - \ref SCIP_STAGE_SOLVING
9607  */
9609  SCIP* scip, /**< SCIP data structure */
9610  SCIP_VAR* var, /**< variable which should be initialized */
9611  SCIP_Real value, /**< domain value, or SCIP_UNKNOWN */
9612  SCIP_Real downvsids, /**< value to which VSIDS score for downwards branching should be initialized */
9613  SCIP_Real upvsids, /**< value to which VSIDS score for upwards branching should be initialized */
9614  SCIP_Real downconflen, /**< value to which conflict length score for downwards branching should be initialized */
9615  SCIP_Real upconflen, /**< value to which conflict length score for upwards branching should be initialized */
9616  SCIP_Real downinfer, /**< value to which inference counter for downwards branching should be initialized */
9617  SCIP_Real upinfer, /**< value to which inference counter for upwards branching should be initialized */
9618  SCIP_Real downcutoff, /**< value to which cutoff counter for downwards branching should be initialized */
9619  SCIP_Real upcutoff /**< value to which cutoff counter for upwards branching should be initialized */
9620  )
9621 {
9622  SCIP_CALL( SCIPcheckStage(scip, "SCIPinitVarValueBranchStats", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
9623 
9624  assert(downvsids >= 0.0 && upvsids >= 0.0);
9625  assert(downconflen >= 0.0 && upconflen >= 0.0);
9626  assert(downinfer >= 0.0 && upinfer >= 0.0);
9627  assert(downcutoff >= 0.0 && upcutoff >= 0.0);
9628 
9629  if( !SCIPisFeasZero(scip, downvsids) || !SCIPisFeasZero(scip, downinfer) || !SCIPisFeasZero(scip, downcutoff) )
9630  {
9631  SCIP_CALL( SCIPvarIncNBranchings(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, 1) );
9632  SCIP_CALL( SCIPvarIncInferenceSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downinfer) );
9633  SCIP_CALL( SCIPvarIncVSIDS(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downvsids) );
9634  SCIP_CALL( SCIPvarIncCutoffSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downcutoff) );
9635  }
9636 
9637  if( !SCIPisFeasZero(scip, downconflen) )
9638  {
9639  SCIP_CALL( SCIPvarIncNActiveConflicts(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downconflen) );
9640  }
9641 
9642  if( !SCIPisFeasZero(scip, upvsids) || !SCIPisFeasZero(scip, upinfer) || !SCIPisFeasZero(scip, upcutoff) )
9643  {
9644  SCIP_CALL( SCIPvarIncNBranchings(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, 1) );
9645  SCIP_CALL( SCIPvarIncInferenceSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upinfer) );
9646  SCIP_CALL( SCIPvarIncVSIDS(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upvsids) );
9647  SCIP_CALL( SCIPvarIncCutoffSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upcutoff) );
9648  }
9649 
9650  if( !SCIPisFeasZero(scip, upconflen) )
9651  {
9652  SCIP_CALL( SCIPvarIncNActiveConflicts(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upconflen) );
9653  }
9654 
9655  return SCIP_OKAY;
9656 }
9657 
9658 /** returns the average number of cutoffs found after branching on the variable in given direction;
9659  * if branching on the variable in the given direction was yet evaluated, the average number of cutoffs
9660  * over all variables for branching in the given direction is returned
9661  *
9662  * @return the average number of cutoffs found after branching on the variable in given direction
9663  *
9664  * @pre This method can be called if @p scip is in one of the following stages:
9665  * - \ref SCIP_STAGE_INITPRESOLVE
9666  * - \ref SCIP_STAGE_PRESOLVING
9667  * - \ref SCIP_STAGE_EXITPRESOLVE
9668  * - \ref SCIP_STAGE_PRESOLVED
9669  * - \ref SCIP_STAGE_INITSOLVE
9670  * - \ref SCIP_STAGE_SOLVING
9671  * - \ref SCIP_STAGE_SOLVED
9672  */
9674  SCIP* scip, /**< SCIP data structure */
9675  SCIP_VAR* var, /**< problem variable */
9676  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9677  )
9678 {
9679  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffs", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9680 
9681  assert( var->scip == scip );
9682 
9683  return SCIPvarGetAvgCutoffs(var, scip->stat, dir);
9684 }
9685 
9686 /** returns the average number of cutoffs found after branching on the variable in given direction in the current run;
9687  * if branching on the variable in the given direction was yet evaluated, the average number of cutoffs
9688  * over all variables for branching in the given direction is returned
9689  *
9690  * @return the average number of cutoffs found after branching on the variable in given direction in the current run
9691  *
9692  * @pre This method can be called if @p scip is in one of the following stages:
9693  * - \ref SCIP_STAGE_INITPRESOLVE
9694  * - \ref SCIP_STAGE_PRESOLVING
9695  * - \ref SCIP_STAGE_EXITPRESOLVE
9696  * - \ref SCIP_STAGE_PRESOLVED
9697  * - \ref SCIP_STAGE_INITSOLVE
9698  * - \ref SCIP_STAGE_SOLVING
9699  * - \ref SCIP_STAGE_SOLVED
9700  */
9702  SCIP* scip, /**< SCIP data structure */
9703  SCIP_VAR* var, /**< problem variable */
9704  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9705  )
9706 {
9707  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffsCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9708 
9709  assert( var->scip == scip );
9710 
9711  return SCIPvarGetAvgCutoffsCurrentRun(var, scip->stat, dir);
9712 }
9713 
9714 /** returns the variable's average cutoff score value
9715  *
9716  * @return the variable's average cutoff score value
9717  *
9718  * @pre This method can be called if @p scip is in one of the following stages:
9719  * - \ref SCIP_STAGE_INITPRESOLVE
9720  * - \ref SCIP_STAGE_PRESOLVING
9721  * - \ref SCIP_STAGE_EXITPRESOLVE
9722  * - \ref SCIP_STAGE_PRESOLVED
9723  * - \ref SCIP_STAGE_INITSOLVE
9724  * - \ref SCIP_STAGE_SOLVING
9725  * - \ref SCIP_STAGE_SOLVED
9726  */
9728  SCIP* scip, /**< SCIP data structure */
9729  SCIP_VAR* var /**< problem variable */
9730  )
9731 {
9732  SCIP_Real cutoffdown;
9733  SCIP_Real cutoffup;
9734 
9735  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9736 
9737  assert( var->scip == scip );
9738 
9739  cutoffdown = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9740  cutoffup = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9741 
9742  return SCIPbranchGetScore(scip->set, var, cutoffdown, cutoffup);
9743 }
9744 
9745 /** returns the variable's average cutoff score value, only using cutoffs of the current run
9746  *
9747  * @return the variable's average cutoff score value, only using cutoffs of the current run
9748  *
9749  * @pre This method can be called if @p scip is in one of the following stages:
9750  * - \ref SCIP_STAGE_INITPRESOLVE
9751  * - \ref SCIP_STAGE_PRESOLVING
9752  * - \ref SCIP_STAGE_EXITPRESOLVE
9753  * - \ref SCIP_STAGE_PRESOLVED
9754  * - \ref SCIP_STAGE_INITSOLVE
9755  * - \ref SCIP_STAGE_SOLVING
9756  * - \ref SCIP_STAGE_SOLVED
9757  */
9759  SCIP* scip, /**< SCIP data structure */
9760  SCIP_VAR* var /**< problem variable */
9761  )
9762 {
9763  SCIP_Real cutoffdown;
9764  SCIP_Real cutoffup;
9765 
9766  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9767 
9768  assert( var->scip == scip );
9769 
9772 
9773  return SCIPbranchGetScore(scip->set, var, cutoffdown, cutoffup);
9774 }
9775 
9776 /** returns the variable's average inference/cutoff score value, weighting the cutoffs of the variable with the given
9777  * factor
9778  *
9779  * @return the variable's average inference/cutoff score value
9780  *
9781  * @pre This method can be called if @p scip is in one of the following stages:
9782  * - \ref SCIP_STAGE_INITPRESOLVE
9783  * - \ref SCIP_STAGE_PRESOLVING
9784  * - \ref SCIP_STAGE_EXITPRESOLVE
9785  * - \ref SCIP_STAGE_PRESOLVED
9786  * - \ref SCIP_STAGE_INITSOLVE
9787  * - \ref SCIP_STAGE_SOLVING
9788  * - \ref SCIP_STAGE_SOLVED
9789  */
9791  SCIP* scip, /**< SCIP data structure */
9792  SCIP_VAR* var, /**< problem variable */
9793  SCIP_Real cutoffweight /**< factor to weigh average number of cutoffs in branching score */
9794  )
9795 {
9796  SCIP_Real avginferdown;
9797  SCIP_Real avginferup;
9798  SCIP_Real avginfer;
9799  SCIP_Real inferdown;
9800  SCIP_Real inferup;
9801  SCIP_Real cutoffdown;
9802  SCIP_Real cutoffup;
9803 
9804  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceCutoffScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9805 
9806  assert( var->scip == scip );
9807 
9810  avginfer = (avginferdown + avginferup)/2.0;
9811  inferdown = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9812  inferup = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9813  cutoffdown = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9814  cutoffup = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9815 
9816  return SCIPbranchGetScore(scip->set, var,
9817  inferdown + cutoffweight * avginfer * cutoffdown, inferup + cutoffweight * avginfer * cutoffup);
9818 }
9819 
9820 /** returns the variable's average inference/cutoff score value, weighting the cutoffs of the variable with the given
9821  * factor, only using inferences and cutoffs of the current run
9822  *
9823  * @return the variable's average inference/cutoff score value, only using inferences and cutoffs of the current run
9824  *
9825  * @pre This method can be called if @p scip is in one of the following stages:
9826  * - \ref SCIP_STAGE_INITPRESOLVE
9827  * - \ref SCIP_STAGE_PRESOLVING
9828  * - \ref SCIP_STAGE_EXITPRESOLVE
9829  * - \ref SCIP_STAGE_PRESOLVED
9830  * - \ref SCIP_STAGE_INITSOLVE
9831  * - \ref SCIP_STAGE_SOLVING
9832  * - \ref SCIP_STAGE_SOLVED
9833  */
9835  SCIP* scip, /**< SCIP data structure */
9836  SCIP_VAR* var, /**< problem variable */
9837  SCIP_Real cutoffweight /**< factor to weigh average number of cutoffs in branching score */
9838  )
9839 {
9840  SCIP_Real avginferdown;
9841  SCIP_Real avginferup;
9842  SCIP_Real avginfer;
9843  SCIP_Real inferdown;
9844  SCIP_Real inferup;
9845  SCIP_Real cutoffdown;
9846  SCIP_Real cutoffup;
9847 
9848  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceCutoffScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9849 
9850  assert( var->scip == scip );
9851 
9854  avginfer = (avginferdown + avginferup)/2.0;
9859 
9860  return SCIPbranchGetScore(scip->set, var,
9861  inferdown + cutoffweight * avginfer * cutoffdown, inferup + cutoffweight * avginfer * cutoffup);
9862 }
9863 
9864 /** outputs variable information to file stream via the message system
9865  *
9866  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9867  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9868  *
9869  * @pre This method can be called if @p scip is in one of the following stages:
9870  * - \ref SCIP_STAGE_PROBLEM
9871  * - \ref SCIP_STAGE_TRANSFORMING
9872  * - \ref SCIP_STAGE_TRANSFORMED
9873  * - \ref SCIP_STAGE_INITPRESOLVE
9874  * - \ref SCIP_STAGE_PRESOLVING
9875  * - \ref SCIP_STAGE_EXITPRESOLVE
9876  * - \ref SCIP_STAGE_PRESOLVED
9877  * - \ref SCIP_STAGE_INITSOLVE
9878  * - \ref SCIP_STAGE_SOLVING
9879  * - \ref SCIP_STAGE_SOLVED
9880  * - \ref SCIP_STAGE_EXITSOLVE
9881  * - \ref SCIP_STAGE_FREETRANS
9882  *
9883  * @note If the message handler is set to a NULL pointer nothing will be printed
9884  */
9886  SCIP* scip, /**< SCIP data structure */
9887  SCIP_VAR* var, /**< problem variable */
9888  FILE* file /**< output file (or NULL for standard output) */
9889  )
9890 {
9891  SCIP_CALL( SCIPcheckStage(scip, "SCIPprintVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
9892 
9893  SCIP_CALL( SCIPvarPrint(var, scip->set, scip->messagehdlr, file) );
9894 
9895  return SCIP_OKAY;
9896 }
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:110
SCIP_STAT * stat
Definition: struct_scip.h:79
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:59
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
SCIP_Real sbup
Definition: struct_lp.h:154
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip_mem.h:99
void SCIPcolGetStrongbranchLast(SCIP_COL *col, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Real *solval, SCIP_Real *lpobjval)
Definition: lp.c:4707
SCIP_Real SCIPvarGetAvgConflictlengthCurrentRun(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:15394
SCIP_RETCODE SCIPflattenVarAggregationGraph(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1693
SCIP_Bool SCIPsolveIsStopped(SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool checknodelimits)
Definition: solve.c:102
SCIP_Longint nsbdivinglps
Definition: struct_stat.h:209
SCIP_RETCODE SCIPchgVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4943
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6215
SCIP_RETCODE SCIPtreeEndProbing(SCIP_TREE *tree, SCIP_REOPT *reopt, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_LP *lp, SCIP_RELAXATION *relaxation, SCIP_PRIMAL *primal, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable)
Definition: tree.c:6869
SCIP_RETCODE SCIPcolGetStrongbranch(SCIP_COL *col, SCIP_Bool integral, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp, int itlim, SCIP_Bool updatecol, SCIP_Bool updatestat, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *lperror)
Definition: lp.c:4299
void SCIPvarGetClosestVlb(SCIP_VAR *var, SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real *closestvlb, int *closestvlbidx)
Definition: var.c:14113
SCIP_Real SCIPgetVarAvgInferences(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9419
SCIP_RETCODE SCIPvarIncInferenceSum(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_BRANCHDIR dir, SCIP_Real value, SCIP_Real weight)
Definition: var.c:15521
SCIP_Bool SCIPvarsHaveCommonClique(SCIP_VAR *var1, SCIP_Bool value1, SCIP_VAR *var2, SCIP_Bool value2, SCIP_Bool regardimplics)
Definition: var.c:11465
SCIP_Real SCIPgetVarAvgCutoffs(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9673
SCIP_VAR ** SCIPcliqueGetVars(SCIP_CLIQUE *clique)
Definition: implics.c:3380
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6273
int SCIPcliquetableGetVarComponentIdx(SCIP_CLIQUETABLE *cliquetable, SCIP_VAR *var)
Definition: implics.c:2348
SCIP_RETCODE SCIPskipSpace(char **s)
Definition: misc.c:10777
void SCIPstatEnableVarHistory(SCIP_STAT *stat)
Definition: stat.c:166
internal methods for storing primal CIP solutions
SCIP_RETCODE SCIPvarIncVSIDS(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_BRANCHDIR dir, SCIP_Real value, SCIP_Real weight)
Definition: var.c:15041
SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5203
SCIP_RETCODE SCIPvarAddVub(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_CLIQUETABLE *cliquetable, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_VAR *vubvar, SCIP_Real vubcoef, SCIP_Real vubconstant, SCIP_Bool transitive, SCIP_Bool *infeasible, int *nbdchgs)
Definition: var.c:10455
void SCIPvarUpdateBestRootSol(SCIP_VAR *var, SCIP_SET *set, SCIP_Real rootsol, SCIP_Real rootredcost, SCIP_Real rootlpobjval)
Definition: var.c:13270
SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2128
SCIP_STATUS status
Definition: struct_stat.h:186
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition: lp.c:17847
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition: scip_tree.c:91
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:365
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
Definition: lpi_clp.cpp:3931
SCIP_RETCODE SCIPsetRelaxSolValsSol(SCIP *scip, SCIP_RELAX *relax, SCIP_SOL *sol, SCIP_Bool includeslp)
Definition: scip_var.c:2489
public methods for branch and bound tree
SCIP_Real SCIPrelaxationGetSolObj(SCIP_RELAXATION *relaxation)
Definition: relax.c:839
SCIP_RETCODE SCIPgetBinvarRepresentative(SCIP *scip, SCIP_VAR *var, SCIP_VAR **repvar, SCIP_Bool *negated)
Definition: scip_var.c:1597
SCIP_RETCODE SCIPbacktrackProbing(SCIP *scip, int probingdepth)
Definition: scip_probing.c:225
internal methods for branch and bound tree
SCIP_Real SCIPgetVarAvgInferenceCutoffScore(SCIP *scip, SCIP_VAR *var, SCIP_Real cutoffweight)
Definition: scip_var.c:9790
SCIP_CONFLICT * conflict
Definition: struct_scip.h:96
SCIP_RETCODE SCIPaddVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real addobj)
Definition: scip_var.c:4562
SCIP_Real SCIPvarGetAvgCutoffsCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:16302
SCIP_Real SCIPvarGetBranchFactor(SCIP_VAR *var)
Definition: var.c:18061
SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:1992
void SCIPlpEndStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16358
SCIP_RETCODE SCIPclearRelaxSolVals(SCIP *scip, SCIP_RELAX *relax)
Definition: scip_var.c:2364
public methods for memory management
SCIP_Real SCIPgetVarAvgInferencesCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9447
int SCIPgetProbingDepth(SCIP *scip)
Definition: scip_probing.c:198
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
SCIP_Real SCIPgetVarConflictlengthScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9334
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6613
#define SCIPsetDuplicateBufferArray(set, ptr, source, num)
Definition: set.h:1736
#define SCIP_DECL_VARTRANS(x)
Definition: type_var.h:151
SCIP_RETCODE SCIPvarChgLbGlobal(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_Real newbound)
Definition: var.c:7175
SCIP_Bool SCIPvarDoNotMultaggr(SCIP_VAR *var)
Definition: var.c:5871
SCIP_RETCODE SCIPvarCreateTransformed(SCIP_VAR **var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
Definition: var.c:2118
public methods for implications, variable bounds, and cliques
SCIP_Real SCIPvarGetPseudocostCountCurrentRun(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:14608
methods for implications, variable bounds, and cliques
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17901
SCIP_RETCODE SCIPvarGetProbvarBinary(SCIP_VAR **var, SCIP_Bool *negated)
Definition: var.c:12300
SCIP_Bool SCIPvarIsPscostRelerrorReliable(SCIP_VAR *var, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real threshold, SCIP_CONFIDENCELEVEL clevel)
Definition: var.c:14774
#define SCIP_MAXSTRLEN
Definition: def.h:302
SCIP_Bool conf_usesb
Definition: struct_set.h:236
SCIP_Real SCIPgetVarPseudocostVal(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta)
Definition: scip_var.c:8814
void SCIPgmlWriteArc(FILE *file, unsigned int source, unsigned int target, const char *label, const char *color)
Definition: misc.c:638
internal methods for clocks and timing issues
#define SCIP_VARTYPE_INTEGER_CHAR
Definition: def.h:158
SCIP_RETCODE SCIPvarChgLbOriginal(SCIP_VAR *var, SCIP_SET *set, SCIP_Real newbound)
Definition: var.c:6557
SCIP_Longint SCIPcolGetStrongbranchNode(SCIP_COL *col)
Definition: lp.c:17173
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:139
SCIP_Real SCIPgetVarRedcost(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1864
int SCIPtreeGetProbingDepth(SCIP_TREE *tree)
Definition: tree.c:8432
SCIP_RETCODE SCIPgetNegatedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **negvars)
Definition: scip_var.c:1560
SCIP_Bool presol_donotaggr
Definition: struct_set.h:463
SCIP_RETCODE SCIPnodeAddBoundinfer(SCIP_NODE *node, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_VAR *var, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype, SCIP_CONS *infercons, SCIP_PROP *inferprop, int inferinfo, SCIP_Bool probingchange)
Definition: tree.c:1812
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17957
SCIP_RETCODE SCIPvarChgLbLazy(SCIP_VAR *var, SCIP_SET *set, SCIP_Real lazylb)
Definition: var.c:7459
#define SCIP_CALL_FINALLY(x, y)
Definition: def.h:436
SCIP_RETCODE SCIPgetVarStrongbranchLast(SCIP *scip, SCIP_VAR *var, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Real *solval, SCIP_Real *lpobjval)
Definition: scip_var.c:4010
SCIP_Real SCIPgetColRedcost(SCIP *scip, SCIP_COL *col)
Definition: scip_lp.c:1154
SCIP_Real constant
Definition: struct_var.h:193
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_EVENTQUEUE * eventqueue
Definition: struct_scip.h:89
SCIP_Longint nsbtimesiterlimhit
Definition: struct_stat.h:121
SCIP_RETCODE SCIPinferVarLbProp(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_PROP *inferprop, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5895
SCIP_Real SCIPvarGetMultaggrLbGlobal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8556
SCIP_RETCODE SCIPchgVarLbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4846
SCIP_PRIMAL * primal
Definition: struct_scip.h:94
void SCIPstatDisableVarHistory(SCIP_STAT *stat)
Definition: stat.c:156
SCIP_Bool SCIPpscostThresholdProbabilityTest(SCIP *scip, SCIP_VAR *var, SCIP_Real frac, SCIP_Real threshold, SCIP_BRANCHDIR dir, SCIP_CONFIDENCELEVEL clevel)
Definition: scip_var.c:9059
SCIP_RETCODE SCIPvarChgUbOriginal(SCIP_VAR *var, SCIP_SET *set, SCIP_Real newbound)
Definition: var.c:6616
void SCIPgmlWriteNode(FILE *file, unsigned int id, const char *label, const char *nodetype, const char *fillcolor, const char *bordercolor)
Definition: misc.c:496
SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip_var.c:1439
SCIP_RETCODE SCIPparseVarName(SCIP *scip, const char *str, SCIP_VAR **var, char **endptr)
Definition: scip_var.c:533
SCIP_RETCODE SCIPvarParseOriginal(SCIP_VAR **var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, const char *str, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARCOPY((*varcopy)), SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_VARDATA *vardata, char **endptr, SCIP_Bool *success)
Definition: var.c:2497
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1248
interface methods for specific LP solvers
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:17422
SCIP_RETCODE SCIPgetLPI(SCIP *scip, SCIP_LPI **lpi)
Definition: scip_lp.c:985
SCIP_Real SCIPvarGetSol(SCIP_VAR *var, SCIP_Bool getlpval)
Definition: var.c:13247
SCIP_RETCODE SCIPchgVarUbLazy(SCIP *scip, SCIP_VAR *var, SCIP_Real lazyub)
Definition: scip_var.c:5164
void SCIPgmlWriteClosing(FILE *file)
Definition: misc.c:698
SCIP_Real SCIPbranchGetScore(SCIP_SET *set, SCIP_VAR *var, SCIP_Real downgain, SCIP_Real upgain)
Definition: branch.c:2190
SCIP_RETCODE SCIPvarMarkDoNotMultaggr(SCIP_VAR *var)
Definition: var.c:6132
SCIP_Real SCIPgetVarPseudocostCountCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:8950
SCIP_BOUNDTYPE SCIPboundchgGetBoundtype(SCIP_BOUNDCHG *boundchg)
Definition: var.c:17169
SCIP_RETCODE SCIPsetRelaxSolVals(SCIP *scip, SCIP_RELAX *relax, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Bool includeslp)
Definition: scip_var.c:2447
SCIP_Real SCIPgetVarPseudocostScoreCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real solval)
Definition: scip_var.c:9141
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_BRANCHCAND * branchcand
Definition: struct_scip.h:90
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition: scip_prob.c:1866
#define NLOCKTYPES
Definition: type_var.h:94
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:360
#define FALSE
Definition: def.h:96
SCIP_Bool SCIPconsIsLockedTypeNeg(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
Definition: cons.c:8471
SCIP_Real SCIPadjustedVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real ub)
Definition: scip_var.c:4645
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3024
SCIP_Bool misc_allowweakdualreds
Definition: struct_set.h:409
SCIP_Bool SCIPsetIsFeasIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6756
SCIP_Real SCIPgetVarVSIDS(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9177
struct SCIP_VarData SCIP_VARDATA
Definition: type_var.h:120
SCIP_RETCODE SCIPinferBinvarProp(SCIP *scip, SCIP_VAR *var, SCIP_Bool fixedval, SCIP_PROP *inferprop, int inferinfo, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6120
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:290
SCIP_Real SCIPgetVarMultaggrUbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6591
SCIP_RETCODE SCIPvarTransform(SCIP_VAR *origvar, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_OBJSENSE objsense, SCIP_VAR **transvar)
Definition: var.c:3462
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Real SCIPgetVarPseudocostValCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta)
Definition: scip_var.c:8842
SCIP_Real constant
Definition: struct_var.h:203
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10788
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6327
SCIP_STAGE stage
Definition: struct_set.h:74
#define TRUE
Definition: def.h:95
SCIP_Real SCIPvarGetAvgConflictlength(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:15350
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
SCIP_RETCODE SCIPaddVarLocks(SCIP *scip, SCIP_VAR *var, int nlocksdown, int nlocksup)
Definition: scip_var.c:4317
SCIP_Longint SCIPgetVarStrongbranchNode(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:4160
SCIP_RETCODE SCIPhashmapInsertInt(SCIP_HASHMAP *hashmap, void *origin, int image)
Definition: misc.c:3142
void SCIPlpStartStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16345
enum SCIP_Varstatus SCIP_VARSTATUS
Definition: type_var.h:57
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1734
int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
Definition: tree.c:8404
SCIP_RETCODE SCIPvarCreateOriginal(SCIP_VAR **var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
Definition: var.c:2075
SCIP_Bool branch_checksbsol
Definition: struct_set.h:207
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17591
SCIP_Bool branch_divingpscost
Definition: struct_set.h:204
SCIP_RETCODE SCIPvarAddImplic(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_CLIQUETABLE *cliquetable, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_Bool varfixing, SCIP_VAR *implvar, SCIP_BOUNDTYPE impltype, SCIP_Real implbound, SCIP_Bool transitive, SCIP_Bool *infeasible, int *nbdchgs)
Definition: var.c:10902
#define SCIP_DECL_VARCOPY(x)
Definition: type_var.h:194
unsigned int sbdownvalid
Definition: struct_lp.h:188
internal methods for branching rules and branching candidate storage
SCIP_RETCODE SCIPcliquetableCleanup(SCIP_CLIQUETABLE *cliquetable, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, int *nchgbds, SCIP_Bool *infeasible)
Definition: implics.c:2920
static SCIP_RETCODE calcCliquePartitionGreedy(SCIP *const scip, SCIP_VAR **const vars, SCIP_Bool *const values, int const nvars, int *const cliquepartition, int *const ncliques)
Definition: scip_var.c:7140
SCIP_RETCODE SCIPcreateVarBasic(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype)
Definition: scip_var.c:194
SCIP_Real SCIPgetVarAvgCutoffsCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9701
SCIP_Bool presol_donotmultaggr
Definition: struct_set.h:462
SCIP_Real SCIPgetVarVSIDSCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9209
SCIP_RETCODE SCIPvarChgUbGlobal(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_Real newbound)
Definition: var.c:7318
SCIP_Real SCIPgetVarAvgCutoffScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9758
public methods for problem variables
SCIP_Bool SCIPisVarPscostRelerrorReliable(SCIP *scip, SCIP_VAR *var, SCIP_Real threshold, SCIP_CONFIDENCELEVEL clevel)
Definition: scip_var.c:9078
SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5320
SCIP_Real SCIPgetRelaxSolObj(SCIP *scip)
Definition: scip_var.c:2632
SCIP_Bool SCIPgetVarWasFixedAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2282
SCIP_Real SCIPvarGetAvgInferences(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:16057
SCIP_Bool diving
Definition: struct_lp.h:380
SCIP_Real SCIPgetVarPseudocost(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:8868
SCIP_RETCODE SCIPchgVarLbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_probing.c:301
SCIP_RETCODE SCIPvarsGetActiveVars(SCIP_SET *set, SCIP_VAR **vars, int *nvars, int varssize, int *requiredsize)
Definition: var.c:11996
SCIP_RETCODE SCIPchgVarUbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4890
SCIP_RETCODE SCIPwriteVarsPolynomial(SCIP *scip, FILE *file, SCIP_VAR ***monomialvars, SCIP_Real **monomialexps, SCIP_Real *monomialcoefs, int *monomialnvars, int nmonomials, SCIP_Bool type)
Definition: scip_var.c:404
void SCIPrelaxationSetSolValid(SCIP_RELAXATION *relaxation, SCIP_Bool isvalid, SCIP_Bool includeslp)
Definition: relax.c:795
SCIP_Real SCIPgetVarMultaggrUbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6561
static SCIP_RETCODE labelSortStable(SCIP *scip, SCIP_VAR **vars, int *classlabels, SCIP_VAR **sortedvars, int *sortedindices, int *classesstartposs, int nvars, int nclasses)
Definition: scip_var.c:7014
SCIP_PROB * transprob
Definition: struct_scip.h:98
SCIP_Bool SCIPrelaxationIsSolValid(SCIP_RELAXATION *relaxation)
Definition: relax.c:808
SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4676
SCIP_Real constant
Definition: struct_var.h:186
SCIP_Bool conf_enable
Definition: struct_set.h:227
SCIP_RETCODE SCIPaddVarVlb(SCIP *scip, SCIP_VAR *var, SCIP_VAR *vlbvar, SCIP_Real vlbcoef, SCIP_Real vlbconstant, SCIP_Bool *infeasible, int *nbdchgs)
Definition: scip_var.c:6661
SCIP_RETCODE SCIPvarChgType(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_VARTYPE vartype)
Definition: var.c:6168
#define SCIP_LONGINT_MAX
Definition: def.h:172
SCIP_RETCODE SCIPprobChgVarType(SCIP_PROB *prob, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_VAR *var, SCIP_VARTYPE vartype)
Definition: prob.c:1142
SCIP_RETCODE SCIPcreateLPSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip_sol.c:370
SCIP_RETCODE SCIPmarkRelaxSolInvalid(SCIP *scip)
Definition: scip_var.c:2582
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
SCIP_RETCODE SCIPvarUpdatePseudocost(SCIP_VAR *var, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
Definition: var.c:14369
#define SCIPsetFreeBufferArray(set, ptr)
Definition: set.h:1741
SCIP_Real SCIPadjustedVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real lb)
Definition: scip_var.c:4613
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition: type_lp.h:51
void SCIPvarAdjustLb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *lb)
Definition: var.c:6507
SCIP_Bool SCIPisTransformed(SCIP *scip)
Definition: scip_general.c:575
SCIP_RETCODE SCIPaddVarVub(SCIP *scip, SCIP_VAR *var, SCIP_VAR *vubvar, SCIP_Real vubcoef, SCIP_Real vubconstant, SCIP_Bool *infeasible, int *nbdchgs)
Definition: scip_var.c:6720
public methods for SCIP variables
SCIP_RETCODE SCIPvarChgBranchDirection(SCIP_VAR *var, SCIP_BRANCHDIR branchdirection)
Definition: var.c:11808
SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
Definition: var.c:17727
SCIP_Bool branch_forceall
Definition: struct_set.h:205
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
SCIP_RETCODE SCIPvarRemoveCliquesImplicsVbs(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_CLIQUETABLE *cliquetable, SCIP_SET *set, SCIP_Bool irrelevantvar, SCIP_Bool onlyredundant, SCIP_Bool removefromvar)
Definition: var.c:1610
SCIP_RETCODE SCIPchgVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:5032
#define SCIPdebugMsg
Definition: scip_message.h:78
SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition: scip_var.c:1480
SCIP_Longint SCIPcolGetStrongbranchLPAge(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4739
SCIP_RETCODE SCIPgetVarStrongbranchInt(SCIP *scip, SCIP_VAR *var, int itlim, SCIP_Bool idempotent, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *downconflict, SCIP_Bool *upconflict, SCIP_Bool *lperror)
Definition: scip_var.c:3662
internal methods for LP management
int SCIPvarGetNCliques(SCIP_VAR *var, SCIP_Bool varfixing)
Definition: var.c:18253
SCIP_PROB * origprob
Definition: struct_scip.h:80
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
SCIP_RETCODE SCIPparseVarsLinearsum(SCIP *scip, const char *str, SCIP_VAR **vars, SCIP_Real *vals, int *nvars, int varssize, int *requiredsize, char **endptr, SCIP_Bool *success)
Definition: scip_var.c:704
SCIP_RETCODE SCIPgetVarClosestVlb(SCIP *scip, SCIP_VAR *var, SCIP_SOL *sol, SCIP_Real *closestvlb, int *closestvlbidx)
Definition: scip_var.c:6609
SCIP_VAR ** vars
Definition: struct_var.h:195
SCIP_Real SCIPcomputeVarUbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6484
internal methods for branching and inference history
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPcomputeVarLbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6505
SCIP_Bool SCIPisStrongbranchDownFirst(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:2655
SCIP_RETCODE SCIPtransformVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition: scip_var.c:1389
public methods for numerical tolerances
SCIP_Bool reopt_enable
Definition: struct_set.h:513
SCIP_Real SCIPgetVarPseudocostScore(SCIP *scip, SCIP_VAR *var, SCIP_Real solval)
Definition: scip_var.c:9103
SCIP_RETCODE SCIPscaleVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real scale)
Definition: scip_var.c:7921
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
SCIP_VAR * var
Definition: struct_var.h:187
#define SCIP_DECL_VARDELTRANS(x)
Definition: type_var.h:164
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6309
public methods for querying solving statistics
SCIP_HISTORY * glbhistorycrun
Definition: struct_stat.h:182
int SCIPcliquetableGetNCliquesCreated(SCIP_CLIQUETABLE *cliquetable)
Definition: implics.c:3516
SCIP_RETCODE SCIPtryStrongbranchLPSol(SCIP *scip, SCIP_Bool *foundsol, SCIP_Bool *cutoff)
Definition: scip_var.c:4079
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3373
SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
Definition: scip_var.c:4259
SCIP_Real SCIPvarGetVSIDSCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:15918
SCIP_RETCODE SCIPupdateVarPseudocost(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
Definition: scip_var.c:8780
public methods for the branch-and-bound tree
SCIP_Real SCIPgetVarBdAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2264
enum SCIP_BranchDir SCIP_BRANCHDIR
Definition: type_history.h:48
SCIP_Bool SCIPisLPRelax(SCIP *scip)
Definition: scip_lp.c:225
SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
Definition: scip_prob.c:2685
SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:8176
SCIP_RETCODE SCIPaddClique(SCIP *scip, SCIP_VAR **vars, SCIP_Bool *values, int nvars, SCIP_Bool isequation, SCIP_Bool *infeasible, int *nbdchgs)
Definition: scip_var.c:6921
SCIP_RETCODE SCIPvarChgLbLocal(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_Real newbound)
Definition: var.c:7960
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17911
SCIP_VAR * SCIPvarGetProbvar(SCIP_VAR *var)
Definition: var.c:12208
int SCIPcliquetableGetNCliques(SCIP_CLIQUETABLE *cliquetable)
Definition: implics.c:3506
SCIP_CLOCK * strongpropclock
Definition: struct_stat.h:179
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:105
SCIP_RETCODE SCIPmultiaggregateVar(SCIP *scip, SCIP_VAR *var, int naggvars, SCIP_VAR **aggvars, SCIP_Real *scalars, SCIP_Real constant, SCIP_Bool *infeasible, SCIP_Bool *aggregated)
Definition: scip_var.c:8535
SCIP_MEM * mem
Definition: struct_scip.h:71
public methods for managing constraints
SCIP_Bool misc_allowstrongdualreds
Definition: struct_set.h:408
SCIP_Real SCIPvarGetImplRedcost(SCIP_VAR *var, SCIP_SET *set, SCIP_Bool varfixing, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp)
Definition: var.c:13458
SCIP_Bool SCIPtreeProbing(SCIP_TREE *tree)
Definition: tree.c:8286
SCIP_RETCODE SCIPparseVarsList(SCIP *scip, const char *str, SCIP_VAR **vars, int *nvars, int varssize, int *requiredsize, char **endptr, char delimiter, SCIP_Bool *success)
Definition: scip_var.c:610
SCIP_Real lb
Definition: struct_lp.h:138
enum SCIP_Confidencelevel SCIP_CONFIDENCELEVEL
Definition: type_misc.h:53
SCIP_RETCODE SCIPvarChgBranchPriority(SCIP_VAR *var, int branchpriority)
Definition: var.c:11677
SCIP_Real SCIPvarGetPseudocost(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real solvaldelta)
Definition: var.c:14467
SCIP_RETCODE SCIPprobRemoveVarName(SCIP_PROB *prob, SCIP_VAR *var)
Definition: prob.c:922
SCIP_AGGREGATE aggregate
Definition: struct_var.h:231
SCIP_RETCODE SCIPmarkDoNotAggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8682
SCIP_Real SCIPsolGetObj(SCIP_SOL *sol, SCIP_SET *set, SCIP_PROB *transprob, SCIP_PROB *origprob)
Definition: sol.c:1571
SCIP_Real sbdown
Definition: struct_lp.h:153
SCIP_RETCODE SCIPvarChgUbLazy(SCIP_VAR *var, SCIP_SET *set, SCIP_Real lazyub)
Definition: var.c:7482
SCIP_Real SCIPgetVarPseudocostVariance(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun)
Definition: scip_var.c:8976
enum SCIP_LockType SCIP_LOCKTYPE
Definition: type_var.h:100
SCIP_RETCODE SCIPgetBinvarRepresentatives(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **repvars, SCIP_Bool *negated)
Definition: scip_var.c:1644
SCIP_Bool SCIPvarDoNotAggr(SCIP_VAR *var)
Definition: var.c:5838
internal methods for storing and manipulating the main problem
#define SCIPerrorMessage
Definition: pub_message.h:64
SCIP_Bool SCIPboundchgIsRedundant(SCIP_BOUNDCHG *boundchg)
Definition: var.c:17179
SCIP_EVENTFILTER * eventfilter
Definition: struct_scip.h:88
SCIP_Bool SCIPlpIsDualReliable(SCIP_LP *lp)
Definition: lp.c:17827
SCIP_Bool SCIPdoNotAggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8585
SCIP_Bool SCIPvarPscostThresholdProbabilityTest(SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var, SCIP_Real frac, SCIP_Real threshold, SCIP_BRANCHDIR dir, SCIP_CONFIDENCELEVEL clevel)
Definition: var.c:14917
SCIP_RETCODE SCIPchgVarLbLazy(SCIP *scip, SCIP_VAR *var, SCIP_Real lazylb)
Definition: scip_var.c:5123
SCIP_Longint lpcount
Definition: struct_stat.h:190
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Longint nbestsolsfound
Definition: struct_primal.h:51
SCIP_Bool SCIPdoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8598
SCIP_RETCODE SCIPpropagateProbing(SCIP *scip, int maxproprounds, SCIP_Bool *cutoff, SCIP_Longint *ndomredsfound)
Definition: scip_probing.c:580
SCIP_RETCODE SCIPvarChgObj(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_Real newobj)
Definition: var.c:6254
SCIP_Bool SCIPrelaxationIsSolZero(SCIP_RELAXATION *relaxation)
Definition: relax.c:785
SCIP_RETCODE SCIPgetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip_sol.c:1398
SCIP_RETCODE SCIPinferVarFixCons(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5432
SCIP_RETCODE SCIPinitVarBranchStats(SCIP *scip, SCIP_VAR *var, SCIP_Real downpscost, SCIP_Real uppscost, SCIP_Real downvsids, SCIP_Real upvsids, SCIP_Real downconflen, SCIP_Real upconflen, SCIP_Real downinfer, SCIP_Real upinfer, SCIP_Real downcutoff, SCIP_Real upcutoff)
Definition: scip_var.c:9537
SCIP_RETCODE SCIPvarRelease(SCIP_VAR **var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: var.c:2873
SCIP_RETCODE SCIPgetProbvarSum(SCIP *scip, SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: scip_var.c:1794
SCIP_RETCODE SCIPaddVarImplication(SCIP *scip, SCIP_VAR *var, SCIP_Bool varfixing, SCIP_VAR *implvar, SCIP_BOUNDTYPE impltype, SCIP_Real implbound, SCIP_Bool *infeasible, int *nbdchgs)
Definition: scip_var.c:6780
SCIP_RETCODE SCIPcheckStage(SCIP *scip, const char *method, SCIP_Bool init, SCIP_Bool problem, SCIP_Bool transforming, SCIP_Bool transformed, SCIP_Bool initpresolve, SCIP_Bool presolving, SCIP_Bool exitpresolve, SCIP_Bool presolved, SCIP_Bool initsolve, SCIP_Bool solving, SCIP_Bool solved, SCIP_Bool exitsolve, SCIP_Bool freetrans, SCIP_Bool freescip)
Definition: debug.c:2208
unsigned int sbupvalid
Definition: struct_lp.h:190
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:57
SCIP_Real SCIPvarGetPseudocostCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real solvaldelta)
Definition: var.c:14516
void SCIPstrCopySection(const char *str, char startchar, char endchar, char *token, int size, char **endptr)
Definition: misc.c:10919
SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:4437
SCIP_RETCODE SCIPvarAddLocks(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LOCKTYPE locktype, int addnlocksdown, int addnlocksup)
Definition: var.c:3168
SCIP_LPSOLSTAT lastsblpsolstats[2]
Definition: struct_stat.h:188
SCIP_CONFLICTSTORE * conflictstore
Definition: struct_scip.h:104
SCIP_RETCODE SCIPvarGetTransformed(SCIP_VAR *origvar, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR **transvar)
Definition: var.c:3549
SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4766
SCIP_Real SCIPcalculatePscostConfidenceBound(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun, SCIP_CONFIDENCELEVEL clevel)
Definition: scip_var.c:8998
SCIP_OBJSENSE objsense
Definition: struct_prob.h:86
SCIP_RETCODE SCIPmarkDoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8715
char branch_firstsbchild
Definition: struct_set.h:195
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17242
SCIP_VAR * transvar
Definition: struct_var.h:179
SCIP_REOPT * reopt
Definition: struct_scip.h:85
SCIP_RETCODE SCIPsetRelaxSolVal(SCIP *scip, SCIP_RELAX *relax, SCIP_VAR *var, SCIP_Real val)
Definition: scip_var.c:2414
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:3058
SCIP_Real SCIPsetFeasCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6791
SCIP_RETCODE SCIPtightenVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6228
SCIP_DOMCHG * SCIPnodeGetDomchg(SCIP_NODE *node)
Definition: tree.c:7539
SCIP_Real cutoffbound
Definition: struct_lp.h:284
SCIP_Longint nsbdivinglpiterations
Definition: struct_stat.h:76
#define NULL
Definition: lpi_spx1.cpp:164
void SCIPvarGetClosestVub(SCIP_VAR *var, SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real *closestvub, int *closestvubidx)
Definition: var.c:14188
SCIP_NEGATE negate
Definition: struct_var.h:233
SCIP_Real SCIPgetVarConflictlengthScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9303
SCIP_RETCODE SCIPvarSetRelaxSol(SCIP_VAR *var, SCIP_SET *set, SCIP_RELAXATION *relaxation, SCIP_Real solval, SCIP_Bool updateobj)
Definition: var.c:13852
data structures for branch and bound tree
SCIP_HISTORY * glbhistory
Definition: struct_stat.h:181
SCIP_Real SCIPboundchgGetNewbound(SCIP_BOUNDCHG *boundchg)
Definition: var.c:17139
#define REALABS(x)
Definition: def.h:210
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
Definition: var.c:18275
SCIP_Real SCIPgetVarAvgInferenceScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9504
SCIP_RETCODE SCIPvarAddVlb(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_CLIQUETABLE *cliquetable, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_VAR *vlbvar, SCIP_Real vlbcoef, SCIP_Real vlbconstant, SCIP_Bool transitive, SCIP_Bool *infeasible, int *nbdchgs)
Definition: var.c:9991
internal methods for global SCIP settings
SCIP_Real SCIPvarCalcPscostConfidenceBound(SCIP_VAR *var, SCIP_SET *set, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun, SCIP_CONFIDENCELEVEL clevel)
Definition: var.c:14736
#define SCIP_CALL(x)
Definition: def.h:394
SCIP_RETCODE SCIPprobAddVarName(SCIP_PROB *prob, SCIP_VAR *var)
Definition: prob.c:906
SCIP main data structure.
SCIP_Bool SCIPsignificantVarPscostDifference(SCIP *scip, SCIP_VAR *varx, SCIP_Real fracx, SCIP_VAR *vary, SCIP_Real fracy, SCIP_BRANCHDIR dir, SCIP_CONFIDENCELEVEL clevel, SCIP_Bool onesided)
Definition: scip_var.c:9029
SCIP_RETCODE SCIPsolveProbingLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition: scip_probing.c:819
SCIP_Real SCIPcomputeVarUbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6526
SCIP_Longint nsbbestsolsfound
Definition: struct_stat.h:108
SCIP_RETCODE SCIPinferVarUbProp(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_PROP *inferprop, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6010
SCIP_RETCODE SCIPvarIncNBranchings(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_BRANCHDIR dir, SCIP_Real value, int depth)
Definition: var.c:15437
SCIP_RETCODE SCIPgetProbvarLinearSum(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize, SCIP_Bool mergemultiples)
Definition: scip_var.c:1738
SCIP_Real SCIPgetVarAvgConflictlength(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9365
SCIP_RETCODE SCIPremoveVarFromGlobalStructures(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:7859
SCIP_RETCODE SCIPgetVarClosestVub(SCIP *scip, SCIP_VAR *var, SCIP_SOL *sol, SCIP_Real *closestvub, int *closestvubidx)
Definition: scip_var.c:6632
SCIP_Longint SCIPgetVarStrongbranchLPAge(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:4194
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPsetIsLbBetter(SCIP_SET *set, SCIP_Real newlb, SCIP_Real oldlb, SCIP_Real oldub)
Definition: set.c:7038
SCIP_Real SCIPvarGetPseudocostCount(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:14563
#define SCIPstatAdd(stat, set, field, val)
Definition: stat.h:280
internal methods for relaxators
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6237
SCIP_RETCODE SCIPvarChgUbLocal(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_Real newbound)
Definition: var.c:8087
SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13119
SCIP_RETCODE SCIPvarPrint(SCIP_VAR *var, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: var.c:3007
SCIP_Real SCIPgetVarPseudocostCount(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:8922
SCIP_RETCODE SCIPlpStartStrongbranch(SCIP_LP *lp)
Definition: lp.c:4180
SCIP_Real SCIPgetVarPseudocostCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:8896
SCIP_CLIQUETABLE * cliquetable
Definition: struct_scip.h:97
SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2386
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:4513
internal methods for problem variables
SCIP_RETCODE SCIPvarChgBranchFactor(SCIP_VAR *var, SCIP_SET *set, SCIP_Real branchfactor)
Definition: var.c:11550
SCIP_RETCODE SCIPvarTryAggregateVars(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_CLIQUETABLE *cliquetable, SCIP_BRANCHCAND *branchcand, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_VAR *varx, SCIP_VAR *vary, SCIP_Real scalarx, SCIP_Real scalary, SCIP_Real rhs, SCIP_Bool *infeasible, SCIP_Bool *aggregated)
Definition: var.c:5282
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
#define SCIP_UNKNOWN
Definition: def.h:207
SCIP_RETCODE SCIPstartStrongbranch(SCIP *scip, SCIP_Bool enablepropagation)
Definition: scip_var.c:2686
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_clp.cpp:2766
public data structures and miscellaneous methods
unsigned int vartype
Definition: struct_var.h:280
SCIP_Bool SCIPcliquetableNeedsComponentUpdate(SCIP_CLIQUETABLE *cliquetable)
Definition: implics.c:3554
SCIP_RETCODE SCIPvarIncCutoffSum(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_BRANCHDIR dir, SCIP_Real value, SCIP_Real weight)
Definition: var.c:15605
void SCIPrelaxationSetSolRelax(SCIP_RELAXATION *relaxation, SCIP_RELAX *relax)
Definition: relax.c:880
#define SCIP_Bool
Definition: def.h:93
SCIP_RETCODE SCIPinferVarFixProp(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_PROP *inferprop, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5826
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip_lp.c:168
void SCIPvarCapture(SCIP_VAR *var)
Definition: var.c:2848
SCIP_CLOCK * sbsoltime
Definition: struct_stat.h:175
SCIP_Real ub
Definition: struct_var.h:171
int SCIPgetNCliquesCreated(SCIP *scip)
Definition: scip_var.c:7602
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2609
SCIP_RETCODE SCIPtreeStartProbing(SCIP_TREE *tree, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp, SCIP_RELAXATION *relaxation, SCIP_PROB *transprob, SCIP_Bool strongbranching)
Definition: tree.c:6435
SCIP_RETCODE SCIProundSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
Definition: scip_sol.c:2455
#define MAXNCLIQUEVARSCOMP
Definition: scip_var.c:7120
static SCIP_RETCODE analyzeStrongbranch(SCIP *scip, SCIP_VAR *var, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *downconflict, SCIP_Bool *upconflict)
Definition: scip_var.c:2839
int SCIPvarGetBranchPriority(SCIP_VAR *var)
Definition: var.c:18073
SCIP_RETCODE SCIPvarFix(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition: var.c:3750
SCIP_MULTAGGR multaggr
Definition: struct_var.h:232
SCIP_RETCODE SCIPgetVarStrongbranchWithPropagation(SCIP *scip, SCIP_VAR *var, SCIP_Real solval, SCIP_Real lpobjval, int itlim, int maxproprounds, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Longint *ndomredsdown, SCIP_Longint *ndomredsup, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *downconflict, SCIP_Bool *upconflict, SCIP_Bool *lperror, SCIP_Real *newlbs, SCIP_Real *newubs)
Definition: scip_var.c:3352
union SCIP_Var::@21 data
SCIP_RETCODE SCIPmarkRelaxSolValid(SCIP *scip, SCIP_RELAX *relax, SCIP_Bool includeslp)
Definition: scip_var.c:2557
SCIP_Bool branch_roundsbsol
Definition: struct_set.h:208
int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition: var.c:3430
SCIP_RETCODE SCIPconflictAnalyzeStrongbranch(SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_COL *col, SCIP_Bool *downconflict, SCIP_Bool *upconflict)
Definition: conflict.c:9015
SCIP_RETCODE SCIPcliquetableComputeCliqueComponents(SCIP_CLIQUETABLE *cliquetable, SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_VAR **vars, int nbinvars, int nintvars, int nimplvars)
Definition: implics.c:3131
#define MAX(x, y)
Definition: tclique_def.h:92
SCIP_Bool SCIPstrToRealValue(const char *str, SCIP_Real *value, char **endptr)
Definition: misc.c:10889
SCIP_RETCODE SCIPtrySolFree(SCIP *scip, SCIP_SOL **sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition: scip_sol.c:3193
SCIP_RETCODE SCIPcalcCliquePartition(SCIP *const scip, SCIP_VAR **const vars, int const nvars, int *const cliquepartition, int *const ncliques)
Definition: scip_var.c:7256
SCIP_VAR * SCIPboundchgGetVar(SCIP_BOUNDCHG *boundchg)
Definition: var.c:17149
methods for debugging
SCIP_Bool * SCIPcliqueGetValues(SCIP_CLIQUE *clique)
Definition: implics.c:3392
SCIP_BOUNDCHG * SCIPdomchgGetBoundchg(SCIP_DOMCHG *domchg, int pos)
Definition: var.c:17197
public methods for LP management
void SCIPcolSetStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Real lpobjval, SCIP_Real primsol, SCIP_Real sbdown, SCIP_Real sbup, SCIP_Bool sbdownvalid, SCIP_Bool sbupvalid, SCIP_Longint iter, int itlim)
Definition: lp.c:4210
datastructures for block memory pools and memory buffers
SCIP_RETCODE SCIPwriteCliqueGraph(SCIP *scip, const char *fname, SCIP_Bool writenodeweights)
Definition: scip_var.c:7710
SCIP_Real SCIPvarGetMultaggrUbGlobal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8622
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip_sol.c:985
SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
Definition: prob.c:2309
void SCIPenableVarHistory(SCIP *scip)
Definition: scip_var.c:8741
SCIP_Real SCIPcomputeVarLbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6463
SCIP_Real SCIPgetVarAvgInferenceCutoffScoreCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real cutoffweight)
Definition: scip_var.c:9834
SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18493
SCIP_RETCODE SCIPgetVarsStrongbranchesInt(SCIP *scip, SCIP_VAR **vars, int nvars, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *downconflict, SCIP_Bool *upconflict, SCIP_Bool *lperror)
Definition: scip_var.c:3884
SCIP_RETCODE SCIPcreateVar(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
Definition: scip_var.c:114
SCIP_RETCODE SCIPvarFlattenAggregationGraph(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: var.c:4414
SCIP_Real SCIPvarGetAvgInferencesCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:16114
SCIP_Bool SCIPtreeHasCurrentNodeLP(SCIP_TREE *tree)
Definition: tree.c:8421
SCIP_Bool SCIPallowWeakDualReds(SCIP *scip)
Definition: scip_var.c:8656
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition: scip_var.c:8276
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:136
SCIP_RETCODE SCIPchgVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition: scip_var.c:7980
SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:4351
int SCIPconflictGetNConflicts(SCIP_CONFLICT *conflict)
Definition: conflict.c:3781
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:17612
void SCIPgmlWriteNodeWeight(FILE *file, unsigned int id, const char *label, const char *nodetype, const char *fillcolor, const char *bordercolor, SCIP_Real weight)
Definition: misc.c:544
SCIP_Real SCIPvarGetRelaxSol(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:13913
datastructures for problem statistics
int nconflicthdlrs
Definition: struct_set.h:122
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Real ub
Definition: struct_lp.h:139
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6635
SCIP_RETCODE SCIPcliquetableAdd(SCIP_CLIQUETABLE *cliquetable, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_VAR **vars, SCIP_Bool *values, int nvars, SCIP_Bool isequation, SCIP_Bool *infeasible, int *nbdchgs)
Definition: implics.c:2376
SCIP_RETCODE SCIPvarAddObj(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_Real addobj)
Definition: var.c:6329
SCIP_RETCODE SCIPinferVarLbCons(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5501
SCIP_RETCODE SCIPvarIncNActiveConflicts(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_BRANCHDIR dir, SCIP_Real value, SCIP_Real length)
Definition: var.c:15177
SCIP_RETCODE SCIPgetVarStrongbranchFrac(SCIP *scip, SCIP_VAR *var, int itlim, SCIP_Bool idempotent, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *downconflict, SCIP_Bool *upconflict, SCIP_Bool *lperror)
Definition: scip_var.c:2919
void SCIPrelaxationSetSolObj(SCIP_RELAXATION *relaxation, SCIP_Real obj)
Definition: relax.c:828
#define SCIP_MAXTREEDEPTH
Definition: def.h:330
SCIP * scip
Definition: struct_var.h:288
SCIP_BDCHGINFO * SCIPvarGetLbchgInfo(SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: var.c:16400
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip_probing.c:97
public methods for the LP relaxation, rows and columns
SCIP_BDCHGINFO * SCIPvarGetUbchgInfo(SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: var.c:16456
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:1992
SCIP_Real SCIPgetVarMultaggrLbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6576
SCIP_RETCODE SCIPcolGetStrongbranches(SCIP_COL **cols, int ncols, SCIP_Bool integral, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *lperror)
Definition: lp.c:4484
SCIP_RETCODE SCIPwriteVarsLinearsum(SCIP *scip, FILE *file, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Bool type)
Definition: scip_var.c:343
#define SCIP_DECL_VARDELORIG(x)
Definition: type_var.h:131
SCIP_Real SCIPlpGetLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13158
datastructures for storing and manipulating the main problem
SCIP_Bool SCIPinDive(SCIP *scip)
Definition: scip_lp.c:2775
void SCIPrelaxationSetSolZero(SCIP_RELAXATION *relaxation, SCIP_Bool iszero)
Definition: relax.c:774
SCIP_Real SCIPsetFeasFloor(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6780
SCIP_CLIQUE ** SCIPgetCliques(SCIP *scip)
Definition: scip_var.c:7629
SCIP_Real SCIPgetVarAvgConflictlengthCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9391
SCIP_RETCODE SCIPaddVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real addfactor)
Definition: scip_var.c:7949
SCIP_LPSOLSTAT SCIPgetLastStrongbranchLPSolStat(SCIP *scip, SCIP_BRANCHDIR branchdir)
Definition: scip_var.c:3988
SCIP_Bool misc_exactsolve
Definition: struct_set.h:393
SCIP_RETCODE SCIPwriteVarsList(SCIP *scip, FILE *file, SCIP_VAR **vars, int nvars, SCIP_Bool type, char delimiter)
Definition: scip_var.c:292
#define SCIP_VARTYPE_IMPLINT_CHAR
Definition: def.h:159
SCIP_RETCODE SCIPsetVarStrongbranchData(SCIP *scip, SCIP_VAR *var, SCIP_Real lpobjval, SCIP_Real primsol, SCIP_Real down, SCIP_Real up, SCIP_Bool downvalid, SCIP_Bool upvalid, SCIP_Longint iter, int itlim)
Definition: scip_var.c:4044
general public methods
int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition: var.c:3417
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition: scip_lp.c:247
BMS_BLKMEM * probmem
Definition: struct_mem.h:49
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPgetVarImplRedcost(SCIP *scip, SCIP_VAR *var, SCIP_Bool varfixing)
Definition: scip_var.c:1909
public methods for solutions
internal methods for conflict analysis
void SCIPfreeParseVarsPolynomialData(SCIP *scip, SCIP_VAR ****monomialvars, SCIP_Real ***monomialexps, SCIP_Real **monomialcoefs, int **monomialnvars, int nmonomials)
Definition: scip_var.c:1158
static const SCIP_Real scalars[]
Definition: lp.c:5743
SCIP_RETCODE SCIPvarMultiaggregate(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_CLIQUETABLE *cliquetable, SCIP_BRANCHCAND *branchcand, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, int naggvars, SCIP_VAR **aggvars, SCIP_Real *scalars, SCIP_Real constant, SCIP_Bool *infeasible, SCIP_Bool *aggregated)
Definition: var.c:5436
SCIP_RETCODE SCIPinferVarUbCons(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5615
SCIP_RETCODE SCIPgetVarsStrongbranchesFrac(SCIP *scip, SCIP_VAR **vars, int nvars, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *downconflict, SCIP_Bool *upconflict, SCIP_Bool *lperror)
Definition: scip_var.c:3773
internal methods for main solving loop and node processing
SCIP_RETCODE SCIPgetVarSols(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip_var.c:2327
int SCIPdomchgGetNBoundchgs(SCIP_DOMCHG *domchg)
Definition: var.c:17189
SCIP_RETCODE SCIPnodeAddBoundchg(SCIP_NODE *node, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_VAR *var, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype, SCIP_Bool probingchange)
Definition: tree.c:2087
#define SCIP_VARTYPE_CONTINUOUS_CHAR
Definition: def.h:160
public methods for the probing mode
SCIP_RETCODE SCIPvarGetActiveRepresentatives(SCIP_SET *set, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize, SCIP_Bool mergemultiples)
Definition: var.c:3919
SCIP_NODE * SCIPtreeGetCurrentNode(SCIP_TREE *tree)
Definition: tree.c:8387
SCIP_RETCODE SCIPendStrongbranch(SCIP *scip)
Definition: scip_var.c:2744
SCIP_Bool SCIPisRelaxSolValid(SCIP *scip)
Definition: scip_var.c:2537
SCIP_Bool SCIPvarSignificantPscostDifference(SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *varx, SCIP_Real fracx, SCIP_VAR *vary, SCIP_Real fracy, SCIP_BRANCHDIR dir, SCIP_CONFIDENCELEVEL clevel, SCIP_Bool onesided)
Definition: var.c:14851
SCIP_RETCODE SCIPvarMarkDoNotAggr(SCIP_VAR *var)
Definition: var.c:6096
SCIP_Bool SCIPallowDualReds(SCIP *scip)
Definition: scip_var.c:8614
SCIP_SET * set
Definition: struct_scip.h:72
public methods for message output
int SCIPgetNCliques(SCIP *scip)
Definition: scip_var.c:7575
data structures for LP management
SCIP_RETCODE SCIPaddVarBranchPriority(SCIP *scip, SCIP_VAR *var, int addpriority)
Definition: scip_var.c:8054
SCIP_Real * scalars
Definition: struct_var.h:194
datastructures for problem variables
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:1947
int SCIPcolGetNStrongbranchs(SCIP_COL *col)
Definition: lp.c:17183
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17361
SCIP_RETCODE SCIPcalcNegatedCliquePartition(SCIP *const scip, SCIP_VAR **const vars, int const nvars, int *const cliquepartition, int *const ncliques)
Definition: scip_var.c:7475
SCIP_MESSAGEHDLR * messagehdlr
Definition: struct_scip.h:75
SCIP_RETCODE SCIPaggregateVars(SCIP *scip, SCIP_VAR *varx, SCIP_VAR *vary, SCIP_Real scalarx, SCIP_Real scalary, SCIP_Real rhs, SCIP_Bool *infeasible, SCIP_Bool *redundant, SCIP_Bool *aggregated)
Definition: scip_var.c:8401
SCIP_NODETYPE SCIPnodeGetType(SCIP_NODE *node)
Definition: tree.c:7434
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1214
#define SCIP_Real
Definition: def.h:186
internal methods for problem statistics
SCIP_RETCODE SCIPvarsGetProbvarBinary(SCIP_VAR ***vars, SCIP_Bool **negatedarr, int nvars)
Definition: var.c:12268
SCIP_RETCODE SCIPchgVarBranchDirection(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR branchdirection)
Definition: scip_var.c:8085
SCIP_Bool SCIPhaveVarsCommonClique(SCIP *scip, SCIP_VAR *var1, SCIP_Bool value1, SCIP_VAR *var2, SCIP_Bool value2, SCIP_Bool regardimplics)
Definition: scip_var.c:7659
datastructures for collecting primal CIP solutions and primal informations
public methods for message handling
SCIP_Bool SCIPdoNotAggr(SCIP *scip)
Definition: scip_var.c:8565
SCIP_RETCODE SCIPtransformVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip_var.c:1349
SCIP_Real SCIPvarGetVSIDS(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:18366
#define SCIP_INVALID
Definition: def.h:206
SCIP_RETCODE SCIPvarParseTransformed(SCIP_VAR **var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, const char *str, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARCOPY((*varcopy)), SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_VARDATA *vardata, char **endptr, SCIP_Bool *success)
Definition: var.c:2561
SCIP_Real primsol
Definition: struct_lp.h:148
#define SCIP_Longint
Definition: def.h:171
SCIP_Bool SCIPallColsInLP(SCIP *scip)
Definition: scip_lp.c:649
SCIP_Real SCIPvarGetAvgCutoffs(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:16255
SCIP_Real lb
Definition: struct_var.h:170
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6679
SCIP_Longint nsbsolsfound
Definition: struct_stat.h:104
SCIP_TREE * tree
Definition: struct_scip.h:95
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17407
#define SCIP_VARTYPE_BINARY_CHAR
Definition: def.h:157
SCIP_Real SCIPvarGetMultaggrUbLocal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8490
SCIP_RETCODE SCIPvarChgName(SCIP_VAR *var, BMS_BLKMEM *blkmem, const char *name)
Definition: var.c:2914
SCIP_RELAXATION * relaxation
Definition: struct_scip.h:93
void SCIPsolSetStrongbranching(SCIP_SOL *sol)
Definition: sol.c:2743
static SCIP_RETCODE performStrongbranchWithPropagation(SCIP *scip, SCIP_VAR *var, SCIP_Bool down, SCIP_Bool firstchild, SCIP_Bool propagate, SCIP_Real newbound, int itlim, int maxproprounds, SCIP_Real *value, SCIP_Bool *valid, SCIP_Longint *ndomreductions, SCIP_Bool *conflict, SCIP_Bool *lperror, SCIP_VAR **vars, int nvars, SCIP_Real *newlbs, SCIP_Real *newubs, SCIP_Bool *foundsol, SCIP_Bool *cutoff)
Definition: scip_var.c:3026
SCIP_RETCODE SCIPparseVarsPolynomial(SCIP *scip, const char *str, SCIP_VAR ****monomialvars, SCIP_Real ***monomialexps, SCIP_Real **monomialcoefs, int **monomialnvars, int *nmonomials, char **endptr, SCIP_Bool *success)
Definition: scip_var.c:813
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPdoNotMultaggr(SCIP *scip)
Definition: scip_var.c:8575
SCIP_DOM glbdom
Definition: struct_var.h:225
SCIP_Real SCIPgetVarConflictScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9272
SCIP_Real SCIPhistoryGetAvgInferences(SCIP_HISTORY *history, SCIP_BRANCHDIR dir)
Definition: history.c:658
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
enum SCIP_Vartype SCIP_VARTYPE
Definition: type_var.h:73
SCIP_Bool SCIPconsIsLockedTypePos(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
Definition: cons.c:8459
SCIP_Real SCIPgetVarSol(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:2307
SCIP_VAR * negatedvar
Definition: struct_var.h:242
SCIP_Real SCIPgetColFarkasCoef(SCIP *scip, SCIP_COL *col)
Definition: scip_lp.c:1180
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17967
SCIP_Real SCIPgetVarMultaggrLbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6546
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip_mem.h:111
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
Definition: scip_probing.c:165
int SCIPcliqueGetNVars(SCIP_CLIQUE *clique)
Definition: implics.c:3370
void SCIPgmlWriteOpening(FILE *file, SCIP_Bool directed)
Definition: misc.c:682
void SCIPvarAdjustUb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *ub)
Definition: var.c:6524
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPsetIsUbBetter(SCIP_SET *set, SCIP_Real newub, SCIP_Real oldlb, SCIP_Real oldub)
Definition: set.c:7059
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition: var.c:17384
SCIP_RETCODE SCIPtightenVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6348
static SCIP_RETCODE tightenBounds(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:8102
SCIP_RETCODE SCIPinitVarValueBranchStats(SCIP *scip, SCIP_VAR *var, SCIP_Real value, SCIP_Real downvsids, SCIP_Real upvsids, SCIP_Real downconflen, SCIP_Real upconflen, SCIP_Real downinfer, SCIP_Real upinfer, SCIP_Real downcutoff, SCIP_Real upcutoff)
Definition: scip_var.c:9608
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:132
SCIP_RETCODE SCIPupdateVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition: scip_var.c:8021
void SCIPcolInvalidateStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4264
SCIP_RETCODE SCIPvarGetProbvarSum(SCIP_VAR **var, SCIP_SET *set, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12637
SCIP_NODE * root
Definition: struct_tree.h:186
int SCIPhashmapGetImageInt(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3231
#define SCIP_CALL_ABORT(x)
Definition: def.h:373
SCIP_Real SCIPvarGetPseudoSol(SCIP_VAR *var)
Definition: var.c:18353
SCIP_RETCODE SCIPcleanupCliques(SCIP *scip, SCIP_Bool *infeasible)
Definition: scip_var.c:7532
SCIP_Real SCIPgetVarFarkasCoef(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1954
SCIP_ORIGINAL original
Definition: struct_var.h:229
SCIP_LP * lp
Definition: struct_scip.h:91
#define SCIPABORT()
Definition: def.h:366
SCIP_RETCODE SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
Definition: scip_var.c:230
public methods for global and local (sub)problems
int SCIPgetVarNStrongbranchs(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:4226
SCIP_RETCODE SCIPgetActiveVars(SCIP *scip, SCIP_VAR **vars, int *nvars, int varssize, int *requiredsize)
Definition: scip_var.c:1830
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:17433
SCIP_RETCODE SCIPchgVarUbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_probing.c:345
SCIP_Real SCIPvarGetMultaggrLbLocal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8424
void SCIPdisableVarHistory(SCIP *scip)
Definition: scip_var.c:8760
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1361
SCIP_Real SCIPgetVarAvgInferenceScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9473
datastructures for global SCIP settings
SCIP_RETCODE SCIPlpEndStrongbranch(SCIP_LP *lp)
Definition: lp.c:4195
SCIP_Bool SCIPallowStrongDualReds(SCIP *scip)
Definition: scip_var.c:8629
SCIP_RETCODE SCIPinferBinvarCons(SCIP *scip, SCIP_VAR *var, SCIP_Bool fixedval, SCIP_CONS *infercons, int inferinfo, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5723
SCIP_RETCODE SCIPparseVar(SCIP *scip, SCIP_VAR **var, const char *str, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARCOPY((*varcopy)), SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_VARDATA *vardata, char **endptr, SCIP_Bool *success)
Definition: scip_var.c:474
SCIP_Bool SCIPcolIsInLP(SCIP_COL *col)
Definition: lp.c:17115
SCIP_RETCODE SCIPvarNegate(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR **negvar)
Definition: var.c:5907
SCIP_CLIQUE ** SCIPcliquetableGetCliques(SCIP_CLIQUETABLE *cliquetable)
Definition: implics.c:3526
SCIP_RETCODE SCIPchgVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real branchfactor)
Definition: scip_var.c:7893
SCIP_RETCODE SCIPprintVar(SCIP *scip, SCIP_VAR *var, FILE *file)
Definition: scip_var.c:9885
static SCIP_RETCODE relabelOrderConsistent(SCIP *const scip, int *labels, int const nlabels, int *nclasses)
Definition: scip_var.c:6953
SCIP_Bool SCIPallowObjProp(SCIP *scip)
Definition: scip_var.c:8642
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip_var.c:1527
SCIP_Real SCIPgetVarConflictScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9241
SCIP_RETCODE SCIPbranchcandUpdateVarBranchPriority(SCIP_BRANCHCAND *branchcand, SCIP_SET *set, SCIP_VAR *var, int branchpriority)
Definition: branch.c:1176
SCIP_Real SCIPvarGetPseudocostVariance(SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun)
Definition: var.c:14682
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17571
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:17397
SCIP_Real SCIPgetRelaxSolVal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:2603
SCIP_Real scalar
Definition: struct_var.h:185
void SCIPvarMarkDeleteGlobalStructures(SCIP_VAR *var)
Definition: var.c:17499
SCIP_RETCODE SCIPchgVarName(SCIP *scip, SCIP_VAR *var, const char *name)
Definition: scip_var.c:1299
memory allocation routines
SCIP_Real SCIPgetVarAvgCutoffScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9727