Scippy

SCIP

Solving Constraint Integer Programs

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