Scippy

SCIP

Solving Constraint Integer Programs

prop_probing.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2017 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file prop_probing.c
17  * @brief probing propagator
18  * @author Tobias Achterberg
19  * @author Matthias Miltenberger
20  * @author Michael Winkler
21  */
22 
23 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
24 
25 #include <assert.h>
26 #include <string.h>
27 
28 #include "scip/prop_probing.h"
29 #include "scip/pub_misc.h"
30 
31 
32 #define PROP_NAME "probing"
33 #define PROP_DESC "probing propagator on binary variables"
34 #define PROP_TIMING SCIP_PROPTIMING_AFTERLPLOOP
35 #define PROP_PRIORITY -100000 /**< propagation priority */
36 #define PROP_FREQ -1 /**< propagation frequency */
37 #define PROP_DELAY TRUE /**< should propagation method be delayed, if other propagators found
38  * reductions? */
39 #define PROP_PRESOL_PRIORITY -100000 /**< priority of the presolving method (>= 0: before, < 0: after constraint handlers); combined with presolvers */
40 #define PROP_PRESOLTIMING SCIP_PRESOLTIMING_EXHAUSTIVE /* timing of the presolving method (fast, medium, or exhaustive) */
41 #define PROP_PRESOL_MAXROUNDS -1 /**< maximal number of presolving rounds the presolver participates in (-1: no
42  * limit) */
43 #define MAXDNOM 10000LL /**< maximal denominator for simple rational fixed values */
44 
45 
46 /* @todo check for restricting the maximal number of implications that can be added by probing */
47 
48 /* sorting of probing variables, two different variants are implemeneted */
49 /* #define VARIANT_B */
50 
51 
52 /*
53  * Default parameter settings
54  */
55 
56 #define DEFAULT_MAXRUNS 1 /**< maximal number of runs, probing participates in (-1: no limit) */
57 #define DEFAULT_PROPROUNDS -1 /**< maximal number of propagation rounds in probing subproblems */
58 #define DEFAULT_MAXFIXINGS 25 /**< maximal number of fixings found, until probing is interrupted
59  * (0: don't interrupt) */
60 #define DEFAULT_MAXUSELESS 1000 /**< maximal number of successive probings without fixings,
61  * until probing is aborted (0: don't abort) */
62 #define DEFAULT_MAXTOTALUSELESS 50 /**< maximal number of successive probings without fixings, bound changes,
63  * and implications, until probing is aborted (0: don't abort) */
64 #define DEFAULT_MAXSUMUSELESS 0 /**< maximal number of probings without fixings, until probing is aborted
65  * (0: don't abort) */
66 #define DEFAULT_MAXDEPTH -1 /**< maximal depth until propagation is executed(-1: no limit) */
67 #define DEFAULT_RANDSEED 59 /**< random initial seed */
68 
69 /*
70  * Data structures
71  */
72 
73 /** propagator data */
74 struct SCIP_PropData
75 {
76  SCIP_VAR** sortedvars; /**< problem variables sorted by number of rounding locks, used in presolving */
77  int* nprobed; /**< array of numbers how often we already probed on each variables */
78  int noldtotalvars; /**< number of total variables in problem */
79  int nsortedvars; /**< number of problem variables, used in presolving */
80  int nsortedbinvars; /**< number of binary problem variables, used in presolving */
81  int maxruns; /**< maximal number of runs, probing participates in (-1: no limit) */
82  int proprounds; /**< maximal number of propagation rounds in probing subproblems */
83  int maxfixings; /**< maximal number of fixings found, until probing is interrupted
84  * (0: don't interrupt) */
85  int maxuseless; /**< maximal number of successive probings without fixings,
86  * until probing is aborted (0: don't abort) */
87  int maxtotaluseless; /**< maximal number of successive probings without fixings, bound changes,
88  * and implications, until probing is aborted (0: don't abort) */
89  int maxsumuseless; /**< maximal number of probings without fixings, until probing is aborted
90  * (0: don't abort) */
91  int startidx; /**< starting variable index of next call, used in presolving */
92  int lastsortstartidx; /**< last starting variable index where the variables have been sorted, used in presolving */
93  int nfixings; /**< total number of fixings found in probing */
94  int naggregations; /**< total number of aggregations found in probing */
95  int nimplications; /**< total number of implications found in probing */
96  int nbdchgs; /**< total number of bound changes found in probing */
97  int nuseless; /**< current number of successive useless probings */
98  int ntotaluseless; /**< current number of successive totally useless probings */
99  int nsumuseless; /**< current number of useless probings */
100  int maxdepth; /**< maximal depth until propagation is executed */
101  SCIP_Longint lastnode; /**< last node where probing was applied, or -1 for presolving, and -2 for not applied yet */
102  SCIP_RANDNUMGEN* randnumgen; /**< random number generator */
103 };
104 
105 
106 /*
107  * Local methods
108  */
109 /** initializes the propagator data */
110 static
112  SCIP* scip, /**< SCIP data structure */
113  SCIP_PROPDATA* propdata /**< propagator data */
114  )
115 {
116  assert(propdata != NULL);
118  propdata->sortedvars = NULL;
119  propdata->nprobed = NULL;
120  propdata->noldtotalvars = 0;
121  propdata->nsortedvars = 0;
122  propdata->nsortedbinvars = 0;
123  propdata->startidx = 0;
124  propdata->lastsortstartidx = -1;
125  propdata->nfixings = 0;
126  propdata->naggregations = 0;
127  propdata->nimplications = 0;
128  propdata->nbdchgs = 0;
129  propdata->nuseless = 0;
130  propdata->ntotaluseless = 0;
131  propdata->nsumuseless = 0;
132  propdata->lastnode = -2;
133  propdata->randnumgen = NULL;
134 
135  return SCIP_OKAY;
136 }
137 
138 /** frees the sorted vars array */
139 static
141  SCIP* scip, /**< SCIP data structure */
142  SCIP_PROPDATA* propdata /**< propagator data */
143  )
144 {
145  assert(propdata != NULL);
147  if( propdata->sortedvars != NULL )
148  {
149  int i;
150 
151  /* release variables */
152  for( i = 0; i < propdata->nsortedvars; ++i )
153  {
154  SCIP_CALL( SCIPreleaseVar(scip, &propdata->sortedvars[i]) );
155  }
156  SCIPfreeMemoryArray(scip, &propdata->sortedvars);
157  propdata->nsortedvars = 0;
158  propdata->nsortedbinvars = 0;
159  }
160 
161  SCIPfreeMemoryArrayNull(scip, &propdata->nprobed);
162  propdata->noldtotalvars = 0;
163 
164  return SCIP_OKAY;
165 }
166 
167 /** sorts the binary variables starting with the given index by rounding locks and implications */
168 static
170  SCIP* scip, /**< SCIP data structure */
171  SCIP_PROPDATA* propdata, /**< propagator data */
172  SCIP_VAR** vars, /**< problem variables to be sorted */
173  int nvars, /**< number of problem variables to be sorted */
174  int firstidx /**< first index that should be subject to sorting */
175  )
176 {
177  SCIP_VAR** sortedvars;
178  int nsortedvars;
179  SCIP_Real* scores;
180  int i;
181  int minnprobings;
182  SCIP_Real maxscore;
183  int nlocksdown;
184  int nlocksup;
185  int nimplzero;
186  int nimplone;
187  int nclqzero;
188  int nclqone;
189 
190  assert(propdata != NULL);
191  assert(propdata->nprobed != NULL);
192 
193  assert(vars != NULL || nvars == 0);
194 
195  nsortedvars = nvars - firstidx;
196  if( nsortedvars <= 0 )
197  return SCIP_OKAY;
198 
199  assert(vars != NULL);
200 
201  sortedvars = &(vars[firstidx]);
202 
203  SCIPdebugMsg(scip, "resorting probing variables %d to %d\n", firstidx, nvars-1);
204 
205  /* sort the variables by number of rounding locks and implications */
206  SCIP_CALL( SCIPallocBufferArray(scip, &scores, nsortedvars) );
207 
208  maxscore = -1.0;
209  minnprobings = INT_MAX;
210 
211  /* determine maximal possible score and minimal number of probings over all variables */
212  for( i = 0; i < nvars; ++i )
213  {
214  SCIP_VAR* var;
215  SCIP_Real tmp;
216 
217  var = vars[i];
218 
219  assert(SCIPvarIsBinary(var));
220  assert(propdata->noldtotalvars > SCIPvarGetIndex(var));
221  assert(propdata->nprobed[SCIPvarGetIndex(var)] >= 0);
222 
223  if( SCIPvarIsActive(var) )
224  {
225  nlocksdown = SCIPvarGetNLocksDown(var);
226  nlocksup = SCIPvarGetNLocksUp(var);
227  nimplzero = SCIPvarGetNImpls(var, FALSE);
228  nimplone = SCIPvarGetNImpls(var, TRUE);
229  nclqzero = SCIPvarGetNCliques(var, FALSE);
230  nclqone = SCIPvarGetNCliques(var, TRUE);
231 
232 #ifndef VARIANT_B
233  tmp = -MAX(nlocksdown, nlocksup)
234  + 10.0 * MIN(nimplzero, nimplone)
235  + 100.0 * MIN(nclqzero, nclqone);
236 #else
237  tmp = - ABS(nlocksdown - nlocksup)
238  + MIN(nlocksdown, nlocksup)
239  + 500.0 * nimplzero + 50.0 * nimplone
240  + 50000.0 * nclqzero + 5000.0 * nclqone;
241 #endif
242 
243  if( tmp > maxscore )
244  maxscore = tmp;
245  if( propdata->nprobed[SCIPvarGetIndex(var)] < minnprobings )
246  minnprobings = propdata->nprobed[SCIPvarGetIndex(var)];
247  }
248  }
249 
250  /* correct number of probings on each variable by minimal number of probings */
251  if( minnprobings > 0 )
252  {
253  for( i = 0; i < nvars; ++i )
254  {
255  SCIP_VAR* var;
256 
257  var = vars[i];
258 
259  if( SCIPvarIsActive(var) )
260  propdata->nprobed[SCIPvarGetIndex(var)] -= minnprobings;
261  }
262  }
263 
264  for( i = 0; i < nsortedvars; ++i )
265  {
266  SCIP_VAR* var;
267  var = sortedvars[i];
268 
269  assert(SCIPvarIsBinary(var));
270 
271  /* prefer variables that we did not already probe on */
272  if( SCIPvarIsActive(var) )
273  {
274  SCIP_Real randomoffset;
275  nlocksdown = SCIPvarGetNLocksDown(var);
276  nlocksup = SCIPvarGetNLocksUp(var);
277  nimplzero = SCIPvarGetNImpls(var, FALSE);
278  nimplone = SCIPvarGetNImpls(var, TRUE);
279  nclqzero = SCIPvarGetNCliques(var, FALSE);
280  nclqone = SCIPvarGetNCliques(var, TRUE);
281 
282  assert(propdata->noldtotalvars > SCIPvarGetIndex(var));
283  assert(propdata->nprobed[SCIPvarGetIndex(var)] >= 0);
284 
285  /* use a random offset to break possible ties arbitrarily */
286  randomoffset = SCIPrandomGetReal(propdata->randnumgen, 0.0, 0.5);
287 
288 #ifndef VARIANT_B
289  scores[i] = -maxscore * propdata->nprobed[SCIPvarGetIndex(var)]
290  - MAX(nlocksdown, nlocksup)
291  + 10.0 * MIN(nimplzero, nimplone)
292  + 100.0 * MIN(nclqzero, nclqone) /*lint !e790*/
293  - randomoffset; /* to break ties randomly */
294 #else
295  scores[i] = -maxscore * propdata->nprobed[SCIPvarGetIndex(var)]
296  - ABS(nlocksdown - nlocksup)
297  + MIN(nlocksdown, nlocksup)
298  + 500.0 * nimplzero + 50.0 * nimplone /*lint !e790*/
299  + 50000.0 * nclqzero + 5000.0 * nclqone /*lint !e790*/
300  - randomoffset; /* to break ties randomly */
301 #endif
302  }
303  else
304  scores[i] = -SCIPinfinity(scip);
305  }
306 
307  SCIPsortDownRealPtr(scores, (void**) sortedvars, nsortedvars);
308 
309  SCIPfreeBufferArray(scip, &scores);
310 
311  return SCIP_OKAY;
312 }
313 
314 /** the main probing loop */
315 static
317  SCIP* scip, /**< SCIP data structure */
318  SCIP_PROPDATA* propdata, /**< propagator data */
319  SCIP_VAR** vars, /**< problem variables */
320  int nvars, /**< number of problem variables */
321  int nbinvars, /**< number of binary variables */
322  int* startidx, /**< pointer to store starting variable index of next call */
323  int* nfixedvars, /**< pointer to store number of fixed variables */
324  int* naggrvars, /**< pointer to store number of aggregated variables */
325  int* nchgbds, /**< pointer to store number of changed bounds */
326  int oldnfixedvars, /**< number of previously fixed variables */
327  int oldnaggrvars, /**< number of previously aggregated variables */
328  SCIP_Bool* delay, /**< pointer to store whether propagator should be delayed */
329  SCIP_Bool* cutoff /**< pointer to store whether cutoff occured */
330  )
331 {
332  SCIP_Real* zeroimpllbs;
333  SCIP_Real* zeroimplubs;
334  SCIP_Real* zeroproplbs;
335  SCIP_Real* zeropropubs;
336  SCIP_Real* oneimpllbs;
337  SCIP_Real* oneimplubs;
338  SCIP_Real* oneproplbs;
339  SCIP_Real* onepropubs;
340  int localnfixedvars;
341  int localnaggrvars;
342  int localnchgbds;
343  int localnimplications;
344  int maxfixings;
345  int maxuseless;
346  int maxtotaluseless;
347  int maxsumuseless;
348  int i;
349  int oldstartidx;
350  SCIP_Bool aborted;
351  SCIP_Bool looped;
352 
353  assert(vars != NULL);
354  assert(nbinvars > 0);
355 
356  maxfixings = (propdata->maxfixings > 0 ? propdata->maxfixings : INT_MAX);
357  maxuseless = (propdata->maxuseless > 0 ? propdata->maxuseless : INT_MAX);
358  maxtotaluseless = (propdata->maxtotaluseless > 0 ? propdata->maxtotaluseless : INT_MAX);
359  maxsumuseless = (propdata->maxsumuseless > 0 ? propdata->maxsumuseless : INT_MAX);
360  aborted = FALSE;
361  looped = FALSE;
362  oldstartidx = *startidx;
363  i = *startidx;
364 
365  /* get temporary memory for storing probing results */
366  SCIP_CALL( SCIPallocBufferArray(scip, &zeroimpllbs, nvars) );
367  SCIP_CALL( SCIPallocBufferArray(scip, &zeroimplubs, nvars) );
368  SCIP_CALL( SCIPallocBufferArray(scip, &zeroproplbs, nvars) );
369  SCIP_CALL( SCIPallocBufferArray(scip, &zeropropubs, nvars) );
370  SCIP_CALL( SCIPallocBufferArray(scip, &oneimpllbs, nvars) );
371  SCIP_CALL( SCIPallocBufferArray(scip, &oneimplubs, nvars) );
372  SCIP_CALL( SCIPallocBufferArray(scip, &oneproplbs, nvars) );
373  SCIP_CALL( SCIPallocBufferArray(scip, &onepropubs, nvars) );
374 
375  /* for each binary variable, probe fixing the variable to zero and one */
376  *delay = FALSE;
377  *cutoff = FALSE;
378  do
379  {
380  for( ; i < nbinvars && !(*cutoff); ++i )
381  {
382  SCIP_Bool localcutoff;
383  SCIP_Bool probingzero;
384  SCIP_Bool probingone;
385 
386  /* check whether probing should be aborted */
387  if( propdata->nuseless >= maxuseless || propdata->ntotaluseless >= maxtotaluseless || propdata->nsumuseless >= maxsumuseless || SCIPisStopped(scip) )
388  {
390  " (%.1fs) probing: %d/%d (%.1f%%) - %d fixings, %d aggregations, %d implications, %d bound changes\n",
391  SCIPgetSolvingTime(scip), i+1, nbinvars, 100.0*(SCIP_Real)(i+1)/(SCIP_Real)nbinvars,
392  propdata->nfixings, propdata->naggregations, propdata->nimplications, propdata->nbdchgs);
393 
394  aborted = TRUE;
395 
396  if( propdata->nuseless >= maxuseless )
397  {
399  " (%.1fs) probing aborted: %d/%d successive useless probings\n", SCIPgetSolvingTime(scip),
400  propdata->nuseless, maxuseless);
401  }
402  else if( propdata->ntotaluseless >= maxtotaluseless )
403  {
405  " (%.1fs) probing aborted: %d/%d successive totally useless probings\n", SCIPgetSolvingTime(scip),
406  propdata->ntotaluseless, maxtotaluseless);
407  }
408  else if( propdata->nsumuseless >= maxsumuseless )
409  {
411  " (%.1fs) probing aborted: %d/%d useless probings in total\n", SCIPgetSolvingTime(scip),
412  propdata->nsumuseless, maxsumuseless);
413  }
414  else
415  {
416  assert(SCIPisStopped(scip));
418  " (%.1fs) probing aborted: solving stopped\n", SCIPgetSolvingTime(scip));
419  }
420  break;
421  }
422 
423  /* check if we already fixed enough variables for this round, or probed on all variables */
424  if( *nfixedvars - oldnfixedvars + *naggrvars - oldnaggrvars >= maxfixings || (looped && oldstartidx == i) )
425  {
426  if( *nfixedvars - oldnfixedvars + *naggrvars - oldnaggrvars > 0 )
427  *delay = TRUE;
428  else
429  aborted = TRUE;
430  break;
431  }
432 
433  /* display probing status */
434  if( SCIPgetStage(scip) == SCIP_STAGE_PRESOLVING && (i+1) % 100 == 0 )
435  {
436  SCIP_VERBLEVEL verblevel;
437 
438  verblevel = ((i+1) % 1000 == 0 ? SCIP_VERBLEVEL_HIGH : SCIP_VERBLEVEL_FULL);
439  SCIPverbMessage(scip, verblevel, NULL,
440  " (%.1fs) probing: %d/%d (%.1f%%) - %d fixings, %d aggregations, %d implications, %d bound changes\n",
441  SCIPgetSolvingTime(scip), i+1, nbinvars, 100.0*(SCIP_Real)(i+1)/(SCIP_Real)nbinvars,
442  propdata->nfixings, propdata->naggregations, propdata->nimplications, propdata->nbdchgs);
443  }
444 
445  /* ignore variables, that were fixed, aggregated, or deleted in prior probings */
446  if( !SCIPvarIsActive(vars[i]) || SCIPvarIsDeleted(vars[i])
447  || SCIPvarGetLbLocal(vars[i]) > 0.5 || SCIPvarGetUbLocal(vars[i]) < 0.5 )
448  continue;
449 
450  if( propdata->nuseless > 0 )
451  propdata->nsumuseless++;
452  else
453  propdata->nsumuseless = MAX(propdata->nsumuseless-1, 0);
454  propdata->nuseless++;
455  propdata->ntotaluseless++;
456 
457  /* determine whether one probing should happen */
458  probingone = TRUE;
459  if( SCIPvarGetNLocksUp(vars[i]) == 0 )
460  probingone = FALSE;
461 
462  if( probingone )
463  {
464  /* apply probing for fixing the variable to one */
465  SCIP_CALL( SCIPapplyProbingVar(scip, vars, nvars, i, SCIP_BOUNDTYPE_LOWER, 1.0, propdata->proprounds,
466  oneimpllbs, oneimplubs, oneproplbs, onepropubs, &localcutoff) );
467 
468  if( localcutoff )
469  {
470  SCIP_Bool fixed;
471 
473  {
474  /* the variable can be fixed to FALSE */
475  SCIP_CALL( SCIPfixVar(scip, vars[i], 0.0, cutoff, &fixed) );
476  assert(fixed);
477  }
478  else
479  {
480  SCIP_CALL( SCIPtightenVarUb(scip, vars[i], 0.0, TRUE, cutoff, &fixed) );
481  }
482 
483  if( fixed )
484  {
485  SCIPdebugMsg(scip, "fixed probing variable <%s> to 0.0, nlocks=(%d/%d)\n",
486  SCIPvarGetName(vars[i]), SCIPvarGetNLocksDown(vars[i]), SCIPvarGetNLocksUp(vars[i]));
487  (*nfixedvars)++;
488  propdata->nfixings++;
489  propdata->nuseless = 0;
490  propdata->ntotaluseless = 0;
491  }
492  else if( *cutoff )
493  {
494  SCIPdebugMsg(scip, "tightening upper bound of probing variable <%s> to 0.0 led to a cutoff\n",
495  SCIPvarGetName(vars[i]));
496  }
497  continue; /* don't try downwards direction, because the variable is already fixed */
498  }
499 
500  /* ignore variables, that were fixed, aggregated, or deleted in prior probings
501  * (propagators in one-probe might have found global fixings but did not trigger the localcutoff)
502  */
503  if( !SCIPvarIsActive(vars[i]) || SCIPvarIsDeleted(vars[i])
504  || SCIPvarGetLbLocal(vars[i]) > 0.5 || SCIPvarGetUbLocal(vars[i]) < 0.5 )
505  continue;
506  }
507 
508  /* determine whether zero probing should happen */
509  probingzero = TRUE;
510  if( SCIPvarGetNLocksDown(vars[i]) == 0 )
511  probingzero = FALSE;
512 
513  if( probingzero )
514  {
515  /* apply probing for fixing the variable to zero */
516  SCIP_CALL( SCIPapplyProbingVar(scip, vars, nvars, i, SCIP_BOUNDTYPE_UPPER, 0.0, propdata->proprounds,
517  zeroimpllbs, zeroimplubs, zeroproplbs, zeropropubs, &localcutoff) );
518 
519  if( localcutoff )
520  {
521  SCIP_Bool fixed;
522 
524  {
525  /* the variable can be fixed to TRUE */
526  SCIP_CALL( SCIPfixVar(scip, vars[i], 1.0, cutoff, &fixed) );
527  }
528  else
529  {
530  SCIP_CALL( SCIPtightenVarLb(scip, vars[i], 1.0, TRUE, cutoff, &fixed) );
531  }
532 
533  if( fixed )
534  {
535  SCIPdebugMsg(scip, "fixed probing variable <%s> to 1.0, nlocks=(%d/%d)\n",
536  SCIPvarGetName(vars[i]), SCIPvarGetNLocksDown(vars[i]), SCIPvarGetNLocksUp(vars[i]));
537  (*nfixedvars)++;
538  propdata->nfixings++;
539  propdata->nuseless = 0;
540  propdata->ntotaluseless = 0;
541  }
542  else if( *cutoff )
543  {
544  SCIPdebugMsg(scip, "tightening lower bound of probing variable <%s> to 1.0 led to a cutoff\n",
545  SCIPvarGetName(vars[i]));
546  }
547  continue; /* don't analyze probing deductions, because the variable is already fixed */
548  }
549  }
550 
551  /* not have to check deductions if only one probing direction has been checked */
552  if( !probingzero || !probingone )
553  continue;
554 
555  assert(propdata->noldtotalvars > SCIPvarGetIndex(vars[i]));
556 
557  /* count number of probings on each variable */
558  propdata->nprobed[SCIPvarGetIndex(vars[i])] += 1;
559 
560  /* analyze probing deductions */
561  localnfixedvars = 0;
562  localnaggrvars = 0;
563  localnimplications = 0;
564  localnchgbds = 0;
565  SCIP_CALL( SCIPanalyzeDeductionsProbing(scip, vars[i], 0.0, 1.0,
566  nvars, vars, zeroimpllbs, zeroimplubs, zeroproplbs, zeropropubs, oneimpllbs, oneimplubs, oneproplbs, onepropubs,
567  &localnfixedvars, &localnaggrvars, &localnimplications, &localnchgbds, cutoff) );
568 
569  *nfixedvars += localnfixedvars;
570  *naggrvars += localnaggrvars;
571  *nchgbds += localnchgbds;
572  propdata->nfixings += localnfixedvars;
573  propdata->naggregations += localnaggrvars;
574  propdata->nbdchgs += localnchgbds;
575  propdata->nimplications += localnimplications;
576 
577  if( localnfixedvars > 0 || localnaggrvars > 0 )
578  {
579  SCIPdebugMsg(scip, "probing on <%s> led to %d fixed and %d aggregated variables\n", SCIPvarGetName(vars[i]), localnfixedvars, localnaggrvars);
580  propdata->nuseless = 0;
581  propdata->ntotaluseless = 0;
582  }
583  if( localnimplications > 0 || localnchgbds > 0 )
584  propdata->ntotaluseless = 0;
585  }
586 
587  looped = TRUE;
588 
589  /* check if we reached the end of all binary variables but did not stop, so we start from the beginning */
590  if( i == nbinvars && !(*cutoff) && !(*delay) && !aborted )
591  {
593  " (%.1fs) probing cycle finished: starting next cycle\n", SCIPgetSolvingTime(scip));
594  i = 0;
595 
596  if( SCIPgetStage(scip) == SCIP_STAGE_PRESOLVING )
597  {
598  int nnewvars;
599  int nnewbinvars;
600  int nnewintvars;
601  int nnewimplvars;
602  int lastidx;
603  int v;
604 
605  assert(vars == propdata->sortedvars);
606  assert(nbinvars == propdata->nsortedbinvars);
607 
608  /* release old variables and free memory */
609  for( v = propdata->nsortedvars - 1; v >= 0; --v )
610  {
611  SCIP_CALL( SCIPreleaseVar(scip, &propdata->sortedvars[v]) );
612  }
613  SCIPfreeMemoryArray(scip, &propdata->sortedvars);
614  propdata->nsortedvars = 0;
615  propdata->nsortedbinvars = 0;
616 
617  /* get new variables */
618  nnewvars = SCIPgetNVars(scip);
619  SCIP_CALL( SCIPduplicateMemoryArray(scip, &(propdata->sortedvars), SCIPgetVars(scip), nnewvars) );
620  propdata->nsortedvars = nnewvars;
621 
622  nnewbinvars = SCIPgetNBinVars(scip);
623  nnewintvars = SCIPgetNIntVars(scip);
624  nnewimplvars = SCIPgetNImplVars(scip);
625 
626  /* determine implicit binary variables */
627  lastidx = nnewbinvars + nnewintvars + nnewimplvars;
628  for( v = nnewbinvars; v < lastidx; ++v )
629  {
630  if( SCIPvarIsBinary(propdata->sortedvars[v]) )
631  {
632  SCIPswapPointers((void**) &(propdata->sortedvars[nnewbinvars]), (void**) &(propdata->sortedvars[v]));
633  ++nnewbinvars;
634  }
635  }
636  propdata->nsortedbinvars = nnewbinvars;
637 
638  nbinvars = nnewbinvars;
639  vars = propdata->sortedvars;
640  nvars = propdata->nsortedvars;
641 
642  SCIP_CALL( SCIPreallocBufferArray(scip, &zeroimpllbs, nvars) );
643  SCIP_CALL( SCIPreallocBufferArray(scip, &zeroimplubs, nvars) );
644  SCIP_CALL( SCIPreallocBufferArray(scip, &zeroproplbs, nvars) );
645  SCIP_CALL( SCIPreallocBufferArray(scip, &zeropropubs, nvars) );
646  SCIP_CALL( SCIPreallocBufferArray(scip, &oneimpllbs, nvars) );
647  SCIP_CALL( SCIPreallocBufferArray(scip, &oneimplubs, nvars) );
648  SCIP_CALL( SCIPreallocBufferArray(scip, &oneproplbs, nvars) );
649  SCIP_CALL( SCIPreallocBufferArray(scip, &onepropubs, nvars) );
650 
651  /* correct oldstartidx which is used for early termination */
652  if( oldstartidx >= nbinvars )
653  oldstartidx = nbinvars - 1;
654 
655  /* capture variables to make sure, the variables are not deleted */
656  for( v = propdata->nsortedvars - 1; v >= 0; --v )
657  {
658  SCIP_CALL( SCIPcaptureVar(scip, propdata->sortedvars[v]) );
659  }
660 
661  if( nnewbinvars == 0 )
662  {
663  *startidx = 0;
664  propdata->lastsortstartidx = -1;
665  propdata->nuseless = 0;
666  propdata->ntotaluseless = 0;
667 
668  goto TERMINATE;
669  }
670 
671  /* resorting here might lead to probing a second time on the same variable */
672  SCIP_CALL( sortVariables(scip, propdata, propdata->sortedvars, propdata->nsortedbinvars, 0) );
673  propdata->lastsortstartidx = 0;
674  }
675  }
676 
677  }
678  while( i == 0 && !(*cutoff) && !(*delay) && !aborted );
679 
680  *startidx = i;
681 
682  TERMINATE:
683  /* free temporary memory */
684  SCIPfreeBufferArray(scip, &onepropubs);
685  SCIPfreeBufferArray(scip, &oneproplbs);
686  SCIPfreeBufferArray(scip, &oneimplubs);
687  SCIPfreeBufferArray(scip, &oneimpllbs);
688  SCIPfreeBufferArray(scip, &zeropropubs);
689  SCIPfreeBufferArray(scip, &zeroproplbs);
690  SCIPfreeBufferArray(scip, &zeroimplubs);
691  SCIPfreeBufferArray(scip, &zeroimpllbs);
692 
693  return SCIP_OKAY;
694 }
695 
696 
697 /*
698  * Callback methods of propagator
699  */
700 
701 /** copy method for constraint handler plugins (called when SCIP copies plugins) */
702 static
703 SCIP_DECL_PROPCOPY(propCopyProbing)
704 { /*lint --e{715}*/
705  assert(scip != NULL);
706  assert(prop != NULL);
707  assert(strcmp(SCIPpropGetName(prop), PROP_NAME) == 0);
708 
709  /* call inclusion method for propagator */
711 
712  return SCIP_OKAY;
713 }
714 
715 
716 /** destructor of propagator to free user data (called when SCIP is exiting) */
717 static
718 SCIP_DECL_PROPFREE(propFreeProbing)
719 { /*lint --e{715}*/
720  SCIP_PROPDATA* propdata;
721 
722  /* free propagator data */
723  propdata = SCIPpropGetData(prop);
724  assert(propdata != NULL);
725  assert(propdata->sortedvars == NULL);
726  assert(propdata->nsortedvars == 0);
727  assert(propdata->nsortedbinvars == 0);
728 
729 
730  SCIPfreeBlockMemory(scip, &propdata);
731  SCIPpropSetData(prop, NULL);
732 
733  return SCIP_OKAY;
734 }
735 
736 
737 /** initialization method of propagator (called after problem was transformed) */
738 static
739 SCIP_DECL_PROPINIT(propInitProbing)
740 { /*lint --e{715}*/
741  SCIP_PROPDATA* propdata;
742 
743  propdata = SCIPpropGetData(prop);
744  assert(propdata != NULL);
746  SCIP_CALL( initPropdata(scip, propdata) );
747 
748  /* create random number generator */
749  SCIP_CALL( SCIPrandomCreate(&propdata->randnumgen, SCIPblkmem(scip),
751 
752 
753  return SCIP_OKAY;
754 }
755 
756 
757 /** deinitialization method of propagator (called before transformed problem is freed) */
758 static
759 SCIP_DECL_PROPEXIT(propExitProbing)
760 { /*lint --e{715}*/
761  SCIP_PROPDATA* propdata;
762 
763  propdata = SCIPpropGetData(prop);
764  assert(propdata != NULL);
766  SCIP_CALL( freeSortedvars(scip, propdata) );
767  assert(propdata->sortedvars == NULL);
768  assert(propdata->nsortedvars == 0);
769  assert(propdata->nsortedbinvars == 0);
770 
771  /* free random number generator */
772  SCIPrandomFree(&propdata->randnumgen);
773 
774  return SCIP_OKAY;
775 }
776 
777 /** presolving initialization method of propagator (called when presolving is about to begin) */
778 static
779 SCIP_DECL_PROPINITPRE(propInitpreProbing)
780 { /*lint --e{715}*/
781  SCIP_PROPDATA* propdata;
782 
783  propdata = SCIPpropGetData(prop);
784  assert(propdata != NULL);
786  propdata->lastnode = -2;
787 
788  return SCIP_OKAY;
789 }
790 
791 
792 /** presolving deinitialization method of propagator (called after presolving has been finished) */
793 static
794 SCIP_DECL_PROPEXITPRE(propExitpreProbing)
795 { /*lint --e{715}*/
796  SCIP_PROPDATA* propdata;
797 
798  propdata = SCIPpropGetData(prop);
799  assert(propdata != NULL);
801  /* delete the vars array, if the maximal number of runs are exceeded */
802  if( propdata->maxruns >= 0 && SCIPgetNRuns(scip) >= propdata->maxruns )
803  {
804  SCIP_CALL( freeSortedvars(scip, propdata) );
805  assert(propdata->sortedvars == NULL);
806  assert(propdata->nsortedvars == 0);
807  assert(propdata->nsortedbinvars == 0);
808  }
809 
810  return SCIP_OKAY;
811 }
812 
813 
814 /** solving process initialization method of propagator (called when branch and bound process is about to begin) */
815 static
816 SCIP_DECL_PROPINITSOL(propInitsolProbing)
817 {
818  /*lint --e{715}*/
819  SCIP_PROPDATA* propdata;
820 
821  propdata = SCIPpropGetData(prop);
822  assert(propdata != NULL);
823 
824  /* reset all propdata elements for stopping propagation earlier */
825  propdata->nuseless = 0;
826  propdata->ntotaluseless = 0;
827  propdata->nsumuseless = 0;
828 
829  return SCIP_OKAY;
830 }
831 
832 
833 /** presolve method of propagator */
834 static
835 SCIP_DECL_PROPPRESOL(propPresolProbing)
836 { /*lint --e{715}*/
837  SCIP_PROPDATA* propdata;
838  int nvars;
839  int nbinvars;
840  int nintvars;
841  int nimplvars;
842  int oldnfixedvars;
843  int oldnaggrvars;
844  int oldnchgbds;
845  int oldnimplications;
846  int ntotalvars;
847  SCIP_Bool delay;
848  SCIP_Bool cutoff;
849 
850  assert(result != NULL);
851 
852  *result = SCIP_DIDNOTRUN;
853 
854  nbinvars = SCIPgetNBinVars(scip);
855  nintvars = SCIPgetNIntVars(scip);
856  nimplvars = SCIPgetNImplVars(scip);
857 
858  /* if we have no binary variable anymore, we stop probing */
859  if( nbinvars + nintvars + nimplvars == 0 )
860  return SCIP_OKAY;
861 
862  /* get propagator data */
863  propdata = SCIPpropGetData(prop);
864  assert(propdata != NULL);
865 
866  /* check, if probing should be applied in the current run */
867  if( propdata->maxruns >= 0 && SCIPgetNRuns(scip) > propdata->maxruns )
868  return SCIP_OKAY;
869 
870  /* if no domains changed since the last call, we don't need to probe */
871  if( propdata->lastnode == -1 && nnewfixedvars == 0 && nnewaggrvars == 0 && nnewchgbds == 0 && nnewholes == 0 )
872  return SCIP_OKAY;
873 
874  SCIPdebugMsg(scip, "executing probing (used %.1f sec)\n", SCIPpropGetTime(prop));
875 
876  *result = SCIP_DIDNOTFIND;
877 
878  /* allow some additional probings */
879  propdata->nuseless -= propdata->nuseless/10;
880  propdata->ntotaluseless -= propdata->ntotaluseless/10;
881 
882  /* get variable data */
883  if( propdata->sortedvars == NULL )
884  {
885  int lastidx;
886  int v;
887 
888  assert(propdata->startidx == 0);
889 
890  nvars = SCIPgetNVars(scip);
891 
892  SCIP_CALL( SCIPduplicateMemoryArray(scip, &(propdata->sortedvars), SCIPgetVars(scip), nvars) );
893  propdata->nsortedvars = nvars;
894 
895  /* determine implicit binary variables */
896  lastidx = nbinvars + nintvars + nimplvars;
897  for( v = nbinvars; v < lastidx; ++v )
898  {
899  if( SCIPvarIsBinary(propdata->sortedvars[v]) )
900  {
901  SCIPswapPointers((void**) &(propdata->sortedvars[nbinvars]), (void**) &(propdata->sortedvars[v]));
902  ++nbinvars;
903  }
904  }
905  propdata->nsortedbinvars = nbinvars;
906 
907  /* capture variables to make sure, the variables are not deleted */
908  for( v = propdata->nsortedvars - 1; v >= 0 ; --v )
909  {
910  SCIP_CALL( SCIPcaptureVar(scip, propdata->sortedvars[v]) );
911  }
912  }
913 
914  if( propdata->nsortedbinvars == 0 )
915  return SCIP_OKAY;
916 
917  /* number of total variables is not decreasing, and we can identify every variable by their index, so allocate
918  * enough space
919  */
920  ntotalvars = SCIPgetNTotalVars(scip);
921  if( propdata->noldtotalvars < ntotalvars )
922  {
923  SCIP_CALL( SCIPreallocMemoryArray(scip, &propdata->nprobed, ntotalvars) );
924  BMSclearMemoryArray(&(propdata->nprobed[propdata->noldtotalvars]), ntotalvars - propdata->noldtotalvars); /*lint !e866*/
925  propdata->noldtotalvars = ntotalvars;
926  }
927 
928  propdata->lastnode = -1;
929 
930  /* sort the binary variables by number of rounding locks, if at least 100 variables were probed since last sort */
931  if( propdata->lastsortstartidx < 0 || propdata->startidx - propdata->lastsortstartidx >= 100 )
932  {
933  SCIP_CALL( sortVariables(scip, propdata, propdata->sortedvars, propdata->nsortedbinvars, propdata->startidx) );
934  propdata->lastsortstartidx = propdata->startidx;
935  }
936 
937  oldnfixedvars = *nfixedvars;
938  oldnaggrvars = *naggrvars;
939  oldnchgbds = *nchgbds;
940  oldnimplications = propdata->nimplications;
941 
942  /* start probing on variables */
943  SCIP_CALL( applyProbing(scip, propdata, propdata->sortedvars, propdata->nsortedvars, propdata->nsortedbinvars,
944  &(propdata->startidx), nfixedvars, naggrvars, nchgbds, oldnfixedvars, oldnaggrvars, &delay, &cutoff) );
945 
946  /* adjust result code */
947  if( cutoff )
948  *result = SCIP_CUTOFF;
949  else
950  {
951  if( delay )
952  {
953  /* probing was interrupted because it reached the maximal fixings parameter, so we want to rerun it at the next call */
954  propdata->lastnode = -2;
955  }
956 
957  if( *nfixedvars > oldnfixedvars || *naggrvars > oldnaggrvars || *nchgbds > oldnchgbds
958  || propdata->nimplications > oldnimplications )
959  *result = SCIP_SUCCESS;
960  }
961 
962  return SCIP_OKAY;
963 }
964 
965 
966 /** execution method of propagator */
967 static
968 SCIP_DECL_PROPEXEC(propExecProbing)
969 { /*lint --e{715}*/
970  SCIP_PROPDATA* propdata;
971  SCIP_VAR** vars;
972  SCIP_VAR** binvars;
973  int nvars;
974  int nbinvars;
975  int i;
976  int nfixedvars;
977  int naggrvars;
978  int nchgbds;
979  int oldnfixedvars;
980  int oldnaggrvars;
981  int oldnchgbds;
982  int oldnimplications;
983  int startidx;
984  int ntotalvars;
985  SCIP_Bool delay;
986  SCIP_Bool cutoff;
987 
988  assert(result != NULL);
989 
990  *result = SCIP_DIDNOTRUN;
991 
992  /* avoid recursive infinity loop */
993  if( SCIPinProbing(scip) )
994  return SCIP_OKAY;
995 
996  /* only call propagation on branching candidates, if an optimal LP solution is at hand */
998  return SCIP_OKAY;
999 
1000  /* get propagator data */
1001  propdata = SCIPpropGetData(prop);
1002  assert(propdata != NULL);
1003 
1004  /* if already called stop */
1005  if( propdata->lastnode == SCIPnodeGetNumber(SCIPgetCurrentNode(scip)) )
1006  return SCIP_OKAY;
1007 
1008  /* if maximal depth for propagation is reached, stop */
1009  if( propdata->maxdepth >= 0 && propdata->maxdepth < SCIPgetDepth(scip) )
1010  return SCIP_OKAY;
1011 
1012  propdata->lastnode = SCIPnodeGetNumber(SCIPgetCurrentNode(scip));
1013 
1014  /* get (number of) fractional variables that should be integral */
1015  /* todo check if integrating fractional implicit integer variables is beneficial for probing */
1016  SCIP_CALL( SCIPgetLPBranchCands(scip, &vars, NULL, NULL, &nvars, NULL, NULL) );
1017  nbinvars = 0;
1018 
1019  /* alloc array for fractional binary variables */
1020  SCIP_CALL( SCIPallocBufferArray(scip, &binvars, nvars) );
1021 
1022  /* copy binary variables to array binvars */
1023  for( i = 0; i < nvars; ++i )
1024  {
1025  SCIP_VAR* var;
1026  var = vars[i];
1027 
1028  assert(var != NULL);
1029  if( SCIPvarIsBinary(var) )
1030  {
1031  assert(SCIPvarGetLbLocal(var) < 0.5);
1032  assert(SCIPvarGetUbLocal(var) > 0.5);
1033 
1034  binvars[nbinvars] = var;
1035  ++nbinvars;
1036  }
1037  }
1038  SCIPdebugMsg(scip, "problem <%s> node %" SCIP_LONGINT_FORMAT " probing propagation found %d of %d possible probing candidates\n", SCIPgetProbName(scip), SCIPnodeGetNumber(SCIPgetCurrentNode(scip)), nbinvars, nvars);
1039 
1040  if( nbinvars == 0 )
1041  {
1042  *result = SCIP_DIDNOTFIND;
1043  goto TERMINATE;
1044  }
1045 
1046  /* number of total variables is not decreasing, and we can identify every variable by their index, so allocate
1047  * enough space
1048  */
1049  ntotalvars = SCIPgetNTotalVars(scip);
1050  if( propdata->noldtotalvars < ntotalvars )
1051  {
1052  SCIP_CALL( SCIPreallocMemoryArray(scip, &propdata->nprobed, ntotalvars) );
1053  BMSclearMemoryArray(&(propdata->nprobed[propdata->noldtotalvars]), ntotalvars - propdata->noldtotalvars); /*lint !e866*/
1054  propdata->noldtotalvars = ntotalvars;
1055  }
1056 
1057  /* sort binary variables */
1058  SCIP_CALL( sortVariables(scip, propdata, binvars, nbinvars, 0) );
1059 
1060  oldnfixedvars = 0;
1061  oldnaggrvars = 0;
1062  oldnchgbds = 0;
1063  nfixedvars = 0;
1064  naggrvars = 0;
1065  nchgbds = 0;
1066  startidx = 0;
1067  SCIPdebug( oldnimplications = propdata->nimplications; )
1068 
1069  /* start probing on found variables */
1070  SCIP_CALL( applyProbing(scip, propdata, binvars, nbinvars, nbinvars, &startidx, &nfixedvars, &naggrvars, &nchgbds, oldnfixedvars, oldnaggrvars, &delay, &cutoff) );
1071  SCIPdebugMsg(scip, "probing propagation found %d fixings, %d aggregation, %d nchgbds, and %d implications\n", nfixedvars, naggrvars, nchgbds, (propdata->nimplications) - oldnimplications);
1072 
1073  if( delay )
1074  {
1075  /* probing was interrupted because it reached the maximal fixings parameter, so we want to rerun it at the next call */
1076  propdata->lastnode = -2;
1077  }
1078 
1079  /* adjust result code */
1080  if( cutoff )
1081  *result = SCIP_CUTOFF;
1082  else if( nfixedvars > oldnfixedvars || naggrvars > oldnaggrvars || nchgbds > oldnchgbds )
1083  *result = SCIP_REDUCEDDOM;
1084 
1085  TERMINATE:
1086  SCIPfreeBufferArray(scip, &binvars);
1087 
1088  return SCIP_OKAY;
1089 }
1090 
1091 
1092 /** propagation conflict resolving method of propagator */
1093 static
1094 SCIP_DECL_PROPRESPROP(propRespropProbing)
1095 { /*lint --e{715}*/
1096  *result = SCIP_DIDNOTRUN;
1097 
1098  return SCIP_OKAY;
1099 }
1101 
1102 /*
1103  * propagator specific interface methods
1104  */
1105 
1106 /** creates the probing propagator and includes it in SCIP */
1108  SCIP* scip /**< SCIP data structure */
1109  )
1110 {
1111  SCIP_PROPDATA* propdata;
1112  SCIP_PROP* prop;
1114  /* create probing propagator data */
1115  SCIP_CALL( SCIPallocBlockMemory(scip, &propdata) );
1116  SCIP_CALL( initPropdata(scip, propdata) );
1117 
1118  /* include propagator */
1120  propExecProbing, propdata) );
1121 
1122  assert(prop != NULL);
1123 
1124  /* set optional callbacks via setter functions */
1125  SCIP_CALL( SCIPsetPropCopy(scip, prop, propCopyProbing) );
1126  SCIP_CALL( SCIPsetPropFree(scip, prop, propFreeProbing) );
1127  SCIP_CALL( SCIPsetPropInit(scip, prop, propInitProbing) );
1128  SCIP_CALL( SCIPsetPropExit(scip, prop, propExitProbing) );
1129  SCIP_CALL( SCIPsetPropInitsol(scip, prop, propInitsolProbing) );
1130  SCIP_CALL( SCIPsetPropInitpre(scip, prop, propInitpreProbing) );
1131  SCIP_CALL( SCIPsetPropExitpre(scip, prop, propExitpreProbing) );
1132  SCIP_CALL( SCIPsetPropPresol(scip, prop, propPresolProbing, PROP_PRESOL_PRIORITY, PROP_PRESOL_MAXROUNDS,
1133  PROP_PRESOLTIMING) );
1134  SCIP_CALL( SCIPsetPropResprop(scip, prop, propRespropProbing) );
1135 
1136  /* add probing propagator parameters */
1137  SCIP_CALL( SCIPaddIntParam(scip,
1138  "propagating/" PROP_NAME "/maxruns",
1139  "maximal number of runs, probing participates in (-1: no limit)",
1140  &propdata->maxruns, FALSE, DEFAULT_MAXRUNS, -1, INT_MAX, NULL, NULL) );
1141  SCIP_CALL( SCIPaddIntParam(scip,
1142  "propagating/" PROP_NAME "/proprounds",
1143  "maximal number of propagation rounds in probing subproblems (-1: no limit, 0: auto)",
1144  &propdata->proprounds, TRUE, DEFAULT_PROPROUNDS, -1, INT_MAX, NULL, NULL) );
1145  SCIP_CALL( SCIPaddIntParam(scip,
1146  "propagating/" PROP_NAME "/maxfixings",
1147  "maximal number of fixings found, until probing is interrupted (0: don't iterrupt)",
1148  &propdata->maxfixings, TRUE, DEFAULT_MAXFIXINGS, 0, INT_MAX, NULL, NULL) );
1149  SCIP_CALL( SCIPaddIntParam(scip,
1150  "propagating/" PROP_NAME "/maxuseless",
1151  "maximal number of successive probings without fixings, until probing is aborted (0: don't abort)",
1152  &propdata->maxuseless, TRUE, DEFAULT_MAXUSELESS, 0, INT_MAX, NULL, NULL) );
1153  SCIP_CALL( SCIPaddIntParam(scip,
1154  "propagating/" PROP_NAME "/maxtotaluseless",
1155  "maximal number of successive probings without fixings, bound changes, and implications, until probing is aborted (0: don't abort)",
1156  &propdata->maxtotaluseless, TRUE, DEFAULT_MAXTOTALUSELESS, 0, INT_MAX, NULL, NULL) );
1157  SCIP_CALL( SCIPaddIntParam(scip,
1158  "propagating/" PROP_NAME "/maxsumuseless",
1159  "maximal number of probings without fixings, until probing is aborted (0: don't abort)",
1160  &propdata->maxsumuseless, TRUE, DEFAULT_MAXSUMUSELESS, 0, INT_MAX, NULL, NULL) );
1161  SCIP_CALL( SCIPaddIntParam(scip,
1162  "propagating/" PROP_NAME "/maxdepth",
1163  "maximal depth until propagation is executed(-1: no limit)",
1164  &propdata->maxdepth, TRUE, DEFAULT_MAXDEPTH, -1, INT_MAX, NULL, NULL) );
1165 
1166  return SCIP_OKAY;
1167 }
1168 
1169 
1170 /** applies and evaluates probing of a single variable in the given direction and bound */
1172  SCIP* scip, /**< SCIP data structure */
1173  SCIP_VAR** vars, /**< problem variables */
1174  int nvars, /**< number of problem variables */
1175  int probingpos, /**< variable number to apply probing on */
1176  SCIP_BOUNDTYPE boundtype, /**< which bound should be changed */
1177  SCIP_Real bound, /**< which bound should be set */
1178  int maxproprounds, /**< maximal number of propagation rounds (-1: no limit, 0: parameter settings) */
1179  SCIP_Real* impllbs, /**< array to store lower bounds after applying implications and cliques */
1180  SCIP_Real* implubs, /**< array to store upper bounds after applying implications and cliques */
1181  SCIP_Real* proplbs, /**< array to store lower bounds after full propagation */
1182  SCIP_Real* propubs, /**< array to store upper bounds after full propagation */
1183  SCIP_Bool* cutoff /**< pointer to store whether the probing direction is infeasible */
1184  )
1185 {
1186  assert(impllbs != NULL);
1187  assert(implubs != NULL);
1188  assert(proplbs != NULL);
1189  assert(propubs != NULL);
1190  assert(cutoff != NULL);
1191  assert(0 <= probingpos && probingpos < nvars);
1192  assert(SCIPisGE(scip, bound, SCIPvarGetLbLocal(vars[probingpos])));
1193  assert(SCIPisLE(scip, bound, SCIPvarGetUbLocal(vars[probingpos])));
1194 
1195  SCIPdebugMsg(scip, "applying probing on variable <%s> %s %g (nlocks=%d/%d, impls=%d/%d, clqs=%d/%d)\n",
1196  SCIPvarGetName(vars[probingpos]), boundtype == SCIP_BOUNDTYPE_UPPER ? "<=" : ">=", bound,
1197  SCIPvarGetNLocksDown(vars[probingpos]), SCIPvarGetNLocksUp(vars[probingpos]),
1198  SCIPvarGetNImpls(vars[probingpos], FALSE), SCIPvarGetNImpls(vars[probingpos], TRUE),
1199  SCIPvarGetNCliques(vars[probingpos], FALSE), SCIPvarGetNCliques(vars[probingpos], TRUE));
1200 
1201  /* in debug mode we assert above that this trivial infeasibility does not occur (for performance reasons), but in
1202  * optimized mode we return safely
1203  */
1204  if( SCIPisLT(scip, bound, SCIPvarGetLbLocal(vars[probingpos]))
1205  || SCIPisGT(scip, bound, SCIPvarGetUbLocal(vars[probingpos])) )
1206  {
1207  SCIPdebugMsg(scip, " -> trivial infeasibility detected\n");
1208  *cutoff = TRUE;
1209  return SCIP_OKAY;
1210  }
1211 
1212  /* start probing mode */
1213  SCIP_CALL( SCIPstartProbing(scip) );
1214 
1215  /* enables collection of variable statistics during probing */
1216  SCIPenableVarHistory(scip);
1217 
1218  /* fix variable */
1219  if( boundtype == SCIP_BOUNDTYPE_UPPER )
1220  {
1221  SCIP_CALL( SCIPchgVarUbProbing(scip, vars[probingpos], bound) );
1222  }
1223  else
1224  {
1225  assert(boundtype == SCIP_BOUNDTYPE_LOWER);
1226  SCIP_CALL( SCIPchgVarLbProbing(scip, vars[probingpos], bound) );
1227  }
1228 
1229  /* @todo it might pay off to catch the bounds-tightened event on all variables and then only get the implied and
1230  * propagated bounds on those variables which where really changed on propagation
1231  */
1232 
1233  /* apply propagation of implication graph and clique table */
1235  if( !(*cutoff) )
1236  {
1237  int i;
1238 
1239  for( i = 0; i < nvars; ++i )
1240  {
1241  impllbs[i] = SCIPvarGetLbLocal(vars[i]);
1242  implubs[i] = SCIPvarGetUbLocal(vars[i]);
1243  }
1244 
1245  /* apply propagation */
1246  SCIP_CALL( SCIPpropagateProbing(scip, maxproprounds, cutoff, NULL) );
1247  }
1248  else
1249  {
1250  SCIPdebugMsg(scip, "propagating probing implications after <%s> to %g led to a cutoff\n",
1251  SCIPvarGetName(vars[probingpos]), bound);
1252  }
1253 
1254  /* evaluate propagation */
1255  if( !(*cutoff) )
1256  {
1257  int i;
1258 
1259  for( i = 0; i < nvars; ++i )
1260  {
1261  proplbs[i] = SCIPvarGetLbLocal(vars[i]);
1262  propubs[i] = SCIPvarGetUbLocal(vars[i]);
1263 #if 0
1264 #ifdef SCIP_DEBUG
1265  if( SCIPisGT(scip, proplbs[i], SCIPvarGetLbGlobal(vars[i])) )
1266  {
1267  SCIPdebugMsg(scip, " -> <%s>[%g,%g] >= %g\n", SCIPvarGetName(vars[i]),
1268  SCIPvarGetLbGlobal(vars[i]), SCIPvarGetUbGlobal(vars[i]), proplbs[i]);
1269  }
1270  if( SCIPisLT(scip, propubs[i], SCIPvarGetUbGlobal(vars[i])) )
1271  {
1272  SCIPdebugMsg(scip, " -> <%s>[%g,%g] <= %g\n", SCIPvarGetName(vars[i]),
1273  SCIPvarGetLbGlobal(vars[i]), SCIPvarGetUbGlobal(vars[i]), propubs[i]);
1274  }
1275 #endif
1276 #endif
1277  }
1278  }
1279 
1280  /* exit probing mode */
1281  SCIP_CALL( SCIPendProbing(scip) );
1282 
1283  return SCIP_OKAY;
1284 }
1285 
1286 /** analyses boundchanges resulting from probing on a variable and performs deduced fixations, aggregations, and domain tightenings
1287  * Given a variable probingvar with domain [l,u] and bound tightening results from reducing the domain
1288  * once to [l,leftub] and once to [rightlb,u], the method computes and applies resulting variable fixations, aggregations,
1289  * implications, and bound changes. Variable probingvar does not need to be binary.
1290  * The whole domain of probingvar need to be covered by the left and right branches, i.e.,
1291  * we assume leftub >= rightlb for continuous variables or floor(leftub) >= ceil(rightlb)-1 for discrete variables.
1292  * Bounds after applying implications and cliques do not need to be provided, but if they are omitted and probingvar is a binary variable,
1293  * then already existing implications may be added.
1294  */
1296  SCIP* scip, /**< SCIP data structure */
1297  SCIP_VAR* probingvar, /**< the probing variable */
1298  SCIP_Real leftub, /**< upper bound of probing variable in left branch */
1299  SCIP_Real rightlb, /**< lower bound of probing variable in right branch */
1300  int nvars, /**< number of variables which bound changes should be analyzed */
1301  SCIP_VAR** vars, /**< variables which bound changes should be analyzed */
1302  SCIP_Real* leftimpllbs, /**< lower bounds after applying implications and cliques in left branch, or NULL */
1303  SCIP_Real* leftimplubs, /**< upper bounds after applying implications and cliques in left branch, or NULL */
1304  SCIP_Real* leftproplbs, /**< lower bounds after applying domain propagation in left branch */
1305  SCIP_Real* leftpropubs, /**< upper bounds after applying domain propagation in left branch */
1306  SCIP_Real* rightimpllbs, /**< lower bounds after applying implications and cliques in right branch, or NULL */
1307  SCIP_Real* rightimplubs, /**< upper bounds after applying implications and cliques in right branch, or NULL */
1308  SCIP_Real* rightproplbs, /**< lower bounds after applying domain propagation in right branch */
1309  SCIP_Real* rightpropubs, /**< upper bounds after applying domain propagation in right branch */
1310  int* nfixedvars, /**< pointer to counter which is increased by the number of deduced variable fixations */
1311  int* naggrvars, /**< pointer to counter which is increased by the number of deduced variable aggregations */
1312  int* nimplications, /**< pointer to counter which is increased by the number of deduced implications */
1313  int* nchgbds, /**< pointer to counter which is increased by the number of deduced bound tightenings */
1314  SCIP_Bool* cutoff /**< buffer to store whether a cutoff is detected */
1315  )
1316 {
1317  SCIP_Bool fixedleft;
1318  SCIP_Bool fixedright;
1319  SCIP_Bool probingvarisbinary;
1320  SCIP_Bool probingvarisinteger;
1321  int j;
1322 
1323  assert(scip != NULL);
1324  assert(probingvar != NULL);
1325  assert(SCIPisGE(scip, leftub, SCIPvarGetLbLocal(probingvar))); /* left branch should not be empty by default */
1326  assert(SCIPisLE(scip, rightlb, SCIPvarGetUbLocal(probingvar))); /* right branch should not be empty by default */
1327  assert(vars != NULL || nvars == 0);
1328  assert(leftproplbs != NULL);
1329  assert(leftpropubs != NULL);
1330  assert(rightproplbs != NULL);
1331  assert(rightpropubs != NULL);
1332  assert(nfixedvars != NULL);
1333  assert(naggrvars != NULL);
1334  assert(nimplications != NULL);
1335  assert(nchgbds != NULL);
1336  assert(cutoff != NULL);
1337 
1338  /* @todo the asserts below could be relaxed by taking domain holes into account */
1339  if( SCIPvarGetType(probingvar) != SCIP_VARTYPE_CONTINUOUS )
1340  {
1341  /* adjust bounds to actually used ones */
1342  leftub = SCIPfloor(scip, leftub);
1343  rightlb = SCIPceil(scip, rightlb);
1344 
1345  probingvarisinteger = TRUE;
1346  probingvarisbinary = SCIPvarIsBinary(probingvar);
1347  }
1348  else
1349  {
1350  /* assert dichotomy in case of continuous var: leftub >= rightlb */
1351  assert(SCIPisGE(scip, leftub, rightlb));
1352  probingvarisbinary = FALSE;
1353  probingvarisinteger = FALSE;
1354  }
1355 
1356  /* check if probing variable was fixed in the branches */
1357  fixedleft = SCIPisEQ(scip, SCIPvarGetLbLocal(probingvar), leftub);
1358  fixedright = SCIPisEQ(scip, SCIPvarGetUbLocal(probingvar), rightlb);
1359 
1360  *cutoff = FALSE;
1361 
1362  for( j = 0; j < nvars && !*cutoff; ++j )
1363  {
1364  SCIP_VAR* var;
1365  SCIP_Bool varisinteger;
1366  SCIP_Real newlb;
1367  SCIP_Real newub;
1368 
1369  assert(vars != NULL); /* for flexelint */
1370 
1371  var = vars[j];
1372  assert(var != NULL);
1373 
1374  /* @todo: add holes, and even add holes if x was the probing variable and it followed a better bound on x itself */
1375  /* @todo: check if we probed on an integer variable, that this maybe led to aggregation on two other variables, i.e
1376  * probing on x <= 1 and x >= 2 led to y = 1, z = 1 and y = 0, z = 0 resp., which means y = Z
1377  */
1378 
1379  /* if probing variable is binary, then there is nothing we could deduce here (variable should be fixed in both branches)
1380  * if it is not binary, we want to see if we found bound tightenings, even though it seems quite unlikely */
1381  if( var == probingvar && probingvarisbinary )
1382  continue;
1383 
1384  /* new bounds of the variable is the union of the propagated bounds of the left and right case */
1385  newlb = MIN(leftproplbs[j], rightproplbs[j]);
1386  newub = MAX(leftpropubs[j], rightpropubs[j]);
1387  varisinteger = (SCIPvarGetType(var) < SCIP_VARTYPE_CONTINUOUS);
1388 
1389  /* check for fixed variables */
1390  if( SCIPisEQ(scip, newlb, newub) )
1391  {
1392  SCIP_Real fixval;
1393  SCIP_Bool fixed;
1394 
1395  if( !varisinteger )
1396  {
1397  /* in both probings, variable j is deduced to the same value: fix variable to this value */
1398  fixval = SCIPselectSimpleValue(newlb - 0.9 * SCIPepsilon(scip), newub + 0.9 * SCIPepsilon(scip), MAXDNOM);
1399  }
1400  else
1401  {
1402  fixval = newlb;
1403  }
1404 
1406  {
1407  SCIP_CALL( SCIPfixVar(scip, var, fixval, cutoff, &fixed) );
1408  }
1409  else
1410  {
1411  SCIP_CALL( SCIPtightenVarLb(scip, var, fixval, TRUE, cutoff, &fixed) );
1412  if( !*cutoff )
1413  {
1414  SCIP_Bool tightened;
1415 
1416  SCIP_CALL( SCIPtightenVarUb(scip, var, fixval, TRUE, cutoff, &tightened) );
1417  fixed &= tightened;
1418  }
1419  }
1420 
1421  if( fixed )
1422  {
1423  SCIPdebugMsg(scip, "fixed variable <%s> to %g due to probing on <%s> with nlocks=(%d/%d)\n",
1424  SCIPvarGetName(var), fixval,
1425  SCIPvarGetName(probingvar), SCIPvarGetNLocksDown(probingvar), SCIPvarGetNLocksUp(probingvar));
1426  (*nfixedvars)++;
1427  }
1428  else if( *cutoff )
1429  {
1430  SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible fixing of variable <%s> to %g\n",
1431  SCIPvarGetName(probingvar), SCIPvarGetName(var), fixval);
1432  }
1433 
1434  continue;
1435  }
1436  else
1437  {
1438  /* check for bound tightenings */
1439  SCIP_Real oldlb;
1440  SCIP_Real oldub;
1441  SCIP_Bool tightened;
1442  SCIP_Bool tightenlb;
1443  SCIP_Bool tightenub;
1444  SCIP_Bool force;
1445 
1446  oldlb = SCIPvarGetLbLocal(var);
1447  oldub = SCIPvarGetUbLocal(var);
1448 
1449  if( varisinteger )
1450  {
1451  force = TRUE;
1452  tightenlb = (newlb > oldlb + 0.5);
1453  tightenub = (newub < oldub - 0.5);
1454  }
1455  else
1456  {
1457  force = TRUE;
1458  tightenlb = SCIPisLbBetter(scip, newlb, oldlb, oldub);
1459  tightenub = SCIPisUbBetter(scip, newub, oldlb, oldub);
1460  }
1461 
1462  if( tightenlb )
1463  {
1464  /* in both probings, variable j is deduced to be at least newlb: tighten lower bound */
1465  SCIP_CALL( SCIPtightenVarLb(scip, var, newlb, force, cutoff, &tightened) );
1466  if( tightened )
1467  {
1468  SCIPdebugMsg(scip, "tightened lower bound of variable <%s>[%g,%g] to %g due to probing on <%s> with nlocks=(%d/%d)\n",
1469  SCIPvarGetName(var), oldlb, oldub, newlb,
1470  SCIPvarGetName(probingvar), SCIPvarGetNLocksDown(probingvar), SCIPvarGetNLocksUp(probingvar));
1471  (*nchgbds)++;
1472  }
1473  else if( *cutoff )
1474  {
1475  SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible new lower bound of variable <%s> to %g\n",
1476  SCIPvarGetName(probingvar), SCIPvarGetName(var), newlb);
1477  }
1478  }
1479 
1480  if( tightenub && !*cutoff )
1481  {
1482  /* in both probings, variable j is deduced to be at most newub: tighten upper bound */
1483  SCIP_CALL( SCIPtightenVarUb(scip, var, newub, force, cutoff, &tightened) );
1484  if( tightened )
1485  {
1486  SCIPdebugMsg(scip, "tightened upper bound of variable <%s>[%g,%g] to %g due to probing on <%s> with nlocks=(%d/%d)\n",
1487  SCIPvarGetName(var), oldlb, oldub, newub,
1488  SCIPvarGetName(probingvar), SCIPvarGetNLocksDown(probingvar), SCIPvarGetNLocksUp(probingvar));
1489  (*nchgbds)++;
1490  }
1491  else if( *cutoff )
1492  {
1493  SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible new lower bound of variable <%s> to %g\n",
1494  SCIPvarGetName(probingvar), SCIPvarGetName(var), newub);
1495  }
1496  }
1497  if( *cutoff )
1498  break;
1499  }
1500 
1501  /* below we add aggregations and implications between probingvar and var,
1502  * we don't want this if both variables are the same
1503  */
1504  if( var == probingvar )
1505  continue;
1506 
1507  /* check for aggregations and implications */
1508  if( fixedleft && fixedright &&
1509  SCIPisEQ(scip, leftproplbs[j], leftpropubs[j]) && SCIPisEQ(scip, rightproplbs[j], rightpropubs[j]) )
1510  {
1511  /* var is fixed whenever probingvar is fixed, i.e.,
1512  * var = leftproplbs[j] + (rightproplbs[j] - leftproplbs[j]) / (rightlb - leftub) * (probingvar - leftub)
1513  * -> both variables can be aggregated:
1514  * (rightlb - leftub) * (var - leftproplbs[j]) = (rightproplbs[j] - leftproplbs[j]) * (probingvar - leftub)
1515  * -> (rightlb - leftub) * var - (rightproplbs[j] - leftproplbs[j]) * probingvar = leftproplbs[j] * rightlb - rightproplbs[j] * leftub
1516  *
1517  * check for case where both variables are binary: leftub = 1, rightlb = 0
1518  * case leftproplbs[j] = 0, rightproplbs[j] = 1, i.e., var and probingvar are fixed to same value
1519  * -> aggregation is 1 * var - 1 * probingvar = 0 * 1 - 1 * 0 = 0 -> correct
1520  * case leftproplbs[j] = 1, rightproblbs[j] = 0, i.e., var and probingvar are fixed to opposite values
1521  * -> aggregation is 1 * var + 1 * probingvar = 1 * 1 - 0 * 0 = 0 -> correct
1522  */
1523  if( SCIPgetStage(scip) == SCIP_STAGE_PRESOLVING )
1524  {
1525  SCIP_Bool aggregated;
1526  SCIP_Bool redundant;
1527 
1528  SCIP_CALL( SCIPaggregateVars(scip, var, probingvar,
1529  rightlb - leftub, -(rightproplbs[j] - leftproplbs[j]), leftproplbs[j] * rightlb - rightproplbs[j] * leftub,
1530  cutoff, &redundant, &aggregated) );
1531 
1532  if( aggregated )
1533  {
1534  SCIPdebugMsg(scip, "aggregated variables %g<%s> - %g<%s> == %g, nlocks=(%d/%d)\n",
1535  rightlb - leftub, SCIPvarGetName(var),
1536  rightproplbs[j] - leftproplbs[j], SCIPvarGetName(probingvar),
1537  leftproplbs[j] * rightlb - rightproplbs[j] * leftub,
1538  SCIPvarGetNLocksDown(var), SCIPvarGetNLocksUp(probingvar));
1539  (*naggrvars)++;
1540  }
1541  if( *cutoff )
1542  {
1543  SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible aggregation: %g<%s> - %g<%s> == %g\n",
1544  SCIPvarGetName(probingvar), rightlb - leftub, SCIPvarGetName(var),
1545  rightproplbs[j] - leftproplbs[j], SCIPvarGetName(probingvar),
1546  leftproplbs[j] * rightlb - rightproplbs[j] * leftub);
1547  }
1548  }
1549  else if( probingvarisinteger && SCIPnodeGetDepth(SCIPgetCurrentNode(scip)) == 0 )
1550  {
1551  /* if we are not in presolving, then we cannot do aggregations
1552  * but we can use variable bounds to code the same equality
1553  * var == ((leftproplbs[j] * rightlb - rightproplbs[j] * leftub) + (rightproplbs[j] - leftproplbs[j]) * probingvar) / (rightlb - leftub)
1554  */
1555  int nboundchanges;
1556 
1557  assert(!SCIPisEQ(scip, leftub, rightlb));
1558 
1559  SCIP_CALL( SCIPaddVarVlb(scip, var, probingvar, (rightproplbs[j] - leftproplbs[j]) / (rightlb - leftub), (leftproplbs[j] * rightlb - rightproplbs[j] * leftub) / (rightlb - leftub), cutoff, &nboundchanges) );
1560  (*nchgbds) += nboundchanges;
1561 
1562  if( *cutoff )
1563  {
1564  SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible vlb: %g<%s> - %g<%s> == %g\n",
1565  SCIPvarGetName(probingvar), rightlb - leftub, SCIPvarGetName(var),
1566  rightproplbs[j] - leftproplbs[j], SCIPvarGetName(probingvar),
1567  leftproplbs[j] * rightlb - rightproplbs[j] * leftub);
1568  }
1569  else
1570  {
1571  SCIP_CALL( SCIPaddVarVub(scip, var, probingvar, (rightproplbs[j] - leftproplbs[j]) / (rightlb - leftub), (leftproplbs[j] * rightlb - rightproplbs[j] * leftub) / (rightlb - leftub), cutoff, &nboundchanges) );
1572  (*nchgbds) += nboundchanges;
1573 
1574  if( *cutoff )
1575  {
1576  SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible vub: %g<%s> - %g<%s> == %g\n",
1577  SCIPvarGetName(probingvar), rightlb - leftub, SCIPvarGetName(var),
1578  rightproplbs[j] - leftproplbs[j], SCIPvarGetName(probingvar),
1579  leftproplbs[j] * rightlb - rightproplbs[j] * leftub);
1580  }
1581  }
1582  (*nimplications)++;
1583  }
1584  /* if probingvar is continuous and we are in solving stage, then we do nothing, but it's unlikely that we get
1585  * here (fixedleft && fixedright) with a continuous variable
1586  */
1587  }
1588  /* @todo: check if we can add variable lowerbounds/upperbounds on integer variables */
1589  /* can only add implications on binary variables which are globally valid */
1590  else if( probingvarisbinary && (SCIPgetStage(scip) != SCIP_STAGE_SOLVING || SCIPnodeGetDepth(SCIPgetCurrentNode(scip)) == 0) )
1591  {
1592  /* implications can be added only for binary variables */
1593  int nboundchanges;
1594 
1595  /* since probing var is binary variable, probing should have fixed variable in both branches,
1596  * which is to 0.0 in the left branch and to 1.0 in the right branch */
1597  assert(fixedleft);
1598  assert(fixedright);
1599  assert(SCIPisZero(scip, leftub));
1600  assert(SCIPisEQ(scip, rightlb, 1.0));
1601 
1602  if( SCIPisEQ(scip, newlb, leftpropubs[j]) && (leftimplubs == NULL || leftimplubs[j] > leftpropubs[j]) )
1603  {
1604  /* var is fixed to lower bound whenever probingvar is fixed to 0.0
1605  * and implication is not already known
1606  * -> insert implication: probingvar == 0 => var <= leftpropubs[j]
1607  */
1608  /*SCIPdebugMsg(scip, "found implication <%s> == 0 => <%s> == %g\n",
1609  SCIPvarGetName(probingvar), SCIPvarGetName(var), leftpropubs[j]);*/
1610  SCIP_CALL( SCIPaddVarImplication(scip, probingvar, FALSE, var, SCIP_BOUNDTYPE_UPPER, leftpropubs[j],
1611  cutoff, &nboundchanges) );
1612  (*nimplications)++;
1613  (*nchgbds) += nboundchanges;
1614 
1615  if( *cutoff )
1616  {
1617  SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible implication <%s> == 0 => <%s> == %g\n",
1618  SCIPvarGetName(probingvar), SCIPvarGetName(probingvar), SCIPvarGetName(var), leftpropubs[j]);
1619  }
1620  }
1621  else if( SCIPisEQ(scip, newub, leftproplbs[j]) && (leftimpllbs == NULL || leftimpllbs[j] < leftproplbs[j]) )
1622  {
1623  /* var is fixed to upper bound whenever probingvar is fixed to 0.0
1624  * and implication is not already known
1625  * -> insert implication: probingvar == 0 => var >= leftproplbs[j]
1626  */
1627  /*SCIPdebugMsg(scip, "found implication <%s> == 0 => <%s> == %g\n",
1628  SCIPvarGetName(probingvar), SCIPvarGetName(var), leftproplbs[j]);*/
1629  SCIP_CALL( SCIPaddVarImplication(scip, probingvar, FALSE, var, SCIP_BOUNDTYPE_LOWER, leftproplbs[j],
1630  cutoff, &nboundchanges) );
1631  (*nimplications)++;
1632  (*nchgbds) += nboundchanges;
1633 
1634  if( *cutoff )
1635  {
1636  SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible implication <%s> == 0 => <%s> == %g\n",
1637  SCIPvarGetName(probingvar), SCIPvarGetName(probingvar), SCIPvarGetName(var), leftproplbs[j]);
1638  }
1639  }
1640  /* we can do an else here, since the case where var is fixed for both fixings of probingvar had been handled as aggregation */
1641  else if( SCIPisEQ(scip, newlb, rightpropubs[j]) && (rightimplubs == NULL || rightimplubs[j] > rightpropubs[j]) )
1642  {
1643  /* var is fixed to lower bound whenever probingvar is fixed to 1.0
1644  * and implication is not already known
1645  * -> insert implication: probingvar == 1 => var <= rightpropubs[j]
1646  */
1647  /*SCIPdebugMsg(scip, "found implication <%s> == 1 => <%s> == %g\n",
1648  SCIPvarGetName(probingvar), SCIPvarGetName(var), rightpropubs[j]);*/
1649  SCIP_CALL( SCIPaddVarImplication(scip, probingvar, TRUE, var, SCIP_BOUNDTYPE_UPPER, rightpropubs[j],
1650  cutoff, &nboundchanges) );
1651  (*nimplications)++;
1652  (*nchgbds) += nboundchanges;
1653 
1654  if( *cutoff )
1655  {
1656  SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible implication <%s> == 1 => <%s> == %g\n",
1657  SCIPvarGetName(probingvar), SCIPvarGetName(probingvar), SCIPvarGetName(var), rightpropubs[j]);
1658  }
1659  }
1660  else if( SCIPisEQ(scip, newub, rightproplbs[j]) && (rightimpllbs == NULL || rightimpllbs[j] < rightproplbs[j]) )
1661  {
1662  /* var is fixed to upper bound whenever probingvar is fixed to 1.0
1663  * and implication is not already known
1664  * -> insert implication: probingvar == 1 => var >= leftproplbs[j]
1665  */
1666  /*SCIPdebugMsg(scip, "found implication <%s> == 1 => <%s> == %g\n",
1667  SCIPvarGetName(probingvar), SCIPvarGetName(var), rightproplbs[j]);*/
1668  SCIP_CALL( SCIPaddVarImplication(scip, probingvar, TRUE, var, SCIP_BOUNDTYPE_LOWER, rightproplbs[j],
1669  cutoff, &nboundchanges) );
1670  (*nimplications)++;
1671  (*nchgbds) += nboundchanges;
1672 
1673  if( *cutoff )
1674  {
1675  SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible implication <%s> == 1 => <%s> == %g\n",
1676  SCIPvarGetName(probingvar), SCIPvarGetName(probingvar), SCIPvarGetName(var), rightproplbs[j]);
1677  }
1678  }
1679  else if( SCIPvarGetType(var) != SCIP_VARTYPE_BINARY )
1680  {
1681  /* check for implications for lower or upper bounds (only store implications with bounds tightened at least by 0.5)
1682  * in case of binary variables, this should have been handled in the previous cases, since every boundchange also fixes the variable
1683  */
1684  if( leftpropubs[j] < newub - 0.5 && (leftimplubs == NULL || leftpropubs[j] < leftimplubs[j]) )
1685  {
1686  /* insert implication: probingvar == 0 => var <= leftpropubs[j] */
1687  /*SCIPdebugMsg(scip, "found implication <%s> == 0 => <%s>[%g,%g] <= %g\n",
1688  SCIPvarGetName(probingvar), SCIPvarGetName(var), newlb, newub, leftpropubs[j]);*/
1689  SCIP_CALL( SCIPaddVarImplication(scip, probingvar, FALSE, var, SCIP_BOUNDTYPE_UPPER, leftpropubs[j],
1690  cutoff, &nboundchanges) );
1691  (*nimplications)++;
1692  (*nchgbds) += nboundchanges;
1693 
1694  if( *cutoff )
1695  {
1696  SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible implication <%s> == 0 => <%s> <= %g\n",
1697  SCIPvarGetName(probingvar), SCIPvarGetName(probingvar), SCIPvarGetName(var), leftpropubs[j]);
1698  }
1699  }
1700  if( leftproplbs[j] > newlb + 0.5 && (leftimpllbs == NULL || leftproplbs[j] > leftimpllbs[j]) && !*cutoff )
1701  {
1702  /* insert implication: probingvar == 0 => var >= leftproplbs[j] */
1703  /*SCIPdebugMsg(scip, "found implication <%s> == 0 => <%s>[%g,%g] >= %g\n",
1704  SCIPvarGetName(probingvar), SCIPvarGetName(var), newlb, newub, leftproplbs[j]);*/
1705  SCIP_CALL( SCIPaddVarImplication(scip, probingvar, FALSE, var, SCIP_BOUNDTYPE_LOWER, leftproplbs[j],
1706  cutoff, &nboundchanges) );
1707  (*nimplications)++;
1708  (*nchgbds) += nboundchanges;
1709 
1710  if( *cutoff )
1711  {
1712  SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible implication <%s> == 0 => <%s> >= %g\n",
1713  SCIPvarGetName(probingvar), SCIPvarGetName(probingvar), SCIPvarGetName(var), leftproplbs[j]);
1714  }
1715  }
1716  if( rightpropubs[j] < newub - 0.5 && (rightimplubs == NULL || rightpropubs[j] < rightimplubs[j]) && !*cutoff )
1717  {
1718  /* insert implication: probingvar == 1 => var <= rightpropubs[j] */
1719  /*SCIPdebugMsg(scip, "found implication <%s> == 1 => <%s>[%g,%g] <= %g\n",
1720  SCIPvarGetName(probingvar), SCIPvarGetName(var), newlb, newub, rightpropubs[j]);*/
1721  SCIP_CALL( SCIPaddVarImplication(scip, probingvar, TRUE, var, SCIP_BOUNDTYPE_UPPER, rightpropubs[j],
1722  cutoff, &nboundchanges) );
1723  (*nimplications)++;
1724  (*nchgbds) += nboundchanges;
1725 
1726  if( *cutoff )
1727  {
1728  SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible implication <%s> == 1 => <%s> <= %g\n",
1729  SCIPvarGetName(probingvar), SCIPvarGetName(probingvar), SCIPvarGetName(var), rightpropubs[j]);
1730  }
1731  }
1732  if( rightproplbs[j] > newlb + 0.5 && (rightimpllbs == NULL || rightproplbs[j] > rightimpllbs[j]) && !*cutoff )
1733  {
1734  /* insert implication: probingvar == 1 => var >= rightproplbs[j] */
1735  /*SCIPdebugMsg(scip, "found implication <%s> == 1 => <%s>[%g,%g] >= %g\n",
1736  SCIPvarGetName(probingvar), SCIPvarGetName(var), newlb, newub, rightproplbs[j]);*/
1737  SCIP_CALL( SCIPaddVarImplication(scip, probingvar, TRUE, var, SCIP_BOUNDTYPE_LOWER, rightproplbs[j],
1738  cutoff, &nboundchanges) );
1739  (*nimplications)++;
1740  (*nchgbds) += nboundchanges;
1741 
1742  if( *cutoff )
1743  {
1744  SCIPdebugMsg(scip, "analyzing probing deduction of <%s> led to an infeasible implication <%s> == 1 => <%s> <= %g\n",
1745  SCIPvarGetName(probingvar), SCIPvarGetName(probingvar), SCIPvarGetName(var), rightproplbs[j]);
1746  }
1747  }
1748  }
1749  }
1750  }
1751 
1752  return SCIP_OKAY;
1753 }
SCIP_RETCODE SCIPsetPropPresol(SCIP *scip, SCIP_PROP *prop, SCIP_DECL_PROPPRESOL((*proppresol)), int presolpriority, int presolmaxrounds, SCIP_PRESOLTIMING presoltiming)
Definition: scip.c:7738
static SCIP_RETCODE sortVariables(SCIP *scip, SCIP_PROPDATA *propdata, SCIP_VAR **vars, int nvars, int firstidx)
Definition: prop_probing.c:175
SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
Definition: scip.c:36128
#define DEFAULT_MAXSUMUSELESS
Definition: prop_probing.c:69
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
int SCIPgetNIntVars(SCIP *scip)
Definition: scip.c:11721
SCIP_RETCODE SCIPrandomCreate(SCIP_RANDNUMGEN **randnumgen, BMS_BLKMEM *blkmem, unsigned int initialseed)
Definition: misc.c:8693
static SCIP_DECL_PROPEXITPRE(propExitpreProbing)
Definition: prop_probing.c:800
SCIP_Real SCIPgetSolvingTime(SCIP *scip)
Definition: scip.c:45137
SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip.c:22118
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition: scip.c:40453
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip.c:814
#define PROP_PRESOLTIMING
Definition: prop_probing.c:41
static SCIP_DECL_PROPCOPY(propCopyProbing)
Definition: prop_probing.c:709
SCIP_Bool SCIPisUbBetter(SCIP *scip, SCIP_Real newub, SCIP_Real oldlb, SCIP_Real oldub)
Definition: scip.c:46449
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17166
#define PROP_DESC
Definition: prop_probing.c:33
static long bound
static SCIP_DECL_PROPINITSOL(propInitsolProbing)
Definition: prop_probing.c:822
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17222
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:45803
void SCIPsortDownRealPtr(SCIP_Real *realarray, void **ptrarray, int len)
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip.c:18384
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:16732
#define MAXDNOM
Definition: prop_probing.c:45
void SCIPswapPointers(void **pointer1, void **pointer2)
Definition: misc.c:8996
#define FALSE
Definition: def.h:64
#define DEFAULT_MAXUSELESS
Definition: prop_probing.c:63
SCIP_RETCODE SCIPpropagateProbingImplications(SCIP *scip, SCIP_Bool *cutoff)
Definition: scip.c:35583
SCIP_Real SCIPinfinity(SCIP *scip)
Definition: scip.c:45816
#define TRUE
Definition: def.h:63
#define SCIPdebug(x)
Definition: pub_message.h:74
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
enum SCIP_VerbLevel SCIP_VERBLEVEL
Definition: type_message.h:48
#define PROP_FREQ
Definition: prop_probing.c:36
SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip.c:22234
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip.h:21907
SCIP_Real SCIPselectSimpleValue(SCIP_Real lb, SCIP_Real ub, SCIP_Longint maxdnom)
Definition: misc.c:8482
SCIP_RETCODE SCIPchgVarLbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip.c:35220
static SCIP_RETCODE applyProbing(SCIP *scip, SCIP_PROPDATA *propdata, SCIP_VAR **vars, int nvars, int nbinvars, int *startidx, int *nfixedvars, int *naggrvars, int *nchgbds, int oldnfixedvars, int oldnaggrvars, SCIP_Bool *delay, SCIP_Bool *cutoff)
Definition: prop_probing.c:322
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:45751
SCIP_RETCODE SCIPaddVarVlb(SCIP *scip, SCIP_VAR *var, SCIP_VAR *vlbvar, SCIP_Real vlbcoef, SCIP_Real vlbconstant, SCIP_Bool *infeasible, int *nbdchgs)
Definition: scip.c:23568
int SCIPnodeGetDepth(SCIP_NODE *node)
Definition: tree.c:7153
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:21937
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip.h:21890
SCIP_RETCODE SCIPaddVarVub(SCIP *scip, SCIP_VAR *var, SCIP_VAR *vubvar, SCIP_Real vubcoef, SCIP_Real vubconstant, SCIP_Bool *infeasible, int *nbdchgs)
Definition: scip.c:23627
static SCIP_RETCODE freeSortedvars(SCIP *scip, SCIP_PROPDATA *propdata)
Definition: prop_probing.c:146
#define SCIPdebugMsg
Definition: scip.h:451
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip.c:4202
int SCIPvarGetNCliques(SCIP_VAR *var, SCIP_Bool varfixing)
Definition: var.c:17518
SCIP_Real SCIPepsilon(SCIP *scip)
Definition: scip.c:45246
#define DEFAULT_MAXRUNS
Definition: prop_probing.c:58
const char * SCIPgetProbName(SCIP *scip)
Definition: scip.c:10724
#define DEFAULT_MAXDEPTH
Definition: prop_probing.c:72
SCIP_Bool SCIPisLbBetter(SCIP *scip, SCIP_Real newlb, SCIP_Real oldlb, SCIP_Real oldub)
Definition: scip.c:46434
SCIP_Longint SCIPnodeGetNumber(SCIP_NODE *node)
Definition: tree.c:7143
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17176
void SCIPrandomFree(SCIP_RANDNUMGEN **randnumgen)
Definition: misc.c:8710
SCIP_RETCODE SCIPsetPropExitpre(SCIP *scip, SCIP_PROP *prop, SCIP_DECL_PROPEXITPRE((*propexitpre)))
Definition: scip.c:7722
static SCIP_DECL_PROPINIT(propInitProbing)
Definition: prop_probing.c:745
#define DEFAULT_PROPROUNDS
Definition: prop_probing.c:59
static SCIP_DECL_PROPEXIT(propExitProbing)
Definition: prop_probing.c:765
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:45764
SCIP_RETCODE SCIPpropagateProbing(SCIP *scip, int maxproprounds, SCIP_Bool *cutoff, SCIP_Longint *ndomredsfound)
Definition: scip.c:35477
#define DEFAULT_RANDSEED
Definition: prop_probing.c:73
#define DEFAULT_MAXFIXINGS
Definition: prop_probing.c:60
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.c:23687
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip.c:45519
SCIP_RETCODE SCIPendProbing(SCIP *scip)
Definition: scip.c:35187
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16552
#define NULL
Definition: lpi_spx1.cpp:137
#define SCIP_CALL(x)
Definition: def.h:306
int SCIPgetNTotalVars(SCIP *scip)
Definition: scip.c:12208
static SCIP_RETCODE initPropdata(SCIP *scip, SCIP_PROPDATA *propdata)
Definition: prop_probing.c:117
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip.c:1353
static SCIP_DECL_PROPEXEC(propExecProbing)
Definition: prop_probing.c:974
static SCIP_DECL_PROPRESPROP(propRespropProbing)
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:21925
SCIP_RETCODE SCIPsetPropInit(SCIP *scip, SCIP_PROP *prop, SCIP_DECL_PROPINIT((*propinit)))
Definition: scip.c:7642
public data structures and miscellaneous methods
#define SCIP_Bool
Definition: def.h:61
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip.c:28854
int SCIPgetNImplVars(SCIP *scip)
Definition: scip.c:11766
#define SCIPduplicateMemoryArray(scip, ptr, source, num)
Definition: scip.h:21870
#define PROP_PRESOL_MAXROUNDS
Definition: prop_probing.c:42
int SCIPgetDepth(SCIP *scip)
Definition: scip.c:42094
int SCIPvarGetNImpls(SCIP_VAR *var, SCIP_Bool varfixing)
Definition: var.c:17444
int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition: var.c:3217
#define MAX(x, y)
Definition: tclique_def.h:75
static SCIP_RETCODE aggregation(SCIP *scip, SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata, SCIP_SOL *sol, SCIP_Real *varsolvals, SCIP_Real *bestcontlbs, SCIP_Real *bestcontubs, SCIP_Real *contvarscorebounds, SCIP_Real *rowlhsscores, SCIP_Real *rowrhsscores, int startrow, int maxaggrs, SCIP_Real maxslack, int maxconts, SCIP_Bool *wastried, SCIP_Bool *cutoff, int *ncuts)
Definition: sepa_cmir.c:692
unsigned int SCIPinitializeRandomSeed(SCIP *scip, int initialseedvalue)
Definition: scip.c:25467
void SCIPenableVarHistory(SCIP *scip)
Definition: scip.c:25520
SCIP_RETCODE SCIPanalyzeDeductionsProbing(SCIP *scip, SCIP_VAR *probingvar, SCIP_Real leftub, SCIP_Real rightlb, int nvars, SCIP_VAR **vars, SCIP_Real *leftimpllbs, SCIP_Real *leftimplubs, SCIP_Real *leftproplbs, SCIP_Real *leftpropubs, SCIP_Real *rightimpllbs, SCIP_Real *rightimplubs, SCIP_Real *rightproplbs, SCIP_Real *rightpropubs, int *nfixedvars, int *naggrvars, int *nimplications, int *nchgbds, SCIP_Bool *cutoff)
SCIP_RETCODE SCIPsetPropCopy(SCIP *scip, SCIP_PROP *prop, SCIP_DECL_PROPCOPY((*propcopy)))
Definition: scip.c:7610
#define SCIPfreeMemoryArray(scip, ptr)
Definition: scip.h:21874
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition: scip.c:25141
#define SCIPreallocMemoryArray(scip, ptr, newnum)
Definition: scip.h:21864
int SCIPgetNRuns(SCIP *scip)
Definition: scip.c:41099
#define DEFAULT_MAXTOTALUSELESS
Definition: prop_probing.c:66
int SCIPgetNBinVars(SCIP *scip)
Definition: scip.c:11676
SCIP_Real SCIPrandomGetReal(SCIP_RANDNUMGEN *randnumgen, SCIP_Real minrandval, SCIP_Real maxrandval)
Definition: misc.c:8745
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip.c:35033
const char * SCIPpropGetName(SCIP_PROP *prop)
Definition: prop.c:887
int SCIPgetNVars(SCIP *scip)
Definition: scip.c:11631
#define PROP_PRESOL_PRIORITY
Definition: prop_probing.c:40
SCIP_RETCODE SCIPapplyProbingVar(SCIP *scip, SCIP_VAR **vars, int nvars, int probingpos, SCIP_BOUNDTYPE boundtype, SCIP_Real bound, int maxproprounds, SCIP_Real *impllbs, SCIP_Real *implubs, SCIP_Real *proplbs, SCIP_Real *propubs, SCIP_Bool *cutoff)
int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition: var.c:3162
SCIP_RETCODE SCIPsetPropResprop(SCIP *scip, SCIP_PROP *prop, SCIP_DECL_PROPRESPROP((*propresprop)))
Definition: scip.c:7771
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:45790
static SCIP_DECL_PROPFREE(propFreeProbing)
Definition: prop_probing.c:724
probing propagator
#define PROP_NAME
Definition: prop_probing.c:32
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip.c:11586
SCIP_RETCODE SCIPsetPropInitsol(SCIP *scip, SCIP_PROP *prop, SCIP_DECL_PROPINITSOL((*propinitsol)))
Definition: scip.c:7674
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.c:25250
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:18350
#define SCIP_Real
Definition: def.h:135
struct SCIP_PropData SCIP_PROPDATA
Definition: type_prop.h:38
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip.c:1138
#define MIN(x, y)
Definition: memory.c:75
SCIP_RETCODE SCIPincludePropProbing(SCIP *scip)
SCIP_RETCODE SCIPsetPropFree(SCIP *scip, SCIP_PROP *prop, SCIP_DECL_PROPFREE((*propfree)))
Definition: scip.c:7626
SCIP_PROPDATA * SCIPpropGetData(SCIP_PROP *prop)
Definition: prop.c:735
void SCIPpropSetData(SCIP_PROP *prop, SCIP_PROPDATA *propdata)
Definition: prop.c:745
#define SCIP_Longint
Definition: def.h:120
int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:16849
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:16717
#define PROP_TIMING
Definition: prop_probing.c:34
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
Definition: scip.c:45864
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:45777
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17232
SCIP_RETCODE SCIPstartProbing(SCIP *scip)
Definition: scip.c:35055
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:85
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
Definition: scip.c:45949
SCIP_RETCODE SCIPsetPropInitpre(SCIP *scip, SCIP_PROP *prop, SCIP_DECL_PROPINITPRE((*propinitpre)))
Definition: scip.c:7706
SCIP_RETCODE SCIPsetPropExit(SCIP *scip, SCIP_PROP *prop, SCIP_DECL_PROPEXIT((*propexit)))
Definition: scip.c:7658
#define SCIPfreeMemoryArrayNull(scip, ptr)
Definition: scip.h:21875
static SCIP_DECL_PROPPRESOL(propPresolProbing)
Definition: prop_probing.c:841
SCIP_RETCODE SCIPchgVarUbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip.c:35264
#define PROP_DELAY
Definition: prop_probing.c:37
SCIP_Bool SCIPvarIsDeleted(SCIP_VAR *var)
Definition: var.c:16773
static SCIP_DECL_PROPINITPRE(propInitpreProbing)
Definition: prop_probing.c:785
SCIP_Real SCIPpropGetTime(SCIP_PROP *prop)
Definition: prop.c:1002
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
Definition: scip.c:45937
#define PROP_PRIORITY
Definition: prop_probing.c:35
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:16839
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip.h:21929
SCIP_RETCODE SCIPincludePropBasic(SCIP *scip, SCIP_PROP **propptr, const char *name, const char *desc, int priority, int freq, SCIP_Bool delay, SCIP_PROPTIMING timingmask, SCIP_DECL_PROPEXEC((*propexec)), SCIP_PROPDATA *propdata)
Definition: scip.c:7573