Scippy

SCIP

Solving Constraint Integer Programs

scip_var.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (c) 2002-2024 Zuse Institute Berlin (ZIB) */
7 /* */
8 /* Licensed under the Apache License, Version 2.0 (the "License"); */
9 /* you may not use this file except in compliance with the License. */
10 /* You may obtain a copy of the License at */
11 /* */
12 /* http://www.apache.org/licenses/LICENSE-2.0 */
13 /* */
14 /* Unless required by applicable law or agreed to in writing, software */
15 /* distributed under the License is distributed on an "AS IS" BASIS, */
16 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17 /* See the License for the specific language governing permissions and */
18 /* limitations under the License. */
19 /* */
20 /* You should have received a copy of the Apache-2.0 license */
21 /* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22 /* */
23 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24 
25 /**@file scip_var.c
26  * @ingroup OTHER_CFILES
27  * @brief public methods for SCIP variables
28  * @author Tobias Achterberg
29  * @author Timo Berthold
30  * @author Gerald Gamrath
31  * @author Leona Gottwald
32  * @author Stefan Heinz
33  * @author Gregor Hendel
34  * @author Thorsten Koch
35  * @author Alexander Martin
36  * @author Marc Pfetsch
37  * @author Michael Winkler
38  * @author Kati Wolter
39  *
40  * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE
41  */
42 
43 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
44 
45 #include <ctype.h>
46 #include "blockmemshell/memory.h"
47 #include "lpi/lpi.h"
48 #include "scip/branch.h"
49 #include "scip/clock.h"
50 #include "scip/conflict.h"
51 #include "scip/debug.h"
52 #include "scip/history.h"
53 #include "scip/implics.h"
54 #include "scip/lp.h"
55 #include "scip/prob.h"
56 #include "scip/pub_cons.h"
57 #include "scip/pub_implics.h"
58 #include "scip/pub_lp.h"
59 #include "scip/pub_message.h"
60 #include "scip/pub_misc.h"
61 #include "scip/pub_tree.h"
62 #include "scip/pub_var.h"
63 #include "scip/relax.h"
64 #include "scip/scip_general.h"
65 #include "scip/scip_lp.h"
66 #include "scip/scip_mem.h"
67 #include "scip/scip_message.h"
68 #include "scip/scip_numerics.h"
69 #include "scip/scip_prob.h"
70 #include "scip/scip_probing.h"
71 #include "scip/scip_sol.h"
72 #include "scip/scip_solvingstats.h"
73 #include "scip/scip_tree.h"
74 #include "scip/scip_var.h"
75 #include "scip/set.h"
76 #include "scip/sol.h"
77 #include "scip/solve.h"
78 #include "scip/stat.h"
79 #include "scip/struct_lp.h"
80 #include "scip/struct_mem.h"
81 #include "scip/struct_primal.h"
82 #include "scip/struct_prob.h"
83 #include "scip/struct_scip.h"
84 #include "scip/struct_set.h"
85 #include "scip/struct_stat.h"
86 #include "scip/struct_tree.h"
87 #include "scip/struct_var.h"
88 #include "scip/tree.h"
89 #include "scip/var.h"
90 
91 
92 /** creates and captures problem variable; if variable is of integral type, fractional bounds are automatically rounded;
93  * an integer variable with bounds zero and one is automatically converted into a binary variable;
94  *
95  * @warning When doing column generation and the original problem is a maximization problem, notice that SCIP will
96  * transform the problem into a minimization problem by multiplying the objective function by -1. Thus, the
97  * original objective function value of variables created during the solving process has to be multiplied by
98  * -1, too.
99  *
100  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
101  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
102  *
103  * @pre This method can be called if @p scip is in one of the following stages:
104  * - \ref SCIP_STAGE_PROBLEM
105  * - \ref SCIP_STAGE_TRANSFORMING
106  * - \ref SCIP_STAGE_INITPRESOLVE
107  * - \ref SCIP_STAGE_PRESOLVING
108  * - \ref SCIP_STAGE_EXITPRESOLVE
109  * - \ref SCIP_STAGE_PRESOLVED
110  * - \ref SCIP_STAGE_SOLVING
111  *
112  * @note the variable gets captured, hence at one point you have to release it using the method SCIPreleaseVar()
113  */
115  SCIP* scip, /**< SCIP data structure */
116  SCIP_VAR** var, /**< pointer to variable object */
117  const char* name, /**< name of variable, or NULL for automatic name creation */
118  SCIP_Real lb, /**< lower bound of variable */
119  SCIP_Real ub, /**< upper bound of variable */
120  SCIP_Real obj, /**< objective function value */
121  SCIP_VARTYPE vartype, /**< type of variable */
122  SCIP_Bool initial, /**< should var's column be present in the initial root LP? */
123  SCIP_Bool removable, /**< is var's column removable from the LP (due to aging or cleanup)? */
124  SCIP_DECL_VARDELORIG ((*vardelorig)), /**< frees user data of original variable, or NULL */
125  SCIP_DECL_VARTRANS ((*vartrans)), /**< creates transformed user data by transforming original user data, or NULL */
126  SCIP_DECL_VARDELTRANS ((*vardeltrans)), /**< frees user data of transformed variable, or NULL */
127  SCIP_DECL_VARCOPY ((*varcopy)), /**< copies variable data if wanted to subscip, or NULL */
128  SCIP_VARDATA* vardata /**< user data for this specific variable */
129  )
130 {
131  assert(var != NULL);
132  assert(lb <= ub);
133 
134  SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateVar", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
135 
136  /* forbid infinite objective function values */
137  if( SCIPisInfinity(scip, REALABS(obj)) )
138  {
139  SCIPerrorMessage("invalid objective function value: value is infinite\n");
140  return SCIP_INVALIDDATA;
141  }
142 
143  switch( scip->set->stage )
144  {
145  case SCIP_STAGE_PROBLEM:
146  SCIP_CALL( SCIPvarCreateOriginal(var, scip->mem->probmem, scip->set, scip->stat,
147  name, lb, ub, obj, vartype, initial, removable, vardelorig, vartrans, vardeltrans, varcopy, vardata) );
148  break;
149 
155  case SCIP_STAGE_SOLVING:
156  SCIP_CALL( SCIPvarCreateTransformed(var, scip->mem->probmem, scip->set, scip->stat,
157  name, lb, ub, obj, vartype, initial, removable, vardelorig, vartrans, vardeltrans, varcopy, vardata) );
158  break;
159 
160  default:
161  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
162  return SCIP_INVALIDCALL;
163  } /*lint !e788*/
164 
165  return SCIP_OKAY;
166 }
167 
168 /** creates and captures problem variable with optional callbacks and variable data set to NULL, which can be set
169  * afterwards using SCIPvarSetDelorigData(), SCIPvarSetTransData(),
170  * SCIPvarSetDeltransData(), SCIPvarSetCopy(), and SCIPvarSetData(); sets variable flags initial=TRUE
171  * and removable = FALSE, which can be adjusted by using SCIPvarSetInitial() and SCIPvarSetRemovable(), resp.;
172  * if variable is of integral type, fractional bounds are automatically rounded;
173  * an integer variable with bounds zero and one is automatically converted into a binary variable;
174  *
175  * @warning When doing column generation and the original problem is a maximization problem, notice that SCIP will
176  * transform the problem into a minimization problem by multiplying the objective function by -1. Thus, the
177  * original objective function value of variables created during the solving process has to be multiplied by
178  * -1, too.
179  *
180  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
181  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
182  *
183  * @pre This method can be called if @p scip is in one of the following stages:
184  * - \ref SCIP_STAGE_PROBLEM
185  * - \ref SCIP_STAGE_TRANSFORMING
186  * - \ref SCIP_STAGE_INITPRESOLVE
187  * - \ref SCIP_STAGE_PRESOLVING
188  * - \ref SCIP_STAGE_EXITPRESOLVE
189  * - \ref SCIP_STAGE_PRESOLVED
190  * - \ref SCIP_STAGE_SOLVING
191  *
192  * @note the variable gets captured, hence at one point you have to release it using the method SCIPreleaseVar()
193  */
195  SCIP* scip, /**< SCIP data structure */
196  SCIP_VAR** var, /**< pointer to variable object */
197  const char* name, /**< name of variable, or NULL for automatic name creation */
198  SCIP_Real lb, /**< lower bound of variable */
199  SCIP_Real ub, /**< upper bound of variable */
200  SCIP_Real obj, /**< objective function value */
201  SCIP_VARTYPE vartype /**< type of variable */
202  )
203 {
204  SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateVarBasic", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
205 
206  SCIP_CALL( SCIPcreateVar(scip, var, name, lb, ub, obj, vartype, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
207 
208  return SCIP_OKAY;
209 }
210 
211 /** outputs the variable name to the file stream
212  *
213  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
214  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
215  *
216  * @pre This method can be called if @p scip is in one of the following stages:
217  * - \ref SCIP_STAGE_PROBLEM
218  * - \ref SCIP_STAGE_TRANSFORMING
219  * - \ref SCIP_STAGE_TRANSFORMED
220  * - \ref SCIP_STAGE_INITPRESOLVE
221  * - \ref SCIP_STAGE_PRESOLVING
222  * - \ref SCIP_STAGE_EXITPRESOLVE
223  * - \ref SCIP_STAGE_PRESOLVED
224  * - \ref SCIP_STAGE_INITSOLVE
225  * - \ref SCIP_STAGE_SOLVING
226  * - \ref SCIP_STAGE_SOLVED
227  * - \ref SCIP_STAGE_EXITSOLVE
228  * - \ref SCIP_STAGE_FREETRANS
229  */
231  SCIP* scip, /**< SCIP data structure */
232  FILE* file, /**< output file, or NULL for stdout */
233  SCIP_VAR* var, /**< variable to output */
234  SCIP_Bool type /**< should the variable type be also posted */
235  )
236 {
237  assert(scip != NULL);
238  assert(var != NULL);
239 
240  SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarName", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
241 
242  /* print variable name */
243  if( SCIPvarIsNegated(var) )
244  {
245  SCIP_VAR* negatedvar;
246 
247  SCIP_CALL( SCIPgetNegatedVar(scip, var, &negatedvar) );
248  SCIPinfoMessage(scip, file, "<~%s>", SCIPvarGetName(negatedvar));
249  }
250  else
251  {
252  SCIPinfoMessage(scip, file, "<%s>", SCIPvarGetName(var));
253  }
254 
255  if( type )
256  {
257  /* print variable type */
258  SCIPinfoMessage(scip, file, "[%c]",
262  }
263 
264  return SCIP_OKAY;
265 }
266 
267 /** print the given list of variables to output stream separated by the given delimiter character;
268  *
269  * i. e. the variables x1, x2, ..., xn with given delimiter ',' are written as: <x1>, <x2>, ..., <xn>;
270  *
271  * the method SCIPparseVarsList() can parse such a string
272  *
273  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
274  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
275  *
276  * @pre This method can be called if @p scip is in one of the following stages:
277  * - \ref SCIP_STAGE_PROBLEM
278  * - \ref SCIP_STAGE_TRANSFORMING
279  * - \ref SCIP_STAGE_TRANSFORMED
280  * - \ref SCIP_STAGE_INITPRESOLVE
281  * - \ref SCIP_STAGE_PRESOLVING
282  * - \ref SCIP_STAGE_EXITPRESOLVE
283  * - \ref SCIP_STAGE_PRESOLVED
284  * - \ref SCIP_STAGE_INITSOLVE
285  * - \ref SCIP_STAGE_SOLVING
286  * - \ref SCIP_STAGE_SOLVED
287  * - \ref SCIP_STAGE_EXITSOLVE
288  * - \ref SCIP_STAGE_FREETRANS
289  *
290  * @note The printing process is done via the message handler system.
291  */
293  SCIP* scip, /**< SCIP data structure */
294  FILE* file, /**< output file, or NULL for stdout */
295  SCIP_VAR** vars, /**< variable array to output */
296  int nvars, /**< number of variables */
297  SCIP_Bool type, /**< should the variable type be also posted */
298  char delimiter /**< character which is used for delimitation */
299  )
300 {
301  int v;
302 
303  SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsList", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
304 
305  for( v = 0; v < nvars; ++v )
306  {
307  if( v > 0 )
308  {
309  SCIPinfoMessage(scip, file, "%c", delimiter);
310  }
311 
312  /* print variable name */
313  SCIP_CALL( SCIPwriteVarName(scip, file, vars[v], type) );
314  }
315 
316  return SCIP_OKAY;
317 }
318 
319 /** print the given variables and coefficients as linear sum in the following form
320  * c1 <x1> + c2 <x2> ... + cn <xn>
321  *
322  * This string can be parsed by the method SCIPparseVarsLinearsum().
323  *
324  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
325  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
326  *
327  * @pre This method can be called if @p scip is in one of the following stages:
328  * - \ref SCIP_STAGE_PROBLEM
329  * - \ref SCIP_STAGE_TRANSFORMING
330  * - \ref SCIP_STAGE_TRANSFORMED
331  * - \ref SCIP_STAGE_INITPRESOLVE
332  * - \ref SCIP_STAGE_PRESOLVING
333  * - \ref SCIP_STAGE_EXITPRESOLVE
334  * - \ref SCIP_STAGE_PRESOLVED
335  * - \ref SCIP_STAGE_INITSOLVE
336  * - \ref SCIP_STAGE_SOLVING
337  * - \ref SCIP_STAGE_SOLVED
338  * - \ref SCIP_STAGE_EXITSOLVE
339  * - \ref SCIP_STAGE_FREETRANS
340  *
341  * @note The printing process is done via the message handler system.
342  */
344  SCIP* scip, /**< SCIP data structure */
345  FILE* file, /**< output file, or NULL for stdout */
346  SCIP_VAR** vars, /**< variable array to output */
347  SCIP_Real* vals, /**< array of coefficients or NULL if all coefficients are 1.0 */
348  int nvars, /**< number of variables */
349  SCIP_Bool type /**< should the variable type be also posted */
350  )
351 {
352  int v;
353 
354  SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsLinearsum", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
355 
356  for( v = 0; v < nvars; ++v )
357  {
358  if( vals != NULL )
359  {
360  if( vals[v] == 1.0 )
361  {
362  if( v > 0 )
363  SCIPinfoMessage(scip, file, " +");
364  }
365  else if( vals[v] == -1.0 )
366  SCIPinfoMessage(scip, file, " -");
367  else
368  SCIPinfoMessage(scip, file, " %+.15g", vals[v]);
369  }
370  else if( nvars > 0 )
371  SCIPinfoMessage(scip, file, " +");
372 
373  /* print variable name */
374  SCIP_CALL( SCIPwriteVarName(scip, file, vars[v], type) );
375  }
376 
377  return SCIP_OKAY;
378 }
379 
380 /** print the given terms as signomial in the following form
381  * c1 <x11>^e11 <x12>^e12 ... <x1n>^e1n + c2 <x21>^e21 <x22>^e22 ... + ... + cn <xn1>^en1 ...
382  *
383  * This string can be parsed by the method SCIPparseVarsPolynomial().
384  *
385  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
386  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
387  *
388  * @pre This method can be called if @p scip is in one of the following stages:
389  * - \ref SCIP_STAGE_PROBLEM
390  * - \ref SCIP_STAGE_TRANSFORMING
391  * - \ref SCIP_STAGE_TRANSFORMED
392  * - \ref SCIP_STAGE_INITPRESOLVE
393  * - \ref SCIP_STAGE_PRESOLVING
394  * - \ref SCIP_STAGE_EXITPRESOLVE
395  * - \ref SCIP_STAGE_PRESOLVED
396  * - \ref SCIP_STAGE_INITSOLVE
397  * - \ref SCIP_STAGE_SOLVING
398  * - \ref SCIP_STAGE_SOLVED
399  * - \ref SCIP_STAGE_EXITSOLVE
400  * - \ref SCIP_STAGE_FREETRANS
401  *
402  * @note The printing process is done via the message handler system.
403  */
405  SCIP* scip, /**< SCIP data structure */
406  FILE* file, /**< output file, or NULL for stdout */
407  SCIP_VAR*** monomialvars, /**< arrays with variables for each monomial */
408  SCIP_Real** monomialexps, /**< arrays with variable exponents, or NULL if always 1.0 */
409  SCIP_Real* monomialcoefs, /**< array with monomial coefficients */
410  int* monomialnvars, /**< array with number of variables for each monomial */
411  int nmonomials, /**< number of monomials */
412  SCIP_Bool type /**< should the variable type be also posted */
413  )
414 {
415  int i;
416  int v;
417 
418  assert(scip != NULL);
419  assert(monomialvars != NULL || nmonomials == 0);
420  assert(monomialcoefs != NULL || nmonomials == 0);
421  assert(monomialnvars != NULL || nmonomials == 0);
422 
423  SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsPolynomial", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
424 
425  if( nmonomials == 0 )
426  {
427  SCIPinfoMessage(scip, file, " 0 ");
428  return SCIP_OKAY;
429  }
430 
431  for( i = 0; i < nmonomials; ++i )
432  {
433  if( monomialcoefs[i] == 1.0 ) /*lint !e613*/
434  {
435  if( i > 0 )
436  SCIPinfoMessage(scip, file, " +");
437  }
438  else if( monomialcoefs[i] == -1.0 ) /*lint !e613*/
439  SCIPinfoMessage(scip, file, " -");
440  else
441  SCIPinfoMessage(scip, file, " %+.15g", monomialcoefs[i]); /*lint !e613*/
442 
443  assert(monomialvars[i] != NULL || monomialnvars[i] == 0); /*lint !e613*/
444 
445  for( v = 0; v < monomialnvars[i]; ++v ) /*lint !e613*/
446  {
447  SCIP_CALL( SCIPwriteVarName(scip, file, monomialvars[i][v], type) ); /*lint !e613*/
448  if( monomialexps != NULL && monomialexps[i] != NULL && monomialexps[i][v] != 1.0 )
449  {
450  SCIPinfoMessage(scip, file, "^%.15g", monomialexps[i][v]);
451  }
452  }
453  }
454 
455  return SCIP_OKAY;
456 }
457 
458 /** parses variable information (in cip format) out of a string; if the parsing process was successful a variable is
459  * created and captured; if variable is of integral type, fractional bounds are automatically rounded; an integer
460  * variable with bounds zero and one is automatically converted into a binary variable
461  *
462  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
463  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
464  *
465  * @pre This method can be called if @p scip is in one of the following stages:
466  * - \ref SCIP_STAGE_PROBLEM
467  * - \ref SCIP_STAGE_TRANSFORMING
468  * - \ref SCIP_STAGE_INITPRESOLVE
469  * - \ref SCIP_STAGE_PRESOLVING
470  * - \ref SCIP_STAGE_EXITPRESOLVE
471  * - \ref SCIP_STAGE_PRESOLVED
472  * - \ref SCIP_STAGE_SOLVING
473  */
475  SCIP* scip, /**< SCIP data structure */
476  SCIP_VAR** var, /**< pointer to store the problem variable */
477  const char* str, /**< string to parse */
478  SCIP_Bool initial, /**< should var's column be present in the initial root LP? */
479  SCIP_Bool removable, /**< is var's column removable from the LP (due to aging or cleanup)? */
480  SCIP_DECL_VARCOPY ((*varcopy)), /**< copies variable data if wanted to subscip, or NULL */
481  SCIP_DECL_VARDELORIG ((*vardelorig)), /**< frees user data of original variable */
482  SCIP_DECL_VARTRANS ((*vartrans)), /**< creates transformed user data by transforming original user data */
483  SCIP_DECL_VARDELTRANS ((*vardeltrans)), /**< frees user data of transformed variable */
484  SCIP_VARDATA* vardata, /**< user data for this specific variable */
485  char** endptr, /**< pointer to store the final string position if successful */
486  SCIP_Bool* success /**< pointer store if the paring process was successful */
487  )
488 {
489  assert(var != NULL);
490 
491  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVar", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
492 
493  switch( scip->set->stage )
494  {
495  case SCIP_STAGE_PROBLEM:
496  SCIP_CALL( SCIPvarParseOriginal(var, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
497  str, initial, removable, varcopy, vardelorig, vartrans, vardeltrans, vardata, endptr, success) );
498  break;
499 
505  case SCIP_STAGE_SOLVING:
506  SCIP_CALL( SCIPvarParseTransformed(var, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
507  str, initial, removable, varcopy, vardelorig, vartrans, vardeltrans, vardata, endptr, success) );
508  break;
509 
510  default:
511  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
512  return SCIP_INVALIDCALL;
513  } /*lint !e788*/
514 
515  return SCIP_OKAY;
516 }
517 
518 /** parses the given string for a variable name and stores the variable in the corresponding pointer if such a variable
519  * exits and returns the position where the parsing stopped
520  *
521  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
522  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
523  *
524  * @pre This method can be called if @p scip is in one of the following stages:
525  * - \ref SCIP_STAGE_PROBLEM
526  * - \ref SCIP_STAGE_TRANSFORMING
527  * - \ref SCIP_STAGE_INITPRESOLVE
528  * - \ref SCIP_STAGE_PRESOLVING
529  * - \ref SCIP_STAGE_EXITPRESOLVE
530  * - \ref SCIP_STAGE_PRESOLVED
531  * - \ref SCIP_STAGE_SOLVING
532  */
534  SCIP* scip, /**< SCIP data structure */
535  const char* str, /**< string to parse */
536  SCIP_VAR** var, /**< pointer to store the problem variable, or NULL if it does not exit */
537  char** endptr /**< pointer to store the final string position if successful */
538  )
539 {
540  char varname[SCIP_MAXSTRLEN];
541 
542  assert(str != NULL);
543  assert(var != NULL);
544  assert(endptr != NULL);
545 
546  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarName", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
547 
548  SCIPstrCopySection(str, '<', '>', varname, SCIP_MAXSTRLEN, endptr);
549  assert(*endptr != NULL);
550 
551  if( *endptr == str )
552  {
553  *var = NULL;
554  return SCIP_OKAY;
555  }
556 
557  /* check if we have a negated variable */
558  if( *varname == '~' )
559  {
560  SCIPdebugMsg(scip, "parsed negated variable name <%s>\n", &varname[1]);
561 
562  /* search for the variable and ignore '~' */
563  (*var) = SCIPfindVar(scip, &varname[1]);
564 
565  if( *var != NULL )
566  {
567  SCIP_CALL( SCIPgetNegatedVar(scip, *var, var) );
568  }
569  }
570  else
571  {
572  SCIPdebugMsg(scip, "parsed variable name <%s>\n", varname);
573 
574  /* search for the variable */
575  (*var) = SCIPfindVar(scip, varname);
576  }
577 
578  str = *endptr;
579 
580  /* skip additional variable type marker */
581  if( *str == '[' && (str[1] == SCIP_VARTYPE_BINARY_CHAR || str[1] == SCIP_VARTYPE_INTEGER_CHAR ||
582  str[1] == SCIP_VARTYPE_IMPLINT_CHAR || str[1] == SCIP_VARTYPE_CONTINUOUS_CHAR ) && str[2] == ']' )
583  (*endptr) += 3;
584 
585  return SCIP_OKAY;
586 }
587 
588 /** parse the given string as variable list (here ',' is the delimiter)) (<x1>, <x2>, ..., <xn>) (see
589  * SCIPwriteVarsList() ); if it was successful, the pointer success is set to TRUE
590  *
591  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
592  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
593  *
594  * @pre This method can be called if @p scip is in one of the following stages:
595  * - \ref SCIP_STAGE_PROBLEM
596  * - \ref SCIP_STAGE_TRANSFORMING
597  * - \ref SCIP_STAGE_INITPRESOLVE
598  * - \ref SCIP_STAGE_PRESOLVING
599  * - \ref SCIP_STAGE_EXITPRESOLVE
600  * - \ref SCIP_STAGE_PRESOLVED
601  * - \ref SCIP_STAGE_SOLVING
602  *
603  * @note The pointer success in only set to FALSE in the case that a variable with a parsed variable name does not exist.
604  *
605  * @note If the number of (parsed) variables is greater than the available slots in the variable array, nothing happens
606  * except that the required size is stored in the corresponding integer; the reason for this approach is that we
607  * cannot reallocate memory, since we do not know how the memory has been allocated (e.g., by a C++ 'new' or SCIP
608  * memory functions).
609  */
611  SCIP* scip, /**< SCIP data structure */
612  const char* str, /**< string to parse */
613  SCIP_VAR** vars, /**< array to store the parsed variable */
614  int* nvars, /**< pointer to store number of parsed variables */
615  int varssize, /**< size of the variable array */
616  int* requiredsize, /**< pointer to store the required array size for the active variables */
617  char** endptr, /**< pointer to store the final string position if successful */
618  char delimiter, /**< character which is used for delimitation */
619  SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
620  )
621 {
622  SCIP_VAR** tmpvars;
623  SCIP_VAR* var;
624  int ntmpvars = 0;
625  int v;
626 
627  assert( nvars != NULL );
628  assert( requiredsize != NULL );
629  assert( endptr != NULL );
630  assert( success != NULL );
631 
632  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsList", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
633 
634  /* allocate buffer memory for temporary storing the parsed variables */
635  SCIP_CALL( SCIPallocBufferArray(scip, &tmpvars, varssize) );
636 
637  *success = TRUE;
638 
639  do
640  {
641  *endptr = (char*)str;
642 
643  /* parse variable name */
644  SCIP_CALL( SCIPparseVarName(scip, str, &var, endptr) );
645 
646  if( var == NULL )
647  break;
648 
649  str = *endptr;
650 
651  /* store the variable in the tmp array */
652  if( ntmpvars < varssize )
653  tmpvars[ntmpvars] = var;
654 
655  ntmpvars++;
656 
657  SCIP_CALL( SCIPskipSpace((char**)&str) );
658  }
659  while( *str == delimiter );
660 
661  *endptr = (char*)str;
662 
663  /* if all variable name searches were successful and the variable array has enough slots, copy the collected variables */
664  if( (*success) && ntmpvars <= varssize )
665  {
666  for( v = 0; v < ntmpvars; ++v )
667  vars[v] = tmpvars[v];
668 
669  (*nvars) = ntmpvars;
670  }
671  else
672  (*nvars) = 0;
673 
674  (*requiredsize) = ntmpvars;
675 
676  /* free buffer arrays */
677  SCIPfreeBufferArray(scip, &tmpvars);
678 
679  return SCIP_OKAY;
680 }
681 
682 /** parse the given string as linear sum of variables and coefficients (c1 <x1> + c2 <x2> + ... + cn <xn>)
683  * (see SCIPwriteVarsLinearsum() ); if it was successful, the pointer success is set to TRUE
684  *
685  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
686  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
687  *
688  * @pre This method can be called if @p scip is in one of the following stages:
689  * - \ref SCIP_STAGE_PROBLEM
690  * - \ref SCIP_STAGE_TRANSFORMING
691  * - \ref SCIP_STAGE_INITPRESOLVE
692  * - \ref SCIP_STAGE_PRESOLVING
693  * - \ref SCIP_STAGE_EXITPRESOLVE
694  * - \ref SCIP_STAGE_PRESOLVED
695  * - \ref SCIP_STAGE_SOLVING
696  *
697  * @note The pointer success in only set to FALSE in the case that a variable with a parsed variable name does not exist.
698  *
699  * @note If the number of (parsed) variables is greater than the available slots in the variable array, nothing happens
700  * except that the required size is stored in the corresponding integer; the reason for this approach is that we
701  * cannot reallocate memory, since we do not know how the memory has been allocated (e.g., by a C++ 'new' or SCIP
702  * memory functions).
703  */
705  SCIP* scip, /**< SCIP data structure */
706  const char* str, /**< string to parse */
707  SCIP_VAR** vars, /**< array to store the parsed variables */
708  SCIP_Real* vals, /**< array to store the parsed coefficients */
709  int* nvars, /**< pointer to store number of parsed variables */
710  int varssize, /**< size of the variable array */
711  int* requiredsize, /**< pointer to store the required array size for the active variables */
712  char** endptr, /**< pointer to store the final string position if successful */
713  SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
714  )
715 {
716  SCIP_VAR*** monomialvars;
717  SCIP_Real** monomialexps;
718  SCIP_Real* monomialcoefs;
719  int* monomialnvars;
720  int nmonomials;
721 
722  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsLinearsum", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
723 
724  assert(scip != NULL);
725  assert(str != NULL);
726  assert(vars != NULL || varssize == 0);
727  assert(vals != NULL || varssize == 0);
728  assert(nvars != NULL);
729  assert(requiredsize != NULL);
730  assert(endptr != NULL);
731  assert(success != NULL);
732 
733  *requiredsize = 0;
734 
735  SCIP_CALL( SCIPparseVarsPolynomial(scip, str, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, &nmonomials, endptr, success) );
736 
737  if( !*success )
738  {
739  assert(nmonomials == 0); /* SCIPparseVarsPolynomial should have freed all buffers, so no need to call free here */
740  return SCIP_OKAY;
741  }
742 
743  /* check if linear sum is just "0" */
744  if( nmonomials == 1 && monomialnvars[0] == 0 && monomialcoefs[0] == 0.0 )
745  {
746  *nvars = 0;
747  *requiredsize = 0;
748 
749  SCIPfreeParseVarsPolynomialData(scip, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, nmonomials);
750 
751  return SCIP_OKAY;
752  }
753 
754  *nvars = nmonomials;
755  *requiredsize = nmonomials;
756 
757  /* if we have enough slots in the variables array, copy variables over */
758  if( varssize >= nmonomials )
759  {
760  int v;
761 
762  for( v = 0; v < nmonomials; ++v )
763  {
764  if( monomialnvars[v] == 0 )
765  {
766  SCIPerrorMessage("constant in linear sum\n");
767  *success = FALSE;
768  break;
769  }
770  if( monomialnvars[v] > 1 || monomialexps[v][0] != 1.0 )
771  {
772  SCIPerrorMessage("nonlinear monomial in linear sum\n");
773  *success = FALSE;
774  break;
775  }
776  assert(monomialnvars[v] == 1);
777  assert(monomialvars[v][0] != NULL);
778  assert(monomialexps[v][0] == 1.0);
779 
780  vars[v] = monomialvars[v][0]; /*lint !e613*/
781  vals[v] = monomialcoefs[v]; /*lint !e613*/
782  }
783  }
784 
785  SCIPfreeParseVarsPolynomialData(scip, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, nmonomials);
786 
787  return SCIP_OKAY;
788 }
789 
790 /** parse the given string as signomial of variables and coefficients
791  * (c1 <x11>^e11 <x12>^e12 ... <x1n>^e1n + c2 <x21>^e21 <x22>^e22 ... + ... + cn <xn1>^en1 ...)
792  * (see SCIPwriteVarsPolynomial()); if it was successful, the pointer success is set to TRUE
793  *
794  * The user has to call SCIPfreeParseVarsPolynomialData(scip, monomialvars, monomialexps,
795  * monomialcoefs, monomialnvars, *nmonomials) short after SCIPparseVarsPolynomial to free all the
796  * allocated memory again.
797  *
798  * Parsing is stopped at the end of string (indicated by the \\0-character) or when no more monomials
799  * are recognized.
800  *
801  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
802  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
803  *
804  * @pre This method can be called if @p scip is in one of the following stages:
805  * - \ref SCIP_STAGE_PROBLEM
806  * - \ref SCIP_STAGE_TRANSFORMING
807  * - \ref SCIP_STAGE_INITPRESOLVE
808  * - \ref SCIP_STAGE_PRESOLVING
809  * - \ref SCIP_STAGE_EXITPRESOLVE
810  * - \ref SCIP_STAGE_PRESOLVED
811  * - \ref SCIP_STAGE_SOLVING
812  */
814  SCIP* scip, /**< SCIP data structure */
815  const char* str, /**< string to parse */
816  SCIP_VAR**** monomialvars, /**< pointer to store arrays with variables for each monomial */
817  SCIP_Real*** monomialexps, /**< pointer to store arrays with variable exponents */
818  SCIP_Real** monomialcoefs, /**< pointer to store array with monomial coefficients */
819  int** monomialnvars, /**< pointer to store array with number of variables for each monomial */
820  int* nmonomials, /**< pointer to store number of parsed monomials */
821  char** endptr, /**< pointer to store the final string position if successful */
822  SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
823  )
824 {
825  typedef enum
826  {
827  SCIPPARSEPOLYNOMIAL_STATE_BEGIN, /* we are at the beginning of a monomial */
828  SCIPPARSEPOLYNOMIAL_STATE_INTERMED, /* we are in between the factors of a monomial */
829  SCIPPARSEPOLYNOMIAL_STATE_COEF, /* we parse the coefficient of a monomial */
830  SCIPPARSEPOLYNOMIAL_STATE_VARS, /* we parse monomial variables */
831  SCIPPARSEPOLYNOMIAL_STATE_EXPONENT, /* we parse the exponent of a variable */
832  SCIPPARSEPOLYNOMIAL_STATE_END, /* we are at the end the polynomial */
833  SCIPPARSEPOLYNOMIAL_STATE_ERROR /* a parsing error occured */
834  } SCIPPARSEPOLYNOMIAL_STATES;
835 
836  SCIPPARSEPOLYNOMIAL_STATES state;
837  int monomialssize;
838 
839  /* data of currently parsed monomial */
840  int varssize;
841  int nvars;
842  SCIP_VAR** vars;
843  SCIP_Real* exponents;
844  SCIP_Real coef;
845 
846  assert(scip != NULL);
847  assert(str != NULL);
848  assert(monomialvars != NULL);
849  assert(monomialexps != NULL);
850  assert(monomialnvars != NULL);
851  assert(monomialcoefs != NULL);
852  assert(nmonomials != NULL);
853  assert(endptr != NULL);
854  assert(success != NULL);
855 
856  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsPolynomial", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
857 
858  *success = FALSE;
859  *nmonomials = 0;
860  monomialssize = 0;
861  *monomialvars = NULL;
862  *monomialexps = NULL;
863  *monomialcoefs = NULL;
864  *monomialnvars = NULL;
865 
866  /* initialize state machine */
867  state = SCIPPARSEPOLYNOMIAL_STATE_BEGIN;
868  varssize = 0;
869  nvars = 0;
870  vars = NULL;
871  exponents = NULL;
872  coef = SCIP_INVALID;
873 
874  SCIPdebugMsg(scip, "parsing polynomial from '%s'\n", str);
875 
876  while( *str && state != SCIPPARSEPOLYNOMIAL_STATE_END && state != SCIPPARSEPOLYNOMIAL_STATE_ERROR )
877  {
878  /* skip white space */
879  SCIP_CALL( SCIPskipSpace((char**)&str) );
880 
881  assert(state != SCIPPARSEPOLYNOMIAL_STATE_END);
882 
883  switch( state )
884  {
885  case SCIPPARSEPOLYNOMIAL_STATE_BEGIN:
886  {
887  if( coef != SCIP_INVALID ) /*lint !e777*/
888  {
889  SCIPdebugMsg(scip, "push monomial with coefficient <%g> and <%d> vars\n", coef, nvars);
890 
891  /* push previous monomial */
892  if( monomialssize <= *nmonomials )
893  {
894  monomialssize = SCIPcalcMemGrowSize(scip, *nmonomials+1);
895 
896  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, *nmonomials, monomialssize) );
897  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, *nmonomials, monomialssize) );
898  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, *nmonomials, monomialssize) );
899  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, *nmonomials, monomialssize) );
900  }
901 
902  if( nvars > 0 )
903  {
904  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*monomialvars)[*nmonomials], vars, nvars) ); /*lint !e866*/
905  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*monomialexps)[*nmonomials], exponents, nvars) ); /*lint !e866*/
906  }
907  else
908  {
909  (*monomialvars)[*nmonomials] = NULL;
910  (*monomialexps)[*nmonomials] = NULL;
911  }
912  (*monomialcoefs)[*nmonomials] = coef;
913  (*monomialnvars)[*nmonomials] = nvars;
914  ++*nmonomials;
915 
916  nvars = 0;
917  coef = SCIP_INVALID;
918  }
919 
920  if( *str == '<' )
921  {
922  /* there seem to come a variable at the beginning of a monomial
923  * so assume the coefficient is 1.0
924  */
925  state = SCIPPARSEPOLYNOMIAL_STATE_VARS;
926  coef = 1.0;
927  }
928  else if( *str == '-' || *str == '+' || isdigit(*str) )
929  state = SCIPPARSEPOLYNOMIAL_STATE_COEF;
930  else
931  state = SCIPPARSEPOLYNOMIAL_STATE_END;
932 
933  break;
934  }
935 
936  case SCIPPARSEPOLYNOMIAL_STATE_INTERMED:
937  {
938  if( *str == '<' )
939  {
940  /* there seem to come another variable */
941  state = SCIPPARSEPOLYNOMIAL_STATE_VARS;
942  }
943  else if( *str == '-' || *str == '+' || isdigit(*str) )
944  {
945  /* there seem to come a coefficient, which means the next monomial */
946  state = SCIPPARSEPOLYNOMIAL_STATE_BEGIN;
947  }
948  else /* since we cannot detect the symbols we stop parsing the polynomial */
949  state = SCIPPARSEPOLYNOMIAL_STATE_END;
950 
951  break;
952  }
953 
954  case SCIPPARSEPOLYNOMIAL_STATE_COEF:
955  {
956  if( *str == '+' && !isdigit(str[1]) )
957  {
958  /* only a plus sign, without number */
959  coef = 1.0;
960  ++str;
961  }
962  else if( *str == '-' && !isdigit(str[1]) )
963  {
964  /* only a minus sign, without number */
965  coef = -1.0;
966  ++str;
967  }
968  else if( SCIPstrToRealValue(str, &coef, endptr) )
969  {
970  str = *endptr;
971  }
972  else
973  {
974  SCIPerrorMessage("could not parse number in the beginning of '%s'\n", str);
975  state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
976  break;
977  }
978 
979  /* after the coefficient we go into the intermediate state, i.e., expecting next variables */
980  state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED; /*lint !e838*/
981 
982  break;
983  }
984 
985  case SCIPPARSEPOLYNOMIAL_STATE_VARS:
986  {
987  SCIP_VAR* var;
988 
989  assert(*str == '<');
990 
991  /* parse variable name */
992  SCIP_CALL( SCIPparseVarName(scip, str, &var, endptr) );
993 
994  /* check if variable name was parsed */
995  if( *endptr == str )
996  {
997  state = SCIPPARSEPOLYNOMIAL_STATE_END;
998  break;
999  }
1000 
1001  if( var == NULL )
1002  {
1003  SCIPerrorMessage("did not find variable in the beginning of %s\n", str);
1004  state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
1005  break;
1006  }
1007 
1008  /* add variable to vars array */
1009  if( nvars + 1 > varssize )
1010  {
1011  varssize = SCIPcalcMemGrowSize(scip, nvars+1);
1012  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &vars, nvars, varssize) );
1013  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &exponents, nvars, varssize) );
1014  }
1015  assert(vars != NULL);
1016  assert(exponents != NULL);
1017 
1018  vars[nvars] = var;
1019  exponents[nvars] = 1.0;
1020  ++nvars;
1021 
1022  str = *endptr;
1023 
1024  if( *str == '^' )
1025  state = SCIPPARSEPOLYNOMIAL_STATE_EXPONENT;
1026  else
1027  state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED;
1028 
1029  break;
1030  }
1031 
1032  case SCIPPARSEPOLYNOMIAL_STATE_EXPONENT:
1033  {
1034  assert(*str == '^');
1035  assert(nvars > 0); /* we should be in a monomial that has already a variable */
1036  assert(exponents != NULL);
1037  ++str;
1038 
1039  if( !SCIPstrToRealValue(str, &exponents[nvars-1], endptr) )
1040  {
1041  SCIPerrorMessage("could not parse number in the beginning of '%s'\n", str);
1042  state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
1043  break;
1044  }
1045  str = *endptr;
1046 
1047  /* after the exponent we go into the intermediate state, i.e., expecting next variables */
1048  state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED; /*lint !e838*/
1049  break;
1050  }
1051 
1052  /* coverity[dead_error_line] */
1053  case SCIPPARSEPOLYNOMIAL_STATE_END:
1054  /* coverity[dead_error_line] */
1055  case SCIPPARSEPOLYNOMIAL_STATE_ERROR:
1056  default:
1057  SCIPerrorMessage("unexpected state\n");
1058  return SCIP_READERROR;
1059  }
1060  }
1061 
1062  /* set end pointer */
1063  *endptr = (char*)str;
1064 
1065  /* check state at end of string */
1066  switch( state )
1067  {
1068  case SCIPPARSEPOLYNOMIAL_STATE_BEGIN:
1069  case SCIPPARSEPOLYNOMIAL_STATE_END:
1070  case SCIPPARSEPOLYNOMIAL_STATE_INTERMED:
1071  {
1072  if( coef != SCIP_INVALID ) /*lint !e777*/
1073  {
1074  /* push last monomial */
1075  SCIPdebugMsg(scip, "push monomial with coefficient <%g> and <%d> vars\n", coef, nvars);
1076  if( monomialssize <= *nmonomials )
1077  {
1078  monomialssize = *nmonomials+1;
1079  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, *nmonomials, monomialssize) );
1080  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, *nmonomials, monomialssize) );
1081  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, *nmonomials, monomialssize) );
1082  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, *nmonomials, monomialssize) );
1083  }
1084 
1085  if( nvars > 0 )
1086  {
1087  /* shrink vars and exponents array to needed size and take over ownership */
1088  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &vars, varssize, nvars) );
1089  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &exponents, varssize, nvars) );
1090  (*monomialvars)[*nmonomials] = vars;
1091  (*monomialexps)[*nmonomials] = exponents;
1092  vars = NULL;
1093  exponents = NULL;
1094  }
1095  else
1096  {
1097  (*monomialvars)[*nmonomials] = NULL;
1098  (*monomialexps)[*nmonomials] = NULL;
1099  }
1100  (*monomialcoefs)[*nmonomials] = coef;
1101  (*monomialnvars)[*nmonomials] = nvars;
1102  ++*nmonomials;
1103  }
1104 
1105  *success = TRUE;
1106  break;
1107  }
1108 
1109  case SCIPPARSEPOLYNOMIAL_STATE_COEF:
1110  case SCIPPARSEPOLYNOMIAL_STATE_VARS:
1111  case SCIPPARSEPOLYNOMIAL_STATE_EXPONENT:
1112  {
1113  SCIPerrorMessage("unexpected parsing state at end of polynomial string\n");
1114  }
1115  /*lint -fallthrough*/
1116  case SCIPPARSEPOLYNOMIAL_STATE_ERROR:
1117  assert(!*success);
1118  break;
1119  }
1120 
1121  /* free memory to store current monomial, if still existing */
1122  SCIPfreeBlockMemoryArrayNull(scip, &vars, varssize);
1123  SCIPfreeBlockMemoryArrayNull(scip, &exponents, varssize);
1124 
1125  if( *success && *nmonomials > 0 )
1126  {
1127  /* shrink arrays to required size, so we do not need to keep monomialssize around */
1128  assert(*nmonomials <= monomialssize);
1129  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, monomialssize, *nmonomials) );
1130  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, monomialssize, *nmonomials) );
1131  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, monomialssize, *nmonomials) );
1132  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, monomialssize, *nmonomials) );
1133 
1134  /* SCIPwriteVarsPolynomial(scip, NULL, *monomialvars, *monomialexps, *monomialcoefs, *monomialnvars, *nmonomials, FALSE); */
1135  }
1136  else
1137  {
1138  /* in case of error, cleanup all data here */
1139  SCIPfreeParseVarsPolynomialData(scip, monomialvars, monomialexps, monomialcoefs, monomialnvars, *nmonomials);
1140  *nmonomials = 0;
1141  }
1142 
1143  return SCIP_OKAY;
1144 }
1145 
1146 /** frees memory allocated when parsing a signomial from a string
1147  *
1148  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1149  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1150  *
1151  * @pre This method can be called if @p scip is in one of the following stages:
1152  * - \ref SCIP_STAGE_PROBLEM
1153  * - \ref SCIP_STAGE_TRANSFORMING
1154  * - \ref SCIP_STAGE_INITPRESOLVE
1155  * - \ref SCIP_STAGE_PRESOLVING
1156  * - \ref SCIP_STAGE_EXITPRESOLVE
1157  * - \ref SCIP_STAGE_PRESOLVED
1158  * - \ref SCIP_STAGE_SOLVING
1159  */
1161  SCIP* scip, /**< SCIP data structure */
1162  SCIP_VAR**** monomialvars, /**< pointer to store arrays with variables for each monomial */
1163  SCIP_Real*** monomialexps, /**< pointer to store arrays with variable exponents */
1164  SCIP_Real** monomialcoefs, /**< pointer to store array with monomial coefficients */
1165  int** monomialnvars, /**< pointer to store array with number of variables for each monomial */
1166  int nmonomials /**< pointer to store number of parsed monomials */
1167  )
1168 {
1169  int i;
1170 
1171  assert(scip != NULL);
1172  assert(monomialvars != NULL);
1173  assert(monomialexps != NULL);
1174  assert(monomialcoefs != NULL);
1175  assert(monomialnvars != NULL);
1176  assert((*monomialvars != NULL) == (nmonomials > 0));
1177  assert((*monomialexps != NULL) == (nmonomials > 0));
1178  assert((*monomialcoefs != NULL) == (nmonomials > 0));
1179  assert((*monomialnvars != NULL) == (nmonomials > 0));
1180 
1181  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPfreeParseVarsPolynomialData", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1182 
1183  if( nmonomials == 0 )
1184  return;
1185 
1186  for( i = nmonomials - 1; i >= 0; --i )
1187  {
1188  SCIPfreeBlockMemoryArrayNull(scip, &(*monomialexps)[i], (*monomialnvars)[i]);
1189  SCIPfreeBlockMemoryArrayNull(scip, &(*monomialvars)[i], (*monomialnvars)[i]);
1190  }
1191 
1192  SCIPfreeBlockMemoryArray(scip, monomialcoefs, nmonomials);
1193  SCIPfreeBlockMemoryArray(scip, monomialnvars, nmonomials);
1194  SCIPfreeBlockMemoryArray(scip, monomialexps, nmonomials);
1195  SCIPfreeBlockMemoryArray(scip, monomialvars, nmonomials);
1196 }
1197 
1198 /** increases usage counter of variable
1199  *
1200  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1201  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1202  *
1203  * @pre This method can be called if @p scip is in one of the following stages:
1204  * - \ref SCIP_STAGE_PROBLEM
1205  * - \ref SCIP_STAGE_TRANSFORMING
1206  * - \ref SCIP_STAGE_TRANSFORMED
1207  * - \ref SCIP_STAGE_INITPRESOLVE
1208  * - \ref SCIP_STAGE_PRESOLVING
1209  * - \ref SCIP_STAGE_EXITPRESOLVE
1210  * - \ref SCIP_STAGE_PRESOLVED
1211  * - \ref SCIP_STAGE_INITSOLVE
1212  * - \ref SCIP_STAGE_SOLVING
1213  * - \ref SCIP_STAGE_SOLVED
1214  * - \ref SCIP_STAGE_EXITSOLVE
1215  */
1217  SCIP* scip, /**< SCIP data structure */
1218  SCIP_VAR* var /**< variable to capture */
1219  )
1220 {
1221  SCIP_CALL( SCIPcheckStage(scip, "SCIPcaptureVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1222  assert(var->scip == scip);
1223 
1224  SCIPvarCapture(var);
1225 
1226  return SCIP_OKAY;
1227 }
1228 
1229 /** decreases usage counter of variable, if the usage pointer reaches zero the variable gets freed
1230  *
1231  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1232  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1233  *
1234  * @pre This method can be called if @p scip is in one of the following stages:
1235  * - \ref SCIP_STAGE_PROBLEM
1236  * - \ref SCIP_STAGE_TRANSFORMING
1237  * - \ref SCIP_STAGE_TRANSFORMED
1238  * - \ref SCIP_STAGE_INITPRESOLVE
1239  * - \ref SCIP_STAGE_PRESOLVING
1240  * - \ref SCIP_STAGE_EXITPRESOLVE
1241  * - \ref SCIP_STAGE_PRESOLVED
1242  * - \ref SCIP_STAGE_INITSOLVE
1243  * - \ref SCIP_STAGE_SOLVING
1244  * - \ref SCIP_STAGE_SOLVED
1245  * - \ref SCIP_STAGE_EXITSOLVE
1246  * - \ref SCIP_STAGE_FREETRANS
1247  *
1248  * @note the pointer of the variable will be NULLed
1249  */
1251  SCIP* scip, /**< SCIP data structure */
1252  SCIP_VAR** var /**< pointer to variable */
1253  )
1254 {
1255  assert(var != NULL);
1256  assert(*var != NULL);
1257  assert((*var)->scip == scip);
1258 
1259  SCIP_CALL( SCIPcheckStage(scip, "SCIPreleaseVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1260 
1261  switch( scip->set->stage )
1262  {
1263  case SCIP_STAGE_PROBLEM:
1264  SCIP_CALL( SCIPvarRelease(var, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp) );
1265  return SCIP_OKAY;
1266 
1270  case SCIP_STAGE_PRESOLVING:
1272  case SCIP_STAGE_PRESOLVED:
1273  case SCIP_STAGE_INITSOLVE:
1274  case SCIP_STAGE_SOLVING:
1275  case SCIP_STAGE_SOLVED:
1276  case SCIP_STAGE_EXITSOLVE:
1277  case SCIP_STAGE_FREETRANS:
1278  if( !SCIPvarIsTransformed(*var) && (*var)->nuses == 1 && (*var)->data.original.transvar != NULL )
1279  {
1280  SCIPerrorMessage("cannot release last use of original variable while associated transformed variable exists\n");
1281  return SCIP_INVALIDCALL;
1282  }
1283  SCIP_CALL( SCIPvarRelease(var, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp) );
1284  return SCIP_OKAY;
1285 
1286  default:
1287  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
1288  return SCIP_INVALIDCALL;
1289  } /*lint !e788*/
1290 }
1291 
1292 /** changes the name of a variable
1293  *
1294  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1295  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1296  *
1297  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PROBLEM
1298  *
1299  * @note to get the current name of a variable, use SCIPvarGetName() from pub_var.h
1300  */
1302  SCIP* scip, /**< SCIP data structure */
1303  SCIP_VAR* var, /**< variable */
1304  const char* name /**< new name of constraint */
1305  )
1306 {
1307  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarName", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
1308  assert( var->scip == scip );
1309 
1310  if( SCIPgetStage(scip) != SCIP_STAGE_PROBLEM )
1311  {
1312  SCIPerrorMessage("variable names can only be changed in problem creation stage\n");
1313  SCIPABORT();
1314  return SCIP_INVALIDCALL; /*lint !e527*/
1315  }
1316 
1317  /* remove variable's name from the namespace if the variable was already added */
1318  if( SCIPvarGetProbindex(var) != -1 )
1319  {
1320  SCIP_CALL( SCIPprobRemoveVarName(scip->origprob, var) );
1321  }
1322 
1323  /* change variable name */
1324  SCIP_CALL( SCIPvarChgName(var, SCIPblkmem(scip), name) );
1325 
1326  /* add variable's name to the namespace if the variable was already added */
1327  if( SCIPvarGetProbindex(var) != -1 )
1328  {
1329  SCIP_CALL( SCIPprobAddVarName(scip->origprob, var) );
1330  }
1331 
1332  return SCIP_OKAY;
1333 }
1334 
1335 /** gets and captures transformed variable of a given variable; if the variable is not yet transformed,
1336  * a new transformed variable for this variable is created
1337  *
1338  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1339  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1340  *
1341  * @pre This method can be called if @p scip is in one of the following stages:
1342  * - \ref SCIP_STAGE_TRANSFORMING
1343  * - \ref SCIP_STAGE_TRANSFORMED
1344  * - \ref SCIP_STAGE_INITPRESOLVE
1345  * - \ref SCIP_STAGE_PRESOLVING
1346  * - \ref SCIP_STAGE_EXITPRESOLVE
1347  * - \ref SCIP_STAGE_PRESOLVED
1348  * - \ref SCIP_STAGE_INITSOLVE
1349  * - \ref SCIP_STAGE_SOLVING
1350  */
1352  SCIP* scip, /**< SCIP data structure */
1353  SCIP_VAR* var, /**< variable to get/create transformed variable for */
1354  SCIP_VAR** transvar /**< pointer to store the transformed variable */
1355  )
1356 {
1357  assert(transvar != NULL);
1358 
1359  SCIP_CALL( SCIPcheckStage(scip, "SCIPtransformVar", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1360 
1361  if( SCIPvarIsTransformed(var) )
1362  {
1363  *transvar = var;
1364  SCIPvarCapture(*transvar);
1365  }
1366  else
1367  {
1368  SCIP_CALL( SCIPvarTransform(var, scip->mem->probmem, scip->set, scip->stat, scip->origprob->objsense, transvar) );
1369  }
1370 
1371  return SCIP_OKAY;
1372 }
1373 
1374 /** gets and captures transformed variables for an array of variables;
1375  * if a variable of the array is not yet transformed, a new transformed variable for this variable is created;
1376  * it is possible to call this method with vars == transvars
1377  *
1378  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1379  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1380  *
1381  * @pre This method can be called if @p scip is in one of the following stages:
1382  * - \ref SCIP_STAGE_TRANSFORMING
1383  * - \ref SCIP_STAGE_TRANSFORMED
1384  * - \ref SCIP_STAGE_INITPRESOLVE
1385  * - \ref SCIP_STAGE_PRESOLVING
1386  * - \ref SCIP_STAGE_EXITPRESOLVE
1387  * - \ref SCIP_STAGE_PRESOLVED
1388  * - \ref SCIP_STAGE_INITSOLVE
1389  * - \ref SCIP_STAGE_SOLVING
1390  */
1392  SCIP* scip, /**< SCIP data structure */
1393  int nvars, /**< number of variables to get/create transformed variables for */
1394  SCIP_VAR** vars, /**< array with variables to get/create transformed variables for */
1395  SCIP_VAR** transvars /**< array to store the transformed variables */
1396  )
1397 {
1398  int v;
1399 
1400  assert(nvars == 0 || vars != NULL);
1401  assert(nvars == 0 || transvars != NULL);
1402 
1403  SCIP_CALL( SCIPcheckStage(scip, "SCIPtransformVars", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1404 
1405  for( v = 0; v < nvars; ++v )
1406  {
1407  if( SCIPvarIsTransformed(vars[v]) )
1408  {
1409  transvars[v] = vars[v];
1410  SCIPvarCapture(transvars[v]);
1411  }
1412  else
1413  {
1414  SCIP_CALL( SCIPvarTransform(vars[v], scip->mem->probmem, scip->set, scip->stat, scip->origprob->objsense,
1415  &transvars[v]) );
1416  }
1417  }
1418 
1419  return SCIP_OKAY;
1420 }
1421 
1422 /** gets corresponding transformed variable of a given variable;
1423  * returns NULL as transvar, if transformed variable is not yet existing
1424  *
1425  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1426  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1427  *
1428  * @pre This method can be called if @p scip is in one of the following stages:
1429  * - \ref SCIP_STAGE_TRANSFORMING
1430  * - \ref SCIP_STAGE_TRANSFORMED
1431  * - \ref SCIP_STAGE_INITPRESOLVE
1432  * - \ref SCIP_STAGE_PRESOLVING
1433  * - \ref SCIP_STAGE_EXITPRESOLVE
1434  * - \ref SCIP_STAGE_PRESOLVED
1435  * - \ref SCIP_STAGE_INITSOLVE
1436  * - \ref SCIP_STAGE_SOLVING
1437  * - \ref SCIP_STAGE_SOLVED
1438  * - \ref SCIP_STAGE_EXITSOLVE
1439  * - \ref SCIP_STAGE_FREETRANS
1440  */
1442  SCIP* scip, /**< SCIP data structure */
1443  SCIP_VAR* var, /**< variable to get transformed variable for */
1444  SCIP_VAR** transvar /**< pointer to store the transformed variable */
1445  )
1446 {
1447  assert(transvar != NULL);
1448 
1449  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetTransformedVar", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1450 
1451  if( SCIPvarIsTransformed(var) )
1452  *transvar = var;
1453  else
1454  {
1455  SCIP_CALL( SCIPvarGetTransformed(var, scip->mem->probmem, scip->set, scip->stat, transvar) );
1456  }
1457 
1458  return SCIP_OKAY;
1459 }
1460 
1461 /** gets corresponding transformed variables for an array of variables;
1462  * stores NULL in a transvars slot, if the transformed variable is not yet existing;
1463  * it is possible to call this method with vars == transvars, but remember that variables that are not
1464  * yet transformed will be replaced with NULL
1465  *
1466  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1467  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1468  *
1469  * @pre This method can be called if @p scip is in one of the following stages:
1470  * - \ref SCIP_STAGE_TRANSFORMING
1471  * - \ref SCIP_STAGE_TRANSFORMED
1472  * - \ref SCIP_STAGE_INITPRESOLVE
1473  * - \ref SCIP_STAGE_PRESOLVING
1474  * - \ref SCIP_STAGE_EXITPRESOLVE
1475  * - \ref SCIP_STAGE_PRESOLVED
1476  * - \ref SCIP_STAGE_INITSOLVE
1477  * - \ref SCIP_STAGE_SOLVING
1478  * - \ref SCIP_STAGE_SOLVED
1479  * - \ref SCIP_STAGE_EXITSOLVE
1480  * - \ref SCIP_STAGE_FREETRANS
1481  */
1483  SCIP* scip, /**< SCIP data structure */
1484  int nvars, /**< number of variables to get transformed variables for */
1485  SCIP_VAR** vars, /**< array with variables to get transformed variables for */
1486  SCIP_VAR** transvars /**< array to store the transformed variables */
1487  )
1488 {
1489  int v;
1490 
1491  assert(nvars == 0 || vars != NULL);
1492  assert(nvars == 0 || transvars != NULL);
1493 
1494  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetTransformedVars", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1495 
1496  for( v = 0; v < nvars; ++v )
1497  {
1498  if( SCIPvarIsTransformed(vars[v]) )
1499  transvars[v] = vars[v];
1500  else
1501  {
1502  SCIP_CALL( SCIPvarGetTransformed(vars[v], scip->mem->probmem, scip->set, scip->stat, &transvars[v]) );
1503  }
1504  }
1505 
1506  return SCIP_OKAY;
1507 }
1508 
1509 /** gets negated variable x' = lb + ub - x of variable x; negated variable is created, if not yet existing;
1510  * in difference to \ref SCIPcreateVar, the negated variable must not be released (unless captured explicitly)
1511  *
1512  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1513  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1514  *
1515  * @pre This method can be called if @p scip is in one of the following stages:
1516  * - \ref SCIP_STAGE_PROBLEM
1517  * - \ref SCIP_STAGE_TRANSFORMING
1518  * - \ref SCIP_STAGE_TRANSFORMED
1519  * - \ref SCIP_STAGE_INITPRESOLVE
1520  * - \ref SCIP_STAGE_PRESOLVING
1521  * - \ref SCIP_STAGE_EXITPRESOLVE
1522  * - \ref SCIP_STAGE_PRESOLVED
1523  * - \ref SCIP_STAGE_INITSOLVE
1524  * - \ref SCIP_STAGE_SOLVING
1525  * - \ref SCIP_STAGE_SOLVED
1526  * - \ref SCIP_STAGE_EXITSOLVE
1527  * - \ref SCIP_STAGE_FREETRANS
1528  */
1530  SCIP* scip, /**< SCIP data structure */
1531  SCIP_VAR* var, /**< variable to get negated variable for */
1532  SCIP_VAR** negvar /**< pointer to store the negated variable */
1533  )
1534 {
1535  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNegatedVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1536  assert( var->scip == scip );
1537 
1538  SCIP_CALL( SCIPvarNegate(var, scip->mem->probmem, scip->set, scip->stat, negvar) );
1539 
1540  return SCIP_OKAY;
1541 }
1542 
1543 /** gets negated variables x' = lb + ub - x of variables x; negated variables are created, if not yet existing
1544  *
1545  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1546  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1547  *
1548  * @pre This method can be called if @p scip is in one of the following stages:
1549  * - \ref SCIP_STAGE_PROBLEM
1550  * - \ref SCIP_STAGE_TRANSFORMING
1551  * - \ref SCIP_STAGE_TRANSFORMED
1552  * - \ref SCIP_STAGE_INITPRESOLVE
1553  * - \ref SCIP_STAGE_PRESOLVING
1554  * - \ref SCIP_STAGE_EXITPRESOLVE
1555  * - \ref SCIP_STAGE_PRESOLVED
1556  * - \ref SCIP_STAGE_INITSOLVE
1557  * - \ref SCIP_STAGE_SOLVING
1558  * - \ref SCIP_STAGE_SOLVED
1559  * - \ref SCIP_STAGE_EXITSOLVE
1560  * - \ref SCIP_STAGE_FREETRANS
1561  */
1563  SCIP* scip, /**< SCIP data structure */
1564  int nvars, /**< number of variables to get negated variables for */
1565  SCIP_VAR** vars, /**< array of variables to get negated variables for */
1566  SCIP_VAR** negvars /**< array to store the negated variables */
1567  )
1568 {
1569  int v;
1570 
1571  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNegatedVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1572 
1573  for( v = 0; v < nvars; ++v )
1574  {
1575  SCIP_CALL( SCIPvarNegate(vars[v], scip->mem->probmem, scip->set, scip->stat, &(negvars[v])) );
1576  }
1577 
1578  return SCIP_OKAY;
1579 }
1580 
1581 /** gets a binary variable that is equal to the given binary variable, and that is either active, fixed, or
1582  * multi-aggregated, or the negated variable of an active, fixed, or multi-aggregated variable
1583  *
1584  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1585  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1586  *
1587  * @pre This method can be called if @p scip is in one of the following stages:
1588  * - \ref SCIP_STAGE_PROBLEM
1589  * - \ref SCIP_STAGE_TRANSFORMED
1590  * - \ref SCIP_STAGE_INITPRESOLVE
1591  * - \ref SCIP_STAGE_PRESOLVING
1592  * - \ref SCIP_STAGE_EXITPRESOLVE
1593  * - \ref SCIP_STAGE_PRESOLVED
1594  * - \ref SCIP_STAGE_INITSOLVE
1595  * - \ref SCIP_STAGE_SOLVING
1596  * - \ref SCIP_STAGE_SOLVED
1597  * - \ref SCIP_STAGE_EXITSOLVE
1598  */
1600  SCIP* scip, /**< SCIP data structure */
1601  SCIP_VAR* var, /**< binary variable to get binary representative for */
1602  SCIP_VAR** repvar, /**< pointer to store the binary representative */
1603  SCIP_Bool* negated /**< pointer to store whether the negation of an active variable was returned */
1604  )
1605 {
1606  assert(scip != NULL);
1607  assert(var != NULL);
1608  assert(repvar != NULL);
1609  assert(negated != NULL);
1610  assert(var->scip == scip);
1611 
1612  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetBinvarRepresentative", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1613 
1614  /* get the active representative of the given variable */
1615  *repvar = var;
1616  *negated = FALSE;
1617  SCIP_CALL( SCIPvarGetProbvarBinary(repvar, negated) );
1618 
1619  /* negate the representative, if it corresponds to the negation of the given variable */
1620  if( *negated )
1621  {
1622  SCIP_CALL( SCIPgetNegatedVar(scip, *repvar, repvar) );
1623  }
1624 
1625  return SCIP_OKAY;
1626 }
1627 
1628 /** gets binary variables that are equal to the given binary variables, and which are either active, fixed, or
1629  * multi-aggregated, or the negated variables of active, fixed, or multi-aggregated variables
1630  *
1631  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1632  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1633  *
1634  * @pre This method can be called if @p scip is in one of the following stages:
1635  * - \ref SCIP_STAGE_PROBLEM
1636  * - \ref SCIP_STAGE_TRANSFORMED
1637  * - \ref SCIP_STAGE_INITPRESOLVE
1638  * - \ref SCIP_STAGE_PRESOLVING
1639  * - \ref SCIP_STAGE_EXITPRESOLVE
1640  * - \ref SCIP_STAGE_PRESOLVED
1641  * - \ref SCIP_STAGE_INITSOLVE
1642  * - \ref SCIP_STAGE_SOLVING
1643  * - \ref SCIP_STAGE_SOLVED
1644  * - \ref SCIP_STAGE_EXITSOLVE
1645  */
1647  SCIP* scip, /**< SCIP data structure */
1648  int nvars, /**< number of binary variables to get representatives for */
1649  SCIP_VAR** vars, /**< binary variables to get binary representatives for */
1650  SCIP_VAR** repvars, /**< array to store the binary representatives */
1651  SCIP_Bool* negated /**< array to store whether the negation of an active variable was returned */
1652  )
1653 {
1654  int v;
1655 
1656  assert(scip != NULL);
1657  assert(vars != NULL || nvars == 0);
1658  assert(repvars != NULL || nvars == 0);
1659  assert(negated != NULL || nvars == 0);
1660 
1661  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetBinvarRepresentatives", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1662 
1663  if( nvars == 0 )
1664  return SCIP_OKAY;
1665 
1666  /* get the active representative of the given variable */
1667  BMScopyMemoryArray(repvars, vars, nvars);
1668  BMSclearMemoryArray(negated, nvars);
1669  SCIP_CALL( SCIPvarsGetProbvarBinary(&repvars, &negated, nvars) );
1670 
1671  /* negate the representatives, if they correspond to the negation of the given variables */
1672  for( v = nvars - 1; v >= 0; --v )
1673  if( negated[v] )
1674  {
1675  SCIP_CALL( SCIPgetNegatedVar(scip, repvars[v], &(repvars[v])) );
1676  }
1677 
1678  return SCIP_OKAY;
1679 }
1680 
1681 /** flattens aggregation graph of multi-aggregated variable in order to avoid exponential recursion later on
1682  *
1683  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1684  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1685  *
1686  * @pre This method can be called if @p scip is in one of the following stages:
1687  * - \ref SCIP_STAGE_INITPRESOLVE
1688  * - \ref SCIP_STAGE_PRESOLVING
1689  * - \ref SCIP_STAGE_EXITPRESOLVE
1690  * - \ref SCIP_STAGE_PRESOLVED
1691  * - \ref SCIP_STAGE_INITSOLVE
1692  * - \ref SCIP_STAGE_SOLVING
1693  * - \ref SCIP_STAGE_SOLVED
1694  */
1696  SCIP* scip, /**< SCIP data structure */
1697  SCIP_VAR* var /**< problem variable */
1698  )
1699 {
1700  assert( scip != NULL );
1701  assert( var != NULL );
1702  SCIP_CALL( SCIPcheckStage(scip, "SCIPflattenVarAggregationGraph", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
1703 
1704  SCIP_CALL( SCIPvarFlattenAggregationGraph(var, scip->mem->probmem, scip->set, scip->eventqueue) );
1705 
1706  return SCIP_OKAY;
1707 }
1708 
1709 /** Transforms a given linear sum of variables, that is a_1*x_1 + ... + a_n*x_n + c into a corresponding linear sum of
1710  * active variables, that is b_1*y_1 + ... + b_m*y_m + d.
1711  *
1712  * If the number of needed active variables is greater than the available slots in the variable array, nothing happens
1713  * except that the required size is stored in the corresponding variable (requiredsize). Otherwise, the active variable
1714  * representation is stored in the variable array, scalar array and constant.
1715  *
1716  * The reason for this approach is that we cannot reallocate memory, since we do not know how the memory has been
1717  * allocated (e.g., by a C++ 'new' or SCIP functions).
1718  *
1719  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1720  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1721  *
1722  * @pre This method can be called if @p scip is in one of the following stages:
1723  * - \ref SCIP_STAGE_TRANSFORMED
1724  * - \ref SCIP_STAGE_INITPRESOLVE
1725  * - \ref SCIP_STAGE_PRESOLVING
1726  * - \ref SCIP_STAGE_EXITPRESOLVE
1727  * - \ref SCIP_STAGE_PRESOLVED
1728  * - \ref SCIP_STAGE_INITSOLVE
1729  * - \ref SCIP_STAGE_SOLVING
1730  * - \ref SCIP_STAGE_SOLVED
1731  * - \ref SCIP_STAGE_EXITSOLVE
1732  * - \ref SCIP_STAGE_FREETRANS
1733  *
1734  * @note The resulting linear sum is stored into the given variable array, scalar array, and constant. That means the
1735  * given entries are overwritten.
1736  *
1737  * @note That method can be used to convert a single variables into variable space of active variables. Therefore call
1738  * the method with the linear sum 1.0*x + 0.0.
1739  */
1741  SCIP* scip, /**< SCIP data structure */
1742  SCIP_VAR** vars, /**< variable array x_1, ..., x_n in the linear sum which will be
1743  * overwritten by the variable array y_1, ..., y_m in the linear sum
1744  * w.r.t. active variables */
1745  SCIP_Real* scalars, /**< scalars a_1, ..., a_n in linear sum which will be overwritten to the
1746  * scalars b_1, ..., b_m in the linear sum of the active variables */
1747  int* nvars, /**< pointer to number of variables in the linear sum which will be
1748  * overwritten by the number of variables in the linear sum corresponding
1749  * to the active variables */
1750  int varssize, /**< available slots in vars and scalars array which is needed to check if
1751  * the array are large enough for the linear sum w.r.t. active
1752  * variables */
1753  SCIP_Real* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c which
1754  * will chnage to constant d in the linear sum b_1*y_1 + ... + b_m*y_m +
1755  * d w.r.t. the active variables */
1756  int* requiredsize, /**< pointer to store the required array size for the linear sum w.r.t. the
1757  * active variables */
1758  SCIP_Bool mergemultiples /**< should multiple occurrences of a var be replaced by a single coeff? */
1759  )
1760 {
1761  assert( scip != NULL );
1762  assert( nvars != NULL );
1763  assert( vars != NULL || *nvars == 0 );
1764  assert( scalars != NULL || *nvars == 0 );
1765  assert( constant != NULL );
1766  assert( requiredsize != NULL );
1767  assert( *nvars <= varssize );
1768 
1769  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetProbvarLinearSum", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1770  SCIP_CALL( SCIPvarGetActiveRepresentatives(scip->set, vars, scalars, nvars, varssize, constant, requiredsize, mergemultiples) );
1771 
1772  return SCIP_OKAY;
1773 }
1774 
1775 /** transforms given variable, scalar and constant to the corresponding active, fixed, or
1776  * multi-aggregated variable, scalar and constant; if the variable resolves to a fixed variable,
1777  * "scalar" will be 0.0 and the value of the sum will be stored in "constant"; a multi-aggregation
1778  * with only one active variable (this can happen due to fixings after the multi-aggregation),
1779  * is treated like an aggregation; if the multi-aggregation constant is infinite, "scalar" will be 0.0
1780  *
1781  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1782  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1783  *
1784  * @pre This method can be called if @p scip is in one of the following stages:
1785  * - \ref SCIP_STAGE_TRANSFORMED
1786  * - \ref SCIP_STAGE_INITPRESOLVE
1787  * - \ref SCIP_STAGE_PRESOLVING
1788  * - \ref SCIP_STAGE_EXITPRESOLVE
1789  * - \ref SCIP_STAGE_PRESOLVED
1790  * - \ref SCIP_STAGE_INITSOLVE
1791  * - \ref SCIP_STAGE_SOLVING
1792  * - \ref SCIP_STAGE_SOLVED
1793  * - \ref SCIP_STAGE_EXITSOLVE
1794  * - \ref SCIP_STAGE_FREETRANS
1795  */
1797  SCIP* scip, /**< SCIP data structure */
1798  SCIP_VAR** var, /**< pointer to problem variable x in sum a*x + c */
1799  SCIP_Real* scalar, /**< pointer to scalar a in sum a*x + c */
1800  SCIP_Real* constant /**< pointer to constant c in sum a*x + c */
1801  )
1802 {
1803  assert(scip != NULL);
1804  assert(var != NULL);
1805  assert(scalar != NULL);
1806  assert(constant != NULL);
1807 
1808  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetProbvarSum", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1809  SCIP_CALL( SCIPvarGetProbvarSum(var, scip->set, scalar, constant) );
1810 
1811  return SCIP_OKAY;
1812 }
1813 
1814 /** return for given variables all their active counterparts; all active variables will be pairwise different
1815  * @note It does not hold that the first output variable is the active variable for the first input variable.
1816  *
1817  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1818  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1819  *
1820  * @pre This method can be called if @p scip is in one of the following stages:
1821  * - \ref SCIP_STAGE_TRANSFORMED
1822  * - \ref SCIP_STAGE_INITPRESOLVE
1823  * - \ref SCIP_STAGE_PRESOLVING
1824  * - \ref SCIP_STAGE_EXITPRESOLVE
1825  * - \ref SCIP_STAGE_PRESOLVED
1826  * - \ref SCIP_STAGE_INITSOLVE
1827  * - \ref SCIP_STAGE_SOLVING
1828  * - \ref SCIP_STAGE_SOLVED
1829  * - \ref SCIP_STAGE_EXITSOLVE
1830  * - \ref SCIP_STAGE_FREETRANS
1831  */
1833  SCIP* scip, /**< SCIP data structure */
1834  SCIP_VAR** vars, /**< variable array with given variables and as output all active
1835  * variables, if enough slots exist
1836  */
1837  int* nvars, /**< number of given variables, and as output number of active variables,
1838  * if enough slots exist
1839  */
1840  int varssize, /**< available slots in vars array */
1841  int* requiredsize /**< pointer to store the required array size for the active variables */
1842  )
1843 {
1844  assert(scip != NULL);
1845  assert(nvars != NULL);
1846  assert(vars != NULL || *nvars == 0);
1847  assert(varssize >= *nvars);
1848  assert(requiredsize != NULL);
1849 
1850  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetActiveVars", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1851  SCIP_CALL( SCIPvarsGetActiveVars(scip->set, vars, nvars, varssize, requiredsize) );
1852 
1853  return SCIP_OKAY;
1854 }
1855 
1856 /** returns the reduced costs of the variable in the current node's LP relaxation;
1857  * the current node has to have a feasible LP.
1858  *
1859  * returns SCIP_INVALID if the variable is active but not in the current LP;
1860  * returns 0 if the variable has been aggregated out or fixed in presolving.
1861  *
1862  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1863  *
1864  * @note The return value of this method should be used carefully if the dual feasibility check was explictely disabled.
1865  */
1867  SCIP* scip, /**< SCIP data structure */
1868  SCIP_VAR* var /**< variable to get reduced costs, should be a column in current node LP */
1869  )
1870 {
1871  assert( scip != NULL );
1872  assert( var != NULL );
1873  assert( var->scip == scip );
1874 
1875  switch( SCIPvarGetStatus(var) )
1876  {
1878  if( var->data.original.transvar == NULL )
1879  return SCIP_INVALID;
1880  return SCIPgetVarRedcost(scip, var->data.original.transvar);
1881 
1882  case SCIP_VARSTATUS_COLUMN:
1883  return SCIPgetColRedcost(scip, SCIPvarGetCol(var));
1884 
1885  case SCIP_VARSTATUS_LOOSE:
1886  return SCIP_INVALID;
1887 
1888  case SCIP_VARSTATUS_FIXED:
1892  return 0.0;
1893 
1894  default:
1895  SCIPerrorMessage("unknown variable status\n");
1896  SCIPABORT();
1897  return 0.0; /*lint !e527*/
1898  }
1899 }
1900 
1901 /** returns the implied reduced costs of the variable in the current node's LP relaxation;
1902  * the current node has to have a feasible LP.
1903  *
1904  * returns SCIP_INVALID if the variable is active but not in the current LP;
1905  * returns 0 if the variable has been aggregated out or fixed in presolving.
1906  *
1907  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1908  *
1909  * @note The return value of this method should be used carefully if the dual feasibility check was explictely disabled.
1910  */
1912  SCIP* scip, /**< SCIP data structure */
1913  SCIP_VAR* var, /**< variable to get reduced costs, should be a column in current node LP */
1914  SCIP_Bool varfixing /**< FALSE if for x == 0, TRUE for x == 1 */
1915  )
1916 {
1917  assert( scip != NULL );
1918  assert( var != NULL );
1919  assert( var->scip == scip );
1920 
1921  switch( SCIPvarGetStatus(var) )
1922  {
1924  if( var->data.original.transvar == NULL )
1925  return SCIP_INVALID;
1926  return SCIPgetVarImplRedcost(scip, var->data.original.transvar, varfixing);
1927 
1928  case SCIP_VARSTATUS_COLUMN:
1929  return SCIPvarGetImplRedcost(var, scip->set, varfixing, scip->stat, scip->transprob, scip->lp);
1930 
1931  case SCIP_VARSTATUS_LOOSE:
1932  return SCIP_INVALID;
1933 
1934  case SCIP_VARSTATUS_FIXED:
1938  return 0.0;
1939 
1940  default:
1941  SCIPerrorMessage("unknown variable status\n");
1942  SCIPABORT();
1943  return 0.0; /*lint !e527*/
1944  }
1945 }
1946 
1947 
1948 /** returns the Farkas coefficient of the variable in the current node's LP relaxation;
1949  * the current node has to have an infeasible LP.
1950  *
1951  * returns SCIP_INVALID if the variable is active but not in the current LP;
1952  * returns 0 if the variable has been aggregated out or fixed in presolving.
1953  *
1954  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1955  */
1957  SCIP* scip, /**< SCIP data structure */
1958  SCIP_VAR* var /**< variable to get reduced costs, should be a column in current node LP */
1959  )
1960 {
1961  assert(scip != NULL);
1962  assert(var != NULL);
1963  assert(var->scip == scip);
1964 
1965  switch( SCIPvarGetStatus(var) )
1966  {
1968  if( var->data.original.transvar == NULL )
1969  return SCIP_INVALID;
1970  return SCIPgetVarFarkasCoef(scip,var->data.original.transvar);
1971 
1972  case SCIP_VARSTATUS_COLUMN:
1973  return SCIPgetColFarkasCoef(scip,SCIPvarGetCol(var));
1974 
1975  case SCIP_VARSTATUS_LOOSE:
1976  return SCIP_INVALID;
1977 
1978  case SCIP_VARSTATUS_FIXED:
1982  return 0.0;
1983 
1984  default:
1985  SCIPerrorMessage("unknown variable status\n");
1986  SCIPABORT();
1987  return 0.0; /*lint !e527*/
1988  }
1989 }
1990 
1991 /** returns lower bound of variable directly before or after the bound change given by the bound change index
1992  * was applied
1993  */
1995  SCIP* scip, /**< SCIP data structure */
1996  SCIP_VAR* var, /**< problem variable */
1997  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
1998  SCIP_Bool after /**< should the bound change with given index be included? */
1999  )
2000 {
2001  SCIP_VARSTATUS varstatus;
2002  SCIP_BDCHGINFO* bdchginfo;
2003  assert(var != NULL);
2004 
2005  varstatus = SCIPvarGetStatus(var);
2006 
2007  /* get bounds of attached variables */
2008  switch( varstatus )
2009  {
2011  assert(var->data.original.transvar != NULL);
2012  return SCIPgetVarLbAtIndex(scip, var->data.original.transvar, bdchgidx, after);
2013 
2014  case SCIP_VARSTATUS_COLUMN:
2015  case SCIP_VARSTATUS_LOOSE:
2016  if( bdchgidx == NULL )
2017  return SCIPvarGetLbLocal(var);
2018  else
2019  {
2020  bdchginfo = SCIPvarGetLbchgInfo(var, bdchgidx, after);
2021  if( bdchginfo != NULL )
2022  return SCIPbdchginfoGetNewbound(bdchginfo);
2023  else
2024  return var->glbdom.lb;
2025  }
2026 
2027  case SCIP_VARSTATUS_FIXED:
2028  return var->glbdom.lb;
2029 
2030  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c -> y = (x-c)/a */
2031  assert(var->data.aggregate.var != NULL);
2032  if( var->data.aggregate.scalar > 0.0 )
2033  {
2034  SCIP_Real lb;
2035 
2036  lb = SCIPgetVarLbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2037 
2038  /* a > 0 -> get lower bound of y */
2039  if( SCIPisInfinity(scip, -lb) )
2040  return -SCIPinfinity(scip);
2041  else if( SCIPisInfinity(scip, lb) )
2042  return SCIPinfinity(scip);
2043  else
2044  return var->data.aggregate.scalar * lb + var->data.aggregate.constant;
2045  }
2046  else if( var->data.aggregate.scalar < 0.0 )
2047  {
2048  SCIP_Real ub;
2049 
2050  ub = SCIPgetVarUbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2051 
2052  /* a < 0 -> get upper bound of y */
2053  if( SCIPisInfinity(scip, -ub) )
2054  return SCIPinfinity(scip);
2055  else if( SCIPisInfinity(scip, ub) )
2056  return -SCIPinfinity(scip);
2057  else
2058  return var->data.aggregate.scalar * ub + var->data.aggregate.constant;
2059  }
2060  else
2061  {
2062  SCIPerrorMessage("scalar is zero in aggregation\n");
2063  SCIPABORT();
2064  return SCIP_INVALID; /*lint !e527*/
2065  }
2066 
2068  /* handle multi-aggregated variables depending on one variable only (possibly caused by SCIPvarFlattenAggregationGraph()) */
2069  if ( var->data.multaggr.nvars == 1 )
2070  {
2071  assert(var->data.multaggr.vars != NULL);
2072  assert(var->data.multaggr.scalars != NULL);
2073  assert(var->data.multaggr.vars[0] != NULL);
2074 
2075  if( var->data.multaggr.scalars[0] > 0.0 )
2076  {
2077  SCIP_Real lb;
2078 
2079  lb = SCIPgetVarLbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2080 
2081  /* a > 0 -> get lower bound of y */
2082  if( SCIPisInfinity(scip, -lb) )
2083  return -SCIPinfinity(scip);
2084  else if( SCIPisInfinity(scip, lb) )
2085  return SCIPinfinity(scip);
2086  else
2087  return var->data.multaggr.scalars[0] * lb + var->data.multaggr.constant;
2088  }
2089  else if( var->data.multaggr.scalars[0] < 0.0 )
2090  {
2091  SCIP_Real ub;
2092 
2093  ub = SCIPgetVarUbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2094 
2095  /* a < 0 -> get upper bound of y */
2096  if( SCIPisInfinity(scip, -ub) )
2097  return SCIPinfinity(scip);
2098  else if( SCIPisInfinity(scip, ub) )
2099  return -SCIPinfinity(scip);
2100  else
2101  return var->data.multaggr.scalars[0] * ub + var->data.multaggr.constant;
2102  }
2103  else
2104  {
2105  SCIPerrorMessage("scalar is zero in multi-aggregation\n");
2106  SCIPABORT();
2107  return SCIP_INVALID; /*lint !e527*/
2108  }
2109  }
2110  SCIPerrorMessage("cannot get the bounds of a multi-aggregated variable.\n");
2111  SCIPABORT();
2112  return SCIP_INVALID; /*lint !e527*/
2113 
2114  case SCIP_VARSTATUS_NEGATED: /* x' = offset - x -> x = offset - x' */
2115  assert(var->negatedvar != NULL);
2117  assert(var->negatedvar->negatedvar == var);
2118  return var->data.negate.constant - SCIPgetVarUbAtIndex(scip, var->negatedvar, bdchgidx, after);
2119 
2120  default:
2121  SCIPerrorMessage("unknown variable status\n");
2122  SCIPABORT();
2123  return SCIP_INVALID; /*lint !e527*/
2124  }
2125 }
2126 
2127 /** returns upper bound of variable directly before or after the bound change given by the bound change index
2128  * was applied
2129  */
2131  SCIP* scip, /**< SCIP data structure */
2132  SCIP_VAR* var, /**< problem variable */
2133  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2134  SCIP_Bool after /**< should the bound change with given index be included? */
2135  )
2136 {
2137  SCIP_VARSTATUS varstatus;
2138  SCIP_BDCHGINFO* bdchginfo;
2139  assert(var != NULL);
2140 
2141  varstatus = SCIPvarGetStatus(var);
2142 
2143  /* get bounds of attached variables */
2144  switch( varstatus )
2145  {
2147  assert(var->data.original.transvar != NULL);
2148  return SCIPgetVarUbAtIndex(scip, var->data.original.transvar, bdchgidx, after);
2149 
2150  case SCIP_VARSTATUS_COLUMN:
2151  case SCIP_VARSTATUS_LOOSE:
2152  if( bdchgidx == NULL )
2153  return SCIPvarGetUbLocal(var);
2154  else
2155  {
2156  bdchginfo = SCIPvarGetUbchgInfo(var, bdchgidx, after);
2157  if( bdchginfo != NULL )
2158  return SCIPbdchginfoGetNewbound(bdchginfo);
2159  else
2160  return var->glbdom.ub;
2161  }
2162 
2163  case SCIP_VARSTATUS_FIXED:
2164  return var->glbdom.ub;
2165 
2166  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c -> y = (x-c)/a */
2167  assert(var->data.aggregate.var != NULL);
2168  if( var->data.aggregate.scalar > 0.0 )
2169  {
2170  SCIP_Real ub;
2171 
2172  ub = SCIPgetVarUbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2173 
2174  /* a > 0 -> get lower bound of y */
2175  if( SCIPisInfinity(scip, -ub) )
2176  return -SCIPinfinity(scip);
2177  else if( SCIPisInfinity(scip, ub) )
2178  return SCIPinfinity(scip);
2179  else
2180  return var->data.aggregate.scalar * ub + var->data.aggregate.constant;
2181  }
2182  else if( var->data.aggregate.scalar < 0.0 )
2183  {
2184  SCIP_Real lb;
2185 
2186  lb = SCIPgetVarLbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2187 
2188  /* a < 0 -> get upper bound of y */
2189  if ( SCIPisInfinity(scip, -lb) )
2190  return SCIPinfinity(scip);
2191  else if ( SCIPisInfinity(scip, lb) )
2192  return -SCIPinfinity(scip);
2193  else
2194  return var->data.aggregate.scalar * lb + var->data.aggregate.constant;
2195  }
2196  else
2197  {
2198  SCIPerrorMessage("scalar is zero in aggregation\n");
2199  SCIPABORT();
2200  return SCIP_INVALID; /*lint !e527*/
2201  }
2202 
2204  /* handle multi-aggregated variables depending on one variable only (possibly caused by SCIPvarFlattenAggregationGraph()) */
2205  if ( var->data.multaggr.nvars == 1 )
2206  {
2207  assert(var->data.multaggr.vars != NULL);
2208  assert(var->data.multaggr.scalars != NULL);
2209  assert(var->data.multaggr.vars[0] != NULL);
2210 
2211  if( var->data.multaggr.scalars[0] > 0.0 )
2212  {
2213  SCIP_Real ub;
2214 
2215  ub = SCIPgetVarUbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2216 
2217  /* a > 0 -> get lower bound of y */
2218  if ( SCIPisInfinity(scip, -ub) )
2219  return -SCIPinfinity(scip);
2220  else if ( SCIPisInfinity(scip, ub) )
2221  return SCIPinfinity(scip);
2222  else
2223  return var->data.multaggr.scalars[0] * ub + var->data.multaggr.constant;
2224  }
2225  else if( var->data.multaggr.scalars[0] < 0.0 )
2226  {
2227  SCIP_Real lb;
2228 
2229  lb = SCIPgetVarLbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2230 
2231  /* a < 0 -> get upper bound of y */
2232  if ( SCIPisInfinity(scip, -lb) )
2233  return SCIPinfinity(scip);
2234  else if ( SCIPisInfinity(scip, lb) )
2235  return -SCIPinfinity(scip);
2236  else
2237  return var->data.multaggr.scalars[0] * lb + var->data.multaggr.constant;
2238  }
2239  else
2240  {
2241  SCIPerrorMessage("scalar is zero in multi-aggregation\n");
2242  SCIPABORT();
2243  return SCIP_INVALID; /*lint !e527*/
2244  }
2245  }
2246  SCIPerrorMessage("cannot get the bounds of a multiple aggregated variable.\n");
2247  SCIPABORT();
2248  return SCIP_INVALID; /*lint !e527*/
2249 
2250  case SCIP_VARSTATUS_NEGATED: /* x' = offset - x -> x = offset - x' */
2251  assert(var->negatedvar != NULL);
2253  assert(var->negatedvar->negatedvar == var);
2254  return var->data.negate.constant - SCIPgetVarLbAtIndex(scip, var->negatedvar, bdchgidx, after);
2255 
2256  default:
2257  SCIPerrorMessage("unknown variable status\n");
2258  SCIPABORT();
2259  return SCIP_INVALID; /*lint !e527*/
2260  }
2261 }
2262 
2263 /** returns lower or upper bound of variable directly before or after the bound change given by the bound change index
2264  * was applied
2265  */
2267  SCIP* scip, /**< SCIP data structure */
2268  SCIP_VAR* var, /**< problem variable */
2269  SCIP_BOUNDTYPE boundtype, /**< type of bound: lower or upper bound */
2270  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2271  SCIP_Bool after /**< should the bound change with given index be included? */
2272  )
2273 {
2274  if( boundtype == SCIP_BOUNDTYPE_LOWER )
2275  return SCIPgetVarLbAtIndex(scip, var, bdchgidx, after);
2276  else
2277  {
2278  assert(boundtype == SCIP_BOUNDTYPE_UPPER);
2279  return SCIPgetVarUbAtIndex(scip, var, bdchgidx, after);
2280  }
2281 }
2282 
2283 /** returns whether the binary variable was fixed at the time given by the bound change index */
2285  SCIP* scip, /**< SCIP data structure */
2286  SCIP_VAR* var, /**< problem variable */
2287  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2288  SCIP_Bool after /**< should the bound change with given index be included? */
2289  )
2290 {
2291  assert(var != NULL);
2292  assert(SCIPvarIsBinary(var));
2293 
2294  /* check the current bounds first in order to decide at which bound change information we have to look
2295  * (which is expensive because we have to follow the aggregation tree to the active variable)
2296  */
2297  return ((SCIPvarGetLbLocal(var) > 0.5 && SCIPgetVarLbAtIndex(scip, var, bdchgidx, after) > 0.5)
2298  || (SCIPvarGetUbLocal(var) < 0.5 && SCIPgetVarUbAtIndex(scip, var, bdchgidx, after) < 0.5));
2299 }
2300 
2301 /** gets solution value for variable in current node
2302  *
2303  * @return solution value for variable in current node
2304  *
2305  * @pre This method can be called if @p scip is in one of the following stages:
2306  * - \ref SCIP_STAGE_PRESOLVED
2307  * - \ref SCIP_STAGE_SOLVING
2308  */
2310  SCIP* scip, /**< SCIP data structure */
2311  SCIP_VAR* var /**< variable to get solution value for */
2312  )
2313 {
2315  assert( var->scip == scip );
2316 
2317  return SCIPvarGetSol(var, SCIPtreeHasCurrentNodeLP(scip->tree));
2318 }
2319 
2320 /** gets solution values of multiple variables in current node
2321  *
2322  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2323  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2324  *
2325  * @pre This method can be called if @p scip is in one of the following stages:
2326  * - \ref SCIP_STAGE_PRESOLVED
2327  * - \ref SCIP_STAGE_SOLVING
2328  */
2330  SCIP* scip, /**< SCIP data structure */
2331  int nvars, /**< number of variables to get solution value for */
2332  SCIP_VAR** vars, /**< array with variables to get value for */
2333  SCIP_Real* vals /**< array to store solution values of variables */
2334  )
2335 {
2336  int v;
2337 
2338  assert(nvars == 0 || vars != NULL);
2339  assert(nvars == 0 || vals != NULL);
2340 
2341  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarSols", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2342 
2343  if( SCIPtreeHasCurrentNodeLP(scip->tree) )
2344  {
2345  for( v = 0; v < nvars; ++v )
2346  vals[v] = SCIPvarGetLPSol(vars[v]);
2347  }
2348  else
2349  {
2350  for( v = 0; v < nvars; ++v )
2351  vals[v] = SCIPvarGetPseudoSol(vars[v]);
2352  }
2353 
2354  return SCIP_OKAY;
2355 }
2356 
2357 /** sets the solution value of all variables in the global relaxation solution to zero
2358  *
2359  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2360  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2361  *
2362  * @pre This method can be called if @p scip is in one of the following stages:
2363  * - \ref SCIP_STAGE_PRESOLVED
2364  * - \ref SCIP_STAGE_SOLVING
2365  */
2367  SCIP* scip, /**< SCIP data structure */
2368  SCIP_RELAX* relax /**< relaxator data structure */
2369  )
2370 {
2371  SCIP_VAR** vars;
2372  int nvars;
2373  int v;
2374 
2375  assert(scip != NULL);
2376 
2377  SCIP_CALL( SCIPcheckStage(scip, "SCIPclearRelaxSolVals", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2378 
2379  /* update the responsible relax pointer */
2380  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2381 
2382  /* the relaxation solution is already cleared */
2383  if( SCIPrelaxationIsSolZero(scip->relaxation) )
2384  return SCIP_OKAY;
2385 
2386  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
2387 
2388  for( v = 0; v < nvars; v++ )
2389  {
2390  SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, 0.0, FALSE) );
2391  }
2392 
2393  SCIPrelaxationSetSolObj(scip->relaxation, 0.0);
2395 
2396  return SCIP_OKAY;
2397 }
2398 
2399 /** sets the value of the given variable in the global relaxation solution;
2400  * this solution can be filled by the relaxation handlers and can be used by heuristics and for separation;
2401  * You can use SCIPclearRelaxSolVals() to set all values to zero, initially;
2402  * after setting all solution values, you have to call SCIPmarkRelaxSolValid()
2403  * to inform SCIP that the stored solution is valid
2404  *
2405  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2406  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2407  *
2408  * @pre This method can be called if @p scip is in one of the following stages:
2409  * - \ref SCIP_STAGE_PRESOLVED
2410  * - \ref SCIP_STAGE_SOLVING
2411  *
2412  * @note This method incrementally updates the objective value of the relaxation solution. If the whole solution
2413  * should be updated, using SCIPsetRelaxSolVals() instead or calling SCIPclearRelaxSolVals() before setting
2414  * the first value to reset the solution and the objective value to 0 may help the numerics.
2415  */
2417  SCIP* scip, /**< SCIP data structure */
2418  SCIP_RELAX* relax, /**< relaxator data structure */
2419  SCIP_VAR* var, /**< variable to set value for */
2420  SCIP_Real val /**< solution value of variable */
2421  )
2422 {
2423  assert(scip != NULL);
2424 
2425  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolVal", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2426 
2427  SCIP_CALL( SCIPvarSetRelaxSol(var, scip->set, scip->relaxation, val, TRUE) );
2428 
2429  if( val != 0.0 )
2432  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2433 
2434  return SCIP_OKAY;
2435 }
2436 
2437 /** sets the values of the given variables in the global relaxation solution and informs SCIP about the validity
2438  * and whether the solution can be enforced via linear cuts;
2439  * this solution can be filled by the relaxation handlers and can be used by heuristics and for separation;
2440  * the solution is automatically cleared, s.t. all other variables get value 0.0
2441  *
2442  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2443  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2444  *
2445  * @pre This method can be called if @p scip is in one of the following stages:
2446  * - \ref SCIP_STAGE_PRESOLVED
2447  * - \ref SCIP_STAGE_SOLVING
2448  */
2450  SCIP* scip, /**< SCIP data structure */
2451  SCIP_RELAX* relax, /**< relaxator data structure */
2452  int nvars, /**< number of variables to set relaxation solution value for */
2453  SCIP_VAR** vars, /**< array with variables to set value for */
2454  SCIP_Real* vals, /**< array with solution values of variables */
2455  SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2456  )
2457 {
2458  int v;
2459 
2460  assert(scip != NULL);
2461  assert(nvars == 0 || vars != NULL);
2462  assert(nvars == 0 || vals != NULL);
2463 
2464  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolVals", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2465 
2466  SCIP_CALL( SCIPclearRelaxSolVals(scip, relax) );
2467 
2468  for( v = 0; v < nvars; v++ )
2469  {
2470  SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, vals[v], TRUE) );
2471  }
2472 
2474  SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2475  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2476 
2477  return SCIP_OKAY;
2478 }
2479 
2480 /** sets the values of the variables in the global relaxation solution to the values in the given primal solution
2481  * and informs SCIP about the validity and whether the solution can be enforced via linear cuts;
2482  * the relaxation solution can be filled by the relaxation handlers and might be used by heuristics and for separation
2483  *
2484  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2485  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2486  *
2487  * @pre This method can be called if @p scip is in one of the following stages:
2488  * - \ref SCIP_STAGE_PRESOLVED
2489  * - \ref SCIP_STAGE_SOLVING
2490  */
2492  SCIP* scip, /**< SCIP data structure */
2493  SCIP_RELAX* relax, /**< relaxator data structure */
2494  SCIP_SOL* sol, /**< primal relaxation solution */
2495  SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2496  )
2497 {
2498  SCIP_VAR** vars;
2499  SCIP_Real* vals;
2500  int nvars;
2501  int v;
2502 
2503  assert(scip != NULL);
2504 
2505  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolValsSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2506 
2507  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
2508 
2509  /* alloc buffer array for solution values of the variables and get the values */
2510  SCIP_CALL( SCIPallocBufferArray(scip, &vals, nvars) );
2511  SCIP_CALL( SCIPgetSolVals(scip, sol, nvars, vars, vals) );
2512 
2513  SCIP_CALL( SCIPclearRelaxSolVals(scip, relax) );
2514 
2515  for( v = 0; v < nvars; v++ )
2516  {
2517  SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, vals[v], FALSE) );
2518  }
2519 
2520  SCIPrelaxationSetSolObj(scip->relaxation, SCIPsolGetObj(sol, scip->set, scip->transprob, scip->origprob));
2521 
2523  SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2524  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2525 
2526  SCIPfreeBufferArray(scip, &vals);
2527 
2528  return SCIP_OKAY;
2529 }
2530 
2531 /** returns whether the relaxation solution is valid
2532  *
2533  * @return TRUE, if the relaxation solution is valid; FALSE, otherwise
2534  *
2535  * @pre This method can be called if @p scip is in one of the following stages:
2536  * - \ref SCIP_STAGE_PRESOLVED
2537  * - \ref SCIP_STAGE_SOLVING
2538  */
2540  SCIP* scip /**< SCIP data structure */
2541  )
2542 {
2543  assert(scip != NULL);
2544 
2545  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisRelaxSolValid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2546 
2547  return SCIPrelaxationIsSolValid(scip->relaxation);
2548 }
2549 
2550 /** informs SCIP that the relaxation solution is valid and whether the relaxation can be enforced through linear cuts
2551  *
2552  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2553  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2554  *
2555  * @pre This method can be called if @p scip is in one of the following stages:
2556  * - \ref SCIP_STAGE_PRESOLVED
2557  * - \ref SCIP_STAGE_SOLVING
2558  */
2560  SCIP* scip, /**< SCIP data structure */
2561  SCIP_RELAX* relax, /**< relaxator data structure that set the current relaxation solution */
2562  SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2563  )
2564 {
2565  assert(scip != NULL);
2566 
2567  SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkRelaxSolValid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2568 
2569  SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2570  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2571 
2572  return SCIP_OKAY;
2573 }
2574 
2575 /** informs SCIP, that the relaxation solution is invalid
2576  *
2577  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2578  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2579  *
2580  * @pre This method can be called if @p scip is in one of the following stages:
2581  * - \ref SCIP_STAGE_PRESOLVED
2582  * - \ref SCIP_STAGE_SOLVING
2583  */
2585  SCIP* scip /**< SCIP data structure */
2586  )
2587 {
2588  assert(scip != NULL);
2589 
2590  SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkRelaxSolInvalid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2591 
2593 
2594  return SCIP_OKAY;
2595 }
2596 
2597 /** gets the relaxation solution value of the given variable
2598  *
2599  * @return the relaxation solution value of the given variable
2600  *
2601  * @pre This method can be called if @p scip is in one of the following stages:
2602  * - \ref SCIP_STAGE_PRESOLVED
2603  * - \ref SCIP_STAGE_SOLVING
2604  */
2606  SCIP* scip, /**< SCIP data structure */
2607  SCIP_VAR* var /**< variable to get value for */
2608  )
2609 {
2610  assert(scip != NULL);
2611  assert(var != NULL);
2612  assert(var->scip == scip);
2613 
2614  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetRelaxSolVal", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2615 
2616  if( !SCIPrelaxationIsSolValid(scip->relaxation) )
2617  {
2618  SCIPerrorMessage("Relaxation Solution is not valid!\n");
2619  SCIPABORT();
2620  return SCIP_INVALID; /*lint !e527*/
2621  }
2622 
2623  return SCIPvarGetRelaxSol(var, scip->set);
2624 }
2625 
2626 /** gets the relaxation solution objective value
2627  *
2628  * @return the objective value of the relaxation solution
2629  *
2630  * @pre This method can be called if @p scip is in one of the following stages:
2631  * - \ref SCIP_STAGE_PRESOLVED
2632  * - \ref SCIP_STAGE_SOLVING
2633  */
2635  SCIP* scip /**< SCIP data structure */
2636  )
2637 {
2638  assert(scip != NULL);
2639 
2640  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetRelaxSolObj", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2641 
2642  if( !SCIPrelaxationIsSolValid(scip->relaxation) )
2643  {
2644  SCIPerrorMessage("Relaxation Solution is not valid!\n");
2645  SCIPABORT();
2646  return SCIP_INVALID; /*lint !e527*/
2647  }
2648 
2649  return SCIPrelaxationGetSolObj(scip->relaxation);
2650 }
2651 
2652 /** determine which branching direction should be evaluated first by strong branching
2653  *
2654  * @return TRUE iff strong branching should first evaluate the down child
2655  *
2656  */
2658  SCIP* scip, /**< SCIP data structure */
2659  SCIP_VAR* var /**< variable to determine the branching direction on */
2660  )
2661 {
2662  switch( scip->set->branch_firstsbchild )
2663  {
2664  case 'u':
2665  return FALSE;
2666  case 'd':
2667  return TRUE;
2668  case 'a':
2669  return (SCIPvarGetNLocksDown(var) > SCIPvarGetNLocksUp(var));
2670  default:
2671  assert(scip->set->branch_firstsbchild == 'h');
2673  }
2674 }
2675 
2676 /** start strong branching - call before any strong branching
2677  *
2678  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2679  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2680  *
2681  * @pre This method can be called if @p scip is in one of the following stages:
2682  * - \ref SCIP_STAGE_PRESOLVED
2683  * - \ref SCIP_STAGE_SOLVING
2684  *
2685  * @note if propagation is enabled, strong branching is not done directly on the LP, but probing nodes are created
2686  * which allow to perform propagation but also creates some overhead
2687  */
2689  SCIP* scip, /**< SCIP data structure */
2690  SCIP_Bool enablepropagation /**< should propagation be done before solving the strong branching LP? */
2691  )
2692 {
2693  assert( scip != NULL );
2694  SCIP_CALL( SCIPcheckStage(scip, "SCIPstartStrongbranch", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2695 
2696  assert(!SCIPinProbing(scip));
2697 
2698  SCIPdebugMsg(scip, "starting strong branching mode%s: lpcount=%" SCIP_LONGINT_FORMAT "\n", enablepropagation ? " with propagation" : "", scip->stat->lpcount - scip->stat->nsbdivinglps);
2699 
2700  /* start probing mode to allow propagation before solving the strong branching LPs; if no propagation should be done,
2701  * start the strong branching mode in the LP interface
2702  */
2703  if( enablepropagation )
2704  {
2705  if( SCIPtreeProbing(scip->tree) )
2706  {
2707  SCIPerrorMessage("cannot start strong branching with propagation while in probing mode\n");
2708  return SCIP_INVALIDCALL;
2709  }
2710 
2711  if( scip->lp != NULL && SCIPlpDiving(scip->lp) )
2712  {
2713  SCIPerrorMessage("cannot start strong branching with propagation while in diving mode\n");
2714  return SCIP_INVALIDCALL;
2715  }
2716 
2717  /* other then in SCIPstartProbing(), we do not disable collecting variable statistics during strong branching;
2718  * we cannot disable it, because the pseudo costs would not be updated, otherwise,
2719  * and reliability branching would end up doing strong branching all the time
2720  */
2721  SCIP_CALL( SCIPtreeStartProbing(scip->tree, scip->mem->probmem, scip->set, scip->lp, scip->relaxation, scip->transprob, TRUE) );
2722 
2723  /* inform the LP that the current probing mode is used for strong branching */
2725  }
2726  else
2727  {
2729  }
2730 
2731  /* reset local strong branching info */
2733 
2734  return SCIP_OKAY;
2735 }
2736 
2737 /** end strong branching - call after any strong branching
2738  *
2739  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2740  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2741  *
2742  * @pre This method can be called if @p scip is in one of the following stages:
2743  * - \ref SCIP_STAGE_PRESOLVED
2744  * - \ref SCIP_STAGE_SOLVING
2745  */
2747  SCIP* scip /**< SCIP data structure */
2748  )
2749 {
2750  assert( scip != NULL );
2751 
2752  SCIP_CALL( SCIPcheckStage(scip, "SCIPendStrongbranch", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2753 
2754  /* depending on whether the strong branching mode was started with propagation enabled or not, we end the strong
2755  * branching probing mode or the LP strong branching mode
2756  */
2757  if( SCIPtreeProbing(scip->tree) )
2758  {
2759  SCIP_NODE* node;
2760  SCIP_DOMCHG* domchg;
2761  SCIP_VAR** boundchgvars;
2762  SCIP_Real* bounds;
2763  SCIP_BOUNDTYPE* boundtypes;
2764  int nboundchgs;
2765  int nbnds;
2766  int i;
2767 
2768  /* collect all bound changes deducted during probing, which were applied at the probing root and apply them to the
2769  * focusnode
2770  */
2771  node = SCIPgetCurrentNode(scip);
2772  assert(SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE);
2773  assert(SCIPgetProbingDepth(scip) == 0);
2774 
2775  domchg = SCIPnodeGetDomchg(node);
2776  nboundchgs = SCIPdomchgGetNBoundchgs(domchg);
2777 
2778  SCIP_CALL( SCIPallocBufferArray(scip, &boundchgvars, nboundchgs) );
2779  SCIP_CALL( SCIPallocBufferArray(scip, &bounds, nboundchgs) );
2780  SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, nboundchgs) );
2781 
2782  for( i = 0, nbnds = 0; i < nboundchgs; ++i )
2783  {
2784  SCIP_BOUNDCHG* boundchg;
2785 
2786  boundchg = SCIPdomchgGetBoundchg(domchg, i);
2787 
2788  /* ignore redundant bound changes */
2789  if( SCIPboundchgIsRedundant(boundchg) )
2790  continue;
2791 
2792  boundchgvars[nbnds] = SCIPboundchgGetVar(boundchg);
2793  bounds[nbnds] = SCIPboundchgGetNewbound(boundchg);
2794  boundtypes[nbnds] = SCIPboundchgGetBoundtype(boundchg);
2795  ++nbnds;
2796  }
2797 
2798  SCIPdebugMsg(scip, "ending strong branching with probing: %d bound changes collected\n", nbnds);
2799 
2800  /* inform the LP that the probing mode is not used for strong branching anymore */
2802 
2803  /* switch back from probing to normal operation mode and restore variables and constraints to focus node */
2804  SCIP_CALL( SCIPtreeEndProbing(scip->tree, scip->reopt, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
2805  scip->transprob, scip->origprob, scip->lp, scip->relaxation, scip->primal,
2806  scip->branchcand, scip->eventqueue, scip->eventfilter, scip->cliquetable) );
2807 
2808  /* apply the collected bound changes */
2809  for( i = 0; i < nbnds; ++i )
2810  {
2811  if( boundtypes[i] == SCIP_BOUNDTYPE_LOWER )
2812  {
2813  SCIPdebugMsg(scip, "apply probing lower bound change <%s> >= %.9g\n", SCIPvarGetName(boundchgvars[i]), bounds[i]);
2814  SCIP_CALL( SCIPchgVarLb(scip, boundchgvars[i], bounds[i]) );
2815  }
2816  else
2817  {
2818  SCIPdebugMsg(scip, "apply probing upper bound change <%s> <= %.9g\n", SCIPvarGetName(boundchgvars[i]), bounds[i]);
2819  SCIP_CALL( SCIPchgVarUb(scip, boundchgvars[i], bounds[i]) );
2820  }
2821  }
2822 
2823  SCIPfreeBufferArray(scip, &boundtypes);
2824  SCIPfreeBufferArray(scip, &bounds);
2825  SCIPfreeBufferArray(scip, &boundchgvars);
2826  }
2827  else
2828  {
2829  SCIPdebugMsg(scip, "ending strong branching\n");
2830 
2832  }
2833 
2834  return SCIP_OKAY;
2835 }
2836 
2837 /** analyze the strong branching for the given variable; that includes conflict analysis for infeasible branches and
2838  * storing of root reduced cost information
2839  */
2840 static
2842  SCIP* scip, /**< SCIP data structure */
2843  SCIP_VAR* var, /**< variable to analyze */
2844  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
2845  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
2846  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
2847  * infeasible downwards branch, or NULL */
2848  SCIP_Bool* upconflict /**< pointer to store whether a conflict constraint was created for an
2849  * infeasible upwards branch, or NULL */
2850  )
2851 {
2852  SCIP_COL* col;
2853  SCIP_Bool downcutoff;
2854  SCIP_Bool upcutoff;
2855 
2856  col = SCIPvarGetCol(var);
2857  assert(col != NULL);
2858 
2859  downcutoff = col->sbdownvalid && SCIPsetIsGE(scip->set, col->sbdown, scip->lp->cutoffbound);
2860  upcutoff = col->sbupvalid && SCIPsetIsGE(scip->set, col->sbup, scip->lp->cutoffbound);
2861 
2862  if( downinf != NULL )
2863  *downinf = downcutoff;
2864  if( upinf != NULL )
2865  *upinf = upcutoff;
2866 
2867  /* analyze infeasible strong branching sub problems:
2868  * because the strong branching's bound change is necessary for infeasibility, it cannot be undone;
2869  * therefore, infeasible strong branchings on non-binary variables will not produce a valid conflict constraint
2870  */
2871  if( scip->set->conf_enable && scip->set->conf_usesb && scip->set->nconflicthdlrs > 0
2872  && SCIPvarIsBinary(var) && SCIPtreeGetCurrentDepth(scip->tree) > 0 )
2873  {
2874  if( (downcutoff && SCIPsetFeasCeil(scip->set, col->primsol-1.0) >= col->lb - 0.5)
2875  || (upcutoff && SCIPsetFeasFloor(scip->set, col->primsol+1.0) <= col->ub + 0.5) )
2876  {
2877  assert(downconflict != NULL);
2878  assert(upconflict != NULL);
2879  SCIP_CALL( SCIPconflictAnalyzeStrongbranch(scip->conflict, scip->conflictstore, scip->mem->probmem, scip->set, scip->stat,
2880  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, col, downconflict, upconflict) );
2881  }
2882  }
2883 
2884  /* the strong branching results can be used to strengthen the root reduced cost information which is used for example
2885  * to propagate against the cutoff bound
2886  *
2887  * @note Ignore the results if the LP solution of the down (up) branch LP is smaller which should not happened by
2888  * theory but can arise due to numerical issues.
2889  */
2890  if( SCIPtreeGetCurrentDepth(scip->tree) == 0 && SCIPvarIsBinary(var) && SCIPlpIsDualReliable(scip->lp) )
2891  {
2892  SCIP_Real lpobjval;
2893 
2894  assert(SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL);
2895 
2896  lpobjval = SCIPlpGetObjval(scip->lp, scip->set, scip->transprob);
2897 
2898  if( col->sbdownvalid && SCIPsetFeasCeil(scip->set, col->primsol-1.0) >= col->lb - 0.5 && lpobjval < col->sbdown )
2899  SCIPvarUpdateBestRootSol(var, scip->set, SCIPvarGetUbGlobal(var), -(col->sbdown - lpobjval), lpobjval);
2900  if( col->sbupvalid && SCIPsetFeasFloor(scip->set, col->primsol+1.0) <= col->ub + 0.5 && lpobjval < col->sbup )
2901  SCIPvarUpdateBestRootSol(var, scip->set, SCIPvarGetLbGlobal(var), col->sbup - lpobjval, lpobjval);
2902  }
2903 
2904  return SCIP_OKAY;
2905 }
2906 
2907 /** gets strong branching information on column variable with fractional value
2908  *
2909  * Before calling this method, the strong branching mode must have been activated by calling SCIPstartStrongbranch();
2910  * after strong branching was done for all candidate variables, the strong branching mode must be ended by
2911  * SCIPendStrongbranch(). Since this method does not apply domain propagation before strongbranching,
2912  * propagation should not be enabled in the SCIPstartStrongbranch() call.
2913  *
2914  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2915  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2916  *
2917  * @pre This method can be called if @p scip is in one of the following stages:
2918  * - \ref SCIP_STAGE_PRESOLVED
2919  * - \ref SCIP_STAGE_SOLVING
2920  */
2922  SCIP* scip, /**< SCIP data structure */
2923  SCIP_VAR* var, /**< variable to get strong branching values for */
2924  int itlim, /**< iteration limit for strong branchings */
2925  SCIP_Bool idempotent, /**< should scip's state remain the same after the call (statistics, column states...), or should it be updated ? */
2926  SCIP_Real* down, /**< stores dual bound after branching column down */
2927  SCIP_Real* up, /**< stores dual bound after branching column up */
2928  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
2929  * otherwise, it can only be used as an estimate value */
2930  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
2931  * otherwise, it can only be used as an estimate value */
2932  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
2933  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
2934  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
2935  * infeasible downwards branch, or NULL */
2936  SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
2937  * infeasible upwards branch, or NULL */
2938  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
2939  * solving process should be stopped (e.g., due to a time limit) */
2940  )
2941 {
2942  SCIP_COL* col;
2943  SCIP_Real localdown;
2944  SCIP_Real localup;
2945  SCIP_Bool localdownvalid;
2946  SCIP_Bool localupvalid;
2947 
2948  assert(scip != NULL);
2949  assert(var != NULL);
2950  assert(lperror != NULL);
2951  assert(!SCIPtreeProbing(scip->tree)); /* we should not be in strong branching with propagation mode */
2952  assert(var->scip == scip);
2953 
2954  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchFrac", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2955 
2956  if( downvalid != NULL )
2957  *downvalid = FALSE;
2958  if( upvalid != NULL )
2959  *upvalid = FALSE;
2960  if( downinf != NULL )
2961  *downinf = FALSE;
2962  if( upinf != NULL )
2963  *upinf = FALSE;
2964  if( downconflict != NULL )
2965  *downconflict = FALSE;
2966  if( upconflict != NULL )
2967  *upconflict = FALSE;
2968 
2970  {
2971  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
2972  return SCIP_INVALIDDATA;
2973  }
2974 
2975  col = SCIPvarGetCol(var);
2976  assert(col != NULL);
2977 
2978  if( !SCIPcolIsInLP(col) )
2979  {
2980  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
2981  return SCIP_INVALIDDATA;
2982  }
2983 
2984  /* check if the solving process should be aborted */
2985  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
2986  {
2987  /* mark this as if the LP failed */
2988  *lperror = TRUE;
2989  return SCIP_OKAY;
2990  }
2991 
2992  /* call strong branching for column with fractional value */
2993  SCIP_CALL( SCIPcolGetStrongbranch(col, FALSE, scip->set, scip->stat, scip->transprob, scip->lp, itlim, !idempotent, !idempotent,
2994  &localdown, &localup, &localdownvalid, &localupvalid, lperror) );
2995 
2996  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
2997  * declare the sub nodes infeasible
2998  */
2999  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3000  {
3001  if( !idempotent ) /*lint !e774*/
3002  {
3003  SCIP_CALL( analyzeStrongbranch(scip, var, downinf, upinf, downconflict, upconflict) );
3004  }
3005  else
3006  {
3007  if( downinf != NULL )
3008  *downinf = localdownvalid && SCIPsetIsGE(scip->set, localdown, scip->lp->cutoffbound);
3009  if( upinf != NULL )
3010  *upinf = localupvalid && SCIPsetIsGE(scip->set, localup, scip->lp->cutoffbound);
3011  }
3012  }
3013 
3014  if( down != NULL )
3015  *down = localdown;
3016  if( up != NULL )
3017  *up = localup;
3018  if( downvalid != NULL )
3019  *downvalid = localdownvalid;
3020  if( upvalid != NULL )
3021  *upvalid = localupvalid;
3022 
3023  return SCIP_OKAY;
3024 }
3025 
3026 /** create, solve, and evaluate a single strong branching child (for strong branching with propagation) */
3027 static
3029  SCIP* scip, /**< SCIP data structure */
3030  SCIP_VAR* var, /**< variable to get strong branching values for */
3031  SCIP_Bool down, /**< do we regard the down child? */
3032  SCIP_Bool firstchild, /**< is this the first of the two strong branching children? */
3033  SCIP_Bool propagate, /**< should domain propagation be performed? */
3034  SCIP_Real newbound, /**< new bound to apply at the strong branching child */
3035  int itlim, /**< iteration limit for strong branchings */
3036  int maxproprounds, /**< maximum number of propagation rounds (-1: no limit, -2: parameter
3037  * settings) */
3038  SCIP_Real* value, /**< stores dual bound for strong branching child */
3039  SCIP_Bool* valid, /**< stores whether the returned value is a valid dual bound, or NULL;
3040  * otherwise, it can only be used as an estimate value */
3041  SCIP_Longint* ndomreductions, /**< pointer to store the number of domain reductions found, or NULL */
3042  SCIP_Bool* conflict, /**< pointer to store whether a conflict constraint was created for an
3043  * infeasible strong branching child, or NULL */
3044  SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred or the
3045  * solving process should be stopped (e.g., due to a time limit) */
3046  SCIP_VAR** vars, /**< active problem variables */
3047  int nvars, /**< number of active problem variables */
3048  SCIP_Real* newlbs, /**< array to store valid lower bounds for all active variables, or NULL */
3049  SCIP_Real* newubs, /**< array to store valid upper bounds for all active variables, or NULL */
3050  SCIP_Bool* foundsol, /**< pointer to store whether a primal solution was found during strong branching */
3051  SCIP_Bool* cutoff /**< pointer to store whether the strong branching child is infeasible */
3052  )
3053 {
3054  SCIP_Longint ndomreds;
3055 
3056  assert(value != NULL);
3057  assert(foundsol != NULL);
3058  assert(cutoff != NULL);
3059  assert(lperror != NULL);
3060  assert(valid != NULL ? !(*valid) : TRUE);
3061 
3062  *foundsol = FALSE;
3063  *cutoff = FALSE;
3064  *lperror = FALSE;
3065 
3066  /* check whether the strong branching child is already infeasible due to the bound change */
3067  if( down )
3068  {
3069  /* the down branch is infeasible due to the branching bound change; since this means that solval is not within the
3070  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3071  * are valid for and were already applied at the probing root
3072  */
3073  if( newbound < SCIPvarGetLbLocal(var) - 0.5 )
3074  {
3075  *value = SCIPinfinity(scip);
3076 
3077  if( valid != NULL )
3078  *valid = TRUE;
3079 
3080  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3081  if( conflict != NULL )
3082  *conflict = TRUE;
3083 
3084  *cutoff = TRUE;
3085 
3086  return SCIP_OKAY;
3087  }
3088  }
3089  else
3090  {
3091  /* the up branch is infeasible due to the branching bound change; since this means that solval is not within the
3092  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3093  * are valid for and were already applied at the probing root
3094  */
3095  if( newbound > SCIPvarGetUbLocal(var) + 0.5 )
3096  {
3097  *value = SCIPinfinity(scip);
3098 
3099  if( valid != NULL )
3100  *valid = TRUE;
3101 
3102  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3103  if( conflict != NULL )
3104  *conflict = TRUE;
3105 
3106  *cutoff = TRUE;
3107 
3108  return SCIP_OKAY;
3109  }
3110  }
3111 
3112  /* we need to ensure that we can create at least one new probing node without exceeding the maximal tree depth */
3114  {
3115  /* create a new probing node for the strong branching child and apply the new bound for the variable */
3116  SCIP_CALL( SCIPnewProbingNode(scip) );
3117 
3118  if( down )
3119  {
3120  assert(SCIPisGE(scip, newbound, SCIPvarGetLbLocal(var)));
3121  if( SCIPisLT(scip, newbound, SCIPvarGetUbLocal(var)) )
3122  {
3123  SCIP_CALL( SCIPchgVarUbProbing(scip, var, newbound) );
3124  }
3125  }
3126  else
3127  {
3128  assert(SCIPisLE(scip, newbound, SCIPvarGetUbLocal(var)));
3129  if( SCIPisGT(scip, newbound, SCIPvarGetLbLocal(var)) )
3130  {
3131  SCIP_CALL( SCIPchgVarLbProbing(scip, var, newbound) );
3132  }
3133  }
3134  }
3135  else
3136  {
3137  if( valid != NULL )
3138  *valid = FALSE;
3139 
3140  *cutoff = FALSE;
3141 
3142  if( conflict != NULL )
3143  *conflict = FALSE;
3144 
3145  return SCIP_OKAY;
3146  }
3147 
3148  /* propagate domains at the probing node */
3149  if( propagate )
3150  {
3151  /* start time measuring */
3152  SCIPclockStart(scip->stat->strongpropclock, scip->set);
3153 
3154  ndomreds = 0;
3155  SCIP_CALL( SCIPpropagateProbing(scip, maxproprounds, cutoff, &ndomreds) );
3156 
3157  /* store number of domain reductions in strong branching */
3158  if( down )
3159  SCIPstatAdd(scip->stat, scip->set, nsbdowndomchgs, ndomreds);
3160  else
3161  SCIPstatAdd(scip->stat, scip->set, nsbupdomchgs, ndomreds);
3162 
3163  if( ndomreductions != NULL )
3164  *ndomreductions = ndomreds;
3165 
3166  /* stop time measuring */
3167  SCIPclockStop(scip->stat->strongpropclock, scip->set);
3168 
3169  if( *cutoff )
3170  {
3171  *value = SCIPinfinity(scip);
3172 
3173  if( valid != NULL )
3174  *valid = TRUE;
3175 
3176  SCIPdebugMsg(scip, "%s branch of var <%s> detected infeasible during propagation\n",
3177  down ? "down" : "up", SCIPvarGetName(var));
3178  }
3179  }
3180 
3181  /* if propagation did not already detect infeasibility, solve the probing LP */
3182  if( !(*cutoff) )
3183  {
3184  SCIP_CALL( SCIPsolveProbingLP(scip, itlim, lperror, cutoff) );
3185  assert(SCIPisLPRelax(scip));
3186 
3187  if( *cutoff )
3188  {
3189  assert(!(*lperror));
3190 
3191  *value = SCIPinfinity(scip);
3192 
3193  if( valid != NULL )
3194  *valid = TRUE;
3195 
3196  SCIPdebugMsg(scip, "%s branch of var <%s> detected infeasible in LP solving: status=%d\n",
3197  down ? "down" : "up", SCIPvarGetName(var), SCIPgetLPSolstat(scip));
3198  }
3199  else if( !(*lperror) )
3200  {
3201  /* save the lp solution status */
3202  scip->stat->lastsblpsolstats[down ? 0 : 1] = SCIPgetLPSolstat(scip);
3203 
3204  switch( SCIPgetLPSolstat(scip) )
3205  {
3207  {
3208  *value = SCIPgetLPObjval(scip);
3209  assert(SCIPisLT(scip, *value, SCIPgetCutoffbound(scip)));
3210 
3211  SCIPdebugMsg(scip, "probing LP solved to optimality, objective value: %16.9g\n", *value);
3212 
3213  if( valid != NULL )
3214  *valid = TRUE;
3215 
3216  /* check the strong branching LP solution for feasibility */
3217  SCIP_CALL( SCIPtryStrongbranchLPSol(scip, foundsol, cutoff) );
3218  break;
3219  }
3221  ++scip->stat->nsbtimesiterlimhit;
3222  /*lint -fallthrough*/
3224  {
3225  /* use LP value as estimate */
3226  SCIP_LPI* lpi;
3227  SCIP_Real objval;
3228  SCIP_Real looseobjval;
3229 
3230  SCIPdebugMsg(scip, "probing LP hit %s limit\n", SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_ITERLIMIT ? "iteration" : "time");
3231 
3232  /* we access the LPI directly, because when a time limit was hit, we cannot access objective value and dual
3233  * feasibility using the SCIPlp... methods; we should try to avoid direct calls to the LPI, but this is rather
3234  * uncritical here, because we are immediately after the SCIPsolveProbingLP() call, because we access the LPI
3235  * read-only, and we check SCIPlpiWasSolved() first
3236  */
3237  SCIP_CALL( SCIPgetLPI(scip, &lpi) );
3238 
3239  if( SCIPlpiWasSolved(lpi) )
3240  {
3241  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
3242  looseobjval = SCIPlpGetLooseObjval(scip->lp, scip->set, scip->transprob);
3243 
3244  /* the infinity value in the LPI should not be smaller than SCIP's infinity value */
3245  assert(!SCIPlpiIsInfinity(lpi, objval) || SCIPisInfinity(scip, objval));
3246 
3247  /* we use SCIP's infinity value here because a value larger than this is counted as infeasible by SCIP */
3248  if( SCIPisInfinity(scip, objval) )
3249  *value = SCIPinfinity(scip);
3250  else if( SCIPisInfinity(scip, -looseobjval) )
3251  *value = -SCIPinfinity(scip);
3252  else
3253  *value = objval + looseobjval;
3254 
3255  if( SCIPlpiIsDualFeasible(lpi) )
3256  {
3257  if( valid != NULL )
3258  *valid = TRUE;
3259 
3260  if( SCIPisGE(scip, *value, SCIPgetCutoffbound(scip)) )
3261  *cutoff = TRUE;
3262  }
3263  }
3264  break;
3265  }
3266  case SCIP_LPSOLSTAT_ERROR:
3268  *lperror = TRUE;
3269  break;
3270  case SCIP_LPSOLSTAT_NOTSOLVED: /* should only be the case for *cutoff = TRUE or *lperror = TRUE */
3271  case SCIP_LPSOLSTAT_OBJLIMIT: /* in this case, *cutoff should be TRUE and we should not get here */
3272  case SCIP_LPSOLSTAT_INFEASIBLE: /* in this case, *cutoff should be TRUE and we should not get here */
3273  default:
3274  SCIPerrorMessage("invalid LP solution status <%d>\n", SCIPgetLPSolstat(scip));
3275  return SCIP_INVALIDDATA;
3276  } /*lint !e788*/
3277  }
3278 
3279  /* If columns are missing in the LP, the cutoff flag may be wrong. Therefore, we need to set it and the valid pointer
3280  * to false here.
3281  */
3282  if( (*cutoff) && !SCIPallColsInLP(scip) )
3283  {
3284  *cutoff = FALSE;
3285  }
3286 
3287 #ifndef NDEBUG
3288  if( *lperror )
3289  {
3290  SCIPdebugMsg(scip, "error during strong branching probing LP solving: status=%d\n", SCIPgetLPSolstat(scip));
3291  }
3292 #endif
3293  }
3294 
3295  /* if the subproblem was feasible, we store the local bounds of the variables after propagation and (possibly)
3296  * conflict analysis
3297  * @todo do this after propagation? should be able to get valid bounds more often, but they might be weaker
3298  */
3299  if( !(*cutoff) && newlbs != NULL)
3300  {
3301  int v;
3302 
3303  assert(newubs != NULL);
3304 
3305  /* initialize the newlbs and newubs to the current local bounds */
3306  if( firstchild )
3307  {
3308  for( v = 0; v < nvars; ++v )
3309  {
3310  newlbs[v] = SCIPvarGetLbLocal(vars[v]);
3311  newubs[v] = SCIPvarGetUbLocal(vars[v]);
3312  }
3313  }
3314  /* update newlbs and newubs: take the weaker of the already stored bounds and the current local bounds */
3315  else
3316  {
3317  for( v = 0; v < nvars; ++v )
3318  {
3319  SCIP_Real lb = SCIPvarGetLbLocal(vars[v]);
3320  SCIP_Real ub = SCIPvarGetUbLocal(vars[v]);
3321 
3322  newlbs[v] = MIN(newlbs[v], lb);
3323  newubs[v] = MAX(newubs[v], ub);
3324  }
3325  }
3326  }
3327 
3328  /* revert all changes at the probing node */
3329  SCIP_CALL( SCIPbacktrackProbing(scip, 0) );
3330 
3331  return SCIP_OKAY;
3332 }
3333 
3334 /** gets strong branching information with previous domain propagation on column variable
3335  *
3336  * Before calling this method, the strong branching mode must have been activated by calling SCIPstartStrongbranch();
3337  * after strong branching was done for all candidate variables, the strong branching mode must be ended by
3338  * SCIPendStrongbranch(). Since this method applies domain propagation before strongbranching, propagation has to be be
3339  * enabled in the SCIPstartStrongbranch() call.
3340  *
3341  * Before solving the strong branching LP, domain propagation can be performed. The number of propagation rounds
3342  * can be specified by the parameter @p maxproprounds.
3343  *
3344  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3345  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3346  *
3347  * @pre This method can be called if @p scip is in one of the following stages:
3348  * - \ref SCIP_STAGE_PRESOLVED
3349  * - \ref SCIP_STAGE_SOLVING
3350  *
3351  * @warning When using this method, LP banching candidates and solution values must be copied beforehand, because
3352  * they are updated w.r.t. the strong branching LP solution.
3353  */
3355  SCIP* scip, /**< SCIP data structure */
3356  SCIP_VAR* var, /**< variable to get strong branching values for */
3357  SCIP_Real solval, /**< value of the variable in the current LP solution */
3358  SCIP_Real lpobjval, /**< LP objective value of the current LP solution */
3359  int itlim, /**< iteration limit for strong branchings */
3360  int maxproprounds, /**< maximum number of propagation rounds (-1: no limit, -2: parameter
3361  * settings) */
3362  SCIP_Real* down, /**< stores dual bound after branching column down */
3363  SCIP_Real* up, /**< stores dual bound after branching column up */
3364  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
3365  * otherwise, it can only be used as an estimate value */
3366  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
3367  * otherwise, it can only be used as an estimate value */
3368  SCIP_Longint* ndomredsdown, /**< pointer to store the number of domain reductions down, or NULL */
3369  SCIP_Longint* ndomredsup, /**< pointer to store the number of domain reductions up, or NULL */
3370  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
3371  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
3372  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
3373  * infeasible downwards branch, or NULL */
3374  SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
3375  * infeasible upwards branch, or NULL */
3376  SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred or the
3377  * solving process should be stopped (e.g., due to a time limit) */
3378  SCIP_Real* newlbs, /**< array to store valid lower bounds for all active variables, or NULL */
3379  SCIP_Real* newubs /**< array to store valid upper bounds for all active variables, or NULL */
3380  )
3381 {
3382  SCIP_COL* col;
3383  SCIP_VAR** vars;
3384  SCIP_Longint oldniters;
3385  SCIP_Real newub;
3386  SCIP_Real newlb;
3387  SCIP_Bool propagate;
3388  SCIP_Bool cutoff;
3389  SCIP_Bool downchild;
3390  SCIP_Bool firstchild;
3391  SCIP_Bool foundsol;
3392  SCIP_Bool downvalidlocal;
3393  SCIP_Bool upvalidlocal;
3394  SCIP_Bool allcolsinlp;
3395  SCIP_Bool enabledconflict;
3396  int oldnconflicts;
3397  int nvars;
3398 
3399  assert(scip != NULL);
3400  assert(var != NULL);
3401  assert(SCIPvarIsIntegral(var));
3402  assert(down != NULL);
3403  assert(up != NULL);
3404  assert(lperror != NULL);
3405  assert((newlbs != NULL) == (newubs != NULL));
3406  assert(SCIPinProbing(scip));
3407  assert(var->scip == scip);
3408 
3409  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchWithPropagation", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3410 
3411  /* check whether propagation should be performed */
3412  propagate = (maxproprounds != 0 && maxproprounds != -3);
3413 
3414  /* Check, if all existing columns are in LP.
3415  * If this is not the case, we may still return that the up and down dual bounds are valid, because the branching
3416  * rule should not apply them otherwise.
3417  * However, we must not set the downinf or upinf pointers to TRUE based on the dual bound, because we cannot
3418  * guarantee that this node can be cut off.
3419  */
3420  allcolsinlp = SCIPallColsInLP(scip);
3421 
3422  /* if maxproprounds is -2, change it to 0, which for the following calls means using the parameter settings */
3423  if( maxproprounds == -2 )
3424  maxproprounds = 0;
3425 
3426  *down = lpobjval;
3427  *up = lpobjval;
3428  if( downvalid != NULL )
3429  *downvalid = FALSE;
3430  if( upvalid != NULL )
3431  *upvalid = FALSE;
3432  if( downinf != NULL )
3433  *downinf = FALSE;
3434  if( upinf != NULL )
3435  *upinf = FALSE;
3436  if( downconflict != NULL )
3437  *downconflict = FALSE;
3438  if( upconflict != NULL )
3439  *upconflict = FALSE;
3440  if( ndomredsdown != NULL )
3441  *ndomredsdown = 0;
3442  if( ndomredsup != NULL )
3443  *ndomredsup = 0;
3444 
3445  *lperror = FALSE;
3446 
3447  vars = SCIPgetVars(scip);
3448  nvars = SCIPgetNVars(scip);
3449 
3451 
3452  /* check if the solving process should be aborted */
3453  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3454  {
3455  /* mark this as if the LP failed */
3456  *lperror = TRUE;
3457  return SCIP_OKAY;
3458  }
3459 
3461  {
3462  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3463  return SCIP_INVALIDDATA;
3464  }
3465 
3466  col = SCIPvarGetCol(var);
3467  assert(col != NULL);
3468 
3469  if( !SCIPcolIsInLP(col) )
3470  {
3471  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3472  return SCIP_INVALIDDATA;
3473  }
3474 
3475  newlb = SCIPfeasFloor(scip, solval + 1.0);
3476  newub = SCIPfeasCeil(scip, solval - 1.0);
3477 
3478  SCIPdebugMsg(scip, "strong branching on var <%s>: solval=%g, lb=%g, ub=%g\n", SCIPvarGetName(var), solval,
3480 
3481  /* the up branch is infeasible due to the branching bound change; since this means that solval is not within the
3482  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3483  * are valid for and were already applied at the probing root
3484  */
3485  if( newlb > SCIPvarGetUbLocal(var) + 0.5 )
3486  {
3487  *up = SCIPinfinity(scip);
3488 
3489  if( upinf != NULL )
3490  *upinf = TRUE;
3491 
3492  if( upvalid != NULL )
3493  *upvalid = TRUE;
3494 
3495  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3496  if( upconflict != NULL )
3497  *upconflict = TRUE;
3498 
3499  SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3500  *down, *up, FALSE, TRUE, 0LL, INT_MAX);
3501 
3502  /* we do not regard the down branch; its valid pointer stays set to FALSE */
3503  return SCIP_OKAY;
3504  }
3505 
3506  /* the down branch is infeasible due to the branching bound change; since this means that solval is not within the
3507  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3508  * are valid for and were already applied at the probing root
3509  */
3510  if( newub < SCIPvarGetLbLocal(var) - 0.5 )
3511  {
3512  *down = SCIPinfinity(scip);
3513 
3514  if( downinf != NULL )
3515  *downinf = TRUE;
3516 
3517  if( downvalid != NULL )
3518  *downvalid = TRUE;
3519 
3520  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3521  if( downconflict != NULL )
3522  *downconflict = TRUE;
3523 
3524  SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3525  *down, *up, TRUE, FALSE, 0LL, INT_MAX);
3526 
3527  /* we do not regard the up branch; its valid pointer stays set to FALSE */
3528  return SCIP_OKAY;
3529  }
3530 
3531  /* We now do strong branching by creating the two potential child nodes as probing nodes and solving them one after
3532  * the other. We will stop when the first child is detected infeasible, saving the effort we would need for the
3533  * second child. Since empirically, the up child tends to be infeasible more often, we do strongbranching first on
3534  * the up branch.
3535  */
3536  oldniters = scip->stat->nsbdivinglpiterations;
3537  firstchild = TRUE;
3538  cutoff = FALSE;
3539 
3540  /* switch conflict analysis according to usesb parameter */
3541  enabledconflict = scip->set->conf_enable;
3542  scip->set->conf_enable = (scip->set->conf_enable && scip->set->conf_usesb);
3543 
3544  /* @todo: decide the branch to look at first based on the cutoffs in previous calls? */
3545  downchild = SCIPisStrongbranchDownFirst(scip, var);
3546 
3547  downvalidlocal = FALSE;
3548  upvalidlocal = FALSE;
3549 
3550  do
3551  {
3552  oldnconflicts = SCIPconflictGetNConflicts(scip->conflict);
3553 
3554  if( downchild )
3555  {
3556  SCIP_CALL( performStrongbranchWithPropagation(scip, var, downchild, firstchild, propagate, newub, itlim, maxproprounds,
3557  down, &downvalidlocal, ndomredsdown, downconflict, lperror, vars, nvars, newlbs, newubs, &foundsol, &cutoff) );
3558 
3559  /* check whether a new solutions rendered the previous child infeasible */
3560  if( foundsol && !firstchild && allcolsinlp )
3561  {
3562  if( SCIPisGE(scip, *up, SCIPgetCutoffbound(scip)) )
3563  {
3564  if( upinf != NULL )
3565  *upinf = TRUE;
3566  }
3567  }
3568 
3569  /* check for infeasibility */
3570  if( cutoff )
3571  {
3572  if( downinf != NULL )
3573  *downinf = TRUE;
3574 
3575  if( downconflict != NULL &&
3576  (SCIPvarGetLbLocal(var) > newub + 0.5 || SCIPconflictGetNConflicts(scip->conflict) > oldnconflicts) )
3577  {
3578  *downconflict = TRUE;
3579  }
3580 
3581  if( !scip->set->branch_forceall )
3582  {
3583  /* if this is the first call, we do not regard the up branch, its valid pointer is initially set to FALSE */
3584  break;
3585  }
3586  }
3587  }
3588  else
3589  {
3590  SCIP_CALL( performStrongbranchWithPropagation(scip, var, downchild, firstchild, propagate, newlb, itlim, maxproprounds,
3591  up, &upvalidlocal, ndomredsup, upconflict, lperror, vars, nvars, newlbs, newubs, &foundsol, &cutoff) );
3592 
3593  /* check whether a new solutions rendered the previous child infeasible */
3594  if( foundsol && !firstchild && allcolsinlp )
3595  {
3596  if( SCIPisGE(scip, *down, SCIPgetCutoffbound(scip)) )
3597  {
3598  if( downinf != NULL )
3599  *downinf = TRUE;
3600  }
3601  }
3602 
3603  /* check for infeasibility */
3604  if( cutoff )
3605  {
3606  if( upinf != NULL )
3607  *upinf = TRUE;
3608 
3609  assert(upinf == NULL || (*upinf) == TRUE);
3610 
3611  if( upconflict != NULL &&
3612  (SCIPvarGetUbLocal(var) < newlb - 0.5 || SCIPconflictGetNConflicts(scip->conflict) > oldnconflicts) )
3613  {
3614  *upconflict = TRUE;
3615  }
3616 
3617  if( !scip->set->branch_forceall )
3618  {
3619  /* if this is the first call, we do not regard the down branch, its valid pointer is initially set to FALSE */
3620  break;
3621  }
3622  }
3623  }
3624 
3625  downchild = !downchild;
3626  firstchild = !firstchild;
3627  }
3628  while( !firstchild );
3629 
3630  /* set strong branching information in column */
3631  if( *lperror )
3632  {
3633  SCIPcolInvalidateStrongbranchData(col, scip->set, scip->stat, scip->lp);
3634  }
3635  else
3636  {
3637  SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3638  *down, *up, downvalidlocal, upvalidlocal, scip->stat->nsbdivinglpiterations - oldniters, itlim);
3639  }
3640 
3641  if( downvalid != NULL )
3642  *downvalid = downvalidlocal;
3643  if( upvalid != NULL )
3644  *upvalid = upvalidlocal;
3645 
3646  scip->set->conf_enable = enabledconflict;
3647 
3648  return SCIP_OKAY; /*lint !e438*/
3649 }
3650 
3651 /** gets strong branching information on column variable x with integral LP solution value (val); that is, the down branch
3652  * is (val -1.0) and the up brach ins (val +1.0)
3653  *
3654  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3655  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3656  *
3657  * @pre This method can be called if @p scip is in one of the following stages:
3658  * - \ref SCIP_STAGE_PRESOLVED
3659  * - \ref SCIP_STAGE_SOLVING
3660  *
3661  * @note If the integral LP solution value is the lower or upper bound of the variable, the corresponding branch will be
3662  * marked as infeasible. That is, the valid pointer and the infeasible pointer are set to TRUE.
3663  */
3665  SCIP* scip, /**< SCIP data structure */
3666  SCIP_VAR* var, /**< variable to get strong branching values for */
3667  int itlim, /**< iteration limit for strong branchings */
3668  SCIP_Bool idempotent, /**< should scip's state remain the same after the call (statistics, column states...), or should it be updated ? */
3669  SCIP_Real* down, /**< stores dual bound after branching column down */
3670  SCIP_Real* up, /**< stores dual bound after branching column up */
3671  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
3672  * otherwise, it can only be used as an estimate value */
3673  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
3674  * otherwise, it can only be used as an estimate value */
3675  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
3676  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
3677  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
3678  * infeasible downwards branch, or NULL */
3679  SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
3680  * infeasible upwards branch, or NULL */
3681  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3682  * solving process should be stopped (e.g., due to a time limit) */
3683  )
3684 {
3685  SCIP_COL* col;
3686  SCIP_Real localdown;
3687  SCIP_Real localup;
3688  SCIP_Bool localdownvalid;
3689  SCIP_Bool localupvalid;
3690 
3691  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchInt", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3692 
3693  assert(lperror != NULL);
3694  assert(var->scip == scip);
3695 
3696  if( downvalid != NULL )
3697  *downvalid = FALSE;
3698  if( upvalid != NULL )
3699  *upvalid = FALSE;
3700  if( downinf != NULL )
3701  *downinf = FALSE;
3702  if( upinf != NULL )
3703  *upinf = FALSE;
3704  if( downconflict != NULL )
3705  *downconflict = FALSE;
3706  if( upconflict != NULL )
3707  *upconflict = FALSE;
3708 
3710  {
3711  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3712  return SCIP_INVALIDDATA;
3713  }
3714 
3715  col = SCIPvarGetCol(var);
3716  assert(col != NULL);
3717 
3718  if( !SCIPcolIsInLP(col) )
3719  {
3720  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3721  return SCIP_INVALIDDATA;
3722  }
3723 
3724  /* check if the solving process should be aborted */
3725  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3726  {
3727  /* mark this as if the LP failed */
3728  *lperror = TRUE;
3729  return SCIP_OKAY;
3730  }
3731 
3732  /* call strong branching for column */
3733  SCIP_CALL( SCIPcolGetStrongbranch(col, TRUE, scip->set, scip->stat, scip->transprob, scip->lp, itlim, !idempotent, !idempotent,
3734  &localdown, &localup, &localdownvalid, &localupvalid, lperror) );
3735 
3736  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3737  * declare the sub nodes infeasible
3738  */
3739  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3740  {
3741  if( !idempotent ) /*lint !e774*/
3742  {
3743  SCIP_CALL( analyzeStrongbranch(scip, var, downinf, upinf, downconflict, upconflict) );
3744  }
3745  else
3746  {
3747  if( downinf != NULL )
3748  *downinf = localdownvalid && SCIPsetIsGE(scip->set, localdown, scip->lp->cutoffbound);
3749  if( upinf != NULL )
3750  *upinf = localupvalid && SCIPsetIsGE(scip->set, localup, scip->lp->cutoffbound);
3751  }
3752  }
3753 
3754  if( down != NULL )
3755  *down = localdown;
3756  if( up != NULL )
3757  *up = localup;
3758  if( downvalid != NULL )
3759  *downvalid = localdownvalid;
3760  if( upvalid != NULL )
3761  *upvalid = localupvalid;
3762 
3763  return SCIP_OKAY;
3764 }
3765 
3766 /** gets strong branching information on column variables with fractional values
3767  *
3768  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3769  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3770  *
3771  * @pre This method can be called if @p scip is in one of the following stages:
3772  * - \ref SCIP_STAGE_PRESOLVED
3773  * - \ref SCIP_STAGE_SOLVING
3774  */
3776  SCIP* scip, /**< SCIP data structure */
3777  SCIP_VAR** vars, /**< variables to get strong branching values for */
3778  int nvars, /**< number of variables */
3779  int itlim, /**< iteration limit for strong branchings */
3780  SCIP_Real* down, /**< stores dual bounds after branching variables down */
3781  SCIP_Real* up, /**< stores dual bounds after branching variables up */
3782  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
3783  * otherwise, they can only be used as an estimate value */
3784  SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
3785  * otherwise, they can only be used as an estimate value */
3786  SCIP_Bool* downinf, /**< array to store whether the downward branches are infeasible, or NULL */
3787  SCIP_Bool* upinf, /**< array to store whether the upward branches are infeasible, or NULL */
3788  SCIP_Bool* downconflict, /**< array to store whether conflict constraints were created for
3789  * infeasible downward branches, or NULL */
3790  SCIP_Bool* upconflict, /**< array to store whether conflict constraints were created for
3791  * infeasible upward branches, or NULL */
3792  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3793  * solving process should be stopped (e.g., due to a time limit) */
3794  )
3795 {
3796  SCIP_COL** cols;
3797  int j;
3798 
3799  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarsStrongbranchesFrac", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3800 
3801  assert( lperror != NULL );
3802  assert( vars != NULL );
3803 
3804  /* set up data */
3805  cols = NULL;
3806  SCIP_CALL( SCIPallocBufferArray(scip, &cols, nvars) );
3807  assert(cols != NULL);
3808  for( j = 0; j < nvars; ++j )
3809  {
3810  SCIP_VAR* var;
3811  SCIP_COL* col;
3812 
3813  if( downvalid != NULL )
3814  downvalid[j] = FALSE;
3815  if( upvalid != NULL )
3816  upvalid[j] = FALSE;
3817  if( downinf != NULL )
3818  downinf[j] = FALSE;
3819  if( upinf != NULL )
3820  upinf[j] = FALSE;
3821  if( downconflict != NULL )
3822  downconflict[j] = FALSE;
3823  if( upconflict != NULL )
3824  upconflict[j] = FALSE;
3825 
3826  var = vars[j];
3827  assert( var != NULL );
3829  {
3830  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3831  SCIPfreeBufferArray(scip, &cols);
3832  return SCIP_INVALIDDATA;
3833  }
3834 
3835  col = SCIPvarGetCol(var);
3836  assert(col != NULL);
3837  cols[j] = col;
3838 
3839  if( !SCIPcolIsInLP(col) )
3840  {
3841  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3842  SCIPfreeBufferArray(scip, &cols);
3843  return SCIP_INVALIDDATA;
3844  }
3845  }
3846 
3847  /* check if the solving process should be aborted */
3848  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3849  {
3850  /* mark this as if the LP failed */
3851  *lperror = TRUE;
3852  }
3853  else
3854  {
3855  /* call strong branching for columns with fractional value */
3856  SCIP_CALL( SCIPcolGetStrongbranches(cols, nvars, FALSE, scip->set, scip->stat, scip->transprob, scip->lp, itlim,
3857  down, up, downvalid, upvalid, lperror) );
3858 
3859  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3860  * declare the sub nodes infeasible
3861  */
3862  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3863  {
3864  for( j = 0; j < nvars; ++j )
3865  {
3866  SCIP_CALL( analyzeStrongbranch(scip, vars[j], (downinf != NULL) ? (&(downinf[j])) : NULL,
3867  (upinf != NULL) ? (&(upinf[j])) : NULL, (downconflict != NULL) ? (&(downconflict[j])) : NULL,
3868  (upconflict != NULL) ? (&(upconflict[j])) : NULL) );
3869  }
3870  }
3871  }
3872  SCIPfreeBufferArray(scip, &cols);
3873 
3874  return SCIP_OKAY;
3875 }
3876 
3877 /** gets strong branching information on column variables with integral values
3878  *
3879  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3880  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3881  *
3882  * @pre This method can be called if @p scip is in one of the following stages:
3883  * - \ref SCIP_STAGE_PRESOLVED
3884  * - \ref SCIP_STAGE_SOLVING
3885  */
3887  SCIP* scip, /**< SCIP data structure */
3888  SCIP_VAR** vars, /**< variables to get strong branching values for */
3889  int nvars, /**< number of variables */
3890  int itlim, /**< iteration limit for strong branchings */
3891  SCIP_Real* down, /**< stores dual bounds after branching variables down */
3892  SCIP_Real* up, /**< stores dual bounds after branching variables up */
3893  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
3894  * otherwise, they can only be used as an estimate value */
3895  SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
3896  * otherwise, they can only be used as an estimate value */
3897  SCIP_Bool* downinf, /**< array to store whether the downward branches are infeasible, or NULL */
3898  SCIP_Bool* upinf, /**< array to store whether the upward branches are infeasible, or NULL */
3899  SCIP_Bool* downconflict, /**< array to store whether conflict constraints were created for
3900  * infeasible downward branches, or NULL */
3901  SCIP_Bool* upconflict, /**< array to store whether conflict constraints were created for
3902  * infeasible upward branches, or NULL */
3903  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3904  * solving process should be stopped (e.g., due to a time limit) */
3905  )
3906 {
3907  SCIP_COL** cols;
3908  int j;
3909 
3910  assert(lperror != NULL);
3911 
3912  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarsStrongbranchesInt", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3913 
3914  assert( vars != NULL );
3915 
3916  /* set up data */
3917  cols = NULL;
3918  SCIP_CALL( SCIPallocBufferArray(scip, &cols, nvars) );
3919  assert(cols != NULL);
3920  for( j = 0; j < nvars; ++j )
3921  {
3922  SCIP_VAR* var;
3923  SCIP_COL* col;
3924 
3925  if( downvalid != NULL )
3926  downvalid[j] = FALSE;
3927  if( upvalid != NULL )
3928  upvalid[j] = FALSE;
3929  if( downinf != NULL )
3930  downinf[j] = FALSE;
3931  if( upinf != NULL )
3932  upinf[j] = FALSE;
3933  if( downconflict != NULL )
3934  downconflict[j] = FALSE;
3935  if( upconflict != NULL )
3936  upconflict[j] = FALSE;
3937 
3938  var = vars[j];
3939  assert( var != NULL );
3941  {
3942  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3943  SCIPfreeBufferArray(scip, &cols);
3944  return SCIP_INVALIDDATA;
3945  }
3946 
3947  col = SCIPvarGetCol(var);
3948  assert(col != NULL);
3949  cols[j] = col;
3950 
3951  if( !SCIPcolIsInLP(col) )
3952  {
3953  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3954  SCIPfreeBufferArray(scip, &cols);
3955  return SCIP_INVALIDDATA;
3956  }
3957  }
3958 
3959  /* check if the solving process should be aborted */
3960  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3961  {
3962  /* mark this as if the LP failed */
3963  *lperror = TRUE;
3964  }
3965  else
3966  {
3967  /* call strong branching for columns */
3968  SCIP_CALL( SCIPcolGetStrongbranches(cols, nvars, TRUE, scip->set, scip->stat, scip->transprob, scip->lp, itlim,
3969  down, up, downvalid, upvalid, lperror) );
3970 
3971  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3972  * declare the sub nodes infeasible
3973  */
3974  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3975  {
3976  for( j = 0; j < nvars; ++j )
3977  {
3978  SCIP_CALL( analyzeStrongbranch(scip, vars[j], (downinf != NULL) ? (&(downinf[j])) : NULL,
3979  (upinf != NULL) ? (&(upinf[j])) : NULL, (downconflict != NULL) ? (&(downconflict[j])) : NULL,
3980  (upconflict != NULL) ? (&(upconflict[j])) : NULL) );
3981  }
3982  }
3983  }
3984  SCIPfreeBufferArray(scip, &cols);
3985 
3986  return SCIP_OKAY;
3987 }
3988 
3989 /** get LP solution status of last strong branching call (currently only works for strong branching with propagation) */
3991  SCIP* scip, /**< SCIP data structure */
3992  SCIP_BRANCHDIR branchdir /**< branching direction for which LP solution status is requested */
3993  )
3994 {
3995  assert(NULL != scip);
3996  assert(branchdir == SCIP_BRANCHDIR_DOWNWARDS || branchdir == SCIP_BRANCHDIR_UPWARDS);
3997 
3998  return scip->stat->lastsblpsolstats[branchdir == SCIP_BRANCHDIR_DOWNWARDS ? 0 : 1];
3999 }
4000 
4001 /** gets strong branching information on COLUMN variable of the last SCIPgetVarStrongbranch() call;
4002  * returns values of SCIP_INVALID, if strong branching was not yet called on the given variable;
4003  * keep in mind, that the returned old values may have nothing to do with the current LP solution
4004  *
4005  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4006  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4007  *
4008  * @pre This method can be called if @p scip is in one of the following stages:
4009  * - \ref SCIP_STAGE_SOLVING
4010  * - \ref SCIP_STAGE_SOLVED
4011  */
4013  SCIP* scip, /**< SCIP data structure */
4014  SCIP_VAR* var, /**< variable to get last strong branching values for */
4015  SCIP_Real* down, /**< stores dual bound after branching column down */
4016  SCIP_Real* up, /**< stores dual bound after branching column up */
4017  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4018  * otherwise, it can only be used as an estimate value */
4019  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4020  * otherwise, it can only be used as an estimate value */
4021  SCIP_Real* solval, /**< stores LP solution value of variable at the last strong branching call, or NULL */
4022  SCIP_Real* lpobjval /**< stores LP objective value at last strong branching call, or NULL */
4023  )
4024 {
4025  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchLast", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
4026 
4028  {
4029  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable\n");
4030  return SCIP_INVALIDDATA;
4031  }
4032 
4033  SCIPcolGetStrongbranchLast(SCIPvarGetCol(var), down, up, downvalid, upvalid, solval, lpobjval);
4034 
4035  return SCIP_OKAY;
4036 }
4037 
4038 /** sets strong branching information for a column variable
4039  *
4040  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4041  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4042  *
4043  * @pre This method can be called if @p scip is in one of the following stages:
4044  * - \ref SCIP_STAGE_SOLVING
4045  */
4047  SCIP* scip, /**< SCIP data structure */
4048  SCIP_VAR* var, /**< variable to set last strong branching values for */
4049  SCIP_Real lpobjval, /**< objective value of the current LP */
4050  SCIP_Real primsol, /**< primal solution value of the column in the current LP */
4051  SCIP_Real down, /**< dual bound after branching column down */
4052  SCIP_Real up, /**< dual bound after branching column up */
4053  SCIP_Bool downvalid, /**< is the returned down value a valid dual bound? */
4054  SCIP_Bool upvalid, /**< is the returned up value a valid dual bound? */
4055  SCIP_Longint iter, /**< total number of strong branching iterations */
4056  int itlim /**< iteration limit applied to the strong branching call */
4057  )
4058 {
4059  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetVarStrongbranchData", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4060 
4062  {
4063  SCIPerrorMessage("cannot set strong branching information on non-COLUMN variable\n");
4064  return SCIP_INVALIDDATA;
4065  }
4066 
4067  SCIPcolSetStrongbranchData(SCIPvarGetCol(var), scip->set, scip->stat, scip->lp, lpobjval, primsol,
4068  down, up, downvalid, upvalid, iter, itlim);
4069 
4070  return SCIP_OKAY;
4071 }
4072 
4073 /** rounds the current solution and tries it afterwards; if feasible, adds it to storage
4074  *
4075  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4076  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4077  *
4078  * @pre This method can be called if @p scip is in one of the following stages:
4079  * - \ref SCIP_STAGE_SOLVING
4080  */
4082  SCIP* scip, /**< SCIP data structure */
4083  SCIP_Bool* foundsol, /**< stores whether solution was feasible and good enough to keep */
4084  SCIP_Bool* cutoff /**< stores whether solution was cutoff due to exceeding the cutoffbound */
4085  )
4086 {
4087  assert(scip != NULL);
4088  assert(foundsol != NULL);
4089  assert(cutoff != NULL);
4090 
4091  SCIP_CALL( SCIPcheckStage(scip, "SCIPtryStrongbranchLPSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4092 
4093  if( scip->set->branch_checksbsol )
4094  {
4095  SCIP_SOL* sol;
4096  SCIP_Bool rounded = TRUE;
4097  SCIP_Real value = SCIPgetLPObjval(scip);
4098  SCIP_Longint oldnbestsolsfound = scip->primal->nbestsolsfound;
4099 
4100  /* start clock for strong branching solutions */
4101  SCIPclockStart(scip->stat->sbsoltime, scip->set);
4102 
4103  SCIP_CALL( SCIPcreateLPSol(scip, &sol, NULL) );
4105 
4106  /* try to round the strong branching solution */
4107  if( scip->set->branch_roundsbsol )
4108  {
4109  SCIP_CALL( SCIProundSol(scip, sol, &rounded) );
4110  }
4111 
4112  /* check the solution for feasibility if rounding worked well (or was not tried) */
4113  if( rounded )
4114  {
4115  SCIP_CALL( SCIPtrySolFree(scip, &sol, FALSE, FALSE, FALSE, TRUE, FALSE, foundsol) );
4116  }
4117  else
4118  {
4119  SCIP_CALL( SCIPfreeSol(scip, &sol) );
4120  }
4121 
4122  if( *foundsol )
4123  {
4124  SCIPdebugMsg(scip, "found new solution in strong branching\n");
4125 
4126  scip->stat->nsbsolsfound++;
4127 
4128  if( scip->primal->nbestsolsfound != oldnbestsolsfound )
4129  {
4130  scip->stat->nsbbestsolsfound++;
4131  }
4132 
4133  if( SCIPisGE(scip, value, SCIPgetCutoffbound(scip)) )
4134  *cutoff = TRUE;
4135  }
4136 
4137  /* stop clock for strong branching solutions */
4138  SCIPclockStop(scip->stat->sbsoltime, scip->set);
4139  }
4140  return SCIP_OKAY;
4141 }
4142 
4143 
4144 /** gets node number of the last node in current branch and bound run, where strong branching was used on the
4145  * given variable, or -1 if strong branching was never applied to the variable in current run
4146  *
4147  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4148  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4149  *
4150  * @pre This method can be called if @p scip is in one of the following stages:
4151  * - \ref SCIP_STAGE_TRANSFORMING
4152  * - \ref SCIP_STAGE_TRANSFORMED
4153  * - \ref SCIP_STAGE_INITPRESOLVE
4154  * - \ref SCIP_STAGE_PRESOLVING
4155  * - \ref SCIP_STAGE_EXITPRESOLVE
4156  * - \ref SCIP_STAGE_PRESOLVED
4157  * - \ref SCIP_STAGE_INITSOLVE
4158  * - \ref SCIP_STAGE_SOLVING
4159  * - \ref SCIP_STAGE_SOLVED
4160  * - \ref SCIP_STAGE_EXITSOLVE
4161  */
4163  SCIP* scip, /**< SCIP data structure */
4164  SCIP_VAR* var /**< variable to get last strong branching node for */
4165  )
4166 {
4167  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarStrongbranchNode", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4168 
4169  assert( var->scip == scip );
4170 
4172  return -1;
4173 
4175 }
4176 
4177 /** if strong branching was already applied on the variable at the current node, returns the number of LPs solved after
4178  * the LP where the strong branching on this variable was applied;
4179  * if strong branching was not yet applied on the variable at the current node, returns INT_MAX
4180  *
4181  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4182  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4183  *
4184  * @pre This method can be called if @p scip is in one of the following stages:
4185  * - \ref SCIP_STAGE_TRANSFORMING
4186  * - \ref SCIP_STAGE_TRANSFORMED
4187  * - \ref SCIP_STAGE_INITPRESOLVE
4188  * - \ref SCIP_STAGE_PRESOLVING
4189  * - \ref SCIP_STAGE_EXITPRESOLVE
4190  * - \ref SCIP_STAGE_PRESOLVED
4191  * - \ref SCIP_STAGE_INITSOLVE
4192  * - \ref SCIP_STAGE_SOLVING
4193  * - \ref SCIP_STAGE_SOLVED
4194  * - \ref SCIP_STAGE_EXITSOLVE
4195  */
4197  SCIP* scip, /**< SCIP data structure */
4198  SCIP_VAR* var /**< variable to get strong branching LP age for */
4199  )
4200 {
4201  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarStrongbranchLPAge", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4202 
4203  assert( var->scip == scip );
4204 
4206  return SCIP_LONGINT_MAX;
4207 
4208  return SCIPcolGetStrongbranchLPAge(SCIPvarGetCol(var), scip->stat);
4209 }
4210 
4211 /** gets number of times, strong branching was applied in current run on the given variable
4212  *
4213  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4214  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4215  *
4216  * @pre This method can be called if @p scip is in one of the following stages:
4217  * - \ref SCIP_STAGE_TRANSFORMING
4218  * - \ref SCIP_STAGE_TRANSFORMED
4219  * - \ref SCIP_STAGE_INITPRESOLVE
4220  * - \ref SCIP_STAGE_PRESOLVING
4221  * - \ref SCIP_STAGE_EXITPRESOLVE
4222  * - \ref SCIP_STAGE_PRESOLVED
4223  * - \ref SCIP_STAGE_INITSOLVE
4224  * - \ref SCIP_STAGE_SOLVING
4225  * - \ref SCIP_STAGE_SOLVED
4226  * - \ref SCIP_STAGE_EXITSOLVE
4227  */
4229  SCIP* scip, /**< SCIP data structure */
4230  SCIP_VAR* var /**< variable to get last strong branching node for */
4231  )
4232 {
4233  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarNStrongbranchs", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4234 
4235  assert( var->scip == scip );
4236 
4238  return 0;
4239 
4241 }
4242 
4243 /** adds given values to lock numbers of type @p locktype of variable for rounding
4244  *
4245  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4246  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4247  *
4248  * @pre This method can be called if @p scip is in one of the following stages:
4249  * - \ref SCIP_STAGE_PROBLEM
4250  * - \ref SCIP_STAGE_TRANSFORMING
4251  * - \ref SCIP_STAGE_TRANSFORMED
4252  * - \ref SCIP_STAGE_INITPRESOLVE
4253  * - \ref SCIP_STAGE_PRESOLVING
4254  * - \ref SCIP_STAGE_EXITPRESOLVE
4255  * - \ref SCIP_STAGE_PRESOLVED
4256  * - \ref SCIP_STAGE_INITSOLVE
4257  * - \ref SCIP_STAGE_SOLVING
4258  * - \ref SCIP_STAGE_EXITSOLVE
4259  * - \ref SCIP_STAGE_FREETRANS
4260  */
4262  SCIP* scip, /**< SCIP data structure */
4263  SCIP_VAR* var, /**< problem variable */
4264  SCIP_LOCKTYPE locktype, /**< type of the variable locks */
4265  int nlocksdown, /**< modification in number of rounding down locks */
4266  int nlocksup /**< modification in number of rounding up locks */
4267  )
4268 {
4269  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarLocksType", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4270 
4271  assert( var->scip == scip );
4272 
4273  switch( scip->set->stage )
4274  {
4275  case SCIP_STAGE_PROBLEM:
4276  assert(!SCIPvarIsTransformed(var));
4277  /*lint -fallthrough*/
4281  case SCIP_STAGE_PRESOLVING:
4283  case SCIP_STAGE_PRESOLVED:
4284  case SCIP_STAGE_INITSOLVE:
4285  case SCIP_STAGE_SOLVING:
4286  case SCIP_STAGE_EXITSOLVE:
4287  case SCIP_STAGE_FREETRANS:
4288  SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, locktype, nlocksdown, nlocksup) );
4289  return SCIP_OKAY;
4290 
4291  default:
4292  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4293  return SCIP_INVALIDCALL;
4294  } /*lint !e788*/
4295 }
4296 
4297 /** adds given values to lock numbers of variable for rounding
4298  *
4299  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4300  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4301  *
4302  * @pre This method can be called if @p scip is in one of the following stages:
4303  * - \ref SCIP_STAGE_PROBLEM
4304  * - \ref SCIP_STAGE_TRANSFORMING
4305  * - \ref SCIP_STAGE_TRANSFORMED
4306  * - \ref SCIP_STAGE_INITPRESOLVE
4307  * - \ref SCIP_STAGE_PRESOLVING
4308  * - \ref SCIP_STAGE_EXITPRESOLVE
4309  * - \ref SCIP_STAGE_PRESOLVED
4310  * - \ref SCIP_STAGE_INITSOLVE
4311  * - \ref SCIP_STAGE_SOLVING
4312  * - \ref SCIP_STAGE_EXITSOLVE
4313  * - \ref SCIP_STAGE_FREETRANS
4314  *
4315  * @note This method will always add variable locks of type model
4316  *
4317  * @note It is recommented to use SCIPaddVarLocksType()
4318  */
4320  SCIP* scip, /**< SCIP data structure */
4321  SCIP_VAR* var, /**< problem variable */
4322  int nlocksdown, /**< modification in number of rounding down locks */
4323  int nlocksup /**< modification in number of rounding up locks */
4324  )
4325 {
4326  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarLocks", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4327 
4328  SCIP_CALL( SCIPaddVarLocksType(scip, var, SCIP_LOCKTYPE_MODEL, nlocksdown, nlocksup) );
4329 
4330  return SCIP_OKAY;
4331 }
4332 
4333 /** add locks of variable with respect to the lock status of the constraint and its negation;
4334  * this method should be called whenever the lock status of a variable in a constraint changes, for example if
4335  * the coefficient of the variable changed its sign or if the left or right hand sides of the constraint were
4336  * added or removed
4337  *
4338  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4339  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4340  *
4341  * @pre This method can be called if @p scip is in one of the following stages:
4342  * - \ref SCIP_STAGE_PROBLEM
4343  * - \ref SCIP_STAGE_TRANSFORMING
4344  * - \ref SCIP_STAGE_TRANSFORMED
4345  * - \ref SCIP_STAGE_INITPRESOLVE
4346  * - \ref SCIP_STAGE_PRESOLVING
4347  * - \ref SCIP_STAGE_EXITPRESOLVE
4348  * - \ref SCIP_STAGE_INITSOLVE
4349  * - \ref SCIP_STAGE_SOLVING
4350  * - \ref SCIP_STAGE_EXITSOLVE
4351  * - \ref SCIP_STAGE_FREETRANS
4352  */
4354  SCIP* scip, /**< SCIP data structure */
4355  SCIP_VAR* var, /**< problem variable */
4356  SCIP_CONS* cons, /**< constraint */
4357  SCIP_Bool lockdown, /**< should the rounding be locked in downwards direction? */
4358  SCIP_Bool lockup /**< should the rounding be locked in upwards direction? */
4359  )
4360 {
4361  int nlocksdown[NLOCKTYPES];
4362  int nlocksup[NLOCKTYPES];
4363  int i;
4364 
4365  SCIP_CALL( SCIPcheckStage(scip, "SCIPlockVarCons", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4366 
4367  assert( var->scip == scip );
4368 
4369  for( i = 0; i < NLOCKTYPES; i++ )
4370  {
4371  nlocksdown[i] = 0;
4372  nlocksup[i] = 0;
4373 
4374  if( SCIPconsIsLockedTypePos(cons, (SCIP_LOCKTYPE) i) )
4375  {
4376  if( lockdown )
4377  ++nlocksdown[i];
4378  if( lockup )
4379  ++nlocksup[i];
4380  }
4381  if( SCIPconsIsLockedTypeNeg(cons, (SCIP_LOCKTYPE) i) )
4382  {
4383  if( lockdown )
4384  ++nlocksup[i];
4385  if( lockup )
4386  ++nlocksdown[i];
4387  }
4388  }
4389 
4390  switch( scip->set->stage )
4391  {
4392  case SCIP_STAGE_PROBLEM:
4393  assert(!SCIPvarIsTransformed(var));
4394  /*lint -fallthrough*/
4398  case SCIP_STAGE_PRESOLVING:
4400  case SCIP_STAGE_INITSOLVE:
4401  case SCIP_STAGE_SOLVING:
4402  case SCIP_STAGE_EXITSOLVE:
4403  case SCIP_STAGE_FREETRANS:
4404  for( i = 0; i < NLOCKTYPES; i++ )
4405  {
4406  if( nlocksdown[i] == 0 && nlocksup[i] == 0 )
4407  continue;
4408 
4409  SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, (SCIP_LOCKTYPE) i, nlocksdown[i], nlocksup[i]) );
4410  }
4411  return SCIP_OKAY;
4412 
4413  default:
4414  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4415  return SCIP_INVALIDCALL;
4416  } /*lint !e788*/
4417 }
4418 
4419 /** remove locks of type @p locktype of variable with respect to the lock status of the constraint and its negation;
4420  * this method should be called whenever the lock status of a variable in a constraint changes, for example if
4421  * the coefficient of the variable changed its sign or if the left or right hand sides of the constraint were
4422  * added or removed
4423  *
4424  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4425  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4426  *
4427  * @pre This method can be called if @p scip is in one of the following stages:
4428  * - \ref SCIP_STAGE_PROBLEM
4429  * - \ref SCIP_STAGE_TRANSFORMING
4430  * - \ref SCIP_STAGE_TRANSFORMED
4431  * - \ref SCIP_STAGE_INITPRESOLVE
4432  * - \ref SCIP_STAGE_PRESOLVING
4433  * - \ref SCIP_STAGE_EXITPRESOLVE
4434  * - \ref SCIP_STAGE_INITSOLVE
4435  * - \ref SCIP_STAGE_SOLVING
4436  * - \ref SCIP_STAGE_EXITSOLVE
4437  * - \ref SCIP_STAGE_FREETRANS
4438  */
4440  SCIP* scip, /**< SCIP data structure */
4441  SCIP_VAR* var, /**< problem variable */
4442  SCIP_CONS* cons, /**< constraint */
4443  SCIP_Bool lockdown, /**< should the rounding be unlocked in downwards direction? */
4444  SCIP_Bool lockup /**< should the rounding be unlocked in upwards direction? */
4445  )
4446 {
4447  int nlocksdown[NLOCKTYPES];
4448  int nlocksup[NLOCKTYPES];
4449  int i;
4450 
4451  SCIP_CALL( SCIPcheckStage(scip, "SCIPunlockVarCons", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4452 
4453  assert( var->scip == scip );
4454 
4455  for( i = 0; i < NLOCKTYPES; i++ )
4456  {
4457  nlocksdown[i] = 0;
4458  nlocksup[i] = 0;
4459 
4460  if( SCIPconsIsLockedTypePos(cons, (SCIP_LOCKTYPE) i) )
4461  {
4462  if( lockdown )
4463  ++nlocksdown[i];
4464  if( lockup )
4465  ++nlocksup[i];
4466  }
4467  if( SCIPconsIsLockedTypeNeg(cons, (SCIP_LOCKTYPE) i) )
4468  {
4469  if( lockdown )
4470  ++nlocksup[i];
4471  if( lockup )
4472  ++nlocksdown[i];
4473  }
4474  }
4475  switch( scip->set->stage )
4476  {
4477  case SCIP_STAGE_PROBLEM:
4478  assert(!SCIPvarIsTransformed(var));
4479  /*lint -fallthrough*/
4483  case SCIP_STAGE_PRESOLVING:
4485  case SCIP_STAGE_INITSOLVE:
4486  case SCIP_STAGE_SOLVING:
4487  case SCIP_STAGE_EXITSOLVE:
4488  case SCIP_STAGE_FREETRANS:
4489  for( i = 0; i < NLOCKTYPES; i++ )
4490  {
4491  if( nlocksdown[i] == 0 && nlocksup[i] == 0 )
4492  continue;
4493 
4494  SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, (SCIP_LOCKTYPE) i, -nlocksdown[i], -nlocksup[i]) );
4495  }
4496  return SCIP_OKAY;
4497 
4498  default:
4499  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4500  return SCIP_INVALIDCALL;
4501  } /*lint !e788*/
4502 }
4503 
4504 /** changes variable's objective value
4505  *
4506  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4507  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4508  *
4509  * @pre This method can be called if @p scip is in one of the following stages:
4510  * - \ref SCIP_STAGE_PROBLEM
4511  * - \ref SCIP_STAGE_TRANSFORMING
4512  * - \ref SCIP_STAGE_PRESOLVING
4513  * - \ref SCIP_STAGE_PRESOLVED
4514  */
4516  SCIP* scip, /**< SCIP data structure */
4517  SCIP_VAR* var, /**< variable to change the objective value for */
4518  SCIP_Real newobj /**< new objective value */
4519  )
4520 {
4521  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarObj", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
4522 
4523  assert( var->scip == scip );
4524 
4525  /* forbid infinite objective values */
4526  if( SCIPisInfinity(scip, REALABS(newobj)) )
4527  {
4528  SCIPerrorMessage("invalid objective value: objective value is infinite\n");
4529  return SCIP_INVALIDDATA;
4530  }
4531 
4532  switch( scip->set->stage )
4533  {
4534  case SCIP_STAGE_PROBLEM:
4535  assert(!SCIPvarIsTransformed(var));
4536  SCIP_CALL( SCIPvarChgObj(var, scip->mem->probmem, scip->set, scip->origprob, scip->primal, scip->lp, scip->eventqueue, newobj) );
4537  return SCIP_OKAY;
4538 
4541  case SCIP_STAGE_PRESOLVING:
4542  case SCIP_STAGE_PRESOLVED:
4543  SCIP_CALL( SCIPvarChgObj(var, scip->mem->probmem, scip->set, scip->transprob, scip->primal, scip->lp, scip->eventqueue, newobj) );
4544  return SCIP_OKAY;
4545 
4546  default:
4547  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4548  return SCIP_INVALIDCALL;
4549  } /*lint !e788*/
4550 }
4551 
4552 /** adds value to variable's objective value
4553  *
4554  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4555  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4556  *
4557  * @pre This method can be called if @p scip is in one of the following stages:
4558  * - \ref SCIP_STAGE_PROBLEM
4559  * - \ref SCIP_STAGE_TRANSFORMING
4560  * - \ref SCIP_STAGE_PRESOLVING
4561  * - \ref SCIP_STAGE_EXITPRESOLVE
4562  * - \ref SCIP_STAGE_PRESOLVED
4563  */
4565  SCIP* scip, /**< SCIP data structure */
4566  SCIP_VAR* var, /**< variable to change the objective value for */
4567  SCIP_Real addobj /**< additional objective value */
4568  )
4569 {
4570  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarObj", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
4571 
4572  assert( var->scip == scip );
4573 
4574  switch( scip->set->stage )
4575  {
4576  case SCIP_STAGE_PROBLEM:
4577  assert(!SCIPvarIsTransformed(var));
4578  SCIP_CALL( SCIPvarAddObj(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->primal,
4579  scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue, addobj) );
4580  return SCIP_OKAY;
4581 
4583  case SCIP_STAGE_PRESOLVING:
4585  case SCIP_STAGE_PRESOLVED:
4586  SCIP_CALL( SCIPvarAddObj(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->primal,
4587  scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue, addobj) );
4588  return SCIP_OKAY;
4589 
4590  default:
4591  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4592  return SCIP_INVALIDCALL;
4593  } /*lint !e788*/
4594 }
4595 
4596 /** returns the adjusted (i.e. rounded, if the given variable is of integral type) lower bound value;
4597  * does not change the bounds of the variable
4598  *
4599  * @return adjusted lower bound for the given variable; the bound of the variable is not changed
4600  *
4601  * @pre This method can be called if @p scip is in one of the following stages:
4602  * - \ref SCIP_STAGE_PROBLEM
4603  * - \ref SCIP_STAGE_TRANSFORMING
4604  * - \ref SCIP_STAGE_TRANSFORMED
4605  * - \ref SCIP_STAGE_INITPRESOLVE
4606  * - \ref SCIP_STAGE_PRESOLVING
4607  * - \ref SCIP_STAGE_EXITPRESOLVE
4608  * - \ref SCIP_STAGE_PRESOLVED
4609  * - \ref SCIP_STAGE_INITSOLVE
4610  * - \ref SCIP_STAGE_SOLVING
4611  * - \ref SCIP_STAGE_SOLVED
4612  * - \ref SCIP_STAGE_EXITSOLVE
4613  * - \ref SCIP_STAGE_FREETRANS
4614  */
4616  SCIP* scip, /**< SCIP data structure */
4617  SCIP_VAR* var, /**< variable to adjust the bound for */
4618  SCIP_Real lb /**< lower bound value to adjust */
4619  )
4620 {
4621  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPadjustedVarLb", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
4622 
4623  SCIPvarAdjustLb(var, scip->set, &lb);
4624 
4625  return lb;
4626 }
4627 
4628 /** returns the adjusted (i.e. rounded, if the given variable is of integral type) upper bound value;
4629  * does not change the bounds of the variable
4630  *
4631  * @return adjusted upper bound for the given variable; the bound of the variable is not changed
4632  *
4633  * @pre This method can be called if @p scip is in one of the following stages:
4634  * - \ref SCIP_STAGE_PROBLEM
4635  * - \ref SCIP_STAGE_TRANSFORMING
4636  * - \ref SCIP_STAGE_TRANSFORMED
4637  * - \ref SCIP_STAGE_INITPRESOLVE
4638  * - \ref SCIP_STAGE_PRESOLVING
4639  * - \ref SCIP_STAGE_EXITPRESOLVE
4640  * - \ref SCIP_STAGE_PRESOLVED
4641  * - \ref SCIP_STAGE_INITSOLVE
4642  * - \ref SCIP_STAGE_SOLVING
4643  * - \ref SCIP_STAGE_SOLVED
4644  * - \ref SCIP_STAGE_EXITSOLVE
4645  * - \ref SCIP_STAGE_FREETRANS
4646  */
4648  SCIP* scip, /**< SCIP data structure */
4649  SCIP_VAR* var, /**< variable to adjust the bound for */
4650  SCIP_Real ub /**< upper bound value to adjust */
4651  )
4652 {
4653  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPadjustedVarUb", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
4654 
4655  SCIPvarAdjustUb(var, scip->set, &ub);
4656 
4657  return ub;
4658 }
4659 
4660 /** depending on SCIP's stage, changes lower bound of variable in the problem, in preprocessing, or in current node;
4661  * if possible, adjusts bound to integral value; doesn't store any inference information in the bound change, such
4662  * that in conflict analysis, this change is treated like a branching decision
4663  *
4664  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4665  * SCIPgetVars()) gets resorted.
4666  *
4667  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4668  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4669  *
4670  * @pre This method can be called if @p scip is in one of the following stages:
4671  * - \ref SCIP_STAGE_PROBLEM
4672  * - \ref SCIP_STAGE_TRANSFORMING
4673  * - \ref SCIP_STAGE_PRESOLVING
4674  * - \ref SCIP_STAGE_SOLVING
4675  *
4676  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4677  */
4679  SCIP* scip, /**< SCIP data structure */
4680  SCIP_VAR* var, /**< variable to change the bound for */
4681  SCIP_Real newbound /**< new value for bound */
4682  )
4683 {
4684  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLb", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4685 
4686  SCIPvarAdjustLb(var, scip->set, &newbound);
4687 
4688  /* ignore tightenings of lower bounds to +infinity during solving process */
4689  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4690  {
4691 #ifndef NDEBUG
4692  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4693  SCIPvarGetLbLocal(var));
4694 #endif
4695  return SCIP_OKAY;
4696  }
4697 
4698  switch( scip->set->stage )
4699  {
4700  case SCIP_STAGE_PROBLEM:
4701  assert(!SCIPvarIsTransformed(var));
4702  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4703  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4704  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4705  scip->branchcand, scip->eventqueue, newbound) );
4706  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
4707  break;
4708 
4710  case SCIP_STAGE_PRESOLVED:
4711  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4712  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4713  break;
4714 
4715  case SCIP_STAGE_PRESOLVING:
4716  if( !SCIPinProbing(scip) )
4717  {
4718  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4719  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4720 
4721  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4722  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable,
4723  var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
4724 
4726  {
4727  SCIP_Bool infeasible;
4728 
4729  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
4730  assert(!infeasible);
4731  }
4732  break;
4733  }
4734  /*lint -fallthrough*/
4735  case SCIP_STAGE_SOLVING:
4737  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4738  scip->cliquetable, var, newbound,
4740  break;
4741 
4742  default:
4743  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4744  return SCIP_INVALIDCALL;
4745  } /*lint !e788*/
4746 
4747  return SCIP_OKAY;
4748 }
4749 
4750 /** depending on SCIP's stage, changes upper bound of variable in the problem, in preprocessing, or in current node;
4751  * if possible, adjusts bound to integral value; doesn't store any inference information in the bound change, such
4752  * that in conflict analysis, this change is treated like a branching decision
4753  *
4754  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4755  * SCIPgetVars()) gets resorted.
4756  *
4757  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4758  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4759  *
4760  * @pre This method can be called if @p scip is in one of the following stages:
4761  * - \ref SCIP_STAGE_PROBLEM
4762  * - \ref SCIP_STAGE_TRANSFORMING
4763  * - \ref SCIP_STAGE_PRESOLVING
4764  * - \ref SCIP_STAGE_SOLVING
4765  *
4766  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4767  */
4769  SCIP* scip, /**< SCIP data structure */
4770  SCIP_VAR* var, /**< variable to change the bound for */
4771  SCIP_Real newbound /**< new value for bound */
4772  )
4773 {
4774  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUb", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4775 
4776  SCIPvarAdjustUb(var, scip->set, &newbound);
4777 
4778  /* ignore tightenings of upper bounds to -infinity during solving process */
4779  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4780  {
4781 #ifndef NDEBUG
4782  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
4783  SCIPvarGetUbLocal(var));
4784 #endif
4785  return SCIP_OKAY;
4786  }
4787 
4788  switch( scip->set->stage )
4789  {
4790  case SCIP_STAGE_PROBLEM:
4791  assert(!SCIPvarIsTransformed(var));
4792  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4793  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4794  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4795  scip->branchcand, scip->eventqueue, newbound) );
4796  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
4797  break;
4798 
4800  case SCIP_STAGE_PRESOLVED:
4801  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4802  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4803  break;
4804 
4805  case SCIP_STAGE_PRESOLVING:
4806  if( !SCIPinProbing(scip) )
4807  {
4808  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4809  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4810 
4811  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4812  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4813  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
4814 
4816  {
4817  SCIP_Bool infeasible;
4818 
4819  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
4820  assert(!infeasible);
4821  }
4822  break;
4823  }
4824  /*lint -fallthrough*/
4825  case SCIP_STAGE_SOLVING:
4827  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4828  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
4829  break;
4830 
4831  default:
4832  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4833  return SCIP_INVALIDCALL;
4834  } /*lint !e788*/
4835 
4836  return SCIP_OKAY;
4837 }
4838 
4839 /** changes lower bound of variable in the given node; if possible, adjust bound to integral value; doesn't store any
4840  * inference information in the bound change, such that in conflict analysis, this change is treated like a branching
4841  * decision
4842  *
4843  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4844  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4845  *
4846  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
4847  */
4849  SCIP* scip, /**< SCIP data structure */
4850  SCIP_NODE* node, /**< node to change bound at, or NULL for current node */
4851  SCIP_VAR* var, /**< variable to change the bound for */
4852  SCIP_Real newbound /**< new value for bound */
4853  )
4854 {
4855  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbNode", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4856 
4857  if( node == NULL )
4858  {
4859  SCIP_CALL( SCIPchgVarLb(scip, var, newbound) );
4860  }
4861  else
4862  {
4863  SCIPvarAdjustLb(var, scip->set, &newbound);
4864 
4865  /* ignore tightenings of lower bounds to +infinity during solving process */
4866  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4867  {
4868 #ifndef NDEBUG
4869  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4870  SCIPvarGetLbLocal(var));
4871 #endif
4872  return SCIP_OKAY;
4873  }
4874 
4875  SCIP_CALL( SCIPnodeAddBoundchg(node, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
4876  scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4878  }
4879 
4880  return SCIP_OKAY;
4881 }
4882 
4883 /** changes upper bound of variable in the given node; if possible, adjust bound to integral value; doesn't store any
4884  * inference information in the bound change, such that in conflict analysis, this change is treated like a branching
4885  * decision
4886  *
4887  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4888  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4889  *
4890  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
4891  */
4893  SCIP* scip, /**< SCIP data structure */
4894  SCIP_NODE* node, /**< node to change bound at, or NULL for current node */
4895  SCIP_VAR* var, /**< variable to change the bound for */
4896  SCIP_Real newbound /**< new value for bound */
4897  )
4898 {
4899  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbNode", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4900 
4901  if( node == NULL )
4902  {
4903  SCIP_CALL( SCIPchgVarUb(scip, var, newbound) );
4904  }
4905  else
4906  {
4907  SCIPvarAdjustUb(var, scip->set, &newbound);
4908 
4909  /* ignore tightenings of upper bounds to -infinity during solving process */
4910  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4911  {
4912 #ifndef NDEBUG
4913  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
4914  SCIPvarGetUbLocal(var));
4915 #endif
4916  return SCIP_OKAY;
4917  }
4918 
4919  SCIP_CALL( SCIPnodeAddBoundchg(node, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
4920  scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4922  }
4923 
4924  return SCIP_OKAY;
4925 }
4926 
4927 /** changes global lower bound of variable; if possible, adjust bound to integral value; also tightens the local bound,
4928  * if the global bound is better than the local bound
4929  *
4930  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4931  * SCIPgetVars()) gets resorted.
4932  *
4933  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4934  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4935  *
4936  * @pre This method can be called if @p scip is in one of the following stages:
4937  * - \ref SCIP_STAGE_PROBLEM
4938  * - \ref SCIP_STAGE_TRANSFORMING
4939  * - \ref SCIP_STAGE_TRANSFORMED
4940  * - \ref SCIP_STAGE_PRESOLVING
4941  * - \ref SCIP_STAGE_SOLVING
4942  *
4943  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4944  */
4946  SCIP* scip, /**< SCIP data structure */
4947  SCIP_VAR* var, /**< variable to change the bound for */
4948  SCIP_Real newbound /**< new value for bound */
4949  )
4950 {
4951  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbGlobal", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4952 
4953  SCIPvarAdjustLb(var, scip->set, &newbound);
4954 
4955  /* ignore tightenings of lower bounds to +infinity during solving process */
4956  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4957  {
4958 #ifndef NDEBUG
4959  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4960  SCIPvarGetLbLocal(var));
4961 #endif
4962  return SCIP_OKAY;
4963  }
4964 
4965  switch( scip->set->stage )
4966  {
4967  case SCIP_STAGE_PROBLEM:
4968  assert(!SCIPvarIsTransformed(var));
4969  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4970  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4971  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4972  scip->branchcand, scip->eventqueue, newbound) );
4973  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
4974  break;
4975 
4978  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4979  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4980  break;
4981 
4982  case SCIP_STAGE_PRESOLVING:
4983  if( !SCIPinProbing(scip) )
4984  {
4985  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4986  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4987 
4988  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4989  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4991 
4993  {
4994  SCIP_Bool infeasible;
4995 
4996  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
4997  assert(!infeasible);
4998  }
4999  break;
5000  }
5001  /*lint -fallthrough*/
5002  case SCIP_STAGE_SOLVING:
5003  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5004  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5006  break;
5007 
5008  default:
5009  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5010  return SCIP_INVALIDCALL;
5011  } /*lint !e788*/
5012 
5013  return SCIP_OKAY;
5014 }
5015 
5016 /** changes global upper bound of variable; if possible, adjust bound to integral value; also tightens the local bound,
5017  * if the global bound is better than the local bound
5018  *
5019  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5020  * SCIPgetVars()) gets resorted.
5021  *
5022  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5023  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5024  *
5025  * @pre This method can be called if @p scip is in one of the following stages:
5026  * - \ref SCIP_STAGE_PROBLEM
5027  * - \ref SCIP_STAGE_TRANSFORMING
5028  * - \ref SCIP_STAGE_TRANSFORMED
5029  * - \ref SCIP_STAGE_PRESOLVING
5030  * - \ref SCIP_STAGE_SOLVING
5031  *
5032  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5033  */
5035  SCIP* scip, /**< SCIP data structure */
5036  SCIP_VAR* var, /**< variable to change the bound for */
5037  SCIP_Real newbound /**< new value for bound */
5038  )
5039 {
5040  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbGlobal", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5041 
5042  SCIPvarAdjustUb(var, scip->set, &newbound);
5043 
5044  /* ignore tightenings of upper bounds to -infinity during solving process */
5045  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5046  {
5047 #ifndef NDEBUG
5048  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5049  SCIPvarGetUbLocal(var));
5050 #endif
5051  return SCIP_OKAY;
5052  }
5053 
5054  switch( scip->set->stage )
5055  {
5056  case SCIP_STAGE_PROBLEM:
5057  assert(!SCIPvarIsTransformed(var));
5058  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5059  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5060  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5061  scip->branchcand, scip->eventqueue, newbound) );
5062  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
5063  break;
5064 
5067  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5068  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5069  break;
5070 
5071  case SCIP_STAGE_PRESOLVING:
5072  if( !SCIPinProbing(scip) )
5073  {
5074  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5075  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5076 
5077  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5078  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5080 
5082  {
5083  SCIP_Bool infeasible;
5084 
5085  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
5086  assert(!infeasible);
5087  }
5088  break;
5089  }
5090  /*lint -fallthrough*/
5091  case SCIP_STAGE_SOLVING:
5092  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5093  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5095  break;
5096 
5097  default:
5098  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5099  return SCIP_INVALIDCALL;
5100  } /*lint !e788*/
5101 
5102  return SCIP_OKAY;
5103 }
5104 
5105 /** changes lazy lower bound of the variable, this is only possible if the variable is not in the LP yet
5106  *
5107  * Lazy bounds are bounds that are already enforced by constraints and the objective function.
5108  * Setting a lazy lower bound has the consequence that for variables which lower bound equals the lazy lower bound,
5109  * the lower bound does not need to be passed on to the LP solver.
5110  * This is especially useful in a column generation (branch-and-price) setting.
5111  *
5112  * @attention If the variable has a global lower bound below lazylb, then the global lower bound is tightened to
5113  * lazylb by a call to SCIPchgVarLbGlobal().
5114  *
5115  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5116  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5117  *
5118  * @pre This method can be called if @p scip is in one of the following stages:
5119  * - \ref SCIP_STAGE_PROBLEM
5120  * - \ref SCIP_STAGE_TRANSFORMING
5121  * - \ref SCIP_STAGE_TRANSFORMED
5122  * - \ref SCIP_STAGE_PRESOLVING
5123  * - \ref SCIP_STAGE_SOLVING
5124  */
5126  SCIP* scip, /**< SCIP data structure */
5127  SCIP_VAR* var, /**< problem variable */
5128  SCIP_Real lazylb /**< the lazy lower bound to be set */
5129  )
5130 {
5131  assert(scip != NULL);
5132  assert(var != NULL);
5133 
5134  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbLazy", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5135 
5136  if( SCIPisGT(scip, lazylb, SCIPvarGetLbGlobal(var)) )
5137  {
5138  SCIP_CALL( SCIPchgVarLbGlobal(scip, var, lazylb) );
5139  }
5140 
5141  SCIP_CALL( SCIPvarChgLbLazy(var, scip->set, lazylb) );
5142 
5143  return SCIP_OKAY;
5144 }
5145 
5146 /** changes lazy upper bound of the variable, this is only possible if the variable is not in the LP yet
5147  *
5148  * Lazy bounds are bounds that are already enforced by constraints and the objective function.
5149  * Setting a lazy upper bound has the consequence that for variables which upper bound equals the lazy upper bound,
5150  * the upper bound does not need to be passed on to the LP solver.
5151  * This is especially useful in a column generation (branch-and-price) setting.
5152  *
5153  * @attention If the variable has a global upper bound above lazyub, then the global upper bound is tightened to
5154  * lazyub by a call to SCIPchgVarUbGlobal().
5155  *
5156  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5157  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5158  *
5159  * @pre This method can be called if @p scip is in one of the following stages:
5160  * - \ref SCIP_STAGE_PROBLEM
5161  * - \ref SCIP_STAGE_TRANSFORMING
5162  * - \ref SCIP_STAGE_TRANSFORMED
5163  * - \ref SCIP_STAGE_PRESOLVING
5164  * - \ref SCIP_STAGE_SOLVING
5165  */
5167  SCIP* scip, /**< SCIP data structure */
5168  SCIP_VAR* var, /**< problem variable */
5169  SCIP_Real lazyub /**< the lazy lower bound to be set */
5170  )
5171 {
5172  assert(scip != NULL);
5173  assert(var != NULL);
5174 
5175  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbLazy", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5176 
5177  if( SCIPisLT(scip, lazyub, SCIPvarGetUbGlobal(var)) )
5178  {
5179  SCIP_CALL( SCIPchgVarUbGlobal(scip, var, lazyub) );
5180  }
5181 
5182  SCIP_CALL( SCIPvarChgUbLazy(var, scip->set, lazyub) );
5183 
5184  return SCIP_OKAY;
5185 }
5186 
5187 /** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
5188  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5189  * doesn't store any inference information in the bound change, such that in conflict analysis, this change
5190  * is treated like a branching decision
5191  *
5192  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5193  * SCIPgetVars()) gets resorted.
5194  *
5195  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5196  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5197  *
5198  * @pre This method can be called if @p scip is in one of the following stages:
5199  * - \ref SCIP_STAGE_PROBLEM
5200  * - \ref SCIP_STAGE_PRESOLVING
5201  * - \ref SCIP_STAGE_SOLVING
5202  *
5203  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5204  */
5206  SCIP* scip, /**< SCIP data structure */
5207  SCIP_VAR* var, /**< variable to change the bound for */
5208  SCIP_Real newbound, /**< new value for bound */
5209  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5210  SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
5211  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5212  )
5213 {
5214  SCIP_Real lb;
5215  SCIP_Real ub;
5216 
5217  assert(infeasible != NULL);
5218 
5219  SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarLb", FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5220  /** @todo if needed provide pending local/global bound changes that will be flushed after leaving diving mode (as in struct_tree.h) */
5221  assert(SCIPgetStage(scip) == SCIP_STAGE_PROBLEM || !SCIPinDive(scip));
5222 
5223  *infeasible = FALSE;
5224  if( tightened != NULL )
5225  *tightened = FALSE;
5226 
5227  SCIPvarAdjustLb(var, scip->set, &newbound);
5228 
5229  /* ignore tightenings of lower bounds to +infinity during solving process */
5230  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5231  {
5232 #ifndef NDEBUG
5233  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
5234  SCIPvarGetLbLocal(var));
5235 #endif
5236  return SCIP_OKAY;
5237  }
5238 
5239  /* get current bounds */
5240  lb = SCIPcomputeVarLbLocal(scip, var);
5241  ub = SCIPcomputeVarUbLocal(scip, var);
5242  assert(SCIPsetIsLE(scip->set, lb, ub));
5243 
5244  if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
5245  {
5246  *infeasible = TRUE;
5247  return SCIP_OKAY;
5248  }
5249  newbound = MIN(newbound, ub);
5250 
5251  if( (force && SCIPsetIsLE(scip->set, newbound, lb)) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
5252  return SCIP_OKAY;
5253 
5254  switch( scip->set->stage )
5255  {
5256  case SCIP_STAGE_PROBLEM:
5257  assert(!SCIPvarIsTransformed(var));
5258  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5259  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5260  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5261  scip->branchcand, scip->eventqueue, newbound) );
5262  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
5263  break;
5265  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5266  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5267  break;
5268  case SCIP_STAGE_PRESOLVING:
5269  if( !SCIPinProbing(scip) )
5270  {
5271  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5272  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5273 
5274  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5275  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5277 
5279  {
5280  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5281  assert(!(*infeasible));
5282  }
5283  break;
5284  }
5285  /*lint -fallthrough*/
5286  case SCIP_STAGE_SOLVING:
5288  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable,
5289  var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
5290  break;
5291 
5292  default:
5293  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5294  return SCIP_INVALIDCALL;
5295  } /*lint !e788*/
5296 
5297  /* check whether the lower bound improved */
5298  if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
5299  *tightened = TRUE;
5300 
5301  return SCIP_OKAY;
5302 }
5303 
5304 /** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
5305  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5306  * doesn't store any inference information in the bound change, such that in conflict analysis, this change
5307  * is treated like a branching decision
5308  *
5309  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5310  * SCIPgetVars()) gets resorted.
5311  *
5312  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5313  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5314  *
5315  * @pre This method can be called if @p scip is in one of the following stages:
5316  * - \ref SCIP_STAGE_PROBLEM
5317  * - \ref SCIP_STAGE_PRESOLVING
5318  * - \ref SCIP_STAGE_SOLVING
5319  *
5320  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5321  */
5323  SCIP* scip, /**< SCIP data structure */
5324  SCIP_VAR* var, /**< variable to change the bound for */
5325  SCIP_Real newbound, /**< new value for bound */
5326  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5327  SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
5328  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5329  )
5330 {
5331  SCIP_Real lb;
5332  SCIP_Real ub;
5333 
5334  assert(infeasible != NULL);
5335  SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarUb", FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5336 
5337  /** @todo if needed provide pending local/global bound changes that will be flushed after leaving diving mode (as in struct_tree.h) */
5338  assert(SCIPgetStage(scip) == SCIP_STAGE_PROBLEM || !SCIPinDive(scip));
5339 
5340  *infeasible = FALSE;
5341  if( tightened != NULL )
5342  *tightened = FALSE;
5343 
5344  SCIPvarAdjustUb(var, scip->set, &newbound);
5345 
5346  /* ignore tightenings of upper bounds to -infinity during solving process */
5347  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5348  {
5349 #ifndef NDEBUG
5350  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5351  SCIPvarGetUbLocal(var));
5352 #endif
5353  return SCIP_OKAY;
5354  }
5355 
5356  /* get current bounds */
5357  lb = SCIPcomputeVarLbLocal(scip, var);
5358  ub = SCIPcomputeVarUbLocal(scip, var);
5359  assert(SCIPsetIsLE(scip->set, lb, ub));
5360 
5361  if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
5362  {
5363  *infeasible = TRUE;
5364  return SCIP_OKAY;
5365  }
5366  newbound = MAX(newbound, lb);
5367 
5368  if( (force && SCIPsetIsGE(scip->set, newbound, ub)) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
5369  return SCIP_OKAY;
5370 
5371  switch( scip->set->stage )
5372  {
5373  case SCIP_STAGE_PROBLEM:
5374  assert(!SCIPvarIsTransformed(var));
5375  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5376  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5377  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5378  scip->branchcand, scip->eventqueue, newbound) );
5379  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
5380  break;
5382  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5383  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5384  break;
5385  case SCIP_STAGE_PRESOLVING:
5386  if( !SCIPinProbing(scip) )
5387  {
5388  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5389  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5390 
5391  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5392  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5394 
5396  {
5397  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5398  assert(!(*infeasible));
5399  }
5400  break;
5401  }
5402  /*lint -fallthrough*/
5403  case SCIP_STAGE_SOLVING:
5405  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5406  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
5407  break;
5408 
5409  default:
5410  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5411  return SCIP_INVALIDCALL;
5412  } /*lint !e788*/
5413 
5414  /* check whether the upper bound improved */
5415  if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
5416  *tightened = TRUE;
5417 
5418  return SCIP_OKAY;
5419 }
5420 
5421 /** fixes variable in preprocessing or in the current node, if the new bound is tighter (w.r.t. bound strengthening
5422  * epsilon) than the current bound; if possible, adjusts bound to integral value; the given inference constraint is
5423  * stored, such that the conflict analysis is able to find out the reason for the deduction of the bound change
5424  *
5425  * @note In presolving stage when not in probing mode the variable will be fixed directly, otherwise this method
5426  * changes first the lowerbound by calling SCIPinferVarLbCons and second the upperbound by calling
5427  * SCIPinferVarUbCons
5428  *
5429  * @note If SCIP is in presolving stage, it can happen that the internal variable array (which get be accessed via
5430  * SCIPgetVars()) gets resorted.
5431  *
5432  * @note During presolving, an integer variable which bound changes to {0,1} is upgraded to a binary variable.
5433  */
5435  SCIP* scip, /**< SCIP data structure */
5436  SCIP_VAR* var, /**< variable to change the bound for */
5437  SCIP_Real fixedval, /**< new value for fixation */
5438  SCIP_CONS* infercons, /**< constraint that deduced the bound change */
5439  int inferinfo, /**< user information for inference to help resolving the conflict */
5440  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5441  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5442  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5443  )
5444 {
5445  assert(scip != NULL);
5446  assert(var != NULL);
5447  assert(infeasible != NULL);
5448 
5449  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarFixCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5450 
5451  if( tightened != NULL )
5452  *tightened = FALSE;
5453 
5454  /* in presolving case we take the shortcut to directly fix the variables */
5455  if( SCIPgetStage(scip) == SCIP_STAGE_PRESOLVING && SCIPtreeGetCurrentDepth(scip->tree) == 0 )
5456  {
5457  SCIP_Bool fixed;
5458 
5459  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5460  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter,
5461  scip->eventqueue, scip->cliquetable, fixedval, infeasible, &fixed) );
5462 
5463  if( tightened != NULL )
5464  *tightened = fixed;
5465  }
5466  /* otherwise we use the lb and ub methods */
5467  else
5468  {
5469  SCIP_Bool lbtightened;
5470 
5471  SCIP_CALL( SCIPinferVarLbCons(scip, var, fixedval, infercons, inferinfo, force, infeasible, &lbtightened) );
5472 
5473  if( ! (*infeasible) )
5474  {
5475  SCIP_CALL( SCIPinferVarUbCons(scip, var, fixedval, infercons, inferinfo, force, infeasible, tightened) );
5476 
5477  if( tightened != NULL )
5478  *tightened |= lbtightened;
5479  }
5480  }
5481 
5482  return SCIP_OKAY;
5483 }
5484 
5485 /** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
5486  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5487  * the given inference constraint is stored, such that the conflict analysis is able to find out the reason
5488  * for the deduction of the bound change
5489  *
5490  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5491  * SCIPgetVars()) gets resorted.
5492  *
5493  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5494  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5495  *
5496  * @pre This method can be called if @p scip is in one of the following stages:
5497  * - \ref SCIP_STAGE_PROBLEM
5498  * - \ref SCIP_STAGE_PRESOLVING
5499  * - \ref SCIP_STAGE_SOLVING
5500  *
5501  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5502  */
5504  SCIP* scip, /**< SCIP data structure */
5505  SCIP_VAR* var, /**< variable to change the bound for */
5506  SCIP_Real newbound, /**< new value for bound */
5507  SCIP_CONS* infercons, /**< constraint that deduced the bound change */
5508  int inferinfo, /**< user information for inference to help resolving the conflict */
5509  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5510  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5511  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5512  )
5513 {
5514  SCIP_Real lb;
5515  SCIP_Real ub;
5516 
5517  assert(infeasible != NULL);
5518 
5519  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarLbCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5520 
5521  *infeasible = FALSE;
5522  if( tightened != NULL )
5523  *tightened = FALSE;
5524 
5525  SCIPvarAdjustLb(var, scip->set, &newbound);
5526 
5527  /* ignore tightenings of lower bounds to +infinity during solving process */
5528  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5529  {
5530 #ifndef NDEBUG
5531  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
5532  SCIPvarGetLbLocal(var));
5533 #endif
5534  return SCIP_OKAY;
5535  }
5536 
5537  /* get current bounds */
5538  lb = SCIPvarGetLbLocal(var);
5539  ub = SCIPvarGetUbLocal(var);
5540  assert(SCIPsetIsLE(scip->set, lb, ub));
5541 
5542  if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
5543  {
5544  *infeasible = TRUE;
5545  return SCIP_OKAY;
5546  }
5547  newbound = MIN(newbound, ub);
5548 
5549  if( (force && SCIPsetIsLE(scip->set, newbound, lb)) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
5550  return SCIP_OKAY;
5551 
5552  switch( scip->set->stage )
5553  {
5554  case SCIP_STAGE_PROBLEM:
5555  assert(!SCIPvarIsTransformed(var));
5556  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5557  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5558  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5559  scip->branchcand, scip->eventqueue, newbound) );
5560  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
5561  break;
5562 
5563  case SCIP_STAGE_PRESOLVING:
5564  if( !SCIPinProbing(scip) )
5565  {
5566  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5567  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5568 
5569  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5570  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5572 
5574  {
5575  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5576  assert(!(*infeasible));
5577  }
5578  break;
5579  }
5580  /*lint -fallthrough*/
5581  case SCIP_STAGE_SOLVING:
5583  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5584  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, infercons, NULL, inferinfo, FALSE) );
5585  break;
5586 
5587  default:
5588  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5589  return SCIP_INVALIDCALL;
5590  } /*lint !e788*/
5591 
5592  /* check whether the lower bound improved */
5593  if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
5594  *tightened = TRUE;
5595 
5596  return SCIP_OKAY;
5597 }
5598 
5599 /** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
5600  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5601  * the given inference constraint is stored, such that the conflict analysis is able to find out the reason
5602  * for the deduction of the bound change
5603  *
5604  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5605  * SCIPgetVars()) gets resorted.
5606  *
5607  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5608  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5609  *
5610  * @pre This method can be called if @p scip is in one of the following stages:
5611  * - \ref SCIP_STAGE_PROBLEM
5612  * - \ref SCIP_STAGE_PRESOLVING
5613  * - \ref SCIP_STAGE_SOLVING
5614  *
5615  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5616  */
5618  SCIP* scip, /**< SCIP data structure */
5619  SCIP_VAR* var, /**< variable to change the bound for */
5620  SCIP_Real newbound, /**< new value for bound */
5621  SCIP_CONS* infercons, /**< constraint that deduced the bound change */
5622  int inferinfo, /**< user information for inference to help resolving the conflict */
5623  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5624  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5625  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5626  )
5627 {
5628  SCIP_Real lb;
5629  SCIP_Real ub;
5630 
5631  assert(infeasible != NULL);
5632 
5633  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarUbCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5634 
5635  *infeasible = FALSE;
5636  if( tightened != NULL )
5637  *tightened = FALSE;
5638 
5639  SCIPvarAdjustUb(var, scip->set, &newbound);
5640 
5641  /* ignore tightenings of upper bounds to -infinity during solving process */
5642  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5643  {
5644 #ifndef NDEBUG
5645  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5646  SCIPvarGetUbLocal(var));
5647 #endif
5648  return SCIP_OKAY;
5649  }
5650 
5651  /* get current bounds */
5652  lb = SCIPvarGetLbLocal(var);
5653  ub = SCIPvarGetUbLocal(var);
5654  assert(SCIPsetIsLE(scip->set, lb, ub));
5655 
5656  if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
5657  {
5658  *infeasible = TRUE;
5659  return SCIP_OKAY;
5660  }
5661  newbound = MAX(newbound, lb);
5662 
5663  if( (force && SCIPsetIsGE(scip->set, newbound, ub)) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
5664  return SCIP_OKAY;
5665 
5666  switch( scip->set->stage )
5667  {
5668  case SCIP_STAGE_PROBLEM:
5669  assert(!SCIPvarIsTransformed(var));
5670  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5671  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5672  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5673  scip->branchcand, scip->eventqueue, newbound) );
5674  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
5675  break;
5676 
5677  case SCIP_STAGE_PRESOLVING:
5678  if( !SCIPinProbing(scip) )
5679  {
5680  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5681  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5682 
5683  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5684  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5686 
5688  {
5689  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5690  assert(!(*infeasible));
5691  }
5692  break;
5693  }
5694  /*lint -fallthrough*/
5695  case SCIP_STAGE_SOLVING:
5697  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5698  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, infercons, NULL, inferinfo, FALSE) );
5699  break;
5700 
5701  default:
5702  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5703  return SCIP_INVALIDCALL;
5704  } /*lint !e788*/
5705 
5706  /* check whether the upper bound improved */
5707  if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
5708  *tightened = TRUE;
5709 
5710  return SCIP_OKAY;
5711 }
5712 
5713 /** depending on SCIP's stage, fixes binary variable in the problem, in preprocessing, or in current node;
5714  * the given inference constraint is stored, such that the conflict analysis is able to find out the reason for the
5715  * deduction of the fixing
5716  *
5717  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5718  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5719  *
5720  * @pre This method can be called if @p scip is in one of the following stages:
5721  * - \ref SCIP_STAGE_PROBLEM
5722  * - \ref SCIP_STAGE_PRESOLVING
5723  * - \ref SCIP_STAGE_SOLVING
5724  */
5726  SCIP* scip, /**< SCIP data structure */
5727  SCIP_VAR* var, /**< binary variable to fix */
5728  SCIP_Bool fixedval, /**< value to fix binary variable to */
5729  SCIP_CONS* infercons, /**< constraint that deduced the fixing */
5730  int inferinfo, /**< user information for inference to help resolving the conflict */
5731  SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
5732  SCIP_Bool* tightened /**< pointer to store whether the fixing tightened the local bounds, or NULL */
5733  )
5734 {
5735  SCIP_Real lb;
5736  SCIP_Real ub;
5737 
5738  assert(SCIPvarIsBinary(var));
5739  assert(fixedval == TRUE || fixedval == FALSE);
5740  assert(infeasible != NULL);
5741 
5742  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferBinvarCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5743 
5744  *infeasible = FALSE;
5745  if( tightened != NULL )
5746  *tightened = FALSE;
5747 
5748  /* get current bounds */
5749  lb = SCIPvarGetLbLocal(var);
5750  ub = SCIPvarGetUbLocal(var);
5751  assert(SCIPsetIsEQ(scip->set, lb, 0.0) || SCIPsetIsEQ(scip->set, lb, 1.0));
5752  assert(SCIPsetIsEQ(scip->set, ub, 0.0) || SCIPsetIsEQ(scip->set, ub, 1.0));
5753  assert(SCIPsetIsLE(scip->set, lb, ub));
5754 
5755  /* check, if variable is already fixed */
5756  if( (lb > 0.5) || (ub < 0.5) )
5757  {
5758  *infeasible = (fixedval == (lb < 0.5));
5759 
5760  return SCIP_OKAY;
5761  }
5762 
5763  /* apply the fixing */
5764  switch( scip->set->stage )
5765  {
5766  case SCIP_STAGE_PROBLEM:
5767  assert(!SCIPvarIsTransformed(var));
5768  if( fixedval == TRUE )
5769  {
5770  SCIP_CALL( SCIPchgVarLb(scip, var, 1.0) );
5771  }
5772  else
5773  {
5774  SCIP_CALL( SCIPchgVarUb(scip, var, 0.0) );
5775  }
5776  break;
5777 
5778  case SCIP_STAGE_PRESOLVING:
5779  if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
5780  {
5781  SCIP_Bool fixed;
5782 
5783  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5784  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
5785  scip->cliquetable, (SCIP_Real)fixedval, infeasible, &fixed) );
5786  break;
5787  }
5788  /*lint -fallthrough*/
5789  case SCIP_STAGE_SOLVING:
5790  if( fixedval == TRUE )
5791  {
5793  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5794  scip->cliquetable, var, 1.0, SCIP_BOUNDTYPE_LOWER, infercons, NULL, inferinfo, FALSE) );
5795  }
5796  else
5797  {
5799  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5800  scip->cliquetable, var, 0.0, SCIP_BOUNDTYPE_UPPER, infercons, NULL, inferinfo, FALSE) );
5801  }
5802  break;
5803 
5804  default:
5805  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5806  return SCIP_INVALIDCALL;
5807  } /*lint !e788*/
5808 
5809  if( tightened != NULL )
5810  *tightened = TRUE;
5811 
5812  return SCIP_OKAY;
5813 }
5814 
5815 /** fixes variable in preprocessing or in the current node, if the new bound is tighter (w.r.t. bound strengthening
5816  * epsilon) than the current bound; if possible, adjusts bound to integral value; the given inference constraint is
5817  * stored, such that the conflict analysis is able to find out the reason for the deduction of the bound change
5818  *
5819  * @note In presolving stage when not in probing mode the variable will be fixed directly, otherwise this method
5820  * changes first the lowerbound by calling SCIPinferVarLbProp and second the upperbound by calling
5821  * SCIPinferVarUbProp
5822  *
5823  * @note If SCIP is in presolving stage, it can happen that the internal variable array (which get be accessed via
5824  * SCIPgetVars()) gets resorted.
5825  *
5826  * @note During presolving, an integer variable which bound changes to {0,1} is upgraded to a binary variable.
5827  */
5829  SCIP* scip, /**< SCIP data structure */
5830  SCIP_VAR* var, /**< variable to change the bound for */
5831  SCIP_Real fixedval, /**< new value for fixation */
5832  SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
5833  int inferinfo, /**< user information for inference to help resolving the conflict */
5834  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5835  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5836  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5837  )
5838 {
5839  assert(scip != NULL);
5840  assert(var != NULL);
5841  assert(infeasible != NULL);
5842 
5843  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarFixProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5844 
5845  if( tightened != NULL )
5846  *tightened = FALSE;
5847 
5848  /* in presolving case we take the shortcut to directly fix the variables */
5849  if( SCIPgetStage(scip) == SCIP_STAGE_PRESOLVING && SCIPtreeGetCurrentDepth(scip->tree) == 0 )
5850  {
5851  SCIP_Bool fixed;
5852 
5853  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5854  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
5855  scip->cliquetable, fixedval, infeasible, &fixed) );
5856 
5857  if( tightened != NULL )
5858  *tightened = fixed;
5859  }
5860  /* otherwise we use the lb and ub methods */
5861  else
5862  {
5863  SCIP_Bool lbtightened;
5864 
5865  SCIP_CALL( SCIPinferVarLbProp(scip, var, fixedval, inferprop, inferinfo, force, infeasible, &lbtightened) );
5866 
5867  if( ! (*infeasible) )
5868  {
5869  SCIP_CALL( SCIPinferVarUbProp(scip, var, fixedval, inferprop, inferinfo, force, infeasible, tightened) );
5870 
5871  if( tightened != NULL )
5872  *tightened |= lbtightened;
5873  }
5874  }
5875 
5876  return SCIP_OKAY;
5877 }
5878 
5879 /** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
5880  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5881  * the given inference propagator is stored, such that the conflict analysis is able to find out the reason
5882  * for the deduction of the bound change
5883  *
5884  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5885  * SCIPgetVars()) gets resorted.
5886  *
5887  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5888  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5889  *
5890  * @pre This method can be called if @p scip is in one of the following stages:
5891  * - \ref SCIP_STAGE_PROBLEM
5892  * - \ref SCIP_STAGE_PRESOLVING
5893  * - \ref SCIP_STAGE_SOLVING
5894  *
5895  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5896  */
5898  SCIP* scip, /**< SCIP data structure */
5899  SCIP_VAR* var, /**< variable to change the bound for */
5900  SCIP_Real newbound, /**< new value for bound */
5901  SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
5902  int inferinfo, /**< user information for inference to help resolving the conflict */
5903  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5904  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5905  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5906  )
5907 {
5908  SCIP_Real lb;
5909  SCIP_Real ub;
5910 
5911  assert(infeasible != NULL);
5912 
5913  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarLbProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5914 
5915  *infeasible = FALSE;
5916  if( tightened != NULL )
5917  *tightened = FALSE;
5918 
5919  SCIPvarAdjustLb(var, scip->set, &newbound);
5920 
5921  /* ignore tightenings of lower bounds to +infinity during solving process */
5922  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5923  {
5924 #ifndef NDEBUG
5925  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
5926  SCIPvarGetLbLocal(var));
5927 #endif
5928  return SCIP_OKAY;
5929  }
5930 
5931  /* get current bounds */
5932  lb = SCIPvarGetLbLocal(var);
5933  ub = SCIPvarGetUbLocal(var);
5934  assert(SCIPsetIsLE(scip->set, lb, ub));
5935 
5936  if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
5937  {
5938  *infeasible = TRUE;
5939  return SCIP_OKAY;
5940  }
5941  newbound = MIN(newbound, ub);
5942 
5943  if( (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub))
5944  || SCIPsetIsLE(scip->set, newbound, lb) )
5945  return SCIP_OKAY;
5946 
5947  switch( scip->set->stage )
5948  {
5949  case SCIP_STAGE_PROBLEM:
5950  assert(!SCIPvarIsTransformed(var));
5951  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5952  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5953  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5954  scip->branchcand, scip->eventqueue, newbound) );
5955  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
5956  break;
5957 
5958  case SCIP_STAGE_PRESOLVING:
5959  if( !SCIPinProbing(scip) )
5960  {
5961  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5962  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5963 
5964  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5965  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5967 
5969  {
5970  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5971  assert(!(*infeasible));
5972  }
5973  break;
5974  }
5975  /*lint -fallthrough*/
5976  case SCIP_STAGE_SOLVING:
5978  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5979  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, NULL, inferprop, inferinfo, FALSE) );
5980  break;
5981 
5982  default:
5983  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5984  return SCIP_INVALIDCALL;
5985  } /*lint !e788*/
5986 
5987  /* check whether the lower bound improved */
5988  if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
5989  *tightened = TRUE;
5990 
5991  return SCIP_OKAY;
5992 }
5993 
5994 /** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
5995  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5996  * the given inference propagator is stored, such that the conflict analysis is able to find out the reason
5997  * for the deduction of the bound change
5998  *
5999  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6000  * SCIPgetVars()) gets resorted.
6001  *
6002  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6003  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6004  *
6005  * @pre This method can be called if @p scip is in one of the following stages:
6006  * - \ref SCIP_STAGE_PROBLEM
6007  * - \ref SCIP_STAGE_PRESOLVING
6008  * - \ref SCIP_STAGE_SOLVING
6009  *
6010  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6011  */
6013  SCIP* scip, /**< SCIP data structure */
6014  SCIP_VAR* var, /**< variable to change the bound for */
6015  SCIP_Real newbound, /**< new value for bound */
6016  SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
6017  int inferinfo, /**< user information for inference to help resolving the conflict */
6018  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6019  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
6020  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6021  )
6022 {
6023  SCIP_Real lb;
6024  SCIP_Real ub;
6025 
6026  assert(infeasible != NULL);
6027 
6028  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarUbProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6029 
6030  *infeasible = FALSE;
6031  if( tightened != NULL )
6032  *tightened = FALSE;
6033 
6034  SCIPvarAdjustUb(var, scip->set, &newbound);
6035 
6036  /* ignore tightenings of upper bounds to -infinity during solving process */
6037  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6038  {
6039 #ifndef NDEBUG
6040  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
6041  SCIPvarGetUbLocal(var));
6042 #endif
6043  return SCIP_OKAY;
6044  }
6045 
6046  /* get current bounds */
6047  lb = SCIPvarGetLbLocal(var);
6048  ub = SCIPvarGetUbLocal(var);
6049  assert(SCIPsetIsLE(scip->set, lb, ub));
6050 
6051  if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
6052  {
6053  *infeasible = TRUE;
6054  return SCIP_OKAY;
6055  }
6056  newbound = MAX(newbound, lb);
6057 
6058  if( (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub))
6059  || SCIPsetIsGE(scip->set, newbound, ub) )
6060  return SCIP_OKAY;
6061 
6062  switch( scip->set->stage )
6063  {
6064  case SCIP_STAGE_PROBLEM:
6065  assert(!SCIPvarIsTransformed(var));
6066  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6067  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6068  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6069  scip->branchcand, scip->eventqueue, newbound) );
6070  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
6071  break;
6072 
6073  case SCIP_STAGE_PRESOLVING:
6074  if( !SCIPinProbing(scip) )
6075  {
6076  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6077  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6078 
6079  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6080  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6082 
6084  {
6085  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6086  assert(!(*infeasible));
6087  }
6088  break;
6089  }
6090  /*lint -fallthrough*/
6091  case SCIP_STAGE_SOLVING:
6093  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
6094  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, NULL, inferprop, inferinfo, FALSE) );
6095  break;
6096 
6097  default:
6098  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6099  return SCIP_INVALIDCALL;
6100  } /*lint !e788*/
6101 
6102  /* check whether the upper bound improved */
6103  if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
6104  *tightened = TRUE;
6105 
6106  return SCIP_OKAY;
6107 }
6108 
6109 /** depending on SCIP's stage, fixes binary variable in the problem, in preprocessing, or in current node;
6110  * the given inference propagator is stored, such that the conflict analysis is able to find out the reason for the
6111  * deduction of the fixing
6112  *
6113  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6114  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6115  *
6116  * @pre This method can be called if @p scip is in one of the following stages:
6117  * - \ref SCIP_STAGE_PROBLEM
6118  * - \ref SCIP_STAGE_PRESOLVING
6119  * - \ref SCIP_STAGE_PRESOLVED
6120  * - \ref SCIP_STAGE_SOLVING
6121  */
6123  SCIP* scip, /**< SCIP data structure */
6124  SCIP_VAR* var, /**< binary variable to fix */
6125  SCIP_Bool fixedval, /**< value to fix binary variable to */
6126  SCIP_PROP* inferprop, /**< propagator that deduced the fixing */
6127  int inferinfo, /**< user information for inference to help resolving the conflict */
6128  SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
6129  SCIP_Bool* tightened /**< pointer to store whether the fixing tightened the local bounds, or NULL */
6130  )
6131 {
6132  SCIP_Real lb;
6133  SCIP_Real ub;
6134 
6135  assert(SCIPvarIsBinary(var));
6136  assert(fixedval == TRUE || fixedval == FALSE);
6137  assert(infeasible != NULL);
6138 
6139  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferBinvarProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6140 
6141  *infeasible = FALSE;
6142  if( tightened != NULL )
6143  *tightened = FALSE;
6144 
6145  /* get current bounds */
6146  lb = SCIPvarGetLbLocal(var);
6147  ub = SCIPvarGetUbLocal(var);
6148  assert(SCIPsetIsEQ(scip->set, lb, 0.0) || SCIPsetIsEQ(scip->set, lb, 1.0));
6149  assert(SCIPsetIsEQ(scip->set, ub, 0.0) || SCIPsetIsEQ(scip->set, ub, 1.0));
6150  assert(SCIPsetIsLE(scip->set, lb, ub));
6151 
6152  /* check, if variable is already fixed */
6153  if( (lb > 0.5) || (ub < 0.5) )
6154  {
6155  *infeasible = (fixedval == (lb < 0.5));
6156 
6157  return SCIP_OKAY;
6158  }
6159 
6160  /* apply the fixing */
6161  switch( scip->set->stage )
6162  {
6163  case SCIP_STAGE_PROBLEM:
6164  assert(!SCIPvarIsTransformed(var));
6165  if( fixedval == TRUE )
6166  {
6167  SCIP_CALL( SCIPchgVarLb(scip, var, 1.0) );
6168  }
6169  else
6170  {
6171  SCIP_CALL( SCIPchgVarUb(scip, var, 0.0) );
6172  }
6173  break;
6174 
6175  case SCIP_STAGE_PRESOLVING:
6176  if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
6177  {
6178  SCIP_Bool fixed;
6179 
6180  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6181  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
6182  scip->cliquetable, (SCIP_Real)fixedval, infeasible, &fixed) );
6183  break;
6184  }
6185  /*lint -fallthrough*/
6186  case SCIP_STAGE_SOLVING:
6187  if( fixedval == TRUE )
6188  {
6190  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, 1.0,
6191  SCIP_BOUNDTYPE_LOWER, NULL, inferprop, inferinfo, FALSE) );
6192  }
6193  else
6194  {
6196  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, 0.0,
6197  SCIP_BOUNDTYPE_UPPER, NULL, inferprop, inferinfo, FALSE) );
6198  }
6199  break;
6200 
6201  default:
6202  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6203  return SCIP_INVALIDCALL;
6204  } /*lint !e788*/
6205 
6206  if( tightened != NULL )
6207  *tightened = TRUE;
6208 
6209  return SCIP_OKAY;
6210 }
6211 
6212 /** changes global lower bound of variable in preprocessing or in the current node, if the new bound is tighter
6213  * (w.r.t. bound strengthening epsilon) than the current global bound; if possible, adjusts bound to integral value;
6214  * also tightens the local bound, if the global bound is better than the local bound
6215  *
6216  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6217  * SCIPgetVars()) gets resorted.
6218  *
6219  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6220  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6221  *
6222  * @pre This method can be called if @p scip is in one of the following stages:
6223  * - \ref SCIP_STAGE_PROBLEM
6224  * - \ref SCIP_STAGE_TRANSFORMING
6225  * - \ref SCIP_STAGE_PRESOLVING
6226  * - \ref SCIP_STAGE_SOLVING
6227  *
6228  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6229  */
6231  SCIP* scip, /**< SCIP data structure */
6232  SCIP_VAR* var, /**< variable to change the bound for */
6233  SCIP_Real newbound, /**< new value for bound */
6234  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6235  SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
6236  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6237  )
6238 {
6239  SCIP_Real lb;
6240  SCIP_Real ub;
6241 
6242  assert(infeasible != NULL);
6243 
6244  SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarLbGlobal", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6245 
6246  *infeasible = FALSE;
6247  if( tightened != NULL )
6248  *tightened = FALSE;
6249 
6250  SCIPvarAdjustLb(var, scip->set, &newbound);
6251 
6252  /* ignore tightenings of lower bounds to +infinity during solving process */
6253  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6254  {
6255 #ifndef NDEBUG
6256  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
6257  SCIPvarGetLbLocal(var));
6258 #endif
6259  return SCIP_OKAY;
6260  }
6261 
6262  /* get current bounds */
6263  lb = SCIPvarGetLbGlobal(var);
6264  ub = SCIPvarGetUbGlobal(var);
6265  assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPsetIsLE(scip->set, lb, ub));
6266 
6267  if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
6268  {
6269  *infeasible = TRUE;
6270  return SCIP_OKAY;
6271  }
6272  newbound = MIN(newbound, ub);
6273 
6274  /* bound changes of less than epsilon are ignored by SCIPvarChgLb or raise an assert in SCIPnodeAddBoundinfer,
6275  * so don't apply them even if force is set
6276  */
6277  if( SCIPsetIsEQ(scip->set, lb, newbound) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
6278  return SCIP_OKAY;
6279 
6280  switch( scip->set->stage )
6281  {
6282  case SCIP_STAGE_PROBLEM:
6283  assert(!SCIPvarIsTransformed(var));
6284  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6285  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6286  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6287  scip->branchcand, scip->eventqueue, newbound) );
6288  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
6289  break;
6290 
6292  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6293  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6294  break;
6295 
6296  case SCIP_STAGE_PRESOLVING:
6297  if( !SCIPinProbing(scip) )
6298  {
6299  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6300  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6301 
6302  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6303  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6305 
6307  {
6308  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6309  assert(!(*infeasible));
6310  }
6311  break;
6312  }
6313  /*lint -fallthrough*/
6314  case SCIP_STAGE_SOLVING:
6315  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6316  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6318  break;
6319 
6320  default:
6321  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6322  return SCIP_INVALIDCALL;
6323  } /*lint !e788*/
6324 
6325  /* coverity: unreachable code */
6326  if( tightened != NULL && lb < SCIPcomputeVarLbGlobal(scip, var) )
6327  *tightened = TRUE;
6328 
6329  return SCIP_OKAY;
6330 }
6331 
6332 /** changes global upper bound of variable in preprocessing or in the current node, if the new bound is tighter
6333  * (w.r.t. bound strengthening epsilon) than the current global bound; if possible, adjusts bound to integral value;
6334  * also tightens the local bound, if the global bound is better than the local bound
6335  *
6336  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6337  * SCIPgetVars()) gets resorted.
6338  *
6339  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6340  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6341  *
6342  * @pre This method can be called if @p scip is in one of the following stages:
6343  * - \ref SCIP_STAGE_PROBLEM
6344  * - \ref SCIP_STAGE_TRANSFORMING
6345  * - \ref SCIP_STAGE_PRESOLVING
6346  * - \ref SCIP_STAGE_SOLVING
6347  *
6348  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6349  */
6351  SCIP* scip, /**< SCIP data structure */
6352  SCIP_VAR* var, /**< variable to change the bound for */
6353  SCIP_Real newbound, /**< new value for bound */
6354  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6355  SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
6356  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6357  )
6358 {
6359  SCIP_Real lb;
6360  SCIP_Real ub;
6361 
6362  assert(infeasible != NULL);
6363 
6364  SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarUbGlobal", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6365 
6366  *infeasible = FALSE;
6367  if( tightened != NULL )
6368  *tightened = FALSE;
6369 
6370  SCIPvarAdjustUb(var, scip->set, &newbound);
6371 
6372  /* ignore tightenings of upper bounds to -infinity during solving process */
6373  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6374  {
6375 #ifndef NDEBUG
6376  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
6377  SCIPvarGetUbLocal(var));
6378 #endif
6379  return SCIP_OKAY;
6380  }
6381 
6382  /* get current bounds */
6383  lb = SCIPvarGetLbGlobal(var);
6384  ub = SCIPvarGetUbGlobal(var);
6385  assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPsetIsLE(scip->set, lb, ub));
6386 
6387  if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
6388  {
6389  *infeasible = TRUE;
6390  return SCIP_OKAY;
6391  }
6392  newbound = MAX(newbound, lb);
6393 
6394  /* bound changes of less than epsilon are ignored by SCIPvarChgUb or raise an assert in SCIPnodeAddBoundinfer,
6395  * so don't apply them even if force is set
6396  */
6397  if( SCIPsetIsEQ(scip->set, ub, newbound) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
6398  return SCIP_OKAY;
6399 
6400  switch( scip->set->stage )
6401  {
6402  case SCIP_STAGE_PROBLEM:
6403  assert(!SCIPvarIsTransformed(var));
6404  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6405  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6406  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6407  scip->branchcand, scip->eventqueue, newbound) );
6408  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
6409  break;
6410 
6412  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6413  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6414  break;
6415 
6416  case SCIP_STAGE_PRESOLVING:
6417  if( !SCIPinProbing(scip) )
6418  {
6419  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6420  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6421 
6422  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6423  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6425 
6427  {
6428  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6429  assert(!(*infeasible));
6430  }
6431  break;
6432  }
6433  /*lint -fallthrough*/
6434  case SCIP_STAGE_SOLVING:
6435  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6436  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6438  break;
6439 
6440  default:
6441  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6442  return SCIP_INVALIDCALL;
6443  } /*lint !e788*/
6444 
6445  /* coverity: unreachable code */
6446  if( tightened != NULL && ub > SCIPcomputeVarUbGlobal(scip, var) )
6447  *tightened = TRUE;
6448 
6449  return SCIP_OKAY;
6450 }
6451 
6452 /* some simple variable functions implemented as defines */
6453 #undef SCIPcomputeVarLbGlobal
6454 #undef SCIPcomputeVarUbGlobal
6455 #undef SCIPcomputeVarLbLocal
6456 #undef SCIPcomputeVarUbLocal
6457 
6458 /** for a multi-aggregated variable, returns the global lower bound computed by adding the global bounds from all aggregation variables
6459  *
6460  * 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
6461  * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetLbGlobal.
6462  *
6463  * @return the global lower bound computed by adding the global bounds from all aggregation variables
6464  */
6466  SCIP* scip, /**< SCIP data structure */
6467  SCIP_VAR* var /**< variable to compute the bound for */
6468  )
6469 {
6470  assert(scip != NULL);
6471  assert(var != NULL);
6472 
6474  return SCIPvarGetMultaggrLbGlobal(var, scip->set);
6475  else
6476  return SCIPvarGetLbGlobal(var);
6477 }
6478 
6479 /** for a multi-aggregated variable, returns the global upper bound computed by adding the global bounds from all aggregation variables
6480  *
6481  * 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
6482  * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetUbGlobal
6483  *
6484  * @return the global upper bound computed by adding the global bounds from all aggregation variables
6485  */
6487  SCIP* scip, /**< SCIP data structure */
6488  SCIP_VAR* var /**< variable to compute the bound for */
6489  )
6490 {
6491  assert(scip != NULL);
6492  assert(var != NULL);
6493 
6495  return SCIPvarGetMultaggrUbGlobal(var, scip->set);
6496  else
6497  return SCIPvarGetUbGlobal(var);
6498 }
6499 
6500 /** for a multi-aggregated variable, returns the local lower bound computed by adding the local bounds from all aggregation variables
6501  *
6502  * 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
6503  * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetLbLocal.
6504  *
6505  * @return the local lower bound computed by adding the global bounds from all aggregation variables
6506  */
6508  SCIP* scip, /**< SCIP data structure */
6509  SCIP_VAR* var /**< variable to compute the bound for */
6510  )
6511 {
6512  assert(scip != NULL);
6513  assert(var != NULL);
6514 
6516  return SCIPvarGetMultaggrLbLocal(var, scip->set);
6517  else
6518  return SCIPvarGetLbLocal(var);
6519 }
6520 
6521 /** for a multi-aggregated variable, returns the local upper bound computed by adding the local bounds from all aggregation variables
6522  *
6523  * 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
6524  * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetUbLocal.
6525  *
6526  * @return the local upper bound computed by adding the global bounds from all aggregation variables
6527  */
6529  SCIP* scip, /**< SCIP data structure */
6530  SCIP_VAR* var /**< variable to compute the bound for */
6531  )
6532 {
6533  assert(scip != NULL);
6534  assert(var != NULL);
6535 
6537  return SCIPvarGetMultaggrUbLocal(var, scip->set);
6538  else
6539  return SCIPvarGetUbLocal(var);
6540 }
6541 
6542 /** for a multi-aggregated variable, gives the global lower bound computed by adding the global bounds from all
6543  * aggregation variables, this global bound may be tighter than the one given by SCIPvarGetLbGlobal, since the latter is
6544  * not updated if bounds of aggregation variables are changing
6545  *
6546  * calling this function for a non-multi-aggregated variable is not allowed
6547  */
6549  SCIP* scip, /**< SCIP data structure */
6550  SCIP_VAR* var /**< variable to compute the bound for */
6551  )
6552 {
6553  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
6554  return SCIPvarGetMultaggrLbGlobal(var, scip->set);
6555 }
6556 
6557 /** for a multi-aggregated variable, gives the global upper bound computed by adding the global bounds from all
6558  * aggregation variables, this upper bound may be tighter than the one given by SCIPvarGetUbGlobal, since the latter is
6559  * not updated if bounds of aggregation variables are changing
6560  *
6561  * calling this function for a non-multi-aggregated variable is not allowed
6562  */
6564  SCIP* scip, /**< SCIP data structure */
6565  SCIP_VAR* var /**< variable to compute the bound for */
6566  )
6567 {
6568  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
6569  return SCIPvarGetMultaggrUbGlobal(var, scip->set);
6570 }
6571 
6572 /** for a multi-aggregated variable, gives the local lower bound computed by adding the local bounds from all
6573  * aggregation variables, this lower bound may be tighter than the one given by SCIPvarGetLbLocal, since the latter is
6574  * not updated if bounds of aggregation variables are changing
6575  *
6576  * calling this function for a non-multi-aggregated variable is not allowed
6577  */
6579  SCIP* scip, /**< SCIP data structure */
6580  SCIP_VAR* var /**< variable to compute the bound for */
6581  )
6582 {
6583  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
6584  return SCIPvarGetMultaggrLbLocal(var, scip->set);
6585 }
6586 
6587 /** for a multi-aggregated variable, gives the local upper bound computed by adding the local bounds from all
6588  * aggregation variables, this upper bound may be tighter than the one given by SCIPvarGetUbLocal, since the latter is
6589  * not updated if bounds of aggregation variables are changing
6590  *
6591  * calling this function for a non-multi-aggregated variable is not allowed
6592  */
6594  SCIP* scip, /**< SCIP data structure */
6595  SCIP_VAR* var /**< variable to compute the bound for */
6596  )
6597 {
6598  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
6599  return SCIPvarGetMultaggrUbLocal(var, scip->set);
6600 }
6601 
6602 /** returns solution value and index of variable lower bound that is closest to the variable's value in the given primal
6603  * solution or current LP solution if no primal solution is given; returns an index of -1 if no variable lower bound is
6604  * available
6605  *
6606  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6607  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6608  *
6609  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
6610  */
6612  SCIP* scip, /**< SCIP data structure */
6613  SCIP_VAR* var, /**< active problem variable */
6614  SCIP_SOL* sol, /**< primal solution, or NULL for LP solution */
6615  SCIP_Real* closestvlb, /**< pointer to store the value of the closest variable lower bound */
6616  int* closestvlbidx /**< pointer to store the index of the closest variable lower bound */
6617  )
6618 {
6619  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarClosestVlb", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6620 
6621  SCIPvarGetClosestVlb(var, sol, scip->set, scip->stat, closestvlb, closestvlbidx);
6622 
6623  return SCIP_OKAY;
6624 }
6625 
6626 /** returns solution value and index of variable upper bound that is closest to the variable's value in the given primal solution;
6627  * or current LP solution if no primal solution is given; returns an index of -1 if no variable upper bound is available
6628  *
6629  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6630  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6631  *
6632  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
6633  */
6635  SCIP* scip, /**< SCIP data structure */
6636  SCIP_VAR* var, /**< active problem variable */
6637  SCIP_SOL* sol, /**< primal solution, or NULL for LP solution */
6638  SCIP_Real* closestvub, /**< pointer to store the value of the closest variable lower bound */
6639  int* closestvubidx /**< pointer to store the index of the closest variable lower bound */
6640  )
6641 {
6642  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarClosestVub", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6643 
6644  SCIPvarGetClosestVub(var, sol, scip->set, scip->stat, closestvub, closestvubidx);
6645 
6646  return SCIP_OKAY;
6647 }
6648 
6649 /** informs variable x about a globally valid variable lower bound x >= b*z + d with integer variable z;
6650  * if z is binary, the corresponding valid implication for z is also added;
6651  * if z is non-continuous and 1/b not too small, the corresponding valid upper/lower bound
6652  * z <= (x-d)/b or z >= (x-d)/b (depending on the sign of of b) is added, too;
6653  * improves the global bounds of the variable and the vlb variable if possible
6654  *
6655  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6656  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6657  *
6658  * @pre This method can be called if @p scip is in one of the following stages:
6659  * - \ref SCIP_STAGE_PRESOLVING
6660  * - \ref SCIP_STAGE_PRESOLVED
6661  * - \ref SCIP_STAGE_SOLVING
6662  */
6664  SCIP* scip, /**< SCIP data structure */
6665  SCIP_VAR* var, /**< problem variable */
6666  SCIP_VAR* vlbvar, /**< variable z in x >= b*z + d */
6667  SCIP_Real vlbcoef, /**< coefficient b in x >= b*z + d */
6668  SCIP_Real vlbconstant, /**< constant d in x >= b*z + d */
6669  SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6670  int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6671  )
6672 {
6673  int nlocalbdchgs;
6674 
6675  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarVlb", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6676 
6677  SCIP_CALL( SCIPvarAddVlb(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->tree,
6678  scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, vlbvar, vlbcoef, vlbconstant,
6679  TRUE, infeasible, &nlocalbdchgs) );
6680 
6681  *nbdchgs = nlocalbdchgs;
6682 
6683  /* 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
6684  * detected infeasibility
6685  */
6686  if( !(*infeasible) && SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisZero(scip, 1.0/vlbcoef) )
6687  {
6688  if( vlbcoef > 0.0 )
6689  {
6690  /* if b > 0, we have a variable upper bound: x >= b*z + d => z <= (x-d)/b */
6691  SCIP_CALL( SCIPvarAddVub(vlbvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6692  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vlbcoef,
6693  -vlbconstant/vlbcoef, TRUE, infeasible, &nlocalbdchgs) );
6694  }
6695  else
6696  {
6697  /* if b < 0, we have a variable lower bound: x >= b*z + d => z >= (x-d)/b */
6698  SCIP_CALL( SCIPvarAddVlb(vlbvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6699  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vlbcoef,
6700  -vlbconstant/vlbcoef, TRUE, infeasible, &nlocalbdchgs) );
6701  }
6702  *nbdchgs += nlocalbdchgs;
6703  }
6704 
6705  return SCIP_OKAY;
6706 }
6707 
6708 /** informs variable x about a globally valid variable upper bound x <= b*z + d with integer variable z;
6709  * if z is binary, the corresponding valid implication for z is also added;
6710  * if z is non-continuous and 1/b not too small, the corresponding valid lower/upper bound
6711  * z >= (x-d)/b or z <= (x-d)/b (depending on the sign of of b) is added, too;
6712  * improves the global bounds of the variable and the vlb variable if possible
6713  *
6714  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6715  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6716  *
6717  * @pre This method can be called if @p scip is in one of the following stages:
6718  * - \ref SCIP_STAGE_PRESOLVING
6719  * - \ref SCIP_STAGE_PRESOLVED
6720  * - \ref SCIP_STAGE_SOLVING
6721  */
6723  SCIP* scip, /**< SCIP data structure */
6724  SCIP_VAR* var, /**< problem variable */
6725  SCIP_VAR* vubvar, /**< variable z in x <= b*z + d */
6726  SCIP_Real vubcoef, /**< coefficient b in x <= b*z + d */
6727  SCIP_Real vubconstant, /**< constant d in x <= b*z + d */
6728  SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6729  int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6730  )
6731 {
6732  int nlocalbdchgs;
6733 
6734  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarVub", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6735 
6736  SCIP_CALL( SCIPvarAddVub(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->tree,
6737  scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, vubvar, vubcoef, vubconstant, TRUE,
6738  infeasible, &nlocalbdchgs) );
6739 
6740  *nbdchgs = nlocalbdchgs;
6741 
6742  /* 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
6743  * detected infeasibility
6744  */
6745  if( !(*infeasible) && SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisZero(scip, 1.0/vubcoef) )
6746  {
6747  if( vubcoef > 0.0 )
6748  {
6749  /* if b < 0, we have a variable lower bound: x >= b*z + d => z >= (x-d)/b */
6750  SCIP_CALL( SCIPvarAddVlb(vubvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6751  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vubcoef,
6752  -vubconstant/vubcoef, TRUE, infeasible, &nlocalbdchgs) );
6753  }
6754  else
6755  {
6756  /* if b > 0, we have a variable upper bound: x >= b*z + d => z <= (x-d)/b */
6757  SCIP_CALL( SCIPvarAddVub(vubvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6758  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vubcoef,
6759  -vubconstant/vubcoef, TRUE, infeasible, &nlocalbdchgs) );
6760  }
6761  *nbdchgs += nlocalbdchgs;
6762  }
6763 
6764  return SCIP_OKAY;
6765 }
6766 
6767 /** informs binary variable x about a globally valid implication: x == 0 or x == 1 ==> y <= b or y >= b;
6768  * also adds the corresponding implication or variable bound to the implied variable;
6769  * if the implication is conflicting, the variable is fixed to the opposite value;
6770  * if the variable is already fixed to the given value, the implication is performed immediately;
6771  * if the implication is redundant with respect to the variables' global bounds, it is ignored
6772  *
6773  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6774  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6775  *
6776  * @pre This method can be called if @p scip is in one of the following stages:
6777  * - \ref SCIP_STAGE_TRANSFORMED
6778  * - \ref SCIP_STAGE_PRESOLVING
6779  * - \ref SCIP_STAGE_PRESOLVED
6780  * - \ref SCIP_STAGE_SOLVING
6781  */
6783  SCIP* scip, /**< SCIP data structure */
6784  SCIP_VAR* var, /**< problem variable */
6785  SCIP_Bool varfixing, /**< FALSE if y should be added in implications for x == 0, TRUE for x == 1 */
6786  SCIP_VAR* implvar, /**< variable y in implication y <= b or y >= b */
6787  SCIP_BOUNDTYPE impltype, /**< type of implication y <= b (SCIP_BOUNDTYPE_UPPER)
6788  * or y >= b (SCIP_BOUNDTYPE_LOWER) */
6789  SCIP_Real implbound, /**< bound b in implication y <= b or y >= b */
6790  SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6791  int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6792  )
6793 {
6794  SCIP_VAR* implprobvar;
6795 
6796  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarImplication", FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6797 
6798  assert(infeasible != NULL);
6799  *infeasible = FALSE;
6800 
6801  if ( nbdchgs != NULL )
6802  *nbdchgs = 0;
6803 
6804  if( !SCIPvarIsBinary(var) )
6805  {
6806  SCIPerrorMessage("can't add implication for nonbinary variable\n");
6807  return SCIP_INVALIDDATA;
6808  }
6809 
6810  implprobvar = SCIPvarGetProbvar(implvar);
6811  /* transform implication containing two binary variables to a clique; the condition ensures that the active representative
6812  * of implvar is actually binary
6813  */
6814  if( SCIPvarIsBinary(implvar) && (SCIPvarIsActive(implvar) || (implprobvar != NULL && SCIPvarIsBinary(implprobvar))) )
6815  {
6816  assert(SCIPisFeasEQ(scip, implbound, 1.0) || SCIPisFeasZero(scip, implbound));
6817  assert((impltype == SCIP_BOUNDTYPE_UPPER) == SCIPisFeasZero(scip, implbound));
6818 
6819  /* only add clique if implication is not redundant with respect to global bounds of the implication variable */
6820  if( (impltype == SCIP_BOUNDTYPE_LOWER && SCIPvarGetLbGlobal(implvar) < 0.5) ||
6821  (impltype == SCIP_BOUNDTYPE_UPPER && SCIPvarGetUbGlobal(implvar) > 0.5) )
6822  {
6823  SCIP_VAR* vars[2];
6824  SCIP_Bool vals[2];
6825 
6826  vars[0] = var;
6827  vars[1] = implvar;
6828  vals[0] = varfixing;
6829  vals[1] = (impltype == SCIP_BOUNDTYPE_UPPER);
6830 
6831  SCIP_CALL( SCIPaddClique(scip, vars, vals, 2, FALSE, infeasible, nbdchgs) );
6832  }
6833 
6834  return SCIP_OKAY;
6835  }
6836 
6837  /* the implication graph can only handle 'real' binary (SCIP_VARTYPE_BINARY) variables, therefore we transform the
6838  * implication in variable bounds, (lowerbound of y will be abbreviated by lby, upperbound equivlaent) the follwing
6839  * four cases are:
6840  *
6841  * 1. (x >= 1 => y >= b) => y >= (b - lby) * x + lby
6842  * 2. (x >= 1 => y <= b) => y <= (b - uby) * x + uby
6843  * 3. (x <= 0 => y >= b) => y >= (lby - b) * x + b
6844  * 4. (x <= 0 => y <= b) => y <= (uby - b) * x + b
6845  */
6846  if( SCIPvarGetType(var) != SCIP_VARTYPE_BINARY )
6847  {
6848  SCIP_Real lby;
6849  SCIP_Real uby;
6850 
6851  lby = SCIPvarGetLbGlobal(implvar);
6852  uby = SCIPvarGetUbGlobal(implvar);
6853 
6854  if( varfixing == TRUE )
6855  {
6856  if( impltype == SCIP_BOUNDTYPE_LOWER )
6857  {
6858  /* we return if the lower bound is infinity */
6859  if( SCIPisInfinity(scip, -lby) )
6860  return SCIP_OKAY;
6861 
6862  SCIP_CALL( SCIPvarAddVlb(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6863  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6864  implbound - lby, lby, TRUE, infeasible, nbdchgs) );
6865  }
6866  else
6867  {
6868  /* we return if the upper bound is infinity */
6869  if( SCIPisInfinity(scip, uby) )
6870  return SCIP_OKAY;
6871 
6872  SCIP_CALL( SCIPvarAddVub(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6873  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6874  implbound - uby, uby, TRUE, infeasible, nbdchgs) );
6875  }
6876  }
6877  else
6878  {
6879  if( impltype == SCIP_BOUNDTYPE_LOWER )
6880  {
6881  /* we return if the lower bound is infinity */
6882  if( SCIPisInfinity(scip, -lby) )
6883  return SCIP_OKAY;
6884 
6885  SCIP_CALL( SCIPvarAddVlb(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6886  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6887  lby - implbound, implbound, TRUE, infeasible, nbdchgs) );
6888  }
6889  else
6890  {
6891  /* we return if the upper bound is infinity */
6892  if( SCIPisInfinity(scip, uby) )
6893  return SCIP_OKAY;
6894 
6895  SCIP_CALL( SCIPvarAddVub(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6896  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6897  uby - implbound, implbound, TRUE, infeasible, nbdchgs) );
6898  }
6899  }
6900  }
6901  else
6902  {
6903  SCIP_CALL( SCIPvarAddImplic(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6904  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, varfixing, implvar, impltype,
6905  implbound, TRUE, infeasible, nbdchgs) );
6906  }
6907 
6908  return SCIP_OKAY;
6909 }
6910 
6911 /** adds a clique information to SCIP, stating that at most one of the given binary variables can be set to 1;
6912  * if a variable appears twice in the same clique, the corresponding implications are performed
6913  *
6914  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6915  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6916  *
6917  * @pre This method can be called if @p scip is in one of the following stages:
6918  * - \ref SCIP_STAGE_TRANSFORMED
6919  * - \ref SCIP_STAGE_PRESOLVING
6920  * - \ref SCIP_STAGE_PRESOLVED
6921  * - \ref SCIP_STAGE_SOLVING
6922  */
6924  SCIP* scip, /**< SCIP data structure */
6925  SCIP_VAR** vars, /**< binary variables in the clique from which at most one can be set to 1 */
6926  SCIP_Bool* values, /**< values of the variables in the clique; NULL to use TRUE for all vars */
6927  int nvars, /**< number of variables in the clique */
6928  SCIP_Bool isequation, /**< is the clique an equation or an inequality? */
6929  SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6930  int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6931  )
6932 {
6933  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddClique", FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6934 
6935  *infeasible = FALSE;
6936  if( nbdchgs != NULL )
6937  *nbdchgs = 0;
6938 
6939  if( nvars > 1 )
6940  {
6941  /* add the clique to the clique table */
6942  SCIP_CALL( SCIPcliquetableAdd(scip->cliquetable, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6943  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, vars, values, nvars, isequation,
6944  infeasible, nbdchgs) );
6945  }
6946 
6947  return SCIP_OKAY;
6948 }
6949 
6950 /** relabels the given labels in-place in an increasing fashion: the first seen label is 0, the next label 1, etc...
6951  *
6952  * @note every label equal to -1 is treated as a previously unseen, unique label and gets a new ordered label.
6953  */
6954 static
6956  SCIP*const scip, /**< SCIP data structure */
6957  int* labels, /**< current labels that will be overwritten */
6958  int const nlabels, /**< number of variables in the clique */
6959  int* nclasses /**< pointer to store the total number of distinct labels */
6960  )
6961 {
6962  SCIP_HASHMAP* classidx2newlabel;
6963 
6964  int classidx;
6965  int i;
6966 
6967  SCIP_CALL( SCIPhashmapCreate(&classidx2newlabel, SCIPblkmem(scip), nlabels) );
6968 
6969  classidx = 0;
6970 
6971  /* loop over labels to create local class indices that obey the variable order */
6972  for( i = 0; i < nlabels; ++i )
6973  {
6974  int currentlabel = labels[i];
6975  int localclassidx;
6976 
6977  /* labels equal to -1 are stored as singleton classes */
6978  if( currentlabel == -1 )
6979  {
6980  ++classidx;
6981  localclassidx = classidx;
6982  }
6983  else
6984  {
6985  assert(currentlabel >= 0);
6986  /* look up the class index image in the hash map; if it is not stored yet, new class index is created and stored */
6987  if( !SCIPhashmapExists(classidx2newlabel, (void*)(size_t)currentlabel) )
6988  {
6989  ++classidx;
6990  localclassidx = classidx;
6991  SCIP_CALL( SCIPhashmapInsertInt(classidx2newlabel, (void*)(size_t)currentlabel, classidx) ); /*lint !e571*/
6992  }
6993  else
6994  {
6995  localclassidx = SCIPhashmapGetImageInt(classidx2newlabel, (void*)(size_t)currentlabel); /*lint !e571*/
6996  }
6997  }
6998  assert(localclassidx - 1 >= 0);
6999  assert(localclassidx - 1 <= i);
7000 
7001  /* indices start with zero, but we have an offset of 1 because we cannot store 0 in a hashmap */
7002  labels[i] = localclassidx - 1;
7003  }
7004 
7005  assert(classidx > 0);
7006  assert(classidx <= nlabels);
7007  *nclasses = classidx;
7008 
7009  SCIPhashmapFree(&classidx2newlabel);
7010 
7011  return SCIP_OKAY;
7012 }
7013 
7014 /** sort the variables w.r.t. the given labels; thereby ensure the current order of the variables with the same label. */
7015 static
7017  SCIP* scip, /**< SCIP data structure */
7018  SCIP_VAR** vars, /**< variable array */
7019  int* classlabels, /**< array that contains a class label for every variable */
7020  SCIP_VAR** sortedvars, /**< array to store variables after stable sorting */
7021  int* sortedindices, /**< array to store indices of sorted variables in the original vars array */
7022  int* classesstartposs, /**< starting position array for each label class (must have size nclasses + 1) */
7023  int nvars, /**< size of the vars arrays */
7024  int nclasses /**< number of label classes */
7025  )
7026 {
7027  SCIP_VAR*** varpointers;
7028  int** indexpointers;
7029  int* classcount;
7030 
7031  int nextpos;
7032  int c;
7033  int v;
7034 
7035  assert(scip != NULL);
7036  assert(vars != NULL);
7037  assert(sortedindices != NULL);
7038  assert(classesstartposs != NULL);
7039 
7040  assert(nvars == 0 || vars != NULL);
7041 
7042  if( nvars == 0 )
7043  return SCIP_OKAY;
7044 
7045  assert(classlabels != NULL);
7046  assert(nclasses > 0);
7047 
7048  /* we first count all class cardinalities and allocate temporary memory for a bucket sort */
7049  SCIP_CALL( SCIPallocBufferArray(scip, &classcount, nclasses) );
7050  BMSclearMemoryArray(classcount, nclasses);
7051 
7052  /* first we count for each class the number of elements */
7053  for( v = nvars - 1; v >= 0; --v )
7054  {
7055  assert(0 <= classlabels[v] && classlabels[v] < nclasses);
7056  ++(classcount[classlabels[v]]);
7057  }
7058 
7059 #ifndef NDEBUG
7060  BMSclearMemoryArray(sortedvars, nvars);
7061  BMSclearMemoryArray(sortedindices, nvars);
7062 #endif
7063  SCIP_CALL( SCIPallocBufferArray(scip, &varpointers, nclasses) );
7064  SCIP_CALL( SCIPallocBufferArray(scip, &indexpointers, nclasses) );
7065 
7066  nextpos = 0;
7067  /* now we initialize all start pointers for each class, so they will be ordered */
7068  for( c = 0; c < nclasses; ++c )
7069  {
7070  /* to reach the goal that all variables of each class will be standing next to each other we will initialize the
7071  * starting pointers for each class by adding the cardinality of each class to the last class starting pointer
7072  * e.g. class1 has 4 elements and class2 has 3 elements then the starting pointer for class1 will be the pointer
7073  * to sortedvars[0], the starting pointer to class2 will be the pointer to sortedvars[4] and to class3 it will be
7074  * the pointer to sortedvars[7]
7075  */
7076  varpointers[c] = (SCIP_VAR**) (sortedvars + nextpos);
7077  indexpointers[c] = (int*) (sortedindices + nextpos);
7078  classesstartposs[c] = nextpos;
7079  assert(classcount[c] > 0);
7080  nextpos += classcount[c];
7081  assert(nextpos > 0);
7082  }
7083  assert(nextpos == nvars);
7084  classesstartposs[c] = nextpos;
7085 
7086  /* now we copy all variables to the right order */
7087  for( v = 0; v < nvars; ++v )
7088  {
7089  /* copy variable itself to the right position */
7090  *(varpointers[classlabels[v]]) = vars[v]; /*lint !e613*/
7091  ++(varpointers[classlabels[v]]);
7092 
7093  /* copy index */
7094  *(indexpointers[classlabels[v]]) = v;
7095  ++(indexpointers[classlabels[v]]);
7096  }
7097 
7098 /* in debug mode, we ensure the correctness of the mapping */
7099 #ifndef NDEBUG
7100  for( v = 0; v < nvars; ++v )
7101  {
7102  assert(sortedvars[v] != NULL);
7103  assert(sortedindices[v] >= 0);
7104 
7105  /* assert that the sorted indices map back to the correct variable in the original order */
7106  assert(vars[sortedindices[v]] == sortedvars[v]);
7107  }
7108 #endif
7109 
7110  /* free temporary memory */
7111  SCIPfreeBufferArray(scip, &indexpointers);
7112  SCIPfreeBufferArray(scip, &varpointers);
7113  SCIPfreeBufferArray(scip, &classcount);
7114 
7115  return SCIP_OKAY;
7116 }
7117 
7118 
7119 /* calculate clique partition for a maximal amount of comparisons on variables due to expensive algorithm
7120  * @todo: check for a good value, maybe it's better to check parts of variables
7121  */
7122 #define MAXNCLIQUEVARSCOMP 1000000
7123 
7124 /** calculates a partition of the given set of binary variables into cliques;
7125  * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7126  * were assigned to the same clique;
7127  * the first variable is always assigned to clique 0, and a variable can only be assigned to clique i if at least one of
7128  * the preceding variables was assigned to clique i-1;
7129  * for each clique at most 1 variables can be set to TRUE in a feasible solution;
7130  *
7131  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7132  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7133  *
7134  * @pre This method can be called if @p scip is in one of the following stages:
7135  * - \ref SCIP_STAGE_INITPRESOLVE
7136  * - \ref SCIP_STAGE_PRESOLVING
7137  * - \ref SCIP_STAGE_EXITPRESOLVE
7138  * - \ref SCIP_STAGE_PRESOLVED
7139  * - \ref SCIP_STAGE_SOLVING
7140  */
7141 static
7143  SCIP*const scip, /**< SCIP data structure */
7144  SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7145  SCIP_Bool*const values, /**< clique value (TRUE or FALSE) for each variable in the clique */
7146  int const nvars, /**< number of variables in the array */
7147  int*const cliquepartition, /**< array of length nvars to store the clique partition */
7148  int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7149  )
7150 {
7151  SCIP_VAR** cliquevars;
7152  SCIP_Bool* cliquevalues;
7153  int i;
7154  int maxncliquevarscomp;
7155  int ncliquevars;
7156 
7157  /* allocate temporary memory for storing the variables of the current clique */
7158  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &cliquevars, nvars) );
7159  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &cliquevalues, nvars) );
7160 
7161  /* initialize the cliquepartition array with -1 */
7162  for( i = nvars - 1; i >= 0; --i )
7163  cliquepartition[i] = -1;
7164 
7165  maxncliquevarscomp = (int) MIN(nvars * (SCIP_Longint)nvars, MAXNCLIQUEVARSCOMP);
7166  /* calculate the clique partition */
7167  *ncliques = 0;
7168  for( i = 0; i < nvars; ++i )
7169  {
7170  if( cliquepartition[i] == -1 )
7171  {
7172  int j;
7173 
7174  /* variable starts a new clique */
7175  cliquepartition[i] = *ncliques;
7176  cliquevars[0] = vars[i];
7177  cliquevalues[0] = values[i];
7178  ncliquevars = 1;
7179 
7180  /* if variable is not active (multi-aggregated or fixed), it cannot be in any clique */
7181  if( SCIPvarIsActive(vars[i]) && SCIPvarGetNCliques(vars[i], values[i]) > 0 )
7182  {
7183  /* greedily fill up the clique */
7184  for( j = i+1; j < nvars; ++j )
7185  {
7186  /* if variable is not active (multi-aggregated or fixed), it cannot be in any clique */
7187  if( cliquepartition[j] == -1 && SCIPvarIsActive(vars[j]) )
7188  {
7189  int k;
7190 
7191  /* check if every variable in the current clique can be extended by tmpvars[j] */
7192  for( k = ncliquevars - 1; k >= 0; --k )
7193  {
7194  if( !SCIPvarsHaveCommonClique(vars[j], values[j], cliquevars[k], cliquevalues[k], FALSE) )
7195  break;
7196  }
7197 
7198  if( k == -1 )
7199  {
7200  /* put the variable into the same clique */
7201  cliquepartition[j] = cliquepartition[i];
7202  cliquevars[ncliquevars] = vars[j];
7203  cliquevalues[ncliquevars] = values[j];
7204  ++ncliquevars;
7205  }
7206  }
7207  }
7208  }
7209 
7210  /* this clique is finished */
7211  ++(*ncliques);
7212  }
7213  assert(cliquepartition[i] >= 0 && cliquepartition[i] < i+1);
7214 
7215  /* break if we reached the maximal number of comparisons */
7216  if( i * nvars > maxncliquevarscomp )
7217  break;
7218  }
7219  /* if we had to many variables fill up the cliquepartition and put each variable in a separate clique */
7220  for( ; i < nvars; ++i )
7221  {
7222  if( cliquepartition[i] == -1 )
7223  {
7224  cliquepartition[i] = *ncliques;
7225  ++(*ncliques);
7226  }
7227  }
7228 
7229  SCIPsetFreeBufferArray(scip->set, &cliquevalues);
7230  SCIPsetFreeBufferArray(scip->set, &cliquevars);
7231 
7232  return SCIP_OKAY;
7233 }
7234 
7235 /** calculates a partition of the given set of binary variables into cliques; takes into account independent clique components
7236  *
7237  * The algorithm performs the following steps:
7238  * - recomputes connected components of the clique table, if necessary
7239  * - computes a clique partition for every connected component greedily.
7240  * - relabels the resulting clique partition such that it satisfies the description below
7241  *
7242  * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7243  * were assigned to the same clique;
7244  * the first variable is always assigned to clique 0, and a variable can only be assigned to clique i if at least one of
7245  * the preceding variables was assigned to clique i-1;
7246  * for each clique at most 1 variables can be set to TRUE in a feasible solution;
7247  *
7248  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7249  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7250  *
7251  * @pre This method can be called if @p scip is in one of the following stages:
7252  * - \ref SCIP_STAGE_INITPRESOLVE
7253  * - \ref SCIP_STAGE_PRESOLVING
7254  * - \ref SCIP_STAGE_EXITPRESOLVE
7255  * - \ref SCIP_STAGE_PRESOLVED
7256  * - \ref SCIP_STAGE_SOLVING
7257  */
7259  SCIP*const scip, /**< SCIP data structure */
7260  SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7261  int const nvars, /**< number of variables in the clique */
7262  int*const cliquepartition, /**< array of length nvars to store the clique partition */
7263  int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7264  )
7265 {
7266  SCIP_VAR** tmpvars;
7267 
7268  SCIP_VAR** sortedtmpvars;
7269  SCIP_Bool* tmpvalues;
7270  SCIP_Bool* sortedtmpvalues;
7271  int* componentlabels;
7272  int* sortedindices;
7273  int* componentstartposs;
7274  int i;
7275  int c;
7276 
7277  int ncomponents;
7278 
7279  assert(scip != NULL);
7280  assert(nvars == 0 || vars != NULL);
7281  assert(nvars == 0 || cliquepartition != NULL);
7282  assert(ncliques != NULL);
7283 
7284  SCIP_CALL( SCIPcheckStage(scip, "SCIPcalcCliquePartition", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7285 
7286  if( nvars == 0 )
7287  {
7288  *ncliques = 0;
7289  return SCIP_OKAY;
7290  }
7291 
7292  /* early abort if no cliques are present */
7293  if( SCIPgetNCliques(scip) == 0 )
7294  {
7295  for( i = 0; i < nvars; ++i )
7296  cliquepartition[i] = i;
7297 
7298  *ncliques = nvars;
7299 
7300  return SCIP_OKAY;
7301  }
7302 
7303  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &tmpvalues, nvars) );
7304  SCIP_CALL( SCIPsetDuplicateBufferArray(scip->set, &tmpvars, vars, nvars) );
7305  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &componentlabels, nvars) );
7306  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedindices, nvars) );
7307 
7308  /* initialize the tmpvalues array */
7309  for( i = nvars - 1; i >= 0; --i )
7310  {
7311  tmpvalues[i] = TRUE;
7312  cliquepartition[i] = -1;
7313  }
7314 
7315  /* get corresponding active problem variables */
7316  SCIP_CALL( SCIPvarsGetProbvarBinary(&tmpvars, &tmpvalues, nvars) );
7317 
7318  ncomponents = -1;
7319 
7320  /* update clique components if necessary */
7322  {
7323  SCIP_VAR** allvars;
7324  int nallbinvars;
7325  int nallintvars;
7326  int nallimplvars;
7327 
7328  SCIP_CALL( SCIPgetVarsData(scip, &allvars, NULL, &nallbinvars, &nallintvars, &nallimplvars, NULL) );
7329 
7330  SCIP_CALL( SCIPcliquetableComputeCliqueComponents(scip->cliquetable, scip->set, SCIPblkmem(scip), allvars, nallbinvars, nallintvars, nallimplvars) );
7331  }
7332 
7334 
7335  /* store the global clique component labels */
7336  for( i = 0; i < nvars; ++i )
7337  {
7338  if( SCIPvarIsActive(tmpvars[i]) )
7339  componentlabels[i] = SCIPcliquetableGetVarComponentIdx(scip->cliquetable, tmpvars[i]);
7340  else
7341  componentlabels[i] = -1;
7342  }
7343 
7344  /* relabel component labels order consistent as prerequisite for a stable sort */
7345  SCIP_CALL( relabelOrderConsistent(scip, componentlabels, nvars, &ncomponents) );
7346  assert(ncomponents >= 1);
7347  assert(ncomponents <= nvars);
7348 
7349  /* allocate storage array for the starting positions of the components */
7350  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &componentstartposs, ncomponents + 1) );
7351 
7352  /* stable sort the variables w.r.t. the component labels so that we can restrict the quadratic algorithm to the components */
7353  if( ncomponents > 1 )
7354  {
7355  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedtmpvars, nvars) );
7356  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedtmpvalues, nvars) );
7357  SCIP_CALL( labelSortStable(scip, tmpvars, componentlabels, sortedtmpvars, sortedindices, componentstartposs, nvars, ncomponents) );
7358 
7359  /* reassign the tmpvalues with respect to the sorting */
7360  for( i = 0; i < nvars; ++i )
7361  {
7362  assert(tmpvars[sortedindices[i]] == sortedtmpvars[i]);
7363  sortedtmpvalues[i] = tmpvalues[sortedindices[i]];
7364  }
7365  }
7366  else
7367  {
7368  /* if we have only one large connected component, skip the stable sorting and prepare the data differently */
7369  sortedtmpvars = tmpvars;
7370  sortedtmpvalues = tmpvalues;
7371  componentstartposs[0] = 0;
7372  componentstartposs[1] = nvars;
7373 
7374  /* sorted indices are the identity */
7375  for( i = 0; i < nvars; ++i )
7376  sortedindices[i] = i;
7377  }
7378 
7379  *ncliques = 0;
7380  /* calculate a greedy clique partition for each connected component */
7381  for( c = 0; c < ncomponents; ++c )
7382  {
7383  int* localcliquepartition;
7384  int nlocalcliques;
7385  int ncomponentvars;
7386  int l;
7387 
7388  /* extract the number of variables in this connected component */
7389  ncomponentvars = componentstartposs[c + 1] - componentstartposs[c];
7390  nlocalcliques = 0;
7391 
7392  /* allocate necessary memory to hold the intermediate component clique partition */
7393  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &localcliquepartition, ncomponentvars) );
7394 
7395  /* call greedy clique algorithm for all component variables */
7396  SCIP_CALL( calcCliquePartitionGreedy(scip, &(sortedtmpvars[componentstartposs[c]]), &(sortedtmpvalues[componentstartposs[c]]),
7397  ncomponentvars, localcliquepartition, &nlocalcliques) );
7398 
7399  assert(nlocalcliques >= 1);
7400  assert(nlocalcliques <= ncomponentvars);
7401 
7402  /* store the obtained clique partition with an offset of ncliques for the original variables */
7403  for( l = componentstartposs[c]; l < componentstartposs[c + 1]; ++l )
7404  {
7405  int origvaridx = sortedindices[l];
7406  assert(cliquepartition[origvaridx] == -1);
7407  assert(localcliquepartition[l - componentstartposs[c]] <= l - componentstartposs[c]);
7408  cliquepartition[origvaridx] = localcliquepartition[l - componentstartposs[c]] + (*ncliques);
7409  }
7410  *ncliques += nlocalcliques;
7411 
7412  /* free the local clique partition */
7413  SCIPsetFreeBufferArray(scip->set, &localcliquepartition);
7414  }
7415 
7416  /* except in the two trivial cases, we have to ensure the order consistency of the partition indices */
7417  if( ncomponents > 1 && ncomponents < nvars )
7418  {
7419  int partitionsize;
7420  SCIP_CALL( relabelOrderConsistent(scip, cliquepartition, nvars, &partitionsize) );
7421 
7422  assert(partitionsize == *ncliques);
7423  }
7424 
7425  if( ncomponents > 1 )
7426  {
7427  SCIPsetFreeBufferArray(scip->set, &sortedtmpvalues);
7428  SCIPsetFreeBufferArray(scip->set, &sortedtmpvars);
7429  }
7430 
7431  /* use the greedy algorithm as a whole to verify the result on small number of variables */
7432 #ifdef SCIP_DISABLED_CODE
7433  {
7434  int* debugcliquepartition;
7435  int ndebugcliques;
7436 
7437  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &debugcliquepartition, nvars) );
7438 
7439  /* call greedy clique algorithm for all component variables */
7440  SCIP_CALL( calcCliquePartitionGreedy(scip, tmpvars, tmpvalues, nvars, debugcliquepartition, &ndebugcliques) );
7441 
7442  /* loop and compare the traditional greedy clique with */
7443  for( i = 0; i < nvars; ++i )
7444  assert(i * nvars > MAXNCLIQUEVARSCOMP || cliquepartition[i] == debugcliquepartition[i]);
7445 
7446  SCIPsetFreeBufferArray(scip->set, &debugcliquepartition);
7447  }
7448 #endif
7449 
7450  /* free temporary memory */
7451  SCIPsetFreeBufferArray(scip->set, &componentstartposs);
7452  SCIPsetFreeBufferArray(scip->set, &sortedindices);
7453  SCIPsetFreeBufferArray(scip->set, &componentlabels);
7454  SCIPsetFreeBufferArray(scip->set, &tmpvars);
7455  SCIPsetFreeBufferArray(scip->set, &tmpvalues);
7456 
7457  return SCIP_OKAY;
7458 }
7459 
7460 /** calculates a partition of the given set of binary variables into negated cliques;
7461  * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7462  * were assigned to the same negated clique;
7463  * the first variable is always assigned to clique 0 and a variable can only be assigned to clique i if at least one of
7464  * the preceding variables was assigned to clique i-1;
7465  * for each clique with n_c variables at least n_c-1 variables can be set to TRUE in a feasible solution;
7466  *
7467  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7468  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7469  *
7470  * @pre This method can be called if @p scip is in one of the following stages:
7471  * - \ref SCIP_STAGE_INITPRESOLVE
7472  * - \ref SCIP_STAGE_PRESOLVING
7473  * - \ref SCIP_STAGE_EXITPRESOLVE
7474  * - \ref SCIP_STAGE_PRESOLVED
7475  * - \ref SCIP_STAGE_SOLVING
7476  */
7478  SCIP*const scip, /**< SCIP data structure */
7479  SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7480  int const nvars, /**< number of variables in the clique */
7481  int*const cliquepartition, /**< array of length nvars to store the clique partition */
7482  int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7483  )
7484 {
7485  SCIP_VAR** negvars;
7486  int v;
7487 
7488  assert(scip != NULL);
7489  assert(cliquepartition != NULL || nvars == 0);
7490  assert(ncliques != NULL);
7491 
7492  if( nvars == 0 )
7493  {
7494  *ncliques = 0;
7495  return SCIP_OKAY;
7496  }
7497  assert(vars != NULL);
7498 
7499  /* allocate temporary memory */
7500  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &negvars, nvars) );
7501 
7502  /* get all negated variables */
7503  for( v = nvars - 1; v >= 0; --v )
7504  {
7505  SCIP_CALL( SCIPgetNegatedVar(scip, vars[v], &(negvars[v])) );
7506  }
7507 
7508  /* calculate cliques on negated variables, which are "negated" cliques on normal variables array */
7509  SCIP_CALL( SCIPcalcCliquePartition( scip, negvars, nvars, cliquepartition, ncliques) );
7510 
7511  /* free temporary memory */
7512  SCIPsetFreeBufferArray(scip->set, &negvars);
7513 
7514  return SCIP_OKAY;
7515 }
7516 
7517 
7518 /** force SCIP to clean up all cliques; cliques do not get automatically cleaned up after presolving. Use
7519  * this method to prevent inactive variables in cliques when retrieved via SCIPgetCliques()
7520  *
7521  * @return SCIP_OKAY if everything worked, otherwise a suitable error code is passed
7522  *
7523  * @pre This method can be called if @p scip is in one of the following stages:
7524  * - \ref SCIP_STAGE_TRANSFORMED
7525  * - \ref SCIP_STAGE_INITPRESOLVE
7526  * - \ref SCIP_STAGE_PRESOLVING
7527  * - \ref SCIP_STAGE_EXITPRESOLVE
7528  * - \ref SCIP_STAGE_PRESOLVED
7529  * - \ref SCIP_STAGE_INITSOLVE
7530  * - \ref SCIP_STAGE_SOLVING
7531  * - \ref SCIP_STAGE_SOLVED
7532  * - \ref SCIP_STAGE_EXITSOLVE
7533  */
7535  SCIP* scip, /**< SCIP data structure */
7536  SCIP_Bool* infeasible /**< pointer to store if cleanup detected infeasibility */
7537  )
7538 {
7539  int nlocalbdchgs;
7540  SCIP_Bool globalinfeasibility;
7541 
7542  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPcleanupCliques", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7543 
7544  globalinfeasibility = FALSE;
7545  nlocalbdchgs = 0;
7546  SCIP_CALL( SCIPcliquetableCleanup(scip->cliquetable, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
7547  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, &nlocalbdchgs,
7548  &globalinfeasibility) );
7549 
7550  if( infeasible != NULL )
7551  *infeasible = globalinfeasibility;
7552 
7553  if( globalinfeasibility )
7555 
7556  return SCIP_OKAY;
7557 }
7558 
7559 /** gets the number of cliques in the clique table
7560  *
7561  * @return number of cliques in the clique table
7562  *
7563  * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7564  * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
7565  *
7566  * @pre This method can be called if @p scip is in one of the following stages:
7567  * - \ref SCIP_STAGE_TRANSFORMED
7568  * - \ref SCIP_STAGE_INITPRESOLVE
7569  * - \ref SCIP_STAGE_PRESOLVING
7570  * - \ref SCIP_STAGE_EXITPRESOLVE
7571  * - \ref SCIP_STAGE_PRESOLVED
7572  * - \ref SCIP_STAGE_INITSOLVE
7573  * - \ref SCIP_STAGE_SOLVING
7574  * - \ref SCIP_STAGE_SOLVED
7575  * - \ref SCIP_STAGE_EXITSOLVE
7576  */
7578  SCIP* scip /**< SCIP data structure */
7579  )
7580 {
7581  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNCliques", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7582 
7584 }
7585 
7586 /** gets the number of cliques created so far by the cliquetable
7587  *
7588  * @return number of cliques created so far by the cliquetable
7589  *
7590  * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7591  * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
7592  *
7593  * @pre This method can be called if @p scip is in one of the following stages:
7594  * - \ref SCIP_STAGE_TRANSFORMED
7595  * - \ref SCIP_STAGE_INITPRESOLVE
7596  * - \ref SCIP_STAGE_PRESOLVING
7597  * - \ref SCIP_STAGE_EXITPRESOLVE
7598  * - \ref SCIP_STAGE_PRESOLVED
7599  * - \ref SCIP_STAGE_INITSOLVE
7600  * - \ref SCIP_STAGE_SOLVING
7601  * - \ref SCIP_STAGE_SOLVED
7602  * - \ref SCIP_STAGE_EXITSOLVE
7603  */
7605  SCIP* scip /**< SCIP data structure */
7606  )
7607 {
7608  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNCliquesCreated", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7609 
7611 }
7612 
7613 /** gets the array of cliques in the clique table
7614  *
7615  * @return array of cliques in the clique table
7616  *
7617  * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7618  * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
7619  *
7620  * @pre This method can be called if @p scip is in one of the following stages:
7621  * - \ref SCIP_STAGE_TRANSFORMED
7622  * - \ref SCIP_STAGE_INITPRESOLVE
7623  * - \ref SCIP_STAGE_PRESOLVING
7624  * - \ref SCIP_STAGE_EXITPRESOLVE
7625  * - \ref SCIP_STAGE_PRESOLVED
7626  * - \ref SCIP_STAGE_INITSOLVE
7627  * - \ref SCIP_STAGE_SOLVING
7628  * - \ref SCIP_STAGE_SOLVED
7629  * - \ref SCIP_STAGE_EXITSOLVE
7630  */
7632  SCIP* scip /**< SCIP data structure */
7633  )
7634 {
7635  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetCliques", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7636 
7637  return SCIPcliquetableGetCliques(scip->cliquetable);
7638 }
7639 
7640 /** returns whether there is a clique that contains both given variable/value pairs;
7641  * the variables must be active binary variables;
7642  * if regardimplics is FALSE, only the cliques in the clique table are looked at;
7643  * if regardimplics is TRUE, both the cliques and the implications of the implication graph are regarded
7644  *
7645  * @return TRUE, if there is a clique that contains both variable/clique pairs; FALSE, otherwise
7646  *
7647  * @pre This method can be called if @p scip is in one of the following stages:
7648  * - \ref SCIP_STAGE_TRANSFORMED
7649  * - \ref SCIP_STAGE_INITPRESOLVE
7650  * - \ref SCIP_STAGE_PRESOLVING
7651  * - \ref SCIP_STAGE_EXITPRESOLVE
7652  * - \ref SCIP_STAGE_PRESOLVED
7653  * - \ref SCIP_STAGE_INITSOLVE
7654  * - \ref SCIP_STAGE_SOLVING
7655  * - \ref SCIP_STAGE_SOLVED
7656  * - \ref SCIP_STAGE_EXITSOLVE
7657  *
7658  * @note a variable with it's negated variable are NOT! in a clique
7659  * @note a variable with itself are in a clique
7660  */
7662  SCIP* scip, /**< SCIP data structure */
7663  SCIP_VAR* var1, /**< first variable */
7664  SCIP_Bool value1, /**< value of first variable */
7665  SCIP_VAR* var2, /**< second variable */
7666  SCIP_Bool value2, /**< value of second variable */
7667  SCIP_Bool regardimplics /**< should the implication graph also be searched for a clique? */
7668  )
7669 {
7670  assert(scip != NULL);
7671  assert(var1 != NULL);
7672  assert(var2 != NULL);
7673  assert(SCIPvarIsActive(var1));
7674  assert(SCIPvarIsActive(var2));
7675  assert(SCIPvarIsBinary(var1));
7676  assert(SCIPvarIsBinary(var2));
7677 
7678  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPhaveVarsCommonClique", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7679 
7680  /* if both variables together have more cliques then actual cliques exist, then they have a common clique (in debug
7681  * mode we check this for correctness), otherwise we need to call the pairwise comparison method for these variables
7682  */
7683 #ifndef NDEBUG
7684  assert((SCIPvarGetNCliques(var1, value1) + SCIPvarGetNCliques(var2, value2) > SCIPcliquetableGetNCliques(scip->cliquetable)) ? SCIPvarsHaveCommonClique(var1, value1, var2, value2, FALSE) : TRUE);
7685 #endif
7686 
7687  return (SCIPvarGetNCliques(var1, value1) + SCIPvarGetNCliques(var2, value2) > SCIPcliquetableGetNCliques(scip->cliquetable)
7688  || SCIPvarsHaveCommonClique(var1, value1, var2, value2, regardimplics));
7689 }
7690 
7691 /** writes the clique graph to a gml file
7692  *
7693  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7694  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7695  *
7696  * @pre This method can be called if @p scip is in one of the following stages:
7697  * - \ref SCIP_STAGE_TRANSFORMED
7698  * - \ref SCIP_STAGE_INITPRESOLVE
7699  * - \ref SCIP_STAGE_PRESOLVING
7700  * - \ref SCIP_STAGE_EXITPRESOLVE
7701  * - \ref SCIP_STAGE_PRESOLVED
7702  * - \ref SCIP_STAGE_INITSOLVE
7703  * - \ref SCIP_STAGE_SOLVING
7704  * - \ref SCIP_STAGE_SOLVED
7705  * - \ref SCIP_STAGE_EXITSOLVE
7706  *
7707  * @note there can be duplicated arcs in the output file
7708  *
7709  * If @p writenodeweights is true, only nodes corresponding to variables that have a fractional value and only edges
7710  * between such nodes are written.
7711  */
7713  SCIP* scip, /**< SCIP data structure */
7714  const char* fname, /**< name of file */
7715  SCIP_Bool writenodeweights /**< should we write weights of nodes? */
7716  )
7717 {
7718  FILE* gmlfile;
7719  SCIP_HASHMAP* nodehashmap;
7720  SCIP_CLIQUE** cliques;
7721  SCIP_VAR** clqvars;
7722  SCIP_VAR** allvars;
7723  SCIP_Bool* clqvalues;
7724  char nodename[SCIP_MAXSTRLEN];
7725  int nallvars;
7726  int nbinvars;
7727  int nintvars;
7728  int nimplvars;
7729  int ncliques;
7730  int c;
7731  int v1;
7732  int v2;
7733  int id1;
7734  int id2;
7735 
7736  assert(scip != NULL);
7737  assert(fname != NULL);
7738 
7739  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPwriteCliqueGraph", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7740 
7741  /* get all active variables */
7742  SCIP_CALL( SCIPgetVarsData(scip, &allvars, &nallvars, &nbinvars, &nintvars, &nimplvars, NULL) );
7743 
7744  /* no possible variables for cliques exist */
7745  if( nbinvars + nimplvars == 0 )
7746  return SCIP_OKAY;
7747 
7748  ncliques = SCIPgetNCliques(scip);
7749 
7750  /* no cliques and do not wont to check for binary implications */
7751  if( ncliques == 0 )
7752  return SCIP_OKAY;
7753 
7754  /* open gml file */
7755  gmlfile = fopen(fname, "w");
7756 
7757  if( gmlfile == NULL )
7758  {
7759  SCIPerrorMessage("cannot open graph file <%s>\n", fname);
7760  SCIPABORT();
7761  return SCIP_INVALIDDATA; /*lint !e527*/
7762  }
7763 
7764  /* create the hash map */
7765  SCIP_CALL_FINALLY( SCIPhashmapCreate(&nodehashmap, SCIPblkmem(scip), nbinvars+nimplvars), fclose(gmlfile) );
7766 
7767  /* write starting of gml file */
7768  SCIPgmlWriteOpening(gmlfile, TRUE);
7769 
7770  cliques = SCIPgetCliques(scip);
7771 
7772  /* write nodes and arcs for all cliques */
7773  for( c = ncliques - 1; c >= 0; --c )
7774  {
7775  clqvalues = SCIPcliqueGetValues(cliques[c]);
7776  clqvars = SCIPcliqueGetVars(cliques[c]);
7777 
7778  for( v1 = SCIPcliqueGetNVars(cliques[c]) - 1; v1 >= 0; --v1 )
7779  {
7780  id1 = clqvalues[v1] ? SCIPvarGetProbindex(clqvars[v1]) : (nallvars + SCIPvarGetProbindex(clqvars[v1]));
7781 
7782  /* if corresponding node was not added yet, add it */
7783  if( !SCIPhashmapExists(nodehashmap, (void*)(size_t)id1) )
7784  {
7785  assert(id1 >= 0);
7786  SCIP_CALL_FINALLY( SCIPhashmapInsertInt(nodehashmap, (void*)(size_t)id1, 1), fclose(gmlfile) ); /*lint !e571*/
7787 
7788  (void) SCIPsnprintf(nodename, SCIP_MAXSTRLEN, "%s%s", (id1 >= nallvars ? "~" : ""), SCIPvarGetName(clqvars[v1]));
7789 
7790  /* write new gml node for new variable */
7791  if ( writenodeweights )
7792  {
7793  if ( ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v1])) )
7794  SCIPgmlWriteNodeWeight(gmlfile, (unsigned int)id1, nodename, NULL, NULL, NULL, SCIPgetSolVal(scip, NULL, clqvars[v1]));
7795  }
7796  else
7797  {
7798  SCIPgmlWriteNode(gmlfile, (unsigned int)id1, nodename, NULL, NULL, NULL);
7799  }
7800  }
7801 
7802  for( v2 = SCIPcliqueGetNVars(cliques[c]) - 1; v2 >= 0; --v2 )
7803  {
7804  if( v1 == v2 )
7805  continue;
7806 
7807  id2 = clqvalues[v2] ? SCIPvarGetProbindex(clqvars[v2]) : (nallvars + SCIPvarGetProbindex(clqvars[v2]));
7808 
7809  /* if corresponding node was not added yet, add it */
7810  if( !SCIPhashmapExists(nodehashmap, (void*)(size_t)id2) )
7811  {
7812  assert(id2 >= 0);
7813  SCIP_CALL_FINALLY( SCIPhashmapInsertInt(nodehashmap, (void*)(size_t)id2, 1), fclose(gmlfile) ); /*lint !e571*/
7814 
7815  (void) SCIPsnprintf(nodename, SCIP_MAXSTRLEN, "%s%s", (id2 >= nallvars ? "~" : ""), SCIPvarGetName(clqvars[v2]));
7816 
7817  /* write new gml node for new variable */
7818  if ( writenodeweights )
7819  {
7820  if ( ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v2])) )
7821  SCIPgmlWriteNodeWeight(gmlfile, (unsigned int)id2, nodename, NULL, NULL, NULL, SCIPgetSolVal(scip, NULL, clqvars[v2]));
7822  }
7823  else
7824  {
7825  SCIPgmlWriteNode(gmlfile, (unsigned int)id2, nodename, NULL, NULL, NULL);
7826  }
7827  }
7828 
7829  /* write gml arc between resultant and operand */
7830  if ( ! writenodeweights || ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v2])) )
7831  SCIPgmlWriteArc(gmlfile, (unsigned int)id1, (unsigned int)id2, NULL, NULL);
7832  }
7833  }
7834  }
7835 
7836  /* free the hash map */
7837  SCIPhashmapFree(&nodehashmap);
7838 
7839  SCIPgmlWriteClosing(gmlfile);
7840  fclose(gmlfile);
7841 
7842  return SCIP_OKAY;
7843 }
7844 
7845 /** Removes (irrelevant) variable from all its global structures, i.e. cliques, implications and variable bounds.
7846  * This is an advanced method which should be used with care.
7847  *
7848  * @return SCIP_OKAY if everything worked, otherwise a suitable error code is passed
7849  *
7850  * @pre This method can be called if @p scip is in one of the following stages:
7851  * - \ref SCIP_STAGE_TRANSFORMED
7852  * - \ref SCIP_STAGE_INITPRESOLVE
7853  * - \ref SCIP_STAGE_PRESOLVING
7854  * - \ref SCIP_STAGE_EXITPRESOLVE
7855  * - \ref SCIP_STAGE_PRESOLVED
7856  * - \ref SCIP_STAGE_INITSOLVE
7857  * - \ref SCIP_STAGE_SOLVING
7858  * - \ref SCIP_STAGE_SOLVED
7859  * - \ref SCIP_STAGE_EXITSOLVE
7860  */
7862  SCIP* scip, /**< SCIP data structure */
7863  SCIP_VAR* var /**< variable to remove from global structures */
7864  )
7865 {
7866  assert(scip != NULL);
7867 
7868  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPremoveVarFromGlobalStructures", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7869 
7870  /* mark the variable as deletable from global structures - This is necessary for the delayed clean up of cliques */
7872 
7873  /* remove variable from all its cliques, implications, and variable bounds */
7875 
7876  return SCIP_OKAY;
7877 }
7878 
7879 /** sets the branch factor of the variable; this value can be used in the branching methods to scale the score
7880  * values of the variables; higher factor leads to a higher probability that this variable is chosen for branching
7881  *
7882  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7883  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7884  *
7885  * @pre This method can be called if @p scip is in one of the following stages:
7886  * - \ref SCIP_STAGE_PROBLEM
7887  * - \ref SCIP_STAGE_TRANSFORMING
7888  * - \ref SCIP_STAGE_TRANSFORMED
7889  * - \ref SCIP_STAGE_INITPRESOLVE
7890  * - \ref SCIP_STAGE_PRESOLVING
7891  * - \ref SCIP_STAGE_EXITPRESOLVE
7892  * - \ref SCIP_STAGE_PRESOLVED
7893  * - \ref SCIP_STAGE_SOLVING
7894  */
7896  SCIP* scip, /**< SCIP data structure */
7897  SCIP_VAR* var, /**< problem variable */
7898  SCIP_Real branchfactor /**< factor to weigh variable's branching score with */
7899  )
7900 {
7901  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7902 
7903  SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, branchfactor) );
7904 
7905  return SCIP_OKAY;
7906 }
7907 
7908 /** scales the branch factor of the variable with the given value
7909  *
7910  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7911  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7912  *
7913  * @pre This method can be called if @p scip is in one of the following stages:
7914  * - \ref SCIP_STAGE_PROBLEM
7915  * - \ref SCIP_STAGE_TRANSFORMING
7916  * - \ref SCIP_STAGE_TRANSFORMED
7917  * - \ref SCIP_STAGE_INITPRESOLVE
7918  * - \ref SCIP_STAGE_PRESOLVING
7919  * - \ref SCIP_STAGE_EXITPRESOLVE
7920  * - \ref SCIP_STAGE_PRESOLVED
7921  * - \ref SCIP_STAGE_SOLVING
7922  */
7924  SCIP* scip, /**< SCIP data structure */
7925  SCIP_VAR* var, /**< problem variable */
7926  SCIP_Real scale /**< factor to scale variable's branching factor with */
7927  )
7928 {
7929  SCIP_CALL( SCIPcheckStage(scip, "SCIPscaleVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7930 
7931  SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, scale * SCIPvarGetBranchFactor(var)) );
7932 
7933  return SCIP_OKAY;
7934 }
7935 
7936 /** adds the given value to the branch factor of the variable
7937  *
7938  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7939  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7940  *
7941  * @pre This method can be called if @p scip is in one of the following stages:
7942  * - \ref SCIP_STAGE_PROBLEM
7943  * - \ref SCIP_STAGE_TRANSFORMING
7944  * - \ref SCIP_STAGE_TRANSFORMED
7945  * - \ref SCIP_STAGE_INITPRESOLVE
7946  * - \ref SCIP_STAGE_PRESOLVING
7947  * - \ref SCIP_STAGE_EXITPRESOLVE
7948  * - \ref SCIP_STAGE_PRESOLVED
7949  * - \ref SCIP_STAGE_SOLVING
7950  */
7952  SCIP* scip, /**< SCIP data structure */
7953  SCIP_VAR* var, /**< problem variable */
7954  SCIP_Real addfactor /**< value to add to the branch factor of the variable */
7955  )
7956 {
7957  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7958 
7959  SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, addfactor + SCIPvarGetBranchFactor(var)) );
7960 
7961  return SCIP_OKAY;
7962 }
7963 
7964 /** sets the branch priority of the variable; variables with higher branch priority are always preferred to variables
7965  * with lower priority in selection of branching variable
7966  *
7967  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7968  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7969  *
7970  * @pre This method can be called if @p scip is in one of the following stages:
7971  * - \ref SCIP_STAGE_PROBLEM
7972  * - \ref SCIP_STAGE_TRANSFORMING
7973  * - \ref SCIP_STAGE_TRANSFORMED
7974  * - \ref SCIP_STAGE_INITPRESOLVE
7975  * - \ref SCIP_STAGE_PRESOLVING
7976  * - \ref SCIP_STAGE_EXITPRESOLVE
7977  * - \ref SCIP_STAGE_PRESOLVED
7978  * - \ref SCIP_STAGE_SOLVING
7979  *
7980  * @note the default branching priority is 0
7981  */
7983  SCIP* scip, /**< SCIP data structure */
7984  SCIP_VAR* var, /**< problem variable */
7985  int branchpriority /**< branch priority of the variable */
7986  )
7987 {
7988  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7989 
7990  assert( var->scip == scip );
7991 
7992  if( SCIPisTransformed(scip) )
7993  {
7994  assert(scip->branchcand != NULL);
7995 
7996  /* inform the pseudo branch candidates that the branch priority changes and change the branch priority */
7997  SCIP_CALL( SCIPbranchcandUpdateVarBranchPriority(scip->branchcand, scip->set, var, branchpriority) );
7998  }
7999  else
8000  {
8001  /* change the branching priority of the variable */
8002  SCIP_CALL( SCIPvarChgBranchPriority(var, branchpriority) );
8003  }
8004 
8005  return SCIP_OKAY;
8006 }
8007 
8008 /** changes the branch priority of the variable to the given value, if it is larger than the current priority
8009  *
8010  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8011  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8012  *
8013  * @pre This method can be called if @p scip is in one of the following stages:
8014  * - \ref SCIP_STAGE_PROBLEM
8015  * - \ref SCIP_STAGE_TRANSFORMING
8016  * - \ref SCIP_STAGE_TRANSFORMED
8017  * - \ref SCIP_STAGE_INITPRESOLVE
8018  * - \ref SCIP_STAGE_PRESOLVING
8019  * - \ref SCIP_STAGE_EXITPRESOLVE
8020  * - \ref SCIP_STAGE_PRESOLVED
8021  * - \ref SCIP_STAGE_SOLVING
8022  */
8024  SCIP* scip, /**< SCIP data structure */
8025  SCIP_VAR* var, /**< problem variable */
8026  int branchpriority /**< new branch priority of the variable, if it is larger than current priority */
8027  )
8028 {
8029  SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8030 
8031  assert( var->scip == scip );
8032 
8033  if( branchpriority > SCIPvarGetBranchPriority(var) )
8034  {
8035  SCIP_CALL( SCIPvarChgBranchPriority(var, branchpriority) );
8036  }
8037 
8038  return SCIP_OKAY;
8039 }
8040 
8041 /** adds the given value to the branch priority of the variable
8042  *
8043  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8044  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8045  *
8046  * @pre This method can be called if @p scip is in one of the following stages:
8047  * - \ref SCIP_STAGE_PROBLEM
8048  * - \ref SCIP_STAGE_TRANSFORMING
8049  * - \ref SCIP_STAGE_TRANSFORMED
8050  * - \ref SCIP_STAGE_INITPRESOLVE
8051  * - \ref SCIP_STAGE_PRESOLVING
8052  * - \ref SCIP_STAGE_EXITPRESOLVE
8053  * - \ref SCIP_STAGE_PRESOLVED
8054  * - \ref SCIP_STAGE_SOLVING
8055  */
8057  SCIP* scip, /**< SCIP data structure */
8058  SCIP_VAR* var, /**< problem variable */
8059  int addpriority /**< value to add to the branch priority of the variable */
8060  )
8061 {
8062  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8063 
8064  assert( var->scip == scip );
8065 
8066  SCIP_CALL( SCIPvarChgBranchPriority(var, addpriority + SCIPvarGetBranchPriority(var)) );
8067 
8068  return SCIP_OKAY;
8069 }
8070 
8071 /** sets the branch direction of the variable (-1: prefer downwards branch, 0: automatic selection, +1: prefer upwards
8072  * branch)
8073  *
8074  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8075  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8076  *
8077  * @pre This method can be called if @p scip is in one of the following stages:
8078  * - \ref SCIP_STAGE_PROBLEM
8079  * - \ref SCIP_STAGE_TRANSFORMING
8080  * - \ref SCIP_STAGE_TRANSFORMED
8081  * - \ref SCIP_STAGE_INITPRESOLVE
8082  * - \ref SCIP_STAGE_PRESOLVING
8083  * - \ref SCIP_STAGE_EXITPRESOLVE
8084  * - \ref SCIP_STAGE_PRESOLVED
8085  * - \ref SCIP_STAGE_SOLVING
8086  */
8088  SCIP* scip, /**< SCIP data structure */
8089  SCIP_VAR* var, /**< problem variable */
8090  SCIP_BRANCHDIR branchdirection /**< preferred branch direction of the variable (downwards, upwards, auto) */
8091  )
8092 {
8093  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchDirection", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8094 
8095  assert( var->scip == scip );
8096 
8097  SCIP_CALL( SCIPvarChgBranchDirection(var, branchdirection) );
8098 
8099  return SCIP_OKAY;
8100 }
8101 
8102 /** tightens the variable bounds due to a new variable type */
8103 static
8105  SCIP* scip, /**< SCIP data structure */
8106  SCIP_VAR* var, /**< variable to change the bound for */
8107  SCIP_VARTYPE vartype, /**< new type of variable */
8108  SCIP_Bool* infeasible /**< pointer to store whether an infeasibility was detected (, due to
8109  * integrality condition of the new variable type) */
8110  )
8111 {
8112  assert(scip != NULL);
8114  assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPvarIsTransformed(var));
8115  assert(var->scip == scip);
8116 
8117  *infeasible = FALSE;
8118 
8119  /* adjusts bounds if the variable type changed form continuous to non-continuous (integral) */
8121  {
8122  SCIP_Bool tightened;
8123 
8124  /* we adjust variable bounds to integers first, since otherwise a later bound tightening with a fractional old
8125  * bound may give an assert because SCIP expects non-continuous variables to have non-fractional bounds
8126  *
8127  * we adjust bounds with a fractionality within [eps,feastol] only if the resulting bound change is a bound
8128  * tightening, because relaxing bounds may not be allowed
8129  */
8130  if( !SCIPisFeasIntegral(scip, SCIPvarGetLbGlobal(var)) ||
8132  (!SCIPsetIsEQ(scip->set, SCIPvarGetLbGlobal(var), SCIPfeasCeil(scip, SCIPvarGetLbGlobal(var))) &&
8134  )
8135  {
8136  SCIP_CALL( SCIPtightenVarLbGlobal(scip, var, SCIPfeasCeil(scip, SCIPvarGetLbGlobal(var)), TRUE, infeasible, &tightened) );
8137  if( *infeasible )
8138  return SCIP_OKAY;
8139 
8140  /* 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
8141  * 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
8142  */
8143  assert(tightened || SCIPisFeasLE(scip, SCIPvarGetUbGlobal(var), SCIPfeasCeil(scip, SCIPvarGetLbGlobal(var))));
8144  }
8145  if( !SCIPisFeasIntegral(scip, SCIPvarGetUbGlobal(var)) ||
8147  )
8148  {
8149  SCIP_CALL( SCIPtightenVarUbGlobal(scip, var, SCIPfeasFloor(scip, SCIPvarGetUbGlobal(var)), TRUE, infeasible, &tightened) );
8150  if( *infeasible )
8151  return SCIP_OKAY;
8152 
8153  assert(tightened || SCIPisFeasGE(scip, SCIPvarGetLbGlobal(var), SCIPfeasFloor(scip, SCIPvarGetUbGlobal(var))));
8154  }
8155  }
8156 
8157  return SCIP_OKAY;
8158 }
8159 
8160 /** changes type of variable in the problem;
8161  *
8162  * @warning This type change might change the variable array returned from SCIPgetVars() and SCIPgetVarsData();
8163  *
8164  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8165  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8166  *
8167  * @pre This method can be called if @p scip is in one of the following stages:
8168  * - \ref SCIP_STAGE_PROBLEM
8169  * - \ref SCIP_STAGE_TRANSFORMING
8170  * - \ref SCIP_STAGE_PRESOLVING
8171  *
8172  * @note If SCIP is already beyond the SCIP_STAGE_PROBLEM and a original variable is passed, the variable type of the
8173  * corresponding transformed variable is changed; the type of the original variable does not change
8174  *
8175  * @note If the type changes from a continuous variable to a non-continuous variable the bounds of the variable get
8176  * adjusted w.r.t. to integrality information
8177  */
8179  SCIP* scip, /**< SCIP data structure */
8180  SCIP_VAR* var, /**< variable to change the bound for */
8181  SCIP_VARTYPE vartype, /**< new type of variable */
8182  SCIP_Bool* infeasible /**< pointer to store whether an infeasibility was detected (, due to
8183  * integrality condition of the new variable type) */
8184  )
8185 {
8186  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarType", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
8187 
8188  assert(var != NULL);
8189  assert(var->scip == scip);
8190 
8191  if( SCIPvarIsNegated(var) )
8192  {
8193  SCIPdebugMsg(scip, "upgrading type of negated variable <%s> from %d to %d\n", SCIPvarGetName(var), SCIPvarGetType(var), vartype);
8194  var = SCIPvarGetNegationVar(var);
8195  }
8196 #ifndef NDEBUG
8197  else
8198  {
8199  if( SCIPgetStage(scip) > SCIP_STAGE_PROBLEM )
8200  {
8201  SCIPdebugMsg(scip, "upgrading type of variable <%s> from %d to %d\n", SCIPvarGetName(var), SCIPvarGetType(var), vartype);
8202  }
8203  }
8204 #endif
8205 
8206  /* change variable type */
8207  switch( scip->set->stage )
8208  {
8209  case SCIP_STAGE_PROBLEM:
8210  assert(!SCIPvarIsTransformed(var));
8211 
8212  /* first adjust the variable due to new integrality information */
8213  SCIP_CALL( tightenBounds(scip, var, vartype, infeasible) );
8214 
8215  /* second change variable type */
8216  if( SCIPvarGetProbindex(var) >= 0 )
8217  {
8218  SCIP_CALL( SCIPprobChgVarType(scip->origprob, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8219  scip->branchcand, scip->eventqueue, scip->cliquetable, var, vartype) );
8220  }
8221  else
8222  {
8223  SCIP_CALL( SCIPvarChgType(var, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8224  scip->eventqueue, vartype) );
8225  }
8226  break;
8227 
8228  case SCIP_STAGE_PRESOLVING:
8229  if( !SCIPvarIsTransformed(var) )
8230  {
8231  SCIP_VAR* transvar;
8232 
8233  SCIP_CALL( SCIPgetTransformedVar(scip, var, &transvar) );
8234  assert(transvar != NULL);
8235 
8236  /* recall method with transformed variable */
8237  SCIP_CALL( SCIPchgVarType(scip, transvar, vartype, infeasible) );
8238  return SCIP_OKAY;
8239  }
8240 
8241  /* first adjust the variable due to new integrality information */
8242  SCIP_CALL( tightenBounds(scip, var, vartype, infeasible) );
8243 
8244  /* second change variable type */
8245  if( SCIPvarGetProbindex(var) >= 0 )
8246  {
8247  SCIP_CALL( SCIPprobChgVarType(scip->transprob, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8248  scip->branchcand, scip->eventqueue, scip->cliquetable, var, vartype) );
8249  }
8250  else
8251  {
8252  SCIP_CALL( SCIPvarChgType(var, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8253  scip->eventqueue, vartype) );
8254  }
8255  break;
8256 
8257  default:
8258  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
8259  return SCIP_INVALIDCALL;
8260  } /*lint !e788*/
8261 
8262  return SCIP_OKAY;
8263 }
8264 
8265 /** in problem creation and solving stage, both bounds of the variable are set to the given value;
8266  * in presolving stage, the variable is converted into a fixed variable, and bounds are changed respectively;
8267  * conversion into a fixed variable changes the vars array returned from SCIPgetVars() and SCIPgetVarsData(),
8268  * and also renders arrays returned from the SCIPvarGetImpl...() methods invalid
8269  *
8270  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8271  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8272  *
8273  * @pre This method can be called if @p scip is in one of the following stages:
8274  * - \ref SCIP_STAGE_PROBLEM
8275  * - \ref SCIP_STAGE_PRESOLVING
8276  * - \ref SCIP_STAGE_SOLVING
8277  */
8279  SCIP* scip, /**< SCIP data structure */
8280  SCIP_VAR* var, /**< variable to fix */
8281  SCIP_Real fixedval, /**< value to fix variable to */
8282  SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
8283  SCIP_Bool* fixed /**< pointer to store whether the fixing was performed (variable was unfixed) */
8284  )
8285 {
8286  assert(var != NULL);
8287  assert(infeasible != NULL);
8288  assert(fixed != NULL);
8289 
8290  SCIP_CALL( SCIPcheckStage(scip, "SCIPfixVar", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8291 
8292  *infeasible = FALSE;
8293  *fixed = FALSE;
8294 
8295  /* in the problem creation stage, modify the bounds as requested, independently from the current bounds */
8296  if( scip->set->stage != SCIP_STAGE_PROBLEM )
8297  {
8298  if( (SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPsetIsFeasIntegral(scip->set, fixedval))
8299  || SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetLbLocal(var))
8300  || SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8301  {
8302  *infeasible = TRUE;
8303  return SCIP_OKAY;
8304  }
8305  else if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED )
8306  {
8307  *infeasible = !SCIPsetIsFeasEQ(scip->set, fixedval, SCIPvarGetLbLocal(var));
8308  return SCIP_OKAY;
8309  }
8310  }
8311  else
8312  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_ORIGINAL);
8313 
8314  switch( scip->set->stage )
8315  {
8316  case SCIP_STAGE_PROBLEM:
8317  /* in the problem creation stage, modify the bounds as requested, independently from the current bounds;
8318  * we have to make sure, that the order of the bound changes does not intermediately produce an invalid
8319  * interval lb > ub
8320  */
8321  if( fixedval <= SCIPvarGetLbLocal(var) )
8322  {
8323  SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
8324  SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
8325  *fixed = TRUE;
8326  }
8327  else
8328  {
8329  SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
8330  SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
8331  *fixed = TRUE;
8332  }
8333  return SCIP_OKAY;
8334 
8335  case SCIP_STAGE_PRESOLVING:
8336  if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
8337  {
8338  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8339  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8340  scip->cliquetable, fixedval, infeasible, fixed) );
8341  return SCIP_OKAY;
8342  }
8343  /*lint -fallthrough*/
8344  case SCIP_STAGE_SOLVING:
8345  if( SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetLbLocal(var)) )
8346  {
8347  if( SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8348  {
8349  *infeasible = TRUE;
8350  return SCIP_OKAY;
8351  }
8352  else
8353  {
8354  SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
8355  *fixed = TRUE;
8356  }
8357  }
8358  if( SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8359  {
8360  if( SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetLbLocal(var)) )
8361  {
8362  *infeasible = TRUE;
8363  return SCIP_OKAY;
8364  }
8365  else
8366  {
8367  SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
8368  *fixed = TRUE;
8369  }
8370  }
8371  return SCIP_OKAY;
8372 
8373  default:
8374  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
8375  return SCIP_INVALIDCALL;
8376  } /*lint !e788*/
8377 }
8378 
8379 /** From a given equality a*x + b*y == c, aggregates one of the variables and removes it from the set of
8380  * active problem variables. This changes the vars array returned from SCIPgetVars() and SCIPgetVarsData(),
8381  * and also renders the arrays returned from the SCIPvarGetImpl...() methods for the two variables invalid.
8382  * In the first step, the equality is transformed into an equality with active problem variables
8383  * a'*x' + b'*y' == c'. If x' == y', this leads to the detection of redundancy if a' == -b' and c' == 0,
8384  * of infeasibility, if a' == -b' and c' != 0, or to a variable fixing x' == c'/(a'+b') (and possible
8385  * infeasibility) otherwise.
8386  * In the second step, the variable to be aggregated is chosen among x' and y', prefering a less strict variable
8387  * type as aggregation variable (i.e. continuous variables are preferred over implicit integers, implicit integers
8388  * over integers, and integers over binaries). If none of the variables is continuous, it is tried to find an integer
8389  * aggregation (i.e. integral coefficients a'' and b'', such that a''*x' + b''*y' == c''). This can lead to
8390  * the detection of infeasibility (e.g. if c'' is fractional), or to a rejection of the aggregation (denoted by
8391  * aggregated == FALSE), if the resulting integer coefficients are too large and thus numerically instable.
8392  *
8393  * The output flags have the following meaning:
8394  * - infeasible: the problem is infeasible
8395  * - redundant: the equality can be deleted from the constraint set
8396  * - aggregated: the aggregation was successfully performed (the variables were not aggregated before)
8397  *
8398  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8399  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8400  *
8401  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PRESOLVING
8402  */
8404  SCIP* scip, /**< SCIP data structure */
8405  SCIP_VAR* varx, /**< variable x in equality a*x + b*y == c */
8406  SCIP_VAR* vary, /**< variable y in equality a*x + b*y == c */
8407  SCIP_Real scalarx, /**< multiplier a in equality a*x + b*y == c */
8408  SCIP_Real scalary, /**< multiplier b in equality a*x + b*y == c */
8409  SCIP_Real rhs, /**< right hand side c in equality a*x + b*y == c */
8410  SCIP_Bool* infeasible, /**< pointer to store whether the aggregation is infeasible */
8411  SCIP_Bool* redundant, /**< pointer to store whether the equality is (now) redundant */
8412  SCIP_Bool* aggregated /**< pointer to store whether the aggregation was successful */
8413  )
8414 {
8415  SCIP_Real constantx;
8416  SCIP_Real constanty;
8417 
8418  assert(infeasible != NULL);
8419  assert(redundant != NULL);
8420  assert(aggregated != NULL);
8421 
8422  SCIP_CALL( SCIPcheckStage(scip, "SCIPaggregateVars", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
8423 
8424  *infeasible = FALSE;
8425  *redundant = FALSE;
8426  *aggregated = FALSE;
8427 
8428  if( SCIPtreeProbing(scip->tree) )
8429  {
8430  SCIPerrorMessage("cannot aggregate variables during probing\n");
8431  return SCIP_INVALIDCALL;
8432  }
8433  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
8434 
8435  /* do not perform aggregation if it is globally deactivated */
8436  if( scip->set->presol_donotaggr )
8437  return SCIP_OKAY;
8438 
8439  /* get the corresponding equality in active problem variable space:
8440  * transform both expressions "a*x + 0" and "b*y + 0" into problem variable space
8441  */
8442  constantx = 0.0;
8443  constanty = 0.0;
8444  SCIP_CALL( SCIPvarGetProbvarSum(&varx, scip->set, &scalarx, &constantx) );
8445  SCIP_CALL( SCIPvarGetProbvarSum(&vary, scip->set, &scalary, &constanty) );
8446 
8447  /* we cannot aggregate multi-aggregated variables */
8449  return SCIP_OKAY;
8450 
8451  /* move the constant to the right hand side to acquire the form "a'*x' + b'*y' == c'" */
8452  rhs -= (constantx + constanty);
8453 
8454  /* if a scalar is zero, treat the variable as fixed-to-zero variable */
8455  if( SCIPsetIsZero(scip->set, scalarx) )
8456  varx = NULL;
8457  if( SCIPsetIsZero(scip->set, scalary) )
8458  vary = NULL;
8459 
8460  /* capture the special cases that less than two variables are left, due to resolutions to a fixed variable or
8461  * to the same active variable
8462  */
8463  if( varx == NULL && vary == NULL )
8464  {
8465  /* both variables were resolved to fixed variables */
8466  *infeasible = !SCIPsetIsZero(scip->set, rhs);
8467  *redundant = TRUE;
8468  }
8469  else if( varx == NULL )
8470  {
8471  assert(SCIPsetIsZero(scip->set, scalarx));
8472  assert(!SCIPsetIsZero(scip->set, scalary));
8473 
8474  /* variable x was resolved to fixed variable: variable y can be fixed to c'/b' */
8475  SCIP_CALL( SCIPvarFix(vary, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8476  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8477  scip->cliquetable, rhs/scalary, infeasible, aggregated) );
8478  *redundant = TRUE;
8479  }
8480  else if( vary == NULL )
8481  {
8482  assert(SCIPsetIsZero(scip->set, scalary));
8483  assert(!SCIPsetIsZero(scip->set, scalarx));
8484 
8485  /* variable y was resolved to fixed variable: variable x can be fixed to c'/a' */
8486  SCIP_CALL( SCIPvarFix(varx, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8487  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8488  scip->cliquetable, rhs/scalarx, infeasible, aggregated) );
8489  *redundant = TRUE;
8490  }
8491  else if( varx == vary )
8492  {
8493  /* both variables were resolved to the same active problem variable: this variable can be fixed */
8494  scalarx += scalary;
8495  if( SCIPsetIsZero(scip->set, scalarx) )
8496  {
8497  /* left hand side of equality is zero: equality is potentially infeasible */
8498  *infeasible = !SCIPsetIsZero(scip->set, rhs);
8499  }
8500  else
8501  {
8502  /* sum of scalars is not zero: fix variable x' == y' to c'/(a'+b') */
8503  SCIP_CALL( SCIPvarFix(varx, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8504  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8505  scip->cliquetable, rhs/scalarx, infeasible, aggregated) );
8506  }
8507  *redundant = TRUE;
8508  }
8509  else
8510  {
8511  /* both variables are different active problem variables, and both scalars are non-zero: try to aggregate them */
8512  SCIP_CALL( SCIPvarTryAggregateVars(scip->set, scip->mem->probmem, scip->stat, scip->transprob, scip->origprob,
8513  scip->primal, scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventfilter,
8514  scip->eventqueue, varx, vary, scalarx, scalary, rhs, infeasible, aggregated) );
8515  *redundant = *aggregated;
8516  }
8517 
8518  return SCIP_OKAY;
8519 }
8520 
8521 /** converts variable into multi-aggregated variable; this changes the variable array returned from
8522  * SCIPgetVars() and SCIPgetVarsData();
8523  *
8524  * @warning The integrality condition is not checked anymore on the multi-aggregated variable. You must not
8525  * multi-aggregate an integer variable without being sure, that integrality on the aggregation variables
8526  * implies integrality on the aggregated variable.
8527  *
8528  * The output flags have the following meaning:
8529  * - infeasible: the problem is infeasible
8530  * - aggregated: the aggregation was successfully performed (the variables were not aggregated before)
8531  *
8532  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8533  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8534  *
8535  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PRESOLVING
8536  */
8538  SCIP* scip, /**< SCIP data structure */
8539  SCIP_VAR* var, /**< variable x to aggregate */
8540  int naggvars, /**< number n of variables in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8541  SCIP_VAR** aggvars, /**< variables y_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8542  SCIP_Real* scalars, /**< multipliers a_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8543  SCIP_Real constant, /**< constant shift c in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8544  SCIP_Bool* infeasible, /**< pointer to store whether the aggregation is infeasible */
8545  SCIP_Bool* aggregated /**< pointer to store whether the aggregation was successful */
8546  )
8547 {
8548  SCIP_CALL( SCIPcheckStage(scip, "SCIPmultiaggregateVar", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
8549 
8550  assert(var->scip == scip);
8551 
8552  if( SCIPtreeProbing(scip->tree) )
8553  {
8554  SCIPerrorMessage("cannot multi-aggregate variables during probing\n");
8555  return SCIP_INVALIDCALL;
8556  }
8557  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
8558 
8559  SCIP_CALL( SCIPvarMultiaggregate(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8560  scip->primal, scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventfilter,
8561  scip->eventqueue, naggvars, aggvars, scalars, constant, infeasible, aggregated) );
8562 
8563  return SCIP_OKAY;
8564 }
8565 
8566 /** returns whether aggregation of variables is not allowed */
8568  SCIP* scip /**< SCIP data structure */
8569  )
8570 {
8571  assert(scip != NULL);
8572 
8573  return scip->set->presol_donotaggr;
8574 }
8575 
8576 /** returns whether multi-aggregation is disabled */
8578  SCIP* scip /**< SCIP data structure */
8579  )
8580 {
8581  assert(scip != NULL);
8582 
8583  return scip->set->presol_donotmultaggr;
8584 }
8585 
8586 /** returns whether variable is not allowed to be aggregated */
8588  SCIP* scip, /**< SCIP data structure */
8589  SCIP_VAR* var /**< variable x to aggregate */
8590  )
8591 {
8592  assert(scip != NULL);
8593  assert(var != NULL);
8594  assert(var->scip == scip);
8595 
8596  return scip->set->presol_donotaggr || SCIPvarDoNotAggr(var);
8597 }
8598 
8599 /** returns whether variable is not allowed to be multi-aggregated */
8601  SCIP* scip, /**< SCIP data structure */
8602  SCIP_VAR* var /**< variable x to aggregate */
8603  )
8604 {
8605  assert(scip != NULL);
8606  assert(var != NULL);
8607  assert(var->scip == scip);
8608 
8609  return scip->set->presol_donotmultaggr || SCIPvarDoNotMultaggr(var);
8610 }
8611 
8612 /** returns whether dual reductions are allowed during propagation and presolving
8613  *
8614  * @deprecated Please use SCIPallowStrongDualReds()
8615  */
8617  SCIP* scip /**< SCIP data structure */
8618  )
8619 {
8620  assert(scip != NULL);
8621 
8622  return !scip->set->reopt_enable && scip->set->misc_allowstrongdualreds;
8623 }
8624 
8625 /** returns whether strong dual reductions are allowed during propagation and presolving
8626  *
8627  * @note A reduction is called strong dual, if it may discard feasible/optimal solutions, but leaves at least one
8628  * optimal solution intact. Often such reductions are based on analyzing the objective function and variable
8629  * locks.
8630  */
8632  SCIP* scip /**< SCIP data structure */
8633  )
8634 {
8635  assert(scip != NULL);
8636 
8637  return !scip->set->reopt_enable && scip->set->misc_allowstrongdualreds;
8638 }
8639 
8640 /** returns whether propagation w.r.t. current objective is allowed
8641  *
8642  * @deprecated Please use SCIPallowWeakDualReds()
8643  */
8645  SCIP* scip /**< SCIP data structure */
8646  )
8647 {
8648  assert(scip != NULL);
8649 
8650  return !scip->set->reopt_enable && scip->set->misc_allowweakdualreds;
8651 }
8652 
8653 /** returns whether weak dual reductions are allowed during propagation and presolving
8654  *
8655  * @note A reduction is called weak dual, if it may discard feasible solutions, but leaves at all optimal solutions
8656  * intact. Often such reductions are based on analyzing the objective function, reduced costs, and/or dual LPs.
8657  */
8659  SCIP* scip /**< SCIP data structure */
8660  )
8661 {
8662  assert(scip != NULL);
8663 
8664  return !scip->set->reopt_enable && scip->set->misc_allowweakdualreds;
8665 }
8666 
8667 /** marks the variable that it must not be aggregated
8668  *
8669  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8670  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8671  *
8672  * @pre This method can be called if @p scip is in one of the following stages:
8673  * - \ref SCIP_STAGE_INIT
8674  * - \ref SCIP_STAGE_PROBLEM
8675  * - \ref SCIP_STAGE_TRANSFORMING
8676  * - \ref SCIP_STAGE_TRANSFORMED
8677  * - \ref SCIP_STAGE_INITPRESOLVE
8678  * - \ref SCIP_STAGE_PRESOLVING
8679  * - \ref SCIP_STAGE_EXITPRESOLVE
8680  *
8681  * @note There exists no "unmark" method since it has to be ensured that if a plugin requires that a variable is not
8682  * aggregated that this is will be the case.
8683  */
8685  SCIP* scip, /**< SCIP data structure */
8686  SCIP_VAR* var /**< variable to delete */
8687  )
8688 {
8689  assert(scip != NULL);
8690  assert(var != NULL);
8691  assert(var->scip == scip);
8692 
8693  SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkDoNotAggrVar", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE) );
8694 
8696 
8697  return SCIP_OKAY;
8698 }
8699 
8700 /** marks the variable that it must not be multi-aggregated
8701  *
8702  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8703  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8704  *
8705  * @pre This method can be called if @p scip is in one of the following stages:
8706  * - \ref SCIP_STAGE_INIT
8707  * - \ref SCIP_STAGE_PROBLEM
8708  * - \ref SCIP_STAGE_TRANSFORMING
8709  * - \ref SCIP_STAGE_TRANSFORMED
8710  * - \ref SCIP_STAGE_INITPRESOLVE
8711  * - \ref SCIP_STAGE_PRESOLVING
8712  * - \ref SCIP_STAGE_EXITPRESOLVE
8713  *
8714  * @note There exists no "unmark" method since it has to be ensured that if a plugin requires that a variable is not
8715  * multi-aggregated that this is will be the case.
8716  */
8718  SCIP* scip, /**< SCIP data structure */
8719  SCIP_VAR* var /**< variable to delete */
8720  )
8721 {
8722  assert(scip != NULL);
8723  assert(var != NULL);
8724  assert(var->scip == scip);
8725 
8726  SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkDoNotMultaggrVar", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE) );
8727 
8729 
8730  return SCIP_OKAY;
8731 }
8732 
8733 /** enables the collection of statistics for a variable
8734  *
8735  * @pre This method can be called if @p scip is in one of the following stages:
8736  * - \ref SCIP_STAGE_PROBLEM
8737  * - \ref SCIP_STAGE_INITPRESOLVE
8738  * - \ref SCIP_STAGE_PRESOLVING
8739  * - \ref SCIP_STAGE_EXITPRESOLVE
8740  * - \ref SCIP_STAGE_SOLVING
8741  * - \ref SCIP_STAGE_SOLVED
8742  */
8744  SCIP* scip /**< SCIP data structure */
8745  )
8746 {
8747  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPenableVarHistory", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8748 
8750 }
8751 
8752 /** disables the collection of any statistic for a variable
8753  *
8754  * @pre This method can be called if @p scip is in one of the following stages:
8755  * - \ref SCIP_STAGE_PROBLEM
8756  * - \ref SCIP_STAGE_INITPRESOLVE
8757  * - \ref SCIP_STAGE_PRESOLVING
8758  * - \ref SCIP_STAGE_EXITPRESOLVE
8759  * - \ref SCIP_STAGE_SOLVING
8760  * - \ref SCIP_STAGE_SOLVED
8761  */
8763  SCIP* scip /**< SCIP data structure */
8764  )
8765 {
8766  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPdisableVarHistory", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8767 
8769 }
8770 
8771 /** updates the pseudo costs of the given variable and the global pseudo costs after a change of "solvaldelta" in the
8772  * variable's solution value and resulting change of "objdelta" in the in the LP's objective value;
8773  * the update is ignored, if the objective value difference is infinite
8774  *
8775  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8776  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8777  *
8778  * @pre This method can be called if @p scip is in one of the following stages:
8779  * - \ref SCIP_STAGE_SOLVING
8780  * - \ref SCIP_STAGE_SOLVED
8781  */
8783  SCIP* scip, /**< SCIP data structure */
8784  SCIP_VAR* var, /**< problem variable */
8785  SCIP_Real solvaldelta, /**< difference of variable's new LP value - old LP value */
8786  SCIP_Real objdelta, /**< difference of new LP's objective value - old LP's objective value */
8787  SCIP_Real weight /**< weight in (0,1] of this update in pseudo cost sum */
8788  )
8789 {
8790  SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateVarPseudocost", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8791 
8792  if( !SCIPsetIsInfinity(scip->set, 2*objdelta) ) /* differences infinity - eps should also be treated as infinity */
8793  {
8794  if( scip->set->branch_divingpscost || (!scip->lp->diving && !SCIPtreeProbing(scip->tree)) )
8795  {
8796  SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, solvaldelta, objdelta, weight) );
8797  }
8798  }
8799 
8800  return SCIP_OKAY;
8801 }
8802 
8803 /** gets the variable's pseudo cost value for the given change of the variable's LP value
8804  *
8805  * @return the variable's pseudo cost value for the given change of the variable's LP value
8806  *
8807  * @pre This method can be called if @p scip is in one of the following stages:
8808  * - \ref SCIP_STAGE_INITPRESOLVE
8809  * - \ref SCIP_STAGE_PRESOLVING
8810  * - \ref SCIP_STAGE_EXITPRESOLVE
8811  * - \ref SCIP_STAGE_PRESOLVED
8812  * - \ref SCIP_STAGE_INITSOLVE
8813  * - \ref SCIP_STAGE_SOLVING
8814  * - \ref SCIP_STAGE_SOLVED
8815  */
8817  SCIP* scip, /**< SCIP data structure */
8818  SCIP_VAR* var, /**< problem variable */
8819  SCIP_Real solvaldelta /**< difference of variable's new LP value - old LP value */
8820  )
8821 {
8822  assert( var->scip == scip );
8823 
8824  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostVal", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8825 
8826  return SCIPvarGetPseudocost(var, scip->stat, solvaldelta);
8827 }
8828 
8829 /** gets the variable's pseudo cost value for the given change of the variable's LP value,
8830  * only using the pseudo cost information of the current run
8831  *
8832  * @return the variable's pseudo cost value for the given change of the variable's LP value,
8833  * only using the pseudo cost information of the current run
8834  *
8835  * @pre This method can be called if @p scip is in one of the following stages:
8836  * - \ref SCIP_STAGE_INITPRESOLVE
8837  * - \ref SCIP_STAGE_PRESOLVING
8838  * - \ref SCIP_STAGE_EXITPRESOLVE
8839  * - \ref SCIP_STAGE_PRESOLVED
8840  * - \ref SCIP_STAGE_INITSOLVE
8841  * - \ref SCIP_STAGE_SOLVING
8842  * - \ref SCIP_STAGE_SOLVED
8843  */
8845  SCIP* scip, /**< SCIP data structure */
8846  SCIP_VAR* var, /**< problem variable */
8847  SCIP_Real solvaldelta /**< difference of variable's new LP value - old LP value */
8848  )
8849 {
8850  assert( var->scip == scip );
8851 
8852  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostValCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8853 
8854  return SCIPvarGetPseudocostCurrentRun(var, scip->stat, solvaldelta);
8855 }
8856 
8857 /** gets the variable's pseudo cost value for the given direction
8858  *
8859  * @return the variable's pseudo cost value for the given direction
8860  *
8861  * @pre This method can be called if @p scip is in one of the following stages:
8862  * - \ref SCIP_STAGE_INITPRESOLVE
8863  * - \ref SCIP_STAGE_PRESOLVING
8864  * - \ref SCIP_STAGE_EXITPRESOLVE
8865  * - \ref SCIP_STAGE_PRESOLVED
8866  * - \ref SCIP_STAGE_INITSOLVE
8867  * - \ref SCIP_STAGE_SOLVING
8868  * - \ref SCIP_STAGE_SOLVED
8869  */
8871  SCIP* scip, /**< SCIP data structure */
8872  SCIP_VAR* var, /**< problem variable */
8873  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8874  )
8875 {
8876  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocost", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8877  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8878  assert(var->scip == scip);
8879 
8880  return SCIPvarGetPseudocost(var, scip->stat, dir == SCIP_BRANCHDIR_DOWNWARDS ? -1.0 : 1.0);
8881 }
8882 
8883 /** gets the variable's pseudo cost value for the given direction,
8884  * only using the pseudo cost information of the current run
8885  *
8886  * @return the variable's pseudo cost value for the given direction,
8887  * only using the pseudo cost information of the current run
8888  *
8889  * @pre This method can be called if @p scip is in one of the following stages:
8890  * - \ref SCIP_STAGE_INITPRESOLVE
8891  * - \ref SCIP_STAGE_PRESOLVING
8892  * - \ref SCIP_STAGE_EXITPRESOLVE
8893  * - \ref SCIP_STAGE_PRESOLVED
8894  * - \ref SCIP_STAGE_INITSOLVE
8895  * - \ref SCIP_STAGE_SOLVING
8896  * - \ref SCIP_STAGE_SOLVED
8897  */
8899  SCIP* scip, /**< SCIP data structure */
8900  SCIP_VAR* var, /**< problem variable */
8901  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8902  )
8903 {
8904  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8905  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8906  assert(var->scip == scip);
8907 
8908  return SCIPvarGetPseudocostCurrentRun(var, scip->stat, dir == SCIP_BRANCHDIR_DOWNWARDS ? -1.0 : 1.0);
8909 }
8910 
8911 /** gets the variable's (possible fractional) number of pseudo cost updates for the given direction
8912  *
8913  * @return the variable's (possible fractional) number of pseudo cost updates for the given direction
8914  *
8915  * @pre This method can be called if @p scip is in one of the following stages:
8916  * - \ref SCIP_STAGE_INITPRESOLVE
8917  * - \ref SCIP_STAGE_PRESOLVING
8918  * - \ref SCIP_STAGE_EXITPRESOLVE
8919  * - \ref SCIP_STAGE_PRESOLVED
8920  * - \ref SCIP_STAGE_INITSOLVE
8921  * - \ref SCIP_STAGE_SOLVING
8922  * - \ref SCIP_STAGE_SOLVED
8923  */
8925  SCIP* scip, /**< SCIP data structure */
8926  SCIP_VAR* var, /**< problem variable */
8927  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8928  )
8929 {
8930  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCount", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8931  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8932  assert(var->scip == scip);
8933 
8934  return SCIPvarGetPseudocostCount(var, dir);
8935 }
8936 
8937 /** gets the variable's (possible fractional) number of pseudo cost updates for the given direction,
8938  * only using the pseudo cost information of the current run
8939  *
8940  * @return the variable's (possible fractional) number of pseudo cost updates for the given direction,
8941  * only using the pseudo cost information of the current run
8942  *
8943  * @pre This method can be called if @p scip is in one of the following stages:
8944  * - \ref SCIP_STAGE_INITPRESOLVE
8945  * - \ref SCIP_STAGE_PRESOLVING
8946  * - \ref SCIP_STAGE_EXITPRESOLVE
8947  * - \ref SCIP_STAGE_PRESOLVED
8948  * - \ref SCIP_STAGE_INITSOLVE
8949  * - \ref SCIP_STAGE_SOLVING
8950  * - \ref SCIP_STAGE_SOLVED
8951  */
8953  SCIP* scip, /**< SCIP data structure */
8954  SCIP_VAR* var, /**< problem variable */
8955  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8956  )
8957 {
8958  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCountCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8959  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8960  assert(var->scip == scip);
8961 
8962  return SCIPvarGetPseudocostCountCurrentRun(var, dir);
8963 }
8964 
8965 /** get pseudo cost variance of the variable, either for entire solve or only for current branch and bound run
8966  *
8967  * @return returns the (corrected) variance of pseudo code information collected so far.
8968  *
8969  * @pre This method can be called if @p scip is in one of the following stages:
8970  * - \ref SCIP_STAGE_INITPRESOLVE
8971  * - \ref SCIP_STAGE_PRESOLVING
8972  * - \ref SCIP_STAGE_EXITPRESOLVE
8973  * - \ref SCIP_STAGE_PRESOLVED
8974  * - \ref SCIP_STAGE_INITSOLVE
8975  * - \ref SCIP_STAGE_SOLVING
8976  * - \ref SCIP_STAGE_SOLVED
8977  */
8979  SCIP* scip, /**< SCIP data structure */
8980  SCIP_VAR* var, /**< problem variable */
8981  SCIP_BRANCHDIR dir, /**< branching direction (downwards, or upwards) */
8982  SCIP_Bool onlycurrentrun /**< only for pseudo costs of current branch and bound run */
8983  )
8984 {
8985  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostVariance", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8986  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8987  assert(var->scip == scip);
8988 
8989  return SCIPvarGetPseudocostVariance(var, dir, onlycurrentrun);
8990 }
8991 
8992 /** calculates a confidence bound for this variable under the assumption of normally distributed pseudo costs
8993  *
8994  * The confidence bound \f$ \theta \geq 0\f$ denotes the interval borders \f$ [X - \theta, \ X + \theta]\f$, which contains
8995  * the true pseudo costs of the variable, i.e., the expected value of the normal distribution, with a probability
8996  * of 2 * clevel - 1.
8997  *
8998  * @return value of confidence bound for this variable
8999  */
9001  SCIP* scip, /**< SCIP data structure */
9002  SCIP_VAR* var, /**< variable in question */
9003  SCIP_BRANCHDIR dir, /**< the branching direction for the confidence bound */
9004  SCIP_Bool onlycurrentrun, /**< should only the current run be taken into account */
9005  SCIP_CONFIDENCELEVEL clevel /**< confidence level for the interval */
9006  )
9007 {
9008  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPcalculatePscostConfidenceBound", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9009 
9010  return SCIPvarCalcPscostConfidenceBound(var, scip->set, dir, onlycurrentrun, clevel);
9011 }
9012 
9013 /** check if variable pseudo-costs have a significant difference in location. The significance depends on
9014  * the choice of \p clevel and on the kind of tested hypothesis. The one-sided hypothesis, which
9015  * should be rejected, is that fracy * mu_y >= fracx * mu_x, where mu_y and mu_x denote the
9016  * unknown location means of the underlying pseudo-cost distributions of x and y.
9017  *
9018  * This method is applied best if variable x has a better pseudo-cost score than y. The method hypothesizes that y were actually
9019  * better than x (despite the current information), meaning that y can be expected to yield branching
9020  * decisions as least as good as x in the long run. If the method returns TRUE, the current history information is
9021  * sufficient to safely rely on the alternative hypothesis that x yields indeed a better branching score (on average)
9022  * than y.
9023  *
9024  * @note The order of x and y matters for the one-sided hypothesis
9025  *
9026  * @note set \p onesided to FALSE if you are not sure which variable is better. The hypothesis tested then reads
9027  * fracy * mu_y == fracx * mu_x vs the alternative hypothesis fracy * mu_y != fracx * mu_x.
9028  *
9029  * @return TRUE if the hypothesis can be safely rejected at the given confidence level
9030  */
9032  SCIP* scip, /**< SCIP data structure */
9033  SCIP_VAR* varx, /**< variable x */
9034  SCIP_Real fracx, /**< the fractionality of variable x */
9035  SCIP_VAR* vary, /**< variable y */
9036  SCIP_Real fracy, /**< the fractionality of variable y */
9037  SCIP_BRANCHDIR dir, /**< branching direction */
9038  SCIP_CONFIDENCELEVEL clevel, /**< confidence level for rejecting hypothesis */
9039  SCIP_Bool onesided /**< should a one-sided hypothesis y >= x be tested? */
9040  )
9041 {
9042  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPsignificantVarPscostDifference", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9043 
9044  return SCIPvarSignificantPscostDifference(scip->set, scip->stat, varx, fracx, vary, fracy, dir, clevel, onesided);
9045 }
9046 
9047 /** tests at a given confidence level whether the variable pseudo-costs only have a small probability to
9048  * exceed a \p threshold. This is useful to determine if past observations provide enough evidence
9049  * to skip an expensive strong-branching step if there is already a candidate that has been proven to yield an improvement
9050  * of at least \p threshold.
9051  *
9052  * @note use \p clevel to adjust the level of confidence. For SCIP_CONFIDENCELEVEL_MIN, the method returns TRUE if
9053  * the estimated probability to exceed \p threshold is less than 25 %.
9054  *
9055  * @see SCIP_Confidencelevel for a list of available levels. The used probability limits refer to the one-sided levels
9056  * of confidence.
9057  *
9058  * @return TRUE if the variable pseudo-cost probabilistic model is likely to be smaller than \p threshold
9059  * at the given confidence level \p clevel.
9060  */
9062  SCIP* scip, /**< SCIP data structure */
9063  SCIP_VAR* var, /**< variable x */
9064  SCIP_Real frac, /**< the fractionality of variable x */
9065  SCIP_Real threshold, /**< the threshold to test against */
9066  SCIP_BRANCHDIR dir, /**< branching direction */
9067  SCIP_CONFIDENCELEVEL clevel /**< confidence level for rejecting hypothesis */
9068  )
9069 {
9070  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPpscostThresholdProbabilityTest", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9071 
9072  return SCIPvarPscostThresholdProbabilityTest(scip->set, scip->stat, var, frac, threshold, dir, clevel);
9073 }
9074 
9075 /** check if the current pseudo cost relative error in a direction violates the given threshold. The Relative
9076  * Error is calculated at a specific confidence level
9077  *
9078  * @return TRUE if relative error in variable pseudo costs is smaller than \p threshold
9079  */
9081  SCIP* scip, /**< SCIP data structure */
9082  SCIP_VAR* var, /**< variable in question */
9083  SCIP_Real threshold, /**< threshold for relative errors to be considered reliable (enough) */
9084  SCIP_CONFIDENCELEVEL clevel /**< a given confidence level */
9085  )
9086 {
9087  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisVarPscostRelerrorReliable", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9088 
9089  return SCIPvarIsPscostRelerrorReliable(var, scip->set, scip->stat, threshold, clevel);
9090 }
9091 
9092 /** gets the variable's pseudo cost score value for the given LP solution value
9093  *
9094  * @return the variable's pseudo cost score value for the given LP solution value
9095  *
9096  * @pre This method can be called if @p scip is in one of the following stages:
9097  * - \ref SCIP_STAGE_INITPRESOLVE
9098  * - \ref SCIP_STAGE_PRESOLVING
9099  * - \ref SCIP_STAGE_EXITPRESOLVE
9100  * - \ref SCIP_STAGE_PRESOLVED
9101  * - \ref SCIP_STAGE_INITSOLVE
9102  * - \ref SCIP_STAGE_SOLVING
9103  * - \ref SCIP_STAGE_SOLVED
9104  */
9106  SCIP* scip, /**< SCIP data structure */
9107  SCIP_VAR* var, /**< problem variable */
9108  SCIP_Real solval /**< variable's LP solution value */
9109  )
9110 {
9111  SCIP_Real downsol;
9112  SCIP_Real upsol;
9113  SCIP_Real pscostdown;
9114  SCIP_Real pscostup;
9115 
9116  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9117 
9118  assert( var->scip == scip );
9119 
9120  downsol = SCIPsetFeasCeil(scip->set, solval-1.0);
9121  upsol = SCIPsetFeasFloor(scip->set, solval+1.0);
9122  pscostdown = SCIPvarGetPseudocost(var, scip->stat, downsol-solval);
9123  pscostup = SCIPvarGetPseudocost(var, scip->stat, upsol-solval);
9124 
9125  return SCIPbranchGetScore(scip->set, var, pscostdown, pscostup);
9126 }
9127 
9128 /** gets the variable's pseudo cost score value for the given LP solution value,
9129  * only using the pseudo cost information of the current run
9130  *
9131  * @return the variable's pseudo cost score value for the given LP solution value,
9132  * only using the pseudo cost information of the current run
9133  *
9134  * @pre This method can be called if @p scip is in one of the following stages:
9135  * - \ref SCIP_STAGE_INITPRESOLVE
9136  * - \ref SCIP_STAGE_PRESOLVING
9137  * - \ref SCIP_STAGE_EXITPRESOLVE
9138  * - \ref SCIP_STAGE_PRESOLVED
9139  * - \ref SCIP_STAGE_INITSOLVE
9140  * - \ref SCIP_STAGE_SOLVING
9141  * - \ref SCIP_STAGE_SOLVED
9142  */
9144  SCIP* scip, /**< SCIP data structure */
9145  SCIP_VAR* var, /**< problem variable */
9146  SCIP_Real solval /**< variable's LP solution value */
9147  )
9148 {
9149  SCIP_Real downsol;
9150  SCIP_Real upsol;
9151  SCIP_Real pscostdown;
9152  SCIP_Real pscostup;
9153 
9154  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9155 
9156  assert( var->scip == scip );
9157 
9158  downsol = SCIPsetFeasCeil(scip->set, solval-1.0);
9159  upsol = SCIPsetFeasFloor(scip->set, solval+1.0);
9160  pscostdown = SCIPvarGetPseudocostCurrentRun(var, scip->stat, downsol-solval);
9161  pscostup = SCIPvarGetPseudocostCurrentRun(var, scip->stat, upsol-solval);
9162 
9163  return SCIPbranchGetScore(scip->set, var, pscostdown, pscostup);
9164 }
9165 
9166 /** returns the variable's VSIDS value
9167  *
9168  * @return the variable's VSIDS value
9169  *
9170  * @pre This method can be called if @p scip is in one of the following stages:
9171  * - \ref SCIP_STAGE_INITPRESOLVE
9172  * - \ref SCIP_STAGE_PRESOLVING
9173  * - \ref SCIP_STAGE_EXITPRESOLVE
9174  * - \ref SCIP_STAGE_PRESOLVED
9175  * - \ref SCIP_STAGE_INITSOLVE
9176  * - \ref SCIP_STAGE_SOLVING
9177  * - \ref SCIP_STAGE_SOLVED
9178  */
9180  SCIP* scip, /**< SCIP data structure */
9181  SCIP_VAR* var, /**< problem variable */
9182  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9183  )
9184 {
9185  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarVSIDS", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9186 
9187  assert( var->scip == scip );
9188 
9189  if( dir != SCIP_BRANCHDIR_DOWNWARDS && dir != SCIP_BRANCHDIR_UPWARDS )
9190  {
9191  SCIPerrorMessage("invalid branching direction %d when asking for VSIDS value\n", dir);
9192  return SCIP_INVALID;
9193  }
9194 
9195  return SCIPvarGetVSIDS(var, scip->stat, dir);
9196 }
9197 
9198 /** returns the variable's VSIDS value only using conflicts of the current run
9199  *
9200  * @return the variable's VSIDS value only using conflicts of the current run
9201  *
9202  * @pre This method can be called if @p scip is in one of the following stages:
9203  * - \ref SCIP_STAGE_INITPRESOLVE
9204  * - \ref SCIP_STAGE_PRESOLVING
9205  * - \ref SCIP_STAGE_EXITPRESOLVE
9206  * - \ref SCIP_STAGE_PRESOLVED
9207  * - \ref SCIP_STAGE_INITSOLVE
9208  * - \ref SCIP_STAGE_SOLVING
9209  * - \ref SCIP_STAGE_SOLVED
9210  */
9212  SCIP* scip, /**< SCIP data structure */
9213  SCIP_VAR* var, /**< problem variable */
9214  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9215  )
9216 {
9217  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarVSIDSCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9218 
9219  assert( var->scip == scip );
9220 
9221  if( dir != SCIP_BRANCHDIR_DOWNWARDS && dir != SCIP_BRANCHDIR_UPWARDS )
9222  {
9223  SCIPerrorMessage("invalid branching direction %d when asking for VSIDS value\n", dir);
9224  return SCIP_INVALID;
9225  }
9226 
9227  return SCIPvarGetVSIDSCurrentRun(var, scip->stat, dir);
9228 }
9229 
9230 /** returns the variable's conflict score value
9231  *
9232  * @return the variable's conflict score value
9233  *
9234  * @pre This method can be called if @p scip is in one of the following stages:
9235  * - \ref SCIP_STAGE_INITPRESOLVE
9236  * - \ref SCIP_STAGE_PRESOLVING
9237  * - \ref SCIP_STAGE_EXITPRESOLVE
9238  * - \ref SCIP_STAGE_PRESOLVED
9239  * - \ref SCIP_STAGE_INITSOLVE
9240  * - \ref SCIP_STAGE_SOLVING
9241  * - \ref SCIP_STAGE_SOLVED
9242  */
9244  SCIP* scip, /**< SCIP data structure */
9245  SCIP_VAR* var /**< problem variable */
9246  )
9247 {
9248  SCIP_Real downscore;
9249  SCIP_Real upscore;
9250 
9251  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9252 
9253  assert( var->scip == scip );
9254 
9255  downscore = SCIPvarGetVSIDS(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9256  upscore = SCIPvarGetVSIDS(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9257 
9258  return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9259 }
9260 
9261 /** returns the variable's conflict score value only using conflicts of the current run
9262  *
9263  * @return the variable's conflict score value only using conflicts of the current run
9264  *
9265  * @pre This method can be called if @p scip is in one of the following stages:
9266  * - \ref SCIP_STAGE_INITPRESOLVE
9267  * - \ref SCIP_STAGE_PRESOLVING
9268  * - \ref SCIP_STAGE_EXITPRESOLVE
9269  * - \ref SCIP_STAGE_PRESOLVED
9270  * - \ref SCIP_STAGE_INITSOLVE
9271  * - \ref SCIP_STAGE_SOLVING
9272  * - \ref SCIP_STAGE_SOLVED
9273  */
9275  SCIP* scip, /**< SCIP data structure */
9276  SCIP_VAR* var /**< problem variable */
9277  )
9278 {
9279  SCIP_Real downscore;
9280  SCIP_Real upscore;
9281 
9282  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9283 
9284  assert( var->scip == scip );
9285 
9286  downscore = SCIPvarGetVSIDSCurrentRun(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9287  upscore = SCIPvarGetVSIDSCurrentRun(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9288 
9289  return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9290 }
9291 
9292 /** returns the variable's conflict length score
9293  *
9294  * @return the variable's conflict length score
9295  *
9296  * @pre This method can be called if @p scip is in one of the following stages:
9297  * - \ref SCIP_STAGE_INITPRESOLVE
9298  * - \ref SCIP_STAGE_PRESOLVING
9299  * - \ref SCIP_STAGE_EXITPRESOLVE
9300  * - \ref SCIP_STAGE_PRESOLVED
9301  * - \ref SCIP_STAGE_INITSOLVE
9302  * - \ref SCIP_STAGE_SOLVING
9303  * - \ref SCIP_STAGE_SOLVED
9304  */
9306  SCIP* scip, /**< SCIP data structure */
9307  SCIP_VAR* var /**< problem variable */
9308  )
9309 {
9310  SCIP_Real downscore;
9311  SCIP_Real upscore;
9312 
9313  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictlengthScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9314 
9315  assert( var->scip == scip );
9316 
9319 
9320  return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9321 }
9322 
9323 /** returns the variable's conflict length score only using conflicts of the current run
9324  *
9325  * @return the variable's conflict length score only using conflicts of the current run
9326  *
9327  * @pre This method can be called if @p scip is in one of the following stages:
9328  * - \ref SCIP_STAGE_INITPRESOLVE
9329  * - \ref SCIP_STAGE_PRESOLVING
9330  * - \ref SCIP_STAGE_EXITPRESOLVE
9331  * - \ref SCIP_STAGE_PRESOLVED
9332  * - \ref SCIP_STAGE_INITSOLVE
9333  * - \ref SCIP_STAGE_SOLVING
9334  * - \ref SCIP_STAGE_SOLVED
9335  */
9337  SCIP* scip, /**< SCIP data structure */
9338  SCIP_VAR* var /**< problem variable */
9339  )
9340 {
9341  SCIP_Real downscore;
9342  SCIP_Real upscore;
9343 
9344  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictlengthScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9345 
9346  assert( var->scip == scip );
9347 
9350 
9351  return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9352 }
9353 
9354 /** returns the variable's average conflict length
9355  *
9356  * @return the variable's average conflict length
9357  *
9358  * @pre This method can be called if @p scip is in one of the following stages:
9359  * - \ref SCIP_STAGE_INITPRESOLVE
9360  * - \ref SCIP_STAGE_PRESOLVING
9361  * - \ref SCIP_STAGE_EXITPRESOLVE
9362  * - \ref SCIP_STAGE_PRESOLVED
9363  * - \ref SCIP_STAGE_INITSOLVE
9364  * - \ref SCIP_STAGE_SOLVING
9365  * - \ref SCIP_STAGE_SOLVED
9366  */
9368  SCIP* scip, /**< SCIP data structure */
9369  SCIP_VAR* var, /**< problem variable */
9370  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9371  )
9372 {
9373  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgConflictlength", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9374 
9375  assert( var->scip == scip );
9376 
9377  return SCIPvarGetAvgConflictlength(var, dir);
9378 }
9379 
9380 /** returns the variable's average conflict length only using conflicts of the current run
9381  *
9382  * @return the variable's average conflict length only using conflicts of the current run
9383  *
9384  * @pre This method can be called if @p scip is in one of the following stages:
9385  * - \ref SCIP_STAGE_INITPRESOLVE
9386  * - \ref SCIP_STAGE_PRESOLVING
9387  * - \ref SCIP_STAGE_EXITPRESOLVE
9388  * - \ref SCIP_STAGE_PRESOLVED
9389  * - \ref SCIP_STAGE_INITSOLVE
9390  * - \ref SCIP_STAGE_SOLVING
9391  * - \ref SCIP_STAGE_SOLVED
9392  */
9394  SCIP* scip, /**< SCIP data structure */
9395  SCIP_VAR* var, /**< problem variable */
9396  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9397  )
9398 {
9399  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgConflictlengthCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9400 
9401  assert( var->scip == scip );
9402 
9403  return SCIPvarGetAvgConflictlengthCurrentRun(var, dir);
9404 }
9405 
9406 /** returns the average number of inferences found after branching on the variable in given direction;
9407  * if branching on the variable in the given direction was yet evaluated, the average number of inferences
9408  * over all variables for branching in the given direction is returned
9409  *
9410  * @return the average number of inferences found after branching on the variable in given direction
9411  *
9412  * @pre This method can be called if @p scip is in one of the following stages:
9413  * - \ref SCIP_STAGE_INITPRESOLVE
9414  * - \ref SCIP_STAGE_PRESOLVING
9415  * - \ref SCIP_STAGE_EXITPRESOLVE
9416  * - \ref SCIP_STAGE_PRESOLVED
9417  * - \ref SCIP_STAGE_INITSOLVE
9418  * - \ref SCIP_STAGE_SOLVING
9419  * - \ref SCIP_STAGE_SOLVED
9420  */
9422  SCIP* scip, /**< SCIP data structure */
9423  SCIP_VAR* var, /**< problem variable */
9424  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9425  )
9426 {
9427  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferences", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9428 
9429  assert( var->scip == scip );
9430 
9431  return SCIPvarGetAvgInferences(var, scip->stat, dir);
9432 }
9433 
9434 /** returns the average number of inferences found after branching on the variable in given direction in the current run;
9435  * if branching on the variable in the given direction was yet evaluated, the average number of inferences
9436  * over all variables for branching in the given direction is returned
9437  *
9438  * @return the average number of inferences found after branching on the variable in given direction in the current run
9439  *
9440  * @pre This method can be called if @p scip is in one of the following stages:
9441  * - \ref SCIP_STAGE_INITPRESOLVE
9442  * - \ref SCIP_STAGE_PRESOLVING
9443  * - \ref SCIP_STAGE_EXITPRESOLVE
9444  * - \ref SCIP_STAGE_PRESOLVED
9445  * - \ref SCIP_STAGE_INITSOLVE
9446  * - \ref SCIP_STAGE_SOLVING
9447  * - \ref SCIP_STAGE_SOLVED
9448  */
9450  SCIP* scip, /**< SCIP data structure */
9451  SCIP_VAR* var, /**< problem variable */
9452  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9453  )
9454 {
9455  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferencesCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9456 
9457  assert( var->scip == scip );
9458 
9459  return SCIPvarGetAvgInferencesCurrentRun(var, scip->stat, dir);
9460 }
9461 
9462 /** returns the variable's average inference score value
9463  *
9464  * @return the variable's average inference score value
9465  *
9466  * @pre This method can be called if @p scip is in one of the following stages:
9467  * - \ref SCIP_STAGE_INITPRESOLVE
9468  * - \ref SCIP_STAGE_PRESOLVING
9469  * - \ref SCIP_STAGE_EXITPRESOLVE
9470  * - \ref SCIP_STAGE_PRESOLVED
9471  * - \ref SCIP_STAGE_INITSOLVE
9472  * - \ref SCIP_STAGE_SOLVING
9473  * - \ref SCIP_STAGE_SOLVED
9474  */
9476  SCIP* scip, /**< SCIP data structure */
9477  SCIP_VAR* var /**< problem variable */
9478  )
9479 {
9480  SCIP_Real inferdown;
9481  SCIP_Real inferup;
9482 
9483  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9484 
9485  assert( var->scip == scip );
9486 
9487  inferdown = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9488  inferup = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9489 
9490  return SCIPbranchGetScore(scip->set, var, inferdown, inferup);
9491 }
9492 
9493 /** returns the variable's average inference score value only using inferences of the current run
9494  *
9495  * @return the variable's average inference score value only using inferences of the current run
9496  *
9497  * @pre This method can be called if @p scip is in one of the following stages:
9498  * - \ref SCIP_STAGE_INITPRESOLVE
9499  * - \ref SCIP_STAGE_PRESOLVING
9500  * - \ref SCIP_STAGE_EXITPRESOLVE
9501  * - \ref SCIP_STAGE_PRESOLVED
9502  * - \ref SCIP_STAGE_INITSOLVE
9503  * - \ref SCIP_STAGE_SOLVING
9504  * - \ref SCIP_STAGE_SOLVED
9505  */
9507  SCIP* scip, /**< SCIP data structure */
9508  SCIP_VAR* var /**< problem variable */
9509  )
9510 {
9511  SCIP_Real inferdown;
9512  SCIP_Real inferup;
9513 
9514  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9515 
9516  assert( var->scip == scip );
9517 
9520 
9521  return SCIPbranchGetScore(scip->set, var, inferdown, inferup);
9522 }
9523 
9524 /** initializes the upwards and downwards pseudocosts, conflict scores, conflict lengths, inference scores, cutoff scores
9525  * of a variable to the given values
9526  *
9527  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9528  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9529  *
9530  * @pre This method can be called if @p scip is in one of the following stages:
9531  * - \ref SCIP_STAGE_TRANSFORMED
9532  * - \ref SCIP_STAGE_INITPRESOLVE
9533  * - \ref SCIP_STAGE_PRESOLVING
9534  * - \ref SCIP_STAGE_EXITPRESOLVE
9535  * - \ref SCIP_STAGE_PRESOLVED
9536  * - \ref SCIP_STAGE_INITSOLVE
9537  * - \ref SCIP_STAGE_SOLVING
9538  */
9540  SCIP* scip, /**< SCIP data structure */
9541  SCIP_VAR* var, /**< variable which should be initialized */
9542  SCIP_Real downpscost, /**< value to which pseudocosts for downwards branching should be initialized */
9543  SCIP_Real uppscost, /**< value to which pseudocosts for upwards branching should be initialized */
9544  SCIP_Real downvsids, /**< value to which VSIDS score for downwards branching should be initialized */
9545  SCIP_Real upvsids, /**< value to which VSIDS score for upwards branching should be initialized */
9546  SCIP_Real downconflen, /**< value to which conflict length score for downwards branching should be initialized */
9547  SCIP_Real upconflen, /**< value to which conflict length score for upwards branching should be initialized */
9548  SCIP_Real downinfer, /**< value to which inference counter for downwards branching should be initialized */
9549  SCIP_Real upinfer, /**< value to which inference counter for upwards branching should be initialized */
9550  SCIP_Real downcutoff, /**< value to which cutoff counter for downwards branching should be initialized */
9551  SCIP_Real upcutoff /**< value to which cutoff counter for upwards branching should be initialized */
9552  )
9553 {
9554  SCIP_CALL( SCIPcheckStage(scip, "SCIPinitVarBranchStats", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
9555 
9556  assert(downpscost >= 0.0 && uppscost >= 0.0);
9557  assert(downvsids >= 0.0 && upvsids >= 0.0);
9558  assert(downconflen >= 0.0 && upconflen >= 0.0);
9559  assert(downinfer >= 0.0 && upinfer >= 0.0);
9560  assert(downcutoff >= 0.0 && upcutoff >= 0.0);
9561 
9562  if( !SCIPisFeasZero(scip, downpscost) || !SCIPisFeasZero(scip, downvsids)
9563  || !SCIPisFeasZero(scip, downinfer) || !SCIPisFeasZero(scip, downcutoff) )
9564  {
9566  SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, -1.0, downpscost, 1.0) );
9568  SCIP_CALL( SCIPvarIncVSIDS(var, NULL, scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, SCIP_UNKNOWN, downvsids) );
9570  }
9571 
9572  if( !SCIPisFeasZero(scip, downconflen) )
9573  {
9575  }
9576 
9577  if( !SCIPisFeasZero(scip, uppscost) || !SCIPisFeasZero(scip, upvsids)
9578  || !SCIPisFeasZero(scip, upinfer) || !SCIPisFeasZero(scip, upcutoff) )
9579  {
9581  SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, 1.0, uppscost, 1.0) );
9583  SCIP_CALL( SCIPvarIncVSIDS(var, NULL, scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, SCIP_UNKNOWN, upvsids) );
9585  }
9586 
9587  if( !SCIPisFeasZero(scip, upconflen) )
9588  {
9590  }
9591 
9592  return SCIP_OKAY;
9593 }
9594 
9595 /** initializes the upwards and downwards conflict scores, conflict lengths, inference scores, cutoff scores of a
9596  * variable w.r.t. a value by the given values (SCIP_VALUEHISTORY)
9597  *
9598  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9599  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9600  *
9601  * @pre This method can be called if @p scip is in one of the following stages:
9602  * - \ref SCIP_STAGE_TRANSFORMED
9603  * - \ref SCIP_STAGE_INITPRESOLVE
9604  * - \ref SCIP_STAGE_PRESOLVING
9605  * - \ref SCIP_STAGE_EXITPRESOLVE
9606  * - \ref SCIP_STAGE_PRESOLVED
9607  * - \ref SCIP_STAGE_INITSOLVE
9608  * - \ref SCIP_STAGE_SOLVING
9609  */
9611  SCIP* scip, /**< SCIP data structure */
9612  SCIP_VAR* var, /**< variable which should be initialized */
9613  SCIP_Real value, /**< domain value, or SCIP_UNKNOWN */
9614  SCIP_Real downvsids, /**< value to which VSIDS score for downwards branching should be initialized */
9615  SCIP_Real upvsids, /**< value to which VSIDS score for upwards branching should be initialized */
9616  SCIP_Real downconflen, /**< value to which conflict length score for downwards branching should be initialized */
9617  SCIP_Real upconflen, /**< value to which conflict length score for upwards branching should be initialized */
9618  SCIP_Real downinfer, /**< value to which inference counter for downwards branching should be initialized */
9619  SCIP_Real upinfer, /**< value to which inference counter for upwards branching should be initialized */
9620  SCIP_Real downcutoff, /**< value to which cutoff counter for downwards branching should be initialized */
9621  SCIP_Real upcutoff /**< value to which cutoff counter for upwards branching should be initialized */
9622  )
9623 {
9624  SCIP_CALL( SCIPcheckStage(scip, "SCIPinitVarValueBranchStats", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
9625 
9626  assert(downvsids >= 0.0 && upvsids >= 0.0);
9627  assert(downconflen >= 0.0 && upconflen >= 0.0);
9628  assert(downinfer >= 0.0 && upinfer >= 0.0);
9629  assert(downcutoff >= 0.0 && upcutoff >= 0.0);
9630 
9631  if( !SCIPisFeasZero(scip, downvsids) || !SCIPisFeasZero(scip, downinfer) || !SCIPisFeasZero(scip, downcutoff) )
9632  {
9633  SCIP_CALL( SCIPvarIncNBranchings(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, 1) );
9634  SCIP_CALL( SCIPvarIncInferenceSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downinfer) );
9635  SCIP_CALL( SCIPvarIncVSIDS(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downvsids) );
9636  SCIP_CALL( SCIPvarIncCutoffSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downcutoff) );
9637  }
9638 
9639  if( !SCIPisFeasZero(scip, downconflen) )
9640  {
9641  SCIP_CALL( SCIPvarIncNActiveConflicts(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downconflen) );
9642  }
9643 
9644  if( !SCIPisFeasZero(scip, upvsids) || !SCIPisFeasZero(scip, upinfer) || !SCIPisFeasZero(scip, upcutoff) )
9645  {
9646  SCIP_CALL( SCIPvarIncNBranchings(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, 1) );
9647  SCIP_CALL( SCIPvarIncInferenceSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upinfer) );
9648  SCIP_CALL( SCIPvarIncVSIDS(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upvsids) );
9649  SCIP_CALL( SCIPvarIncCutoffSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upcutoff) );
9650  }
9651 
9652  if( !SCIPisFeasZero(scip, upconflen) )
9653  {
9654  SCIP_CALL( SCIPvarIncNActiveConflicts(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upconflen) );
9655  }
9656 
9657  return SCIP_OKAY;
9658 }
9659 
9660 /** returns the average number of cutoffs found after branching on the variable in given direction;
9661  * if branching on the variable in the given direction was yet evaluated, the average number of cutoffs
9662  * over all variables for branching in the given direction is returned
9663  *
9664  * @return the average number of cutoffs found after branching on the variable in given direction
9665  *
9666  * @pre This method can be called if @p scip is in one of the following stages:
9667  * - \ref SCIP_STAGE_INITPRESOLVE
9668  * - \ref SCIP_STAGE_PRESOLVING
9669  * - \ref SCIP_STAGE_EXITPRESOLVE
9670  * - \ref SCIP_STAGE_PRESOLVED
9671  * - \ref SCIP_STAGE_INITSOLVE
9672  * - \ref SCIP_STAGE_SOLVING
9673  * - \ref SCIP_STAGE_SOLVED
9674  */
9676  SCIP* scip, /**< SCIP data structure */
9677  SCIP_VAR* var, /**< problem variable */
9678  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9679  )
9680 {
9681  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffs", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9682 
9683  assert( var->scip == scip );
9684 
9685  return SCIPvarGetAvgCutoffs(var, scip->stat, dir);
9686 }
9687 
9688 /** returns the average number of cutoffs found after branching on the variable in given direction in the current run;
9689  * if branching on the variable in the given direction was yet evaluated, the average number of cutoffs
9690  * over all variables for branching in the given direction is returned
9691  *
9692  * @return the average number of cutoffs found after branching on the variable in given direction in the current run
9693  *
9694  * @pre This method can be called if @p scip is in one of the following stages:
9695  * - \ref SCIP_STAGE_INITPRESOLVE
9696  * - \ref SCIP_STAGE_PRESOLVING
9697  * - \ref SCIP_STAGE_EXITPRESOLVE
9698  * - \ref SCIP_STAGE_PRESOLVED
9699  * - \ref SCIP_STAGE_INITSOLVE
9700  * - \ref SCIP_STAGE_SOLVING
9701  * - \ref SCIP_STAGE_SOLVED
9702  */
9704  SCIP* scip, /**< SCIP data structure */
9705  SCIP_VAR* var, /**< problem variable */
9706  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9707  )
9708 {
9709  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffsCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9710 
9711  assert( var->scip == scip );
9712 
9713  return SCIPvarGetAvgCutoffsCurrentRun(var, scip->stat, dir);
9714 }
9715 
9716 /** returns the variable's average cutoff score value
9717  *
9718  * @return the variable's average cutoff score value
9719  *
9720  * @pre This method can be called if @p scip is in one of the following stages:
9721  * - \ref SCIP_STAGE_INITPRESOLVE
9722  * - \ref SCIP_STAGE_PRESOLVING
9723  * - \ref SCIP_STAGE_EXITPRESOLVE
9724  * - \ref SCIP_STAGE_PRESOLVED
9725  * - \ref SCIP_STAGE_INITSOLVE
9726  * - \ref SCIP_STAGE_SOLVING
9727  * - \ref SCIP_STAGE_SOLVED
9728  */
9730  SCIP* scip, /**< SCIP data structure */
9731  SCIP_VAR* var /**< problem variable */
9732  )
9733 {
9734  SCIP_Real cutoffdown;
9735  SCIP_Real cutoffup;
9736 
9737  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9738 
9739  assert( var->scip == scip );
9740 
9741  cutoffdown = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9742  cutoffup = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9743 
9744  return SCIPbranchGetScore(scip->set, var, cutoffdown, cutoffup);
9745 }
9746 
9747 /** returns the variable's average cutoff score value, only using cutoffs of the current run
9748  *
9749  * @return the variable's average cutoff score value, only using cutoffs of the current run
9750  *
9751  * @pre This method can be called if @p scip is in one of the following stages:
9752  * - \ref SCIP_STAGE_INITPRESOLVE
9753  * - \ref SCIP_STAGE_PRESOLVING
9754  * - \ref SCIP_STAGE_EXITPRESOLVE
9755  * - \ref SCIP_STAGE_PRESOLVED
9756  * - \ref SCIP_STAGE_INITSOLVE
9757  * - \ref SCIP_STAGE_SOLVING
9758  * - \ref SCIP_STAGE_SOLVED
9759  */
9761  SCIP* scip, /**< SCIP data structure */
9762  SCIP_VAR* var /**< problem variable */
9763  )
9764 {
9765  SCIP_Real cutoffdown;
9766  SCIP_Real cutoffup;
9767 
9768  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9769 
9770  assert( var->scip == scip );
9771 
9774 
9775  return SCIPbranchGetScore(scip->set, var, cutoffdown, cutoffup);
9776 }
9777 
9778 /** returns the variable's average inference/cutoff score value, weighting the cutoffs of the variable with the given
9779  * factor
9780  *
9781  * @return the variable's average inference/cutoff score value
9782  *
9783  * @pre This method can be called if @p scip is in one of the following stages:
9784  * - \ref SCIP_STAGE_INITPRESOLVE
9785  * - \ref SCIP_STAGE_PRESOLVING
9786  * - \ref SCIP_STAGE_EXITPRESOLVE
9787  * - \ref SCIP_STAGE_PRESOLVED
9788  * - \ref SCIP_STAGE_INITSOLVE
9789  * - \ref SCIP_STAGE_SOLVING
9790  * - \ref SCIP_STAGE_SOLVED
9791  */
9793  SCIP* scip, /**< SCIP data structure */
9794  SCIP_VAR* var, /**< problem variable */
9795  SCIP_Real cutoffweight /**< factor to weigh average number of cutoffs in branching score */
9796  )
9797 {
9798  SCIP_Real avginferdown;
9799  SCIP_Real avginferup;
9800  SCIP_Real avginfer;
9801  SCIP_Real inferdown;
9802  SCIP_Real inferup;
9803  SCIP_Real cutoffdown;
9804  SCIP_Real cutoffup;
9805 
9806  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceCutoffScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9807 
9808  assert( var->scip == scip );
9809 
9812  avginfer = (avginferdown + avginferup)/2.0;
9813  inferdown = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9814  inferup = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9815  cutoffdown = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9816  cutoffup = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9817 
9818  return SCIPbranchGetScore(scip->set, var,
9819  inferdown + cutoffweight * avginfer * cutoffdown, inferup + cutoffweight * avginfer * cutoffup);
9820 }
9821 
9822 /** returns the variable's average inference/cutoff score value, weighting the cutoffs of the variable with the given
9823  * factor, only using inferences and cutoffs of the current run
9824  *
9825  * @return the variable's average inference/cutoff score value, only using inferences and cutoffs of the current run
9826  *
9827  * @pre This method can be called if @p scip is in one of the following stages:
9828  * - \ref SCIP_STAGE_INITPRESOLVE
9829  * - \ref SCIP_STAGE_PRESOLVING
9830  * - \ref SCIP_STAGE_EXITPRESOLVE
9831  * - \ref SCIP_STAGE_PRESOLVED
9832  * - \ref SCIP_STAGE_INITSOLVE
9833  * - \ref SCIP_STAGE_SOLVING
9834  * - \ref SCIP_STAGE_SOLVED
9835  */
9837  SCIP* scip, /**< SCIP data structure */
9838  SCIP_VAR* var, /**< problem variable */
9839  SCIP_Real cutoffweight /**< factor to weigh average number of cutoffs in branching score */
9840  )
9841 {
9842  SCIP_Real avginferdown;
9843  SCIP_Real avginferup;
9844  SCIP_Real avginfer;
9845  SCIP_Real inferdown;
9846  SCIP_Real inferup;
9847  SCIP_Real cutoffdown;
9848  SCIP_Real cutoffup;
9849 
9850  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceCutoffScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9851 
9852  assert( var->scip == scip );
9853 
9856  avginfer = (avginferdown + avginferup)/2.0;
9861 
9862  return SCIPbranchGetScore(scip->set, var,
9863  inferdown + cutoffweight * avginfer * cutoffdown, inferup + cutoffweight * avginfer * cutoffup);
9864 }
9865 
9866 /** returns the variable's average GMI efficacy score value
9867  *
9868  * @return the variable's average GMI efficacy score value
9869  *
9870  * @pre This method can be called if @p scip is in one of the following stages:
9871  * - \ref SCIP_STAGE_INITPRESOLVE
9872  * - \ref SCIP_STAGE_PRESOLVING
9873  * - \ref SCIP_STAGE_EXITPRESOLVE
9874  * - \ref SCIP_STAGE_PRESOLVED
9875  * - \ref SCIP_STAGE_INITSOLVE
9876  * - \ref SCIP_STAGE_SOLVING
9877  * - \ref SCIP_STAGE_SOLVED
9878  */
9880  SCIP* scip, /**< SCIP data structure */
9881  SCIP_VAR* var /**< problem variable */
9882 )
9883 {
9884 
9885  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgGMIScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9886 
9887  assert( var->scip == scip );
9888 
9889  return SCIPvarGetAvgGMIScore(var, scip->stat);
9890 }
9891 
9892 /** sets the variable's average GMI efficacy score value
9893  *
9894  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9895  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9896  *
9897  * @pre This method can be called if @p scip is in one of the following stages:
9898  * - \ref SCIP_STAGE_INITPRESOLVE
9899  * - \ref SCIP_STAGE_PRESOLVING
9900  * - \ref SCIP_STAGE_EXITPRESOLVE
9901  * - \ref SCIP_STAGE_PRESOLVED
9902  * - \ref SCIP_STAGE_INITSOLVE
9903  * - \ref SCIP_STAGE_SOLVING
9904  * - \ref SCIP_STAGE_SOLVED
9905  */
9906 SCIP_EXPORT
9908  SCIP* scip, /**< SCIP data structure */
9909  SCIP_VAR* var, /**< problem variable */
9910  SCIP_Real gmieff /**< Efficacy of last GMI cut generated from when var was basic /frac */
9911 )
9912 {
9913  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPincVarGMISumScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9914 
9915  assert( var->scip == scip );
9916 
9917  SCIP_CALL( SCIPvarIncGMIeffSum(var, scip->stat, gmieff) );
9918 
9919  return SCIP_OKAY;
9920 }
9921 
9922 /** returns the variable's last GMI efficacy score value
9923  *
9924  * @return the variable's last GMI efficacy score value
9925  *
9926  * @pre This method can be called if @p scip is in one of the following stages:
9927  * - \ref SCIP_STAGE_INITPRESOLVE
9928  * - \ref SCIP_STAGE_PRESOLVING
9929  * - \ref SCIP_STAGE_EXITPRESOLVE
9930  * - \ref SCIP_STAGE_PRESOLVED
9931  * - \ref SCIP_STAGE_INITSOLVE
9932  * - \ref SCIP_STAGE_SOLVING
9933  * - \ref SCIP_STAGE_SOLVED
9934  */
9936  SCIP* scip, /**< SCIP data structure */
9937  SCIP_VAR* var /**< problem variable */
9938 )
9939 {
9940 
9941  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarLastGMIScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9942 
9943  assert( var->scip == scip );
9944 
9945  return SCIPvarGetLastGMIScore(var, scip->stat);
9946 }
9947 
9948 /** sets the variable's last GMI efficacy score value
9949  *
9950  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9951  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9952  *
9953  * @pre This method can be called if @p scip is in one of the following stages:
9954  * - \ref SCIP_STAGE_INITPRESOLVE
9955  * - \ref SCIP_STAGE_PRESOLVING
9956  * - \ref SCIP_STAGE_EXITPRESOLVE
9957  * - \ref SCIP_STAGE_PRESOLVED
9958  * - \ref SCIP_STAGE_INITSOLVE
9959  * - \ref SCIP_STAGE_SOLVING
9960  * - \ref SCIP_STAGE_SOLVED
9961  */
9963  SCIP* scip, /**< SCIP data structure */
9964  SCIP_VAR* var, /**< problem variable */
9965  SCIP_Real gmieff /**< efficacy of GMI cut from tableau row when variable is basic / frac */
9966 )
9967 {
9968  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPsetVarLastGMIScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9969 
9970  assert( var->scip == scip );
9971 
9972  SCIP_CALL( SCIPvarSetLastGMIScore(var, scip->stat, gmieff) );
9973 
9974  return SCIP_OKAY;
9975 }
9976 
9977 /** outputs variable information to file stream via the message system
9978  *
9979  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9980  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9981  *
9982  * @pre This method can be called if @p scip is in one of the following stages:
9983  * - \ref SCIP_STAGE_PROBLEM
9984  * - \ref SCIP_STAGE_TRANSFORMING
9985  * - \ref SCIP_STAGE_TRANSFORMED
9986  * - \ref SCIP_STAGE_INITPRESOLVE
9987  * - \ref SCIP_STAGE_PRESOLVING
9988  * - \ref SCIP_STAGE_EXITPRESOLVE
9989  * - \ref SCIP_STAGE_PRESOLVED
9990  * - \ref SCIP_STAGE_INITSOLVE
9991  * - \ref SCIP_STAGE_SOLVING
9992  * - \ref SCIP_STAGE_SOLVED
9993  * - \ref SCIP_STAGE_EXITSOLVE
9994  * - \ref SCIP_STAGE_FREETRANS
9995  *
9996  * @note If the message handler is set to a NULL pointer nothing will be printed
9997  */
9999  SCIP* scip, /**< SCIP data structure */
10000  SCIP_VAR* var, /**< problem variable */
10001  FILE* file /**< output file (or NULL for standard output) */
10002  )
10003 {
10004  SCIP_CALL( SCIPcheckStage(scip, "SCIPprintVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
10005 
10006  SCIP_CALL( SCIPvarPrint(var, scip->set, scip->messagehdlr, file) );
10007 
10008  return SCIP_OKAY;
10009 }
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:110
SCIP_STAT * stat
Definition: struct_scip.h:80
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:15405
SCIP_RETCODE SCIPflattenVarAggregationGraph(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1695
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:4945
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6269
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
#define NULL
Definition: def.h:267
void SCIPvarGetClosestVlb(SCIP_VAR *var, SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real *closestvlb, int *closestvlbidx)
Definition: var.c:14124
SCIP_Real SCIPgetVarAvgInferences(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9421
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:15532
SCIP_Bool SCIPvarsHaveCommonClique(SCIP_VAR *var1, SCIP_Bool value1, SCIP_VAR *var2, SCIP_Bool value2, SCIP_Bool regardimplics)
Definition: var.c:11476
SCIP_Real SCIPgetVarAvgCutoffs(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9675
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:6327
int SCIPcliquetableGetVarComponentIdx(SCIP_CLIQUETABLE *cliquetable, SCIP_VAR *var)
Definition: implics.c:2348
SCIP_RETCODE SCIPskipSpace(char **s)
Definition: misc.c:10866
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:15052
SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5205
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:10466
void SCIPvarUpdateBestRootSol(SCIP_VAR *var, SCIP_SET *set, SCIP_Real rootsol, SCIP_Real rootredcost, SCIP_Real rootlpobjval)
Definition: var.c:13281
SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2130
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:380
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
Definition: lpi_clp.cpp:3931
SCIP_Real SCIPvarGetAvgGMIScore(SCIP_VAR *var, SCIP_STAT *stat)
Definition: var.c:16360
SCIP_RETCODE SCIPsetRelaxSolValsSol(SCIP *scip, SCIP_RELAX *relax, SCIP_SOL *sol, SCIP_Bool includeslp)
Definition: scip_var.c:2491
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:1599
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:9792
SCIP_CONFLICT * conflict
Definition: struct_scip.h:97
SCIP_RETCODE SCIPaddVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real addobj)
Definition: scip_var.c:4564
SCIP_Real SCIPvarGetAvgCutoffsCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:16313
SCIP_Real SCIPvarGetBranchFactor(SCIP_VAR *var)
Definition: var.c:18239
SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:1994
void SCIPlpEndStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16358
SCIP_RETCODE SCIPclearRelaxSolVals(SCIP *scip, SCIP_RELAX *relax)
Definition: scip_var.c:2366
public methods for memory management
SCIP_Real SCIPgetVarAvgInferencesCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9449
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:9336
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6667
#define SCIPsetDuplicateBufferArray(set, ptr, source, num)
Definition: set.h:1750
#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:7186
SCIP_Bool SCIPvarDoNotMultaggr(SCIP_VAR *var)
Definition: var.c:5882
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:14619
methods for implications, variable bounds, and cliques
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:18079
SCIP_RETCODE SCIPvarGetProbvarBinary(SCIP_VAR **var, SCIP_Bool *negated)
Definition: var.c:12311
SCIP_Bool SCIPvarIsPscostRelerrorReliable(SCIP_VAR *var, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real threshold, SCIP_CONFIDENCELEVEL clevel)
Definition: var.c:14785
#define SCIP_MAXSTRLEN
Definition: def.h:288
SCIP_Bool conf_usesb
Definition: struct_set.h:237
SCIP_Real SCIPgetVarPseudocostVal(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta)
Definition: scip_var.c:8816
void SCIPgmlWriteArc(FILE *file, unsigned int source, unsigned int target, const char *label, const char *color)
Definition: misc.c:639
internal methods for clocks and timing issues
#define SCIP_VARTYPE_INTEGER_CHAR
Definition: def.h:145
SCIP_RETCODE SCIPvarChgLbOriginal(SCIP_VAR *var, SCIP_SET *set, SCIP_Real newbound)
Definition: var.c:6568
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:1866
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:1562
SCIP_Bool presol_donotaggr
Definition: struct_set.h:465
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:18135
SCIP_RETCODE SCIPvarChgLbLazy(SCIP_VAR *var, SCIP_SET *set, SCIP_Real lazylb)
Definition: var.c:7470
#define SCIP_CALL_FINALLY(x, y)
Definition: def.h:422
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:4012
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:90
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:5897
SCIP_Real SCIPvarGetMultaggrLbGlobal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8567
SCIP_RETCODE SCIPchgVarLbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4848
SCIP_PRIMAL * primal
Definition: struct_scip.h:95
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:9061
SCIP_RETCODE SCIPvarChgUbOriginal(SCIP_VAR *var, SCIP_SET *set, SCIP_Real newbound)
Definition: var.c:6627
void SCIPgmlWriteNode(FILE *file, unsigned int id, const char *label, const char *nodetype, const char *fillcolor, const char *bordercolor)
Definition: misc.c:497
SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip_var.c:1441
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:1250
interface methods for specific LP solvers
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:17600
SCIP_RETCODE SCIPsetVarLastGMIScore(SCIP *scip, SCIP_VAR *var, SCIP_Real gmieff)
Definition: scip_var.c:9962
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:13258
SCIP_RETCODE SCIPchgVarUbLazy(SCIP *scip, SCIP_VAR *var, SCIP_Real lazyub)
Definition: scip_var.c:5166
void SCIPgmlWriteClosing(FILE *file)
Definition: misc.c:699
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:6143
SCIP_Real SCIPgetVarPseudocostCountCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:8952
SCIP_BOUNDTYPE SCIPboundchgGetBoundtype(SCIP_BOUNDCHG *boundchg)
Definition: var.c:17347
SCIP_RETCODE SCIPsetRelaxSolVals(SCIP *scip, SCIP_RELAX *relax, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Bool includeslp)
Definition: scip_var.c:2449
SCIP_Real SCIPgetVarPseudocostScoreCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real solval)
Definition: scip_var.c:9143
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_BRANCHCAND * branchcand
Definition: struct_scip.h:91
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
SCIP_Real SCIPgetVarLastGMIScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9935
#define FALSE
Definition: def.h:94
SCIP_Bool SCIPconsIsLockedTypeNeg(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
Definition: cons.c:8597
SCIP_Real SCIPadjustedVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real ub)
Definition: scip_var.c:4647
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3074
SCIP_Bool misc_allowweakdualreds
Definition: struct_set.h:411
SCIP_Bool SCIPsetIsFeasIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6810
SCIP_Real SCIPgetVarVSIDS(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9179
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:6122
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:290
SCIP_Real SCIPgetVarMultaggrUbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6593
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:8844
SCIP_Real constant
Definition: struct_var.h:203
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10877
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6381
SCIP_STAGE stage
Definition: struct_set.h:75
#define TRUE
Definition: def.h:93
SCIP_Real SCIPvarGetAvgConflictlength(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:15361
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:4319
SCIP_Longint SCIPgetVarStrongbranchNode(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:4162
SCIP_RETCODE SCIPhashmapInsertInt(SCIP_HASHMAP *hashmap, void *origin, int image)
Definition: misc.c:3192
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:1748
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:208
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17769
SCIP_Bool branch_divingpscost
Definition: struct_set.h:205
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:10913
#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:7142
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:9703
SCIP_Bool presol_donotmultaggr
Definition: struct_set.h:464
SCIP_Real SCIPgetVarVSIDSCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9211
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:7329
SCIP_Real SCIPgetVarAvgCutoffScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9760
public methods for problem variables
SCIP_Bool SCIPisVarPscostRelerrorReliable(SCIP *scip, SCIP_VAR *var, SCIP_Real threshold, SCIP_CONFIDENCELEVEL clevel)
Definition: scip_var.c:9080
SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5322
SCIP_Real SCIPgetRelaxSolObj(SCIP *scip)
Definition: scip_var.c:2634
SCIP_Bool SCIPgetVarWasFixedAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2284
SCIP_Real SCIPvarGetAvgInferences(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:16068
SCIP_Bool diving
Definition: struct_lp.h:380
SCIP_Real SCIPgetVarPseudocost(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:8870
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:12007
SCIP_RETCODE SCIPchgVarUbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4892
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:6563
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:7016
SCIP_PROB * transprob
Definition: struct_scip.h:99
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:4678
SCIP_Real constant
Definition: struct_var.h:186
SCIP_Bool conf_enable
Definition: struct_set.h:228
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:6663
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:6179
#define SCIP_LONGINT_MAX
Definition: def.h:159
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:1175
SCIP_RETCODE SCIPcreateLPSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip_sol.c:226
SCIP_RETCODE SCIPmarkRelaxSolInvalid(SCIP *scip)
Definition: scip_var.c:2584
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
int SCIPconflictGetNConflicts(SCIP_CONFLICT *conflict)
SCIP_RETCODE SCIPvarUpdatePseudocost(SCIP_VAR *var, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
Definition: var.c:14380
#define SCIPsetFreeBufferArray(set, ptr)
Definition: set.h:1755
SCIP_Real SCIPadjustedVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real lb)
Definition: scip_var.c:4615
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition: type_lp.h:51
void SCIPvarAdjustLb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *lb)
Definition: var.c:6518
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)
SCIP_Bool SCIPisTransformed(SCIP *scip)
Definition: scip_general.c:590
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:6722
public methods for SCIP variables
SCIP_RETCODE SCIPvarChgBranchDirection(SCIP_VAR *var, SCIP_BRANCHDIR branchdirection)
Definition: var.c:11819
SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
Definition: var.c:17905
SCIP_Bool branch_forceall
Definition: struct_set.h:206
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:5034
#define SCIPdebugMsg
Definition: scip_message.h:78
SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition: scip_var.c:1482
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:3664
internal methods for LP management
int SCIPvarGetNCliques(SCIP_VAR *var, SCIP_Bool varfixing)
Definition: var.c:18431
SCIP_PROB * origprob
Definition: struct_scip.h:81
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:6611
SCIP_VAR ** vars
Definition: struct_var.h:195
SCIP_Real SCIPcomputeVarUbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6486
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:6507
SCIP_Bool SCIPisStrongbranchDownFirst(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:2657
SCIP_RETCODE SCIPtransformVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition: scip_var.c:1391
public methods for numerical tolerances
SCIP_Bool reopt_enable
Definition: struct_set.h:515
SCIP_Real SCIPgetVarPseudocostScore(SCIP *scip, SCIP_VAR *var, SCIP_Real solval)
Definition: scip_var.c:9105
SCIP_RETCODE SCIPscaleVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real scale)
Definition: scip_var.c:7923
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:6363
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:4081
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3423
SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
Definition: scip_var.c:4261
SCIP_Real SCIPvarGetVSIDSCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:15929
SCIP_RETCODE SCIPupdateVarPseudocost(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
Definition: scip_var.c:8782
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:2266
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:8178
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:6923
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:7971
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:18089
SCIP_RETCODE SCIPvarIncGMIeffSum(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real gmieff)
Definition: var.c:16400
SCIP_VAR * SCIPvarGetProbvar(SCIP_VAR *var)
Definition: var.c:12219
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:8537
SCIP_MEM * mem
Definition: struct_scip.h:72
public methods for managing constraints
SCIP_Bool misc_allowstrongdualreds
Definition: struct_set.h:410
SCIP_Real SCIPvarGetImplRedcost(SCIP_VAR *var, SCIP_SET *set, SCIP_Bool varfixing, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp)
Definition: var.c:13469
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:11688
SCIP_Real SCIPvarGetPseudocost(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real solvaldelta)
Definition: var.c:14478
SCIP_RETCODE SCIPprobRemoveVarName(SCIP_PROB *prob, SCIP_VAR *var)
Definition: prob.c:955
SCIP_AGGREGATE aggregate
Definition: struct_var.h:231
SCIP_RETCODE SCIPmarkDoNotAggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8684
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:7493
SCIP_Real SCIPgetVarPseudocostVariance(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun)
Definition: scip_var.c:8978
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:1646
SCIP_RETCODE SCIPincVarGMISumScore(SCIP *scip, SCIP_VAR *var, SCIP_Real gmieff)
Definition: scip_var.c:9907
SCIP_Bool SCIPvarDoNotAggr(SCIP_VAR *var)
Definition: var.c:5849
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:17357
SCIP_EVENTFILTER * eventfilter
Definition: struct_scip.h:89
SCIP_Bool SCIPlpIsDualReliable(SCIP_LP *lp)
Definition: lp.c:17827
SCIP_Bool SCIPdoNotAggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8587
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:14928
SCIP_RETCODE SCIPchgVarLbLazy(SCIP *scip, SCIP_VAR *var, SCIP_Real lazylb)
Definition: scip_var.c:5125
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:8600
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:6265
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:1254
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:5434
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:9539
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:1796
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:6782
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:14527
void SCIPstrCopySection(const char *str, char startchar, char endchar, char *token, int size, char **endptr)
Definition: misc.c:11007
SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:4439
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:105
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:4768
SCIP_Real SCIPcalculatePscostConfidenceBound(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun, SCIP_CONFIDENCELEVEL clevel)
Definition: scip_var.c:9000
SCIP_OBJSENSE objsense
Definition: struct_prob.h:87
SCIP_RETCODE SCIPmarkDoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8717
char branch_firstsbchild
Definition: struct_set.h:196
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17420
SCIP_VAR * transvar
Definition: struct_var.h:179
SCIP_REOPT * reopt
Definition: struct_scip.h:86
SCIP_RETCODE SCIPsetRelaxSolVal(SCIP *scip, SCIP_RELAX *relax, SCIP_VAR *var, SCIP_Real val)
Definition: scip_var.c:2416
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:3108
SCIP_Real SCIPsetFeasCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6845
SCIP_RETCODE SCIPtightenVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6230
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
void SCIPvarGetClosestVub(SCIP_VAR *var, SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real *closestvub, int *closestvubidx)
Definition: var.c:14199
SCIP_NEGATE negate
Definition: struct_var.h:233
SCIP_Real SCIPgetVarConflictlengthScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9305
SCIP_RETCODE SCIPvarSetRelaxSol(SCIP_VAR *var, SCIP_SET *set, SCIP_RELAXATION *relaxation, SCIP_Real solval, SCIP_Bool updateobj)
Definition: var.c:13863
data structures for branch and bound tree
SCIP_HISTORY * glbhistory
Definition: struct_stat.h:181
SCIP_Real SCIPboundchgGetNewbound(SCIP_BOUNDCHG *boundchg)
Definition: var.c:17317
#define REALABS(x)
Definition: def.h:197
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
Definition: var.c:18453
SCIP_Real SCIPgetVarAvgInferenceScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9506
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:10002
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:14747
#define SCIP_CALL(x)
Definition: def.h:380
SCIP_RETCODE SCIPprobAddVarName(SCIP_PROB *prob, SCIP_VAR *var)
Definition: prob.c:939
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:9031
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:6528
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:6012
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:15448
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:1740
SCIP_Real SCIPgetVarAvgConflictlength(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9367
SCIP_RETCODE SCIPremoveVarFromGlobalStructures(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:7861
SCIP_RETCODE SCIPgetVarClosestVub(SCIP *scip, SCIP_VAR *var, SCIP_SOL *sol, SCIP_Real *closestvub, int *closestvubidx)
Definition: scip_var.c:6634
SCIP_Longint SCIPgetVarStrongbranchLPAge(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:4196
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:7092
SCIP_Real SCIPvarGetPseudocostCount(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:14574
#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:6291
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:8098
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:8924
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:8898
SCIP_CLIQUETABLE * cliquetable
Definition: struct_scip.h:98
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:4515
internal methods for problem variables
SCIP_RETCODE SCIPvarChgBranchFactor(SCIP_VAR *var, SCIP_SET *set, SCIP_Real branchfactor)
Definition: var.c:11561
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:5293
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
#define SCIP_UNKNOWN
Definition: def.h:194
SCIP_RETCODE SCIPstartStrongbranch(SCIP *scip, SCIP_Bool enablepropagation)
Definition: scip_var.c:2688
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:15616
void SCIPrelaxationSetSolRelax(SCIP_RELAXATION *relaxation, SCIP_RELAX *relax)
Definition: relax.c:880
#define SCIP_Bool
Definition: def.h:91
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:5828
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:7604
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:2311
#define MAXNCLIQUEVARSCOMP
Definition: scip_var.c:7122
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:2841
int SCIPvarGetBranchPriority(SCIP_VAR *var)
Definition: var.c:18251
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:3354
SCIP_RETCODE SCIPmarkRelaxSolValid(SCIP *scip, SCIP_RELAX *relax, SCIP_Bool includeslp)
Definition: scip_var.c:2559
SCIP_Bool branch_roundsbsol
Definition: struct_set.h:209
int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition: var.c:3430
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
SCIP_Bool SCIPstrToRealValue(const char *str, SCIP_Real *value, char **endptr)
Definition: misc.c:10977
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:3050
SCIP_RETCODE SCIPcalcCliquePartition(SCIP *const scip, SCIP_VAR **const vars, int const nvars, int *const cliquepartition, int *const ncliques)
Definition: scip_var.c:7258
SCIP_VAR * SCIPboundchgGetVar(SCIP_BOUNDCHG *boundchg)
Definition: var.c:17327
#define MIN(x, y)
Definition: def.h:243
methods for debugging
SCIP_Bool * SCIPcliqueGetValues(SCIP_CLIQUE *clique)
Definition: implics.c:3392
SCIP_BOUNDCHG * SCIPdomchgGetBoundchg(SCIP_DOMCHG *domchg, int pos)
Definition: var.c:17375
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:7712
SCIP_Real SCIPvarGetMultaggrUbGlobal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8633
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip_sol.c:841
SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
Definition: prob.c:2350
void SCIPenableVarHistory(SCIP *scip)
Definition: scip_var.c:8743
SCIP_Real SCIPcomputeVarLbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6465
SCIP_Real SCIPgetVarAvgInferenceCutoffScoreCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real cutoffweight)
Definition: scip_var.c:9836
union SCIP_Var::@22 data
SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18671
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:3886
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:4425
SCIP_Real SCIPvarGetAvgInferencesCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:16125
SCIP_Bool SCIPtreeHasCurrentNodeLP(SCIP_TREE *tree)
Definition: tree.c:8421
SCIP_Bool SCIPallowWeakDualReds(SCIP *scip)
Definition: scip_var.c:8658
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition: scip_var.c:8278
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:134
SCIP_RETCODE SCIPchgVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition: scip_var.c:7982
SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:4353
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:17790
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:545
SCIP_Real SCIPvarGetRelaxSol(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:13924
datastructures for problem statistics
int nconflicthdlrs
Definition: struct_set.h:123
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:6689
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:6340
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:5503
SCIP_Real SCIPvarGetLastGMIScore(SCIP_VAR *var, SCIP_STAT *stat)
Definition: var.c:16444
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:15188
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:2921
void SCIPrelaxationSetSolObj(SCIP_RELAXATION *relaxation, SCIP_Real obj)
Definition: relax.c:828
#define SCIP_MAXTREEDEPTH
Definition: def.h:316
SCIP * scip
Definition: struct_var.h:288
SCIP_BDCHGINFO * SCIPvarGetLbchgInfo(SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: var.c:16578
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:16634
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:1992
SCIP_Real SCIPgetVarMultaggrLbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6578
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:6834
#define SCIP_LONGINT_FORMAT
Definition: def.h:165
SCIP_CLIQUE ** SCIPgetCliques(SCIP *scip)
Definition: scip_var.c:7631
SCIP_Real SCIPgetVarAvgConflictlengthCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9393
SCIP_RETCODE SCIPaddVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real addfactor)
Definition: scip_var.c:7951
SCIP_LPSOLSTAT SCIPgetLastStrongbranchLPSolStat(SCIP *scip, SCIP_BRANCHDIR branchdir)
Definition: scip_var.c:3990
SCIP_Bool misc_exactsolve
Definition: struct_set.h:395
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:146
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:4046
general public methods
#define MAX(x, y)
Definition: def.h:239
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:1911
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:1160
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:5447
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:5617
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:3775
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:2329
int SCIPdomchgGetNBoundchgs(SCIP_DOMCHG *domchg)
Definition: var.c:17367
SCIP_RETCODE SCIPvarSetLastGMIScore(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real gmieff)
Definition: var.c:16484
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:147
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:3930
SCIP_NODE * SCIPtreeGetCurrentNode(SCIP_TREE *tree)
Definition: tree.c:8387
SCIP_RETCODE SCIPendStrongbranch(SCIP *scip)
Definition: scip_var.c:2746
SCIP_Bool SCIPisRelaxSolValid(SCIP *scip)
Definition: scip_var.c:2539
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:14862
SCIP_RETCODE SCIPvarMarkDoNotAggr(SCIP_VAR *var)
Definition: var.c:6107
SCIP_Bool SCIPallowDualReds(SCIP *scip)
Definition: scip_var.c:8616
SCIP_SET * set
Definition: struct_scip.h:73
public methods for message output
int SCIPgetNCliques(SCIP *scip)
Definition: scip_var.c:7577
data structures for LP management
SCIP_RETCODE SCIPaddVarBranchPriority(SCIP *scip, SCIP_VAR *var, int addpriority)
Definition: scip_var.c:8056
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:17539
SCIP_RETCODE SCIPcalcNegatedCliquePartition(SCIP *const scip, SCIP_VAR **const vars, int const nvars, int *const cliquepartition, int *const ncliques)
Definition: scip_var.c:7477
SCIP_MESSAGEHDLR * messagehdlr
Definition: struct_scip.h:76
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:8403
SCIP_NODETYPE SCIPnodeGetType(SCIP_NODE *node)
Definition: tree.c:7434
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1216
#define SCIP_Real
Definition: def.h:173
internal methods for problem statistics
SCIP_RETCODE SCIPvarsGetProbvarBinary(SCIP_VAR ***vars, SCIP_Bool **negatedarr, int nvars)
Definition: var.c:12279
SCIP_Real SCIPgetVarAvgGMIScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9879
SCIP_RETCODE SCIPchgVarBranchDirection(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR branchdirection)
Definition: scip_var.c:8087
SCIP_Bool SCIPhaveVarsCommonClique(SCIP *scip, SCIP_VAR *var1, SCIP_Bool value1, SCIP_VAR *var2, SCIP_Bool value2, SCIP_Bool regardimplics)
Definition: scip_var.c:7661
datastructures for collecting primal CIP solutions and primal informations
public methods for message handling
SCIP_Bool SCIPdoNotAggr(SCIP *scip)
Definition: scip_var.c:8567
SCIP_RETCODE SCIPtransformVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip_var.c:1351
SCIP_Real SCIPvarGetVSIDS(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:18544
#define SCIP_INVALID
Definition: def.h:193
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:158
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:16266
SCIP_Real lb
Definition: struct_var.h:170
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6733
SCIP_Longint nsbsolsfound
Definition: struct_stat.h:104
SCIP_TREE * tree
Definition: struct_scip.h:96
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17585
#define SCIP_VARTYPE_BINARY_CHAR
Definition: def.h:144
SCIP_Real SCIPvarGetMultaggrUbLocal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8501
SCIP_RETCODE SCIPvarChgName(SCIP_VAR *var, BMS_BLKMEM *blkmem, const char *name)
Definition: var.c:2914
SCIP_RELAXATION * relaxation
Definition: struct_scip.h:94
void SCIPsolSetStrongbranching(SCIP_SOL *sol)
Definition: sol.c:2909
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:3028
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:8577
SCIP_DOM glbdom
Definition: struct_var.h:225
SCIP_Real SCIPgetVarConflictScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9274
SCIP_Real SCIPhistoryGetAvgInferences(SCIP_HISTORY *history, SCIP_BRANCHDIR dir)
Definition: history.c:665
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:8585
SCIP_Real SCIPgetVarSol(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:2309
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:18145
SCIP_Real SCIPgetVarMultaggrLbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6548
#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:683
void SCIPvarAdjustUb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *ub)
Definition: var.c:6535
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:7113
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition: var.c:17562
SCIP_RETCODE SCIPtightenVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6350
static SCIP_RETCODE tightenBounds(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:8104
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:9610
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:130
SCIP_RETCODE SCIPupdateVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition: scip_var.c:8023
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:12648
SCIP_NODE * root
Definition: struct_tree.h:186
int SCIPhashmapGetImageInt(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3281
#define SCIP_CALL_ABORT(x)
Definition: def.h:359
SCIP_Real SCIPvarGetPseudoSol(SCIP_VAR *var)
Definition: var.c:18531
SCIP_RETCODE SCIPcleanupCliques(SCIP *scip, SCIP_Bool *infeasible)
Definition: scip_var.c:7534
SCIP_Real SCIPgetVarFarkasCoef(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1956
SCIP_ORIGINAL original
Definition: struct_var.h:229
SCIP_LP * lp
Definition: struct_scip.h:92
#define SCIPABORT()
Definition: def.h:352
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:4228
SCIP_RETCODE SCIPgetActiveVars(SCIP *scip, SCIP_VAR **vars, int *nvars, int varssize, int *requiredsize)
Definition: scip_var.c:1832
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:17611
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:8435
void SCIPdisableVarHistory(SCIP *scip)
Definition: scip_var.c:8762
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1217
SCIP_Real SCIPgetVarAvgInferenceScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9475
datastructures for global SCIP settings
SCIP_RETCODE SCIPlpEndStrongbranch(SCIP_LP *lp)
Definition: lp.c:4195
SCIP_Bool SCIPallowStrongDualReds(SCIP *scip)
Definition: scip_var.c:8631
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:5725
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:5918
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:7895
SCIP_RETCODE SCIPprintVar(SCIP *scip, SCIP_VAR *var, FILE *file)
Definition: scip_var.c:9998
static SCIP_RETCODE relabelOrderConsistent(SCIP *const scip, int *labels, int const nlabels, int *nclasses)
Definition: scip_var.c:6955
SCIP_Bool SCIPallowObjProp(SCIP *scip)
Definition: scip_var.c:8644
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip_var.c:1529
SCIP_Real SCIPgetVarConflictScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9243
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:14693
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17749
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:17575
SCIP_Real SCIPgetRelaxSolVal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:2605
SCIP_Real scalar
Definition: struct_var.h:185
void SCIPvarMarkDeleteGlobalStructures(SCIP_VAR *var)
Definition: var.c:17677
SCIP_RETCODE SCIPchgVarName(SCIP *scip, SCIP_VAR *var, const char *name)
Definition: scip_var.c:1301
memory allocation routines
SCIP_Real SCIPgetVarAvgCutoffScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9729