Scippy

SCIP

Solving Constraint Integer Programs

scip_var.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright 2002-2022 Zuse Institute Berlin */
7 /* */
8 /* Licensed under the Apache License, Version 2.0 (the "License"); */
9 /* you may not use this file except in compliance with the License. */
10 /* You may obtain a copy of the License at */
11 /* */
12 /* http://www.apache.org/licenses/LICENSE-2.0 */
13 /* */
14 /* Unless required by applicable law or agreed to in writing, software */
15 /* distributed under the License is distributed on an "AS IS" BASIS, */
16 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17 /* See the License for the specific language governing permissions and */
18 /* limitations under the License. */
19 /* */
20 /* You should have received a copy of the Apache-2.0 license */
21 /* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22 /* */
23 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24 
25 /**@file scip_var.c
26  * @ingroup OTHER_CFILES
27  * @brief public methods for SCIP variables
28  * @author Tobias Achterberg
29  * @author Timo Berthold
30  * @author Gerald Gamrath
31  * @author Leona Gottwald
32  * @author Stefan Heinz
33  * @author Gregor Hendel
34  * @author Thorsten Koch
35  * @author Alexander Martin
36  * @author Marc Pfetsch
37  * @author Michael Winkler
38  * @author Kati Wolter
39  *
40  * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE
41  */
42 
43 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
44 
45 #include "blockmemshell/memory.h"
46 #include "lpi/lpi.h"
47 #include "scip/branch.h"
48 #include "scip/clock.h"
49 #include "scip/conflict.h"
50 #include "scip/debug.h"
51 #include "scip/history.h"
52 #include "scip/implics.h"
53 #include "scip/lp.h"
54 #include "scip/prob.h"
55 #include "scip/pub_cons.h"
56 #include "scip/pub_implics.h"
57 #include "scip/pub_lp.h"
58 #include "scip/pub_message.h"
59 #include "scip/pub_misc.h"
60 #include "scip/pub_tree.h"
61 #include "scip/pub_var.h"
62 #include "scip/relax.h"
63 #include "scip/scip_general.h"
64 #include "scip/scip_lp.h"
65 #include "scip/scip_mem.h"
66 #include "scip/scip_message.h"
67 #include "scip/scip_numerics.h"
68 #include "scip/scip_prob.h"
69 #include "scip/scip_probing.h"
70 #include "scip/scip_sol.h"
71 #include "scip/scip_solvingstats.h"
72 #include "scip/scip_tree.h"
73 #include "scip/scip_var.h"
74 #include "scip/set.h"
75 #include "scip/sol.h"
76 #include "scip/solve.h"
77 #include "scip/stat.h"
78 #include "scip/struct_lp.h"
79 #include "scip/struct_mem.h"
80 #include "scip/struct_primal.h"
81 #include "scip/struct_prob.h"
82 #include "scip/struct_scip.h"
83 #include "scip/struct_set.h"
84 #include "scip/struct_stat.h"
85 #include "scip/struct_tree.h"
86 #include "scip/struct_var.h"
87 #include "scip/tree.h"
88 #include "scip/var.h"
89 #include <ctype.h>
90 
91 
92 /** creates and captures problem variable; if variable is of integral type, fractional bounds are automatically rounded;
93  * an integer variable with bounds zero and one is automatically converted into a binary variable;
94  *
95  * @warning When doing column generation and the original problem is a maximization problem, notice that SCIP will
96  * transform the problem into a minimization problem by multiplying the objective function by -1. Thus, the
97  * original objective function value of variables created during the solving process has to be multiplied by
98  * -1, too.
99  *
100  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
101  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
102  *
103  * @pre This method can be called if @p scip is in one of the following stages:
104  * - \ref SCIP_STAGE_PROBLEM
105  * - \ref SCIP_STAGE_TRANSFORMING
106  * - \ref SCIP_STAGE_INITPRESOLVE
107  * - \ref SCIP_STAGE_PRESOLVING
108  * - \ref SCIP_STAGE_EXITPRESOLVE
109  * - \ref SCIP_STAGE_PRESOLVED
110  * - \ref SCIP_STAGE_SOLVING
111  *
112  * @note the variable gets captured, hence at one point you have to release it using the method SCIPreleaseVar()
113  */
115  SCIP* scip, /**< SCIP data structure */
116  SCIP_VAR** var, /**< pointer to variable object */
117  const char* name, /**< name of variable, or NULL for automatic name creation */
118  SCIP_Real lb, /**< lower bound of variable */
119  SCIP_Real ub, /**< upper bound of variable */
120  SCIP_Real obj, /**< objective function value */
121  SCIP_VARTYPE vartype, /**< type of variable */
122  SCIP_Bool initial, /**< should var's column be present in the initial root LP? */
123  SCIP_Bool removable, /**< is var's column removable from the LP (due to aging or cleanup)? */
124  SCIP_DECL_VARDELORIG ((*vardelorig)), /**< frees user data of original variable, or NULL */
125  SCIP_DECL_VARTRANS ((*vartrans)), /**< creates transformed user data by transforming original user data, or NULL */
126  SCIP_DECL_VARDELTRANS ((*vardeltrans)), /**< frees user data of transformed variable, or NULL */
127  SCIP_DECL_VARCOPY ((*varcopy)), /**< copies variable data if wanted to subscip, or NULL */
128  SCIP_VARDATA* vardata /**< user data for this specific variable */
129  )
130 {
131  assert(var != NULL);
132  assert(lb <= ub);
133 
134  SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateVar", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
135 
136  /* forbid infinite objective function values */
137  if( SCIPisInfinity(scip, REALABS(obj)) )
138  {
139  SCIPerrorMessage("invalid objective function value: value is infinite\n");
140  return SCIP_INVALIDDATA;
141  }
142 
143  switch( scip->set->stage )
144  {
145  case SCIP_STAGE_PROBLEM:
146  SCIP_CALL( SCIPvarCreateOriginal(var, scip->mem->probmem, scip->set, scip->stat,
147  name, lb, ub, obj, vartype, initial, removable, vardelorig, vartrans, vardeltrans, varcopy, vardata) );
148  break;
149 
155  case SCIP_STAGE_SOLVING:
156  SCIP_CALL( SCIPvarCreateTransformed(var, scip->mem->probmem, scip->set, scip->stat,
157  name, lb, ub, obj, vartype, initial, removable, vardelorig, vartrans, vardeltrans, varcopy, vardata) );
158  break;
159 
160  default:
161  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
162  return SCIP_INVALIDCALL;
163  } /*lint !e788*/
164 
165  return SCIP_OKAY;
166 }
167 
168 /** creates and captures problem variable with optional callbacks and variable data set to NULL, which can be set
169  * afterwards using SCIPvarSetDelorigData(), SCIPvarSetTransData(),
170  * SCIPvarSetDeltransData(), SCIPvarSetCopy(), and SCIPvarSetData(); sets variable flags initial=TRUE
171  * and removable = FALSE, which can be adjusted by using SCIPvarSetInitial() and SCIPvarSetRemovable(), resp.;
172  * if variable is of integral type, fractional bounds are automatically rounded;
173  * an integer variable with bounds zero and one is automatically converted into a binary variable;
174  *
175  * @warning When doing column generation and the original problem is a maximization problem, notice that SCIP will
176  * transform the problem into a minimization problem by multiplying the objective function by -1. Thus, the
177  * original objective function value of variables created during the solving process has to be multiplied by
178  * -1, too.
179  *
180  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
181  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
182  *
183  * @pre This method can be called if @p scip is in one of the following stages:
184  * - \ref SCIP_STAGE_PROBLEM
185  * - \ref SCIP_STAGE_TRANSFORMING
186  * - \ref SCIP_STAGE_INITPRESOLVE
187  * - \ref SCIP_STAGE_PRESOLVING
188  * - \ref SCIP_STAGE_EXITPRESOLVE
189  * - \ref SCIP_STAGE_PRESOLVED
190  * - \ref SCIP_STAGE_SOLVING
191  *
192  * @note the variable gets captured, hence at one point you have to release it using the method SCIPreleaseVar()
193  */
195  SCIP* scip, /**< SCIP data structure */
196  SCIP_VAR** var, /**< pointer to variable object */
197  const char* name, /**< name of variable, or NULL for automatic name creation */
198  SCIP_Real lb, /**< lower bound of variable */
199  SCIP_Real ub, /**< upper bound of variable */
200  SCIP_Real obj, /**< objective function value */
201  SCIP_VARTYPE vartype /**< type of variable */
202  )
203 {
204  SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateVarBasic", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
205 
206  SCIP_CALL( SCIPcreateVar(scip, var, name, lb, ub, obj, vartype, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
207 
208  return SCIP_OKAY;
209 }
210 
211 /** outputs the variable name to the file stream
212  *
213  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
214  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
215  *
216  * @pre This method can be called if @p scip is in one of the following stages:
217  * - \ref SCIP_STAGE_PROBLEM
218  * - \ref SCIP_STAGE_TRANSFORMING
219  * - \ref SCIP_STAGE_TRANSFORMED
220  * - \ref SCIP_STAGE_INITPRESOLVE
221  * - \ref SCIP_STAGE_PRESOLVING
222  * - \ref SCIP_STAGE_EXITPRESOLVE
223  * - \ref SCIP_STAGE_PRESOLVED
224  * - \ref SCIP_STAGE_INITSOLVE
225  * - \ref SCIP_STAGE_SOLVING
226  * - \ref SCIP_STAGE_SOLVED
227  * - \ref SCIP_STAGE_EXITSOLVE
228  * - \ref SCIP_STAGE_FREETRANS
229  */
231  SCIP* scip, /**< SCIP data structure */
232  FILE* file, /**< output file, or NULL for stdout */
233  SCIP_VAR* var, /**< variable to output */
234  SCIP_Bool type /**< should the variable type be also posted */
235  )
236 {
237  assert(scip != NULL);
238  assert(var != NULL);
239 
240  SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarName", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
241 
242  /* print variable name */
243  if( SCIPvarIsNegated(var) )
244  {
245  SCIP_VAR* negatedvar;
246 
247  SCIP_CALL( SCIPgetNegatedVar(scip, var, &negatedvar) );
248  SCIPinfoMessage(scip, file, "<~%s>", SCIPvarGetName(negatedvar));
249  }
250  else
251  {
252  SCIPinfoMessage(scip, file, "<%s>", SCIPvarGetName(var));
253  }
254 
255  if( type )
256  {
257  /* print variable type */
258  SCIPinfoMessage(scip, file, "[%c]",
262  }
263 
264  return SCIP_OKAY;
265 }
266 
267 /** print the given list of variables to output stream separated by the given delimiter character;
268  *
269  * i. e. the variables x1, x2, ..., xn with given delimiter ',' are written as: <x1>, <x2>, ..., <xn>;
270  *
271  * the method SCIPparseVarsList() can parse such a string
272  *
273  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
274  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
275  *
276  * @pre This method can be called if @p scip is in one of the following stages:
277  * - \ref SCIP_STAGE_PROBLEM
278  * - \ref SCIP_STAGE_TRANSFORMING
279  * - \ref SCIP_STAGE_TRANSFORMED
280  * - \ref SCIP_STAGE_INITPRESOLVE
281  * - \ref SCIP_STAGE_PRESOLVING
282  * - \ref SCIP_STAGE_EXITPRESOLVE
283  * - \ref SCIP_STAGE_PRESOLVED
284  * - \ref SCIP_STAGE_INITSOLVE
285  * - \ref SCIP_STAGE_SOLVING
286  * - \ref SCIP_STAGE_SOLVED
287  * - \ref SCIP_STAGE_EXITSOLVE
288  * - \ref SCIP_STAGE_FREETRANS
289  *
290  * @note The printing process is done via the message handler system.
291  */
293  SCIP* scip, /**< SCIP data structure */
294  FILE* file, /**< output file, or NULL for stdout */
295  SCIP_VAR** vars, /**< variable array to output */
296  int nvars, /**< number of variables */
297  SCIP_Bool type, /**< should the variable type be also posted */
298  char delimiter /**< character which is used for delimitation */
299  )
300 {
301  int v;
302 
303  SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsList", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
304 
305  for( v = 0; v < nvars; ++v )
306  {
307  if( v > 0 )
308  {
309  SCIPinfoMessage(scip, file, "%c", delimiter);
310  }
311 
312  /* print variable name */
313  SCIP_CALL( SCIPwriteVarName(scip, file, vars[v], type) );
314  }
315 
316  return SCIP_OKAY;
317 }
318 
319 /** print the given variables and coefficients as linear sum in the following form
320  * c1 <x1> + c2 <x2> ... + cn <xn>
321  *
322  * This string can be parsed by the method SCIPparseVarsLinearsum().
323  *
324  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
325  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
326  *
327  * @pre This method can be called if @p scip is in one of the following stages:
328  * - \ref SCIP_STAGE_PROBLEM
329  * - \ref SCIP_STAGE_TRANSFORMING
330  * - \ref SCIP_STAGE_TRANSFORMED
331  * - \ref SCIP_STAGE_INITPRESOLVE
332  * - \ref SCIP_STAGE_PRESOLVING
333  * - \ref SCIP_STAGE_EXITPRESOLVE
334  * - \ref SCIP_STAGE_PRESOLVED
335  * - \ref SCIP_STAGE_INITSOLVE
336  * - \ref SCIP_STAGE_SOLVING
337  * - \ref SCIP_STAGE_SOLVED
338  * - \ref SCIP_STAGE_EXITSOLVE
339  * - \ref SCIP_STAGE_FREETRANS
340  *
341  * @note The printing process is done via the message handler system.
342  */
344  SCIP* scip, /**< SCIP data structure */
345  FILE* file, /**< output file, or NULL for stdout */
346  SCIP_VAR** vars, /**< variable array to output */
347  SCIP_Real* vals, /**< array of coefficients or NULL if all coefficients are 1.0 */
348  int nvars, /**< number of variables */
349  SCIP_Bool type /**< should the variable type be also posted */
350  )
351 {
352  int v;
353 
354  SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsLinearsum", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
355 
356  for( v = 0; v < nvars; ++v )
357  {
358  if( vals != NULL )
359  {
360  if( vals[v] == 1.0 )
361  {
362  if( v > 0 )
363  SCIPinfoMessage(scip, file, " +");
364  }
365  else if( vals[v] == -1.0 )
366  SCIPinfoMessage(scip, file, " -");
367  else
368  SCIPinfoMessage(scip, file, " %+.15g", vals[v]);
369  }
370  else if( nvars > 0 )
371  SCIPinfoMessage(scip, file, " +");
372 
373  /* print variable name */
374  SCIP_CALL( SCIPwriteVarName(scip, file, vars[v], type) );
375  }
376 
377  return SCIP_OKAY;
378 }
379 
380 /** print the given terms as signomial in the following form
381  * c1 <x11>^e11 <x12>^e12 ... <x1n>^e1n + c2 <x21>^e21 <x22>^e22 ... + ... + cn <xn1>^en1 ...
382  *
383  * This string can be parsed by the method SCIPparseVarsPolynomial().
384  *
385  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
386  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
387  *
388  * @pre This method can be called if @p scip is in one of the following stages:
389  * - \ref SCIP_STAGE_PROBLEM
390  * - \ref SCIP_STAGE_TRANSFORMING
391  * - \ref SCIP_STAGE_TRANSFORMED
392  * - \ref SCIP_STAGE_INITPRESOLVE
393  * - \ref SCIP_STAGE_PRESOLVING
394  * - \ref SCIP_STAGE_EXITPRESOLVE
395  * - \ref SCIP_STAGE_PRESOLVED
396  * - \ref SCIP_STAGE_INITSOLVE
397  * - \ref SCIP_STAGE_SOLVING
398  * - \ref SCIP_STAGE_SOLVED
399  * - \ref SCIP_STAGE_EXITSOLVE
400  * - \ref SCIP_STAGE_FREETRANS
401  *
402  * @note The printing process is done via the message handler system.
403  */
405  SCIP* scip, /**< SCIP data structure */
406  FILE* file, /**< output file, or NULL for stdout */
407  SCIP_VAR*** monomialvars, /**< arrays with variables for each monomial */
408  SCIP_Real** monomialexps, /**< arrays with variable exponents, or NULL if always 1.0 */
409  SCIP_Real* monomialcoefs, /**< array with monomial coefficients */
410  int* monomialnvars, /**< array with number of variables for each monomial */
411  int nmonomials, /**< number of monomials */
412  SCIP_Bool type /**< should the variable type be also posted */
413  )
414 {
415  int i;
416  int v;
417 
418  assert(scip != NULL);
419  assert(monomialvars != NULL || nmonomials == 0);
420  assert(monomialcoefs != NULL || nmonomials == 0);
421  assert(monomialnvars != NULL || nmonomials == 0);
422 
423  SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteVarsPolynomial", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
424 
425  if( nmonomials == 0 )
426  {
427  SCIPinfoMessage(scip, file, " 0 ");
428  return SCIP_OKAY;
429  }
430 
431  for( i = 0; i < nmonomials; ++i )
432  {
433  if( monomialcoefs[i] == 1.0 ) /*lint !e613*/
434  {
435  if( i > 0 )
436  SCIPinfoMessage(scip, file, " +");
437  }
438  else if( monomialcoefs[i] == -1.0 ) /*lint !e613*/
439  SCIPinfoMessage(scip, file, " -");
440  else
441  SCIPinfoMessage(scip, file, " %+.15g", monomialcoefs[i]); /*lint !e613*/
442 
443  assert(monomialvars[i] != NULL || monomialnvars[i] == 0); /*lint !e613*/
444 
445  for( v = 0; v < monomialnvars[i]; ++v ) /*lint !e613*/
446  {
447  SCIP_CALL( SCIPwriteVarName(scip, file, monomialvars[i][v], type) ); /*lint !e613*/
448  if( monomialexps != NULL && monomialexps[i] != NULL && monomialexps[i][v] != 1.0 )
449  {
450  SCIPinfoMessage(scip, file, "^%.15g", monomialexps[i][v]);
451  }
452  }
453  }
454 
455  return SCIP_OKAY;
456 }
457 
458 /** parses variable information (in cip format) out of a string; if the parsing process was successful a variable is
459  * created and captured; if variable is of integral type, fractional bounds are automatically rounded; an integer
460  * variable with bounds zero and one is automatically converted into a binary variable
461  *
462  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
463  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
464  *
465  * @pre This method can be called if @p scip is in one of the following stages:
466  * - \ref SCIP_STAGE_PROBLEM
467  * - \ref SCIP_STAGE_TRANSFORMING
468  * - \ref SCIP_STAGE_INITPRESOLVE
469  * - \ref SCIP_STAGE_PRESOLVING
470  * - \ref SCIP_STAGE_EXITPRESOLVE
471  * - \ref SCIP_STAGE_PRESOLVED
472  * - \ref SCIP_STAGE_SOLVING
473  */
475  SCIP* scip, /**< SCIP data structure */
476  SCIP_VAR** var, /**< pointer to store the problem variable */
477  const char* str, /**< string to parse */
478  SCIP_Bool initial, /**< should var's column be present in the initial root LP? */
479  SCIP_Bool removable, /**< is var's column removable from the LP (due to aging or cleanup)? */
480  SCIP_DECL_VARCOPY ((*varcopy)), /**< copies variable data if wanted to subscip, or NULL */
481  SCIP_DECL_VARDELORIG ((*vardelorig)), /**< frees user data of original variable */
482  SCIP_DECL_VARTRANS ((*vartrans)), /**< creates transformed user data by transforming original user data */
483  SCIP_DECL_VARDELTRANS ((*vardeltrans)), /**< frees user data of transformed variable */
484  SCIP_VARDATA* vardata, /**< user data for this specific variable */
485  char** endptr, /**< pointer to store the final string position if successful */
486  SCIP_Bool* success /**< pointer store if the paring process was successful */
487  )
488 {
489  assert(var != NULL);
490 
491  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVar", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
492 
493  switch( scip->set->stage )
494  {
495  case SCIP_STAGE_PROBLEM:
496  SCIP_CALL( SCIPvarParseOriginal(var, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
497  str, initial, removable, varcopy, vardelorig, vartrans, vardeltrans, vardata, endptr, success) );
498  break;
499 
505  case SCIP_STAGE_SOLVING:
506  SCIP_CALL( SCIPvarParseTransformed(var, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
507  str, initial, removable, varcopy, vardelorig, vartrans, vardeltrans, vardata, endptr, success) );
508  break;
509 
510  default:
511  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
512  return SCIP_INVALIDCALL;
513  } /*lint !e788*/
514 
515  return SCIP_OKAY;
516 }
517 
518 /** parses the given string for a variable name and stores the variable in the corresponding pointer if such a variable
519  * exits and returns the position where the parsing stopped
520  *
521  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
522  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
523  *
524  * @pre This method can be called if @p scip is in one of the following stages:
525  * - \ref SCIP_STAGE_PROBLEM
526  * - \ref SCIP_STAGE_TRANSFORMING
527  * - \ref SCIP_STAGE_INITPRESOLVE
528  * - \ref SCIP_STAGE_PRESOLVING
529  * - \ref SCIP_STAGE_EXITPRESOLVE
530  * - \ref SCIP_STAGE_PRESOLVED
531  * - \ref SCIP_STAGE_SOLVING
532  */
534  SCIP* scip, /**< SCIP data structure */
535  const char* str, /**< string to parse */
536  SCIP_VAR** var, /**< pointer to store the problem variable, or NULL if it does not exit */
537  char** endptr /**< pointer to store the final string position if successful */
538  )
539 {
540  char varname[SCIP_MAXSTRLEN];
541 
542  assert(str != NULL);
543  assert(var != NULL);
544  assert(endptr != NULL);
545 
546  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarName", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
547 
548  SCIPstrCopySection(str, '<', '>', varname, SCIP_MAXSTRLEN, endptr);
549  assert(*endptr != NULL);
550 
551  if( *varname == '\0' )
552  {
553  SCIPerrorMessage("invalid variable name string given: could not find '<'\n");
554  return SCIP_INVALIDDATA;
555  }
556 
557  /* check if we have a negated variable */
558  if( *varname == '~' )
559  {
560  SCIPdebugMsg(scip, "parsed negated variable name <%s>\n", &varname[1]);
561 
562  /* search for the variable and ignore '~' */
563  (*var) = SCIPfindVar(scip, &varname[1]);
564 
565  if( *var != NULL )
566  {
567  SCIP_CALL( SCIPgetNegatedVar(scip, *var, var) );
568  }
569  }
570  else
571  {
572  SCIPdebugMsg(scip, "parsed variable name <%s>\n", varname);
573 
574  /* search for the variable */
575  (*var) = SCIPfindVar(scip, varname);
576  }
577 
578  str = *endptr;
579 
580  /* skip additional variable type marker */
581  if( *str == '[' && (str[1] == SCIP_VARTYPE_BINARY_CHAR || str[1] == SCIP_VARTYPE_INTEGER_CHAR ||
582  str[1] == SCIP_VARTYPE_IMPLINT_CHAR || str[1] == SCIP_VARTYPE_CONTINUOUS_CHAR ) && str[2] == ']' )
583  (*endptr) += 3;
584 
585  return SCIP_OKAY;
586 }
587 
588 /** parse the given string as variable list (here ',' is the delimiter)) (<x1>, <x2>, ..., <xn>) (see
589  * SCIPwriteVarsList() ); if it was successful, the pointer success is set to TRUE
590  *
591  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
592  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
593  *
594  * @pre This method can be called if @p scip is in one of the following stages:
595  * - \ref SCIP_STAGE_PROBLEM
596  * - \ref SCIP_STAGE_TRANSFORMING
597  * - \ref SCIP_STAGE_INITPRESOLVE
598  * - \ref SCIP_STAGE_PRESOLVING
599  * - \ref SCIP_STAGE_EXITPRESOLVE
600  * - \ref SCIP_STAGE_PRESOLVED
601  * - \ref SCIP_STAGE_SOLVING
602  *
603  * @note The pointer success in only set to FALSE in the case that a variable with a parsed variable name does not exist.
604  *
605  * @note If the number of (parsed) variables is greater than the available slots in the variable array, nothing happens
606  * except that the required size is stored in the corresponding integer; the reason for this approach is that we
607  * cannot reallocate memory, since we do not know how the memory has been allocated (e.g., by a C++ 'new' or SCIP
608  * memory functions).
609  */
611  SCIP* scip, /**< SCIP data structure */
612  const char* str, /**< string to parse */
613  SCIP_VAR** vars, /**< array to store the parsed variable */
614  int* nvars, /**< pointer to store number of parsed variables */
615  int varssize, /**< size of the variable array */
616  int* requiredsize, /**< pointer to store the required array size for the active variables */
617  char** endptr, /**< pointer to store the final string position if successful */
618  char delimiter, /**< character which is used for delimitation */
619  SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
620  )
621 {
622  SCIP_VAR** tmpvars;
623  SCIP_VAR* var;
624  int ntmpvars = 0;
625  int v;
626 
627  assert( nvars != NULL );
628  assert( requiredsize != NULL );
629  assert( endptr != NULL );
630  assert( success != NULL );
631 
632  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsList", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
633 
634  /* allocate buffer memory for temporary storing the parsed variables */
635  SCIP_CALL( SCIPallocBufferArray(scip, &tmpvars, varssize) );
636 
637  (*success) = TRUE;
638 
639  do
640  {
641  *endptr = (char*)str;
642 
643  /* parse variable name */
644  SCIP_CALL( SCIPparseVarName(scip, str, &var, endptr) );
645 
646  if( var == NULL )
647  {
648  SCIPdebugMsg(scip, "variable with name <%s> does not exist\n", SCIPvarGetName(var));
649  (*success) = FALSE;
650  break;
651  }
652 
653  /* store the variable in the tmp array */
654  if( ntmpvars < varssize )
655  tmpvars[ntmpvars] = var;
656 
657  ntmpvars++;
658 
659  str = *endptr;
660 
661  while( isspace((unsigned char)*str) )
662  str++;
663  }
664  while( *str == delimiter );
665 
666  *endptr = (char*)str;
667 
668  /* if all variable name searches were successful and the variable array has enough slots, copy the collected variables */
669  if( (*success) && ntmpvars <= varssize )
670  {
671  for( v = 0; v < ntmpvars; ++v )
672  vars[v] = tmpvars[v];
673 
674  (*nvars) = ntmpvars;
675  }
676  else
677  (*nvars) = 0;
678 
679  (*requiredsize) = ntmpvars;
680 
681  /* free buffer arrays */
682  SCIPfreeBufferArray(scip, &tmpvars);
683 
684  return SCIP_OKAY;
685 }
686 
687 /** parse the given string as linear sum of variables and coefficients (c1 <x1> + c2 <x2> + ... + cn <xn>)
688  * (see SCIPwriteVarsLinearsum() ); if it was successful, the pointer success is set to TRUE
689  *
690  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
691  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
692  *
693  * @pre This method can be called if @p scip is in one of the following stages:
694  * - \ref SCIP_STAGE_PROBLEM
695  * - \ref SCIP_STAGE_TRANSFORMING
696  * - \ref SCIP_STAGE_INITPRESOLVE
697  * - \ref SCIP_STAGE_PRESOLVING
698  * - \ref SCIP_STAGE_EXITPRESOLVE
699  * - \ref SCIP_STAGE_PRESOLVED
700  * - \ref SCIP_STAGE_SOLVING
701  *
702  * @note The pointer success in only set to FALSE in the case that a variable with a parsed variable name does not exist.
703  *
704  * @note If the number of (parsed) variables is greater than the available slots in the variable array, nothing happens
705  * except that the required size is stored in the corresponding integer; the reason for this approach is that we
706  * cannot reallocate memory, since we do not know how the memory has been allocated (e.g., by a C++ 'new' or SCIP
707  * memory functions).
708  */
710  SCIP* scip, /**< SCIP data structure */
711  const char* str, /**< string to parse */
712  SCIP_VAR** vars, /**< array to store the parsed variables */
713  SCIP_Real* vals, /**< array to store the parsed coefficients */
714  int* nvars, /**< pointer to store number of parsed variables */
715  int varssize, /**< size of the variable array */
716  int* requiredsize, /**< pointer to store the required array size for the active variables */
717  char** endptr, /**< pointer to store the final string position if successful */
718  SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
719  )
720 {
721  SCIP_VAR*** monomialvars;
722  SCIP_Real** monomialexps;
723  SCIP_Real* monomialcoefs;
724  int* monomialnvars;
725  int nmonomials;
726 
727  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsLinearsum", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
728 
729  assert(scip != NULL);
730  assert(str != NULL);
731  assert(vars != NULL || varssize == 0);
732  assert(vals != NULL || varssize == 0);
733  assert(nvars != NULL);
734  assert(requiredsize != NULL);
735  assert(endptr != NULL);
736  assert(success != NULL);
737 
738  *requiredsize = 0;
739 
740  SCIP_CALL( SCIPparseVarsPolynomial(scip, str, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, &nmonomials, endptr, success) );
741 
742  if( !*success )
743  {
744  assert(nmonomials == 0); /* SCIPparseVarsPolynomial should have freed all buffers, so no need to call free here */
745  return SCIP_OKAY;
746  }
747 
748  /* check if linear sum is just "0" */
749  if( nmonomials == 1 && monomialnvars[0] == 0 && monomialcoefs[0] == 0.0 )
750  {
751  *nvars = 0;
752  *requiredsize = 0;
753 
754  SCIPfreeParseVarsPolynomialData(scip, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, nmonomials);
755 
756  return SCIP_OKAY;
757  }
758 
759  *nvars = nmonomials;
760  *requiredsize = nmonomials;
761 
762  /* if we have enough slots in the variables array, copy variables over */
763  if( varssize >= nmonomials )
764  {
765  int v;
766 
767  for( v = 0; v < nmonomials; ++v )
768  {
769  if( monomialnvars[v] == 0 )
770  {
771  SCIPerrorMessage("constant in linear sum\n");
772  *success = FALSE;
773  break;
774  }
775  if( monomialnvars[v] > 1 || monomialexps[v][0] != 1.0 )
776  {
777  SCIPerrorMessage("nonlinear monomial in linear sum\n");
778  *success = FALSE;
779  break;
780  }
781  assert(monomialnvars[v] == 1);
782  assert(monomialvars[v][0] != NULL);
783  assert(monomialexps[v][0] == 1.0);
784 
785  vars[v] = monomialvars[v][0]; /*lint !e613*/
786  vals[v] = monomialcoefs[v]; /*lint !e613*/
787  }
788  }
789 
790  SCIPfreeParseVarsPolynomialData(scip, &monomialvars, &monomialexps, &monomialcoefs, &monomialnvars, nmonomials);
791 
792  return SCIP_OKAY;
793 }
794 
795 /** parse the given string as signomial of variables and coefficients
796  * (c1 <x11>^e11 <x12>^e12 ... <x1n>^e1n + c2 <x21>^e21 <x22>^e22 ... + ... + cn <xn1>^en1 ...)
797  * (see SCIPwriteVarsPolynomial()); if it was successful, the pointer success is set to TRUE
798  *
799  * The user has to call SCIPfreeParseVarsPolynomialData(scip, monomialvars, monomialexps,
800  * monomialcoefs, monomialnvars, *nmonomials) short after SCIPparseVarsPolynomial to free all the
801  * allocated memory again.
802  *
803  * Parsing is stopped at the end of string (indicated by the \\0-character) or when no more monomials
804  * are recognized.
805  *
806  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
807  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
808  *
809  * @pre This method can be called if @p scip is in one of the following stages:
810  * - \ref SCIP_STAGE_PROBLEM
811  * - \ref SCIP_STAGE_TRANSFORMING
812  * - \ref SCIP_STAGE_INITPRESOLVE
813  * - \ref SCIP_STAGE_PRESOLVING
814  * - \ref SCIP_STAGE_EXITPRESOLVE
815  * - \ref SCIP_STAGE_PRESOLVED
816  * - \ref SCIP_STAGE_SOLVING
817  */
819  SCIP* scip, /**< SCIP data structure */
820  const char* str, /**< string to parse */
821  SCIP_VAR**** monomialvars, /**< pointer to store arrays with variables for each monomial */
822  SCIP_Real*** monomialexps, /**< pointer to store arrays with variable exponents */
823  SCIP_Real** monomialcoefs, /**< pointer to store array with monomial coefficients */
824  int** monomialnvars, /**< pointer to store array with number of variables for each monomial */
825  int* nmonomials, /**< pointer to store number of parsed monomials */
826  char** endptr, /**< pointer to store the final string position if successful */
827  SCIP_Bool* success /**< pointer to store the whether the parsing was successful or not */
828  )
829 {
830  typedef enum
831  {
832  SCIPPARSEPOLYNOMIAL_STATE_BEGIN, /* we are at the beginning of a monomial */
833  SCIPPARSEPOLYNOMIAL_STATE_INTERMED, /* we are in between the factors of a monomial */
834  SCIPPARSEPOLYNOMIAL_STATE_COEF, /* we parse the coefficient of a monomial */
835  SCIPPARSEPOLYNOMIAL_STATE_VARS, /* we parse monomial variables */
836  SCIPPARSEPOLYNOMIAL_STATE_EXPONENT, /* we parse the exponent of a variable */
837  SCIPPARSEPOLYNOMIAL_STATE_END, /* we are at the end the polynomial */
838  SCIPPARSEPOLYNOMIAL_STATE_ERROR /* a parsing error occured */
839  } SCIPPARSEPOLYNOMIAL_STATES;
840 
841  SCIPPARSEPOLYNOMIAL_STATES state;
842  int monomialssize;
843 
844  /* data of currently parsed monomial */
845  int varssize;
846  int nvars;
847  SCIP_VAR** vars;
848  SCIP_Real* exponents;
849  SCIP_Real coef;
850 
851  assert(scip != NULL);
852  assert(str != NULL);
853  assert(monomialvars != NULL);
854  assert(monomialexps != NULL);
855  assert(monomialnvars != NULL);
856  assert(monomialcoefs != NULL);
857  assert(nmonomials != NULL);
858  assert(endptr != NULL);
859  assert(success != NULL);
860 
861  SCIP_CALL( SCIPcheckStage(scip, "SCIPparseVarsPolynomial", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
862 
863  *success = FALSE;
864  *nmonomials = 0;
865  monomialssize = 0;
866  *monomialvars = NULL;
867  *monomialexps = NULL;
868  *monomialcoefs = NULL;
869  *monomialnvars = NULL;
870 
871  /* initialize state machine */
872  state = SCIPPARSEPOLYNOMIAL_STATE_BEGIN;
873  varssize = 0;
874  nvars = 0;
875  vars = NULL;
876  exponents = NULL;
877  coef = SCIP_INVALID;
878 
879  SCIPdebugMsg(scip, "parsing polynomial from '%s'\n", str);
880 
881  while( *str && state != SCIPPARSEPOLYNOMIAL_STATE_END && state != SCIPPARSEPOLYNOMIAL_STATE_ERROR )
882  {
883  /* skip white space */
884  while( isspace((unsigned char)*str) )
885  str++;
886 
887  assert(state != SCIPPARSEPOLYNOMIAL_STATE_END);
888 
889  switch( state )
890  {
891  case SCIPPARSEPOLYNOMIAL_STATE_BEGIN:
892  {
893  if( coef != SCIP_INVALID ) /*lint !e777*/
894  {
895  SCIPdebugMsg(scip, "push monomial with coefficient <%g> and <%d> vars\n", coef, nvars);
896 
897  /* push previous monomial */
898  if( monomialssize <= *nmonomials )
899  {
900  monomialssize = SCIPcalcMemGrowSize(scip, *nmonomials+1);
901 
902  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, *nmonomials, monomialssize) );
903  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, *nmonomials, monomialssize) );
904  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, *nmonomials, monomialssize) );
905  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, *nmonomials, monomialssize) );
906  }
907 
908  if( nvars > 0 )
909  {
910  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*monomialvars)[*nmonomials], vars, nvars) ); /*lint !e866*/
911  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*monomialexps)[*nmonomials], exponents, nvars) ); /*lint !e866*/
912  }
913  else
914  {
915  (*monomialvars)[*nmonomials] = NULL;
916  (*monomialexps)[*nmonomials] = NULL;
917  }
918  (*monomialcoefs)[*nmonomials] = coef;
919  (*monomialnvars)[*nmonomials] = nvars;
920  ++*nmonomials;
921 
922  nvars = 0;
923  coef = SCIP_INVALID;
924  }
925 
926  if( *str == '<' )
927  {
928  /* there seem to come a variable at the beginning of a monomial
929  * so assume the coefficient is 1.0
930  */
931  state = SCIPPARSEPOLYNOMIAL_STATE_VARS;
932  coef = 1.0;
933  }
934  else if( *str == '-' || *str == '+' || isdigit(*str) )
935  state = SCIPPARSEPOLYNOMIAL_STATE_COEF;
936  else
937  state = SCIPPARSEPOLYNOMIAL_STATE_END;
938 
939  break;
940  }
941 
942  case SCIPPARSEPOLYNOMIAL_STATE_INTERMED:
943  {
944  if( *str == '<' )
945  {
946  /* there seem to come another variable */
947  state = SCIPPARSEPOLYNOMIAL_STATE_VARS;
948  }
949  else if( *str == '-' || *str == '+' || isdigit(*str) )
950  {
951  /* there seem to come a coefficient, which means the next monomial */
952  state = SCIPPARSEPOLYNOMIAL_STATE_BEGIN;
953  }
954  else /* since we cannot detect the symbols we stop parsing the polynomial */
955  state = SCIPPARSEPOLYNOMIAL_STATE_END;
956 
957  break;
958  }
959 
960  case SCIPPARSEPOLYNOMIAL_STATE_COEF:
961  {
962  if( *str == '+' && !isdigit(str[1]) )
963  {
964  /* only a plus sign, without number */
965  coef = 1.0;
966  ++str;
967  }
968  else if( *str == '-' && !isdigit(str[1]) )
969  {
970  /* only a minus sign, without number */
971  coef = -1.0;
972  ++str;
973  }
974  else if( SCIPstrToRealValue(str, &coef, endptr) )
975  {
976  str = *endptr;
977  }
978  else
979  {
980  SCIPerrorMessage("could not parse number in the beginning of '%s'\n", str);
981  state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
982  break;
983  }
984 
985  /* after the coefficient we go into the intermediate state, i.e., expecting next variables */
986  state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED; /*lint !e838*/
987 
988  break;
989  }
990 
991  case SCIPPARSEPOLYNOMIAL_STATE_VARS:
992  {
993  SCIP_VAR* var;
994 
995  assert(*str == '<');
996 
997  /* parse variable name */
998  SCIP_CALL( SCIPparseVarName(scip, str, &var, endptr) );
999 
1000  /* check if variable name was parsed */
1001  if( *endptr == str )
1002  {
1003  state = SCIPPARSEPOLYNOMIAL_STATE_END;
1004  break;
1005  }
1006 
1007  if( var == NULL )
1008  {
1009  SCIPerrorMessage("did not find variable in the beginning of %s\n", str);
1010  state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
1011  break;
1012  }
1013 
1014  /* add variable to vars array */
1015  if( nvars + 1 > varssize )
1016  {
1017  varssize = SCIPcalcMemGrowSize(scip, nvars+1);
1018  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &vars, nvars, varssize) );
1019  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &exponents, nvars, varssize) );
1020  }
1021  assert(vars != NULL);
1022  assert(exponents != NULL);
1023 
1024  vars[nvars] = var;
1025  exponents[nvars] = 1.0;
1026  ++nvars;
1027 
1028  str = *endptr;
1029 
1030  if( *str == '^' )
1031  state = SCIPPARSEPOLYNOMIAL_STATE_EXPONENT;
1032  else
1033  state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED;
1034 
1035  break;
1036  }
1037 
1038  case SCIPPARSEPOLYNOMIAL_STATE_EXPONENT:
1039  {
1040  assert(*str == '^');
1041  assert(nvars > 0); /* we should be in a monomial that has already a variable */
1042  assert(exponents != NULL);
1043  ++str;
1044 
1045  if( !SCIPstrToRealValue(str, &exponents[nvars-1], endptr) )
1046  {
1047  SCIPerrorMessage("could not parse number in the beginning of '%s'\n", str);
1048  state = SCIPPARSEPOLYNOMIAL_STATE_ERROR;
1049  break;
1050  }
1051  str = *endptr;
1052 
1053  /* after the exponent we go into the intermediate state, i.e., expecting next variables */
1054  state = SCIPPARSEPOLYNOMIAL_STATE_INTERMED; /*lint !e838*/
1055  break;
1056  }
1057 
1058  case SCIPPARSEPOLYNOMIAL_STATE_END:
1059  case SCIPPARSEPOLYNOMIAL_STATE_ERROR:
1060  default:
1061  SCIPerrorMessage("unexpected state\n");
1062  return SCIP_READERROR;
1063  }
1064  }
1065 
1066  /* set end pointer */
1067  *endptr = (char*)str;
1068 
1069  /* check state at end of string */
1070  switch( state )
1071  {
1072  case SCIPPARSEPOLYNOMIAL_STATE_BEGIN:
1073  case SCIPPARSEPOLYNOMIAL_STATE_END:
1074  case SCIPPARSEPOLYNOMIAL_STATE_INTERMED:
1075  {
1076  if( coef != SCIP_INVALID ) /*lint !e777*/
1077  {
1078  /* push last monomial */
1079  SCIPdebugMsg(scip, "push monomial with coefficient <%g> and <%d> vars\n", coef, nvars);
1080  if( monomialssize <= *nmonomials )
1081  {
1082  monomialssize = *nmonomials+1;
1083  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, *nmonomials, monomialssize) );
1084  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, *nmonomials, monomialssize) );
1085  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, *nmonomials, monomialssize) );
1086  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, *nmonomials, monomialssize) );
1087  }
1088 
1089  if( nvars > 0 )
1090  {
1091  /* shrink vars and exponents array to needed size and take over ownership */
1092  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &vars, varssize, nvars) );
1093  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &exponents, varssize, nvars) );
1094  (*monomialvars)[*nmonomials] = vars;
1095  (*monomialexps)[*nmonomials] = exponents;
1096  vars = NULL;
1097  exponents = NULL;
1098  }
1099  else
1100  {
1101  (*monomialvars)[*nmonomials] = NULL;
1102  (*monomialexps)[*nmonomials] = NULL;
1103  }
1104  (*monomialcoefs)[*nmonomials] = coef;
1105  (*monomialnvars)[*nmonomials] = nvars;
1106  ++*nmonomials;
1107  }
1108 
1109  *success = TRUE;
1110  break;
1111  }
1112 
1113  case SCIPPARSEPOLYNOMIAL_STATE_COEF:
1114  case SCIPPARSEPOLYNOMIAL_STATE_VARS:
1115  case SCIPPARSEPOLYNOMIAL_STATE_EXPONENT:
1116  {
1117  SCIPerrorMessage("unexpected parsing state at end of polynomial string\n");
1118  }
1119  /*lint -fallthrough*/
1120  case SCIPPARSEPOLYNOMIAL_STATE_ERROR:
1121  assert(!*success);
1122  break;
1123  }
1124 
1125  /* free memory to store current monomial, if still existing */
1126  SCIPfreeBlockMemoryArrayNull(scip, &vars, varssize);
1127  SCIPfreeBlockMemoryArrayNull(scip, &exponents, varssize);
1128 
1129  if( *success && *nmonomials > 0 )
1130  {
1131  /* shrink arrays to required size, so we do not need to keep monomialssize around */
1132  assert(*nmonomials <= monomialssize);
1133  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialvars, monomialssize, *nmonomials) );
1134  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialexps, monomialssize, *nmonomials) );
1135  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialnvars, monomialssize, *nmonomials) );
1136  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, monomialcoefs, monomialssize, *nmonomials) );
1137 
1138  /* SCIPwriteVarsPolynomial(scip, NULL, *monomialvars, *monomialexps, *monomialcoefs, *monomialnvars, *nmonomials, FALSE); */
1139  }
1140  else
1141  {
1142  /* in case of error, cleanup all data here */
1143  SCIPfreeParseVarsPolynomialData(scip, monomialvars, monomialexps, monomialcoefs, monomialnvars, *nmonomials);
1144  *nmonomials = 0;
1145  }
1146 
1147  return SCIP_OKAY;
1148 }
1149 
1150 /** frees memory allocated when parsing a signomial from a string
1151  *
1152  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1153  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1154  *
1155  * @pre This method can be called if @p scip is in one of the following stages:
1156  * - \ref SCIP_STAGE_PROBLEM
1157  * - \ref SCIP_STAGE_TRANSFORMING
1158  * - \ref SCIP_STAGE_INITPRESOLVE
1159  * - \ref SCIP_STAGE_PRESOLVING
1160  * - \ref SCIP_STAGE_EXITPRESOLVE
1161  * - \ref SCIP_STAGE_PRESOLVED
1162  * - \ref SCIP_STAGE_SOLVING
1163  */
1165  SCIP* scip, /**< SCIP data structure */
1166  SCIP_VAR**** monomialvars, /**< pointer to store arrays with variables for each monomial */
1167  SCIP_Real*** monomialexps, /**< pointer to store arrays with variable exponents */
1168  SCIP_Real** monomialcoefs, /**< pointer to store array with monomial coefficients */
1169  int** monomialnvars, /**< pointer to store array with number of variables for each monomial */
1170  int nmonomials /**< pointer to store number of parsed monomials */
1171  )
1172 {
1173  int i;
1174 
1175  assert(scip != NULL);
1176  assert(monomialvars != NULL);
1177  assert(monomialexps != NULL);
1178  assert(monomialcoefs != NULL);
1179  assert(monomialnvars != NULL);
1180  assert((*monomialvars != NULL) == (nmonomials > 0));
1181  assert((*monomialexps != NULL) == (nmonomials > 0));
1182  assert((*monomialcoefs != NULL) == (nmonomials > 0));
1183  assert((*monomialnvars != NULL) == (nmonomials > 0));
1184 
1185  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPfreeParseVarsPolynomialData", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1186 
1187  if( nmonomials == 0 )
1188  return;
1189 
1190  for( i = nmonomials - 1; i >= 0; --i )
1191  {
1192  SCIPfreeBlockMemoryArrayNull(scip, &(*monomialexps)[i], (*monomialnvars)[i]);
1193  SCIPfreeBlockMemoryArrayNull(scip, &(*monomialvars)[i], (*monomialnvars)[i]);
1194  }
1195 
1196  SCIPfreeBlockMemoryArray(scip, monomialcoefs, nmonomials);
1197  SCIPfreeBlockMemoryArray(scip, monomialnvars, nmonomials);
1198  SCIPfreeBlockMemoryArray(scip, monomialexps, nmonomials);
1199  SCIPfreeBlockMemoryArray(scip, monomialvars, nmonomials);
1200 }
1201 
1202 /** increases usage counter of variable
1203  *
1204  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1205  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1206  *
1207  * @pre This method can be called if @p scip is in one of the following stages:
1208  * - \ref SCIP_STAGE_PROBLEM
1209  * - \ref SCIP_STAGE_TRANSFORMING
1210  * - \ref SCIP_STAGE_TRANSFORMED
1211  * - \ref SCIP_STAGE_INITPRESOLVE
1212  * - \ref SCIP_STAGE_PRESOLVING
1213  * - \ref SCIP_STAGE_EXITPRESOLVE
1214  * - \ref SCIP_STAGE_PRESOLVED
1215  * - \ref SCIP_STAGE_INITSOLVE
1216  * - \ref SCIP_STAGE_SOLVING
1217  * - \ref SCIP_STAGE_SOLVED
1218  * - \ref SCIP_STAGE_EXITSOLVE
1219  */
1221  SCIP* scip, /**< SCIP data structure */
1222  SCIP_VAR* var /**< variable to capture */
1223  )
1224 {
1225  SCIP_CALL( SCIPcheckStage(scip, "SCIPcaptureVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1226  assert(var->scip == scip);
1227 
1228  SCIPvarCapture(var);
1229 
1230  return SCIP_OKAY;
1231 }
1232 
1233 /** decreases usage counter of variable, if the usage pointer reaches zero the variable gets freed
1234  *
1235  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1236  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1237  *
1238  * @pre This method can be called if @p scip is in one of the following stages:
1239  * - \ref SCIP_STAGE_PROBLEM
1240  * - \ref SCIP_STAGE_TRANSFORMING
1241  * - \ref SCIP_STAGE_TRANSFORMED
1242  * - \ref SCIP_STAGE_INITPRESOLVE
1243  * - \ref SCIP_STAGE_PRESOLVING
1244  * - \ref SCIP_STAGE_EXITPRESOLVE
1245  * - \ref SCIP_STAGE_PRESOLVED
1246  * - \ref SCIP_STAGE_INITSOLVE
1247  * - \ref SCIP_STAGE_SOLVING
1248  * - \ref SCIP_STAGE_SOLVED
1249  * - \ref SCIP_STAGE_EXITSOLVE
1250  * - \ref SCIP_STAGE_FREETRANS
1251  *
1252  * @note the pointer of the variable will be NULLed
1253  */
1255  SCIP* scip, /**< SCIP data structure */
1256  SCIP_VAR** var /**< pointer to variable */
1257  )
1258 {
1259  assert(var != NULL);
1260  assert(*var != NULL);
1261  assert((*var)->scip == scip);
1262 
1263  SCIP_CALL( SCIPcheckStage(scip, "SCIPreleaseVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1264 
1265  switch( scip->set->stage )
1266  {
1267  case SCIP_STAGE_PROBLEM:
1268  SCIP_CALL( SCIPvarRelease(var, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp) );
1269  return SCIP_OKAY;
1270 
1274  case SCIP_STAGE_PRESOLVING:
1276  case SCIP_STAGE_PRESOLVED:
1277  case SCIP_STAGE_INITSOLVE:
1278  case SCIP_STAGE_SOLVING:
1279  case SCIP_STAGE_SOLVED:
1280  case SCIP_STAGE_EXITSOLVE:
1281  case SCIP_STAGE_FREETRANS:
1282  if( !SCIPvarIsTransformed(*var) && (*var)->nuses == 1 && (*var)->data.original.transvar != NULL )
1283  {
1284  SCIPerrorMessage("cannot release last use of original variable while associated transformed variable exists\n");
1285  return SCIP_INVALIDCALL;
1286  }
1287  SCIP_CALL( SCIPvarRelease(var, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp) );
1288  return SCIP_OKAY;
1289 
1290  default:
1291  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
1292  return SCIP_INVALIDCALL;
1293  } /*lint !e788*/
1294 }
1295 
1296 /** changes the name of a variable
1297  *
1298  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1299  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1300  *
1301  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PROBLEM
1302  *
1303  * @note to get the current name of a variable, use SCIPvarGetName() from pub_var.h
1304  */
1306  SCIP* scip, /**< SCIP data structure */
1307  SCIP_VAR* var, /**< variable */
1308  const char* name /**< new name of constraint */
1309  )
1310 {
1311  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarName", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
1312  assert( var->scip == scip );
1313 
1314  if( SCIPgetStage(scip) != SCIP_STAGE_PROBLEM )
1315  {
1316  SCIPerrorMessage("variable names can only be changed in problem creation stage\n");
1317  SCIPABORT();
1318  return SCIP_INVALIDCALL; /*lint !e527*/
1319  }
1320 
1321  /* remove variable's name from the namespace if the variable was already added */
1322  if( SCIPvarGetProbindex(var) != -1 )
1323  {
1324  SCIP_CALL( SCIPprobRemoveVarName(scip->origprob, var) );
1325  }
1326 
1327  /* change variable name */
1328  SCIP_CALL( SCIPvarChgName(var, SCIPblkmem(scip), name) );
1329 
1330  /* add variable's name to the namespace if the variable was already added */
1331  if( SCIPvarGetProbindex(var) != -1 )
1332  {
1333  SCIP_CALL( SCIPprobAddVarName(scip->origprob, var) );
1334  }
1335 
1336  return SCIP_OKAY;
1337 }
1338 
1339 /** gets and captures transformed variable of a given variable; if the variable is not yet transformed,
1340  * a new transformed variable for this variable is created
1341  *
1342  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1343  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1344  *
1345  * @pre This method can be called if @p scip is in one of the following stages:
1346  * - \ref SCIP_STAGE_TRANSFORMING
1347  * - \ref SCIP_STAGE_TRANSFORMED
1348  * - \ref SCIP_STAGE_INITPRESOLVE
1349  * - \ref SCIP_STAGE_PRESOLVING
1350  * - \ref SCIP_STAGE_EXITPRESOLVE
1351  * - \ref SCIP_STAGE_PRESOLVED
1352  * - \ref SCIP_STAGE_INITSOLVE
1353  * - \ref SCIP_STAGE_SOLVING
1354  */
1356  SCIP* scip, /**< SCIP data structure */
1357  SCIP_VAR* var, /**< variable to get/create transformed variable for */
1358  SCIP_VAR** transvar /**< pointer to store the transformed variable */
1359  )
1360 {
1361  assert(transvar != NULL);
1362 
1363  SCIP_CALL( SCIPcheckStage(scip, "SCIPtransformVar", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1364 
1365  if( SCIPvarIsTransformed(var) )
1366  {
1367  *transvar = var;
1368  SCIPvarCapture(*transvar);
1369  }
1370  else
1371  {
1372  SCIP_CALL( SCIPvarTransform(var, scip->mem->probmem, scip->set, scip->stat, scip->origprob->objsense, transvar) );
1373  }
1374 
1375  return SCIP_OKAY;
1376 }
1377 
1378 /** gets and captures transformed variables for an array of variables;
1379  * if a variable of the array is not yet transformed, a new transformed variable for this variable is created;
1380  * it is possible to call this method with vars == transvars
1381  *
1382  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1383  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1384  *
1385  * @pre This method can be called if @p scip is in one of the following stages:
1386  * - \ref SCIP_STAGE_TRANSFORMING
1387  * - \ref SCIP_STAGE_TRANSFORMED
1388  * - \ref SCIP_STAGE_INITPRESOLVE
1389  * - \ref SCIP_STAGE_PRESOLVING
1390  * - \ref SCIP_STAGE_EXITPRESOLVE
1391  * - \ref SCIP_STAGE_PRESOLVED
1392  * - \ref SCIP_STAGE_INITSOLVE
1393  * - \ref SCIP_STAGE_SOLVING
1394  */
1396  SCIP* scip, /**< SCIP data structure */
1397  int nvars, /**< number of variables to get/create transformed variables for */
1398  SCIP_VAR** vars, /**< array with variables to get/create transformed variables for */
1399  SCIP_VAR** transvars /**< array to store the transformed variables */
1400  )
1401 {
1402  int v;
1403 
1404  assert(nvars == 0 || vars != NULL);
1405  assert(nvars == 0 || transvars != NULL);
1406 
1407  SCIP_CALL( SCIPcheckStage(scip, "SCIPtransformVars", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1408 
1409  for( v = 0; v < nvars; ++v )
1410  {
1411  if( SCIPvarIsTransformed(vars[v]) )
1412  {
1413  transvars[v] = vars[v];
1414  SCIPvarCapture(transvars[v]);
1415  }
1416  else
1417  {
1418  SCIP_CALL( SCIPvarTransform(vars[v], scip->mem->probmem, scip->set, scip->stat, scip->origprob->objsense,
1419  &transvars[v]) );
1420  }
1421  }
1422 
1423  return SCIP_OKAY;
1424 }
1425 
1426 /** gets corresponding transformed variable of a given variable;
1427  * returns NULL as transvar, if transformed variable is not yet existing
1428  *
1429  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1430  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1431  *
1432  * @pre This method can be called if @p scip is in one of the following stages:
1433  * - \ref SCIP_STAGE_TRANSFORMING
1434  * - \ref SCIP_STAGE_TRANSFORMED
1435  * - \ref SCIP_STAGE_INITPRESOLVE
1436  * - \ref SCIP_STAGE_PRESOLVING
1437  * - \ref SCIP_STAGE_EXITPRESOLVE
1438  * - \ref SCIP_STAGE_PRESOLVED
1439  * - \ref SCIP_STAGE_INITSOLVE
1440  * - \ref SCIP_STAGE_SOLVING
1441  * - \ref SCIP_STAGE_SOLVED
1442  * - \ref SCIP_STAGE_EXITSOLVE
1443  * - \ref SCIP_STAGE_FREETRANS
1444  */
1446  SCIP* scip, /**< SCIP data structure */
1447  SCIP_VAR* var, /**< variable to get transformed variable for */
1448  SCIP_VAR** transvar /**< pointer to store the transformed variable */
1449  )
1450 {
1451  assert(transvar != NULL);
1452 
1453  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetTransformedVar", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1454 
1455  if( SCIPvarIsTransformed(var) )
1456  *transvar = var;
1457  else
1458  {
1459  SCIP_CALL( SCIPvarGetTransformed(var, scip->mem->probmem, scip->set, scip->stat, transvar) );
1460  }
1461 
1462  return SCIP_OKAY;
1463 }
1464 
1465 /** gets corresponding transformed variables for an array of variables;
1466  * stores NULL in a transvars slot, if the transformed variable is not yet existing;
1467  * it is possible to call this method with vars == transvars, but remember that variables that are not
1468  * yet transformed will be replaced with NULL
1469  *
1470  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1471  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1472  *
1473  * @pre This method can be called if @p scip is in one of the following stages:
1474  * - \ref SCIP_STAGE_TRANSFORMING
1475  * - \ref SCIP_STAGE_TRANSFORMED
1476  * - \ref SCIP_STAGE_INITPRESOLVE
1477  * - \ref SCIP_STAGE_PRESOLVING
1478  * - \ref SCIP_STAGE_EXITPRESOLVE
1479  * - \ref SCIP_STAGE_PRESOLVED
1480  * - \ref SCIP_STAGE_INITSOLVE
1481  * - \ref SCIP_STAGE_SOLVING
1482  * - \ref SCIP_STAGE_SOLVED
1483  * - \ref SCIP_STAGE_EXITSOLVE
1484  * - \ref SCIP_STAGE_FREETRANS
1485  */
1487  SCIP* scip, /**< SCIP data structure */
1488  int nvars, /**< number of variables to get transformed variables for */
1489  SCIP_VAR** vars, /**< array with variables to get transformed variables for */
1490  SCIP_VAR** transvars /**< array to store the transformed variables */
1491  )
1492 {
1493  int v;
1494 
1495  assert(nvars == 0 || vars != NULL);
1496  assert(nvars == 0 || transvars != NULL);
1497 
1498  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetTransformedVars", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1499 
1500  for( v = 0; v < nvars; ++v )
1501  {
1502  if( SCIPvarIsTransformed(vars[v]) )
1503  transvars[v] = vars[v];
1504  else
1505  {
1506  SCIP_CALL( SCIPvarGetTransformed(vars[v], scip->mem->probmem, scip->set, scip->stat, &transvars[v]) );
1507  }
1508  }
1509 
1510  return SCIP_OKAY;
1511 }
1512 
1513 /** gets negated variable x' = lb + ub - x of variable x; negated variable is created, if not yet existing;
1514  * in difference to \ref SCIPcreateVar, the negated variable must not be released (unless captured explicitly)
1515  *
1516  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1517  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1518  *
1519  * @pre This method can be called if @p scip is in one of the following stages:
1520  * - \ref SCIP_STAGE_PROBLEM
1521  * - \ref SCIP_STAGE_TRANSFORMING
1522  * - \ref SCIP_STAGE_TRANSFORMED
1523  * - \ref SCIP_STAGE_INITPRESOLVE
1524  * - \ref SCIP_STAGE_PRESOLVING
1525  * - \ref SCIP_STAGE_EXITPRESOLVE
1526  * - \ref SCIP_STAGE_PRESOLVED
1527  * - \ref SCIP_STAGE_INITSOLVE
1528  * - \ref SCIP_STAGE_SOLVING
1529  * - \ref SCIP_STAGE_SOLVED
1530  * - \ref SCIP_STAGE_EXITSOLVE
1531  * - \ref SCIP_STAGE_FREETRANS
1532  */
1534  SCIP* scip, /**< SCIP data structure */
1535  SCIP_VAR* var, /**< variable to get negated variable for */
1536  SCIP_VAR** negvar /**< pointer to store the negated variable */
1537  )
1538 {
1539  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNegatedVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1540  assert( var->scip == scip );
1541 
1542  SCIP_CALL( SCIPvarNegate(var, scip->mem->probmem, scip->set, scip->stat, negvar) );
1543 
1544  return SCIP_OKAY;
1545 }
1546 
1547 /** gets negated variables x' = lb + ub - x of variables x; negated variables are created, if not yet existing
1548  *
1549  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1550  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1551  *
1552  * @pre This method can be called if @p scip is in one of the following stages:
1553  * - \ref SCIP_STAGE_PROBLEM
1554  * - \ref SCIP_STAGE_TRANSFORMING
1555  * - \ref SCIP_STAGE_TRANSFORMED
1556  * - \ref SCIP_STAGE_INITPRESOLVE
1557  * - \ref SCIP_STAGE_PRESOLVING
1558  * - \ref SCIP_STAGE_EXITPRESOLVE
1559  * - \ref SCIP_STAGE_PRESOLVED
1560  * - \ref SCIP_STAGE_INITSOLVE
1561  * - \ref SCIP_STAGE_SOLVING
1562  * - \ref SCIP_STAGE_SOLVED
1563  * - \ref SCIP_STAGE_EXITSOLVE
1564  * - \ref SCIP_STAGE_FREETRANS
1565  */
1567  SCIP* scip, /**< SCIP data structure */
1568  int nvars, /**< number of variables to get negated variables for */
1569  SCIP_VAR** vars, /**< array of variables to get negated variables for */
1570  SCIP_VAR** negvars /**< array to store the negated variables */
1571  )
1572 {
1573  int v;
1574 
1575  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNegatedVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1576 
1577  for( v = 0; v < nvars; ++v )
1578  {
1579  SCIP_CALL( SCIPvarNegate(vars[v], scip->mem->probmem, scip->set, scip->stat, &(negvars[v])) );
1580  }
1581 
1582  return SCIP_OKAY;
1583 }
1584 
1585 /** gets a binary variable that is equal to the given binary variable, and that is either active, fixed, or
1586  * multi-aggregated, or the negated variable of an active, fixed, or multi-aggregated variable
1587  *
1588  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1589  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1590  *
1591  * @pre This method can be called if @p scip is in one of the following stages:
1592  * - \ref SCIP_STAGE_PROBLEM
1593  * - \ref SCIP_STAGE_TRANSFORMED
1594  * - \ref SCIP_STAGE_INITPRESOLVE
1595  * - \ref SCIP_STAGE_PRESOLVING
1596  * - \ref SCIP_STAGE_EXITPRESOLVE
1597  * - \ref SCIP_STAGE_PRESOLVED
1598  * - \ref SCIP_STAGE_INITSOLVE
1599  * - \ref SCIP_STAGE_SOLVING
1600  * - \ref SCIP_STAGE_SOLVED
1601  * - \ref SCIP_STAGE_EXITSOLVE
1602  */
1604  SCIP* scip, /**< SCIP data structure */
1605  SCIP_VAR* var, /**< binary variable to get binary representative for */
1606  SCIP_VAR** repvar, /**< pointer to store the binary representative */
1607  SCIP_Bool* negated /**< pointer to store whether the negation of an active variable was returned */
1608  )
1609 {
1610  assert(scip != NULL);
1611  assert(var != NULL);
1612  assert(repvar != NULL);
1613  assert(negated != NULL);
1614  assert(var->scip == scip);
1615 
1616  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetBinvarRepresentative", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1617 
1618  /* get the active representative of the given variable */
1619  *repvar = var;
1620  *negated = FALSE;
1621  SCIP_CALL( SCIPvarGetProbvarBinary(repvar, negated) );
1622 
1623  /* negate the representative, if it corresponds to the negation of the given variable */
1624  if( *negated )
1625  {
1626  SCIP_CALL( SCIPgetNegatedVar(scip, *repvar, repvar) );
1627  }
1628 
1629  return SCIP_OKAY;
1630 }
1631 
1632 /** gets binary variables that are equal to the given binary variables, and which are either active, fixed, or
1633  * multi-aggregated, or the negated variables of active, fixed, or multi-aggregated variables
1634  *
1635  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1636  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1637  *
1638  * @pre This method can be called if @p scip is in one of the following stages:
1639  * - \ref SCIP_STAGE_PROBLEM
1640  * - \ref SCIP_STAGE_TRANSFORMED
1641  * - \ref SCIP_STAGE_INITPRESOLVE
1642  * - \ref SCIP_STAGE_PRESOLVING
1643  * - \ref SCIP_STAGE_EXITPRESOLVE
1644  * - \ref SCIP_STAGE_PRESOLVED
1645  * - \ref SCIP_STAGE_INITSOLVE
1646  * - \ref SCIP_STAGE_SOLVING
1647  * - \ref SCIP_STAGE_SOLVED
1648  * - \ref SCIP_STAGE_EXITSOLVE
1649  */
1651  SCIP* scip, /**< SCIP data structure */
1652  int nvars, /**< number of binary variables to get representatives for */
1653  SCIP_VAR** vars, /**< binary variables to get binary representatives for */
1654  SCIP_VAR** repvars, /**< array to store the binary representatives */
1655  SCIP_Bool* negated /**< array to store whether the negation of an active variable was returned */
1656  )
1657 {
1658  int v;
1659 
1660  assert(scip != NULL);
1661  assert(vars != NULL || nvars == 0);
1662  assert(repvars != NULL || nvars == 0);
1663  assert(negated != NULL || nvars == 0);
1664 
1665  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetBinvarRepresentatives", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1666 
1667  if( nvars == 0 )
1668  return SCIP_OKAY;
1669 
1670  /* get the active representative of the given variable */
1671  BMScopyMemoryArray(repvars, vars, nvars);
1672  BMSclearMemoryArray(negated, nvars);
1673  SCIP_CALL( SCIPvarsGetProbvarBinary(&repvars, &negated, nvars) );
1674 
1675  /* negate the representatives, if they correspond to the negation of the given variables */
1676  for( v = nvars - 1; v >= 0; --v )
1677  if( negated[v] )
1678  {
1679  SCIP_CALL( SCIPgetNegatedVar(scip, repvars[v], &(repvars[v])) );
1680  }
1681 
1682  return SCIP_OKAY;
1683 }
1684 
1685 /** flattens aggregation graph of multi-aggregated variable in order to avoid exponential recursion later on
1686  *
1687  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1688  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1689  *
1690  * @pre This method can be called if @p scip is in one of the following stages:
1691  * - \ref SCIP_STAGE_INITPRESOLVE
1692  * - \ref SCIP_STAGE_PRESOLVING
1693  * - \ref SCIP_STAGE_EXITPRESOLVE
1694  * - \ref SCIP_STAGE_PRESOLVED
1695  * - \ref SCIP_STAGE_INITSOLVE
1696  * - \ref SCIP_STAGE_SOLVING
1697  * - \ref SCIP_STAGE_SOLVED
1698  */
1700  SCIP* scip, /**< SCIP data structure */
1701  SCIP_VAR* var /**< problem variable */
1702  )
1703 {
1704  assert( scip != NULL );
1705  assert( var != NULL );
1706  SCIP_CALL( SCIPcheckStage(scip, "SCIPflattenVarAggregationGraph", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
1707 
1708  SCIP_CALL( SCIPvarFlattenAggregationGraph(var, scip->mem->probmem, scip->set, scip->eventqueue) );
1709 
1710  return SCIP_OKAY;
1711 }
1712 
1713 /** Transforms a given linear sum of variables, that is a_1*x_1 + ... + a_n*x_n + c into a corresponding linear sum of
1714  * active variables, that is b_1*y_1 + ... + b_m*y_m + d.
1715  *
1716  * If the number of needed active variables is greater than the available slots in the variable array, nothing happens
1717  * except that the required size is stored in the corresponding variable (requiredsize). Otherwise, the active variable
1718  * representation is stored in the variable array, scalar array and constant.
1719  *
1720  * The reason for this approach is that we cannot reallocate memory, since we do not know how the memory has been
1721  * allocated (e.g., by a C++ 'new' or SCIP functions).
1722  *
1723  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1724  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1725  *
1726  * @pre This method can be called if @p scip is in one of the following stages:
1727  * - \ref SCIP_STAGE_TRANSFORMED
1728  * - \ref SCIP_STAGE_INITPRESOLVE
1729  * - \ref SCIP_STAGE_PRESOLVING
1730  * - \ref SCIP_STAGE_EXITPRESOLVE
1731  * - \ref SCIP_STAGE_PRESOLVED
1732  * - \ref SCIP_STAGE_INITSOLVE
1733  * - \ref SCIP_STAGE_SOLVING
1734  * - \ref SCIP_STAGE_SOLVED
1735  * - \ref SCIP_STAGE_EXITSOLVE
1736  * - \ref SCIP_STAGE_FREETRANS
1737  *
1738  * @note The resulting linear sum is stored into the given variable array, scalar array, and constant. That means the
1739  * given entries are overwritten.
1740  *
1741  * @note That method can be used to convert a single variables into variable space of active variables. Therefore call
1742  * the method with the linear sum 1.0*x + 0.0.
1743  */
1745  SCIP* scip, /**< SCIP data structure */
1746  SCIP_VAR** vars, /**< variable array x_1, ..., x_n in the linear sum which will be
1747  * overwritten by the variable array y_1, ..., y_m in the linear sum
1748  * w.r.t. active variables */
1749  SCIP_Real* scalars, /**< scalars a_1, ..., a_n in linear sum which will be overwritten to the
1750  * scalars b_1, ..., b_m in the linear sum of the active variables */
1751  int* nvars, /**< pointer to number of variables in the linear sum which will be
1752  * overwritten by the number of variables in the linear sum corresponding
1753  * to the active variables */
1754  int varssize, /**< available slots in vars and scalars array which is needed to check if
1755  * the array are large enough for the linear sum w.r.t. active
1756  * variables */
1757  SCIP_Real* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c which
1758  * will chnage to constant d in the linear sum b_1*y_1 + ... + b_m*y_m +
1759  * d w.r.t. the active variables */
1760  int* requiredsize, /**< pointer to store the required array size for the linear sum w.r.t. the
1761  * active variables */
1762  SCIP_Bool mergemultiples /**< should multiple occurrences of a var be replaced by a single coeff? */
1763  )
1764 {
1765  assert( scip != NULL );
1766  assert( nvars != NULL );
1767  assert( vars != NULL || *nvars == 0 );
1768  assert( scalars != NULL || *nvars == 0 );
1769  assert( constant != NULL );
1770  assert( requiredsize != NULL );
1771  assert( *nvars <= varssize );
1772 
1773  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetProbvarLinearSum", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1774  SCIP_CALL( SCIPvarGetActiveRepresentatives(scip->set, vars, scalars, nvars, varssize, constant, requiredsize, mergemultiples) );
1775 
1776  return SCIP_OKAY;
1777 }
1778 
1779 /** transforms given variable, scalar and constant to the corresponding active, fixed, or
1780  * multi-aggregated variable, scalar and constant; if the variable resolves to a fixed variable,
1781  * "scalar" will be 0.0 and the value of the sum will be stored in "constant"; a multi-aggregation
1782  * with only one active variable (this can happen due to fixings after the multi-aggregation),
1783  * is treated like an aggregation; if the multi-aggregation constant is infinite, "scalar" will be 0.0
1784  *
1785  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1786  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1787  *
1788  * @pre This method can be called if @p scip is in one of the following stages:
1789  * - \ref SCIP_STAGE_TRANSFORMED
1790  * - \ref SCIP_STAGE_INITPRESOLVE
1791  * - \ref SCIP_STAGE_PRESOLVING
1792  * - \ref SCIP_STAGE_EXITPRESOLVE
1793  * - \ref SCIP_STAGE_PRESOLVED
1794  * - \ref SCIP_STAGE_INITSOLVE
1795  * - \ref SCIP_STAGE_SOLVING
1796  * - \ref SCIP_STAGE_SOLVED
1797  * - \ref SCIP_STAGE_EXITSOLVE
1798  * - \ref SCIP_STAGE_FREETRANS
1799  */
1801  SCIP* scip, /**< SCIP data structure */
1802  SCIP_VAR** var, /**< pointer to problem variable x in sum a*x + c */
1803  SCIP_Real* scalar, /**< pointer to scalar a in sum a*x + c */
1804  SCIP_Real* constant /**< pointer to constant c in sum a*x + c */
1805  )
1806 {
1807  assert(scip != NULL);
1808  assert(var != NULL);
1809  assert(scalar != NULL);
1810  assert(constant != NULL);
1811 
1812  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetProbvarSum", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1813  SCIP_CALL( SCIPvarGetProbvarSum(var, scip->set, scalar, constant) );
1814 
1815  return SCIP_OKAY;
1816 }
1817 
1818 /** return for given variables all their active counterparts; all active variables will be pairwise different
1819  * @note It does not hold that the first output variable is the active variable for the first input variable.
1820  *
1821  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1822  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1823  *
1824  * @pre This method can be called if @p scip is in one of the following stages:
1825  * - \ref SCIP_STAGE_TRANSFORMED
1826  * - \ref SCIP_STAGE_INITPRESOLVE
1827  * - \ref SCIP_STAGE_PRESOLVING
1828  * - \ref SCIP_STAGE_EXITPRESOLVE
1829  * - \ref SCIP_STAGE_PRESOLVED
1830  * - \ref SCIP_STAGE_INITSOLVE
1831  * - \ref SCIP_STAGE_SOLVING
1832  * - \ref SCIP_STAGE_SOLVED
1833  * - \ref SCIP_STAGE_EXITSOLVE
1834  * - \ref SCIP_STAGE_FREETRANS
1835  */
1837  SCIP* scip, /**< SCIP data structure */
1838  SCIP_VAR** vars, /**< variable array with given variables and as output all active
1839  * variables, if enough slots exist
1840  */
1841  int* nvars, /**< number of given variables, and as output number of active variables,
1842  * if enough slots exist
1843  */
1844  int varssize, /**< available slots in vars array */
1845  int* requiredsize /**< pointer to store the required array size for the active variables */
1846  )
1847 {
1848  assert(scip != NULL);
1849  assert(nvars != NULL);
1850  assert(vars != NULL || *nvars == 0);
1851  assert(varssize >= *nvars);
1852  assert(requiredsize != NULL);
1853 
1854  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetActiveVars", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1855  SCIP_CALL( SCIPvarsGetActiveVars(scip->set, vars, nvars, varssize, requiredsize) );
1856 
1857  return SCIP_OKAY;
1858 }
1859 
1860 /** returns the reduced costs of the variable in the current node's LP relaxation;
1861  * the current node has to have a feasible LP.
1862  *
1863  * returns SCIP_INVALID if the variable is active but not in the current LP;
1864  * returns 0 if the variable has been aggregated out or fixed in presolving.
1865  *
1866  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1867  *
1868  * @note The return value of this method should be used carefully if the dual feasibility check was explictely disabled.
1869  */
1871  SCIP* scip, /**< SCIP data structure */
1872  SCIP_VAR* var /**< variable to get reduced costs, should be a column in current node LP */
1873  )
1874 {
1875  assert( scip != NULL );
1876  assert( var != NULL );
1877  assert( var->scip == scip );
1878 
1879  switch( SCIPvarGetStatus(var) )
1880  {
1882  if( var->data.original.transvar == NULL )
1883  return SCIP_INVALID;
1884  return SCIPgetVarRedcost(scip, var->data.original.transvar);
1885 
1886  case SCIP_VARSTATUS_COLUMN:
1887  return SCIPgetColRedcost(scip, SCIPvarGetCol(var));
1888 
1889  case SCIP_VARSTATUS_LOOSE:
1890  return SCIP_INVALID;
1891 
1892  case SCIP_VARSTATUS_FIXED:
1896  return 0.0;
1897 
1898  default:
1899  SCIPerrorMessage("unknown variable status\n");
1900  SCIPABORT();
1901  return 0.0; /*lint !e527*/
1902  }
1903 }
1904 
1905 /** returns the implied reduced costs of the variable in the current node's LP relaxation;
1906  * the current node has to have a feasible LP.
1907  *
1908  * returns SCIP_INVALID if the variable is active but not in the current LP;
1909  * returns 0 if the variable has been aggregated out or fixed in presolving.
1910  *
1911  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1912  *
1913  * @note The return value of this method should be used carefully if the dual feasibility check was explictely disabled.
1914  */
1916  SCIP* scip, /**< SCIP data structure */
1917  SCIP_VAR* var, /**< variable to get reduced costs, should be a column in current node LP */
1918  SCIP_Bool varfixing /**< FALSE if for x == 0, TRUE for x == 1 */
1919  )
1920 {
1921  assert( scip != NULL );
1922  assert( var != NULL );
1923  assert( var->scip == scip );
1924 
1925  switch( SCIPvarGetStatus(var) )
1926  {
1928  if( var->data.original.transvar == NULL )
1929  return SCIP_INVALID;
1930  return SCIPgetVarImplRedcost(scip, var->data.original.transvar, varfixing);
1931 
1932  case SCIP_VARSTATUS_COLUMN:
1933  return SCIPvarGetImplRedcost(var, scip->set, varfixing, scip->stat, scip->transprob, scip->lp);
1934 
1935  case SCIP_VARSTATUS_LOOSE:
1936  return SCIP_INVALID;
1937 
1938  case SCIP_VARSTATUS_FIXED:
1942  return 0.0;
1943 
1944  default:
1945  SCIPerrorMessage("unknown variable status\n");
1946  SCIPABORT();
1947  return 0.0; /*lint !e527*/
1948  }
1949 }
1950 
1951 
1952 /** returns the Farkas coefficient of the variable in the current node's LP relaxation;
1953  * the current node has to have an infeasible LP.
1954  *
1955  * returns SCIP_INVALID if the variable is active but not in the current LP;
1956  * returns 0 if the variable has been aggregated out or fixed in presolving.
1957  *
1958  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1959  */
1961  SCIP* scip, /**< SCIP data structure */
1962  SCIP_VAR* var /**< variable to get reduced costs, should be a column in current node LP */
1963  )
1964 {
1965  assert(scip != NULL);
1966  assert(var != NULL);
1967  assert(var->scip == scip);
1968 
1969  switch( SCIPvarGetStatus(var) )
1970  {
1972  if( var->data.original.transvar == NULL )
1973  return SCIP_INVALID;
1974  return SCIPgetVarFarkasCoef(scip,var->data.original.transvar);
1975 
1976  case SCIP_VARSTATUS_COLUMN:
1977  return SCIPgetColFarkasCoef(scip,SCIPvarGetCol(var));
1978 
1979  case SCIP_VARSTATUS_LOOSE:
1980  return SCIP_INVALID;
1981 
1982  case SCIP_VARSTATUS_FIXED:
1986  return 0.0;
1987 
1988  default:
1989  SCIPerrorMessage("unknown variable status\n");
1990  SCIPABORT();
1991  return 0.0; /*lint !e527*/
1992  }
1993 }
1994 
1995 /** returns lower bound of variable directly before or after the bound change given by the bound change index
1996  * was applied
1997  */
1999  SCIP* scip, /**< SCIP data structure */
2000  SCIP_VAR* var, /**< problem variable */
2001  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2002  SCIP_Bool after /**< should the bound change with given index be included? */
2003  )
2004 {
2005  SCIP_VARSTATUS varstatus;
2006  SCIP_BDCHGINFO* bdchginfo;
2007  assert(var != NULL);
2008 
2009  varstatus = SCIPvarGetStatus(var);
2010 
2011  /* get bounds of attached variables */
2012  switch( varstatus )
2013  {
2015  assert(var->data.original.transvar != NULL);
2016  return SCIPgetVarLbAtIndex(scip, var->data.original.transvar, bdchgidx, after);
2017 
2018  case SCIP_VARSTATUS_COLUMN:
2019  case SCIP_VARSTATUS_LOOSE:
2020  if( bdchgidx == NULL )
2021  return SCIPvarGetLbLocal(var);
2022  else
2023  {
2024  bdchginfo = SCIPvarGetLbchgInfo(var, bdchgidx, after);
2025  if( bdchginfo != NULL )
2026  return SCIPbdchginfoGetNewbound(bdchginfo);
2027  else
2028  return var->glbdom.lb;
2029  }
2030 
2031  case SCIP_VARSTATUS_FIXED:
2032  return var->glbdom.lb;
2033 
2034  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c -> y = (x-c)/a */
2035  assert(var->data.aggregate.var != NULL);
2036  if( var->data.aggregate.scalar > 0.0 )
2037  {
2038  SCIP_Real lb;
2039 
2040  lb = SCIPgetVarLbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2041 
2042  /* a > 0 -> get lower bound of y */
2043  if( SCIPisInfinity(scip, -lb) )
2044  return -SCIPinfinity(scip);
2045  else if( SCIPisInfinity(scip, lb) )
2046  return SCIPinfinity(scip);
2047  else
2048  return var->data.aggregate.scalar * lb + var->data.aggregate.constant;
2049  }
2050  else if( var->data.aggregate.scalar < 0.0 )
2051  {
2052  SCIP_Real ub;
2053 
2054  ub = SCIPgetVarUbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2055 
2056  /* a < 0 -> get upper bound of y */
2057  if( SCIPisInfinity(scip, -ub) )
2058  return SCIPinfinity(scip);
2059  else if( SCIPisInfinity(scip, ub) )
2060  return -SCIPinfinity(scip);
2061  else
2062  return var->data.aggregate.scalar * ub + var->data.aggregate.constant;
2063  }
2064  else
2065  {
2066  SCIPerrorMessage("scalar is zero in aggregation\n");
2067  SCIPABORT();
2068  return SCIP_INVALID; /*lint !e527*/
2069  }
2070 
2072  /* handle multi-aggregated variables depending on one variable only (possibly caused by SCIPvarFlattenAggregationGraph()) */
2073  if ( var->data.multaggr.nvars == 1 )
2074  {
2075  assert(var->data.multaggr.vars != NULL);
2076  assert(var->data.multaggr.scalars != NULL);
2077  assert(var->data.multaggr.vars[0] != NULL);
2078 
2079  if( var->data.multaggr.scalars[0] > 0.0 )
2080  {
2081  SCIP_Real lb;
2082 
2083  lb = SCIPgetVarLbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2084 
2085  /* a > 0 -> get lower bound of y */
2086  if( SCIPisInfinity(scip, -lb) )
2087  return -SCIPinfinity(scip);
2088  else if( SCIPisInfinity(scip, lb) )
2089  return SCIPinfinity(scip);
2090  else
2091  return var->data.multaggr.scalars[0] * lb + var->data.multaggr.constant;
2092  }
2093  else if( var->data.multaggr.scalars[0] < 0.0 )
2094  {
2095  SCIP_Real ub;
2096 
2097  ub = SCIPgetVarUbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2098 
2099  /* a < 0 -> get upper bound of y */
2100  if( SCIPisInfinity(scip, -ub) )
2101  return SCIPinfinity(scip);
2102  else if( SCIPisInfinity(scip, ub) )
2103  return -SCIPinfinity(scip);
2104  else
2105  return var->data.multaggr.scalars[0] * ub + var->data.multaggr.constant;
2106  }
2107  else
2108  {
2109  SCIPerrorMessage("scalar is zero in multi-aggregation\n");
2110  SCIPABORT();
2111  return SCIP_INVALID; /*lint !e527*/
2112  }
2113  }
2114  SCIPerrorMessage("cannot get the bounds of a multi-aggregated variable.\n");
2115  SCIPABORT();
2116  return SCIP_INVALID; /*lint !e527*/
2117 
2118  case SCIP_VARSTATUS_NEGATED: /* x' = offset - x -> x = offset - x' */
2119  assert(var->negatedvar != NULL);
2121  assert(var->negatedvar->negatedvar == var);
2122  return var->data.negate.constant - SCIPgetVarUbAtIndex(scip, var->negatedvar, bdchgidx, after);
2123 
2124  default:
2125  SCIPerrorMessage("unknown variable status\n");
2126  SCIPABORT();
2127  return SCIP_INVALID; /*lint !e527*/
2128  }
2129 }
2130 
2131 /** returns upper bound of variable directly before or after the bound change given by the bound change index
2132  * was applied
2133  */
2135  SCIP* scip, /**< SCIP data structure */
2136  SCIP_VAR* var, /**< problem variable */
2137  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2138  SCIP_Bool after /**< should the bound change with given index be included? */
2139  )
2140 {
2141  SCIP_VARSTATUS varstatus;
2142  SCIP_BDCHGINFO* bdchginfo;
2143  assert(var != NULL);
2144 
2145  varstatus = SCIPvarGetStatus(var);
2146 
2147  /* get bounds of attached variables */
2148  switch( varstatus )
2149  {
2151  assert(var->data.original.transvar != NULL);
2152  return SCIPgetVarUbAtIndex(scip, var->data.original.transvar, bdchgidx, after);
2153 
2154  case SCIP_VARSTATUS_COLUMN:
2155  case SCIP_VARSTATUS_LOOSE:
2156  if( bdchgidx == NULL )
2157  return SCIPvarGetUbLocal(var);
2158  else
2159  {
2160  bdchginfo = SCIPvarGetUbchgInfo(var, bdchgidx, after);
2161  if( bdchginfo != NULL )
2162  return SCIPbdchginfoGetNewbound(bdchginfo);
2163  else
2164  return var->glbdom.ub;
2165  }
2166 
2167  case SCIP_VARSTATUS_FIXED:
2168  return var->glbdom.ub;
2169 
2170  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c -> y = (x-c)/a */
2171  assert(var->data.aggregate.var != NULL);
2172  if( var->data.aggregate.scalar > 0.0 )
2173  {
2174  SCIP_Real ub;
2175 
2176  ub = SCIPgetVarUbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2177 
2178  /* a > 0 -> get lower bound of y */
2179  if( SCIPisInfinity(scip, -ub) )
2180  return -SCIPinfinity(scip);
2181  else if( SCIPisInfinity(scip, ub) )
2182  return SCIPinfinity(scip);
2183  else
2184  return var->data.aggregate.scalar * ub + var->data.aggregate.constant;
2185  }
2186  else if( var->data.aggregate.scalar < 0.0 )
2187  {
2188  SCIP_Real lb;
2189 
2190  lb = SCIPgetVarLbAtIndex(scip, var->data.aggregate.var, bdchgidx, after);
2191 
2192  /* a < 0 -> get upper bound of y */
2193  if ( SCIPisInfinity(scip, -lb) )
2194  return SCIPinfinity(scip);
2195  else if ( SCIPisInfinity(scip, lb) )
2196  return -SCIPinfinity(scip);
2197  else
2198  return var->data.aggregate.scalar * lb + var->data.aggregate.constant;
2199  }
2200  else
2201  {
2202  SCIPerrorMessage("scalar is zero in aggregation\n");
2203  SCIPABORT();
2204  return SCIP_INVALID; /*lint !e527*/
2205  }
2206 
2208  /* handle multi-aggregated variables depending on one variable only (possibly caused by SCIPvarFlattenAggregationGraph()) */
2209  if ( var->data.multaggr.nvars == 1 )
2210  {
2211  assert(var->data.multaggr.vars != NULL);
2212  assert(var->data.multaggr.scalars != NULL);
2213  assert(var->data.multaggr.vars[0] != NULL);
2214 
2215  if( var->data.multaggr.scalars[0] > 0.0 )
2216  {
2217  SCIP_Real ub;
2218 
2219  ub = SCIPgetVarUbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2220 
2221  /* a > 0 -> get lower bound of y */
2222  if ( SCIPisInfinity(scip, -ub) )
2223  return -SCIPinfinity(scip);
2224  else if ( SCIPisInfinity(scip, ub) )
2225  return SCIPinfinity(scip);
2226  else
2227  return var->data.multaggr.scalars[0] * ub + var->data.multaggr.constant;
2228  }
2229  else if( var->data.multaggr.scalars[0] < 0.0 )
2230  {
2231  SCIP_Real lb;
2232 
2233  lb = SCIPgetVarLbAtIndex(scip, var->data.multaggr.vars[0], bdchgidx, after);
2234 
2235  /* a < 0 -> get upper bound of y */
2236  if ( SCIPisInfinity(scip, -lb) )
2237  return SCIPinfinity(scip);
2238  else if ( SCIPisInfinity(scip, lb) )
2239  return -SCIPinfinity(scip);
2240  else
2241  return var->data.multaggr.scalars[0] * lb + var->data.multaggr.constant;
2242  }
2243  else
2244  {
2245  SCIPerrorMessage("scalar is zero in multi-aggregation\n");
2246  SCIPABORT();
2247  return SCIP_INVALID; /*lint !e527*/
2248  }
2249  }
2250  SCIPerrorMessage("cannot get the bounds of a multiple aggregated variable.\n");
2251  SCIPABORT();
2252  return SCIP_INVALID; /*lint !e527*/
2253 
2254  case SCIP_VARSTATUS_NEGATED: /* x' = offset - x -> x = offset - x' */
2255  assert(var->negatedvar != NULL);
2257  assert(var->negatedvar->negatedvar == var);
2258  return var->data.negate.constant - SCIPgetVarLbAtIndex(scip, var->negatedvar, bdchgidx, after);
2259 
2260  default:
2261  SCIPerrorMessage("unknown variable status\n");
2262  SCIPABORT();
2263  return SCIP_INVALID; /*lint !e527*/
2264  }
2265 }
2266 
2267 /** returns lower or upper bound of variable directly before or after the bound change given by the bound change index
2268  * was applied
2269  */
2271  SCIP* scip, /**< SCIP data structure */
2272  SCIP_VAR* var, /**< problem variable */
2273  SCIP_BOUNDTYPE boundtype, /**< type of bound: lower or upper bound */
2274  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2275  SCIP_Bool after /**< should the bound change with given index be included? */
2276  )
2277 {
2278  if( boundtype == SCIP_BOUNDTYPE_LOWER )
2279  return SCIPgetVarLbAtIndex(scip, var, bdchgidx, after);
2280  else
2281  {
2282  assert(boundtype == SCIP_BOUNDTYPE_UPPER);
2283  return SCIPgetVarUbAtIndex(scip, var, bdchgidx, after);
2284  }
2285 }
2286 
2287 /** returns whether the binary variable was fixed at the time given by the bound change index */
2289  SCIP* scip, /**< SCIP data structure */
2290  SCIP_VAR* var, /**< problem variable */
2291  SCIP_BDCHGIDX* bdchgidx, /**< bound change index representing time on path to current node */
2292  SCIP_Bool after /**< should the bound change with given index be included? */
2293  )
2294 {
2295  assert(var != NULL);
2296  assert(SCIPvarIsBinary(var));
2297 
2298  /* check the current bounds first in order to decide at which bound change information we have to look
2299  * (which is expensive because we have to follow the aggregation tree to the active variable)
2300  */
2301  return ((SCIPvarGetLbLocal(var) > 0.5 && SCIPgetVarLbAtIndex(scip, var, bdchgidx, after) > 0.5)
2302  || (SCIPvarGetUbLocal(var) < 0.5 && SCIPgetVarUbAtIndex(scip, var, bdchgidx, after) < 0.5));
2303 }
2304 
2305 /** gets solution value for variable in current node
2306  *
2307  * @return solution value for variable in current node
2308  *
2309  * @pre This method can be called if @p scip is in one of the following stages:
2310  * - \ref SCIP_STAGE_PRESOLVED
2311  * - \ref SCIP_STAGE_SOLVING
2312  */
2314  SCIP* scip, /**< SCIP data structure */
2315  SCIP_VAR* var /**< variable to get solution value for */
2316  )
2317 {
2319  assert( var->scip == scip );
2320 
2321  return SCIPvarGetSol(var, SCIPtreeHasCurrentNodeLP(scip->tree));
2322 }
2323 
2324 /** gets solution values of multiple variables in current node
2325  *
2326  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2327  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2328  *
2329  * @pre This method can be called if @p scip is in one of the following stages:
2330  * - \ref SCIP_STAGE_PRESOLVED
2331  * - \ref SCIP_STAGE_SOLVING
2332  */
2334  SCIP* scip, /**< SCIP data structure */
2335  int nvars, /**< number of variables to get solution value for */
2336  SCIP_VAR** vars, /**< array with variables to get value for */
2337  SCIP_Real* vals /**< array to store solution values of variables */
2338  )
2339 {
2340  int v;
2341 
2342  assert(nvars == 0 || vars != NULL);
2343  assert(nvars == 0 || vals != NULL);
2344 
2345  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarSols", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2346 
2347  if( SCIPtreeHasCurrentNodeLP(scip->tree) )
2348  {
2349  for( v = 0; v < nvars; ++v )
2350  vals[v] = SCIPvarGetLPSol(vars[v]);
2351  }
2352  else
2353  {
2354  for( v = 0; v < nvars; ++v )
2355  vals[v] = SCIPvarGetPseudoSol(vars[v]);
2356  }
2357 
2358  return SCIP_OKAY;
2359 }
2360 
2361 /** sets the solution value of all variables in the global relaxation solution to zero
2362  *
2363  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2364  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2365  *
2366  * @pre This method can be called if @p scip is in one of the following stages:
2367  * - \ref SCIP_STAGE_PRESOLVED
2368  * - \ref SCIP_STAGE_SOLVING
2369  */
2371  SCIP* scip, /**< SCIP data structure */
2372  SCIP_RELAX* relax /**< relaxator data structure */
2373  )
2374 {
2375  SCIP_VAR** vars;
2376  int nvars;
2377  int v;
2378 
2379  assert(scip != NULL);
2380 
2381  SCIP_CALL( SCIPcheckStage(scip, "SCIPclearRelaxSolVals", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2382 
2383  /* update the responsible relax pointer */
2384  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2385 
2386  /* the relaxation solution is already cleared */
2387  if( SCIPrelaxationIsSolZero(scip->relaxation) )
2388  return SCIP_OKAY;
2389 
2390  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
2391 
2392  for( v = 0; v < nvars; v++ )
2393  {
2394  SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, 0.0, FALSE) );
2395  }
2396 
2397  SCIPrelaxationSetSolObj(scip->relaxation, 0.0);
2399 
2400  return SCIP_OKAY;
2401 }
2402 
2403 /** sets the value of the given variable in the global relaxation solution;
2404  * this solution can be filled by the relaxation handlers and can be used by heuristics and for separation;
2405  * You can use SCIPclearRelaxSolVals() to set all values to zero, initially;
2406  * after setting all solution values, you have to call SCIPmarkRelaxSolValid()
2407  * to inform SCIP that the stored solution is valid
2408  *
2409  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2410  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2411  *
2412  * @pre This method can be called if @p scip is in one of the following stages:
2413  * - \ref SCIP_STAGE_PRESOLVED
2414  * - \ref SCIP_STAGE_SOLVING
2415  *
2416  * @note This method incrementally updates the objective value of the relaxation solution. If the whole solution
2417  * should be updated, using SCIPsetRelaxSolVals() instead or calling SCIPclearRelaxSolVals() before setting
2418  * the first value to reset the solution and the objective value to 0 may help the numerics.
2419  */
2421  SCIP* scip, /**< SCIP data structure */
2422  SCIP_RELAX* relax, /**< relaxator data structure */
2423  SCIP_VAR* var, /**< variable to set value for */
2424  SCIP_Real val /**< solution value of variable */
2425  )
2426 {
2427  assert(scip != NULL);
2428 
2429  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolVal", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2430 
2431  SCIP_CALL( SCIPvarSetRelaxSol(var, scip->set, scip->relaxation, val, TRUE) );
2432 
2433  if( val != 0.0 )
2436  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2437 
2438  return SCIP_OKAY;
2439 }
2440 
2441 /** sets the values of the given variables in the global relaxation solution and informs SCIP about the validity
2442  * and whether the solution can be enforced via linear cuts;
2443  * this solution can be filled by the relaxation handlers and can be used by heuristics and for separation;
2444  * the solution is automatically cleared, s.t. all other variables get value 0.0
2445  *
2446  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2447  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2448  *
2449  * @pre This method can be called if @p scip is in one of the following stages:
2450  * - \ref SCIP_STAGE_PRESOLVED
2451  * - \ref SCIP_STAGE_SOLVING
2452  */
2454  SCIP* scip, /**< SCIP data structure */
2455  SCIP_RELAX* relax, /**< relaxator data structure */
2456  int nvars, /**< number of variables to set relaxation solution value for */
2457  SCIP_VAR** vars, /**< array with variables to set value for */
2458  SCIP_Real* vals, /**< array with solution values of variables */
2459  SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2460  )
2461 {
2462  int v;
2463 
2464  assert(scip != NULL);
2465  assert(nvars == 0 || vars != NULL);
2466  assert(nvars == 0 || vals != NULL);
2467 
2468  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolVals", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2469 
2470  SCIP_CALL( SCIPclearRelaxSolVals(scip, relax) );
2471 
2472  for( v = 0; v < nvars; v++ )
2473  {
2474  SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, vals[v], TRUE) );
2475  }
2476 
2478  SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2479  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2480 
2481  return SCIP_OKAY;
2482 }
2483 
2484 /** sets the values of the variables in the global relaxation solution to the values in the given primal solution
2485  * and informs SCIP about the validity and whether the solution can be enforced via linear cuts;
2486  * the relaxation solution can be filled by the relaxation handlers and might be used by heuristics and for separation
2487  *
2488  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2489  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2490  *
2491  * @pre This method can be called if @p scip is in one of the following stages:
2492  * - \ref SCIP_STAGE_PRESOLVED
2493  * - \ref SCIP_STAGE_SOLVING
2494  */
2496  SCIP* scip, /**< SCIP data structure */
2497  SCIP_RELAX* relax, /**< relaxator data structure */
2498  SCIP_SOL* sol, /**< primal relaxation solution */
2499  SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2500  )
2501 {
2502  SCIP_VAR** vars;
2503  SCIP_Real* vals;
2504  int nvars;
2505  int v;
2506 
2507  assert(scip != NULL);
2508 
2509  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxSolValsSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2510 
2511  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
2512 
2513  /* alloc buffer array for solution values of the variables and get the values */
2514  SCIP_CALL( SCIPallocBufferArray(scip, &vals, nvars) );
2515  SCIP_CALL( SCIPgetSolVals(scip, sol, nvars, vars, vals) );
2516 
2517  SCIP_CALL( SCIPclearRelaxSolVals(scip, relax) );
2518 
2519  for( v = 0; v < nvars; v++ )
2520  {
2521  SCIP_CALL( SCIPvarSetRelaxSol(vars[v], scip->set, scip->relaxation, vals[v], FALSE) );
2522  }
2523 
2524  SCIPrelaxationSetSolObj(scip->relaxation, SCIPsolGetObj(sol, scip->set, scip->transprob, scip->origprob));
2525 
2527  SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2528  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2529 
2530  SCIPfreeBufferArray(scip, &vals);
2531 
2532  return SCIP_OKAY;
2533 }
2534 
2535 /** returns whether the relaxation solution is valid
2536  *
2537  * @return TRUE, if the relaxation solution is valid; FALSE, otherwise
2538  *
2539  * @pre This method can be called if @p scip is in one of the following stages:
2540  * - \ref SCIP_STAGE_PRESOLVED
2541  * - \ref SCIP_STAGE_SOLVING
2542  */
2544  SCIP* scip /**< SCIP data structure */
2545  )
2546 {
2547  assert(scip != NULL);
2548 
2549  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisRelaxSolValid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2550 
2551  return SCIPrelaxationIsSolValid(scip->relaxation);
2552 }
2553 
2554 /** informs SCIP that the relaxation solution is valid and whether the relaxation can be enforced through linear cuts
2555  *
2556  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2557  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2558  *
2559  * @pre This method can be called if @p scip is in one of the following stages:
2560  * - \ref SCIP_STAGE_PRESOLVED
2561  * - \ref SCIP_STAGE_SOLVING
2562  */
2564  SCIP* scip, /**< SCIP data structure */
2565  SCIP_RELAX* relax, /**< relaxator data structure that set the current relaxation solution */
2566  SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
2567  )
2568 {
2569  assert(scip != NULL);
2570 
2571  SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkRelaxSolValid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2572 
2573  SCIPrelaxationSetSolValid(scip->relaxation, TRUE, includeslp);
2574  SCIPrelaxationSetSolRelax(scip->relaxation, relax);
2575 
2576  return SCIP_OKAY;
2577 }
2578 
2579 /** informs SCIP, that the relaxation solution is invalid
2580  *
2581  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2582  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2583  *
2584  * @pre This method can be called if @p scip is in one of the following stages:
2585  * - \ref SCIP_STAGE_PRESOLVED
2586  * - \ref SCIP_STAGE_SOLVING
2587  */
2589  SCIP* scip /**< SCIP data structure */
2590  )
2591 {
2592  assert(scip != NULL);
2593 
2594  SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkRelaxSolInvalid", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2595 
2597 
2598  return SCIP_OKAY;
2599 }
2600 
2601 /** gets the relaxation solution value of the given variable
2602  *
2603  * @return the relaxation solution value of the given variable
2604  *
2605  * @pre This method can be called if @p scip is in one of the following stages:
2606  * - \ref SCIP_STAGE_PRESOLVED
2607  * - \ref SCIP_STAGE_SOLVING
2608  */
2610  SCIP* scip, /**< SCIP data structure */
2611  SCIP_VAR* var /**< variable to get value for */
2612  )
2613 {
2614  assert(scip != NULL);
2615  assert(var != NULL);
2616  assert(var->scip == scip);
2617 
2618  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetRelaxSolVal", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2619 
2620  if( !SCIPrelaxationIsSolValid(scip->relaxation) )
2621  {
2622  SCIPerrorMessage("Relaxation Solution is not valid!\n");
2623  SCIPABORT();
2624  return SCIP_INVALID; /*lint !e527*/
2625  }
2626 
2627  return SCIPvarGetRelaxSol(var, scip->set);
2628 }
2629 
2630 /** gets the relaxation solution objective value
2631  *
2632  * @return the objective value of the relaxation solution
2633  *
2634  * @pre This method can be called if @p scip is in one of the following stages:
2635  * - \ref SCIP_STAGE_PRESOLVED
2636  * - \ref SCIP_STAGE_SOLVING
2637  */
2639  SCIP* scip /**< SCIP data structure */
2640  )
2641 {
2642  assert(scip != NULL);
2643 
2644  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetRelaxSolObj", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2645 
2646  if( !SCIPrelaxationIsSolValid(scip->relaxation) )
2647  {
2648  SCIPerrorMessage("Relaxation Solution is not valid!\n");
2649  SCIPABORT();
2650  return SCIP_INVALID; /*lint !e527*/
2651  }
2652 
2653  return SCIPrelaxationGetSolObj(scip->relaxation);
2654 }
2655 
2656 /** determine which branching direction should be evaluated first by strong branching
2657  *
2658  * @return TRUE iff strong branching should first evaluate the down child
2659  *
2660  */
2662  SCIP* scip, /**< SCIP data structure */
2663  SCIP_VAR* var /**< variable to determine the branching direction on */
2664  )
2665 {
2666  switch( scip->set->branch_firstsbchild )
2667  {
2668  case 'u':
2669  return FALSE;
2670  case 'd':
2671  return TRUE;
2672  case 'a':
2673  return (SCIPvarGetNLocksDown(var) > SCIPvarGetNLocksUp(var));
2674  default:
2675  assert(scip->set->branch_firstsbchild == 'h');
2677  }
2678 }
2679 
2680 /** start strong branching - call before any strong branching
2681  *
2682  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2683  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2684  *
2685  * @pre This method can be called if @p scip is in one of the following stages:
2686  * - \ref SCIP_STAGE_PRESOLVED
2687  * - \ref SCIP_STAGE_SOLVING
2688  *
2689  * @note if propagation is enabled, strong branching is not done directly on the LP, but probing nodes are created
2690  * which allow to perform propagation but also creates some overhead
2691  */
2693  SCIP* scip, /**< SCIP data structure */
2694  SCIP_Bool enablepropagation /**< should propagation be done before solving the strong branching LP? */
2695  )
2696 {
2697  assert( scip != NULL );
2698  SCIP_CALL( SCIPcheckStage(scip, "SCIPstartStrongbranch", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2699 
2700  assert(!SCIPinProbing(scip));
2701 
2702  SCIPdebugMsg(scip, "starting strong branching mode%s: lpcount=%" SCIP_LONGINT_FORMAT "\n", enablepropagation ? " with propagation" : "", scip->stat->lpcount - scip->stat->nsbdivinglps);
2703 
2704  /* start probing mode to allow propagation before solving the strong branching LPs; if no propagation should be done,
2705  * start the strong branching mode in the LP interface
2706  */
2707  if( enablepropagation )
2708  {
2709  if( SCIPtreeProbing(scip->tree) )
2710  {
2711  SCIPerrorMessage("cannot start strong branching with propagation while in probing mode\n");
2712  return SCIP_INVALIDCALL;
2713  }
2714 
2715  if( scip->lp != NULL && SCIPlpDiving(scip->lp) )
2716  {
2717  SCIPerrorMessage("cannot start strong branching with propagation while in diving mode\n");
2718  return SCIP_INVALIDCALL;
2719  }
2720 
2721  /* other then in SCIPstartProbing(), we do not disable collecting variable statistics during strong branching;
2722  * we cannot disable it, because the pseudo costs would not be updated, otherwise,
2723  * and reliability branching would end up doing strong branching all the time
2724  */
2725  SCIP_CALL( SCIPtreeStartProbing(scip->tree, scip->mem->probmem, scip->set, scip->lp, scip->relaxation, scip->transprob, TRUE) );
2726 
2727  /* inform the LP that the current probing mode is used for strong branching */
2729  }
2730  else
2731  {
2733  }
2734 
2735  /* reset local strong branching info */
2737 
2738  return SCIP_OKAY;
2739 }
2740 
2741 /** end strong branching - call after any strong branching
2742  *
2743  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2744  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2745  *
2746  * @pre This method can be called if @p scip is in one of the following stages:
2747  * - \ref SCIP_STAGE_PRESOLVED
2748  * - \ref SCIP_STAGE_SOLVING
2749  */
2751  SCIP* scip /**< SCIP data structure */
2752  )
2753 {
2754  assert( scip != NULL );
2755 
2756  SCIP_CALL( SCIPcheckStage(scip, "SCIPendStrongbranch", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2757 
2758  /* depending on whether the strong branching mode was started with propagation enabled or not, we end the strong
2759  * branching probing mode or the LP strong branching mode
2760  */
2761  if( SCIPtreeProbing(scip->tree) )
2762  {
2763  SCIP_NODE* node;
2764  SCIP_DOMCHG* domchg;
2765  SCIP_VAR** boundchgvars;
2766  SCIP_Real* bounds;
2767  SCIP_BOUNDTYPE* boundtypes;
2768  int nboundchgs;
2769  int nbnds;
2770  int i;
2771 
2772  /* collect all bound changes deducted during probing, which were applied at the probing root and apply them to the
2773  * focusnode
2774  */
2775  node = SCIPgetCurrentNode(scip);
2776  assert(SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE);
2777  assert(SCIPgetProbingDepth(scip) == 0);
2778 
2779  domchg = SCIPnodeGetDomchg(node);
2780  nboundchgs = SCIPdomchgGetNBoundchgs(domchg);
2781 
2782  SCIP_CALL( SCIPallocBufferArray(scip, &boundchgvars, nboundchgs) );
2783  SCIP_CALL( SCIPallocBufferArray(scip, &bounds, nboundchgs) );
2784  SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, nboundchgs) );
2785 
2786  for( i = 0, nbnds = 0; i < nboundchgs; ++i )
2787  {
2788  SCIP_BOUNDCHG* boundchg;
2789 
2790  boundchg = SCIPdomchgGetBoundchg(domchg, i);
2791 
2792  /* ignore redundant bound changes */
2793  if( SCIPboundchgIsRedundant(boundchg) )
2794  continue;
2795 
2796  boundchgvars[nbnds] = SCIPboundchgGetVar(boundchg);
2797  bounds[nbnds] = SCIPboundchgGetNewbound(boundchg);
2798  boundtypes[nbnds] = SCIPboundchgGetBoundtype(boundchg);
2799  ++nbnds;
2800  }
2801 
2802  SCIPdebugMsg(scip, "ending strong branching with probing: %d bound changes collected\n", nbnds);
2803 
2804  /* inform the LP that the probing mode is not used for strong branching anymore */
2806 
2807  /* switch back from probing to normal operation mode and restore variables and constraints to focus node */
2808  SCIP_CALL( SCIPtreeEndProbing(scip->tree, scip->reopt, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
2809  scip->transprob, scip->origprob, scip->lp, scip->relaxation, scip->primal,
2810  scip->branchcand, scip->eventqueue, scip->eventfilter, scip->cliquetable) );
2811 
2812  /* apply the collected bound changes */
2813  for( i = 0; i < nbnds; ++i )
2814  {
2815  if( boundtypes[i] == SCIP_BOUNDTYPE_LOWER )
2816  {
2817  SCIPdebugMsg(scip, "apply probing lower bound change <%s> >= %.9g\n", SCIPvarGetName(boundchgvars[i]), bounds[i]);
2818  SCIP_CALL( SCIPchgVarLb(scip, boundchgvars[i], bounds[i]) );
2819  }
2820  else
2821  {
2822  SCIPdebugMsg(scip, "apply probing upper bound change <%s> <= %.9g\n", SCIPvarGetName(boundchgvars[i]), bounds[i]);
2823  SCIP_CALL( SCIPchgVarUb(scip, boundchgvars[i], bounds[i]) );
2824  }
2825  }
2826 
2827  SCIPfreeBufferArray(scip, &boundtypes);
2828  SCIPfreeBufferArray(scip, &bounds);
2829  SCIPfreeBufferArray(scip, &boundchgvars);
2830  }
2831  else
2832  {
2833  SCIPdebugMsg(scip, "ending strong branching\n");
2834 
2836  }
2837 
2838  return SCIP_OKAY;
2839 }
2840 
2841 /** analyze the strong branching for the given variable; that includes conflict analysis for infeasible branches and
2842  * storing of root reduced cost information
2843  */
2844 static
2846  SCIP* scip, /**< SCIP data structure */
2847  SCIP_VAR* var, /**< variable to analyze */
2848  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
2849  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
2850  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
2851  * infeasible downwards branch, or NULL */
2852  SCIP_Bool* upconflict /**< pointer to store whether a conflict constraint was created for an
2853  * infeasible upwards branch, or NULL */
2854  )
2855 {
2856  SCIP_COL* col;
2857  SCIP_Bool downcutoff;
2858  SCIP_Bool upcutoff;
2859 
2860  col = SCIPvarGetCol(var);
2861  assert(col != NULL);
2862 
2863  downcutoff = col->sbdownvalid && SCIPsetIsGE(scip->set, col->sbdown, scip->lp->cutoffbound);
2864  upcutoff = col->sbupvalid && SCIPsetIsGE(scip->set, col->sbup, scip->lp->cutoffbound);
2865 
2866  if( downinf != NULL )
2867  *downinf = downcutoff;
2868  if( upinf != NULL )
2869  *upinf = upcutoff;
2870 
2871  /* analyze infeasible strong branching sub problems:
2872  * because the strong branching's bound change is necessary for infeasibility, it cannot be undone;
2873  * therefore, infeasible strong branchings on non-binary variables will not produce a valid conflict constraint
2874  */
2875  if( scip->set->conf_enable && scip->set->conf_usesb && scip->set->nconflicthdlrs > 0
2876  && SCIPvarIsBinary(var) && SCIPtreeGetCurrentDepth(scip->tree) > 0 )
2877  {
2878  if( (downcutoff && SCIPsetFeasCeil(scip->set, col->primsol-1.0) >= col->lb - 0.5)
2879  || (upcutoff && SCIPsetFeasFloor(scip->set, col->primsol+1.0) <= col->ub + 0.5) )
2880  {
2881  assert(downconflict != NULL);
2882  assert(upconflict != NULL);
2883  SCIP_CALL( SCIPconflictAnalyzeStrongbranch(scip->conflict, scip->conflictstore, scip->mem->probmem, scip->set, scip->stat,
2884  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, col, downconflict, upconflict) );
2885  }
2886  }
2887 
2888  /* the strong branching results can be used to strengthen the root reduced cost information which is used for example
2889  * to propagate against the cutoff bound
2890  *
2891  * @note Ignore the results if the LP solution of the down (up) branch LP is smaller which should not happened by
2892  * theory but can arise due to numerical issues.
2893  */
2894  if( SCIPtreeGetCurrentDepth(scip->tree) == 0 && SCIPvarIsBinary(var) && SCIPlpIsDualReliable(scip->lp) )
2895  {
2896  SCIP_Real lpobjval;
2897 
2898  assert(SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL);
2899 
2900  lpobjval = SCIPlpGetObjval(scip->lp, scip->set, scip->transprob);
2901 
2902  if( col->sbdownvalid && SCIPsetFeasCeil(scip->set, col->primsol-1.0) >= col->lb - 0.5 && lpobjval < col->sbdown )
2903  SCIPvarUpdateBestRootSol(var, scip->set, SCIPvarGetUbGlobal(var), -(col->sbdown - lpobjval), lpobjval);
2904  if( col->sbupvalid && SCIPsetFeasFloor(scip->set, col->primsol+1.0) <= col->ub + 0.5 && lpobjval < col->sbup )
2905  SCIPvarUpdateBestRootSol(var, scip->set, SCIPvarGetLbGlobal(var), col->sbup - lpobjval, lpobjval);
2906  }
2907 
2908  return SCIP_OKAY;
2909 }
2910 
2911 /** gets strong branching information on column variable with fractional value
2912  *
2913  * Before calling this method, the strong branching mode must have been activated by calling SCIPstartStrongbranch();
2914  * after strong branching was done for all candidate variables, the strong branching mode must be ended by
2915  * SCIPendStrongbranch(). Since this method does not apply domain propagation before strongbranching,
2916  * propagation should not be enabled in the SCIPstartStrongbranch() call.
2917  *
2918  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2919  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2920  *
2921  * @pre This method can be called if @p scip is in one of the following stages:
2922  * - \ref SCIP_STAGE_PRESOLVED
2923  * - \ref SCIP_STAGE_SOLVING
2924  */
2926  SCIP* scip, /**< SCIP data structure */
2927  SCIP_VAR* var, /**< variable to get strong branching values for */
2928  int itlim, /**< iteration limit for strong branchings */
2929  SCIP_Bool idempotent, /**< should scip's state remain the same after the call (statistics, column states...), or should it be updated ? */
2930  SCIP_Real* down, /**< stores dual bound after branching column down */
2931  SCIP_Real* up, /**< stores dual bound after branching column up */
2932  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
2933  * otherwise, it can only be used as an estimate value */
2934  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
2935  * otherwise, it can only be used as an estimate value */
2936  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
2937  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
2938  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
2939  * infeasible downwards branch, or NULL */
2940  SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
2941  * infeasible upwards branch, or NULL */
2942  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
2943  * solving process should be stopped (e.g., due to a time limit) */
2944  )
2945 {
2946  SCIP_COL* col;
2947  SCIP_Real localdown;
2948  SCIP_Real localup;
2949  SCIP_Bool localdownvalid;
2950  SCIP_Bool localupvalid;
2951 
2952  assert(scip != NULL);
2953  assert(var != NULL);
2954  assert(lperror != NULL);
2955  assert(!SCIPtreeProbing(scip->tree)); /* we should not be in strong branching with propagation mode */
2956  assert(var->scip == scip);
2957 
2958  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchFrac", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2959 
2960  if( downvalid != NULL )
2961  *downvalid = FALSE;
2962  if( upvalid != NULL )
2963  *upvalid = FALSE;
2964  if( downinf != NULL )
2965  *downinf = FALSE;
2966  if( upinf != NULL )
2967  *upinf = FALSE;
2968  if( downconflict != NULL )
2969  *downconflict = FALSE;
2970  if( upconflict != NULL )
2971  *upconflict = FALSE;
2972 
2974  {
2975  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
2976  return SCIP_INVALIDDATA;
2977  }
2978 
2979  col = SCIPvarGetCol(var);
2980  assert(col != NULL);
2981 
2982  if( !SCIPcolIsInLP(col) )
2983  {
2984  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
2985  return SCIP_INVALIDDATA;
2986  }
2987 
2988  /* check if the solving process should be aborted */
2989  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
2990  {
2991  /* mark this as if the LP failed */
2992  *lperror = TRUE;
2993  return SCIP_OKAY;
2994  }
2995 
2996  /* call strong branching for column with fractional value */
2997  SCIP_CALL( SCIPcolGetStrongbranch(col, FALSE, scip->set, scip->stat, scip->transprob, scip->lp, itlim, !idempotent, !idempotent,
2998  &localdown, &localup, &localdownvalid, &localupvalid, lperror) );
2999 
3000  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3001  * declare the sub nodes infeasible
3002  */
3003  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3004  {
3005  if( !idempotent ) /*lint !e774*/
3006  {
3007  SCIP_CALL( analyzeStrongbranch(scip, var, downinf, upinf, downconflict, upconflict) );
3008  }
3009  else
3010  {
3011  if( downinf != NULL )
3012  *downinf = localdownvalid && SCIPsetIsGE(scip->set, localdown, scip->lp->cutoffbound);
3013  if( upinf != NULL )
3014  *upinf = localupvalid && SCIPsetIsGE(scip->set, localup, scip->lp->cutoffbound);
3015  }
3016  }
3017 
3018  if( down != NULL )
3019  *down = localdown;
3020  if( up != NULL )
3021  *up = localup;
3022  if( downvalid != NULL )
3023  *downvalid = localdownvalid;
3024  if( upvalid != NULL )
3025  *upvalid = localupvalid;
3026 
3027  return SCIP_OKAY;
3028 }
3029 
3030 /** create, solve, and evaluate a single strong branching child (for strong branching with propagation) */
3031 static
3033  SCIP* scip, /**< SCIP data structure */
3034  SCIP_VAR* var, /**< variable to get strong branching values for */
3035  SCIP_Bool down, /**< do we regard the down child? */
3036  SCIP_Bool firstchild, /**< is this the first of the two strong branching children? */
3037  SCIP_Bool propagate, /**< should domain propagation be performed? */
3038  SCIP_Real newbound, /**< new bound to apply at the strong branching child */
3039  int itlim, /**< iteration limit for strong branchings */
3040  int maxproprounds, /**< maximum number of propagation rounds (-1: no limit, -2: parameter
3041  * settings) */
3042  SCIP_Real* value, /**< stores dual bound for strong branching child */
3043  SCIP_Bool* valid, /**< stores whether the returned value is a valid dual bound, or NULL;
3044  * otherwise, it can only be used as an estimate value */
3045  SCIP_Longint* ndomreductions, /**< pointer to store the number of domain reductions found, or NULL */
3046  SCIP_Bool* conflict, /**< pointer to store whether a conflict constraint was created for an
3047  * infeasible strong branching child, or NULL */
3048  SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred or the
3049  * solving process should be stopped (e.g., due to a time limit) */
3050  SCIP_VAR** vars, /**< active problem variables */
3051  int nvars, /**< number of active problem variables */
3052  SCIP_Real* newlbs, /**< array to store valid lower bounds for all active variables, or NULL */
3053  SCIP_Real* newubs, /**< array to store valid upper bounds for all active variables, or NULL */
3054  SCIP_Bool* foundsol, /**< pointer to store whether a primal solution was found during strong branching */
3055  SCIP_Bool* cutoff /**< pointer to store whether the strong branching child is infeasible */
3056  )
3057 {
3058  SCIP_Longint ndomreds;
3059 
3060  assert(value != NULL);
3061  assert(foundsol != NULL);
3062  assert(cutoff != NULL);
3063  assert(lperror != NULL);
3064  assert(valid != NULL ? !(*valid) : TRUE);
3065 
3066  *foundsol = FALSE;
3067  *cutoff = FALSE;
3068  *lperror = FALSE;
3069 
3070  /* check whether the strong branching child is already infeasible due to the bound change */
3071  if( down )
3072  {
3073  /* the down branch is infeasible due to the branching bound change; since this means that solval is not within the
3074  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3075  * are valid for and were already applied at the probing root
3076  */
3077  if( newbound < SCIPvarGetLbLocal(var) - 0.5 )
3078  {
3079  *value = SCIPinfinity(scip);
3080 
3081  if( valid != NULL )
3082  *valid = TRUE;
3083 
3084  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3085  if( conflict != NULL )
3086  *conflict = TRUE;
3087 
3088  *cutoff = TRUE;
3089 
3090  return SCIP_OKAY;
3091  }
3092  }
3093  else
3094  {
3095  /* the up branch is infeasible due to the branching bound change; since this means that solval is not within the
3096  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3097  * are valid for and were already applied at the probing root
3098  */
3099  if( newbound > SCIPvarGetUbLocal(var) + 0.5 )
3100  {
3101  *value = SCIPinfinity(scip);
3102 
3103  if( valid != NULL )
3104  *valid = TRUE;
3105 
3106  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3107  if( conflict != NULL )
3108  *conflict = TRUE;
3109 
3110  *cutoff = TRUE;
3111 
3112  return SCIP_OKAY;
3113  }
3114  }
3115 
3116  /* we need to ensure that we can create at least one new probing node without exceeding the maximal tree depth */
3118  {
3119  /* create a new probing node for the strong branching child and apply the new bound for the variable */
3120  SCIP_CALL( SCIPnewProbingNode(scip) );
3121 
3122  if( down )
3123  {
3124  assert(SCIPisGE(scip, newbound, SCIPvarGetLbLocal(var)));
3125  if( SCIPisLT(scip, newbound, SCIPvarGetUbLocal(var)) )
3126  {
3127  SCIP_CALL( SCIPchgVarUbProbing(scip, var, newbound) );
3128  }
3129  }
3130  else
3131  {
3132  assert(SCIPisLE(scip, newbound, SCIPvarGetUbLocal(var)));
3133  if( SCIPisGT(scip, newbound, SCIPvarGetLbLocal(var)) )
3134  {
3135  SCIP_CALL( SCIPchgVarLbProbing(scip, var, newbound) );
3136  }
3137  }
3138  }
3139  else
3140  {
3141  if( valid != NULL )
3142  *valid = FALSE;
3143 
3144  *cutoff = FALSE;
3145 
3146  if( conflict != NULL )
3147  *conflict = FALSE;
3148 
3149  return SCIP_OKAY;
3150  }
3151 
3152  /* propagate domains at the probing node */
3153  if( propagate )
3154  {
3155  /* start time measuring */
3156  SCIPclockStart(scip->stat->strongpropclock, scip->set);
3157 
3158  ndomreds = 0;
3159  SCIP_CALL( SCIPpropagateProbing(scip, maxproprounds, cutoff, &ndomreds) );
3160 
3161  /* store number of domain reductions in strong branching */
3162  if( down )
3163  SCIPstatAdd(scip->stat, scip->set, nsbdowndomchgs, ndomreds);
3164  else
3165  SCIPstatAdd(scip->stat, scip->set, nsbupdomchgs, ndomreds);
3166 
3167  if( ndomreductions != NULL )
3168  *ndomreductions = ndomreds;
3169 
3170  /* stop time measuring */
3171  SCIPclockStop(scip->stat->strongpropclock, scip->set);
3172 
3173  if( *cutoff )
3174  {
3175  *value = SCIPinfinity(scip);
3176 
3177  if( valid != NULL )
3178  *valid = TRUE;
3179 
3180  SCIPdebugMsg(scip, "%s branch of var <%s> detected infeasible during propagation\n",
3181  down ? "down" : "up", SCIPvarGetName(var));
3182  }
3183  }
3184 
3185  /* if propagation did not already detect infeasibility, solve the probing LP */
3186  if( !(*cutoff) )
3187  {
3188  SCIP_CALL( SCIPsolveProbingLP(scip, itlim, lperror, cutoff) );
3189  assert(SCIPisLPRelax(scip));
3190 
3191  if( *cutoff )
3192  {
3193  assert(!(*lperror));
3194 
3195  *value = SCIPinfinity(scip);
3196 
3197  if( valid != NULL )
3198  *valid = TRUE;
3199 
3200  SCIPdebugMsg(scip, "%s branch of var <%s> detected infeasible in LP solving: status=%d\n",
3201  down ? "down" : "up", SCIPvarGetName(var), SCIPgetLPSolstat(scip));
3202  }
3203  else if( !(*lperror) )
3204  {
3205  /* save the lp solution status */
3206  scip->stat->lastsblpsolstats[down ? 0 : 1] = SCIPgetLPSolstat(scip);
3207 
3208  switch( SCIPgetLPSolstat(scip) )
3209  {
3211  {
3212  *value = SCIPgetLPObjval(scip);
3213  assert(SCIPisLT(scip, *value, SCIPgetCutoffbound(scip)));
3214 
3215  SCIPdebugMsg(scip, "probing LP solved to optimality, objective value: %16.9g\n", *value);
3216 
3217  if( valid != NULL )
3218  *valid = TRUE;
3219 
3220  /* check the strong branching LP solution for feasibility */
3221  SCIP_CALL( SCIPtryStrongbranchLPSol(scip, foundsol, cutoff) );
3222  break;
3223  }
3225  ++scip->stat->nsbtimesiterlimhit;
3226  /*lint -fallthrough*/
3228  {
3229  /* use LP value as estimate */
3230  SCIP_LPI* lpi;
3231  SCIP_Real objval;
3232  SCIP_Real looseobjval;
3233 
3234  SCIPdebugMsg(scip, "probing LP hit %s limit\n", SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_ITERLIMIT ? "iteration" : "time");
3235 
3236  /* we access the LPI directly, because when a time limit was hit, we cannot access objective value and dual
3237  * feasibility using the SCIPlp... methods; we should try to avoid direct calls to the LPI, but this is rather
3238  * uncritical here, because we are immediately after the SCIPsolveProbingLP() call, because we access the LPI
3239  * read-only, and we check SCIPlpiWasSolved() first
3240  */
3241  SCIP_CALL( SCIPgetLPI(scip, &lpi) );
3242 
3243  if( SCIPlpiWasSolved(lpi) )
3244  {
3245  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
3246  looseobjval = SCIPlpGetLooseObjval(scip->lp, scip->set, scip->transprob);
3247 
3248  /* the infinity value in the LPI should not be smaller than SCIP's infinity value */
3249  assert(!SCIPlpiIsInfinity(lpi, objval) || SCIPisInfinity(scip, objval));
3250 
3251  /* we use SCIP's infinity value here because a value larger than this is counted as infeasible by SCIP */
3252  if( SCIPisInfinity(scip, objval) )
3253  *value = SCIPinfinity(scip);
3254  else if( SCIPisInfinity(scip, -looseobjval) )
3255  *value = -SCIPinfinity(scip);
3256  else
3257  *value = objval + looseobjval;
3258 
3259  if( SCIPlpiIsDualFeasible(lpi) )
3260  {
3261  if( valid != NULL )
3262  *valid = TRUE;
3263 
3264  if( SCIPisGE(scip, *value, SCIPgetCutoffbound(scip)) )
3265  *cutoff = TRUE;
3266  }
3267  }
3268  break;
3269  }
3270  case SCIP_LPSOLSTAT_ERROR:
3272  *lperror = TRUE;
3273  break;
3274  case SCIP_LPSOLSTAT_NOTSOLVED: /* should only be the case for *cutoff = TRUE or *lperror = TRUE */
3275  case SCIP_LPSOLSTAT_OBJLIMIT: /* in this case, *cutoff should be TRUE and we should not get here */
3276  case SCIP_LPSOLSTAT_INFEASIBLE: /* in this case, *cutoff should be TRUE and we should not get here */
3277  default:
3278  SCIPerrorMessage("invalid LP solution status <%d>\n", SCIPgetLPSolstat(scip));
3279  return SCIP_INVALIDDATA;
3280  } /*lint !e788*/
3281  }
3282 
3283  /* If columns are missing in the LP, the cutoff flag may be wrong. Therefore, we need to set it and the valid pointer
3284  * to false here.
3285  */
3286  if( (*cutoff) && !SCIPallColsInLP(scip) )
3287  {
3288  *cutoff = FALSE;
3289  }
3290 
3291 #ifndef NDEBUG
3292  if( *lperror )
3293  {
3294  SCIPdebugMsg(scip, "error during strong branching probing LP solving: status=%d\n", SCIPgetLPSolstat(scip));
3295  }
3296 #endif
3297  }
3298 
3299  /* if the subproblem was feasible, we store the local bounds of the variables after propagation and (possibly)
3300  * conflict analysis
3301  * @todo do this after propagation? should be able to get valid bounds more often, but they might be weaker
3302  */
3303  if( !(*cutoff) && newlbs != NULL)
3304  {
3305  int v;
3306 
3307  assert(newubs != NULL);
3308 
3309  /* initialize the newlbs and newubs to the current local bounds */
3310  if( firstchild )
3311  {
3312  for( v = 0; v < nvars; ++v )
3313  {
3314  newlbs[v] = SCIPvarGetLbLocal(vars[v]);
3315  newubs[v] = SCIPvarGetUbLocal(vars[v]);
3316  }
3317  }
3318  /* update newlbs and newubs: take the weaker of the already stored bounds and the current local bounds */
3319  else
3320  {
3321  for( v = 0; v < nvars; ++v )
3322  {
3323  SCIP_Real lb = SCIPvarGetLbLocal(vars[v]);
3324  SCIP_Real ub = SCIPvarGetUbLocal(vars[v]);
3325 
3326  newlbs[v] = MIN(newlbs[v], lb);
3327  newubs[v] = MAX(newubs[v], ub);
3328  }
3329  }
3330  }
3331 
3332  /* revert all changes at the probing node */
3333  SCIP_CALL( SCIPbacktrackProbing(scip, 0) );
3334 
3335  return SCIP_OKAY;
3336 }
3337 
3338 /** gets strong branching information with previous domain propagation on column variable
3339  *
3340  * Before calling this method, the strong branching mode must have been activated by calling SCIPstartStrongbranch();
3341  * after strong branching was done for all candidate variables, the strong branching mode must be ended by
3342  * SCIPendStrongbranch(). Since this method applies domain propagation before strongbranching, propagation has to be be
3343  * enabled in the SCIPstartStrongbranch() call.
3344  *
3345  * Before solving the strong branching LP, domain propagation can be performed. The number of propagation rounds
3346  * can be specified by the parameter @p maxproprounds.
3347  *
3348  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3349  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3350  *
3351  * @pre This method can be called if @p scip is in one of the following stages:
3352  * - \ref SCIP_STAGE_PRESOLVED
3353  * - \ref SCIP_STAGE_SOLVING
3354  *
3355  * @warning When using this method, LP banching candidates and solution values must be copied beforehand, because
3356  * they are updated w.r.t. the strong branching LP solution.
3357  */
3359  SCIP* scip, /**< SCIP data structure */
3360  SCIP_VAR* var, /**< variable to get strong branching values for */
3361  SCIP_Real solval, /**< value of the variable in the current LP solution */
3362  SCIP_Real lpobjval, /**< LP objective value of the current LP solution */
3363  int itlim, /**< iteration limit for strong branchings */
3364  int maxproprounds, /**< maximum number of propagation rounds (-1: no limit, -2: parameter
3365  * settings) */
3366  SCIP_Real* down, /**< stores dual bound after branching column down */
3367  SCIP_Real* up, /**< stores dual bound after branching column up */
3368  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
3369  * otherwise, it can only be used as an estimate value */
3370  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
3371  * otherwise, it can only be used as an estimate value */
3372  SCIP_Longint* ndomredsdown, /**< pointer to store the number of domain reductions down, or NULL */
3373  SCIP_Longint* ndomredsup, /**< pointer to store the number of domain reductions up, or NULL */
3374  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
3375  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
3376  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
3377  * infeasible downwards branch, or NULL */
3378  SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
3379  * infeasible upwards branch, or NULL */
3380  SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred or the
3381  * solving process should be stopped (e.g., due to a time limit) */
3382  SCIP_Real* newlbs, /**< array to store valid lower bounds for all active variables, or NULL */
3383  SCIP_Real* newubs /**< array to store valid upper bounds for all active variables, or NULL */
3384  )
3385 {
3386  SCIP_COL* col;
3387  SCIP_VAR** vars;
3388  SCIP_Longint oldniters;
3389  SCIP_Real newub;
3390  SCIP_Real newlb;
3391  SCIP_Bool propagate;
3392  SCIP_Bool cutoff;
3393  SCIP_Bool downchild;
3394  SCIP_Bool firstchild;
3395  SCIP_Bool foundsol;
3396  SCIP_Bool downvalidlocal;
3397  SCIP_Bool upvalidlocal;
3398  SCIP_Bool allcolsinlp;
3399  SCIP_Bool enabledconflict;
3400  int oldnconflicts;
3401  int nvars;
3402 
3403  assert(scip != NULL);
3404  assert(var != NULL);
3405  assert(SCIPvarIsIntegral(var));
3406  assert(down != NULL);
3407  assert(up != NULL);
3408  assert(lperror != NULL);
3409  assert((newlbs != NULL) == (newubs != NULL));
3410  assert(SCIPinProbing(scip));
3411  assert(var->scip == scip);
3412 
3413  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchWithPropagation", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3414 
3415  /* check whether propagation should be performed */
3416  propagate = (maxproprounds != 0 && maxproprounds != -3);
3417 
3418  /* Check, if all existing columns are in LP.
3419  * If this is not the case, we may still return that the up and down dual bounds are valid, because the branching
3420  * rule should not apply them otherwise.
3421  * However, we must not set the downinf or upinf pointers to TRUE based on the dual bound, because we cannot
3422  * guarantee that this node can be cut off.
3423  */
3424  allcolsinlp = SCIPallColsInLP(scip);
3425 
3426  /* if maxproprounds is -2, change it to 0, which for the following calls means using the parameter settings */
3427  if( maxproprounds == -2 )
3428  maxproprounds = 0;
3429 
3430  *down = lpobjval;
3431  *up = lpobjval;
3432  if( downvalid != NULL )
3433  *downvalid = FALSE;
3434  if( upvalid != NULL )
3435  *upvalid = FALSE;
3436  if( downinf != NULL )
3437  *downinf = FALSE;
3438  if( upinf != NULL )
3439  *upinf = FALSE;
3440  if( downconflict != NULL )
3441  *downconflict = FALSE;
3442  if( upconflict != NULL )
3443  *upconflict = FALSE;
3444  if( ndomredsdown != NULL )
3445  *ndomredsdown = 0;
3446  if( ndomredsup != NULL )
3447  *ndomredsup = 0;
3448 
3449  *lperror = FALSE;
3450 
3451  vars = SCIPgetVars(scip);
3452  nvars = SCIPgetNVars(scip);
3453 
3455 
3456  /* check if the solving process should be aborted */
3457  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3458  {
3459  /* mark this as if the LP failed */
3460  *lperror = TRUE;
3461  return SCIP_OKAY;
3462  }
3463 
3465  {
3466  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3467  return SCIP_INVALIDDATA;
3468  }
3469 
3470  col = SCIPvarGetCol(var);
3471  assert(col != NULL);
3472 
3473  if( !SCIPcolIsInLP(col) )
3474  {
3475  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3476  return SCIP_INVALIDDATA;
3477  }
3478 
3479  newlb = SCIPfeasFloor(scip, solval + 1.0);
3480  newub = SCIPfeasCeil(scip, solval - 1.0);
3481 
3482  SCIPdebugMsg(scip, "strong branching on var <%s>: solval=%g, lb=%g, ub=%g\n", SCIPvarGetName(var), solval,
3484 
3485  /* the up branch is infeasible due to the branching bound change; since this means that solval is not within the
3486  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3487  * are valid for and were already applied at the probing root
3488  */
3489  if( newlb > SCIPvarGetUbLocal(var) + 0.5 )
3490  {
3491  *up = SCIPinfinity(scip);
3492 
3493  if( upinf != NULL )
3494  *upinf = TRUE;
3495 
3496  if( upvalid != NULL )
3497  *upvalid = TRUE;
3498 
3499  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3500  if( upconflict != NULL )
3501  *upconflict = TRUE;
3502 
3503  SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3504  *down, *up, FALSE, TRUE, 0LL, INT_MAX);
3505 
3506  /* we do not regard the down branch; its valid pointer stays set to FALSE */
3507  return SCIP_OKAY;
3508  }
3509 
3510  /* the down branch is infeasible due to the branching bound change; since this means that solval is not within the
3511  * bounds, this should only happen if previous strong branching calls on other variables detected bound changes which
3512  * are valid for and were already applied at the probing root
3513  */
3514  if( newub < SCIPvarGetLbLocal(var) - 0.5 )
3515  {
3516  *down = SCIPinfinity(scip);
3517 
3518  if( downinf != NULL )
3519  *downinf = TRUE;
3520 
3521  if( downvalid != NULL )
3522  *downvalid = TRUE;
3523 
3524  /* bound changes are applied in SCIPendStrongbranch(), which can be seen as a conflict constraint */
3525  if( downconflict != NULL )
3526  *downconflict = TRUE;
3527 
3528  SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3529  *down, *up, TRUE, FALSE, 0LL, INT_MAX);
3530 
3531  /* we do not regard the up branch; its valid pointer stays set to FALSE */
3532  return SCIP_OKAY;
3533  }
3534 
3535  /* We now do strong branching by creating the two potential child nodes as probing nodes and solving them one after
3536  * the other. We will stop when the first child is detected infeasible, saving the effort we would need for the
3537  * second child. Since empirically, the up child tends to be infeasible more often, we do strongbranching first on
3538  * the up branch.
3539  */
3540  oldniters = scip->stat->nsbdivinglpiterations;
3541  firstchild = TRUE;
3542  cutoff = FALSE;
3543 
3544  /* switch conflict analysis according to usesb parameter */
3545  enabledconflict = scip->set->conf_enable;
3546  scip->set->conf_enable = (scip->set->conf_enable && scip->set->conf_usesb);
3547 
3548  /* @todo: decide the branch to look at first based on the cutoffs in previous calls? */
3549  downchild = SCIPisStrongbranchDownFirst(scip, var);
3550 
3551  downvalidlocal = FALSE;
3552  upvalidlocal = FALSE;
3553 
3554  do
3555  {
3556  oldnconflicts = SCIPconflictGetNConflicts(scip->conflict);
3557 
3558  if( downchild )
3559  {
3560  SCIP_CALL( performStrongbranchWithPropagation(scip, var, downchild, firstchild, propagate, newub, itlim, maxproprounds,
3561  down, &downvalidlocal, ndomredsdown, downconflict, lperror, vars, nvars, newlbs, newubs, &foundsol, &cutoff) );
3562 
3563  /* check whether a new solutions rendered the previous child infeasible */
3564  if( foundsol && !firstchild && allcolsinlp )
3565  {
3566  if( SCIPisGE(scip, *up, SCIPgetCutoffbound(scip)) )
3567  {
3568  if( upinf != NULL )
3569  *upinf = TRUE;
3570  }
3571  }
3572 
3573  /* check for infeasibility */
3574  if( cutoff )
3575  {
3576  if( downinf != NULL )
3577  *downinf = TRUE;
3578 
3579  if( downconflict != NULL &&
3580  (SCIPvarGetLbLocal(var) > newub + 0.5 || SCIPconflictGetNConflicts(scip->conflict) > oldnconflicts) )
3581  {
3582  *downconflict = TRUE;
3583  }
3584 
3585  if( !scip->set->branch_forceall )
3586  {
3587  /* if this is the first call, we do not regard the up branch, its valid pointer is initially set to FALSE */
3588  break;
3589  }
3590  }
3591  }
3592  else
3593  {
3594  SCIP_CALL( performStrongbranchWithPropagation(scip, var, downchild, firstchild, propagate, newlb, itlim, maxproprounds,
3595  up, &upvalidlocal, ndomredsup, upconflict, lperror, vars, nvars, newlbs, newubs, &foundsol, &cutoff) );
3596 
3597  /* check whether a new solutions rendered the previous child infeasible */
3598  if( foundsol && !firstchild && allcolsinlp )
3599  {
3600  if( SCIPisGE(scip, *down, SCIPgetCutoffbound(scip)) )
3601  {
3602  if( downinf != NULL )
3603  *downinf = TRUE;
3604  }
3605  }
3606 
3607  /* check for infeasibility */
3608  if( cutoff )
3609  {
3610  if( upinf != NULL )
3611  *upinf = TRUE;
3612 
3613  assert(upinf == NULL || (*upinf) == TRUE);
3614 
3615  if( upconflict != NULL &&
3616  (SCIPvarGetUbLocal(var) < newlb - 0.5 || SCIPconflictGetNConflicts(scip->conflict) > oldnconflicts) )
3617  {
3618  *upconflict = TRUE;
3619  }
3620 
3621  if( !scip->set->branch_forceall )
3622  {
3623  /* if this is the first call, we do not regard the down branch, its valid pointer is initially set to FALSE */
3624  break;
3625  }
3626  }
3627  }
3628 
3629  downchild = !downchild;
3630  firstchild = !firstchild;
3631  }
3632  while( !firstchild );
3633 
3634  /* set strong branching information in column */
3635  if( *lperror )
3636  {
3637  SCIPcolInvalidateStrongbranchData(col, scip->set, scip->stat, scip->lp);
3638  }
3639  else
3640  {
3641  SCIPcolSetStrongbranchData(col, scip->set, scip->stat, scip->lp, lpobjval, solval,
3642  *down, *up, downvalidlocal, upvalidlocal, scip->stat->nsbdivinglpiterations - oldniters, itlim);
3643  }
3644 
3645  if( downvalid != NULL )
3646  *downvalid = downvalidlocal;
3647  if( upvalid != NULL )
3648  *upvalid = upvalidlocal;
3649 
3650  scip->set->conf_enable = enabledconflict;
3651 
3652  return SCIP_OKAY; /*lint !e438*/
3653 }
3654 
3655 /** gets strong branching information on column variable x with integral LP solution value (val); that is, the down branch
3656  * is (val -1.0) and the up brach ins (val +1.0)
3657  *
3658  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3659  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3660  *
3661  * @pre This method can be called if @p scip is in one of the following stages:
3662  * - \ref SCIP_STAGE_PRESOLVED
3663  * - \ref SCIP_STAGE_SOLVING
3664  *
3665  * @note If the integral LP solution value is the lower or upper bound of the variable, the corresponding branch will be
3666  * marked as infeasible. That is, the valid pointer and the infeasible pointer are set to TRUE.
3667  */
3669  SCIP* scip, /**< SCIP data structure */
3670  SCIP_VAR* var, /**< variable to get strong branching values for */
3671  int itlim, /**< iteration limit for strong branchings */
3672  SCIP_Bool idempotent, /**< should scip's state remain the same after the call (statistics, column states...), or should it be updated ? */
3673  SCIP_Real* down, /**< stores dual bound after branching column down */
3674  SCIP_Real* up, /**< stores dual bound after branching column up */
3675  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
3676  * otherwise, it can only be used as an estimate value */
3677  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
3678  * otherwise, it can only be used as an estimate value */
3679  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
3680  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
3681  SCIP_Bool* downconflict, /**< pointer to store whether a conflict constraint was created for an
3682  * infeasible downwards branch, or NULL */
3683  SCIP_Bool* upconflict, /**< pointer to store whether a conflict constraint was created for an
3684  * infeasible upwards branch, or NULL */
3685  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3686  * solving process should be stopped (e.g., due to a time limit) */
3687  )
3688 {
3689  SCIP_COL* col;
3690  SCIP_Real localdown;
3691  SCIP_Real localup;
3692  SCIP_Bool localdownvalid;
3693  SCIP_Bool localupvalid;
3694 
3695  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchInt", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3696 
3697  assert(lperror != NULL);
3698  assert(var->scip == scip);
3699 
3700  if( downvalid != NULL )
3701  *downvalid = FALSE;
3702  if( upvalid != NULL )
3703  *upvalid = FALSE;
3704  if( downinf != NULL )
3705  *downinf = FALSE;
3706  if( upinf != NULL )
3707  *upinf = FALSE;
3708  if( downconflict != NULL )
3709  *downconflict = FALSE;
3710  if( upconflict != NULL )
3711  *upconflict = FALSE;
3712 
3714  {
3715  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3716  return SCIP_INVALIDDATA;
3717  }
3718 
3719  col = SCIPvarGetCol(var);
3720  assert(col != NULL);
3721 
3722  if( !SCIPcolIsInLP(col) )
3723  {
3724  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3725  return SCIP_INVALIDDATA;
3726  }
3727 
3728  /* check if the solving process should be aborted */
3729  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3730  {
3731  /* mark this as if the LP failed */
3732  *lperror = TRUE;
3733  return SCIP_OKAY;
3734  }
3735 
3736  /* call strong branching for column */
3737  SCIP_CALL( SCIPcolGetStrongbranch(col, TRUE, scip->set, scip->stat, scip->transprob, scip->lp, itlim, !idempotent, !idempotent,
3738  &localdown, &localup, &localdownvalid, &localupvalid, lperror) );
3739 
3740  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3741  * declare the sub nodes infeasible
3742  */
3743  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3744  {
3745  if( !idempotent ) /*lint !e774*/
3746  {
3747  SCIP_CALL( analyzeStrongbranch(scip, var, downinf, upinf, downconflict, upconflict) );
3748  }
3749  else
3750  {
3751  if( downinf != NULL )
3752  *downinf = localdownvalid && SCIPsetIsGE(scip->set, localdown, scip->lp->cutoffbound);
3753  if( upinf != NULL )
3754  *upinf = localupvalid && SCIPsetIsGE(scip->set, localup, scip->lp->cutoffbound);
3755  }
3756  }
3757 
3758  if( down != NULL )
3759  *down = localdown;
3760  if( up != NULL )
3761  *up = localup;
3762  if( downvalid != NULL )
3763  *downvalid = localdownvalid;
3764  if( upvalid != NULL )
3765  *upvalid = localupvalid;
3766 
3767  return SCIP_OKAY;
3768 }
3769 
3770 /** gets strong branching information on column variables with fractional values
3771  *
3772  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3773  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3774  *
3775  * @pre This method can be called if @p scip is in one of the following stages:
3776  * - \ref SCIP_STAGE_PRESOLVED
3777  * - \ref SCIP_STAGE_SOLVING
3778  */
3780  SCIP* scip, /**< SCIP data structure */
3781  SCIP_VAR** vars, /**< variables to get strong branching values for */
3782  int nvars, /**< number of variables */
3783  int itlim, /**< iteration limit for strong branchings */
3784  SCIP_Real* down, /**< stores dual bounds after branching variables down */
3785  SCIP_Real* up, /**< stores dual bounds after branching variables up */
3786  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
3787  * otherwise, they can only be used as an estimate value */
3788  SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
3789  * otherwise, they can only be used as an estimate value */
3790  SCIP_Bool* downinf, /**< array to store whether the downward branches are infeasible, or NULL */
3791  SCIP_Bool* upinf, /**< array to store whether the upward branches are infeasible, or NULL */
3792  SCIP_Bool* downconflict, /**< array to store whether conflict constraints were created for
3793  * infeasible downward branches, or NULL */
3794  SCIP_Bool* upconflict, /**< array to store whether conflict constraints were created for
3795  * infeasible upward branches, or NULL */
3796  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3797  * solving process should be stopped (e.g., due to a time limit) */
3798  )
3799 {
3800  SCIP_COL** cols;
3801  int j;
3802 
3803  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarsStrongbranchesFrac", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3804 
3805  assert( lperror != NULL );
3806  assert( vars != NULL );
3807 
3808  /* set up data */
3809  cols = NULL;
3810  SCIP_CALL( SCIPallocBufferArray(scip, &cols, nvars) );
3811  assert(cols != NULL);
3812  for( j = 0; j < nvars; ++j )
3813  {
3814  SCIP_VAR* var;
3815  SCIP_COL* col;
3816 
3817  if( downvalid != NULL )
3818  downvalid[j] = FALSE;
3819  if( upvalid != NULL )
3820  upvalid[j] = FALSE;
3821  if( downinf != NULL )
3822  downinf[j] = FALSE;
3823  if( upinf != NULL )
3824  upinf[j] = FALSE;
3825  if( downconflict != NULL )
3826  downconflict[j] = FALSE;
3827  if( upconflict != NULL )
3828  upconflict[j] = FALSE;
3829 
3830  var = vars[j];
3831  assert( var != NULL );
3833  {
3834  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3835  SCIPfreeBufferArray(scip, &cols);
3836  return SCIP_INVALIDDATA;
3837  }
3838 
3839  col = SCIPvarGetCol(var);
3840  assert(col != NULL);
3841  cols[j] = col;
3842 
3843  if( !SCIPcolIsInLP(col) )
3844  {
3845  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3846  SCIPfreeBufferArray(scip, &cols);
3847  return SCIP_INVALIDDATA;
3848  }
3849  }
3850 
3851  /* check if the solving process should be aborted */
3852  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3853  {
3854  /* mark this as if the LP failed */
3855  *lperror = TRUE;
3856  }
3857  else
3858  {
3859  /* call strong branching for columns with fractional value */
3860  SCIP_CALL( SCIPcolGetStrongbranches(cols, nvars, FALSE, scip->set, scip->stat, scip->transprob, scip->lp, itlim,
3861  down, up, downvalid, upvalid, lperror) );
3862 
3863  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3864  * declare the sub nodes infeasible
3865  */
3866  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3867  {
3868  for( j = 0; j < nvars; ++j )
3869  {
3870  SCIP_CALL( analyzeStrongbranch(scip, vars[j], (downinf != NULL) ? (&(downinf[j])) : NULL,
3871  (upinf != NULL) ? (&(upinf[j])) : NULL, (downconflict != NULL) ? (&(downconflict[j])) : NULL,
3872  (upconflict != NULL) ? (&(upconflict[j])) : NULL) );
3873  }
3874  }
3875  }
3876  SCIPfreeBufferArray(scip, &cols);
3877 
3878  return SCIP_OKAY;
3879 }
3880 
3881 /** gets strong branching information on column variables with integral values
3882  *
3883  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3884  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3885  *
3886  * @pre This method can be called if @p scip is in one of the following stages:
3887  * - \ref SCIP_STAGE_PRESOLVED
3888  * - \ref SCIP_STAGE_SOLVING
3889  */
3891  SCIP* scip, /**< SCIP data structure */
3892  SCIP_VAR** vars, /**< variables to get strong branching values for */
3893  int nvars, /**< number of variables */
3894  int itlim, /**< iteration limit for strong branchings */
3895  SCIP_Real* down, /**< stores dual bounds after branching variables down */
3896  SCIP_Real* up, /**< stores dual bounds after branching variables up */
3897  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
3898  * otherwise, they can only be used as an estimate value */
3899  SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
3900  * otherwise, they can only be used as an estimate value */
3901  SCIP_Bool* downinf, /**< array to store whether the downward branches are infeasible, or NULL */
3902  SCIP_Bool* upinf, /**< array to store whether the upward branches are infeasible, or NULL */
3903  SCIP_Bool* downconflict, /**< array to store whether conflict constraints were created for
3904  * infeasible downward branches, or NULL */
3905  SCIP_Bool* upconflict, /**< array to store whether conflict constraints were created for
3906  * infeasible upward branches, or NULL */
3907  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred or the
3908  * solving process should be stopped (e.g., due to a time limit) */
3909  )
3910 {
3911  SCIP_COL** cols;
3912  int j;
3913 
3914  assert(lperror != NULL);
3915 
3916  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarsStrongbranchesInt", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3917 
3918  assert( vars != NULL );
3919 
3920  /* set up data */
3921  cols = NULL;
3922  SCIP_CALL( SCIPallocBufferArray(scip, &cols, nvars) );
3923  assert(cols != NULL);
3924  for( j = 0; j < nvars; ++j )
3925  {
3926  SCIP_VAR* var;
3927  SCIP_COL* col;
3928 
3929  if( downvalid != NULL )
3930  downvalid[j] = FALSE;
3931  if( upvalid != NULL )
3932  upvalid[j] = FALSE;
3933  if( downinf != NULL )
3934  downinf[j] = FALSE;
3935  if( upinf != NULL )
3936  upinf[j] = FALSE;
3937  if( downconflict != NULL )
3938  downconflict[j] = FALSE;
3939  if( upconflict != NULL )
3940  upconflict[j] = FALSE;
3941 
3942  var = vars[j];
3943  assert( var != NULL );
3945  {
3946  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable <%s>\n", SCIPvarGetName(var));
3947  SCIPfreeBufferArray(scip, &cols);
3948  return SCIP_INVALIDDATA;
3949  }
3950 
3951  col = SCIPvarGetCol(var);
3952  assert(col != NULL);
3953  cols[j] = col;
3954 
3955  if( !SCIPcolIsInLP(col) )
3956  {
3957  SCIPerrorMessage("cannot get strong branching information on variable <%s> not in current LP\n", SCIPvarGetName(var));
3958  SCIPfreeBufferArray(scip, &cols);
3959  return SCIP_INVALIDDATA;
3960  }
3961  }
3962 
3963  /* check if the solving process should be aborted */
3964  if( SCIPsolveIsStopped(scip->set, scip->stat, FALSE) )
3965  {
3966  /* mark this as if the LP failed */
3967  *lperror = TRUE;
3968  }
3969  else
3970  {
3971  /* call strong branching for columns */
3972  SCIP_CALL( SCIPcolGetStrongbranches(cols, nvars, TRUE, scip->set, scip->stat, scip->transprob, scip->lp, itlim,
3973  down, up, downvalid, upvalid, lperror) );
3974 
3975  /* check, if the branchings are infeasible; in exact solving mode, we cannot trust the strong branching enough to
3976  * declare the sub nodes infeasible
3977  */
3978  if( !(*lperror) && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->set->misc_exactsolve )
3979  {
3980  for( j = 0; j < nvars; ++j )
3981  {
3982  SCIP_CALL( analyzeStrongbranch(scip, vars[j], (downinf != NULL) ? (&(downinf[j])) : NULL,
3983  (upinf != NULL) ? (&(upinf[j])) : NULL, (downconflict != NULL) ? (&(downconflict[j])) : NULL,
3984  (upconflict != NULL) ? (&(upconflict[j])) : NULL) );
3985  }
3986  }
3987  }
3988  SCIPfreeBufferArray(scip, &cols);
3989 
3990  return SCIP_OKAY;
3991 }
3992 
3993 /** get LP solution status of last strong branching call (currently only works for strong branching with propagation) */
3995  SCIP* scip, /**< SCIP data structure */
3996  SCIP_BRANCHDIR branchdir /**< branching direction for which LP solution status is requested */
3997  )
3998 {
3999  assert(NULL != scip);
4000  assert(branchdir == SCIP_BRANCHDIR_DOWNWARDS || branchdir == SCIP_BRANCHDIR_UPWARDS);
4001 
4002  return scip->stat->lastsblpsolstats[branchdir == SCIP_BRANCHDIR_DOWNWARDS ? 0 : 1];
4003 }
4004 
4005 /** gets strong branching information on COLUMN variable of the last SCIPgetVarStrongbranch() call;
4006  * returns values of SCIP_INVALID, if strong branching was not yet called on the given variable;
4007  * keep in mind, that the returned old values may have nothing to do with the current LP solution
4008  *
4009  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4010  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4011  *
4012  * @pre This method can be called if @p scip is in one of the following stages:
4013  * - \ref SCIP_STAGE_SOLVING
4014  * - \ref SCIP_STAGE_SOLVED
4015  */
4017  SCIP* scip, /**< SCIP data structure */
4018  SCIP_VAR* var, /**< variable to get last strong branching values for */
4019  SCIP_Real* down, /**< stores dual bound after branching column down */
4020  SCIP_Real* up, /**< stores dual bound after branching column up */
4021  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4022  * otherwise, it can only be used as an estimate value */
4023  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4024  * otherwise, it can only be used as an estimate value */
4025  SCIP_Real* solval, /**< stores LP solution value of variable at the last strong branching call, or NULL */
4026  SCIP_Real* lpobjval /**< stores LP objective value at last strong branching call, or NULL */
4027  )
4028 {
4029  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarStrongbranchLast", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
4030 
4032  {
4033  SCIPerrorMessage("cannot get strong branching information on non-COLUMN variable\n");
4034  return SCIP_INVALIDDATA;
4035  }
4036 
4037  SCIPcolGetStrongbranchLast(SCIPvarGetCol(var), down, up, downvalid, upvalid, solval, lpobjval);
4038 
4039  return SCIP_OKAY;
4040 }
4041 
4042 /** sets strong branching information for a column variable
4043  *
4044  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4045  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4046  *
4047  * @pre This method can be called if @p scip is in one of the following stages:
4048  * - \ref SCIP_STAGE_SOLVING
4049  */
4051  SCIP* scip, /**< SCIP data structure */
4052  SCIP_VAR* var, /**< variable to set last strong branching values for */
4053  SCIP_Real lpobjval, /**< objective value of the current LP */
4054  SCIP_Real primsol, /**< primal solution value of the column in the current LP */
4055  SCIP_Real down, /**< dual bound after branching column down */
4056  SCIP_Real up, /**< dual bound after branching column up */
4057  SCIP_Bool downvalid, /**< is the returned down value a valid dual bound? */
4058  SCIP_Bool upvalid, /**< is the returned up value a valid dual bound? */
4059  SCIP_Longint iter, /**< total number of strong branching iterations */
4060  int itlim /**< iteration limit applied to the strong branching call */
4061  )
4062 {
4063  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetVarStrongbranchData", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4064 
4066  {
4067  SCIPerrorMessage("cannot set strong branching information on non-COLUMN variable\n");
4068  return SCIP_INVALIDDATA;
4069  }
4070 
4071  SCIPcolSetStrongbranchData(SCIPvarGetCol(var), scip->set, scip->stat, scip->lp, lpobjval, primsol,
4072  down, up, downvalid, upvalid, iter, itlim);
4073 
4074  return SCIP_OKAY;
4075 }
4076 
4077 /** rounds the current solution and tries it afterwards; if feasible, adds it to storage
4078  *
4079  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4080  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4081  *
4082  * @pre This method can be called if @p scip is in one of the following stages:
4083  * - \ref SCIP_STAGE_SOLVING
4084  */
4086  SCIP* scip, /**< SCIP data structure */
4087  SCIP_Bool* foundsol, /**< stores whether solution was feasible and good enough to keep */
4088  SCIP_Bool* cutoff /**< stores whether solution was cutoff due to exceeding the cutoffbound */
4089  )
4090 {
4091  assert(scip != NULL);
4092  assert(foundsol != NULL);
4093  assert(cutoff != NULL);
4094 
4095  SCIP_CALL( SCIPcheckStage(scip, "SCIPtryStrongbranchLPSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4096 
4097  if( scip->set->branch_checksbsol )
4098  {
4099  SCIP_SOL* sol;
4100  SCIP_Bool rounded = TRUE;
4101  SCIP_Real value = SCIPgetLPObjval(scip);
4102  SCIP_Longint oldnbestsolsfound = scip->primal->nbestsolsfound;
4103 
4104  /* start clock for strong branching solutions */
4105  SCIPclockStart(scip->stat->sbsoltime, scip->set);
4106 
4107  SCIP_CALL( SCIPcreateLPSol(scip, &sol, NULL) );
4109 
4110  /* try to round the strong branching solution */
4111  if( scip->set->branch_roundsbsol )
4112  {
4113  SCIP_CALL( SCIProundSol(scip, sol, &rounded) );
4114  }
4115 
4116  /* check the solution for feasibility if rounding worked well (or was not tried) */
4117  if( rounded )
4118  {
4119  SCIP_CALL( SCIPtrySolFree(scip, &sol, FALSE, FALSE, FALSE, TRUE, FALSE, foundsol) );
4120  }
4121  else
4122  {
4123  SCIP_CALL( SCIPfreeSol(scip, &sol) );
4124  }
4125 
4126  if( *foundsol )
4127  {
4128  SCIPdebugMsg(scip, "found new solution in strong branching\n");
4129 
4130  scip->stat->nsbsolsfound++;
4131 
4132  if( scip->primal->nbestsolsfound != oldnbestsolsfound )
4133  {
4134  scip->stat->nsbbestsolsfound++;
4135  }
4136 
4137  if( SCIPisGE(scip, value, SCIPgetCutoffbound(scip)) )
4138  *cutoff = TRUE;
4139  }
4140 
4141  /* stop clock for strong branching solutions */
4142  SCIPclockStop(scip->stat->sbsoltime, scip->set);
4143  }
4144  return SCIP_OKAY;
4145 }
4146 
4147 
4148 /** gets node number of the last node in current branch and bound run, where strong branching was used on the
4149  * given variable, or -1 if strong branching was never applied to the variable in current run
4150  *
4151  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4152  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4153  *
4154  * @pre This method can be called if @p scip is in one of the following stages:
4155  * - \ref SCIP_STAGE_TRANSFORMING
4156  * - \ref SCIP_STAGE_TRANSFORMED
4157  * - \ref SCIP_STAGE_INITPRESOLVE
4158  * - \ref SCIP_STAGE_PRESOLVING
4159  * - \ref SCIP_STAGE_EXITPRESOLVE
4160  * - \ref SCIP_STAGE_PRESOLVED
4161  * - \ref SCIP_STAGE_INITSOLVE
4162  * - \ref SCIP_STAGE_SOLVING
4163  * - \ref SCIP_STAGE_SOLVED
4164  * - \ref SCIP_STAGE_EXITSOLVE
4165  */
4167  SCIP* scip, /**< SCIP data structure */
4168  SCIP_VAR* var /**< variable to get last strong branching node for */
4169  )
4170 {
4171  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarStrongbranchNode", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4172 
4173  assert( var->scip == scip );
4174 
4176  return -1;
4177 
4179 }
4180 
4181 /** if strong branching was already applied on the variable at the current node, returns the number of LPs solved after
4182  * the LP where the strong branching on this variable was applied;
4183  * if strong branching was not yet applied on the variable at the current node, returns INT_MAX
4184  *
4185  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4186  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4187  *
4188  * @pre This method can be called if @p scip is in one of the following stages:
4189  * - \ref SCIP_STAGE_TRANSFORMING
4190  * - \ref SCIP_STAGE_TRANSFORMED
4191  * - \ref SCIP_STAGE_INITPRESOLVE
4192  * - \ref SCIP_STAGE_PRESOLVING
4193  * - \ref SCIP_STAGE_EXITPRESOLVE
4194  * - \ref SCIP_STAGE_PRESOLVED
4195  * - \ref SCIP_STAGE_INITSOLVE
4196  * - \ref SCIP_STAGE_SOLVING
4197  * - \ref SCIP_STAGE_SOLVED
4198  * - \ref SCIP_STAGE_EXITSOLVE
4199  */
4201  SCIP* scip, /**< SCIP data structure */
4202  SCIP_VAR* var /**< variable to get strong branching LP age for */
4203  )
4204 {
4205  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarStrongbranchLPAge", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4206 
4207  assert( var->scip == scip );
4208 
4210  return SCIP_LONGINT_MAX;
4211 
4212  return SCIPcolGetStrongbranchLPAge(SCIPvarGetCol(var), scip->stat);
4213 }
4214 
4215 /** gets number of times, strong branching was applied in current run on the given variable
4216  *
4217  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4218  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4219  *
4220  * @pre This method can be called if @p scip is in one of the following stages:
4221  * - \ref SCIP_STAGE_TRANSFORMING
4222  * - \ref SCIP_STAGE_TRANSFORMED
4223  * - \ref SCIP_STAGE_INITPRESOLVE
4224  * - \ref SCIP_STAGE_PRESOLVING
4225  * - \ref SCIP_STAGE_EXITPRESOLVE
4226  * - \ref SCIP_STAGE_PRESOLVED
4227  * - \ref SCIP_STAGE_INITSOLVE
4228  * - \ref SCIP_STAGE_SOLVING
4229  * - \ref SCIP_STAGE_SOLVED
4230  * - \ref SCIP_STAGE_EXITSOLVE
4231  */
4233  SCIP* scip, /**< SCIP data structure */
4234  SCIP_VAR* var /**< variable to get last strong branching node for */
4235  )
4236 {
4237  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarNStrongbranchs", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
4238 
4239  assert( var->scip == scip );
4240 
4242  return 0;
4243 
4245 }
4246 
4247 /** adds given values to lock numbers of type @p locktype of variable for rounding
4248  *
4249  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4250  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4251  *
4252  * @pre This method can be called if @p scip is in one of the following stages:
4253  * - \ref SCIP_STAGE_PROBLEM
4254  * - \ref SCIP_STAGE_TRANSFORMING
4255  * - \ref SCIP_STAGE_TRANSFORMED
4256  * - \ref SCIP_STAGE_INITPRESOLVE
4257  * - \ref SCIP_STAGE_PRESOLVING
4258  * - \ref SCIP_STAGE_EXITPRESOLVE
4259  * - \ref SCIP_STAGE_PRESOLVED
4260  * - \ref SCIP_STAGE_INITSOLVE
4261  * - \ref SCIP_STAGE_SOLVING
4262  * - \ref SCIP_STAGE_EXITSOLVE
4263  * - \ref SCIP_STAGE_FREETRANS
4264  */
4266  SCIP* scip, /**< SCIP data structure */
4267  SCIP_VAR* var, /**< problem variable */
4268  SCIP_LOCKTYPE locktype, /**< type of the variable locks */
4269  int nlocksdown, /**< modification in number of rounding down locks */
4270  int nlocksup /**< modification in number of rounding up locks */
4271  )
4272 {
4273  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarLocksType", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4274 
4275  assert( var->scip == scip );
4276 
4277  switch( scip->set->stage )
4278  {
4279  case SCIP_STAGE_PROBLEM:
4280  assert(!SCIPvarIsTransformed(var));
4281  /*lint -fallthrough*/
4285  case SCIP_STAGE_PRESOLVING:
4287  case SCIP_STAGE_PRESOLVED:
4288  case SCIP_STAGE_INITSOLVE:
4289  case SCIP_STAGE_SOLVING:
4290  case SCIP_STAGE_EXITSOLVE:
4291  case SCIP_STAGE_FREETRANS:
4292  SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, locktype, nlocksdown, nlocksup) );
4293  return SCIP_OKAY;
4294 
4295  default:
4296  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4297  return SCIP_INVALIDCALL;
4298  } /*lint !e788*/
4299 }
4300 
4301 /** adds given values to lock numbers of variable for rounding
4302  *
4303  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4304  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4305  *
4306  * @pre This method can be called if @p scip is in one of the following stages:
4307  * - \ref SCIP_STAGE_PROBLEM
4308  * - \ref SCIP_STAGE_TRANSFORMING
4309  * - \ref SCIP_STAGE_TRANSFORMED
4310  * - \ref SCIP_STAGE_INITPRESOLVE
4311  * - \ref SCIP_STAGE_PRESOLVING
4312  * - \ref SCIP_STAGE_EXITPRESOLVE
4313  * - \ref SCIP_STAGE_PRESOLVED
4314  * - \ref SCIP_STAGE_INITSOLVE
4315  * - \ref SCIP_STAGE_SOLVING
4316  * - \ref SCIP_STAGE_EXITSOLVE
4317  * - \ref SCIP_STAGE_FREETRANS
4318  *
4319  * @note This method will always add variable locks of type model
4320  *
4321  * @note It is recommented to use SCIPaddVarLocksType()
4322  */
4324  SCIP* scip, /**< SCIP data structure */
4325  SCIP_VAR* var, /**< problem variable */
4326  int nlocksdown, /**< modification in number of rounding down locks */
4327  int nlocksup /**< modification in number of rounding up locks */
4328  )
4329 {
4330  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarLocks", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4331 
4332  SCIP_CALL( SCIPaddVarLocksType(scip, var, SCIP_LOCKTYPE_MODEL, nlocksdown, nlocksup) );
4333 
4334  return SCIP_OKAY;
4335 }
4336 
4337 /** add locks of variable with respect to the lock status of the constraint and its negation;
4338  * this method should be called whenever the lock status of a variable in a constraint changes, for example if
4339  * the coefficient of the variable changed its sign or if the left or right hand sides of the constraint were
4340  * added or removed
4341  *
4342  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4343  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4344  *
4345  * @pre This method can be called if @p scip is in one of the following stages:
4346  * - \ref SCIP_STAGE_PROBLEM
4347  * - \ref SCIP_STAGE_TRANSFORMING
4348  * - \ref SCIP_STAGE_TRANSFORMED
4349  * - \ref SCIP_STAGE_INITPRESOLVE
4350  * - \ref SCIP_STAGE_PRESOLVING
4351  * - \ref SCIP_STAGE_EXITPRESOLVE
4352  * - \ref SCIP_STAGE_INITSOLVE
4353  * - \ref SCIP_STAGE_SOLVING
4354  * - \ref SCIP_STAGE_EXITSOLVE
4355  * - \ref SCIP_STAGE_FREETRANS
4356  */
4358  SCIP* scip, /**< SCIP data structure */
4359  SCIP_VAR* var, /**< problem variable */
4360  SCIP_CONS* cons, /**< constraint */
4361  SCIP_Bool lockdown, /**< should the rounding be locked in downwards direction? */
4362  SCIP_Bool lockup /**< should the rounding be locked in upwards direction? */
4363  )
4364 {
4365  int nlocksdown[NLOCKTYPES];
4366  int nlocksup[NLOCKTYPES];
4367  int i;
4368 
4369  SCIP_CALL( SCIPcheckStage(scip, "SCIPlockVarCons", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4370 
4371  assert( var->scip == scip );
4372 
4373  for( i = 0; i < NLOCKTYPES; i++ )
4374  {
4375  nlocksdown[i] = 0;
4376  nlocksup[i] = 0;
4377 
4378  if( SCIPconsIsLockedTypePos(cons, (SCIP_LOCKTYPE) i) )
4379  {
4380  if( lockdown )
4381  ++nlocksdown[i];
4382  if( lockup )
4383  ++nlocksup[i];
4384  }
4385  if( SCIPconsIsLockedTypeNeg(cons, (SCIP_LOCKTYPE) i) )
4386  {
4387  if( lockdown )
4388  ++nlocksup[i];
4389  if( lockup )
4390  ++nlocksdown[i];
4391  }
4392  }
4393 
4394  switch( scip->set->stage )
4395  {
4396  case SCIP_STAGE_PROBLEM:
4397  assert(!SCIPvarIsTransformed(var));
4398  /*lint -fallthrough*/
4402  case SCIP_STAGE_PRESOLVING:
4404  case SCIP_STAGE_INITSOLVE:
4405  case SCIP_STAGE_SOLVING:
4406  case SCIP_STAGE_EXITSOLVE:
4407  case SCIP_STAGE_FREETRANS:
4408  for( i = 0; i < NLOCKTYPES; i++ )
4409  {
4410  if( nlocksdown[i] == 0 && nlocksup[i] == 0 )
4411  continue;
4412 
4413  SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, (SCIP_LOCKTYPE) i, nlocksdown[i], nlocksup[i]) );
4414  }
4415  return SCIP_OKAY;
4416 
4417  default:
4418  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4419  return SCIP_INVALIDCALL;
4420  } /*lint !e788*/
4421 }
4422 
4423 /** remove locks of type @p locktype of variable with respect to the lock status of the constraint and its negation;
4424  * this method should be called whenever the lock status of a variable in a constraint changes, for example if
4425  * the coefficient of the variable changed its sign or if the left or right hand sides of the constraint were
4426  * added or removed
4427  *
4428  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4429  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4430  *
4431  * @pre This method can be called if @p scip is in one of the following stages:
4432  * - \ref SCIP_STAGE_PROBLEM
4433  * - \ref SCIP_STAGE_TRANSFORMING
4434  * - \ref SCIP_STAGE_TRANSFORMED
4435  * - \ref SCIP_STAGE_INITPRESOLVE
4436  * - \ref SCIP_STAGE_PRESOLVING
4437  * - \ref SCIP_STAGE_EXITPRESOLVE
4438  * - \ref SCIP_STAGE_INITSOLVE
4439  * - \ref SCIP_STAGE_SOLVING
4440  * - \ref SCIP_STAGE_EXITSOLVE
4441  * - \ref SCIP_STAGE_FREETRANS
4442  */
4444  SCIP* scip, /**< SCIP data structure */
4445  SCIP_VAR* var, /**< problem variable */
4446  SCIP_CONS* cons, /**< constraint */
4447  SCIP_Bool lockdown, /**< should the rounding be unlocked in downwards direction? */
4448  SCIP_Bool lockup /**< should the rounding be unlocked in upwards direction? */
4449  )
4450 {
4451  int nlocksdown[NLOCKTYPES];
4452  int nlocksup[NLOCKTYPES];
4453  int i;
4454 
4455  SCIP_CALL( SCIPcheckStage(scip, "SCIPunlockVarCons", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE) );
4456 
4457  assert( var->scip == scip );
4458 
4459  for( i = 0; i < NLOCKTYPES; i++ )
4460  {
4461  nlocksdown[i] = 0;
4462  nlocksup[i] = 0;
4463 
4464  if( SCIPconsIsLockedTypePos(cons, (SCIP_LOCKTYPE) i) )
4465  {
4466  if( lockdown )
4467  ++nlocksdown[i];
4468  if( lockup )
4469  ++nlocksup[i];
4470  }
4471  if( SCIPconsIsLockedTypeNeg(cons, (SCIP_LOCKTYPE) i) )
4472  {
4473  if( lockdown )
4474  ++nlocksup[i];
4475  if( lockup )
4476  ++nlocksdown[i];
4477  }
4478  }
4479  switch( scip->set->stage )
4480  {
4481  case SCIP_STAGE_PROBLEM:
4482  assert(!SCIPvarIsTransformed(var));
4483  /*lint -fallthrough*/
4487  case SCIP_STAGE_PRESOLVING:
4489  case SCIP_STAGE_INITSOLVE:
4490  case SCIP_STAGE_SOLVING:
4491  case SCIP_STAGE_EXITSOLVE:
4492  case SCIP_STAGE_FREETRANS:
4493  for( i = 0; i < NLOCKTYPES; i++ )
4494  {
4495  if( nlocksdown[i] == 0 && nlocksup[i] == 0 )
4496  continue;
4497 
4498  SCIP_CALL( SCIPvarAddLocks(var, scip->mem->probmem, scip->set, scip->eventqueue, (SCIP_LOCKTYPE) i, -nlocksdown[i], -nlocksup[i]) );
4499  }
4500  return SCIP_OKAY;
4501 
4502  default:
4503  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4504  return SCIP_INVALIDCALL;
4505  } /*lint !e788*/
4506 }
4507 
4508 /** changes variable's objective value
4509  *
4510  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4511  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4512  *
4513  * @pre This method can be called if @p scip is in one of the following stages:
4514  * - \ref SCIP_STAGE_PROBLEM
4515  * - \ref SCIP_STAGE_TRANSFORMING
4516  * - \ref SCIP_STAGE_PRESOLVING
4517  * - \ref SCIP_STAGE_PRESOLVED
4518  */
4520  SCIP* scip, /**< SCIP data structure */
4521  SCIP_VAR* var, /**< variable to change the objective value for */
4522  SCIP_Real newobj /**< new objective value */
4523  )
4524 {
4525  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarObj", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
4526 
4527  assert( var->scip == scip );
4528 
4529  /* forbid infinite objective values */
4530  if( SCIPisInfinity(scip, REALABS(newobj)) )
4531  {
4532  SCIPerrorMessage("invalid objective value: objective value is infinite\n");
4533  return SCIP_INVALIDDATA;
4534  }
4535 
4536  switch( scip->set->stage )
4537  {
4538  case SCIP_STAGE_PROBLEM:
4539  assert(!SCIPvarIsTransformed(var));
4540  SCIP_CALL( SCIPvarChgObj(var, scip->mem->probmem, scip->set, scip->origprob, scip->primal, scip->lp, scip->eventqueue, newobj) );
4541  return SCIP_OKAY;
4542 
4545  case SCIP_STAGE_PRESOLVING:
4546  case SCIP_STAGE_PRESOLVED:
4547  SCIP_CALL( SCIPvarChgObj(var, scip->mem->probmem, scip->set, scip->transprob, scip->primal, scip->lp, scip->eventqueue, newobj) );
4548  return SCIP_OKAY;
4549 
4550  default:
4551  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4552  return SCIP_INVALIDCALL;
4553  } /*lint !e788*/
4554 }
4555 
4556 /** adds value to variable's objective value
4557  *
4558  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4559  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4560  *
4561  * @pre This method can be called if @p scip is in one of the following stages:
4562  * - \ref SCIP_STAGE_PROBLEM
4563  * - \ref SCIP_STAGE_TRANSFORMING
4564  * - \ref SCIP_STAGE_PRESOLVING
4565  * - \ref SCIP_STAGE_EXITPRESOLVE
4566  * - \ref SCIP_STAGE_PRESOLVED
4567  */
4569  SCIP* scip, /**< SCIP data structure */
4570  SCIP_VAR* var, /**< variable to change the objective value for */
4571  SCIP_Real addobj /**< additional objective value */
4572  )
4573 {
4574  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarObj", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
4575 
4576  assert( var->scip == scip );
4577 
4578  switch( scip->set->stage )
4579  {
4580  case SCIP_STAGE_PROBLEM:
4581  assert(!SCIPvarIsTransformed(var));
4582  SCIP_CALL( SCIPvarAddObj(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->primal,
4583  scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue, addobj) );
4584  return SCIP_OKAY;
4585 
4587  case SCIP_STAGE_PRESOLVING:
4589  case SCIP_STAGE_PRESOLVED:
4590  SCIP_CALL( SCIPvarAddObj(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->primal,
4591  scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue, addobj) );
4592  return SCIP_OKAY;
4593 
4594  default:
4595  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4596  return SCIP_INVALIDCALL;
4597  } /*lint !e788*/
4598 }
4599 
4600 /** returns the adjusted (i.e. rounded, if the given variable is of integral type) lower bound value;
4601  * does not change the bounds of the variable
4602  *
4603  * @return adjusted lower bound for the given variable; the bound of the variable is not changed
4604  *
4605  * @pre This method can be called if @p scip is in one of the following stages:
4606  * - \ref SCIP_STAGE_PROBLEM
4607  * - \ref SCIP_STAGE_TRANSFORMING
4608  * - \ref SCIP_STAGE_TRANSFORMED
4609  * - \ref SCIP_STAGE_INITPRESOLVE
4610  * - \ref SCIP_STAGE_PRESOLVING
4611  * - \ref SCIP_STAGE_EXITPRESOLVE
4612  * - \ref SCIP_STAGE_PRESOLVED
4613  * - \ref SCIP_STAGE_INITSOLVE
4614  * - \ref SCIP_STAGE_SOLVING
4615  * - \ref SCIP_STAGE_SOLVED
4616  * - \ref SCIP_STAGE_EXITSOLVE
4617  * - \ref SCIP_STAGE_FREETRANS
4618  */
4620  SCIP* scip, /**< SCIP data structure */
4621  SCIP_VAR* var, /**< variable to adjust the bound for */
4622  SCIP_Real lb /**< lower bound value to adjust */
4623  )
4624 {
4625  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPadjustedVarLb", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
4626 
4627  SCIPvarAdjustLb(var, scip->set, &lb);
4628 
4629  return lb;
4630 }
4631 
4632 /** returns the adjusted (i.e. rounded, if the given variable is of integral type) upper bound value;
4633  * does not change the bounds of the variable
4634  *
4635  * @return adjusted upper bound for the given variable; the bound of the variable is not changed
4636  *
4637  * @pre This method can be called if @p scip is in one of the following stages:
4638  * - \ref SCIP_STAGE_PROBLEM
4639  * - \ref SCIP_STAGE_TRANSFORMING
4640  * - \ref SCIP_STAGE_TRANSFORMED
4641  * - \ref SCIP_STAGE_INITPRESOLVE
4642  * - \ref SCIP_STAGE_PRESOLVING
4643  * - \ref SCIP_STAGE_EXITPRESOLVE
4644  * - \ref SCIP_STAGE_PRESOLVED
4645  * - \ref SCIP_STAGE_INITSOLVE
4646  * - \ref SCIP_STAGE_SOLVING
4647  * - \ref SCIP_STAGE_SOLVED
4648  * - \ref SCIP_STAGE_EXITSOLVE
4649  * - \ref SCIP_STAGE_FREETRANS
4650  */
4652  SCIP* scip, /**< SCIP data structure */
4653  SCIP_VAR* var, /**< variable to adjust the bound for */
4654  SCIP_Real ub /**< upper bound value to adjust */
4655  )
4656 {
4657  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPadjustedVarUb", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
4658 
4659  SCIPvarAdjustUb(var, scip->set, &ub);
4660 
4661  return ub;
4662 }
4663 
4664 /** depending on SCIP's stage, changes lower bound of variable in the problem, in preprocessing, or in current node;
4665  * if possible, adjusts bound to integral value; doesn't store any inference information in the bound change, such
4666  * that in conflict analysis, this change is treated like a branching decision
4667  *
4668  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4669  * SCIPgetVars()) gets resorted.
4670  *
4671  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4672  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4673  *
4674  * @pre This method can be called if @p scip is in one of the following stages:
4675  * - \ref SCIP_STAGE_PROBLEM
4676  * - \ref SCIP_STAGE_TRANSFORMING
4677  * - \ref SCIP_STAGE_PRESOLVING
4678  * - \ref SCIP_STAGE_SOLVING
4679  *
4680  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4681  */
4683  SCIP* scip, /**< SCIP data structure */
4684  SCIP_VAR* var, /**< variable to change the bound for */
4685  SCIP_Real newbound /**< new value for bound */
4686  )
4687 {
4688  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLb", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4689 
4690  SCIPvarAdjustLb(var, scip->set, &newbound);
4691 
4692  /* ignore tightenings of lower bounds to +infinity during solving process */
4693  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4694  {
4695 #ifndef NDEBUG
4696  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4697  SCIPvarGetLbLocal(var));
4698 #endif
4699  return SCIP_OKAY;
4700  }
4701 
4702  switch( scip->set->stage )
4703  {
4704  case SCIP_STAGE_PROBLEM:
4705  assert(!SCIPvarIsTransformed(var));
4706  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4707  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4708  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4709  scip->branchcand, scip->eventqueue, newbound) );
4710  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
4711  break;
4712 
4714  case SCIP_STAGE_PRESOLVED:
4715  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4716  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4717  break;
4718 
4719  case SCIP_STAGE_PRESOLVING:
4720  if( !SCIPinProbing(scip) )
4721  {
4722  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4723  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4724 
4725  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4726  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable,
4727  var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
4728 
4730  {
4731  SCIP_Bool infeasible;
4732 
4733  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
4734  assert(!infeasible);
4735  }
4736  break;
4737  }
4738  /*lint -fallthrough*/
4739  case SCIP_STAGE_SOLVING:
4741  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4742  scip->cliquetable, var, newbound,
4744  break;
4745 
4746  default:
4747  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4748  return SCIP_INVALIDCALL;
4749  } /*lint !e788*/
4750 
4751  return SCIP_OKAY;
4752 }
4753 
4754 /** depending on SCIP's stage, changes upper bound of variable in the problem, in preprocessing, or in current node;
4755  * if possible, adjusts bound to integral value; doesn't store any inference information in the bound change, such
4756  * that in conflict analysis, this change is treated like a branching decision
4757  *
4758  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4759  * SCIPgetVars()) gets resorted.
4760  *
4761  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4762  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4763  *
4764  * @pre This method can be called if @p scip is in one of the following stages:
4765  * - \ref SCIP_STAGE_PROBLEM
4766  * - \ref SCIP_STAGE_TRANSFORMING
4767  * - \ref SCIP_STAGE_PRESOLVING
4768  * - \ref SCIP_STAGE_SOLVING
4769  *
4770  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4771  */
4773  SCIP* scip, /**< SCIP data structure */
4774  SCIP_VAR* var, /**< variable to change the bound for */
4775  SCIP_Real newbound /**< new value for bound */
4776  )
4777 {
4778  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUb", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4779 
4780  SCIPvarAdjustUb(var, scip->set, &newbound);
4781 
4782  /* ignore tightenings of upper bounds to -infinity during solving process */
4783  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4784  {
4785 #ifndef NDEBUG
4786  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
4787  SCIPvarGetUbLocal(var));
4788 #endif
4789  return SCIP_OKAY;
4790  }
4791 
4792  switch( scip->set->stage )
4793  {
4794  case SCIP_STAGE_PROBLEM:
4795  assert(!SCIPvarIsTransformed(var));
4796  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4797  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4798  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4799  scip->branchcand, scip->eventqueue, newbound) );
4800  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
4801  break;
4802 
4804  case SCIP_STAGE_PRESOLVED:
4805  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4806  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4807  break;
4808 
4809  case SCIP_STAGE_PRESOLVING:
4810  if( !SCIPinProbing(scip) )
4811  {
4812  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4813  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4814 
4815  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4816  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4817  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
4818 
4820  {
4821  SCIP_Bool infeasible;
4822 
4823  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
4824  assert(!infeasible);
4825  }
4826  break;
4827  }
4828  /*lint -fallthrough*/
4829  case SCIP_STAGE_SOLVING:
4831  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
4832  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
4833  break;
4834 
4835  default:
4836  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
4837  return SCIP_INVALIDCALL;
4838  } /*lint !e788*/
4839 
4840  return SCIP_OKAY;
4841 }
4842 
4843 /** changes lower bound of variable in the given node; if possible, adjust bound to integral value; doesn't store any
4844  * inference information in the bound change, such that in conflict analysis, this change is treated like a branching
4845  * decision
4846  *
4847  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4848  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4849  *
4850  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
4851  */
4853  SCIP* scip, /**< SCIP data structure */
4854  SCIP_NODE* node, /**< node to change bound at, or NULL for current node */
4855  SCIP_VAR* var, /**< variable to change the bound for */
4856  SCIP_Real newbound /**< new value for bound */
4857  )
4858 {
4859  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbNode", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4860 
4861  if( node == NULL )
4862  {
4863  SCIP_CALL( SCIPchgVarLb(scip, var, newbound) );
4864  }
4865  else
4866  {
4867  SCIPvarAdjustLb(var, scip->set, &newbound);
4868 
4869  /* ignore tightenings of lower bounds to +infinity during solving process */
4870  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4871  {
4872 #ifndef NDEBUG
4873  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4874  SCIPvarGetLbLocal(var));
4875 #endif
4876  return SCIP_OKAY;
4877  }
4878 
4879  SCIP_CALL( SCIPnodeAddBoundchg(node, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
4880  scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4882  }
4883 
4884  return SCIP_OKAY;
4885 }
4886 
4887 /** changes upper bound of variable in the given node; if possible, adjust bound to integral value; doesn't store any
4888  * inference information in the bound change, such that in conflict analysis, this change is treated like a branching
4889  * decision
4890  *
4891  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4892  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4893  *
4894  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
4895  */
4897  SCIP* scip, /**< SCIP data structure */
4898  SCIP_NODE* node, /**< node to change bound at, or NULL for current node */
4899  SCIP_VAR* var, /**< variable to change the bound for */
4900  SCIP_Real newbound /**< new value for bound */
4901  )
4902 {
4903  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbNode", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4904 
4905  if( node == NULL )
4906  {
4907  SCIP_CALL( SCIPchgVarUb(scip, var, newbound) );
4908  }
4909  else
4910  {
4911  SCIPvarAdjustUb(var, scip->set, &newbound);
4912 
4913  /* ignore tightenings of upper bounds to -infinity during solving process */
4914  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4915  {
4916 #ifndef NDEBUG
4917  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
4918  SCIPvarGetUbLocal(var));
4919 #endif
4920  return SCIP_OKAY;
4921  }
4922 
4923  SCIP_CALL( SCIPnodeAddBoundchg(node, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
4924  scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4926  }
4927 
4928  return SCIP_OKAY;
4929 }
4930 
4931 /** changes global lower bound of variable; if possible, adjust bound to integral value; also tightens the local bound,
4932  * if the global bound is better than the local bound
4933  *
4934  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
4935  * SCIPgetVars()) gets resorted.
4936  *
4937  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
4938  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
4939  *
4940  * @pre This method can be called if @p scip is in one of the following stages:
4941  * - \ref SCIP_STAGE_PROBLEM
4942  * - \ref SCIP_STAGE_TRANSFORMING
4943  * - \ref SCIP_STAGE_TRANSFORMED
4944  * - \ref SCIP_STAGE_PRESOLVING
4945  * - \ref SCIP_STAGE_SOLVING
4946  *
4947  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
4948  */
4950  SCIP* scip, /**< SCIP data structure */
4951  SCIP_VAR* var, /**< variable to change the bound for */
4952  SCIP_Real newbound /**< new value for bound */
4953  )
4954 {
4955  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbGlobal", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
4956 
4957  SCIPvarAdjustLb(var, scip->set, &newbound);
4958 
4959  /* ignore tightenings of lower bounds to +infinity during solving process */
4960  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
4961  {
4962 #ifndef NDEBUG
4963  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
4964  SCIPvarGetLbLocal(var));
4965 #endif
4966  return SCIP_OKAY;
4967  }
4968 
4969  switch( scip->set->stage )
4970  {
4971  case SCIP_STAGE_PROBLEM:
4972  assert(!SCIPvarIsTransformed(var));
4973  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4974  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4975  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4976  scip->branchcand, scip->eventqueue, newbound) );
4977  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
4978  break;
4979 
4982  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
4983  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
4984  break;
4985 
4986  case SCIP_STAGE_PRESOLVING:
4987  if( !SCIPinProbing(scip) )
4988  {
4989  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
4990  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
4991 
4992  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
4993  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
4995 
4997  {
4998  SCIP_Bool infeasible;
4999 
5000  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
5001  assert(!infeasible);
5002  }
5003  break;
5004  }
5005  /*lint -fallthrough*/
5006  case SCIP_STAGE_SOLVING:
5007  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5008  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5010  break;
5011 
5012  default:
5013  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5014  return SCIP_INVALIDCALL;
5015  } /*lint !e788*/
5016 
5017  return SCIP_OKAY;
5018 }
5019 
5020 /** changes global upper bound of variable; if possible, adjust bound to integral value; also tightens the local bound,
5021  * if the global bound is better than the local bound
5022  *
5023  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5024  * SCIPgetVars()) gets resorted.
5025  *
5026  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5027  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5028  *
5029  * @pre This method can be called if @p scip is in one of the following stages:
5030  * - \ref SCIP_STAGE_PROBLEM
5031  * - \ref SCIP_STAGE_TRANSFORMING
5032  * - \ref SCIP_STAGE_TRANSFORMED
5033  * - \ref SCIP_STAGE_PRESOLVING
5034  * - \ref SCIP_STAGE_SOLVING
5035  *
5036  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5037  */
5039  SCIP* scip, /**< SCIP data structure */
5040  SCIP_VAR* var, /**< variable to change the bound for */
5041  SCIP_Real newbound /**< new value for bound */
5042  )
5043 {
5044  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbGlobal", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5045 
5046  SCIPvarAdjustUb(var, scip->set, &newbound);
5047 
5048  /* ignore tightenings of upper bounds to -infinity during solving process */
5049  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5050  {
5051 #ifndef NDEBUG
5052  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5053  SCIPvarGetUbLocal(var));
5054 #endif
5055  return SCIP_OKAY;
5056  }
5057 
5058  switch( scip->set->stage )
5059  {
5060  case SCIP_STAGE_PROBLEM:
5061  assert(!SCIPvarIsTransformed(var));
5062  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5063  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5064  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5065  scip->branchcand, scip->eventqueue, newbound) );
5066  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
5067  break;
5068 
5071  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5072  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5073  break;
5074 
5075  case SCIP_STAGE_PRESOLVING:
5076  if( !SCIPinProbing(scip) )
5077  {
5078  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5079  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5080 
5081  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5082  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5084 
5086  {
5087  SCIP_Bool infeasible;
5088 
5089  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
5090  assert(!infeasible);
5091  }
5092  break;
5093  }
5094  /*lint -fallthrough*/
5095  case SCIP_STAGE_SOLVING:
5096  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5097  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5099  break;
5100 
5101  default:
5102  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5103  return SCIP_INVALIDCALL;
5104  } /*lint !e788*/
5105 
5106  return SCIP_OKAY;
5107 }
5108 
5109 /** changes lazy lower bound of the variable, this is only possible if the variable is not in the LP yet
5110  *
5111  * Lazy bounds are bounds that are already enforced by constraints and the objective function.
5112  * Setting a lazy lower bound has the consequence that for variables which lower bound equals the lazy lower bound,
5113  * the lower bound does not need to be passed on to the LP solver.
5114  * This is especially useful in a column generation (branch-and-price) setting.
5115  *
5116  * @attention If the variable has a global lower bound below lazylb, then the global lower bound is tightened to
5117  * lazylb by a call to SCIPchgVarLbGlobal().
5118  *
5119  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5120  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5121  *
5122  * @pre This method can be called if @p scip is in one of the following stages:
5123  * - \ref SCIP_STAGE_PROBLEM
5124  * - \ref SCIP_STAGE_TRANSFORMING
5125  * - \ref SCIP_STAGE_TRANSFORMED
5126  * - \ref SCIP_STAGE_PRESOLVING
5127  * - \ref SCIP_STAGE_SOLVING
5128  */
5130  SCIP* scip, /**< SCIP data structure */
5131  SCIP_VAR* var, /**< problem variable */
5132  SCIP_Real lazylb /**< the lazy lower bound to be set */
5133  )
5134 {
5135  assert(scip != NULL);
5136  assert(var != NULL);
5137 
5138  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarLbLazy", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5139 
5140  if( SCIPisGT(scip, lazylb, SCIPvarGetLbGlobal(var)) )
5141  {
5142  SCIP_CALL( SCIPchgVarLbGlobal(scip, var, lazylb) );
5143  }
5144 
5145  SCIP_CALL( SCIPvarChgLbLazy(var, scip->set, lazylb) );
5146 
5147  return SCIP_OKAY;
5148 }
5149 
5150 /** changes lazy upper bound of the variable, this is only possible if the variable is not in the LP yet
5151  *
5152  * Lazy bounds are bounds that are already enforced by constraints and the objective function.
5153  * Setting a lazy upper bound has the consequence that for variables which upper bound equals the lazy upper bound,
5154  * the upper bound does not need to be passed on to the LP solver.
5155  * This is especially useful in a column generation (branch-and-price) setting.
5156  *
5157  * @attention If the variable has a global upper bound above lazyub, then the global upper bound is tightened to
5158  * lazyub by a call to SCIPchgVarUbGlobal().
5159  *
5160  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5161  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5162  *
5163  * @pre This method can be called if @p scip is in one of the following stages:
5164  * - \ref SCIP_STAGE_PROBLEM
5165  * - \ref SCIP_STAGE_TRANSFORMING
5166  * - \ref SCIP_STAGE_TRANSFORMED
5167  * - \ref SCIP_STAGE_PRESOLVING
5168  * - \ref SCIP_STAGE_SOLVING
5169  */
5171  SCIP* scip, /**< SCIP data structure */
5172  SCIP_VAR* var, /**< problem variable */
5173  SCIP_Real lazyub /**< the lazy lower bound to be set */
5174  )
5175 {
5176  assert(scip != NULL);
5177  assert(var != NULL);
5178 
5179  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarUbLazy", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5180 
5181  if( SCIPisLT(scip, lazyub, SCIPvarGetUbGlobal(var)) )
5182  {
5183  SCIP_CALL( SCIPchgVarUbGlobal(scip, var, lazyub) );
5184  }
5185 
5186  SCIP_CALL( SCIPvarChgUbLazy(var, scip->set, lazyub) );
5187 
5188  return SCIP_OKAY;
5189 }
5190 
5191 /** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
5192  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5193  * doesn't store any inference information in the bound change, such that in conflict analysis, this change
5194  * is treated like a branching decision
5195  *
5196  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5197  * SCIPgetVars()) gets resorted.
5198  *
5199  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5200  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5201  *
5202  * @pre This method can be called if @p scip is in one of the following stages:
5203  * - \ref SCIP_STAGE_PROBLEM
5204  * - \ref SCIP_STAGE_PRESOLVING
5205  * - \ref SCIP_STAGE_SOLVING
5206  *
5207  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5208  */
5210  SCIP* scip, /**< SCIP data structure */
5211  SCIP_VAR* var, /**< variable to change the bound for */
5212  SCIP_Real newbound, /**< new value for bound */
5213  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5214  SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
5215  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5216  )
5217 {
5218  SCIP_Real lb;
5219  SCIP_Real ub;
5220 
5221  assert(infeasible != NULL);
5222 
5223  SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarLb", FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5224  /** @todo if needed provide pending local/global bound changes that will be flushed after leaving diving mode (as in struct_tree.h) */
5225  assert(SCIPgetStage(scip) == SCIP_STAGE_PROBLEM || !SCIPinDive(scip));
5226 
5227  *infeasible = FALSE;
5228  if( tightened != NULL )
5229  *tightened = FALSE;
5230 
5231  SCIPvarAdjustLb(var, scip->set, &newbound);
5232 
5233  /* ignore tightenings of lower bounds to +infinity during solving process */
5234  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5235  {
5236 #ifndef NDEBUG
5237  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
5238  SCIPvarGetLbLocal(var));
5239 #endif
5240  return SCIP_OKAY;
5241  }
5242 
5243  /* get current bounds */
5244  lb = SCIPcomputeVarLbLocal(scip, var);
5245  ub = SCIPcomputeVarUbLocal(scip, var);
5246  assert(SCIPsetIsLE(scip->set, lb, ub));
5247 
5248  if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
5249  {
5250  *infeasible = TRUE;
5251  return SCIP_OKAY;
5252  }
5253  newbound = MIN(newbound, ub);
5254 
5255  if( (force && SCIPsetIsLE(scip->set, newbound, lb)) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
5256  return SCIP_OKAY;
5257 
5258  switch( scip->set->stage )
5259  {
5260  case SCIP_STAGE_PROBLEM:
5261  assert(!SCIPvarIsTransformed(var));
5262  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5263  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5264  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5265  scip->branchcand, scip->eventqueue, newbound) );
5266  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
5267  break;
5269  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5270  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5271  break;
5272  case SCIP_STAGE_PRESOLVING:
5273  if( !SCIPinProbing(scip) )
5274  {
5275  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5276  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5277 
5278  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5279  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5281 
5283  {
5284  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5285  assert(!(*infeasible));
5286  }
5287  break;
5288  }
5289  /*lint -fallthrough*/
5290  case SCIP_STAGE_SOLVING:
5292  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable,
5293  var, newbound, SCIP_BOUNDTYPE_LOWER, FALSE) );
5294  break;
5295 
5296  default:
5297  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5298  return SCIP_INVALIDCALL;
5299  } /*lint !e788*/
5300 
5301  /* check whether the lower bound improved */
5302  if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
5303  *tightened = TRUE;
5304 
5305  return SCIP_OKAY;
5306 }
5307 
5308 /** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
5309  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5310  * doesn't store any inference information in the bound change, such that in conflict analysis, this change
5311  * is treated like a branching decision
5312  *
5313  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5314  * SCIPgetVars()) gets resorted.
5315  *
5316  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5317  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5318  *
5319  * @pre This method can be called if @p scip is in one of the following stages:
5320  * - \ref SCIP_STAGE_PROBLEM
5321  * - \ref SCIP_STAGE_PRESOLVING
5322  * - \ref SCIP_STAGE_SOLVING
5323  *
5324  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5325  */
5327  SCIP* scip, /**< SCIP data structure */
5328  SCIP_VAR* var, /**< variable to change the bound for */
5329  SCIP_Real newbound, /**< new value for bound */
5330  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5331  SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
5332  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5333  )
5334 {
5335  SCIP_Real lb;
5336  SCIP_Real ub;
5337 
5338  assert(infeasible != NULL);
5339  SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarUb", FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5340 
5341  /** @todo if needed provide pending local/global bound changes that will be flushed after leaving diving mode (as in struct_tree.h) */
5342  assert(SCIPgetStage(scip) == SCIP_STAGE_PROBLEM || !SCIPinDive(scip));
5343 
5344  *infeasible = FALSE;
5345  if( tightened != NULL )
5346  *tightened = FALSE;
5347 
5348  SCIPvarAdjustUb(var, scip->set, &newbound);
5349 
5350  /* ignore tightenings of upper bounds to -infinity during solving process */
5351  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5352  {
5353 #ifndef NDEBUG
5354  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5355  SCIPvarGetUbLocal(var));
5356 #endif
5357  return SCIP_OKAY;
5358  }
5359 
5360  /* get current bounds */
5361  lb = SCIPcomputeVarLbLocal(scip, var);
5362  ub = SCIPcomputeVarUbLocal(scip, var);
5363  assert(SCIPsetIsLE(scip->set, lb, ub));
5364 
5365  if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
5366  {
5367  *infeasible = TRUE;
5368  return SCIP_OKAY;
5369  }
5370  newbound = MAX(newbound, lb);
5371 
5372  if( (force && SCIPsetIsGE(scip->set, newbound, ub)) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
5373  return SCIP_OKAY;
5374 
5375  switch( scip->set->stage )
5376  {
5377  case SCIP_STAGE_PROBLEM:
5378  assert(!SCIPvarIsTransformed(var));
5379  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5380  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5381  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5382  scip->branchcand, scip->eventqueue, newbound) );
5383  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
5384  break;
5386  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5387  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5388  break;
5389  case SCIP_STAGE_PRESOLVING:
5390  if( !SCIPinProbing(scip) )
5391  {
5392  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5393  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5394 
5395  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5396  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5398 
5400  {
5401  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5402  assert(!(*infeasible));
5403  }
5404  break;
5405  }
5406  /*lint -fallthrough*/
5407  case SCIP_STAGE_SOLVING:
5409  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5410  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, FALSE) );
5411  break;
5412 
5413  default:
5414  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5415  return SCIP_INVALIDCALL;
5416  } /*lint !e788*/
5417 
5418  /* check whether the upper bound improved */
5419  if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
5420  *tightened = TRUE;
5421 
5422  return SCIP_OKAY;
5423 }
5424 
5425 /** fixes variable in preprocessing or in the current node, if the new bound is tighter (w.r.t. bound strengthening
5426  * epsilon) than the current bound; if possible, adjusts bound to integral value; the given inference constraint is
5427  * stored, such that the conflict analysis is able to find out the reason for the deduction of the bound change
5428  *
5429  * @note In presolving stage when not in probing mode the variable will be fixed directly, otherwise this method
5430  * changes first the lowerbound by calling SCIPinferVarLbCons and second the upperbound by calling
5431  * SCIPinferVarUbCons
5432  *
5433  * @note If SCIP is in presolving stage, it can happen that the internal variable array (which get be accessed via
5434  * SCIPgetVars()) gets resorted.
5435  *
5436  * @note During presolving, an integer variable which bound changes to {0,1} is upgraded to a binary variable.
5437  */
5439  SCIP* scip, /**< SCIP data structure */
5440  SCIP_VAR* var, /**< variable to change the bound for */
5441  SCIP_Real fixedval, /**< new value for fixation */
5442  SCIP_CONS* infercons, /**< constraint that deduced the bound change */
5443  int inferinfo, /**< user information for inference to help resolving the conflict */
5444  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5445  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5446  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5447  )
5448 {
5449  assert(scip != NULL);
5450  assert(var != NULL);
5451  assert(infeasible != NULL);
5452 
5453  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarFixCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5454 
5455  if( tightened != NULL )
5456  *tightened = FALSE;
5457 
5458  /* in presolving case we take the shortcut to directly fix the variables */
5459  if( SCIPgetStage(scip) == SCIP_STAGE_PRESOLVING && SCIPtreeGetCurrentDepth(scip->tree) == 0 )
5460  {
5461  SCIP_Bool fixed;
5462 
5463  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5464  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter,
5465  scip->eventqueue, scip->cliquetable, fixedval, infeasible, &fixed) );
5466 
5467  if( tightened != NULL )
5468  *tightened = fixed;
5469  }
5470  /* otherwise we use the lb and ub methods */
5471  else
5472  {
5473  SCIP_Bool lbtightened;
5474 
5475  SCIP_CALL( SCIPinferVarLbCons(scip, var, fixedval, infercons, inferinfo, force, infeasible, &lbtightened) );
5476 
5477  if( ! (*infeasible) )
5478  {
5479  SCIP_CALL( SCIPinferVarUbCons(scip, var, fixedval, infercons, inferinfo, force, infeasible, tightened) );
5480 
5481  if( tightened != NULL )
5482  *tightened |= lbtightened;
5483  }
5484  }
5485 
5486  return SCIP_OKAY;
5487 }
5488 
5489 /** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
5490  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5491  * the given inference constraint is stored, such that the conflict analysis is able to find out the reason
5492  * for the deduction of the bound change
5493  *
5494  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5495  * SCIPgetVars()) gets resorted.
5496  *
5497  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5498  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5499  *
5500  * @pre This method can be called if @p scip is in one of the following stages:
5501  * - \ref SCIP_STAGE_PROBLEM
5502  * - \ref SCIP_STAGE_PRESOLVING
5503  * - \ref SCIP_STAGE_SOLVING
5504  *
5505  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5506  */
5508  SCIP* scip, /**< SCIP data structure */
5509  SCIP_VAR* var, /**< variable to change the bound for */
5510  SCIP_Real newbound, /**< new value for bound */
5511  SCIP_CONS* infercons, /**< constraint that deduced the bound change */
5512  int inferinfo, /**< user information for inference to help resolving the conflict */
5513  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5514  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5515  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5516  )
5517 {
5518  SCIP_Real lb;
5519  SCIP_Real ub;
5520 
5521  assert(infeasible != NULL);
5522 
5523  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarLbCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5524 
5525  *infeasible = FALSE;
5526  if( tightened != NULL )
5527  *tightened = FALSE;
5528 
5529  SCIPvarAdjustLb(var, scip->set, &newbound);
5530 
5531  /* ignore tightenings of lower bounds to +infinity during solving process */
5532  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5533  {
5534 #ifndef NDEBUG
5535  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
5536  SCIPvarGetLbLocal(var));
5537 #endif
5538  return SCIP_OKAY;
5539  }
5540 
5541  /* get current bounds */
5542  lb = SCIPvarGetLbLocal(var);
5543  ub = SCIPvarGetUbLocal(var);
5544  assert(SCIPsetIsLE(scip->set, lb, ub));
5545 
5546  if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
5547  {
5548  *infeasible = TRUE;
5549  return SCIP_OKAY;
5550  }
5551  newbound = MIN(newbound, ub);
5552 
5553  if( (force && SCIPsetIsLE(scip->set, newbound, lb)) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
5554  return SCIP_OKAY;
5555 
5556  switch( scip->set->stage )
5557  {
5558  case SCIP_STAGE_PROBLEM:
5559  assert(!SCIPvarIsTransformed(var));
5560  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5561  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5562  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5563  scip->branchcand, scip->eventqueue, newbound) );
5564  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
5565  break;
5566 
5567  case SCIP_STAGE_PRESOLVING:
5568  if( !SCIPinProbing(scip) )
5569  {
5570  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5571  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5572 
5573  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5574  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5576 
5578  {
5579  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5580  assert(!(*infeasible));
5581  }
5582  break;
5583  }
5584  /*lint -fallthrough*/
5585  case SCIP_STAGE_SOLVING:
5587  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5588  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, infercons, NULL, inferinfo, FALSE) );
5589  break;
5590 
5591  default:
5592  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5593  return SCIP_INVALIDCALL;
5594  } /*lint !e788*/
5595 
5596  /* check whether the lower bound improved */
5597  if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
5598  *tightened = TRUE;
5599 
5600  return SCIP_OKAY;
5601 }
5602 
5603 /** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
5604  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5605  * the given inference constraint is stored, such that the conflict analysis is able to find out the reason
5606  * for the deduction of the bound change
5607  *
5608  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5609  * SCIPgetVars()) gets resorted.
5610  *
5611  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5612  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5613  *
5614  * @pre This method can be called if @p scip is in one of the following stages:
5615  * - \ref SCIP_STAGE_PROBLEM
5616  * - \ref SCIP_STAGE_PRESOLVING
5617  * - \ref SCIP_STAGE_SOLVING
5618  *
5619  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5620  */
5622  SCIP* scip, /**< SCIP data structure */
5623  SCIP_VAR* var, /**< variable to change the bound for */
5624  SCIP_Real newbound, /**< new value for bound */
5625  SCIP_CONS* infercons, /**< constraint that deduced the bound change */
5626  int inferinfo, /**< user information for inference to help resolving the conflict */
5627  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5628  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5629  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5630  )
5631 {
5632  SCIP_Real lb;
5633  SCIP_Real ub;
5634 
5635  assert(infeasible != NULL);
5636 
5637  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarUbCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5638 
5639  *infeasible = FALSE;
5640  if( tightened != NULL )
5641  *tightened = FALSE;
5642 
5643  SCIPvarAdjustUb(var, scip->set, &newbound);
5644 
5645  /* ignore tightenings of upper bounds to -infinity during solving process */
5646  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5647  {
5648 #ifndef NDEBUG
5649  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
5650  SCIPvarGetUbLocal(var));
5651 #endif
5652  return SCIP_OKAY;
5653  }
5654 
5655  /* get current bounds */
5656  lb = SCIPvarGetLbLocal(var);
5657  ub = SCIPvarGetUbLocal(var);
5658  assert(SCIPsetIsLE(scip->set, lb, ub));
5659 
5660  if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
5661  {
5662  *infeasible = TRUE;
5663  return SCIP_OKAY;
5664  }
5665  newbound = MAX(newbound, lb);
5666 
5667  if( (force && SCIPsetIsGE(scip->set, newbound, ub)) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
5668  return SCIP_OKAY;
5669 
5670  switch( scip->set->stage )
5671  {
5672  case SCIP_STAGE_PROBLEM:
5673  assert(!SCIPvarIsTransformed(var));
5674  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5675  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5676  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5677  scip->branchcand, scip->eventqueue, newbound) );
5678  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
5679  break;
5680 
5681  case SCIP_STAGE_PRESOLVING:
5682  if( !SCIPinProbing(scip) )
5683  {
5684  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5685  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5686 
5687  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5688  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5690 
5692  {
5693  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5694  assert(!(*infeasible));
5695  }
5696  break;
5697  }
5698  /*lint -fallthrough*/
5699  case SCIP_STAGE_SOLVING:
5701  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5702  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, infercons, NULL, inferinfo, FALSE) );
5703  break;
5704 
5705  default:
5706  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5707  return SCIP_INVALIDCALL;
5708  } /*lint !e788*/
5709 
5710  /* check whether the upper bound improved */
5711  if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
5712  *tightened = TRUE;
5713 
5714  return SCIP_OKAY;
5715 }
5716 
5717 /** depending on SCIP's stage, fixes binary variable in the problem, in preprocessing, or in current node;
5718  * the given inference constraint is stored, such that the conflict analysis is able to find out the reason for the
5719  * deduction of the fixing
5720  *
5721  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5722  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5723  *
5724  * @pre This method can be called if @p scip is in one of the following stages:
5725  * - \ref SCIP_STAGE_PROBLEM
5726  * - \ref SCIP_STAGE_PRESOLVING
5727  * - \ref SCIP_STAGE_SOLVING
5728  */
5730  SCIP* scip, /**< SCIP data structure */
5731  SCIP_VAR* var, /**< binary variable to fix */
5732  SCIP_Bool fixedval, /**< value to fix binary variable to */
5733  SCIP_CONS* infercons, /**< constraint that deduced the fixing */
5734  int inferinfo, /**< user information for inference to help resolving the conflict */
5735  SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
5736  SCIP_Bool* tightened /**< pointer to store whether the fixing tightened the local bounds, or NULL */
5737  )
5738 {
5739  SCIP_Real lb;
5740  SCIP_Real ub;
5741 
5742  assert(SCIPvarIsBinary(var));
5743  assert(fixedval == TRUE || fixedval == FALSE);
5744  assert(infeasible != NULL);
5745 
5746  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferBinvarCons", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5747 
5748  *infeasible = FALSE;
5749  if( tightened != NULL )
5750  *tightened = FALSE;
5751 
5752  /* get current bounds */
5753  lb = SCIPvarGetLbLocal(var);
5754  ub = SCIPvarGetUbLocal(var);
5755  assert(SCIPsetIsEQ(scip->set, lb, 0.0) || SCIPsetIsEQ(scip->set, lb, 1.0));
5756  assert(SCIPsetIsEQ(scip->set, ub, 0.0) || SCIPsetIsEQ(scip->set, ub, 1.0));
5757  assert(SCIPsetIsLE(scip->set, lb, ub));
5758 
5759  /* check, if variable is already fixed */
5760  if( (lb > 0.5) || (ub < 0.5) )
5761  {
5762  *infeasible = (fixedval == (lb < 0.5));
5763 
5764  return SCIP_OKAY;
5765  }
5766 
5767  /* apply the fixing */
5768  switch( scip->set->stage )
5769  {
5770  case SCIP_STAGE_PROBLEM:
5771  assert(!SCIPvarIsTransformed(var));
5772  if( fixedval == TRUE )
5773  {
5774  SCIP_CALL( SCIPchgVarLb(scip, var, 1.0) );
5775  }
5776  else
5777  {
5778  SCIP_CALL( SCIPchgVarUb(scip, var, 0.0) );
5779  }
5780  break;
5781 
5782  case SCIP_STAGE_PRESOLVING:
5783  if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
5784  {
5785  SCIP_Bool fixed;
5786 
5787  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5788  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
5789  scip->cliquetable, (SCIP_Real)fixedval, infeasible, &fixed) );
5790  break;
5791  }
5792  /*lint -fallthrough*/
5793  case SCIP_STAGE_SOLVING:
5794  if( fixedval == TRUE )
5795  {
5797  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5798  scip->cliquetable, var, 1.0, SCIP_BOUNDTYPE_LOWER, infercons, NULL, inferinfo, FALSE) );
5799  }
5800  else
5801  {
5803  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5804  scip->cliquetable, var, 0.0, SCIP_BOUNDTYPE_UPPER, infercons, NULL, inferinfo, FALSE) );
5805  }
5806  break;
5807 
5808  default:
5809  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5810  return SCIP_INVALIDCALL;
5811  } /*lint !e788*/
5812 
5813  if( tightened != NULL )
5814  *tightened = TRUE;
5815 
5816  return SCIP_OKAY;
5817 }
5818 
5819 /** fixes variable in preprocessing or in the current node, if the new bound is tighter (w.r.t. bound strengthening
5820  * epsilon) than the current bound; if possible, adjusts bound to integral value; the given inference constraint is
5821  * stored, such that the conflict analysis is able to find out the reason for the deduction of the bound change
5822  *
5823  * @note In presolving stage when not in probing mode the variable will be fixed directly, otherwise this method
5824  * changes first the lowerbound by calling SCIPinferVarLbProp and second the upperbound by calling
5825  * SCIPinferVarUbProp
5826  *
5827  * @note If SCIP is in presolving stage, it can happen that the internal variable array (which get be accessed via
5828  * SCIPgetVars()) gets resorted.
5829  *
5830  * @note During presolving, an integer variable which bound changes to {0,1} is upgraded to a binary variable.
5831  */
5833  SCIP* scip, /**< SCIP data structure */
5834  SCIP_VAR* var, /**< variable to change the bound for */
5835  SCIP_Real fixedval, /**< new value for fixation */
5836  SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
5837  int inferinfo, /**< user information for inference to help resolving the conflict */
5838  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5839  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5840  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5841  )
5842 {
5843  assert(scip != NULL);
5844  assert(var != NULL);
5845  assert(infeasible != NULL);
5846 
5847  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarFixProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5848 
5849  if( tightened != NULL )
5850  *tightened = FALSE;
5851 
5852  /* in presolving case we take the shortcut to directly fix the variables */
5853  if( SCIPgetStage(scip) == SCIP_STAGE_PRESOLVING && SCIPtreeGetCurrentDepth(scip->tree) == 0 )
5854  {
5855  SCIP_Bool fixed;
5856 
5857  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
5858  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
5859  scip->cliquetable, fixedval, infeasible, &fixed) );
5860 
5861  if( tightened != NULL )
5862  *tightened = fixed;
5863  }
5864  /* otherwise we use the lb and ub methods */
5865  else
5866  {
5867  SCIP_Bool lbtightened;
5868 
5869  SCIP_CALL( SCIPinferVarLbProp(scip, var, fixedval, inferprop, inferinfo, force, infeasible, &lbtightened) );
5870 
5871  if( ! (*infeasible) )
5872  {
5873  SCIP_CALL( SCIPinferVarUbProp(scip, var, fixedval, inferprop, inferinfo, force, infeasible, tightened) );
5874 
5875  if( tightened != NULL )
5876  *tightened |= lbtightened;
5877  }
5878  }
5879 
5880  return SCIP_OKAY;
5881 }
5882 
5883 /** changes lower bound of variable in preprocessing or in the current node, if the new bound is tighter
5884  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
5885  * the given inference propagator is stored, such that the conflict analysis is able to find out the reason
5886  * for the deduction of the bound change
5887  *
5888  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
5889  * SCIPgetVars()) gets resorted.
5890  *
5891  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
5892  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
5893  *
5894  * @pre This method can be called if @p scip is in one of the following stages:
5895  * - \ref SCIP_STAGE_PROBLEM
5896  * - \ref SCIP_STAGE_PRESOLVING
5897  * - \ref SCIP_STAGE_SOLVING
5898  *
5899  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
5900  */
5902  SCIP* scip, /**< SCIP data structure */
5903  SCIP_VAR* var, /**< variable to change the bound for */
5904  SCIP_Real newbound, /**< new value for bound */
5905  SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
5906  int inferinfo, /**< user information for inference to help resolving the conflict */
5907  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
5908  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
5909  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
5910  )
5911 {
5912  SCIP_Real lb;
5913  SCIP_Real ub;
5914 
5915  assert(infeasible != NULL);
5916 
5917  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarLbProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
5918 
5919  *infeasible = FALSE;
5920  if( tightened != NULL )
5921  *tightened = FALSE;
5922 
5923  SCIPvarAdjustLb(var, scip->set, &newbound);
5924 
5925  /* ignore tightenings of lower bounds to +infinity during solving process */
5926  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
5927  {
5928 #ifndef NDEBUG
5929  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
5930  SCIPvarGetLbLocal(var));
5931 #endif
5932  return SCIP_OKAY;
5933  }
5934 
5935  /* get current bounds */
5936  lb = SCIPvarGetLbLocal(var);
5937  ub = SCIPvarGetUbLocal(var);
5938  assert(SCIPsetIsLE(scip->set, lb, ub));
5939 
5940  if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
5941  {
5942  *infeasible = TRUE;
5943  return SCIP_OKAY;
5944  }
5945  newbound = MIN(newbound, ub);
5946 
5947  if( (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub))
5948  || SCIPsetIsLE(scip->set, newbound, lb) )
5949  return SCIP_OKAY;
5950 
5951  switch( scip->set->stage )
5952  {
5953  case SCIP_STAGE_PROBLEM:
5954  assert(!SCIPvarIsTransformed(var));
5955  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5956  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
5957  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
5958  scip->branchcand, scip->eventqueue, newbound) );
5959  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
5960  break;
5961 
5962  case SCIP_STAGE_PRESOLVING:
5963  if( !SCIPinProbing(scip) )
5964  {
5965  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
5966  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
5967 
5968  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
5969  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
5971 
5973  {
5974  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
5975  assert(!(*infeasible));
5976  }
5977  break;
5978  }
5979  /*lint -fallthrough*/
5980  case SCIP_STAGE_SOLVING:
5982  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
5983  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, NULL, inferprop, inferinfo, FALSE) );
5984  break;
5985 
5986  default:
5987  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
5988  return SCIP_INVALIDCALL;
5989  } /*lint !e788*/
5990 
5991  /* check whether the lower bound improved */
5992  if( tightened != NULL && lb < SCIPcomputeVarLbLocal(scip, var) )
5993  *tightened = TRUE;
5994 
5995  return SCIP_OKAY;
5996 }
5997 
5998 /** changes upper bound of variable in preprocessing or in the current node, if the new bound is tighter
5999  * (w.r.t. bound strengthening epsilon) than the current bound; if possible, adjusts bound to integral value;
6000  * the given inference propagator is stored, such that the conflict analysis is able to find out the reason
6001  * for the deduction of the bound change
6002  *
6003  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6004  * SCIPgetVars()) gets resorted.
6005  *
6006  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6007  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6008  *
6009  * @pre This method can be called if @p scip is in one of the following stages:
6010  * - \ref SCIP_STAGE_PROBLEM
6011  * - \ref SCIP_STAGE_PRESOLVING
6012  * - \ref SCIP_STAGE_SOLVING
6013  *
6014  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6015  */
6017  SCIP* scip, /**< SCIP data structure */
6018  SCIP_VAR* var, /**< variable to change the bound for */
6019  SCIP_Real newbound, /**< new value for bound */
6020  SCIP_PROP* inferprop, /**< propagator that deduced the bound change */
6021  int inferinfo, /**< user information for inference to help resolving the conflict */
6022  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6023  SCIP_Bool* infeasible, /**< pointer to store whether the bound change is infeasible */
6024  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6025  )
6026 {
6027  SCIP_Real lb;
6028  SCIP_Real ub;
6029 
6030  assert(infeasible != NULL);
6031 
6032  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferVarUbProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6033 
6034  *infeasible = FALSE;
6035  if( tightened != NULL )
6036  *tightened = FALSE;
6037 
6038  SCIPvarAdjustUb(var, scip->set, &newbound);
6039 
6040  /* ignore tightenings of upper bounds to -infinity during solving process */
6041  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6042  {
6043 #ifndef NDEBUG
6044  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
6045  SCIPvarGetUbLocal(var));
6046 #endif
6047  return SCIP_OKAY;
6048  }
6049 
6050  /* get current bounds */
6051  lb = SCIPvarGetLbLocal(var);
6052  ub = SCIPvarGetUbLocal(var);
6053  assert(SCIPsetIsLE(scip->set, lb, ub));
6054 
6055  if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
6056  {
6057  *infeasible = TRUE;
6058  return SCIP_OKAY;
6059  }
6060  newbound = MAX(newbound, lb);
6061 
6062  if( (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub))
6063  || SCIPsetIsGE(scip->set, newbound, ub) )
6064  return SCIP_OKAY;
6065 
6066  switch( scip->set->stage )
6067  {
6068  case SCIP_STAGE_PROBLEM:
6069  assert(!SCIPvarIsTransformed(var));
6070  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6071  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6072  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6073  scip->branchcand, scip->eventqueue, newbound) );
6074  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
6075  break;
6076 
6077  case SCIP_STAGE_PRESOLVING:
6078  if( !SCIPinProbing(scip) )
6079  {
6080  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6081  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6082 
6083  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6084  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6086 
6088  {
6089  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6090  assert(!(*infeasible));
6091  }
6092  break;
6093  }
6094  /*lint -fallthrough*/
6095  case SCIP_STAGE_SOLVING:
6097  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
6098  scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, NULL, inferprop, inferinfo, FALSE) );
6099  break;
6100 
6101  default:
6102  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6103  return SCIP_INVALIDCALL;
6104  } /*lint !e788*/
6105 
6106  /* check whether the upper bound improved */
6107  if( tightened != NULL && ub > SCIPcomputeVarUbLocal(scip, var) )
6108  *tightened = TRUE;
6109 
6110  return SCIP_OKAY;
6111 }
6112 
6113 /** depending on SCIP's stage, fixes binary variable in the problem, in preprocessing, or in current node;
6114  * the given inference propagator is stored, such that the conflict analysis is able to find out the reason for the
6115  * deduction of the fixing
6116  *
6117  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6118  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6119  *
6120  * @pre This method can be called if @p scip is in one of the following stages:
6121  * - \ref SCIP_STAGE_PROBLEM
6122  * - \ref SCIP_STAGE_PRESOLVING
6123  * - \ref SCIP_STAGE_PRESOLVED
6124  * - \ref SCIP_STAGE_SOLVING
6125  */
6127  SCIP* scip, /**< SCIP data structure */
6128  SCIP_VAR* var, /**< binary variable to fix */
6129  SCIP_Bool fixedval, /**< value to fix binary variable to */
6130  SCIP_PROP* inferprop, /**< propagator that deduced the fixing */
6131  int inferinfo, /**< user information for inference to help resolving the conflict */
6132  SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
6133  SCIP_Bool* tightened /**< pointer to store whether the fixing tightened the local bounds, or NULL */
6134  )
6135 {
6136  SCIP_Real lb;
6137  SCIP_Real ub;
6138 
6139  assert(SCIPvarIsBinary(var));
6140  assert(fixedval == TRUE || fixedval == FALSE);
6141  assert(infeasible != NULL);
6142 
6143  SCIP_CALL( SCIPcheckStage(scip, "SCIPinferBinvarProp", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6144 
6145  *infeasible = FALSE;
6146  if( tightened != NULL )
6147  *tightened = FALSE;
6148 
6149  /* get current bounds */
6150  lb = SCIPvarGetLbLocal(var);
6151  ub = SCIPvarGetUbLocal(var);
6152  assert(SCIPsetIsEQ(scip->set, lb, 0.0) || SCIPsetIsEQ(scip->set, lb, 1.0));
6153  assert(SCIPsetIsEQ(scip->set, ub, 0.0) || SCIPsetIsEQ(scip->set, ub, 1.0));
6154  assert(SCIPsetIsLE(scip->set, lb, ub));
6155 
6156  /* check, if variable is already fixed */
6157  if( (lb > 0.5) || (ub < 0.5) )
6158  {
6159  *infeasible = (fixedval == (lb < 0.5));
6160 
6161  return SCIP_OKAY;
6162  }
6163 
6164  /* apply the fixing */
6165  switch( scip->set->stage )
6166  {
6167  case SCIP_STAGE_PROBLEM:
6168  assert(!SCIPvarIsTransformed(var));
6169  if( fixedval == TRUE )
6170  {
6171  SCIP_CALL( SCIPchgVarLb(scip, var, 1.0) );
6172  }
6173  else
6174  {
6175  SCIP_CALL( SCIPchgVarUb(scip, var, 0.0) );
6176  }
6177  break;
6178 
6179  case SCIP_STAGE_PRESOLVING:
6180  if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
6181  {
6182  SCIP_Bool fixed;
6183 
6184  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6185  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
6186  scip->cliquetable, (SCIP_Real)fixedval, infeasible, &fixed) );
6187  break;
6188  }
6189  /*lint -fallthrough*/
6190  case SCIP_STAGE_SOLVING:
6191  if( fixedval == TRUE )
6192  {
6194  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, 1.0,
6195  SCIP_BOUNDTYPE_LOWER, NULL, inferprop, inferinfo, FALSE) );
6196  }
6197  else
6198  {
6200  scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, 0.0,
6201  SCIP_BOUNDTYPE_UPPER, NULL, inferprop, inferinfo, FALSE) );
6202  }
6203  break;
6204 
6205  default:
6206  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6207  return SCIP_INVALIDCALL;
6208  } /*lint !e788*/
6209 
6210  if( tightened != NULL )
6211  *tightened = TRUE;
6212 
6213  return SCIP_OKAY;
6214 }
6215 
6216 /** changes global lower bound of variable in preprocessing or in the current node, if the new bound is tighter
6217  * (w.r.t. bound strengthening epsilon) than the current global bound; if possible, adjusts bound to integral value;
6218  * also tightens the local bound, if the global bound is better than the local bound
6219  *
6220  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6221  * SCIPgetVars()) gets resorted.
6222  *
6223  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6224  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6225  *
6226  * @pre This method can be called if @p scip is in one of the following stages:
6227  * - \ref SCIP_STAGE_PROBLEM
6228  * - \ref SCIP_STAGE_TRANSFORMING
6229  * - \ref SCIP_STAGE_PRESOLVING
6230  * - \ref SCIP_STAGE_SOLVING
6231  *
6232  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6233  */
6235  SCIP* scip, /**< SCIP data structure */
6236  SCIP_VAR* var, /**< variable to change the bound for */
6237  SCIP_Real newbound, /**< new value for bound */
6238  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6239  SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
6240  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6241  )
6242 {
6243  SCIP_Real lb;
6244  SCIP_Real ub;
6245 
6246  assert(infeasible != NULL);
6247 
6248  SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarLbGlobal", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6249 
6250  *infeasible = FALSE;
6251  if( tightened != NULL )
6252  *tightened = FALSE;
6253 
6254  SCIPvarAdjustLb(var, scip->set, &newbound);
6255 
6256  /* ignore tightenings of lower bounds to +infinity during solving process */
6257  if( SCIPisInfinity(scip, newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6258  {
6259 #ifndef NDEBUG
6260  SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
6261  SCIPvarGetLbLocal(var));
6262 #endif
6263  return SCIP_OKAY;
6264  }
6265 
6266  /* get current bounds */
6267  lb = SCIPvarGetLbGlobal(var);
6268  ub = SCIPvarGetUbGlobal(var);
6269  assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPsetIsLE(scip->set, lb, ub));
6270 
6271  if( SCIPsetIsFeasGT(scip->set, newbound, ub) )
6272  {
6273  *infeasible = TRUE;
6274  return SCIP_OKAY;
6275  }
6276  newbound = MIN(newbound, ub);
6277 
6278  /* bound changes of less than epsilon are ignored by SCIPvarChgLb or raise an assert in SCIPnodeAddBoundinfer,
6279  * so don't apply them even if force is set
6280  */
6281  if( SCIPsetIsEQ(scip->set, lb, newbound) || (!force && !SCIPsetIsLbBetter(scip->set, newbound, lb, ub)) )
6282  return SCIP_OKAY;
6283 
6284  switch( scip->set->stage )
6285  {
6286  case SCIP_STAGE_PROBLEM:
6287  assert(!SCIPvarIsTransformed(var));
6288  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6289  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6290  SCIP_CALL( SCIPvarChgLbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6291  scip->branchcand, scip->eventqueue, newbound) );
6292  SCIP_CALL( SCIPvarChgLbOriginal(var, scip->set, newbound) );
6293  break;
6294 
6296  SCIP_CALL( SCIPvarChgLbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6297  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6298  break;
6299 
6300  case SCIP_STAGE_PRESOLVING:
6301  if( !SCIPinProbing(scip) )
6302  {
6303  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6304  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6305 
6306  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6307  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6309 
6311  {
6312  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6313  assert(!(*infeasible));
6314  }
6315  break;
6316  }
6317  /*lint -fallthrough*/
6318  case SCIP_STAGE_SOLVING:
6319  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6320  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6322  break;
6323 
6324  default:
6325  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6326  return SCIP_INVALIDCALL;
6327  } /*lint !e788*/
6328 
6329  /* coverity: unreachable code */
6330  if( tightened != NULL && lb < SCIPcomputeVarLbGlobal(scip, var) )
6331  *tightened = TRUE;
6332 
6333  return SCIP_OKAY;
6334 }
6335 
6336 /** changes global upper bound of variable in preprocessing or in the current node, if the new bound is tighter
6337  * (w.r.t. bound strengthening epsilon) than the current global bound; if possible, adjusts bound to integral value;
6338  * also tightens the local bound, if the global bound is better than the local bound
6339  *
6340  * @warning If SCIP is in presolving stage, it can happen that the internal variable array (which can be accessed via
6341  * SCIPgetVars()) gets resorted.
6342  *
6343  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6344  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6345  *
6346  * @pre This method can be called if @p scip is in one of the following stages:
6347  * - \ref SCIP_STAGE_PROBLEM
6348  * - \ref SCIP_STAGE_TRANSFORMING
6349  * - \ref SCIP_STAGE_PRESOLVING
6350  * - \ref SCIP_STAGE_SOLVING
6351  *
6352  * @note During presolving, an integer variable whose bound changes to {0,1} is upgraded to a binary variable.
6353  */
6355  SCIP* scip, /**< SCIP data structure */
6356  SCIP_VAR* var, /**< variable to change the bound for */
6357  SCIP_Real newbound, /**< new value for bound */
6358  SCIP_Bool force, /**< force tightening even if below bound strengthening tolerance */
6359  SCIP_Bool* infeasible, /**< pointer to store whether the new domain is empty */
6360  SCIP_Bool* tightened /**< pointer to store whether the bound was tightened, or NULL */
6361  )
6362 {
6363  SCIP_Real lb;
6364  SCIP_Real ub;
6365 
6366  assert(infeasible != NULL);
6367 
6368  SCIP_CALL( SCIPcheckStage(scip, "SCIPtightenVarUbGlobal", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6369 
6370  *infeasible = FALSE;
6371  if( tightened != NULL )
6372  *tightened = FALSE;
6373 
6374  SCIPvarAdjustUb(var, scip->set, &newbound);
6375 
6376  /* ignore tightenings of upper bounds to -infinity during solving process */
6377  if( SCIPisInfinity(scip, -newbound) && SCIPgetStage(scip) == SCIP_STAGE_SOLVING )
6378  {
6379 #ifndef NDEBUG
6380  SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
6381  SCIPvarGetUbLocal(var));
6382 #endif
6383  return SCIP_OKAY;
6384  }
6385 
6386  /* get current bounds */
6387  lb = SCIPvarGetLbGlobal(var);
6388  ub = SCIPvarGetUbGlobal(var);
6389  assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPsetIsLE(scip->set, lb, ub));
6390 
6391  if( SCIPsetIsFeasLT(scip->set, newbound, lb) )
6392  {
6393  *infeasible = TRUE;
6394  return SCIP_OKAY;
6395  }
6396  newbound = MAX(newbound, lb);
6397 
6398  /* bound changes of less than epsilon are ignored by SCIPvarChgUb or raise an assert in SCIPnodeAddBoundinfer,
6399  * so don't apply them even if force is set
6400  */
6401  if( SCIPsetIsEQ(scip->set, ub, newbound) || (!force && !SCIPsetIsUbBetter(scip->set, newbound, lb, ub)) )
6402  return SCIP_OKAY;
6403 
6404  switch( scip->set->stage )
6405  {
6406  case SCIP_STAGE_PROBLEM:
6407  assert(!SCIPvarIsTransformed(var));
6408  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6409  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6410  SCIP_CALL( SCIPvarChgUbLocal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6411  scip->branchcand, scip->eventqueue, newbound) );
6412  SCIP_CALL( SCIPvarChgUbOriginal(var, scip->set, newbound) );
6413  break;
6414 
6416  SCIP_CALL( SCIPvarChgUbGlobal(var, scip->mem->probmem, scip->set, scip->stat, scip->lp,
6417  scip->branchcand, scip->eventqueue, scip->cliquetable, newbound) );
6418  break;
6419 
6420  case SCIP_STAGE_PRESOLVING:
6421  if( !SCIPinProbing(scip) )
6422  {
6423  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
6424  assert(scip->tree->root == SCIPtreeGetCurrentNode(scip->tree));
6425 
6426  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6427  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6429 
6431  {
6432  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, infeasible) );
6433  assert(!(*infeasible));
6434  }
6435  break;
6436  }
6437  /*lint -fallthrough*/
6438  case SCIP_STAGE_SOLVING:
6439  SCIP_CALL( SCIPnodeAddBoundchg(scip->tree->root, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6440  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->cliquetable, var, newbound,
6442  break;
6443 
6444  default:
6445  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
6446  return SCIP_INVALIDCALL;
6447  } /*lint !e788*/
6448 
6449  /* coverity: unreachable code */
6450  if( tightened != NULL && ub > SCIPcomputeVarUbGlobal(scip, var) )
6451  *tightened = TRUE;
6452 
6453  return SCIP_OKAY;
6454 }
6455 
6456 /* some simple variable functions implemented as defines */
6457 #undef SCIPcomputeVarLbGlobal
6458 #undef SCIPcomputeVarUbGlobal
6459 #undef SCIPcomputeVarLbLocal
6460 #undef SCIPcomputeVarUbLocal
6461 
6462 /** for a multi-aggregated variable, returns the global lower bound computed by adding the global bounds from all aggregation variables
6463  *
6464  * 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
6465  * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetLbGlobal.
6466  *
6467  * @return the global lower bound computed by adding the global bounds from all aggregation variables
6468  */
6470  SCIP* scip, /**< SCIP data structure */
6471  SCIP_VAR* var /**< variable to compute the bound for */
6472  )
6473 {
6474  assert(scip != NULL);
6475  assert(var != NULL);
6476 
6478  return SCIPvarGetMultaggrLbGlobal(var, scip->set);
6479  else
6480  return SCIPvarGetLbGlobal(var);
6481 }
6482 
6483 /** for a multi-aggregated variable, returns the global upper bound computed by adding the global bounds from all aggregation variables
6484  *
6485  * 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
6486  * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetUbGlobal
6487  *
6488  * @return the global upper bound computed by adding the global bounds from all aggregation variables
6489  */
6491  SCIP* scip, /**< SCIP data structure */
6492  SCIP_VAR* var /**< variable to compute the bound for */
6493  )
6494 {
6495  assert(scip != NULL);
6496  assert(var != NULL);
6497 
6499  return SCIPvarGetMultaggrUbGlobal(var, scip->set);
6500  else
6501  return SCIPvarGetUbGlobal(var);
6502 }
6503 
6504 /** for a multi-aggregated variable, returns the local lower bound computed by adding the local bounds from all aggregation variables
6505  *
6506  * 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
6507  * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetLbLocal.
6508  *
6509  * @return the local lower bound computed by adding the global bounds from all aggregation variables
6510  */
6512  SCIP* scip, /**< SCIP data structure */
6513  SCIP_VAR* var /**< variable to compute the bound for */
6514  )
6515 {
6516  assert(scip != NULL);
6517  assert(var != NULL);
6518 
6520  return SCIPvarGetMultaggrLbLocal(var, scip->set);
6521  else
6522  return SCIPvarGetLbLocal(var);
6523 }
6524 
6525 /** for a multi-aggregated variable, returns the local upper bound computed by adding the local bounds from all aggregation variables
6526  *
6527  * 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
6528  * calling this function for a non-multi-aggregated variable results in a call to SCIPvarGetUbLocal.
6529  *
6530  * @return the local upper bound computed by adding the global bounds from all aggregation variables
6531  */
6533  SCIP* scip, /**< SCIP data structure */
6534  SCIP_VAR* var /**< variable to compute the bound for */
6535  )
6536 {
6537  assert(scip != NULL);
6538  assert(var != NULL);
6539 
6541  return SCIPvarGetMultaggrUbLocal(var, scip->set);
6542  else
6543  return SCIPvarGetUbLocal(var);
6544 }
6545 
6546 /** for a multi-aggregated variable, gives the global lower bound computed by adding the global bounds from all
6547  * aggregation variables, this global bound may be tighter than the one given by SCIPvarGetLbGlobal, since the latter is
6548  * not updated if bounds of aggregation variables are changing
6549  *
6550  * calling this function for a non-multi-aggregated variable is not allowed
6551  */
6553  SCIP* scip, /**< SCIP data structure */
6554  SCIP_VAR* var /**< variable to compute the bound for */
6555  )
6556 {
6557  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
6558  return SCIPvarGetMultaggrLbGlobal(var, scip->set);
6559 }
6560 
6561 /** for a multi-aggregated variable, gives the global upper bound computed by adding the global bounds from all
6562  * aggregation variables, this upper bound may be tighter than the one given by SCIPvarGetUbGlobal, since the latter is
6563  * not updated if bounds of aggregation variables are changing
6564  *
6565  * calling this function for a non-multi-aggregated variable is not allowed
6566  */
6568  SCIP* scip, /**< SCIP data structure */
6569  SCIP_VAR* var /**< variable to compute the bound for */
6570  )
6571 {
6572  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
6573  return SCIPvarGetMultaggrUbGlobal(var, scip->set);
6574 }
6575 
6576 /** for a multi-aggregated variable, gives the local lower bound computed by adding the local bounds from all
6577  * aggregation variables, this lower bound may be tighter than the one given by SCIPvarGetLbLocal, since the latter is
6578  * not updated if bounds of aggregation variables are changing
6579  *
6580  * calling this function for a non-multi-aggregated variable is not allowed
6581  */
6583  SCIP* scip, /**< SCIP data structure */
6584  SCIP_VAR* var /**< variable to compute the bound for */
6585  )
6586 {
6587  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
6588  return SCIPvarGetMultaggrLbLocal(var, scip->set);
6589 }
6590 
6591 /** for a multi-aggregated variable, gives the local upper bound computed by adding the local bounds from all
6592  * aggregation variables, this upper bound may be tighter than the one given by SCIPvarGetUbLocal, since the latter is
6593  * not updated if bounds of aggregation variables are changing
6594  *
6595  * calling this function for a non-multi-aggregated variable is not allowed
6596  */
6598  SCIP* scip, /**< SCIP data structure */
6599  SCIP_VAR* var /**< variable to compute the bound for */
6600  )
6601 {
6602  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
6603  return SCIPvarGetMultaggrUbLocal(var, scip->set);
6604 }
6605 
6606 /** returns solution value and index of variable lower bound that is closest to the variable's value in the given primal
6607  * solution or current LP solution if no primal solution is given; returns an index of -1 if no variable lower bound is
6608  * available
6609  *
6610  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6611  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6612  *
6613  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
6614  */
6616  SCIP* scip, /**< SCIP data structure */
6617  SCIP_VAR* var, /**< active problem variable */
6618  SCIP_SOL* sol, /**< primal solution, or NULL for LP solution */
6619  SCIP_Real* closestvlb, /**< pointer to store the value of the closest variable lower bound */
6620  int* closestvlbidx /**< pointer to store the index of the closest variable lower bound */
6621  )
6622 {
6623  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarClosestVlb", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6624 
6625  SCIPvarGetClosestVlb(var, sol, scip->set, scip->stat, closestvlb, closestvlbidx);
6626 
6627  return SCIP_OKAY;
6628 }
6629 
6630 /** returns solution value and index of variable upper bound that is closest to the variable's value in the given primal solution;
6631  * or current LP solution if no primal solution is given; returns an index of -1 if no variable upper bound is available
6632  *
6633  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6634  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6635  *
6636  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
6637  */
6639  SCIP* scip, /**< SCIP data structure */
6640  SCIP_VAR* var, /**< active problem variable */
6641  SCIP_SOL* sol, /**< primal solution, or NULL for LP solution */
6642  SCIP_Real* closestvub, /**< pointer to store the value of the closest variable lower bound */
6643  int* closestvubidx /**< pointer to store the index of the closest variable lower bound */
6644  )
6645 {
6646  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarClosestVub", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6647 
6648  SCIPvarGetClosestVub(var, sol, scip->set, scip->stat, closestvub, closestvubidx);
6649 
6650  return SCIP_OKAY;
6651 }
6652 
6653 /** informs variable x about a globally valid variable lower bound x >= b*z + d with integer variable z;
6654  * if z is binary, the corresponding valid implication for z is also added;
6655  * if z is non-continuous and 1/b not too small, the corresponding valid upper/lower bound
6656  * z <= (x-d)/b or z >= (x-d)/b (depending on the sign of of b) is added, too;
6657  * improves the global bounds of the variable and the vlb variable if possible
6658  *
6659  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6660  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6661  *
6662  * @pre This method can be called if @p scip is in one of the following stages:
6663  * - \ref SCIP_STAGE_PRESOLVING
6664  * - \ref SCIP_STAGE_PRESOLVED
6665  * - \ref SCIP_STAGE_SOLVING
6666  */
6668  SCIP* scip, /**< SCIP data structure */
6669  SCIP_VAR* var, /**< problem variable */
6670  SCIP_VAR* vlbvar, /**< variable z in x >= b*z + d */
6671  SCIP_Real vlbcoef, /**< coefficient b in x >= b*z + d */
6672  SCIP_Real vlbconstant, /**< constant d in x >= b*z + d */
6673  SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6674  int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6675  )
6676 {
6677  int nlocalbdchgs;
6678 
6679  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarVlb", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6680 
6681  SCIP_CALL( SCIPvarAddVlb(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->tree,
6682  scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, vlbvar, vlbcoef, vlbconstant,
6683  TRUE, infeasible, &nlocalbdchgs) );
6684 
6685  *nbdchgs = nlocalbdchgs;
6686 
6687  /* 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
6688  * detected infeasibility
6689  */
6690  if( !(*infeasible) && SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisZero(scip, 1.0/vlbcoef) )
6691  {
6692  if( vlbcoef > 0.0 )
6693  {
6694  /* if b > 0, we have a variable upper bound: x >= b*z + d => z <= (x-d)/b */
6695  SCIP_CALL( SCIPvarAddVub(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  else
6700  {
6701  /* if b < 0, we have a variable lower bound: x >= b*z + d => z >= (x-d)/b */
6702  SCIP_CALL( SCIPvarAddVlb(vlbvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6703  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vlbcoef,
6704  -vlbconstant/vlbcoef, TRUE, infeasible, &nlocalbdchgs) );
6705  }
6706  *nbdchgs += nlocalbdchgs;
6707  }
6708 
6709  return SCIP_OKAY;
6710 }
6711 
6712 /** informs variable x about a globally valid variable upper bound x <= b*z + d with integer variable z;
6713  * if z is binary, the corresponding valid implication for z is also added;
6714  * if z is non-continuous and 1/b not too small, the corresponding valid lower/upper bound
6715  * z >= (x-d)/b or z <= (x-d)/b (depending on the sign of of b) is added, too;
6716  * improves the global bounds of the variable and the vlb variable if possible
6717  *
6718  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6719  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6720  *
6721  * @pre This method can be called if @p scip is in one of the following stages:
6722  * - \ref SCIP_STAGE_PRESOLVING
6723  * - \ref SCIP_STAGE_PRESOLVED
6724  * - \ref SCIP_STAGE_SOLVING
6725  */
6727  SCIP* scip, /**< SCIP data structure */
6728  SCIP_VAR* var, /**< problem variable */
6729  SCIP_VAR* vubvar, /**< variable z in x <= b*z + d */
6730  SCIP_Real vubcoef, /**< coefficient b in x <= b*z + d */
6731  SCIP_Real vubconstant, /**< constant d in x <= b*z + d */
6732  SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6733  int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6734  )
6735 {
6736  int nlocalbdchgs;
6737 
6738  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarVub", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6739 
6740  SCIP_CALL( SCIPvarAddVub(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob, scip->tree,
6741  scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, vubvar, vubcoef, vubconstant, TRUE,
6742  infeasible, &nlocalbdchgs) );
6743 
6744  *nbdchgs = nlocalbdchgs;
6745 
6746  /* 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
6747  * detected infeasibility
6748  */
6749  if( !(*infeasible) && SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisZero(scip, 1.0/vubcoef) )
6750  {
6751  if( vubcoef > 0.0 )
6752  {
6753  /* if b < 0, we have a variable lower bound: x >= b*z + d => z >= (x-d)/b */
6754  SCIP_CALL( SCIPvarAddVlb(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  else
6759  {
6760  /* if b > 0, we have a variable upper bound: x >= b*z + d => z <= (x-d)/b */
6761  SCIP_CALL( SCIPvarAddVub(vubvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6762  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var, 1.0/vubcoef,
6763  -vubconstant/vubcoef, TRUE, infeasible, &nlocalbdchgs) );
6764  }
6765  *nbdchgs += nlocalbdchgs;
6766  }
6767 
6768  return SCIP_OKAY;
6769 }
6770 
6771 /** informs binary variable x about a globally valid implication: x == 0 or x == 1 ==> y <= b or y >= b;
6772  * also adds the corresponding implication or variable bound to the implied variable;
6773  * if the implication is conflicting, the variable is fixed to the opposite value;
6774  * if the variable is already fixed to the given value, the implication is performed immediately;
6775  * if the implication is redundant with respect to the variables' global bounds, it is ignored
6776  *
6777  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6778  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6779  *
6780  * @pre This method can be called if @p scip is in one of the following stages:
6781  * - \ref SCIP_STAGE_TRANSFORMED
6782  * - \ref SCIP_STAGE_PRESOLVING
6783  * - \ref SCIP_STAGE_PRESOLVED
6784  * - \ref SCIP_STAGE_SOLVING
6785  */
6787  SCIP* scip, /**< SCIP data structure */
6788  SCIP_VAR* var, /**< problem variable */
6789  SCIP_Bool varfixing, /**< FALSE if y should be added in implications for x == 0, TRUE for x == 1 */
6790  SCIP_VAR* implvar, /**< variable y in implication y <= b or y >= b */
6791  SCIP_BOUNDTYPE impltype, /**< type of implication y <= b (SCIP_BOUNDTYPE_UPPER)
6792  * or y >= b (SCIP_BOUNDTYPE_LOWER) */
6793  SCIP_Real implbound, /**< bound b in implication y <= b or y >= b */
6794  SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6795  int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6796  )
6797 {
6798  SCIP_VAR* implprobvar;
6799 
6800  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarImplication", FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6801 
6802  assert(infeasible != NULL);
6803  *infeasible = FALSE;
6804 
6805  if ( nbdchgs != NULL )
6806  *nbdchgs = 0;
6807 
6808  if( !SCIPvarIsBinary(var) )
6809  {
6810  SCIPerrorMessage("can't add implication for nonbinary variable\n");
6811  return SCIP_INVALIDDATA;
6812  }
6813 
6814  implprobvar = SCIPvarGetProbvar(implvar);
6815  /* transform implication containing two binary variables to a clique; the condition ensures that the active representative
6816  * of implvar is actually binary
6817  */
6818  if( SCIPvarIsBinary(implvar) && (SCIPvarIsActive(implvar) || (implprobvar != NULL && SCIPvarIsBinary(implprobvar))) )
6819  {
6820  assert(SCIPisFeasEQ(scip, implbound, 1.0) || SCIPisFeasZero(scip, implbound));
6821  assert((impltype == SCIP_BOUNDTYPE_UPPER) == SCIPisFeasZero(scip, implbound));
6822 
6823  /* only add clique if implication is not redundant with respect to global bounds of the implication variable */
6824  if( (impltype == SCIP_BOUNDTYPE_LOWER && SCIPvarGetLbGlobal(implvar) < 0.5) ||
6825  (impltype == SCIP_BOUNDTYPE_UPPER && SCIPvarGetUbGlobal(implvar) > 0.5) )
6826  {
6827  SCIP_VAR* vars[2];
6828  SCIP_Bool vals[2];
6829 
6830  vars[0] = var;
6831  vars[1] = implvar;
6832  vals[0] = varfixing;
6833  vals[1] = (impltype == SCIP_BOUNDTYPE_UPPER);
6834 
6835  SCIP_CALL( SCIPaddClique(scip, vars, vals, 2, FALSE, infeasible, nbdchgs) );
6836  }
6837 
6838  return SCIP_OKAY;
6839  }
6840 
6841  /* the implication graph can only handle 'real' binary (SCIP_VARTYPE_BINARY) variables, therefore we transform the
6842  * implication in variable bounds, (lowerbound of y will be abbreviated by lby, upperbound equivlaent) the follwing
6843  * four cases are:
6844  *
6845  * 1. (x >= 1 => y >= b) => y >= (b - lby) * x + lby
6846  * 2. (x >= 1 => y <= b) => y <= (b - uby) * x + uby
6847  * 3. (x <= 0 => y >= b) => y >= (lby - b) * x + b
6848  * 4. (x <= 0 => y <= b) => y <= (uby - b) * x + b
6849  */
6850  if( SCIPvarGetType(var) != SCIP_VARTYPE_BINARY )
6851  {
6852  SCIP_Real lby;
6853  SCIP_Real uby;
6854 
6855  lby = SCIPvarGetLbGlobal(implvar);
6856  uby = SCIPvarGetUbGlobal(implvar);
6857 
6858  if( varfixing == TRUE )
6859  {
6860  if( impltype == SCIP_BOUNDTYPE_LOWER )
6861  {
6862  /* we return if the lower bound is infinity */
6863  if( SCIPisInfinity(scip, -lby) )
6864  return SCIP_OKAY;
6865 
6866  SCIP_CALL( SCIPvarAddVlb(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6867  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6868  implbound - lby, lby, TRUE, infeasible, nbdchgs) );
6869  }
6870  else
6871  {
6872  /* we return if the upper bound is infinity */
6873  if( SCIPisInfinity(scip, uby) )
6874  return SCIP_OKAY;
6875 
6876  SCIP_CALL( SCIPvarAddVub(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6877  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6878  implbound - uby, uby, TRUE, infeasible, nbdchgs) );
6879  }
6880  }
6881  else
6882  {
6883  if( impltype == SCIP_BOUNDTYPE_LOWER )
6884  {
6885  /* we return if the lower bound is infinity */
6886  if( SCIPisInfinity(scip, -lby) )
6887  return SCIP_OKAY;
6888 
6889  SCIP_CALL( SCIPvarAddVlb(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6890  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6891  lby - implbound, implbound, TRUE, infeasible, nbdchgs) );
6892  }
6893  else
6894  {
6895  /* we return if the upper bound is infinity */
6896  if( SCIPisInfinity(scip, uby) )
6897  return SCIP_OKAY;
6898 
6899  SCIP_CALL( SCIPvarAddVub(implvar, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6900  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, var,
6901  uby - implbound, implbound, TRUE, infeasible, nbdchgs) );
6902  }
6903  }
6904  }
6905  else
6906  {
6907  SCIP_CALL( SCIPvarAddImplic(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
6908  scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventqueue, varfixing, implvar, impltype,
6909  implbound, TRUE, infeasible, nbdchgs) );
6910  }
6911 
6912  return SCIP_OKAY;
6913 }
6914 
6915 /** adds a clique information to SCIP, stating that at most one of the given binary variables can be set to 1;
6916  * if a variable appears twice in the same clique, the corresponding implications are performed
6917  *
6918  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
6919  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
6920  *
6921  * @pre This method can be called if @p scip is in one of the following stages:
6922  * - \ref SCIP_STAGE_TRANSFORMED
6923  * - \ref SCIP_STAGE_PRESOLVING
6924  * - \ref SCIP_STAGE_PRESOLVED
6925  * - \ref SCIP_STAGE_SOLVING
6926  */
6928  SCIP* scip, /**< SCIP data structure */
6929  SCIP_VAR** vars, /**< binary variables in the clique from which at most one can be set to 1 */
6930  SCIP_Bool* values, /**< values of the variables in the clique; NULL to use TRUE for all vars */
6931  int nvars, /**< number of variables in the clique */
6932  SCIP_Bool isequation, /**< is the clique an equation or an inequality? */
6933  SCIP_Bool* infeasible, /**< pointer to store whether an infeasibility was detected */
6934  int* nbdchgs /**< pointer to store the number of performed bound changes, or NULL */
6935  )
6936 {
6937  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddClique", FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
6938 
6939  *infeasible = FALSE;
6940  if( nbdchgs != NULL )
6941  *nbdchgs = 0;
6942 
6943  if( nvars > 1 )
6944  {
6945  /* add the clique to the clique table */
6946  SCIP_CALL( SCIPcliquetableAdd(scip->cliquetable, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
6947  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, vars, values, nvars, isequation,
6948  infeasible, nbdchgs) );
6949  }
6950 
6951  return SCIP_OKAY;
6952 }
6953 
6954 /** relabels the given labels in-place in an increasing fashion: the first seen label is 0, the next label 1, etc...
6955  *
6956  * @note every label equal to -1 is treated as a previously unseen, unique label and gets a new ordered label.
6957  */
6958 static
6960  SCIP*const scip, /**< SCIP data structure */
6961  int* labels, /**< current labels that will be overwritten */
6962  int const nlabels, /**< number of variables in the clique */
6963  int* nclasses /**< pointer to store the total number of distinct labels */
6964  )
6965 {
6966  SCIP_HASHMAP* classidx2newlabel;
6967 
6968  int classidx;
6969  int i;
6970 
6971  SCIP_CALL( SCIPhashmapCreate(&classidx2newlabel, SCIPblkmem(scip), nlabels) );
6972 
6973  classidx = 0;
6974 
6975  /* loop over labels to create local class indices that obey the variable order */
6976  for( i = 0; i < nlabels; ++i )
6977  {
6978  int currentlabel = labels[i];
6979  int localclassidx;
6980 
6981  /* labels equal to -1 are stored as singleton classes */
6982  if( currentlabel == -1 )
6983  {
6984  ++classidx;
6985  localclassidx = classidx;
6986  }
6987  else
6988  {
6989  assert(currentlabel >= 0);
6990  /* look up the class index image in the hash map; if it is not stored yet, new class index is created and stored */
6991  if( !SCIPhashmapExists(classidx2newlabel, (void*)(size_t)currentlabel) )
6992  {
6993  ++classidx;
6994  localclassidx = classidx;
6995  SCIP_CALL( SCIPhashmapInsertInt(classidx2newlabel, (void*)(size_t)currentlabel, classidx) ); /*lint !e571*/
6996  }
6997  else
6998  {
6999  localclassidx = SCIPhashmapGetImageInt(classidx2newlabel, (void*)(size_t)currentlabel); /*lint !e571*/
7000  }
7001  }
7002  assert(localclassidx - 1 >= 0);
7003  assert(localclassidx - 1 <= i);
7004 
7005  /* indices start with zero, but we have an offset of 1 because we cannot store 0 in a hashmap */
7006  labels[i] = localclassidx - 1;
7007  }
7008 
7009  assert(classidx > 0);
7010  assert(classidx <= nlabels);
7011  *nclasses = classidx;
7012 
7013  SCIPhashmapFree(&classidx2newlabel);
7014 
7015  return SCIP_OKAY;
7016 }
7017 
7018 /** sort the variables w.r.t. the given labels; thereby ensure the current order of the variables with the same label. */
7019 static
7021  SCIP* scip, /**< SCIP data structure */
7022  SCIP_VAR** vars, /**< variable array */
7023  int* classlabels, /**< array that contains a class label for every variable */
7024  SCIP_VAR** sortedvars, /**< array to store variables after stable sorting */
7025  int* sortedindices, /**< array to store indices of sorted variables in the original vars array */
7026  int* classesstartposs, /**< starting position array for each label class (must have size nclasses + 1) */
7027  int nvars, /**< size of the vars arrays */
7028  int nclasses /**< number of label classes */
7029  )
7030 {
7031  SCIP_VAR*** varpointers;
7032  int** indexpointers;
7033  int* classcount;
7034 
7035  int nextpos;
7036  int c;
7037  int v;
7038 
7039  assert(scip != NULL);
7040  assert(vars != NULL);
7041  assert(sortedindices != NULL);
7042  assert(classesstartposs != NULL);
7043 
7044  assert(nvars == 0 || vars != NULL);
7045 
7046  if( nvars == 0 )
7047  return SCIP_OKAY;
7048 
7049  assert(classlabels != NULL);
7050  assert(nclasses > 0);
7051 
7052  /* we first count all class cardinalities and allocate temporary memory for a bucket sort */
7053  SCIP_CALL( SCIPallocBufferArray(scip, &classcount, nclasses) );
7054  BMSclearMemoryArray(classcount, nclasses);
7055 
7056  /* first we count for each class the number of elements */
7057  for( v = nvars - 1; v >= 0; --v )
7058  {
7059  assert(0 <= classlabels[v] && classlabels[v] < nclasses);
7060  ++(classcount[classlabels[v]]);
7061  }
7062 
7063 #ifndef NDEBUG
7064  BMSclearMemoryArray(sortedvars, nvars);
7065  BMSclearMemoryArray(sortedindices, nvars);
7066 #endif
7067  SCIP_CALL( SCIPallocBufferArray(scip, &varpointers, nclasses) );
7068  SCIP_CALL( SCIPallocBufferArray(scip, &indexpointers, nclasses) );
7069 
7070  nextpos = 0;
7071  /* now we initialize all start pointers for each class, so they will be ordered */
7072  for( c = 0; c < nclasses; ++c )
7073  {
7074  /* to reach the goal that all variables of each class will be standing next to each other we will initialize the
7075  * starting pointers for each class by adding the cardinality of each class to the last class starting pointer
7076  * e.g. class1 has 4 elements and class2 has 3 elements then the starting pointer for class1 will be the pointer
7077  * to sortedvars[0], the starting pointer to class2 will be the pointer to sortedvars[4] and to class3 it will be
7078  * the pointer to sortedvars[7]
7079  */
7080  varpointers[c] = (SCIP_VAR**) (sortedvars + nextpos);
7081  indexpointers[c] = (int*) (sortedindices + nextpos);
7082  classesstartposs[c] = nextpos;
7083  assert(classcount[c] > 0);
7084  nextpos += classcount[c];
7085  assert(nextpos > 0);
7086  }
7087  assert(nextpos == nvars);
7088  classesstartposs[c] = nextpos;
7089 
7090  /* now we copy all variables to the right order */
7091  for( v = 0; v < nvars; ++v )
7092  {
7093  /* copy variable itself to the right position */
7094  *(varpointers[classlabels[v]]) = vars[v]; /*lint !e613*/
7095  ++(varpointers[classlabels[v]]);
7096 
7097  /* copy index */
7098  *(indexpointers[classlabels[v]]) = v;
7099  ++(indexpointers[classlabels[v]]);
7100  }
7101 
7102 /* in debug mode, we ensure the correctness of the mapping */
7103 #ifndef NDEBUG
7104  for( v = 0; v < nvars; ++v )
7105  {
7106  assert(sortedvars[v] != NULL);
7107  assert(sortedindices[v] >= 0);
7108 
7109  /* assert that the sorted indices map back to the correct variable in the original order */
7110  assert(vars[sortedindices[v]] == sortedvars[v]);
7111  }
7112 #endif
7113 
7114  /* free temporary memory */
7115  SCIPfreeBufferArray(scip, &indexpointers);
7116  SCIPfreeBufferArray(scip, &varpointers);
7117  SCIPfreeBufferArray(scip, &classcount);
7118 
7119  return SCIP_OKAY;
7120 }
7121 
7122 
7123 /* calculate clique partition for a maximal amount of comparisons on variables due to expensive algorithm
7124  * @todo: check for a good value, maybe it's better to check parts of variables
7125  */
7126 #define MAXNCLIQUEVARSCOMP 1000000
7127 
7128 /** calculates a partition of the given set of binary variables into cliques;
7129  * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7130  * were assigned to the same clique;
7131  * the first variable is always assigned to clique 0, and a variable can only be assigned to clique i if at least one of
7132  * the preceding variables was assigned to clique i-1;
7133  * for each clique at most 1 variables can be set to TRUE in a feasible solution;
7134  *
7135  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7136  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7137  *
7138  * @pre This method can be called if @p scip is in one of the following stages:
7139  * - \ref SCIP_STAGE_INITPRESOLVE
7140  * - \ref SCIP_STAGE_PRESOLVING
7141  * - \ref SCIP_STAGE_EXITPRESOLVE
7142  * - \ref SCIP_STAGE_PRESOLVED
7143  * - \ref SCIP_STAGE_SOLVING
7144  */
7145 static
7147  SCIP*const scip, /**< SCIP data structure */
7148  SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7149  SCIP_Bool*const values, /**< clique value (TRUE or FALSE) for each variable in the clique */
7150  int const nvars, /**< number of variables in the array */
7151  int*const cliquepartition, /**< array of length nvars to store the clique partition */
7152  int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7153  )
7154 {
7155  SCIP_VAR** cliquevars;
7156  SCIP_Bool* cliquevalues;
7157  int i;
7158  int maxncliquevarscomp;
7159  int ncliquevars;
7160 
7161  /* allocate temporary memory for storing the variables of the current clique */
7162  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &cliquevars, nvars) );
7163  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &cliquevalues, nvars) );
7164 
7165  /* initialize the cliquepartition array with -1 */
7166  for( i = nvars - 1; i >= 0; --i )
7167  cliquepartition[i] = -1;
7168 
7169  maxncliquevarscomp = (int) MIN(nvars * (SCIP_Longint)nvars, MAXNCLIQUEVARSCOMP);
7170  /* calculate the clique partition */
7171  *ncliques = 0;
7172  for( i = 0; i < nvars; ++i )
7173  {
7174  if( cliquepartition[i] == -1 )
7175  {
7176  int j;
7177 
7178  /* variable starts a new clique */
7179  cliquepartition[i] = *ncliques;
7180  cliquevars[0] = vars[i];
7181  cliquevalues[0] = values[i];
7182  ncliquevars = 1;
7183 
7184  /* if variable is not active (multi-aggregated or fixed), it cannot be in any clique */
7185  if( SCIPvarIsActive(vars[i]) && SCIPvarGetNCliques(vars[i], values[i]) > 0 )
7186  {
7187  /* greedily fill up the clique */
7188  for( j = i+1; j < nvars; ++j )
7189  {
7190  /* if variable is not active (multi-aggregated or fixed), it cannot be in any clique */
7191  if( cliquepartition[j] == -1 && SCIPvarIsActive(vars[j]) )
7192  {
7193  int k;
7194 
7195  /* check if every variable in the current clique can be extended by tmpvars[j] */
7196  for( k = ncliquevars - 1; k >= 0; --k )
7197  {
7198  if( !SCIPvarsHaveCommonClique(vars[j], values[j], cliquevars[k], cliquevalues[k], FALSE) )
7199  break;
7200  }
7201 
7202  if( k == -1 )
7203  {
7204  /* put the variable into the same clique */
7205  cliquepartition[j] = cliquepartition[i];
7206  cliquevars[ncliquevars] = vars[j];
7207  cliquevalues[ncliquevars] = values[j];
7208  ++ncliquevars;
7209  }
7210  }
7211  }
7212  }
7213 
7214  /* this clique is finished */
7215  ++(*ncliques);
7216  }
7217  assert(cliquepartition[i] >= 0 && cliquepartition[i] < i+1);
7218 
7219  /* break if we reached the maximal number of comparisons */
7220  if( i * nvars > maxncliquevarscomp )
7221  break;
7222  }
7223  /* if we had to many variables fill up the cliquepartition and put each variable in a separate clique */
7224  for( ; i < nvars; ++i )
7225  {
7226  if( cliquepartition[i] == -1 )
7227  {
7228  cliquepartition[i] = *ncliques;
7229  ++(*ncliques);
7230  }
7231  }
7232 
7233  SCIPsetFreeBufferArray(scip->set, &cliquevalues);
7234  SCIPsetFreeBufferArray(scip->set, &cliquevars);
7235 
7236  return SCIP_OKAY;
7237 }
7238 
7239 /** calculates a partition of the given set of binary variables into cliques; takes into account independent clique components
7240  *
7241  * The algorithm performs the following steps:
7242  * - recomputes connected components of the clique table, if necessary
7243  * - computes a clique partition for every connected component greedily.
7244  * - relabels the resulting clique partition such that it satisfies the description below
7245  *
7246  * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7247  * were assigned to the same clique;
7248  * the first variable is always assigned to clique 0, and a variable can only be assigned to clique i if at least one of
7249  * the preceding variables was assigned to clique i-1;
7250  * for each clique at most 1 variables can be set to TRUE in a feasible solution;
7251  *
7252  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7253  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7254  *
7255  * @pre This method can be called if @p scip is in one of the following stages:
7256  * - \ref SCIP_STAGE_INITPRESOLVE
7257  * - \ref SCIP_STAGE_PRESOLVING
7258  * - \ref SCIP_STAGE_EXITPRESOLVE
7259  * - \ref SCIP_STAGE_PRESOLVED
7260  * - \ref SCIP_STAGE_SOLVING
7261  */
7263  SCIP*const scip, /**< SCIP data structure */
7264  SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7265  int const nvars, /**< number of variables in the clique */
7266  int*const cliquepartition, /**< array of length nvars to store the clique partition */
7267  int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7268  )
7269 {
7270  SCIP_VAR** tmpvars;
7271 
7272  SCIP_VAR** sortedtmpvars;
7273  SCIP_Bool* tmpvalues;
7274  SCIP_Bool* sortedtmpvalues;
7275  int* componentlabels;
7276  int* sortedindices;
7277  int* componentstartposs;
7278  int i;
7279  int c;
7280 
7281  int ncomponents;
7282 
7283  assert(scip != NULL);
7284  assert(nvars == 0 || vars != NULL);
7285  assert(nvars == 0 || cliquepartition != NULL);
7286  assert(ncliques != NULL);
7287 
7288  SCIP_CALL( SCIPcheckStage(scip, "SCIPcalcCliquePartition", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7289 
7290  if( nvars == 0 )
7291  {
7292  *ncliques = 0;
7293  return SCIP_OKAY;
7294  }
7295 
7296  /* early abort if no cliques are present */
7297  if( SCIPgetNCliques(scip) == 0 )
7298  {
7299  for( i = 0; i < nvars; ++i )
7300  cliquepartition[i] = i;
7301 
7302  *ncliques = nvars;
7303 
7304  return SCIP_OKAY;
7305  }
7306 
7307  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &tmpvalues, nvars) );
7308  SCIP_CALL( SCIPsetDuplicateBufferArray(scip->set, &tmpvars, vars, nvars) );
7309  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &componentlabels, nvars) );
7310  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedindices, nvars) );
7311 
7312  /* initialize the tmpvalues array */
7313  for( i = nvars - 1; i >= 0; --i )
7314  {
7315  tmpvalues[i] = TRUE;
7316  cliquepartition[i] = -1;
7317  }
7318 
7319  /* get corresponding active problem variables */
7320  SCIP_CALL( SCIPvarsGetProbvarBinary(&tmpvars, &tmpvalues, nvars) );
7321 
7322  ncomponents = -1;
7323 
7324  /* update clique components if necessary */
7326  {
7327  SCIP_VAR** allvars;
7328  int nallbinvars;
7329  int nallintvars;
7330  int nallimplvars;
7331 
7332  SCIP_CALL( SCIPgetVarsData(scip, &allvars, NULL, &nallbinvars, &nallintvars, &nallimplvars, NULL) );
7333 
7334  SCIP_CALL( SCIPcliquetableComputeCliqueComponents(scip->cliquetable, scip->set, SCIPblkmem(scip), allvars, nallbinvars, nallintvars, nallimplvars) );
7335  }
7336 
7338 
7339  /* store the global clique component labels */
7340  for( i = 0; i < nvars; ++i )
7341  {
7342  if( SCIPvarIsActive(tmpvars[i]) )
7343  componentlabels[i] = SCIPcliquetableGetVarComponentIdx(scip->cliquetable, tmpvars[i]);
7344  else
7345  componentlabels[i] = -1;
7346  }
7347 
7348  /* relabel component labels order consistent as prerequisite for a stable sort */
7349  SCIP_CALL( relabelOrderConsistent(scip, componentlabels, nvars, &ncomponents) );
7350  assert(ncomponents >= 1);
7351  assert(ncomponents <= nvars);
7352 
7353  /* allocate storage array for the starting positions of the components */
7354  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &componentstartposs, ncomponents + 1) );
7355 
7356  /* stable sort the variables w.r.t. the component labels so that we can restrict the quadratic algorithm to the components */
7357  if( ncomponents > 1 )
7358  {
7359  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedtmpvars, nvars) );
7360  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &sortedtmpvalues, nvars) );
7361  SCIP_CALL( labelSortStable(scip, tmpvars, componentlabels, sortedtmpvars, sortedindices, componentstartposs, nvars, ncomponents) );
7362 
7363  /* reassign the tmpvalues with respect to the sorting */
7364  for( i = 0; i < nvars; ++i )
7365  {
7366  assert(tmpvars[sortedindices[i]] == sortedtmpvars[i]);
7367  sortedtmpvalues[i] = tmpvalues[sortedindices[i]];
7368  }
7369  }
7370  else
7371  {
7372  /* if we have only one large connected component, skip the stable sorting and prepare the data differently */
7373  sortedtmpvars = tmpvars;
7374  sortedtmpvalues = tmpvalues;
7375  componentstartposs[0] = 0;
7376  componentstartposs[1] = nvars;
7377 
7378  /* sorted indices are the identity */
7379  for( i = 0; i < nvars; ++i )
7380  sortedindices[i] = i;
7381  }
7382 
7383  *ncliques = 0;
7384  /* calculate a greedy clique partition for each connected component */
7385  for( c = 0; c < ncomponents; ++c )
7386  {
7387  int* localcliquepartition;
7388  int nlocalcliques;
7389  int ncomponentvars;
7390  int l;
7391 
7392  /* extract the number of variables in this connected component */
7393  ncomponentvars = componentstartposs[c + 1] - componentstartposs[c];
7394  nlocalcliques = 0;
7395 
7396  /* allocate necessary memory to hold the intermediate component clique partition */
7397  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &localcliquepartition, ncomponentvars) );
7398 
7399  /* call greedy clique algorithm for all component variables */
7400  SCIP_CALL( calcCliquePartitionGreedy(scip, &(sortedtmpvars[componentstartposs[c]]), &(sortedtmpvalues[componentstartposs[c]]),
7401  ncomponentvars, localcliquepartition, &nlocalcliques) );
7402 
7403  assert(nlocalcliques >= 1);
7404  assert(nlocalcliques <= ncomponentvars);
7405 
7406  /* store the obtained clique partition with an offset of ncliques for the original variables */
7407  for( l = componentstartposs[c]; l < componentstartposs[c + 1]; ++l )
7408  {
7409  int origvaridx = sortedindices[l];
7410  assert(cliquepartition[origvaridx] == -1);
7411  assert(localcliquepartition[l - componentstartposs[c]] <= l - componentstartposs[c]);
7412  cliquepartition[origvaridx] = localcliquepartition[l - componentstartposs[c]] + (*ncliques);
7413  }
7414  *ncliques += nlocalcliques;
7415 
7416  /* free the local clique partition */
7417  SCIPsetFreeBufferArray(scip->set, &localcliquepartition);
7418  }
7419 
7420  /* except in the two trivial cases, we have to ensure the order consistency of the partition indices */
7421  if( ncomponents > 1 && ncomponents < nvars )
7422  {
7423  int partitionsize;
7424  SCIP_CALL( relabelOrderConsistent(scip, cliquepartition, nvars, &partitionsize) );
7425 
7426  assert(partitionsize == *ncliques);
7427  }
7428 
7429  if( ncomponents > 1 )
7430  {
7431  SCIPsetFreeBufferArray(scip->set, &sortedtmpvalues);
7432  SCIPsetFreeBufferArray(scip->set, &sortedtmpvars);
7433  }
7434 
7435  /* use the greedy algorithm as a whole to verify the result on small number of variables */
7436 #ifdef SCIP_DISABLED_CODE
7437  {
7438  int* debugcliquepartition;
7439  int ndebugcliques;
7440 
7441  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &debugcliquepartition, nvars) );
7442 
7443  /* call greedy clique algorithm for all component variables */
7444  SCIP_CALL( calcCliquePartitionGreedy(scip, tmpvars, tmpvalues, nvars, debugcliquepartition, &ndebugcliques) );
7445 
7446  /* loop and compare the traditional greedy clique with */
7447  for( i = 0; i < nvars; ++i )
7448  assert(i * nvars > MAXNCLIQUEVARSCOMP || cliquepartition[i] == debugcliquepartition[i]);
7449 
7450  SCIPsetFreeBufferArray(scip->set, &debugcliquepartition);
7451  }
7452 #endif
7453 
7454  /* free temporary memory */
7455  SCIPsetFreeBufferArray(scip->set, &componentstartposs);
7456  SCIPsetFreeBufferArray(scip->set, &sortedindices);
7457  SCIPsetFreeBufferArray(scip->set, &componentlabels);
7458  SCIPsetFreeBufferArray(scip->set, &tmpvars);
7459  SCIPsetFreeBufferArray(scip->set, &tmpvalues);
7460 
7461  return SCIP_OKAY;
7462 }
7463 
7464 /** calculates a partition of the given set of binary variables into negated cliques;
7465  * afterwards the output array contains one value for each variable, such that two variables got the same value iff they
7466  * were assigned to the same negated clique;
7467  * the first variable is always assigned to clique 0 and a variable can only be assigned to clique i if at least one of
7468  * the preceding variables was assigned to clique i-1;
7469  * for each clique with n_c variables at least n_c-1 variables can be set to TRUE in a feasible solution;
7470  *
7471  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7472  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7473  *
7474  * @pre This method can be called if @p scip is in one of the following stages:
7475  * - \ref SCIP_STAGE_INITPRESOLVE
7476  * - \ref SCIP_STAGE_PRESOLVING
7477  * - \ref SCIP_STAGE_EXITPRESOLVE
7478  * - \ref SCIP_STAGE_PRESOLVED
7479  * - \ref SCIP_STAGE_SOLVING
7480  */
7482  SCIP*const scip, /**< SCIP data structure */
7483  SCIP_VAR**const vars, /**< binary variables in the clique from which at most one can be set to 1 */
7484  int const nvars, /**< number of variables in the clique */
7485  int*const cliquepartition, /**< array of length nvars to store the clique partition */
7486  int*const ncliques /**< pointer to store the number of cliques actually contained in the partition */
7487  )
7488 {
7489  SCIP_VAR** negvars;
7490  int v;
7491 
7492  assert(scip != NULL);
7493  assert(cliquepartition != NULL || nvars == 0);
7494  assert(ncliques != NULL);
7495 
7496  if( nvars == 0 )
7497  {
7498  *ncliques = 0;
7499  return SCIP_OKAY;
7500  }
7501  assert(vars != NULL);
7502 
7503  /* allocate temporary memory */
7504  SCIP_CALL( SCIPsetAllocBufferArray(scip->set, &negvars, nvars) );
7505 
7506  /* get all negated variables */
7507  for( v = nvars - 1; v >= 0; --v )
7508  {
7509  SCIP_CALL( SCIPgetNegatedVar(scip, vars[v], &(negvars[v])) );
7510  }
7511 
7512  /* calculate cliques on negated variables, which are "negated" cliques on normal variables array */
7513  SCIP_CALL( SCIPcalcCliquePartition( scip, negvars, nvars, cliquepartition, ncliques) );
7514 
7515  /* free temporary memory */
7516  SCIPsetFreeBufferArray(scip->set, &negvars);
7517 
7518  return SCIP_OKAY;
7519 }
7520 
7521 
7522 /** force SCIP to clean up all cliques; cliques do not get automatically cleaned up after presolving. Use
7523  * this method to prevent inactive variables in cliques when retrieved via SCIPgetCliques()
7524  *
7525  * @return SCIP_OKAY if everything worked, otherwise a suitable error code is passed
7526  *
7527  * @pre This method can be called if @p scip is in one of the following stages:
7528  * - \ref SCIP_STAGE_TRANSFORMED
7529  * - \ref SCIP_STAGE_INITPRESOLVE
7530  * - \ref SCIP_STAGE_PRESOLVING
7531  * - \ref SCIP_STAGE_EXITPRESOLVE
7532  * - \ref SCIP_STAGE_PRESOLVED
7533  * - \ref SCIP_STAGE_INITSOLVE
7534  * - \ref SCIP_STAGE_SOLVING
7535  * - \ref SCIP_STAGE_SOLVED
7536  * - \ref SCIP_STAGE_EXITSOLVE
7537  */
7539  SCIP* scip, /**< SCIP data structure */
7540  SCIP_Bool* infeasible /**< pointer to store if cleanup detected infeasibility */
7541  )
7542 {
7543  int nlocalbdchgs;
7544  SCIP_Bool globalinfeasibility;
7545 
7546  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPcleanupCliques", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7547 
7548  globalinfeasibility = FALSE;
7549  nlocalbdchgs = 0;
7550  SCIP_CALL( SCIPcliquetableCleanup(scip->cliquetable, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
7551  scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, &nlocalbdchgs,
7552  &globalinfeasibility) );
7553 
7554  if( infeasible != NULL )
7555  *infeasible = globalinfeasibility;
7556 
7557  if( globalinfeasibility )
7559 
7560  return SCIP_OKAY;
7561 }
7562 
7563 /** gets the number of cliques in the clique table
7564  *
7565  * @return number of cliques in the clique table
7566  *
7567  * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7568  * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
7569  *
7570  * @pre This method can be called if @p scip is in one of the following stages:
7571  * - \ref SCIP_STAGE_TRANSFORMED
7572  * - \ref SCIP_STAGE_INITPRESOLVE
7573  * - \ref SCIP_STAGE_PRESOLVING
7574  * - \ref SCIP_STAGE_EXITPRESOLVE
7575  * - \ref SCIP_STAGE_PRESOLVED
7576  * - \ref SCIP_STAGE_INITSOLVE
7577  * - \ref SCIP_STAGE_SOLVING
7578  * - \ref SCIP_STAGE_SOLVED
7579  * - \ref SCIP_STAGE_EXITSOLVE
7580  */
7582  SCIP* scip /**< SCIP data structure */
7583  )
7584 {
7585  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNCliques", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7586 
7588 }
7589 
7590 /** gets the number of cliques created so far by the cliquetable
7591  *
7592  * @return number of cliques created so far by the cliquetable
7593  *
7594  * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7595  * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
7596  *
7597  * @pre This method can be called if @p scip is in one of the following stages:
7598  * - \ref SCIP_STAGE_TRANSFORMED
7599  * - \ref SCIP_STAGE_INITPRESOLVE
7600  * - \ref SCIP_STAGE_PRESOLVING
7601  * - \ref SCIP_STAGE_EXITPRESOLVE
7602  * - \ref SCIP_STAGE_PRESOLVED
7603  * - \ref SCIP_STAGE_INITSOLVE
7604  * - \ref SCIP_STAGE_SOLVING
7605  * - \ref SCIP_STAGE_SOLVED
7606  * - \ref SCIP_STAGE_EXITSOLVE
7607  */
7609  SCIP* scip /**< SCIP data structure */
7610  )
7611 {
7612  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNCliquesCreated", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7613 
7615 }
7616 
7617 /** gets the array of cliques in the clique table
7618  *
7619  * @return array of cliques in the clique table
7620  *
7621  * @note cliques do not get automatically cleaned up after presolving. Use SCIPcleanupCliques()
7622  * to prevent inactive variables in cliques when retrieved via SCIPgetCliques(). This might reduce the number of cliques
7623  *
7624  * @pre This method can be called if @p scip is in one of the following stages:
7625  * - \ref SCIP_STAGE_TRANSFORMED
7626  * - \ref SCIP_STAGE_INITPRESOLVE
7627  * - \ref SCIP_STAGE_PRESOLVING
7628  * - \ref SCIP_STAGE_EXITPRESOLVE
7629  * - \ref SCIP_STAGE_PRESOLVED
7630  * - \ref SCIP_STAGE_INITSOLVE
7631  * - \ref SCIP_STAGE_SOLVING
7632  * - \ref SCIP_STAGE_SOLVED
7633  * - \ref SCIP_STAGE_EXITSOLVE
7634  */
7636  SCIP* scip /**< SCIP data structure */
7637  )
7638 {
7639  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetCliques", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7640 
7641  return SCIPcliquetableGetCliques(scip->cliquetable);
7642 }
7643 
7644 /** returns whether there is a clique that contains both given variable/value pairs;
7645  * the variables must be active binary variables;
7646  * if regardimplics is FALSE, only the cliques in the clique table are looked at;
7647  * if regardimplics is TRUE, both the cliques and the implications of the implication graph are regarded
7648  *
7649  * @return TRUE, if there is a clique that contains both variable/clique pairs; FALSE, otherwise
7650  *
7651  * @pre This method can be called if @p scip is in one of the following stages:
7652  * - \ref SCIP_STAGE_TRANSFORMED
7653  * - \ref SCIP_STAGE_INITPRESOLVE
7654  * - \ref SCIP_STAGE_PRESOLVING
7655  * - \ref SCIP_STAGE_EXITPRESOLVE
7656  * - \ref SCIP_STAGE_PRESOLVED
7657  * - \ref SCIP_STAGE_INITSOLVE
7658  * - \ref SCIP_STAGE_SOLVING
7659  * - \ref SCIP_STAGE_SOLVED
7660  * - \ref SCIP_STAGE_EXITSOLVE
7661  *
7662  * @note a variable with it's negated variable are NOT! in a clique
7663  * @note a variable with itself are in a clique
7664  */
7666  SCIP* scip, /**< SCIP data structure */
7667  SCIP_VAR* var1, /**< first variable */
7668  SCIP_Bool value1, /**< value of first variable */
7669  SCIP_VAR* var2, /**< second variable */
7670  SCIP_Bool value2, /**< value of second variable */
7671  SCIP_Bool regardimplics /**< should the implication graph also be searched for a clique? */
7672  )
7673 {
7674  assert(scip != NULL);
7675  assert(var1 != NULL);
7676  assert(var2 != NULL);
7677  assert(SCIPvarIsActive(var1));
7678  assert(SCIPvarIsActive(var2));
7679  assert(SCIPvarIsBinary(var1));
7680  assert(SCIPvarIsBinary(var2));
7681 
7682  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPhaveVarsCommonClique", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7683 
7684  /* if both variables together have more cliques then actual cliques exist, then they have a common clique (in debug
7685  * mode we check this for correctness), otherwise we need to call the pairwise comparison method for these variables
7686  */
7687 #ifndef NDEBUG
7688  assert((SCIPvarGetNCliques(var1, value1) + SCIPvarGetNCliques(var2, value2) > SCIPcliquetableGetNCliques(scip->cliquetable)) ? SCIPvarsHaveCommonClique(var1, value1, var2, value2, FALSE) : TRUE);
7689 #endif
7690 
7691  return (SCIPvarGetNCliques(var1, value1) + SCIPvarGetNCliques(var2, value2) > SCIPcliquetableGetNCliques(scip->cliquetable)
7692  || SCIPvarsHaveCommonClique(var1, value1, var2, value2, regardimplics));
7693 }
7694 
7695 /** writes the clique graph to a gml file
7696  *
7697  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7698  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7699  *
7700  * @pre This method can be called if @p scip is in one of the following stages:
7701  * - \ref SCIP_STAGE_TRANSFORMED
7702  * - \ref SCIP_STAGE_INITPRESOLVE
7703  * - \ref SCIP_STAGE_PRESOLVING
7704  * - \ref SCIP_STAGE_EXITPRESOLVE
7705  * - \ref SCIP_STAGE_PRESOLVED
7706  * - \ref SCIP_STAGE_INITSOLVE
7707  * - \ref SCIP_STAGE_SOLVING
7708  * - \ref SCIP_STAGE_SOLVED
7709  * - \ref SCIP_STAGE_EXITSOLVE
7710  *
7711  * @note there can be duplicated arcs in the output file
7712  *
7713  * If @p writenodeweights is true, only nodes corresponding to variables that have a fractional value and only edges
7714  * between such nodes are written.
7715  */
7717  SCIP* scip, /**< SCIP data structure */
7718  const char* fname, /**< name of file */
7719  SCIP_Bool writenodeweights /**< should we write weights of nodes? */
7720  )
7721 {
7722  FILE* gmlfile;
7723  SCIP_HASHMAP* nodehashmap;
7724  SCIP_CLIQUE** cliques;
7725  SCIP_VAR** clqvars;
7726  SCIP_VAR** allvars;
7727  SCIP_Bool* clqvalues;
7728  char nodename[SCIP_MAXSTRLEN];
7729  int nallvars;
7730  int nbinvars;
7731  int nintvars;
7732  int nimplvars;
7733  int ncliques;
7734  int c;
7735  int v1;
7736  int v2;
7737  int id1;
7738  int id2;
7739 
7740  assert(scip != NULL);
7741  assert(fname != NULL);
7742 
7743  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPwriteCliqueGraph", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7744 
7745  /* get all active variables */
7746  SCIP_CALL( SCIPgetVarsData(scip, &allvars, &nallvars, &nbinvars, &nintvars, &nimplvars, NULL) );
7747 
7748  /* no possible variables for cliques exist */
7749  if( nbinvars + nimplvars == 0 )
7750  return SCIP_OKAY;
7751 
7752  ncliques = SCIPgetNCliques(scip);
7753 
7754  /* no cliques and do not wont to check for binary implications */
7755  if( ncliques == 0 )
7756  return SCIP_OKAY;
7757 
7758  /* open gml file */
7759  gmlfile = fopen(fname, "w");
7760 
7761  if( gmlfile == NULL )
7762  {
7763  SCIPerrorMessage("cannot open graph file <%s>\n", fname);
7764  SCIPABORT();
7765  return SCIP_INVALIDDATA; /*lint !e527*/
7766  }
7767 
7768  /* create the hash map */
7769  SCIP_CALL_FINALLY( SCIPhashmapCreate(&nodehashmap, SCIPblkmem(scip), nbinvars+nimplvars), fclose(gmlfile) );
7770 
7771  /* write starting of gml file */
7772  SCIPgmlWriteOpening(gmlfile, TRUE);
7773 
7774  cliques = SCIPgetCliques(scip);
7775 
7776  /* write nodes and arcs for all cliques */
7777  for( c = ncliques - 1; c >= 0; --c )
7778  {
7779  clqvalues = SCIPcliqueGetValues(cliques[c]);
7780  clqvars = SCIPcliqueGetVars(cliques[c]);
7781 
7782  for( v1 = SCIPcliqueGetNVars(cliques[c]) - 1; v1 >= 0; --v1 )
7783  {
7784  id1 = clqvalues[v1] ? SCIPvarGetProbindex(clqvars[v1]) : (nallvars + SCIPvarGetProbindex(clqvars[v1]));
7785 
7786  /* if corresponding node was not added yet, add it */
7787  if( !SCIPhashmapExists(nodehashmap, (void*)(size_t)id1) )
7788  {
7789  assert(id1 >= 0);
7790  SCIP_CALL_FINALLY( SCIPhashmapInsertInt(nodehashmap, (void*)(size_t)id1, 1), fclose(gmlfile) ); /*lint !e571*/
7791 
7792  (void) SCIPsnprintf(nodename, SCIP_MAXSTRLEN, "%s%s", (id1 >= nallvars ? "~" : ""), SCIPvarGetName(clqvars[v1]));
7793 
7794  /* write new gml node for new variable */
7795  if ( writenodeweights )
7796  {
7797  if ( ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v1])) )
7798  SCIPgmlWriteNodeWeight(gmlfile, (unsigned int)id1, nodename, NULL, NULL, NULL, SCIPgetSolVal(scip, NULL, clqvars[v1]));
7799  }
7800  else
7801  {
7802  SCIPgmlWriteNode(gmlfile, (unsigned int)id1, nodename, NULL, NULL, NULL);
7803  }
7804  }
7805 
7806  for( v2 = SCIPcliqueGetNVars(cliques[c]) - 1; v2 >= 0; --v2 )
7807  {
7808  if( v1 == v2 )
7809  continue;
7810 
7811  id2 = clqvalues[v2] ? SCIPvarGetProbindex(clqvars[v2]) : (nallvars + SCIPvarGetProbindex(clqvars[v2]));
7812 
7813  /* if corresponding node was not added yet, add it */
7814  if( !SCIPhashmapExists(nodehashmap, (void*)(size_t)id2) )
7815  {
7816  assert(id2 >= 0);
7817  SCIP_CALL_FINALLY( SCIPhashmapInsertInt(nodehashmap, (void*)(size_t)id2, 1), fclose(gmlfile) ); /*lint !e571*/
7818 
7819  (void) SCIPsnprintf(nodename, SCIP_MAXSTRLEN, "%s%s", (id2 >= nallvars ? "~" : ""), SCIPvarGetName(clqvars[v2]));
7820 
7821  /* write new gml node for new variable */
7822  if ( writenodeweights )
7823  {
7824  if ( ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v2])) )
7825  SCIPgmlWriteNodeWeight(gmlfile, (unsigned int)id2, nodename, NULL, NULL, NULL, SCIPgetSolVal(scip, NULL, clqvars[v2]));
7826  }
7827  else
7828  {
7829  SCIPgmlWriteNode(gmlfile, (unsigned int)id2, nodename, NULL, NULL, NULL);
7830  }
7831  }
7832 
7833  /* write gml arc between resultant and operand */
7834  if ( ! writenodeweights || ! SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, clqvars[v2])) )
7835  SCIPgmlWriteArc(gmlfile, (unsigned int)id1, (unsigned int)id2, NULL, NULL);
7836  }
7837  }
7838  }
7839 
7840  /* free the hash map */
7841  SCIPhashmapFree(&nodehashmap);
7842 
7843  SCIPgmlWriteClosing(gmlfile);
7844  fclose(gmlfile);
7845 
7846  return SCIP_OKAY;
7847 }
7848 
7849 /** Removes (irrelevant) variable from all its global structures, i.e. cliques, implications and variable bounds.
7850  * This is an advanced method which should be used with care.
7851  *
7852  * @return SCIP_OKAY if everything worked, otherwise a suitable error code is passed
7853  *
7854  * @pre This method can be called if @p scip is in one of the following stages:
7855  * - \ref SCIP_STAGE_TRANSFORMED
7856  * - \ref SCIP_STAGE_INITPRESOLVE
7857  * - \ref SCIP_STAGE_PRESOLVING
7858  * - \ref SCIP_STAGE_EXITPRESOLVE
7859  * - \ref SCIP_STAGE_PRESOLVED
7860  * - \ref SCIP_STAGE_INITSOLVE
7861  * - \ref SCIP_STAGE_SOLVING
7862  * - \ref SCIP_STAGE_SOLVED
7863  * - \ref SCIP_STAGE_EXITSOLVE
7864  */
7866  SCIP* scip, /**< SCIP data structure */
7867  SCIP_VAR* var /**< variable to remove from global structures */
7868  )
7869 {
7870  assert(scip != NULL);
7871 
7872  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPremoveVarFromGlobalStructures", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
7873 
7874  /* mark the variable as deletable from global structures - This is necessary for the delayed clean up of cliques */
7876 
7877  /* remove variable from all its cliques, implications, and variable bounds */
7879 
7880  return SCIP_OKAY;
7881 }
7882 
7883 /** sets the branch factor of the variable; this value can be used in the branching methods to scale the score
7884  * values of the variables; higher factor leads to a higher probability that this variable is chosen for branching
7885  *
7886  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7887  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7888  *
7889  * @pre This method can be called if @p scip is in one of the following stages:
7890  * - \ref SCIP_STAGE_PROBLEM
7891  * - \ref SCIP_STAGE_TRANSFORMING
7892  * - \ref SCIP_STAGE_TRANSFORMED
7893  * - \ref SCIP_STAGE_INITPRESOLVE
7894  * - \ref SCIP_STAGE_PRESOLVING
7895  * - \ref SCIP_STAGE_EXITPRESOLVE
7896  * - \ref SCIP_STAGE_PRESOLVED
7897  * - \ref SCIP_STAGE_SOLVING
7898  */
7900  SCIP* scip, /**< SCIP data structure */
7901  SCIP_VAR* var, /**< problem variable */
7902  SCIP_Real branchfactor /**< factor to weigh variable's branching score with */
7903  )
7904 {
7905  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7906 
7907  SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, branchfactor) );
7908 
7909  return SCIP_OKAY;
7910 }
7911 
7912 /** scales the branch factor of the variable with the given value
7913  *
7914  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7915  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7916  *
7917  * @pre This method can be called if @p scip is in one of the following stages:
7918  * - \ref SCIP_STAGE_PROBLEM
7919  * - \ref SCIP_STAGE_TRANSFORMING
7920  * - \ref SCIP_STAGE_TRANSFORMED
7921  * - \ref SCIP_STAGE_INITPRESOLVE
7922  * - \ref SCIP_STAGE_PRESOLVING
7923  * - \ref SCIP_STAGE_EXITPRESOLVE
7924  * - \ref SCIP_STAGE_PRESOLVED
7925  * - \ref SCIP_STAGE_SOLVING
7926  */
7928  SCIP* scip, /**< SCIP data structure */
7929  SCIP_VAR* var, /**< problem variable */
7930  SCIP_Real scale /**< factor to scale variable's branching factor with */
7931  )
7932 {
7933  SCIP_CALL( SCIPcheckStage(scip, "SCIPscaleVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7934 
7935  SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, scale * SCIPvarGetBranchFactor(var)) );
7936 
7937  return SCIP_OKAY;
7938 }
7939 
7940 /** adds the given value to the branch factor of the variable
7941  *
7942  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7943  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7944  *
7945  * @pre This method can be called if @p scip is in one of the following stages:
7946  * - \ref SCIP_STAGE_PROBLEM
7947  * - \ref SCIP_STAGE_TRANSFORMING
7948  * - \ref SCIP_STAGE_TRANSFORMED
7949  * - \ref SCIP_STAGE_INITPRESOLVE
7950  * - \ref SCIP_STAGE_PRESOLVING
7951  * - \ref SCIP_STAGE_EXITPRESOLVE
7952  * - \ref SCIP_STAGE_PRESOLVED
7953  * - \ref SCIP_STAGE_SOLVING
7954  */
7956  SCIP* scip, /**< SCIP data structure */
7957  SCIP_VAR* var, /**< problem variable */
7958  SCIP_Real addfactor /**< value to add to the branch factor of the variable */
7959  )
7960 {
7961  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarBranchFactor", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7962 
7963  SCIP_CALL( SCIPvarChgBranchFactor(var, scip->set, addfactor + SCIPvarGetBranchFactor(var)) );
7964 
7965  return SCIP_OKAY;
7966 }
7967 
7968 /** sets the branch priority of the variable; variables with higher branch priority are always preferred to variables
7969  * with lower priority in selection of branching variable
7970  *
7971  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
7972  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
7973  *
7974  * @pre This method can be called if @p scip is in one of the following stages:
7975  * - \ref SCIP_STAGE_PROBLEM
7976  * - \ref SCIP_STAGE_TRANSFORMING
7977  * - \ref SCIP_STAGE_TRANSFORMED
7978  * - \ref SCIP_STAGE_INITPRESOLVE
7979  * - \ref SCIP_STAGE_PRESOLVING
7980  * - \ref SCIP_STAGE_EXITPRESOLVE
7981  * - \ref SCIP_STAGE_PRESOLVED
7982  * - \ref SCIP_STAGE_SOLVING
7983  *
7984  * @note the default branching priority is 0
7985  */
7987  SCIP* scip, /**< SCIP data structure */
7988  SCIP_VAR* var, /**< problem variable */
7989  int branchpriority /**< branch priority of the variable */
7990  )
7991 {
7992  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
7993 
7994  assert( var->scip == scip );
7995 
7996  if( SCIPisTransformed(scip) )
7997  {
7998  assert(scip->branchcand != NULL);
7999 
8000  /* inform the pseudo branch candidates that the branch priority changes and change the branch priority */
8001  SCIP_CALL( SCIPbranchcandUpdateVarBranchPriority(scip->branchcand, scip->set, var, branchpriority) );
8002  }
8003  else
8004  {
8005  /* change the branching priority of the variable */
8006  SCIP_CALL( SCIPvarChgBranchPriority(var, branchpriority) );
8007  }
8008 
8009  return SCIP_OKAY;
8010 }
8011 
8012 /** changes the branch priority of the variable to the given value, if it is larger than the current priority
8013  *
8014  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8015  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8016  *
8017  * @pre This method can be called if @p scip is in one of the following stages:
8018  * - \ref SCIP_STAGE_PROBLEM
8019  * - \ref SCIP_STAGE_TRANSFORMING
8020  * - \ref SCIP_STAGE_TRANSFORMED
8021  * - \ref SCIP_STAGE_INITPRESOLVE
8022  * - \ref SCIP_STAGE_PRESOLVING
8023  * - \ref SCIP_STAGE_EXITPRESOLVE
8024  * - \ref SCIP_STAGE_PRESOLVED
8025  * - \ref SCIP_STAGE_SOLVING
8026  */
8028  SCIP* scip, /**< SCIP data structure */
8029  SCIP_VAR* var, /**< problem variable */
8030  int branchpriority /**< new branch priority of the variable, if it is larger than current priority */
8031  )
8032 {
8033  SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8034 
8035  assert( var->scip == scip );
8036 
8037  if( branchpriority > SCIPvarGetBranchPriority(var) )
8038  {
8039  SCIP_CALL( SCIPvarChgBranchPriority(var, branchpriority) );
8040  }
8041 
8042  return SCIP_OKAY;
8043 }
8044 
8045 /** adds the given value to the branch priority of the variable
8046  *
8047  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8048  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8049  *
8050  * @pre This method can be called if @p scip is in one of the following stages:
8051  * - \ref SCIP_STAGE_PROBLEM
8052  * - \ref SCIP_STAGE_TRANSFORMING
8053  * - \ref SCIP_STAGE_TRANSFORMED
8054  * - \ref SCIP_STAGE_INITPRESOLVE
8055  * - \ref SCIP_STAGE_PRESOLVING
8056  * - \ref SCIP_STAGE_EXITPRESOLVE
8057  * - \ref SCIP_STAGE_PRESOLVED
8058  * - \ref SCIP_STAGE_SOLVING
8059  */
8061  SCIP* scip, /**< SCIP data structure */
8062  SCIP_VAR* var, /**< problem variable */
8063  int addpriority /**< value to add to the branch priority of the variable */
8064  )
8065 {
8066  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVarBranchPriority", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8067 
8068  assert( var->scip == scip );
8069 
8070  SCIP_CALL( SCIPvarChgBranchPriority(var, addpriority + SCIPvarGetBranchPriority(var)) );
8071 
8072  return SCIP_OKAY;
8073 }
8074 
8075 /** sets the branch direction of the variable (-1: prefer downwards branch, 0: automatic selection, +1: prefer upwards
8076  * branch)
8077  *
8078  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8079  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8080  *
8081  * @pre This method can be called if @p scip is in one of the following stages:
8082  * - \ref SCIP_STAGE_PROBLEM
8083  * - \ref SCIP_STAGE_TRANSFORMING
8084  * - \ref SCIP_STAGE_TRANSFORMED
8085  * - \ref SCIP_STAGE_INITPRESOLVE
8086  * - \ref SCIP_STAGE_PRESOLVING
8087  * - \ref SCIP_STAGE_EXITPRESOLVE
8088  * - \ref SCIP_STAGE_PRESOLVED
8089  * - \ref SCIP_STAGE_SOLVING
8090  */
8092  SCIP* scip, /**< SCIP data structure */
8093  SCIP_VAR* var, /**< problem variable */
8094  SCIP_BRANCHDIR branchdirection /**< preferred branch direction of the variable (downwards, upwards, auto) */
8095  )
8096 {
8097  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBranchDirection", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8098 
8099  assert( var->scip == scip );
8100 
8101  SCIP_CALL( SCIPvarChgBranchDirection(var, branchdirection) );
8102 
8103  return SCIP_OKAY;
8104 }
8105 
8106 /** tightens the variable bounds due to a new variable type */
8107 static
8109  SCIP* scip, /**< SCIP data structure */
8110  SCIP_VAR* var, /**< variable to change the bound for */
8111  SCIP_VARTYPE vartype, /**< new type of variable */
8112  SCIP_Bool* infeasible /**< pointer to store whether an infeasibility was detected (, due to
8113  * integrality condition of the new variable type) */
8114  )
8115 {
8116  assert(scip != NULL);
8118  assert(scip->set->stage == SCIP_STAGE_PROBLEM || SCIPvarIsTransformed(var));
8119  assert(var->scip == scip);
8120 
8121  *infeasible = FALSE;
8122 
8123  /* adjusts bounds if the variable type changed form continuous to non-continuous (integral) */
8125  {
8126  SCIP_Bool tightened;
8127 
8128  /* we adjust variable bounds to integers first, since otherwise a later bound tightening with a fractional old
8129  * bound may give an assert because SCIP expects non-continuous variables to have non-fractional bounds
8130  *
8131  * we adjust bounds with a fractionality within [eps,feastol] only if the resulting bound change is a bound
8132  * tightening, because relaxing bounds may not be allowed
8133  */
8134  if( !SCIPisFeasIntegral(scip, SCIPvarGetLbGlobal(var)) ||
8136  (!SCIPsetIsEQ(scip->set, SCIPvarGetLbGlobal(var), SCIPfeasCeil(scip, SCIPvarGetLbGlobal(var))) &&
8138  )
8139  {
8140  SCIP_CALL( SCIPtightenVarLbGlobal(scip, var, SCIPfeasCeil(scip, SCIPvarGetLbGlobal(var)), TRUE, infeasible, &tightened) );
8141  if( *infeasible )
8142  return SCIP_OKAY;
8143 
8144  /* 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
8145  * 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
8146  */
8147  assert(tightened || SCIPisFeasLE(scip, SCIPvarGetUbGlobal(var), SCIPfeasCeil(scip, SCIPvarGetLbGlobal(var))));
8148  }
8149  if( !SCIPisFeasIntegral(scip, SCIPvarGetUbGlobal(var)) ||
8151  )
8152  {
8153  SCIP_CALL( SCIPtightenVarUbGlobal(scip, var, SCIPfeasFloor(scip, SCIPvarGetUbGlobal(var)), TRUE, infeasible, &tightened) );
8154  if( *infeasible )
8155  return SCIP_OKAY;
8156 
8157  assert(tightened || SCIPisFeasGE(scip, SCIPvarGetLbGlobal(var), SCIPfeasFloor(scip, SCIPvarGetUbGlobal(var))));
8158  }
8159  }
8160 
8161  return SCIP_OKAY;
8162 }
8163 
8164 /** changes type of variable in the problem;
8165  *
8166  * @warning This type change might change the variable array returned from SCIPgetVars() and SCIPgetVarsData();
8167  *
8168  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8169  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8170  *
8171  * @pre This method can be called if @p scip is in one of the following stages:
8172  * - \ref SCIP_STAGE_PROBLEM
8173  * - \ref SCIP_STAGE_TRANSFORMING
8174  * - \ref SCIP_STAGE_PRESOLVING
8175  *
8176  * @note If SCIP is already beyond the SCIP_STAGE_PROBLEM and a original variable is passed, the variable type of the
8177  * corresponding transformed variable is changed; the type of the original variable does not change
8178  *
8179  * @note If the type changes from a continuous variable to a non-continuous variable the bounds of the variable get
8180  * adjusted w.r.t. to integrality information
8181  */
8183  SCIP* scip, /**< SCIP data structure */
8184  SCIP_VAR* var, /**< variable to change the bound for */
8185  SCIP_VARTYPE vartype, /**< new type of variable */
8186  SCIP_Bool* infeasible /**< pointer to store whether an infeasibility was detected (, due to
8187  * integrality condition of the new variable type) */
8188  )
8189 {
8190  SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarType", FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
8191 
8192  assert(var != NULL);
8193  assert(var->scip == scip);
8194 
8195  if( SCIPvarIsNegated(var) )
8196  {
8197  SCIPdebugMsg(scip, "upgrading type of negated variable <%s> from %d to %d\n", SCIPvarGetName(var), SCIPvarGetType(var), vartype);
8198  var = SCIPvarGetNegationVar(var);
8199  }
8200 #ifndef NDEBUG
8201  else
8202  {
8203  if( SCIPgetStage(scip) > SCIP_STAGE_PROBLEM )
8204  {
8205  SCIPdebugMsg(scip, "upgrading type of variable <%s> from %d to %d\n", SCIPvarGetName(var), SCIPvarGetType(var), vartype);
8206  }
8207  }
8208 #endif
8209 
8210  /* change variable type */
8211  switch( scip->set->stage )
8212  {
8213  case SCIP_STAGE_PROBLEM:
8214  assert(!SCIPvarIsTransformed(var));
8215 
8216  /* first adjust the variable due to new integrality information */
8217  SCIP_CALL( tightenBounds(scip, var, vartype, infeasible) );
8218 
8219  /* second change variable type */
8220  if( SCIPvarGetProbindex(var) >= 0 )
8221  {
8222  SCIP_CALL( SCIPprobChgVarType(scip->origprob, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8223  scip->branchcand, scip->eventqueue, scip->cliquetable, var, vartype) );
8224  }
8225  else
8226  {
8227  SCIP_CALL( SCIPvarChgType(var, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8228  scip->eventqueue, vartype) );
8229  }
8230  break;
8231 
8232  case SCIP_STAGE_PRESOLVING:
8233  if( !SCIPvarIsTransformed(var) )
8234  {
8235  SCIP_VAR* transvar;
8236 
8237  SCIP_CALL( SCIPgetTransformedVar(scip, var, &transvar) );
8238  assert(transvar != NULL);
8239 
8240  /* recall method with transformed variable */
8241  SCIP_CALL( SCIPchgVarType(scip, transvar, vartype, infeasible) );
8242  return SCIP_OKAY;
8243  }
8244 
8245  /* first adjust the variable due to new integrality information */
8246  SCIP_CALL( tightenBounds(scip, var, vartype, infeasible) );
8247 
8248  /* second change variable type */
8249  if( SCIPvarGetProbindex(var) >= 0 )
8250  {
8251  SCIP_CALL( SCIPprobChgVarType(scip->transprob, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8252  scip->branchcand, scip->eventqueue, scip->cliquetable, var, vartype) );
8253  }
8254  else
8255  {
8256  SCIP_CALL( SCIPvarChgType(var, scip->mem->probmem, scip->set, scip->primal, scip->lp,
8257  scip->eventqueue, vartype) );
8258  }
8259  break;
8260 
8261  default:
8262  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
8263  return SCIP_INVALIDCALL;
8264  } /*lint !e788*/
8265 
8266  return SCIP_OKAY;
8267 }
8268 
8269 /** in problem creation and solving stage, both bounds of the variable are set to the given value;
8270  * in presolving stage, the variable is converted into a fixed variable, and bounds are changed respectively;
8271  * conversion into a fixed variable changes the vars array returned from SCIPgetVars() and SCIPgetVarsData(),
8272  * and also renders arrays returned from the SCIPvarGetImpl...() methods invalid
8273  *
8274  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8275  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8276  *
8277  * @pre This method can be called if @p scip is in one of the following stages:
8278  * - \ref SCIP_STAGE_PROBLEM
8279  * - \ref SCIP_STAGE_PRESOLVING
8280  * - \ref SCIP_STAGE_SOLVING
8281  */
8283  SCIP* scip, /**< SCIP data structure */
8284  SCIP_VAR* var, /**< variable to fix */
8285  SCIP_Real fixedval, /**< value to fix variable to */
8286  SCIP_Bool* infeasible, /**< pointer to store whether the fixing is infeasible */
8287  SCIP_Bool* fixed /**< pointer to store whether the fixing was performed (variable was unfixed) */
8288  )
8289 {
8290  assert(var != NULL);
8291  assert(infeasible != NULL);
8292  assert(fixed != NULL);
8293 
8294  SCIP_CALL( SCIPcheckStage(scip, "SCIPfixVar", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
8295 
8296  *infeasible = FALSE;
8297  *fixed = FALSE;
8298 
8299  /* in the problem creation stage, modify the bounds as requested, independently from the current bounds */
8300  if( scip->set->stage != SCIP_STAGE_PROBLEM )
8301  {
8302  if( (SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPsetIsFeasIntegral(scip->set, fixedval))
8303  || SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetLbLocal(var))
8304  || SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8305  {
8306  *infeasible = TRUE;
8307  return SCIP_OKAY;
8308  }
8309  else if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED )
8310  {
8311  *infeasible = !SCIPsetIsFeasEQ(scip->set, fixedval, SCIPvarGetLbLocal(var));
8312  return SCIP_OKAY;
8313  }
8314  }
8315  else
8316  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_ORIGINAL);
8317 
8318  switch( scip->set->stage )
8319  {
8320  case SCIP_STAGE_PROBLEM:
8321  /* in the problem creation stage, modify the bounds as requested, independently from the current bounds;
8322  * we have to make sure, that the order of the bound changes does not intermediately produce an invalid
8323  * interval lb > ub
8324  */
8325  if( fixedval <= SCIPvarGetLbLocal(var) )
8326  {
8327  SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
8328  SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
8329  *fixed = TRUE;
8330  }
8331  else
8332  {
8333  SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
8334  SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
8335  *fixed = TRUE;
8336  }
8337  return SCIP_OKAY;
8338 
8339  case SCIP_STAGE_PRESOLVING:
8340  if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
8341  {
8342  SCIP_CALL( SCIPvarFix(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8343  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8344  scip->cliquetable, fixedval, infeasible, fixed) );
8345  return SCIP_OKAY;
8346  }
8347  /*lint -fallthrough*/
8348  case SCIP_STAGE_SOLVING:
8349  if( SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetLbLocal(var)) )
8350  {
8351  if( SCIPsetIsFeasGT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8352  {
8353  *infeasible = TRUE;
8354  return SCIP_OKAY;
8355  }
8356  else
8357  {
8358  SCIP_CALL( SCIPchgVarLb(scip, var, fixedval) );
8359  *fixed = TRUE;
8360  }
8361  }
8362  if( SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetUbLocal(var)) )
8363  {
8364  if( SCIPsetIsFeasLT(scip->set, fixedval, SCIPvarGetLbLocal(var)) )
8365  {
8366  *infeasible = TRUE;
8367  return SCIP_OKAY;
8368  }
8369  else
8370  {
8371  SCIP_CALL( SCIPchgVarUb(scip, var, fixedval) );
8372  *fixed = TRUE;
8373  }
8374  }
8375  return SCIP_OKAY;
8376 
8377  default:
8378  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
8379  return SCIP_INVALIDCALL;
8380  } /*lint !e788*/
8381 }
8382 
8383 /** From a given equality a*x + b*y == c, aggregates one of the variables and removes it from the set of
8384  * active problem variables. This changes the vars array returned from SCIPgetVars() and SCIPgetVarsData(),
8385  * and also renders the arrays returned from the SCIPvarGetImpl...() methods for the two variables invalid.
8386  * In the first step, the equality is transformed into an equality with active problem variables
8387  * a'*x' + b'*y' == c'. If x' == y', this leads to the detection of redundancy if a' == -b' and c' == 0,
8388  * of infeasibility, if a' == -b' and c' != 0, or to a variable fixing x' == c'/(a'+b') (and possible
8389  * infeasibility) otherwise.
8390  * In the second step, the variable to be aggregated is chosen among x' and y', prefering a less strict variable
8391  * type as aggregation variable (i.e. continuous variables are preferred over implicit integers, implicit integers
8392  * over integers, and integers over binaries). If none of the variables is continuous, it is tried to find an integer
8393  * aggregation (i.e. integral coefficients a'' and b'', such that a''*x' + b''*y' == c''). This can lead to
8394  * the detection of infeasibility (e.g. if c'' is fractional), or to a rejection of the aggregation (denoted by
8395  * aggregated == FALSE), if the resulting integer coefficients are too large and thus numerically instable.
8396  *
8397  * The output flags have the following meaning:
8398  * - infeasible: the problem is infeasible
8399  * - redundant: the equality can be deleted from the constraint set
8400  * - aggregated: the aggregation was successfully performed (the variables were not aggregated before)
8401  *
8402  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8403  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8404  *
8405  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PRESOLVING
8406  */
8408  SCIP* scip, /**< SCIP data structure */
8409  SCIP_VAR* varx, /**< variable x in equality a*x + b*y == c */
8410  SCIP_VAR* vary, /**< variable y in equality a*x + b*y == c */
8411  SCIP_Real scalarx, /**< multiplier a in equality a*x + b*y == c */
8412  SCIP_Real scalary, /**< multiplier b in equality a*x + b*y == c */
8413  SCIP_Real rhs, /**< right hand side c in equality a*x + b*y == c */
8414  SCIP_Bool* infeasible, /**< pointer to store whether the aggregation is infeasible */
8415  SCIP_Bool* redundant, /**< pointer to store whether the equality is (now) redundant */
8416  SCIP_Bool* aggregated /**< pointer to store whether the aggregation was successful */
8417  )
8418 {
8419  SCIP_Real constantx;
8420  SCIP_Real constanty;
8421 
8422  assert(infeasible != NULL);
8423  assert(redundant != NULL);
8424  assert(aggregated != NULL);
8425 
8426  SCIP_CALL( SCIPcheckStage(scip, "SCIPaggregateVars", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
8427 
8428  *infeasible = FALSE;
8429  *redundant = FALSE;
8430  *aggregated = FALSE;
8431 
8432  if( SCIPtreeProbing(scip->tree) )
8433  {
8434  SCIPerrorMessage("cannot aggregate variables during probing\n");
8435  return SCIP_INVALIDCALL;
8436  }
8437  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
8438 
8439  /* do not perform aggregation if it is globally deactivated */
8440  if( scip->set->presol_donotaggr )
8441  return SCIP_OKAY;
8442 
8443  /* get the corresponding equality in active problem variable space:
8444  * transform both expressions "a*x + 0" and "b*y + 0" into problem variable space
8445  */
8446  constantx = 0.0;
8447  constanty = 0.0;
8448  SCIP_CALL( SCIPvarGetProbvarSum(&varx, scip->set, &scalarx, &constantx) );
8449  SCIP_CALL( SCIPvarGetProbvarSum(&vary, scip->set, &scalary, &constanty) );
8450 
8451  /* we cannot aggregate multi-aggregated variables */
8453  return SCIP_OKAY;
8454 
8455  /* move the constant to the right hand side to acquire the form "a'*x' + b'*y' == c'" */
8456  rhs -= (constantx + constanty);
8457 
8458  /* if a scalar is zero, treat the variable as fixed-to-zero variable */
8459  if( SCIPsetIsZero(scip->set, scalarx) )
8460  varx = NULL;
8461  if( SCIPsetIsZero(scip->set, scalary) )
8462  vary = NULL;
8463 
8464  /* capture the special cases that less than two variables are left, due to resolutions to a fixed variable or
8465  * to the same active variable
8466  */
8467  if( varx == NULL && vary == NULL )
8468  {
8469  /* both variables were resolved to fixed variables */
8470  *infeasible = !SCIPsetIsZero(scip->set, rhs);
8471  *redundant = TRUE;
8472  }
8473  else if( varx == NULL )
8474  {
8475  assert(SCIPsetIsZero(scip->set, scalarx));
8476  assert(!SCIPsetIsZero(scip->set, scalary));
8477 
8478  /* variable x was resolved to fixed variable: variable y can be fixed to c'/b' */
8479  SCIP_CALL( SCIPvarFix(vary, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8480  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8481  scip->cliquetable, rhs/scalary, infeasible, aggregated) );
8482  *redundant = TRUE;
8483  }
8484  else if( vary == NULL )
8485  {
8486  assert(SCIPsetIsZero(scip->set, scalary));
8487  assert(!SCIPsetIsZero(scip->set, scalarx));
8488 
8489  /* variable y was resolved to fixed variable: variable x can be fixed to c'/a' */
8490  SCIP_CALL( SCIPvarFix(varx, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8491  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8492  scip->cliquetable, rhs/scalarx, infeasible, aggregated) );
8493  *redundant = TRUE;
8494  }
8495  else if( varx == vary )
8496  {
8497  /* both variables were resolved to the same active problem variable: this variable can be fixed */
8498  scalarx += scalary;
8499  if( SCIPsetIsZero(scip->set, scalarx) )
8500  {
8501  /* left hand side of equality is zero: equality is potentially infeasible */
8502  *infeasible = !SCIPsetIsZero(scip->set, rhs);
8503  }
8504  else
8505  {
8506  /* sum of scalars is not zero: fix variable x' == y' to c'/(a'+b') */
8507  SCIP_CALL( SCIPvarFix(varx, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8508  scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue,
8509  scip->cliquetable, rhs/scalarx, infeasible, aggregated) );
8510  }
8511  *redundant = TRUE;
8512  }
8513  else
8514  {
8515  /* both variables are different active problem variables, and both scalars are non-zero: try to aggregate them */
8516  SCIP_CALL( SCIPvarTryAggregateVars(scip->set, scip->mem->probmem, scip->stat, scip->transprob, scip->origprob,
8517  scip->primal, scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventfilter,
8518  scip->eventqueue, varx, vary, scalarx, scalary, rhs, infeasible, aggregated) );
8519  *redundant = *aggregated;
8520  }
8521 
8522  return SCIP_OKAY;
8523 }
8524 
8525 /** converts variable into multi-aggregated variable; this changes the variable array returned from
8526  * SCIPgetVars() and SCIPgetVarsData();
8527  *
8528  * @warning The integrality condition is not checked anymore on the multi-aggregated variable. You must not
8529  * multi-aggregate an integer variable without being sure, that integrality on the aggregation variables
8530  * implies integrality on the aggregated variable.
8531  *
8532  * The output flags have the following meaning:
8533  * - infeasible: the problem is infeasible
8534  * - aggregated: the aggregation was successfully performed (the variables were not aggregated before)
8535  *
8536  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8537  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8538  *
8539  * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_PRESOLVING
8540  */
8542  SCIP* scip, /**< SCIP data structure */
8543  SCIP_VAR* var, /**< variable x to aggregate */
8544  int naggvars, /**< number n of variables in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8545  SCIP_VAR** aggvars, /**< variables y_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8546  SCIP_Real* scalars, /**< multipliers a_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8547  SCIP_Real constant, /**< constant shift c in aggregation x = a_1*y_1 + ... + a_n*y_n + c */
8548  SCIP_Bool* infeasible, /**< pointer to store whether the aggregation is infeasible */
8549  SCIP_Bool* aggregated /**< pointer to store whether the aggregation was successful */
8550  )
8551 {
8552  SCIP_CALL( SCIPcheckStage(scip, "SCIPmultiaggregateVar", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
8553 
8554  assert(var->scip == scip);
8555 
8556  if( SCIPtreeProbing(scip->tree) )
8557  {
8558  SCIPerrorMessage("cannot multi-aggregate variables during probing\n");
8559  return SCIP_INVALIDCALL;
8560  }
8561  assert(SCIPtreeGetCurrentDepth(scip->tree) == 0);
8562 
8563  SCIP_CALL( SCIPvarMultiaggregate(var, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
8564  scip->primal, scip->tree, scip->reopt, scip->lp, scip->cliquetable, scip->branchcand, scip->eventfilter,
8565  scip->eventqueue, naggvars, aggvars, scalars, constant, infeasible, aggregated) );
8566 
8567  return SCIP_OKAY;
8568 }
8569 
8570 /** returns whether aggregation of variables is not allowed */
8572  SCIP* scip /**< SCIP data structure */
8573  )
8574 {
8575  assert(scip != NULL);
8576 
8577  return scip->set->presol_donotaggr;
8578 }
8579 
8580 /** returns whether multi-aggregation is disabled */
8582  SCIP* scip /**< SCIP data structure */
8583  )
8584 {
8585  assert(scip != NULL);
8586 
8587  return scip->set->presol_donotmultaggr;
8588 }
8589 
8590 /** returns whether variable is not allowed to be aggregated */
8592  SCIP* scip, /**< SCIP data structure */
8593  SCIP_VAR* var /**< variable x to aggregate */
8594  )
8595 {
8596  assert(scip != NULL);
8597  assert(var != NULL);
8598  assert(var->scip == scip);
8599 
8600  return scip->set->presol_donotaggr || SCIPvarDoNotAggr(var);
8601 }
8602 
8603 /** returns whether variable is not allowed to be multi-aggregated */
8605  SCIP* scip, /**< SCIP data structure */
8606  SCIP_VAR* var /**< variable x to aggregate */
8607  )
8608 {
8609  assert(scip != NULL);
8610  assert(var != NULL);
8611  assert(var->scip == scip);
8612 
8613  return scip->set->presol_donotmultaggr || SCIPvarDoNotMultaggr(var);
8614 }
8615 
8616 /** returns whether dual reductions are allowed during propagation and presolving
8617  *
8618  * @deprecated Please use SCIPallowStrongDualReds()
8619  */
8621  SCIP* scip /**< SCIP data structure */
8622  )
8623 {
8624  assert(scip != NULL);
8625 
8626  return !scip->set->reopt_enable && scip->set->misc_allowstrongdualreds;
8627 }
8628 
8629 /** returns whether strong dual reductions are allowed during propagation and presolving
8630  *
8631  * @note A reduction is called strong dual, if it may discard feasible/optimal solutions, but leaves at least one
8632  * optimal solution intact. Often such reductions are based on analyzing the objective function and variable
8633  * locks.
8634  */
8636  SCIP* scip /**< SCIP data structure */
8637  )
8638 {
8639  assert(scip != NULL);
8640 
8641  return !scip->set->reopt_enable && scip->set->misc_allowstrongdualreds;
8642 }
8643 
8644 /** returns whether propagation w.r.t. current objective is allowed
8645  *
8646  * @deprecated Please use SCIPallowWeakDualReds()
8647  */
8649  SCIP* scip /**< SCIP data structure */
8650  )
8651 {
8652  assert(scip != NULL);
8653 
8654  return !scip->set->reopt_enable && scip->set->misc_allowweakdualreds;
8655 }
8656 
8657 /** returns whether weak dual reductions are allowed during propagation and presolving
8658  *
8659  * @note A reduction is called weak dual, if it may discard feasible solutions, but leaves at all optimal solutions
8660  * intact. Often such reductions are based on analyzing the objective function, reduced costs, and/or dual LPs.
8661  */
8663  SCIP* scip /**< SCIP data structure */
8664  )
8665 {
8666  assert(scip != NULL);
8667 
8668  return !scip->set->reopt_enable && scip->set->misc_allowweakdualreds;
8669 }
8670 
8671 /** marks the variable that it must not be aggregated
8672  *
8673  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8674  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8675  *
8676  * @pre This method can be called if @p scip is in one of the following stages:
8677  * - \ref SCIP_STAGE_INIT
8678  * - \ref SCIP_STAGE_PROBLEM
8679  * - \ref SCIP_STAGE_TRANSFORMING
8680  * - \ref SCIP_STAGE_TRANSFORMED
8681  * - \ref SCIP_STAGE_INITPRESOLVE
8682  * - \ref SCIP_STAGE_PRESOLVING
8683  * - \ref SCIP_STAGE_EXITPRESOLVE
8684  *
8685  * @note There exists no "unmark" method since it has to be ensured that if a plugin requires that a variable is not
8686  * aggregated that this is will be the case.
8687  */
8689  SCIP* scip, /**< SCIP data structure */
8690  SCIP_VAR* var /**< variable to delete */
8691  )
8692 {
8693  assert(scip != NULL);
8694  assert(var != NULL);
8695  assert(var->scip == scip);
8696 
8697  SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkDoNotAggrVar", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE) );
8698 
8700 
8701  return SCIP_OKAY;
8702 }
8703 
8704 /** marks the variable that it must not be multi-aggregated
8705  *
8706  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8707  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8708  *
8709  * @pre This method can be called if @p scip is in one of the following stages:
8710  * - \ref SCIP_STAGE_INIT
8711  * - \ref SCIP_STAGE_PROBLEM
8712  * - \ref SCIP_STAGE_TRANSFORMING
8713  * - \ref SCIP_STAGE_TRANSFORMED
8714  * - \ref SCIP_STAGE_INITPRESOLVE
8715  * - \ref SCIP_STAGE_PRESOLVING
8716  * - \ref SCIP_STAGE_EXITPRESOLVE
8717  *
8718  * @note There exists no "unmark" method since it has to be ensured that if a plugin requires that a variable is not
8719  * multi-aggregated that this is will be the case.
8720  */
8722  SCIP* scip, /**< SCIP data structure */
8723  SCIP_VAR* var /**< variable to delete */
8724  )
8725 {
8726  assert(scip != NULL);
8727  assert(var != NULL);
8728  assert(var->scip == scip);
8729 
8730  SCIP_CALL( SCIPcheckStage(scip, "SCIPmarkDoNotMultaggrVar", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE) );
8731 
8733 
8734  return SCIP_OKAY;
8735 }
8736 
8737 /** enables the collection of statistics for a variable
8738  *
8739  * @pre This method can be called if @p scip is in one of the following stages:
8740  * - \ref SCIP_STAGE_PROBLEM
8741  * - \ref SCIP_STAGE_INITPRESOLVE
8742  * - \ref SCIP_STAGE_PRESOLVING
8743  * - \ref SCIP_STAGE_EXITPRESOLVE
8744  * - \ref SCIP_STAGE_SOLVING
8745  * - \ref SCIP_STAGE_SOLVED
8746  */
8748  SCIP* scip /**< SCIP data structure */
8749  )
8750 {
8751  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPenableVarHistory", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8752 
8754 }
8755 
8756 /** disables the collection of any statistic for a variable
8757  *
8758  * @pre This method can be called if @p scip is in one of the following stages:
8759  * - \ref SCIP_STAGE_PROBLEM
8760  * - \ref SCIP_STAGE_INITPRESOLVE
8761  * - \ref SCIP_STAGE_PRESOLVING
8762  * - \ref SCIP_STAGE_EXITPRESOLVE
8763  * - \ref SCIP_STAGE_SOLVING
8764  * - \ref SCIP_STAGE_SOLVED
8765  */
8767  SCIP* scip /**< SCIP data structure */
8768  )
8769 {
8770  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPdisableVarHistory", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8771 
8773 }
8774 
8775 /** updates the pseudo costs of the given variable and the global pseudo costs after a change of "solvaldelta" in the
8776  * variable's solution value and resulting change of "objdelta" in the in the LP's objective value;
8777  * the update is ignored, if the objective value difference is infinite
8778  *
8779  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
8780  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
8781  *
8782  * @pre This method can be called if @p scip is in one of the following stages:
8783  * - \ref SCIP_STAGE_SOLVING
8784  * - \ref SCIP_STAGE_SOLVED
8785  */
8787  SCIP* scip, /**< SCIP data structure */
8788  SCIP_VAR* var, /**< problem variable */
8789  SCIP_Real solvaldelta, /**< difference of variable's new LP value - old LP value */
8790  SCIP_Real objdelta, /**< difference of new LP's objective value - old LP's objective value */
8791  SCIP_Real weight /**< weight in (0,1] of this update in pseudo cost sum */
8792  )
8793 {
8794  SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateVarPseudocost", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8795 
8796  if( !SCIPsetIsInfinity(scip->set, 2*objdelta) ) /* differences infinity - eps should also be treated as infinity */
8797  {
8798  if( scip->set->branch_divingpscost || (!scip->lp->diving && !SCIPtreeProbing(scip->tree)) )
8799  {
8800  SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, solvaldelta, objdelta, weight) );
8801  }
8802  }
8803 
8804  return SCIP_OKAY;
8805 }
8806 
8807 /** gets the variable's pseudo cost value for the given change of the variable's LP value
8808  *
8809  * @return the variable's pseudo cost value for the given change of the variable's LP value
8810  *
8811  * @pre This method can be called if @p scip is in one of the following stages:
8812  * - \ref SCIP_STAGE_INITPRESOLVE
8813  * - \ref SCIP_STAGE_PRESOLVING
8814  * - \ref SCIP_STAGE_EXITPRESOLVE
8815  * - \ref SCIP_STAGE_PRESOLVED
8816  * - \ref SCIP_STAGE_INITSOLVE
8817  * - \ref SCIP_STAGE_SOLVING
8818  * - \ref SCIP_STAGE_SOLVED
8819  */
8821  SCIP* scip, /**< SCIP data structure */
8822  SCIP_VAR* var, /**< problem variable */
8823  SCIP_Real solvaldelta /**< difference of variable's new LP value - old LP value */
8824  )
8825 {
8826  assert( var->scip == scip );
8827 
8828  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostVal", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8829 
8830  return SCIPvarGetPseudocost(var, scip->stat, solvaldelta);
8831 }
8832 
8833 /** gets the variable's pseudo cost value for the given change of the variable's LP value,
8834  * only using the pseudo cost information of the current run
8835  *
8836  * @return the variable's pseudo cost value for the given change of the variable's LP value,
8837  * only using the pseudo cost information of the current run
8838  *
8839  * @pre This method can be called if @p scip is in one of the following stages:
8840  * - \ref SCIP_STAGE_INITPRESOLVE
8841  * - \ref SCIP_STAGE_PRESOLVING
8842  * - \ref SCIP_STAGE_EXITPRESOLVE
8843  * - \ref SCIP_STAGE_PRESOLVED
8844  * - \ref SCIP_STAGE_INITSOLVE
8845  * - \ref SCIP_STAGE_SOLVING
8846  * - \ref SCIP_STAGE_SOLVED
8847  */
8849  SCIP* scip, /**< SCIP data structure */
8850  SCIP_VAR* var, /**< problem variable */
8851  SCIP_Real solvaldelta /**< difference of variable's new LP value - old LP value */
8852  )
8853 {
8854  assert( var->scip == scip );
8855 
8856  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostValCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8857 
8858  return SCIPvarGetPseudocostCurrentRun(var, scip->stat, solvaldelta);
8859 }
8860 
8861 /** gets the variable's pseudo cost value for the given direction
8862  *
8863  * @return the variable's pseudo cost value for the given direction
8864  *
8865  * @pre This method can be called if @p scip is in one of the following stages:
8866  * - \ref SCIP_STAGE_INITPRESOLVE
8867  * - \ref SCIP_STAGE_PRESOLVING
8868  * - \ref SCIP_STAGE_EXITPRESOLVE
8869  * - \ref SCIP_STAGE_PRESOLVED
8870  * - \ref SCIP_STAGE_INITSOLVE
8871  * - \ref SCIP_STAGE_SOLVING
8872  * - \ref SCIP_STAGE_SOLVED
8873  */
8875  SCIP* scip, /**< SCIP data structure */
8876  SCIP_VAR* var, /**< problem variable */
8877  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8878  )
8879 {
8880  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocost", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8881  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8882  assert(var->scip == scip);
8883 
8884  return SCIPvarGetPseudocost(var, scip->stat, dir == SCIP_BRANCHDIR_DOWNWARDS ? -1.0 : 1.0);
8885 }
8886 
8887 /** gets the variable's pseudo cost value for the given direction,
8888  * only using the pseudo cost information of the current run
8889  *
8890  * @return the variable's pseudo cost value for the given direction,
8891  * only using the pseudo cost information of the current run
8892  *
8893  * @pre This method can be called if @p scip is in one of the following stages:
8894  * - \ref SCIP_STAGE_INITPRESOLVE
8895  * - \ref SCIP_STAGE_PRESOLVING
8896  * - \ref SCIP_STAGE_EXITPRESOLVE
8897  * - \ref SCIP_STAGE_PRESOLVED
8898  * - \ref SCIP_STAGE_INITSOLVE
8899  * - \ref SCIP_STAGE_SOLVING
8900  * - \ref SCIP_STAGE_SOLVED
8901  */
8903  SCIP* scip, /**< SCIP data structure */
8904  SCIP_VAR* var, /**< problem variable */
8905  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8906  )
8907 {
8908  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8909  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8910  assert(var->scip == scip);
8911 
8912  return SCIPvarGetPseudocostCurrentRun(var, scip->stat, dir == SCIP_BRANCHDIR_DOWNWARDS ? -1.0 : 1.0);
8913 }
8914 
8915 /** gets the variable's (possible fractional) number of pseudo cost updates for the given direction
8916  *
8917  * @return the variable's (possible fractional) number of pseudo cost updates for the given direction
8918  *
8919  * @pre This method can be called if @p scip is in one of the following stages:
8920  * - \ref SCIP_STAGE_INITPRESOLVE
8921  * - \ref SCIP_STAGE_PRESOLVING
8922  * - \ref SCIP_STAGE_EXITPRESOLVE
8923  * - \ref SCIP_STAGE_PRESOLVED
8924  * - \ref SCIP_STAGE_INITSOLVE
8925  * - \ref SCIP_STAGE_SOLVING
8926  * - \ref SCIP_STAGE_SOLVED
8927  */
8929  SCIP* scip, /**< SCIP data structure */
8930  SCIP_VAR* var, /**< problem variable */
8931  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8932  )
8933 {
8934  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCount", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8935  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8936  assert(var->scip == scip);
8937 
8938  return SCIPvarGetPseudocostCount(var, dir);
8939 }
8940 
8941 /** gets the variable's (possible fractional) number of pseudo cost updates for the given direction,
8942  * only using the pseudo cost information of the current run
8943  *
8944  * @return the variable's (possible fractional) number of pseudo cost updates for the given direction,
8945  * only using the pseudo cost information of the current run
8946  *
8947  * @pre This method can be called if @p scip is in one of the following stages:
8948  * - \ref SCIP_STAGE_INITPRESOLVE
8949  * - \ref SCIP_STAGE_PRESOLVING
8950  * - \ref SCIP_STAGE_EXITPRESOLVE
8951  * - \ref SCIP_STAGE_PRESOLVED
8952  * - \ref SCIP_STAGE_INITSOLVE
8953  * - \ref SCIP_STAGE_SOLVING
8954  * - \ref SCIP_STAGE_SOLVED
8955  */
8957  SCIP* scip, /**< SCIP data structure */
8958  SCIP_VAR* var, /**< problem variable */
8959  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
8960  )
8961 {
8962  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostCountCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8963  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8964  assert(var->scip == scip);
8965 
8966  return SCIPvarGetPseudocostCountCurrentRun(var, dir);
8967 }
8968 
8969 /** get pseudo cost variance of the variable, either for entire solve or only for current branch and bound run
8970  *
8971  * @return returns the (corrected) variance of pseudo code information collected so far.
8972  *
8973  * @pre This method can be called if @p scip is in one of the following stages:
8974  * - \ref SCIP_STAGE_INITPRESOLVE
8975  * - \ref SCIP_STAGE_PRESOLVING
8976  * - \ref SCIP_STAGE_EXITPRESOLVE
8977  * - \ref SCIP_STAGE_PRESOLVED
8978  * - \ref SCIP_STAGE_INITSOLVE
8979  * - \ref SCIP_STAGE_SOLVING
8980  * - \ref SCIP_STAGE_SOLVED
8981  */
8983  SCIP* scip, /**< SCIP data structure */
8984  SCIP_VAR* var, /**< problem variable */
8985  SCIP_BRANCHDIR dir, /**< branching direction (downwards, or upwards) */
8986  SCIP_Bool onlycurrentrun /**< only for pseudo costs of current branch and bound run */
8987  )
8988 {
8989  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostVariance", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
8990  assert(dir == SCIP_BRANCHDIR_DOWNWARDS || dir == SCIP_BRANCHDIR_UPWARDS);
8991  assert(var->scip == scip);
8992 
8993  return SCIPvarGetPseudocostVariance(var, dir, onlycurrentrun);
8994 }
8995 
8996 /** calculates a confidence bound for this variable under the assumption of normally distributed pseudo costs
8997  *
8998  * The confidence bound \f$ \theta \geq 0\f$ denotes the interval borders \f$ [X - \theta, \ X + \theta]\f$, which contains
8999  * the true pseudo costs of the variable, i.e., the expected value of the normal distribution, with a probability
9000  * of 2 * clevel - 1.
9001  *
9002  * @return value of confidence bound for this variable
9003  */
9005  SCIP* scip, /**< SCIP data structure */
9006  SCIP_VAR* var, /**< variable in question */
9007  SCIP_BRANCHDIR dir, /**< the branching direction for the confidence bound */
9008  SCIP_Bool onlycurrentrun, /**< should only the current run be taken into account */
9009  SCIP_CONFIDENCELEVEL clevel /**< confidence level for the interval */
9010  )
9011 {
9012  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPcalculatePscostConfidenceBound", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9013 
9014  return SCIPvarCalcPscostConfidenceBound(var, scip->set, dir, onlycurrentrun, clevel);
9015 }
9016 
9017 /** check if variable pseudo-costs have a significant difference in location. The significance depends on
9018  * the choice of \p clevel and on the kind of tested hypothesis. The one-sided hypothesis, which
9019  * should be rejected, is that fracy * mu_y >= fracx * mu_x, where mu_y and mu_x denote the
9020  * unknown location means of the underlying pseudo-cost distributions of x and y.
9021  *
9022  * This method is applied best if variable x has a better pseudo-cost score than y. The method hypothesizes that y were actually
9023  * better than x (despite the current information), meaning that y can be expected to yield branching
9024  * decisions as least as good as x in the long run. If the method returns TRUE, the current history information is
9025  * sufficient to safely rely on the alternative hypothesis that x yields indeed a better branching score (on average)
9026  * than y.
9027  *
9028  * @note The order of x and y matters for the one-sided hypothesis
9029  *
9030  * @note set \p onesided to FALSE if you are not sure which variable is better. The hypothesis tested then reads
9031  * fracy * mu_y == fracx * mu_x vs the alternative hypothesis fracy * mu_y != fracx * mu_x.
9032  *
9033  * @return TRUE if the hypothesis can be safely rejected at the given confidence level
9034  */
9036  SCIP* scip, /**< SCIP data structure */
9037  SCIP_VAR* varx, /**< variable x */
9038  SCIP_Real fracx, /**< the fractionality of variable x */
9039  SCIP_VAR* vary, /**< variable y */
9040  SCIP_Real fracy, /**< the fractionality of variable y */
9041  SCIP_BRANCHDIR dir, /**< branching direction */
9042  SCIP_CONFIDENCELEVEL clevel, /**< confidence level for rejecting hypothesis */
9043  SCIP_Bool onesided /**< should a one-sided hypothesis y >= x be tested? */
9044  )
9045 {
9046  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPsignificantVarPscostDifference", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9047 
9048  return SCIPvarSignificantPscostDifference(scip->set, scip->stat, varx, fracx, vary, fracy, dir, clevel, onesided);
9049 }
9050 
9051 /** tests at a given confidence level whether the variable pseudo-costs only have a small probability to
9052  * exceed a \p threshold. This is useful to determine if past observations provide enough evidence
9053  * to skip an expensive strong-branching step if there is already a candidate that has been proven to yield an improvement
9054  * of at least \p threshold.
9055  *
9056  * @note use \p clevel to adjust the level of confidence. For SCIP_CONFIDENCELEVEL_MIN, the method returns TRUE if
9057  * the estimated probability to exceed \p threshold is less than 25 %.
9058  *
9059  * @see SCIP_Confidencelevel for a list of available levels. The used probability limits refer to the one-sided levels
9060  * of confidence.
9061  *
9062  * @return TRUE if the variable pseudo-cost probabilistic model is likely to be smaller than \p threshold
9063  * at the given confidence level \p clevel.
9064  */
9066  SCIP* scip, /**< SCIP data structure */
9067  SCIP_VAR* var, /**< variable x */
9068  SCIP_Real frac, /**< the fractionality of variable x */
9069  SCIP_Real threshold, /**< the threshold to test against */
9070  SCIP_BRANCHDIR dir, /**< branching direction */
9071  SCIP_CONFIDENCELEVEL clevel /**< confidence level for rejecting hypothesis */
9072  )
9073 {
9074  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPpscostThresholdProbabilityTest", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9075 
9076  return SCIPvarPscostThresholdProbabilityTest(scip->set, scip->stat, var, frac, threshold, dir, clevel);
9077 }
9078 
9079 /** check if the current pseudo cost relative error in a direction violates the given threshold. The Relative
9080  * Error is calculated at a specific confidence level
9081  *
9082  * @return TRUE if relative error in variable pseudo costs is smaller than \p threshold
9083  */
9085  SCIP* scip, /**< SCIP data structure */
9086  SCIP_VAR* var, /**< variable in question */
9087  SCIP_Real threshold, /**< threshold for relative errors to be considered reliable (enough) */
9088  SCIP_CONFIDENCELEVEL clevel /**< a given confidence level */
9089  )
9090 {
9091  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisVarPscostRelerrorReliable", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9092 
9093  return SCIPvarIsPscostRelerrorReliable(var, scip->set, scip->stat, threshold, clevel);
9094 }
9095 
9096 /** gets the variable's pseudo cost score value for the given LP solution value
9097  *
9098  * @return the variable's pseudo cost score value for the given LP solution value
9099  *
9100  * @pre This method can be called if @p scip is in one of the following stages:
9101  * - \ref SCIP_STAGE_INITPRESOLVE
9102  * - \ref SCIP_STAGE_PRESOLVING
9103  * - \ref SCIP_STAGE_EXITPRESOLVE
9104  * - \ref SCIP_STAGE_PRESOLVED
9105  * - \ref SCIP_STAGE_INITSOLVE
9106  * - \ref SCIP_STAGE_SOLVING
9107  * - \ref SCIP_STAGE_SOLVED
9108  */
9110  SCIP* scip, /**< SCIP data structure */
9111  SCIP_VAR* var, /**< problem variable */
9112  SCIP_Real solval /**< variable's LP solution value */
9113  )
9114 {
9115  SCIP_Real downsol;
9116  SCIP_Real upsol;
9117  SCIP_Real pscostdown;
9118  SCIP_Real pscostup;
9119 
9120  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9121 
9122  assert( var->scip == scip );
9123 
9124  downsol = SCIPsetFeasCeil(scip->set, solval-1.0);
9125  upsol = SCIPsetFeasFloor(scip->set, solval+1.0);
9126  pscostdown = SCIPvarGetPseudocost(var, scip->stat, downsol-solval);
9127  pscostup = SCIPvarGetPseudocost(var, scip->stat, upsol-solval);
9128 
9129  return SCIPbranchGetScore(scip->set, var, pscostdown, pscostup);
9130 }
9131 
9132 /** gets the variable's pseudo cost score value for the given LP solution value,
9133  * only using the pseudo cost information of the current run
9134  *
9135  * @return the variable's pseudo cost score value for the given LP solution value,
9136  * only using the pseudo cost information of the current run
9137  *
9138  * @pre This method can be called if @p scip is in one of the following stages:
9139  * - \ref SCIP_STAGE_INITPRESOLVE
9140  * - \ref SCIP_STAGE_PRESOLVING
9141  * - \ref SCIP_STAGE_EXITPRESOLVE
9142  * - \ref SCIP_STAGE_PRESOLVED
9143  * - \ref SCIP_STAGE_INITSOLVE
9144  * - \ref SCIP_STAGE_SOLVING
9145  * - \ref SCIP_STAGE_SOLVED
9146  */
9148  SCIP* scip, /**< SCIP data structure */
9149  SCIP_VAR* var, /**< problem variable */
9150  SCIP_Real solval /**< variable's LP solution value */
9151  )
9152 {
9153  SCIP_Real downsol;
9154  SCIP_Real upsol;
9155  SCIP_Real pscostdown;
9156  SCIP_Real pscostup;
9157 
9158  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarPseudocostScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9159 
9160  assert( var->scip == scip );
9161 
9162  downsol = SCIPsetFeasCeil(scip->set, solval-1.0);
9163  upsol = SCIPsetFeasFloor(scip->set, solval+1.0);
9164  pscostdown = SCIPvarGetPseudocostCurrentRun(var, scip->stat, downsol-solval);
9165  pscostup = SCIPvarGetPseudocostCurrentRun(var, scip->stat, upsol-solval);
9166 
9167  return SCIPbranchGetScore(scip->set, var, pscostdown, pscostup);
9168 }
9169 
9170 /** returns the variable's VSIDS value
9171  *
9172  * @return the variable's VSIDS value
9173  *
9174  * @pre This method can be called if @p scip is in one of the following stages:
9175  * - \ref SCIP_STAGE_INITPRESOLVE
9176  * - \ref SCIP_STAGE_PRESOLVING
9177  * - \ref SCIP_STAGE_EXITPRESOLVE
9178  * - \ref SCIP_STAGE_PRESOLVED
9179  * - \ref SCIP_STAGE_INITSOLVE
9180  * - \ref SCIP_STAGE_SOLVING
9181  * - \ref SCIP_STAGE_SOLVED
9182  */
9184  SCIP* scip, /**< SCIP data structure */
9185  SCIP_VAR* var, /**< problem variable */
9186  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9187  )
9188 {
9189  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarVSIDS", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9190 
9191  assert( var->scip == scip );
9192 
9193  if( dir != SCIP_BRANCHDIR_DOWNWARDS && dir != SCIP_BRANCHDIR_UPWARDS )
9194  {
9195  SCIPerrorMessage("invalid branching direction %d when asking for VSIDS value\n", dir);
9196  return SCIP_INVALID;
9197  }
9198 
9199  return SCIPvarGetVSIDS(var, scip->stat, dir);
9200 }
9201 
9202 /** returns the variable's VSIDS value only using conflicts of the current run
9203  *
9204  * @return the variable's VSIDS value only using conflicts of the current run
9205  *
9206  * @pre This method can be called if @p scip is in one of the following stages:
9207  * - \ref SCIP_STAGE_INITPRESOLVE
9208  * - \ref SCIP_STAGE_PRESOLVING
9209  * - \ref SCIP_STAGE_EXITPRESOLVE
9210  * - \ref SCIP_STAGE_PRESOLVED
9211  * - \ref SCIP_STAGE_INITSOLVE
9212  * - \ref SCIP_STAGE_SOLVING
9213  * - \ref SCIP_STAGE_SOLVED
9214  */
9216  SCIP* scip, /**< SCIP data structure */
9217  SCIP_VAR* var, /**< problem variable */
9218  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9219  )
9220 {
9221  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarVSIDSCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9222 
9223  assert( var->scip == scip );
9224 
9225  if( dir != SCIP_BRANCHDIR_DOWNWARDS && dir != SCIP_BRANCHDIR_UPWARDS )
9226  {
9227  SCIPerrorMessage("invalid branching direction %d when asking for VSIDS value\n", dir);
9228  return SCIP_INVALID;
9229  }
9230 
9231  return SCIPvarGetVSIDSCurrentRun(var, scip->stat, dir);
9232 }
9233 
9234 /** returns the variable's conflict score value
9235  *
9236  * @return the variable's conflict score value
9237  *
9238  * @pre This method can be called if @p scip is in one of the following stages:
9239  * - \ref SCIP_STAGE_INITPRESOLVE
9240  * - \ref SCIP_STAGE_PRESOLVING
9241  * - \ref SCIP_STAGE_EXITPRESOLVE
9242  * - \ref SCIP_STAGE_PRESOLVED
9243  * - \ref SCIP_STAGE_INITSOLVE
9244  * - \ref SCIP_STAGE_SOLVING
9245  * - \ref SCIP_STAGE_SOLVED
9246  */
9248  SCIP* scip, /**< SCIP data structure */
9249  SCIP_VAR* var /**< problem variable */
9250  )
9251 {
9252  SCIP_Real downscore;
9253  SCIP_Real upscore;
9254 
9255  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9256 
9257  assert( var->scip == scip );
9258 
9259  downscore = SCIPvarGetVSIDS(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9260  upscore = SCIPvarGetVSIDS(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9261 
9262  return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9263 }
9264 
9265 /** returns the variable's conflict score value only using conflicts of the current run
9266  *
9267  * @return the variable's conflict score value only using conflicts of the current run
9268  *
9269  * @pre This method can be called if @p scip is in one of the following stages:
9270  * - \ref SCIP_STAGE_INITPRESOLVE
9271  * - \ref SCIP_STAGE_PRESOLVING
9272  * - \ref SCIP_STAGE_EXITPRESOLVE
9273  * - \ref SCIP_STAGE_PRESOLVED
9274  * - \ref SCIP_STAGE_INITSOLVE
9275  * - \ref SCIP_STAGE_SOLVING
9276  * - \ref SCIP_STAGE_SOLVED
9277  */
9279  SCIP* scip, /**< SCIP data structure */
9280  SCIP_VAR* var /**< problem variable */
9281  )
9282 {
9283  SCIP_Real downscore;
9284  SCIP_Real upscore;
9285 
9286  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9287 
9288  assert( var->scip == scip );
9289 
9290  downscore = SCIPvarGetVSIDSCurrentRun(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9291  upscore = SCIPvarGetVSIDSCurrentRun(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9292 
9293  return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9294 }
9295 
9296 /** returns the variable's conflict length score
9297  *
9298  * @return the variable's conflict length score
9299  *
9300  * @pre This method can be called if @p scip is in one of the following stages:
9301  * - \ref SCIP_STAGE_INITPRESOLVE
9302  * - \ref SCIP_STAGE_PRESOLVING
9303  * - \ref SCIP_STAGE_EXITPRESOLVE
9304  * - \ref SCIP_STAGE_PRESOLVED
9305  * - \ref SCIP_STAGE_INITSOLVE
9306  * - \ref SCIP_STAGE_SOLVING
9307  * - \ref SCIP_STAGE_SOLVED
9308  */
9310  SCIP* scip, /**< SCIP data structure */
9311  SCIP_VAR* var /**< problem variable */
9312  )
9313 {
9314  SCIP_Real downscore;
9315  SCIP_Real upscore;
9316 
9317  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictlengthScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9318 
9319  assert( var->scip == scip );
9320 
9323 
9324  return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9325 }
9326 
9327 /** returns the variable's conflict length score only using conflicts of the current run
9328  *
9329  * @return the variable's conflict length score only using conflicts of the current run
9330  *
9331  * @pre This method can be called if @p scip is in one of the following stages:
9332  * - \ref SCIP_STAGE_INITPRESOLVE
9333  * - \ref SCIP_STAGE_PRESOLVING
9334  * - \ref SCIP_STAGE_EXITPRESOLVE
9335  * - \ref SCIP_STAGE_PRESOLVED
9336  * - \ref SCIP_STAGE_INITSOLVE
9337  * - \ref SCIP_STAGE_SOLVING
9338  * - \ref SCIP_STAGE_SOLVED
9339  */
9341  SCIP* scip, /**< SCIP data structure */
9342  SCIP_VAR* var /**< problem variable */
9343  )
9344 {
9345  SCIP_Real downscore;
9346  SCIP_Real upscore;
9347 
9348  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarConflictlengthScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9349 
9350  assert( var->scip == scip );
9351 
9354 
9355  return SCIPbranchGetScore(scip->set, var, downscore, upscore);
9356 }
9357 
9358 /** returns the variable's average conflict length
9359  *
9360  * @return the variable's average conflict length
9361  *
9362  * @pre This method can be called if @p scip is in one of the following stages:
9363  * - \ref SCIP_STAGE_INITPRESOLVE
9364  * - \ref SCIP_STAGE_PRESOLVING
9365  * - \ref SCIP_STAGE_EXITPRESOLVE
9366  * - \ref SCIP_STAGE_PRESOLVED
9367  * - \ref SCIP_STAGE_INITSOLVE
9368  * - \ref SCIP_STAGE_SOLVING
9369  * - \ref SCIP_STAGE_SOLVED
9370  */
9372  SCIP* scip, /**< SCIP data structure */
9373  SCIP_VAR* var, /**< problem variable */
9374  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9375  )
9376 {
9377  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgConflictlength", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9378 
9379  assert( var->scip == scip );
9380 
9381  return SCIPvarGetAvgConflictlength(var, dir);
9382 }
9383 
9384 /** returns the variable's average conflict length only using conflicts of the current run
9385  *
9386  * @return the variable's average conflict length only using conflicts of the current run
9387  *
9388  * @pre This method can be called if @p scip is in one of the following stages:
9389  * - \ref SCIP_STAGE_INITPRESOLVE
9390  * - \ref SCIP_STAGE_PRESOLVING
9391  * - \ref SCIP_STAGE_EXITPRESOLVE
9392  * - \ref SCIP_STAGE_PRESOLVED
9393  * - \ref SCIP_STAGE_INITSOLVE
9394  * - \ref SCIP_STAGE_SOLVING
9395  * - \ref SCIP_STAGE_SOLVED
9396  */
9398  SCIP* scip, /**< SCIP data structure */
9399  SCIP_VAR* var, /**< problem variable */
9400  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9401  )
9402 {
9403  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgConflictlengthCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9404 
9405  assert( var->scip == scip );
9406 
9407  return SCIPvarGetAvgConflictlengthCurrentRun(var, dir);
9408 }
9409 
9410 /** returns the average number of inferences found after branching on the variable in given direction;
9411  * if branching on the variable in the given direction was yet evaluated, the average number of inferences
9412  * over all variables for branching in the given direction is returned
9413  *
9414  * @return the average number of inferences found after branching on the variable in given direction
9415  *
9416  * @pre This method can be called if @p scip is in one of the following stages:
9417  * - \ref SCIP_STAGE_INITPRESOLVE
9418  * - \ref SCIP_STAGE_PRESOLVING
9419  * - \ref SCIP_STAGE_EXITPRESOLVE
9420  * - \ref SCIP_STAGE_PRESOLVED
9421  * - \ref SCIP_STAGE_INITSOLVE
9422  * - \ref SCIP_STAGE_SOLVING
9423  * - \ref SCIP_STAGE_SOLVED
9424  */
9426  SCIP* scip, /**< SCIP data structure */
9427  SCIP_VAR* var, /**< problem variable */
9428  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9429  )
9430 {
9431  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferences", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9432 
9433  assert( var->scip == scip );
9434 
9435  return SCIPvarGetAvgInferences(var, scip->stat, dir);
9436 }
9437 
9438 /** returns the average number of inferences found after branching on the variable in given direction in the current run;
9439  * if branching on the variable in the given direction was yet evaluated, the average number of inferences
9440  * over all variables for branching in the given direction is returned
9441  *
9442  * @return the average number of inferences found after branching on the variable in given direction in the current run
9443  *
9444  * @pre This method can be called if @p scip is in one of the following stages:
9445  * - \ref SCIP_STAGE_INITPRESOLVE
9446  * - \ref SCIP_STAGE_PRESOLVING
9447  * - \ref SCIP_STAGE_EXITPRESOLVE
9448  * - \ref SCIP_STAGE_PRESOLVED
9449  * - \ref SCIP_STAGE_INITSOLVE
9450  * - \ref SCIP_STAGE_SOLVING
9451  * - \ref SCIP_STAGE_SOLVED
9452  */
9454  SCIP* scip, /**< SCIP data structure */
9455  SCIP_VAR* var, /**< problem variable */
9456  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9457  )
9458 {
9459  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferencesCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9460 
9461  assert( var->scip == scip );
9462 
9463  return SCIPvarGetAvgInferencesCurrentRun(var, scip->stat, dir);
9464 }
9465 
9466 /** returns the variable's average inference score value
9467  *
9468  * @return the variable's average inference score value
9469  *
9470  * @pre This method can be called if @p scip is in one of the following stages:
9471  * - \ref SCIP_STAGE_INITPRESOLVE
9472  * - \ref SCIP_STAGE_PRESOLVING
9473  * - \ref SCIP_STAGE_EXITPRESOLVE
9474  * - \ref SCIP_STAGE_PRESOLVED
9475  * - \ref SCIP_STAGE_INITSOLVE
9476  * - \ref SCIP_STAGE_SOLVING
9477  * - \ref SCIP_STAGE_SOLVED
9478  */
9480  SCIP* scip, /**< SCIP data structure */
9481  SCIP_VAR* var /**< problem variable */
9482  )
9483 {
9484  SCIP_Real inferdown;
9485  SCIP_Real inferup;
9486 
9487  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9488 
9489  assert( var->scip == scip );
9490 
9491  inferdown = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9492  inferup = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9493 
9494  return SCIPbranchGetScore(scip->set, var, inferdown, inferup);
9495 }
9496 
9497 /** returns the variable's average inference score value only using inferences of the current run
9498  *
9499  * @return the variable's average inference score value only using inferences of the current run
9500  *
9501  * @pre This method can be called if @p scip is in one of the following stages:
9502  * - \ref SCIP_STAGE_INITPRESOLVE
9503  * - \ref SCIP_STAGE_PRESOLVING
9504  * - \ref SCIP_STAGE_EXITPRESOLVE
9505  * - \ref SCIP_STAGE_PRESOLVED
9506  * - \ref SCIP_STAGE_INITSOLVE
9507  * - \ref SCIP_STAGE_SOLVING
9508  * - \ref SCIP_STAGE_SOLVED
9509  */
9511  SCIP* scip, /**< SCIP data structure */
9512  SCIP_VAR* var /**< problem variable */
9513  )
9514 {
9515  SCIP_Real inferdown;
9516  SCIP_Real inferup;
9517 
9518  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9519 
9520  assert( var->scip == scip );
9521 
9524 
9525  return SCIPbranchGetScore(scip->set, var, inferdown, inferup);
9526 }
9527 
9528 /** initializes the upwards and downwards pseudocosts, conflict scores, conflict lengths, inference scores, cutoff scores
9529  * of a variable to the given values
9530  *
9531  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9532  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9533  *
9534  * @pre This method can be called if @p scip is in one of the following stages:
9535  * - \ref SCIP_STAGE_TRANSFORMED
9536  * - \ref SCIP_STAGE_INITPRESOLVE
9537  * - \ref SCIP_STAGE_PRESOLVING
9538  * - \ref SCIP_STAGE_EXITPRESOLVE
9539  * - \ref SCIP_STAGE_PRESOLVED
9540  * - \ref SCIP_STAGE_INITSOLVE
9541  * - \ref SCIP_STAGE_SOLVING
9542  */
9544  SCIP* scip, /**< SCIP data structure */
9545  SCIP_VAR* var, /**< variable which should be initialized */
9546  SCIP_Real downpscost, /**< value to which pseudocosts for downwards branching should be initialized */
9547  SCIP_Real uppscost, /**< value to which pseudocosts for upwards branching should be initialized */
9548  SCIP_Real downvsids, /**< value to which VSIDS score for downwards branching should be initialized */
9549  SCIP_Real upvsids, /**< value to which VSIDS score for upwards branching should be initialized */
9550  SCIP_Real downconflen, /**< value to which conflict length score for downwards branching should be initialized */
9551  SCIP_Real upconflen, /**< value to which conflict length score for upwards branching should be initialized */
9552  SCIP_Real downinfer, /**< value to which inference counter for downwards branching should be initialized */
9553  SCIP_Real upinfer, /**< value to which inference counter for upwards branching should be initialized */
9554  SCIP_Real downcutoff, /**< value to which cutoff counter for downwards branching should be initialized */
9555  SCIP_Real upcutoff /**< value to which cutoff counter for upwards branching should be initialized */
9556  )
9557 {
9558  SCIP_CALL( SCIPcheckStage(scip, "SCIPinitVarBranchStats", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
9559 
9560  assert(downpscost >= 0.0 && uppscost >= 0.0);
9561  assert(downvsids >= 0.0 && upvsids >= 0.0);
9562  assert(downconflen >= 0.0 && upconflen >= 0.0);
9563  assert(downinfer >= 0.0 && upinfer >= 0.0);
9564  assert(downcutoff >= 0.0 && upcutoff >= 0.0);
9565 
9566  if( !SCIPisFeasZero(scip, downpscost) || !SCIPisFeasZero(scip, downvsids)
9567  || !SCIPisFeasZero(scip, downinfer) || !SCIPisFeasZero(scip, downcutoff) )
9568  {
9570  SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, -1.0, downpscost, 1.0) );
9572  SCIP_CALL( SCIPvarIncVSIDS(var, NULL, scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, SCIP_UNKNOWN, downvsids) );
9574  }
9575 
9576  if( !SCIPisFeasZero(scip, downconflen) )
9577  {
9579  }
9580 
9581  if( !SCIPisFeasZero(scip, uppscost) || !SCIPisFeasZero(scip, upvsids)
9582  || !SCIPisFeasZero(scip, upinfer) || !SCIPisFeasZero(scip, upcutoff) )
9583  {
9585  SCIP_CALL( SCIPvarUpdatePseudocost(var, scip->set, scip->stat, 1.0, uppscost, 1.0) );
9587  SCIP_CALL( SCIPvarIncVSIDS(var, NULL, scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, SCIP_UNKNOWN, upvsids) );
9589  }
9590 
9591  if( !SCIPisFeasZero(scip, upconflen) )
9592  {
9594  }
9595 
9596  return SCIP_OKAY;
9597 }
9598 
9599 /** initializes the upwards and downwards conflict scores, conflict lengths, inference scores, cutoff scores of a
9600  * variable w.r.t. a value by the given values (SCIP_VALUEHISTORY)
9601  *
9602  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9603  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9604  *
9605  * @pre This method can be called if @p scip is in one of the following stages:
9606  * - \ref SCIP_STAGE_TRANSFORMED
9607  * - \ref SCIP_STAGE_INITPRESOLVE
9608  * - \ref SCIP_STAGE_PRESOLVING
9609  * - \ref SCIP_STAGE_EXITPRESOLVE
9610  * - \ref SCIP_STAGE_PRESOLVED
9611  * - \ref SCIP_STAGE_INITSOLVE
9612  * - \ref SCIP_STAGE_SOLVING
9613  */
9615  SCIP* scip, /**< SCIP data structure */
9616  SCIP_VAR* var, /**< variable which should be initialized */
9617  SCIP_Real value, /**< domain value, or SCIP_UNKNOWN */
9618  SCIP_Real downvsids, /**< value to which VSIDS score for downwards branching should be initialized */
9619  SCIP_Real upvsids, /**< value to which VSIDS score for upwards branching should be initialized */
9620  SCIP_Real downconflen, /**< value to which conflict length score for downwards branching should be initialized */
9621  SCIP_Real upconflen, /**< value to which conflict length score for upwards branching should be initialized */
9622  SCIP_Real downinfer, /**< value to which inference counter for downwards branching should be initialized */
9623  SCIP_Real upinfer, /**< value to which inference counter for upwards branching should be initialized */
9624  SCIP_Real downcutoff, /**< value to which cutoff counter for downwards branching should be initialized */
9625  SCIP_Real upcutoff /**< value to which cutoff counter for upwards branching should be initialized */
9626  )
9627 {
9628  SCIP_CALL( SCIPcheckStage(scip, "SCIPinitVarValueBranchStats", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
9629 
9630  assert(downvsids >= 0.0 && upvsids >= 0.0);
9631  assert(downconflen >= 0.0 && upconflen >= 0.0);
9632  assert(downinfer >= 0.0 && upinfer >= 0.0);
9633  assert(downcutoff >= 0.0 && upcutoff >= 0.0);
9634 
9635  if( !SCIPisFeasZero(scip, downvsids) || !SCIPisFeasZero(scip, downinfer) || !SCIPisFeasZero(scip, downcutoff) )
9636  {
9637  SCIP_CALL( SCIPvarIncNBranchings(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, 1) );
9638  SCIP_CALL( SCIPvarIncInferenceSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downinfer) );
9639  SCIP_CALL( SCIPvarIncVSIDS(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downvsids) );
9640  SCIP_CALL( SCIPvarIncCutoffSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downcutoff) );
9641  }
9642 
9643  if( !SCIPisFeasZero(scip, downconflen) )
9644  {
9645  SCIP_CALL( SCIPvarIncNActiveConflicts(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_DOWNWARDS, value, downconflen) );
9646  }
9647 
9648  if( !SCIPisFeasZero(scip, upvsids) || !SCIPisFeasZero(scip, upinfer) || !SCIPisFeasZero(scip, upcutoff) )
9649  {
9650  SCIP_CALL( SCIPvarIncNBranchings(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, 1) );
9651  SCIP_CALL( SCIPvarIncInferenceSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upinfer) );
9652  SCIP_CALL( SCIPvarIncVSIDS(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upvsids) );
9653  SCIP_CALL( SCIPvarIncCutoffSum(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upcutoff) );
9654  }
9655 
9656  if( !SCIPisFeasZero(scip, upconflen) )
9657  {
9658  SCIP_CALL( SCIPvarIncNActiveConflicts(var, SCIPblkmem(scip), scip->set, scip->stat, SCIP_BRANCHDIR_UPWARDS, value, upconflen) );
9659  }
9660 
9661  return SCIP_OKAY;
9662 }
9663 
9664 /** returns the average number of cutoffs found after branching on the variable in given direction;
9665  * if branching on the variable in the given direction was yet evaluated, the average number of cutoffs
9666  * over all variables for branching in the given direction is returned
9667  *
9668  * @return the average number of cutoffs found after branching on the variable in given direction
9669  *
9670  * @pre This method can be called if @p scip is in one of the following stages:
9671  * - \ref SCIP_STAGE_INITPRESOLVE
9672  * - \ref SCIP_STAGE_PRESOLVING
9673  * - \ref SCIP_STAGE_EXITPRESOLVE
9674  * - \ref SCIP_STAGE_PRESOLVED
9675  * - \ref SCIP_STAGE_INITSOLVE
9676  * - \ref SCIP_STAGE_SOLVING
9677  * - \ref SCIP_STAGE_SOLVED
9678  */
9680  SCIP* scip, /**< SCIP data structure */
9681  SCIP_VAR* var, /**< problem variable */
9682  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9683  )
9684 {
9685  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffs", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9686 
9687  assert( var->scip == scip );
9688 
9689  return SCIPvarGetAvgCutoffs(var, scip->stat, dir);
9690 }
9691 
9692 /** returns the average number of cutoffs found after branching on the variable in given direction in the current run;
9693  * if branching on the variable in the given direction was yet evaluated, the average number of cutoffs
9694  * over all variables for branching in the given direction is returned
9695  *
9696  * @return the average number of cutoffs found after branching on the variable in given direction in the current run
9697  *
9698  * @pre This method can be called if @p scip is in one of the following stages:
9699  * - \ref SCIP_STAGE_INITPRESOLVE
9700  * - \ref SCIP_STAGE_PRESOLVING
9701  * - \ref SCIP_STAGE_EXITPRESOLVE
9702  * - \ref SCIP_STAGE_PRESOLVED
9703  * - \ref SCIP_STAGE_INITSOLVE
9704  * - \ref SCIP_STAGE_SOLVING
9705  * - \ref SCIP_STAGE_SOLVED
9706  */
9708  SCIP* scip, /**< SCIP data structure */
9709  SCIP_VAR* var, /**< problem variable */
9710  SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
9711  )
9712 {
9713  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffsCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9714 
9715  assert( var->scip == scip );
9716 
9717  return SCIPvarGetAvgCutoffsCurrentRun(var, scip->stat, dir);
9718 }
9719 
9720 /** returns the variable's average cutoff score value
9721  *
9722  * @return the variable's average cutoff score value
9723  *
9724  * @pre This method can be called if @p scip is in one of the following stages:
9725  * - \ref SCIP_STAGE_INITPRESOLVE
9726  * - \ref SCIP_STAGE_PRESOLVING
9727  * - \ref SCIP_STAGE_EXITPRESOLVE
9728  * - \ref SCIP_STAGE_PRESOLVED
9729  * - \ref SCIP_STAGE_INITSOLVE
9730  * - \ref SCIP_STAGE_SOLVING
9731  * - \ref SCIP_STAGE_SOLVED
9732  */
9734  SCIP* scip, /**< SCIP data structure */
9735  SCIP_VAR* var /**< problem variable */
9736  )
9737 {
9738  SCIP_Real cutoffdown;
9739  SCIP_Real cutoffup;
9740 
9741  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9742 
9743  assert( var->scip == scip );
9744 
9745  cutoffdown = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9746  cutoffup = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9747 
9748  return SCIPbranchGetScore(scip->set, var, cutoffdown, cutoffup);
9749 }
9750 
9751 /** returns the variable's average cutoff score value, only using cutoffs of the current run
9752  *
9753  * @return the variable's average cutoff score value, only using cutoffs of the current run
9754  *
9755  * @pre This method can be called if @p scip is in one of the following stages:
9756  * - \ref SCIP_STAGE_INITPRESOLVE
9757  * - \ref SCIP_STAGE_PRESOLVING
9758  * - \ref SCIP_STAGE_EXITPRESOLVE
9759  * - \ref SCIP_STAGE_PRESOLVED
9760  * - \ref SCIP_STAGE_INITSOLVE
9761  * - \ref SCIP_STAGE_SOLVING
9762  * - \ref SCIP_STAGE_SOLVED
9763  */
9765  SCIP* scip, /**< SCIP data structure */
9766  SCIP_VAR* var /**< problem variable */
9767  )
9768 {
9769  SCIP_Real cutoffdown;
9770  SCIP_Real cutoffup;
9771 
9772  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgCutoffScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9773 
9774  assert( var->scip == scip );
9775 
9778 
9779  return SCIPbranchGetScore(scip->set, var, cutoffdown, cutoffup);
9780 }
9781 
9782 /** returns the variable's average inference/cutoff score value, weighting the cutoffs of the variable with the given
9783  * factor
9784  *
9785  * @return the variable's average inference/cutoff score value
9786  *
9787  * @pre This method can be called if @p scip is in one of the following stages:
9788  * - \ref SCIP_STAGE_INITPRESOLVE
9789  * - \ref SCIP_STAGE_PRESOLVING
9790  * - \ref SCIP_STAGE_EXITPRESOLVE
9791  * - \ref SCIP_STAGE_PRESOLVED
9792  * - \ref SCIP_STAGE_INITSOLVE
9793  * - \ref SCIP_STAGE_SOLVING
9794  * - \ref SCIP_STAGE_SOLVED
9795  */
9797  SCIP* scip, /**< SCIP data structure */
9798  SCIP_VAR* var, /**< problem variable */
9799  SCIP_Real cutoffweight /**< factor to weigh average number of cutoffs in branching score */
9800  )
9801 {
9802  SCIP_Real avginferdown;
9803  SCIP_Real avginferup;
9804  SCIP_Real avginfer;
9805  SCIP_Real inferdown;
9806  SCIP_Real inferup;
9807  SCIP_Real cutoffdown;
9808  SCIP_Real cutoffup;
9809 
9810  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceCutoffScore", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9811 
9812  assert( var->scip == scip );
9813 
9816  avginfer = (avginferdown + avginferup)/2.0;
9817  inferdown = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9818  inferup = SCIPvarGetAvgInferences(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9819  cutoffdown = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_DOWNWARDS);
9820  cutoffup = SCIPvarGetAvgCutoffs(var, scip->stat, SCIP_BRANCHDIR_UPWARDS);
9821 
9822  return SCIPbranchGetScore(scip->set, var,
9823  inferdown + cutoffweight * avginfer * cutoffdown, inferup + cutoffweight * avginfer * cutoffup);
9824 }
9825 
9826 /** returns the variable's average inference/cutoff score value, weighting the cutoffs of the variable with the given
9827  * factor, only using inferences and cutoffs of the current run
9828  *
9829  * @return the variable's average inference/cutoff score value, only using inferences and cutoffs of the current run
9830  *
9831  * @pre This method can be called if @p scip is in one of the following stages:
9832  * - \ref SCIP_STAGE_INITPRESOLVE
9833  * - \ref SCIP_STAGE_PRESOLVING
9834  * - \ref SCIP_STAGE_EXITPRESOLVE
9835  * - \ref SCIP_STAGE_PRESOLVED
9836  * - \ref SCIP_STAGE_INITSOLVE
9837  * - \ref SCIP_STAGE_SOLVING
9838  * - \ref SCIP_STAGE_SOLVED
9839  */
9841  SCIP* scip, /**< SCIP data structure */
9842  SCIP_VAR* var, /**< problem variable */
9843  SCIP_Real cutoffweight /**< factor to weigh average number of cutoffs in branching score */
9844  )
9845 {
9846  SCIP_Real avginferdown;
9847  SCIP_Real avginferup;
9848  SCIP_Real avginfer;
9849  SCIP_Real inferdown;
9850  SCIP_Real inferup;
9851  SCIP_Real cutoffdown;
9852  SCIP_Real cutoffup;
9853 
9854  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVarAvgInferenceCutoffScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
9855 
9856  assert( var->scip == scip );
9857 
9860  avginfer = (avginferdown + avginferup)/2.0;
9865 
9866  return SCIPbranchGetScore(scip->set, var,
9867  inferdown + cutoffweight * avginfer * cutoffdown, inferup + cutoffweight * avginfer * cutoffup);
9868 }
9869 
9870 /** outputs variable information to file stream via the message system
9871  *
9872  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
9873  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
9874  *
9875  * @pre This method can be called if @p scip is in one of the following stages:
9876  * - \ref SCIP_STAGE_PROBLEM
9877  * - \ref SCIP_STAGE_TRANSFORMING
9878  * - \ref SCIP_STAGE_TRANSFORMED
9879  * - \ref SCIP_STAGE_INITPRESOLVE
9880  * - \ref SCIP_STAGE_PRESOLVING
9881  * - \ref SCIP_STAGE_EXITPRESOLVE
9882  * - \ref SCIP_STAGE_PRESOLVED
9883  * - \ref SCIP_STAGE_INITSOLVE
9884  * - \ref SCIP_STAGE_SOLVING
9885  * - \ref SCIP_STAGE_SOLVED
9886  * - \ref SCIP_STAGE_EXITSOLVE
9887  * - \ref SCIP_STAGE_FREETRANS
9888  *
9889  * @note If the message handler is set to a NULL pointer nothing will be printed
9890  */
9892  SCIP* scip, /**< SCIP data structure */
9893  SCIP_VAR* var, /**< problem variable */
9894  FILE* file /**< output file (or NULL for standard output) */
9895  )
9896 {
9897  SCIP_CALL( SCIPcheckStage(scip, "SCIPprintVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
9898 
9899  SCIP_CALL( SCIPvarPrint(var, scip->set, scip->messagehdlr, file) );
9900 
9901  return SCIP_OKAY;
9902 }
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:110
SCIP_STAT * stat
Definition: struct_scip.h:79
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:59
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
SCIP_Real sbup
Definition: struct_lp.h:154
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip_mem.h:99
void SCIPcolGetStrongbranchLast(SCIP_COL *col, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Real *solval, SCIP_Real *lpobjval)
Definition: lp.c:4711
SCIP_Real SCIPvarGetAvgConflictlengthCurrentRun(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:15412
SCIP_RETCODE SCIPflattenVarAggregationGraph(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1699
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:4949
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6215
SCIP_RETCODE SCIPtreeEndProbing(SCIP_TREE *tree, SCIP_REOPT *reopt, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_LP *lp, SCIP_RELAXATION *relaxation, SCIP_PRIMAL *primal, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable)
Definition: tree.c:6868
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:4303
void SCIPvarGetClosestVlb(SCIP_VAR *var, SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real *closestvlb, int *closestvlbidx)
Definition: var.c:14131
SCIP_Real SCIPgetVarAvgInferences(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9425
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:15539
SCIP_Bool SCIPvarsHaveCommonClique(SCIP_VAR *var1, SCIP_Bool value1, SCIP_VAR *var2, SCIP_Bool value2, SCIP_Bool regardimplics)
Definition: var.c:11483
SCIP_Real SCIPgetVarAvgCutoffs(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9679
SCIP_VAR ** SCIPcliqueGetVars(SCIP_CLIQUE *clique)
Definition: implics.c:3377
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6273
int SCIPcliquetableGetVarComponentIdx(SCIP_CLIQUETABLE *cliquetable, SCIP_VAR *var)
Definition: implics.c:2348
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:15059
SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5209
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:10470
void SCIPvarUpdateBestRootSol(SCIP_VAR *var, SCIP_SET *set, SCIP_Real rootsol, SCIP_Real rootredcost, SCIP_Real rootlpobjval)
Definition: var.c:13288
SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2134
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:17839
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition: scip_tree.c:91
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:365
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
Definition: lpi_clp.cpp:3931
SCIP_RETCODE SCIPsetRelaxSolValsSol(SCIP *scip, SCIP_RELAX *relax, SCIP_SOL *sol, SCIP_Bool includeslp)
Definition: scip_var.c:2495
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:1603
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:9796
SCIP_CONFLICT * conflict
Definition: struct_scip.h:96
SCIP_RETCODE SCIPaddVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real addobj)
Definition: scip_var.c:4568
SCIP_Real SCIPvarGetAvgCutoffsCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:16320
SCIP_Real SCIPvarGetBranchFactor(SCIP_VAR *var)
Definition: var.c:18079
SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:1998
void SCIPlpEndStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16350
SCIP_RETCODE SCIPclearRelaxSolVals(SCIP *scip, SCIP_RELAX *relax)
Definition: scip_var.c:2370
public methods for memory management
SCIP_Real SCIPgetVarAvgInferencesCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9453
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:9340
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6613
#define SCIPsetDuplicateBufferArray(set, ptr, source, num)
Definition: set.h:1736
#define SCIP_DECL_VARTRANS(x)
Definition: type_var.h:147
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:7190
SCIP_Bool SCIPvarDoNotMultaggr(SCIP_VAR *var)
Definition: var.c:5885
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:2121
public methods for implications, variable bounds, and cliques
SCIP_Real SCIPvarGetPseudocostCountCurrentRun(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:14626
methods for implications, variable bounds, and cliques
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17919
SCIP_RETCODE SCIPvarGetProbvarBinary(SCIP_VAR **var, SCIP_Bool *negated)
Definition: var.c:12318
SCIP_Bool SCIPvarIsPscostRelerrorReliable(SCIP_VAR *var, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real threshold, SCIP_CONFIDENCELEVEL clevel)
Definition: var.c:14792
#define SCIP_MAXSTRLEN
Definition: def.h:302
SCIP_Bool conf_usesb
Definition: struct_set.h:236
SCIP_Real SCIPgetVarPseudocostVal(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta)
Definition: scip_var.c:8820
void SCIPgmlWriteArc(FILE *file, unsigned int source, unsigned int target, const char *label, const char *color)
Definition: misc.c:638
internal methods for clocks and timing issues
#define SCIP_VARTYPE_INTEGER_CHAR
Definition: def.h:158
SCIP_RETCODE SCIPvarChgLbOriginal(SCIP_VAR *var, SCIP_SET *set, SCIP_Real newbound)
Definition: var.c:6572
SCIP_Longint SCIPcolGetStrongbranchNode(SCIP_COL *col)
Definition: lp.c:17165
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:139
SCIP_Real SCIPgetVarRedcost(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1870
int SCIPtreeGetProbingDepth(SCIP_TREE *tree)
Definition: tree.c:8431
SCIP_RETCODE SCIPgetNegatedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **negvars)
Definition: scip_var.c:1566
SCIP_Bool presol_donotaggr
Definition: struct_set.h:463
SCIP_RETCODE SCIPnodeAddBoundinfer(SCIP_NODE *node, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_VAR *var, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype, SCIP_CONS *infercons, SCIP_PROP *inferprop, int inferinfo, SCIP_Bool probingchange)
Definition: tree.c:1812
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17975
SCIP_RETCODE SCIPvarChgLbLazy(SCIP_VAR *var, SCIP_SET *set, SCIP_Real lazylb)
Definition: var.c:7474
#define SCIP_CALL_FINALLY(x, y)
Definition: def.h:435
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:4016
SCIP_Real SCIPgetColRedcost(SCIP *scip, SCIP_COL *col)
Definition: scip_lp.c:1154
SCIP_Real constant
Definition: struct_var.h:193
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_EVENTQUEUE * eventqueue
Definition: struct_scip.h:89
SCIP_Longint nsbtimesiterlimhit
Definition: struct_stat.h:121
SCIP_RETCODE SCIPinferVarLbProp(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_PROP *inferprop, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5901
SCIP_Real SCIPvarGetMultaggrLbGlobal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8571
SCIP_RETCODE SCIPchgVarLbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4852
SCIP_PRIMAL * primal
Definition: struct_scip.h:94
void SCIPstatDisableVarHistory(SCIP_STAT *stat)
Definition: stat.c:156
SCIP_Bool SCIPpscostThresholdProbabilityTest(SCIP *scip, SCIP_VAR *var, SCIP_Real frac, SCIP_Real threshold, SCIP_BRANCHDIR dir, SCIP_CONFIDENCELEVEL clevel)
Definition: scip_var.c:9065
SCIP_RETCODE SCIPvarChgUbOriginal(SCIP_VAR *var, SCIP_SET *set, SCIP_Real newbound)
Definition: var.c:6631
void SCIPgmlWriteNode(FILE *file, unsigned int id, const char *label, const char *nodetype, const char *fillcolor, const char *bordercolor)
Definition: misc.c:496
SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip_var.c:1445
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:2499
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1254
interface methods for specific LP solvers
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:17440
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:13265
SCIP_RETCODE SCIPchgVarUbLazy(SCIP *scip, SCIP_VAR *var, SCIP_Real lazyub)
Definition: scip_var.c:5170
void SCIPgmlWriteClosing(FILE *file)
Definition: misc.c:698
SCIP_Real SCIPbranchGetScore(SCIP_SET *set, SCIP_VAR *var, SCIP_Real downgain, SCIP_Real upgain)
Definition: branch.c:2190
SCIP_RETCODE SCIPvarMarkDoNotMultaggr(SCIP_VAR *var)
Definition: var.c:6146
SCIP_Real SCIPgetVarPseudocostCountCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:8956
SCIP_BOUNDTYPE SCIPboundchgGetBoundtype(SCIP_BOUNDCHG *boundchg)
Definition: var.c:17187
SCIP_RETCODE SCIPsetRelaxSolVals(SCIP *scip, SCIP_RELAX *relax, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Bool includeslp)
Definition: scip_var.c:2453
SCIP_Real SCIPgetVarPseudocostScoreCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real solval)
Definition: scip_var.c:9147
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_BRANCHCAND * branchcand
Definition: struct_scip.h:90
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition: scip_prob.c:1874
#define NLOCKTYPES
Definition: type_var.h:90
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:360
#define FALSE
Definition: def.h:96
SCIP_Bool SCIPconsIsLockedTypeNeg(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
Definition: cons.c:8475
SCIP_Real SCIPadjustedVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real ub)
Definition: scip_var.c:4651
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3023
SCIP_Bool misc_allowweakdualreds
Definition: struct_set.h:409
SCIP_Bool SCIPsetIsFeasIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6756
SCIP_Real SCIPgetVarVSIDS(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9183
struct SCIP_VarData SCIP_VARDATA
Definition: type_var.h:116
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:6126
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:290
SCIP_Real SCIPgetVarMultaggrUbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6597
SCIP_RETCODE SCIPvarTransform(SCIP_VAR *origvar, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_OBJSENSE objsense, SCIP_VAR **transvar)
Definition: var.c:3464
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Real SCIPgetVarPseudocostValCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta)
Definition: scip_var.c:8848
SCIP_Real constant
Definition: struct_var.h:203
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10764
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6327
SCIP_STAGE stage
Definition: struct_set.h:74
#define TRUE
Definition: def.h:95
SCIP_Real SCIPvarGetAvgConflictlength(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:15368
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:4323
SCIP_Longint SCIPgetVarStrongbranchNode(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:4166
SCIP_RETCODE SCIPhashmapInsertInt(SCIP_HASHMAP *hashmap, void *origin, int image)
Definition: misc.c:3141
void SCIPlpStartStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16337
enum SCIP_Varstatus SCIP_VARSTATUS
Definition: type_var.h:57
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1734
int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
Definition: tree.c:8403
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:2078
SCIP_Bool branch_checksbsol
Definition: struct_set.h:207
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17609
SCIP_Bool branch_divingpscost
Definition: struct_set.h:204
SCIP_RETCODE SCIPvarAddImplic(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_CLIQUETABLE *cliquetable, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_Bool varfixing, SCIP_VAR *implvar, SCIP_BOUNDTYPE impltype, SCIP_Real implbound, SCIP_Bool transitive, SCIP_Bool *infeasible, int *nbdchgs)
Definition: var.c:10917
#define SCIP_DECL_VARCOPY(x)
Definition: type_var.h:190
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:2917
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:7146
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:9707
SCIP_Bool presol_donotmultaggr
Definition: struct_set.h:462
SCIP_Real SCIPgetVarVSIDSCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9215
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:7333
SCIP_Real SCIPgetVarAvgCutoffScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9764
public methods for problem variables
SCIP_Bool SCIPisVarPscostRelerrorReliable(SCIP *scip, SCIP_VAR *var, SCIP_Real threshold, SCIP_CONFIDENCELEVEL clevel)
Definition: scip_var.c:9084
SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5326
SCIP_Real SCIPgetRelaxSolObj(SCIP *scip)
Definition: scip_var.c:2638
SCIP_Bool SCIPgetVarWasFixedAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2288
SCIP_Real SCIPvarGetAvgInferences(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:16075
SCIP_Bool diving
Definition: struct_lp.h:380
SCIP_Real SCIPgetVarPseudocost(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:8874
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:12014
SCIP_RETCODE SCIPchgVarUbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4896
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:6567
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:7020
SCIP_PROB * transprob
Definition: struct_scip.h:98
SCIP_Bool SCIPrelaxationIsSolValid(SCIP_RELAXATION *relaxation)
Definition: relax.c:808
SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4682
SCIP_Real constant
Definition: struct_var.h:186
SCIP_Bool conf_enable
Definition: struct_set.h:227
SCIP_RETCODE SCIPaddVarVlb(SCIP *scip, SCIP_VAR *var, SCIP_VAR *vlbvar, SCIP_Real vlbcoef, SCIP_Real vlbconstant, SCIP_Bool *infeasible, int *nbdchgs)
Definition: scip_var.c:6667
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:6182
#define SCIP_LONGINT_MAX
Definition: def.h:172
SCIP_RETCODE SCIPprobChgVarType(SCIP_PROB *prob, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_VAR *var, SCIP_VARTYPE vartype)
Definition: prob.c:1142
SCIP_RETCODE SCIPcreateLPSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip_sol.c:370
SCIP_RETCODE SCIPmarkRelaxSolInvalid(SCIP *scip)
Definition: scip_var.c:2588
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
SCIP_RETCODE SCIPvarUpdatePseudocost(SCIP_VAR *var, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
Definition: var.c:14387
#define SCIPsetFreeBufferArray(set, ptr)
Definition: set.h:1741
SCIP_Real SCIPadjustedVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real lb)
Definition: scip_var.c:4619
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition: type_lp.h:51
void SCIPvarAdjustLb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *lb)
Definition: var.c:6522
SCIP_Bool SCIPisTransformed(SCIP *scip)
Definition: scip_general.c:575
SCIP_RETCODE SCIPaddVarVub(SCIP *scip, SCIP_VAR *var, SCIP_VAR *vubvar, SCIP_Real vubcoef, SCIP_Real vubconstant, SCIP_Bool *infeasible, int *nbdchgs)
Definition: scip_var.c:6726
public methods for SCIP variables
SCIP_RETCODE SCIPvarChgBranchDirection(SCIP_VAR *var, SCIP_BRANCHDIR branchdirection)
Definition: var.c:11826
SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
Definition: var.c:17745
SCIP_Bool branch_forceall
Definition: struct_set.h:205
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
SCIP_RETCODE SCIPvarRemoveCliquesImplicsVbs(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_CLIQUETABLE *cliquetable, SCIP_SET *set, SCIP_Bool irrelevantvar, SCIP_Bool onlyredundant, SCIP_Bool removefromvar)
Definition: var.c:1610
SCIP_RETCODE SCIPchgVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:5038
#define SCIPdebugMsg
Definition: scip_message.h:78
SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition: scip_var.c:1486
SCIP_Longint SCIPcolGetStrongbranchLPAge(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4743
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:3668
internal methods for LP management
int SCIPvarGetNCliques(SCIP_VAR *var, SCIP_Bool varfixing)
Definition: var.c:18271
SCIP_PROB * origprob
Definition: struct_scip.h:80
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
SCIP_RETCODE SCIPparseVarsLinearsum(SCIP *scip, const char *str, SCIP_VAR **vars, SCIP_Real *vals, int *nvars, int varssize, int *requiredsize, char **endptr, SCIP_Bool *success)
Definition: scip_var.c:709
SCIP_RETCODE SCIPgetVarClosestVlb(SCIP *scip, SCIP_VAR *var, SCIP_SOL *sol, SCIP_Real *closestvlb, int *closestvlbidx)
Definition: scip_var.c:6615
SCIP_VAR ** vars
Definition: struct_var.h:195
SCIP_Real SCIPcomputeVarUbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6490
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:6511
SCIP_Bool SCIPisStrongbranchDownFirst(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:2661
SCIP_RETCODE SCIPtransformVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition: scip_var.c:1395
public methods for numerical tolerances
SCIP_Bool reopt_enable
Definition: struct_set.h:513
SCIP_Real SCIPgetVarPseudocostScore(SCIP *scip, SCIP_VAR *var, SCIP_Real solval)
Definition: scip_var.c:9109
SCIP_RETCODE SCIPscaleVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real scale)
Definition: scip_var.c:7927
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:160
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6309
public methods for querying solving statistics
SCIP_HISTORY * glbhistorycrun
Definition: struct_stat.h:182
int SCIPcliquetableGetNCliquesCreated(SCIP_CLIQUETABLE *cliquetable)
Definition: implics.c:3513
SCIP_RETCODE SCIPtryStrongbranchLPSol(SCIP *scip, SCIP_Bool *foundsol, SCIP_Bool *cutoff)
Definition: scip_var.c:4085
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3372
SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
Definition: scip_var.c:4265
SCIP_Real SCIPvarGetVSIDSCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:15936
SCIP_RETCODE SCIPupdateVarPseudocost(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
Definition: scip_var.c:8786
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:2270
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:2693
SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:8182
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:6927
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:7975
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17929
SCIP_VAR * SCIPvarGetProbvar(SCIP_VAR *var)
Definition: var.c:12226
int SCIPcliquetableGetNCliques(SCIP_CLIQUETABLE *cliquetable)
Definition: implics.c:3503
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:8541
SCIP_MEM * mem
Definition: struct_scip.h:71
public methods for managing constraints
SCIP_Bool misc_allowstrongdualreds
Definition: struct_set.h:408
SCIP_Real SCIPvarGetImplRedcost(SCIP_VAR *var, SCIP_SET *set, SCIP_Bool varfixing, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp)
Definition: var.c:13476
SCIP_Bool SCIPtreeProbing(SCIP_TREE *tree)
Definition: tree.c:8285
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:11695
SCIP_Real SCIPvarGetPseudocost(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real solvaldelta)
Definition: var.c:14485
SCIP_RETCODE SCIPprobRemoveVarName(SCIP_PROB *prob, SCIP_VAR *var)
Definition: prob.c:922
SCIP_AGGREGATE aggregate
Definition: struct_var.h:231
SCIP_RETCODE SCIPmarkDoNotAggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8688
SCIP_Real SCIPsolGetObj(SCIP_SOL *sol, SCIP_SET *set, SCIP_PROB *transprob, SCIP_PROB *origprob)
Definition: sol.c:1546
SCIP_Real sbdown
Definition: struct_lp.h:153
SCIP_RETCODE SCIPvarChgUbLazy(SCIP_VAR *var, SCIP_SET *set, SCIP_Real lazyub)
Definition: var.c:7497
SCIP_Real SCIPgetVarPseudocostVariance(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun)
Definition: scip_var.c:8982
enum SCIP_LockType SCIP_LOCKTYPE
Definition: type_var.h:96
SCIP_RETCODE SCIPgetBinvarRepresentatives(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **repvars, SCIP_Bool *negated)
Definition: scip_var.c:1650
SCIP_Bool SCIPvarDoNotAggr(SCIP_VAR *var)
Definition: var.c:5852
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:17197
SCIP_EVENTFILTER * eventfilter
Definition: struct_scip.h:88
SCIP_Bool SCIPlpIsDualReliable(SCIP_LP *lp)
Definition: lp.c:17819
SCIP_Bool SCIPdoNotAggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8591
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:14935
SCIP_RETCODE SCIPchgVarLbLazy(SCIP *scip, SCIP_VAR *var, SCIP_Real lazylb)
Definition: scip_var.c:5129
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:8604
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:6269
SCIP_Bool SCIPrelaxationIsSolZero(SCIP_RELAXATION *relaxation)
Definition: relax.c:785
SCIP_RETCODE SCIPgetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip_sol.c:1398
SCIP_RETCODE SCIPinferVarFixCons(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5438
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:9543
SCIP_RETCODE SCIPvarRelease(SCIP_VAR **var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: var.c:2875
SCIP_RETCODE SCIPgetProbvarSum(SCIP *scip, SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: scip_var.c:1800
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:6786
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:2186
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:14534
void SCIPstrCopySection(const char *str, char startchar, char endchar, char *token, int size, char **endptr)
Definition: misc.c:10895
SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:4443
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:3170
SCIP_LPSOLSTAT lastsblpsolstats[2]
Definition: struct_stat.h:188
SCIP_CONFLICTSTORE * conflictstore
Definition: struct_scip.h:104
SCIP_RETCODE SCIPvarGetTransformed(SCIP_VAR *origvar, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR **transvar)
Definition: var.c:3551
SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4772
SCIP_Real SCIPcalculatePscostConfidenceBound(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Bool onlycurrentrun, SCIP_CONFIDENCELEVEL clevel)
Definition: scip_var.c:9004
SCIP_OBJSENSE objsense
Definition: struct_prob.h:86
SCIP_RETCODE SCIPmarkDoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8721
char branch_firstsbchild
Definition: struct_set.h:195
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17260
SCIP_VAR * transvar
Definition: struct_var.h:179
SCIP_REOPT * reopt
Definition: struct_scip.h:85
SCIP_RETCODE SCIPsetRelaxSolVal(SCIP *scip, SCIP_RELAX *relax, SCIP_VAR *var, SCIP_Real val)
Definition: scip_var.c:2420
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:3057
SCIP_Real SCIPsetFeasCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6791
SCIP_RETCODE SCIPtightenVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6234
SCIP_DOMCHG * SCIPnodeGetDomchg(SCIP_NODE *node)
Definition: tree.c:7538
SCIP_Real cutoffbound
Definition: struct_lp.h:284
SCIP_Longint nsbdivinglpiterations
Definition: struct_stat.h:76
#define NULL
Definition: lpi_spx1.cpp:164
void SCIPvarGetClosestVub(SCIP_VAR *var, SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real *closestvub, int *closestvubidx)
Definition: var.c:14206
SCIP_NEGATE negate
Definition: struct_var.h:233
SCIP_Real SCIPgetVarConflictlengthScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9309
SCIP_RETCODE SCIPvarSetRelaxSol(SCIP_VAR *var, SCIP_SET *set, SCIP_RELAXATION *relaxation, SCIP_Real solval, SCIP_Bool updateobj)
Definition: var.c:13870
data structures for branch and bound tree
SCIP_HISTORY * glbhistory
Definition: struct_stat.h:181
SCIP_Real SCIPboundchgGetNewbound(SCIP_BOUNDCHG *boundchg)
Definition: var.c:17157
#define REALABS(x)
Definition: def.h:210
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
Definition: var.c:18293
SCIP_Real SCIPgetVarAvgInferenceScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9510
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:10006
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:14754
#define SCIP_CALL(x)
Definition: def.h:393
SCIP_RETCODE SCIPprobAddVarName(SCIP_PROB *prob, SCIP_VAR *var)
Definition: prob.c:906
SCIP main data structure.
SCIP_Bool SCIPsignificantVarPscostDifference(SCIP *scip, SCIP_VAR *varx, SCIP_Real fracx, SCIP_VAR *vary, SCIP_Real fracy, SCIP_BRANCHDIR dir, SCIP_CONFIDENCELEVEL clevel, SCIP_Bool onesided)
Definition: scip_var.c:9035
SCIP_RETCODE SCIPsolveProbingLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition: scip_probing.c:819
SCIP_Real SCIPcomputeVarUbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6532
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:6016
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:15455
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:1744
SCIP_Real SCIPgetVarAvgConflictlength(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9371
SCIP_RETCODE SCIPremoveVarFromGlobalStructures(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:7865
SCIP_RETCODE SCIPgetVarClosestVub(SCIP *scip, SCIP_VAR *var, SCIP_SOL *sol, SCIP_Real *closestvub, int *closestvubidx)
Definition: scip_var.c:6638
SCIP_Longint SCIPgetVarStrongbranchLPAge(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:4200
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPsetIsLbBetter(SCIP_SET *set, SCIP_Real newlb, SCIP_Real oldlb, SCIP_Real oldub)
Definition: set.c:7038
SCIP_Real SCIPvarGetPseudocostCount(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:14581
#define SCIPstatAdd(stat, set, field, val)
Definition: stat.h:280
internal methods for relaxators
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6237
SCIP_RETCODE SCIPvarChgUbLocal(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_Real newbound)
Definition: var.c:8102
SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13122
SCIP_RETCODE SCIPvarPrint(SCIP_VAR *var, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: var.c:3009
SCIP_Real SCIPgetVarPseudocostCount(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:8928
SCIP_RETCODE SCIPlpStartStrongbranch(SCIP_LP *lp)
Definition: lp.c:4184
SCIP_Real SCIPgetVarPseudocostCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:8902
SCIP_CLIQUETABLE * cliquetable
Definition: struct_scip.h:97
SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2386
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:4519
internal methods for problem variables
SCIP_RETCODE SCIPvarChgBranchFactor(SCIP_VAR *var, SCIP_SET *set, SCIP_Real branchfactor)
Definition: var.c:11568
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:5284
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
#define SCIP_UNKNOWN
Definition: def.h:207
SCIP_RETCODE SCIPstartStrongbranch(SCIP *scip, SCIP_Bool enablepropagation)
Definition: scip_var.c:2692
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:3551
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:15623
void SCIPrelaxationSetSolRelax(SCIP_RELAXATION *relaxation, SCIP_RELAX *relax)
Definition: relax.c:880
#define SCIP_Bool
Definition: def.h:93
SCIP_RETCODE SCIPinferVarFixProp(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_PROP *inferprop, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5832
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip_lp.c:168
void SCIPvarCapture(SCIP_VAR *var)
Definition: var.c:2850
SCIP_CLOCK * sbsoltime
Definition: struct_stat.h:175
SCIP_Real ub
Definition: struct_var.h:171
int SCIPgetNCliquesCreated(SCIP *scip)
Definition: scip_var.c:7608
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:6434
SCIP_RETCODE SCIProundSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
Definition: scip_sol.c:2455
#define MAXNCLIQUEVARSCOMP
Definition: scip_var.c:7126
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:2845
int SCIPvarGetBranchPriority(SCIP_VAR *var)
Definition: var.c:18091
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:3752
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:3358
union SCIP_Var::@21 data
SCIP_RETCODE SCIPmarkRelaxSolValid(SCIP *scip, SCIP_RELAX *relax, SCIP_Bool includeslp)
Definition: scip_var.c:2563
SCIP_Bool branch_roundsbsol
Definition: struct_set.h:208
int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition: var.c:3432
SCIP_RETCODE SCIPconflictAnalyzeStrongbranch(SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_COL *col, SCIP_Bool *downconflict, SCIP_Bool *upconflict)
Definition: conflict.c:8990
SCIP_RETCODE SCIPcliquetableComputeCliqueComponents(SCIP_CLIQUETABLE *cliquetable, SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_VAR **vars, int nbinvars, int nintvars, int nimplvars)
Definition: implics.c:3128
#define MAX(x, y)
Definition: tclique_def.h:92
SCIP_Bool SCIPstrToRealValue(const char *str, SCIP_Real *value, char **endptr)
Definition: misc.c:10865
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:3240
SCIP_RETCODE SCIPcalcCliquePartition(SCIP *const scip, SCIP_VAR **const vars, int const nvars, int *const cliquepartition, int *const ncliques)
Definition: scip_var.c:7262
SCIP_VAR * SCIPboundchgGetVar(SCIP_BOUNDCHG *boundchg)
Definition: var.c:17167
methods for debugging
SCIP_Bool * SCIPcliqueGetValues(SCIP_CLIQUE *clique)
Definition: implics.c:3389
SCIP_BOUNDCHG * SCIPdomchgGetBoundchg(SCIP_DOMCHG *domchg, int pos)
Definition: var.c:17215
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:4214
datastructures for block memory pools and memory buffers
SCIP_RETCODE SCIPwriteCliqueGraph(SCIP *scip, const char *fname, SCIP_Bool writenodeweights)
Definition: scip_var.c:7716
SCIP_Real SCIPvarGetMultaggrUbGlobal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8637
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip_sol.c:985
SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
Definition: prob.c:2309
void SCIPenableVarHistory(SCIP *scip)
Definition: scip_var.c:8747
SCIP_Real SCIPcomputeVarLbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6469
SCIP_Real SCIPgetVarAvgInferenceCutoffScoreCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real cutoffweight)
Definition: scip_var.c:9840
SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18511
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:3890
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:4417
SCIP_Real SCIPvarGetAvgInferencesCurrentRun(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:16132
SCIP_Bool SCIPtreeHasCurrentNodeLP(SCIP_TREE *tree)
Definition: tree.c:8420
SCIP_Bool SCIPallowWeakDualReds(SCIP *scip)
Definition: scip_var.c:8662
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition: scip_var.c:8282
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:136
SCIP_RETCODE SCIPchgVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition: scip_var.c:7986
SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:4357
int SCIPconflictGetNConflicts(SCIP_CONFLICT *conflict)
Definition: conflict.c:3756
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:17630
void SCIPgmlWriteNodeWeight(FILE *file, unsigned int id, const char *label, const char *nodetype, const char *fillcolor, const char *bordercolor, SCIP_Real weight)
Definition: misc.c:544
SCIP_Real SCIPvarGetRelaxSol(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:13931
datastructures for problem statistics
int nconflicthdlrs
Definition: struct_set.h:122
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Real ub
Definition: struct_lp.h:139
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6635
SCIP_RETCODE SCIPcliquetableAdd(SCIP_CLIQUETABLE *cliquetable, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_VAR **vars, SCIP_Bool *values, int nvars, SCIP_Bool isequation, SCIP_Bool *infeasible, int *nbdchgs)
Definition: implics.c:2376
SCIP_RETCODE SCIPvarAddObj(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_Real addobj)
Definition: var.c:6344
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:5507
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:15195
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:2925
void SCIPrelaxationSetSolObj(SCIP_RELAXATION *relaxation, SCIP_Real obj)
Definition: relax.c:828
#define SCIP_MAXTREEDEPTH
Definition: def.h:329
SCIP * scip
Definition: struct_var.h:288
SCIP_BDCHGINFO * SCIPvarGetLbchgInfo(SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: var.c:16418
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:16474
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:2000
SCIP_Real SCIPgetVarMultaggrLbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6582
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:4488
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:127
SCIP_Real SCIPlpGetLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13161
datastructures for storing and manipulating the main problem
SCIP_Bool SCIPinDive(SCIP *scip)
Definition: scip_lp.c:2769
void SCIPrelaxationSetSolZero(SCIP_RELAXATION *relaxation, SCIP_Bool iszero)
Definition: relax.c:774
SCIP_Real SCIPsetFeasFloor(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6780
SCIP_CLIQUE ** SCIPgetCliques(SCIP *scip)
Definition: scip_var.c:7635
SCIP_Real SCIPgetVarAvgConflictlengthCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip_var.c:9397
SCIP_RETCODE SCIPaddVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real addfactor)
Definition: scip_var.c:7955
SCIP_LPSOLSTAT SCIPgetLastStrongbranchLPSolStat(SCIP *scip, SCIP_BRANCHDIR branchdir)
Definition: scip_var.c:3994
SCIP_Bool misc_exactsolve
Definition: struct_set.h:393
SCIP_RETCODE SCIPwriteVarsList(SCIP *scip, FILE *file, SCIP_VAR **vars, int nvars, SCIP_Bool type, char delimiter)
Definition: scip_var.c:292
#define SCIP_VARTYPE_IMPLINT_CHAR
Definition: def.h:159
SCIP_RETCODE SCIPsetVarStrongbranchData(SCIP *scip, SCIP_VAR *var, SCIP_Real lpobjval, SCIP_Real primsol, SCIP_Real down, SCIP_Real up, SCIP_Bool downvalid, SCIP_Bool upvalid, SCIP_Longint iter, int itlim)
Definition: scip_var.c:4050
general public methods
int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition: var.c:3419
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:1915
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:1164
static const SCIP_Real scalars[]
Definition: lp.c:5747
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:5450
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:5621
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:3779
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:2333
int SCIPdomchgGetNBoundchgs(SCIP_DOMCHG *domchg)
Definition: var.c:17207
SCIP_RETCODE SCIPnodeAddBoundchg(SCIP_NODE *node, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_VAR *var, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype, SCIP_Bool probingchange)
Definition: tree.c:2087
#define SCIP_VARTYPE_CONTINUOUS_CHAR
Definition: def.h:160
public methods for the probing mode
SCIP_RETCODE SCIPvarGetActiveRepresentatives(SCIP_SET *set, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize, SCIP_Bool mergemultiples)
Definition: var.c:3922
SCIP_NODE * SCIPtreeGetCurrentNode(SCIP_TREE *tree)
Definition: tree.c:8386
SCIP_RETCODE SCIPendStrongbranch(SCIP *scip)
Definition: scip_var.c:2750
SCIP_Bool SCIPisRelaxSolValid(SCIP *scip)
Definition: scip_var.c:2543
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:14869
SCIP_RETCODE SCIPvarMarkDoNotAggr(SCIP_VAR *var)
Definition: var.c:6110
SCIP_Bool SCIPallowDualReds(SCIP *scip)
Definition: scip_var.c:8620
SCIP_SET * set
Definition: struct_scip.h:72
public methods for message output
int SCIPgetNCliques(SCIP *scip)
Definition: scip_var.c:7581
data structures for LP management
SCIP_RETCODE SCIPaddVarBranchPriority(SCIP *scip, SCIP_VAR *var, int addpriority)
Definition: scip_var.c:8060
SCIP_Real * scalars
Definition: struct_var.h:194
datastructures for problem variables
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:1955
int SCIPcolGetNStrongbranchs(SCIP_COL *col)
Definition: lp.c:17175
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17379
SCIP_RETCODE SCIPcalcNegatedCliquePartition(SCIP *const scip, SCIP_VAR **const vars, int const nvars, int *const cliquepartition, int *const ncliques)
Definition: scip_var.c:7481
SCIP_MESSAGEHDLR * messagehdlr
Definition: struct_scip.h:75
SCIP_RETCODE SCIPaggregateVars(SCIP *scip, SCIP_VAR *varx, SCIP_VAR *vary, SCIP_Real scalarx, SCIP_Real scalary, SCIP_Real rhs, SCIP_Bool *infeasible, SCIP_Bool *redundant, SCIP_Bool *aggregated)
Definition: scip_var.c:8407
SCIP_NODETYPE SCIPnodeGetType(SCIP_NODE *node)
Definition: tree.c:7433
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1220
#define SCIP_Real
Definition: def.h:186
internal methods for problem statistics
SCIP_RETCODE SCIPvarsGetProbvarBinary(SCIP_VAR ***vars, SCIP_Bool **negatedarr, int nvars)
Definition: var.c:12286
SCIP_RETCODE SCIPchgVarBranchDirection(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR branchdirection)
Definition: scip_var.c:8091
SCIP_Bool SCIPhaveVarsCommonClique(SCIP *scip, SCIP_VAR *var1, SCIP_Bool value1, SCIP_VAR *var2, SCIP_Bool value2, SCIP_Bool regardimplics)
Definition: scip_var.c:7665
datastructures for collecting primal CIP solutions and primal informations
public methods for message handling
SCIP_Bool SCIPdoNotAggr(SCIP *scip)
Definition: scip_var.c:8571
SCIP_RETCODE SCIPtransformVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip_var.c:1355
SCIP_Real SCIPvarGetVSIDS(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:18384
#define SCIP_INVALID
Definition: def.h:206
SCIP_RETCODE SCIPvarParseTransformed(SCIP_VAR **var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, const char *str, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARCOPY((*varcopy)), SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_VARDATA *vardata, char **endptr, SCIP_Bool *success)
Definition: var.c:2563
SCIP_Real primsol
Definition: struct_lp.h:148
#define SCIP_Longint
Definition: def.h:171
SCIP_Bool SCIPallColsInLP(SCIP *scip)
Definition: scip_lp.c:649
SCIP_Real SCIPvarGetAvgCutoffs(SCIP_VAR *var, SCIP_STAT *stat, SCIP_BRANCHDIR dir)
Definition: var.c:16273
SCIP_Real lb
Definition: struct_var.h:170
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6679
SCIP_Longint nsbsolsfound
Definition: struct_stat.h:104
SCIP_TREE * tree
Definition: struct_scip.h:95
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17425
#define SCIP_VARTYPE_BINARY_CHAR
Definition: def.h:157
SCIP_Real SCIPvarGetMultaggrUbLocal(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:8505
SCIP_RETCODE SCIPvarChgName(SCIP_VAR *var, BMS_BLKMEM *blkmem, const char *name)
Definition: var.c:2916
SCIP_RELAXATION * relaxation
Definition: struct_scip.h:93
void SCIPsolSetStrongbranching(SCIP_SOL *sol)
Definition: sol.c:2718
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:3032
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:818
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPdoNotMultaggr(SCIP *scip)
Definition: scip_var.c:8581
SCIP_DOM glbdom
Definition: struct_var.h:225
SCIP_Real SCIPgetVarConflictScoreCurrentRun(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9278
SCIP_Real SCIPhistoryGetAvgInferences(SCIP_HISTORY *history, SCIP_BRANCHDIR dir)
Definition: history.c:658
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
enum SCIP_Vartype SCIP_VARTYPE
Definition: type_var.h:69
SCIP_Bool SCIPconsIsLockedTypePos(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
Definition: cons.c:8463
SCIP_Real SCIPgetVarSol(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:2313
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:17985
SCIP_Real SCIPgetVarMultaggrLbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:6552
#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:3367
void SCIPgmlWriteOpening(FILE *file, SCIP_Bool directed)
Definition: misc.c:682
void SCIPvarAdjustUb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *ub)
Definition: var.c:6539
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPsetIsUbBetter(SCIP_SET *set, SCIP_Real newub, SCIP_Real oldlb, SCIP_Real oldub)
Definition: set.c:7059
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition: var.c:17402
SCIP_RETCODE SCIPtightenVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6354
static SCIP_RETCODE tightenBounds(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:8108
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:9614
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:132
SCIP_RETCODE SCIPupdateVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition: scip_var.c:8027
void SCIPcolInvalidateStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4268
SCIP_RETCODE SCIPvarGetProbvarSum(SCIP_VAR **var, SCIP_SET *set, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12655
SCIP_NODE * root
Definition: struct_tree.h:186
int SCIPhashmapGetImageInt(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3230
#define SCIP_CALL_ABORT(x)
Definition: def.h:372
SCIP_Real SCIPvarGetPseudoSol(SCIP_VAR *var)
Definition: var.c:18371
SCIP_RETCODE SCIPcleanupCliques(SCIP *scip, SCIP_Bool *infeasible)
Definition: scip_var.c:7538
SCIP_Real SCIPgetVarFarkasCoef(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1960
SCIP_ORIGINAL original
Definition: struct_var.h:229
SCIP_LP * lp
Definition: struct_scip.h:91
#define SCIPABORT()
Definition: def.h:365
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:4232
SCIP_RETCODE SCIPgetActiveVars(SCIP *scip, SCIP_VAR **vars, int *nvars, int varssize, int *requiredsize)
Definition: scip_var.c:1836
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:17451
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:8439
void SCIPdisableVarHistory(SCIP *scip)
Definition: scip_var.c:8766
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1361
SCIP_Real SCIPgetVarAvgInferenceScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9479
datastructures for global SCIP settings
SCIP_RETCODE SCIPlpEndStrongbranch(SCIP_LP *lp)
Definition: lp.c:4199
SCIP_Bool SCIPallowStrongDualReds(SCIP *scip)
Definition: scip_var.c:8635
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:5729
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:17107
SCIP_RETCODE SCIPvarNegate(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR **negvar)
Definition: var.c:5921
SCIP_CLIQUE ** SCIPcliquetableGetCliques(SCIP_CLIQUETABLE *cliquetable)
Definition: implics.c:3523
SCIP_RETCODE SCIPchgVarBranchFactor(SCIP *scip, SCIP_VAR *var, SCIP_Real branchfactor)
Definition: scip_var.c:7899
SCIP_RETCODE SCIPprintVar(SCIP *scip, SCIP_VAR *var, FILE *file)
Definition: scip_var.c:9891
static SCIP_RETCODE relabelOrderConsistent(SCIP *const scip, int *labels, int const nlabels, int *nclasses)
Definition: scip_var.c:6959
SCIP_Bool SCIPallowObjProp(SCIP *scip)
Definition: scip_var.c:8648
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip_var.c:1533
SCIP_Real SCIPgetVarConflictScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9247
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:14700
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17589
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:17415
SCIP_Real SCIPgetRelaxSolVal(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:2609
SCIP_Real scalar
Definition: struct_var.h:185
void SCIPvarMarkDeleteGlobalStructures(SCIP_VAR *var)
Definition: var.c:17517
SCIP_RETCODE SCIPchgVarName(SCIP *scip, SCIP_VAR *var, const char *name)
Definition: scip_var.c:1305
memory allocation routines
SCIP_Real SCIPgetVarAvgCutoffScore(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:9733