Scippy

SCIP

Solving Constraint Integer Programs

dive.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-2015 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 dive.c
17  * @brief library methods for diving heuristics
18  * @author Gregor Hendel
19  */
20 
21 #include "scip/pub_dive.h"
22 #include "pub_heur.h"
23 
24 /* the indicator and SOS1 constraint handlers are included for the diving algorithm SCIPperformGenericDivingAlgorithm() */
25 #include "scip/cons_indicator.h"
26 #include "scip/cons_sos1.h"
27 
28 #define MINLPITER 10000 /**< minimal number of LP iterations allowed in each LP solving call */
29 
30 
31 /** solve probing LP */
32 static
34  SCIP* scip, /**< SCIP data structure */
35  SCIP_DIVESET* diveset, /**< diving settings */
36  SCIP_Longint maxnlpiterations, /**< maximum number of allowed LP iterations */
37  SCIP_Bool* lperror, /**< pointer to store if an internal LP error occurred */
38  SCIP_Bool* cutoff /**< pointer to store whether the LP was infeasible */
39  )
40 {
41  int lpiterationlimit;
42  SCIP_RETCODE retstat;
43  SCIP_Longint nlpiterations;
44 
45  assert(lperror != NULL);
46  assert(cutoff != NULL);
47 
48  nlpiterations = SCIPgetNLPIterations(scip);
49 
50  /* allow at least MINLPITER more iterations */
51  lpiterationlimit = (int)(maxnlpiterations - SCIPdivesetGetNLPIterations(diveset));
52  lpiterationlimit = MAX(lpiterationlimit, MINLPITER);
53 
54  retstat = SCIPsolveProbingLP(scip, lpiterationlimit, lperror, cutoff);
55 
56  /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
57  * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
58  */
59 #ifdef NDEBUG
60  if( retstat != SCIP_OKAY )
61  {
62  SCIPwarningMessage(scip, "Error while solving LP in %s diving heuristic; LP solve terminated with code <%d>.\n", SCIPdivesetGetName(diveset), retstat);
63  }
64 #else
65  SCIP_CALL( retstat );
66 #endif
67 
68  /* update iteration count */
69  SCIPupdateDivesetLPStats(scip, diveset, SCIPgetNLPIterations(scip) - nlpiterations);
70 
71  return SCIP_OKAY;
72 }
73 
74 /** select the next variable and type of diving */
75 static
77  SCIP* scip, /**< SCIP data structure */
78  SCIP_DIVESET* diveset, /**< dive set */
79  SCIP_SOL* worksol, /**< current working solution */
80  SCIP_Bool onlylpbranchcands, /**< should only LP branching candidates be considered? */
81  SCIP_Bool storelpcandscores, /**< should the scores of the LP candidates be updated? */
82  SCIP_VAR** lpcands, /**< LP branching candidates, or NULL if not needed */
83  SCIP_Real * lpcandssol, /**< solution values LP branching candidates, or NULL if not needed */
84  SCIP_Real* lpcandsfrac, /**< fractionalities of LP branching candidates, or NULL if not needed*/
85  SCIP_Real* lpcandsscores, /**< array with LP branching candidate scores, or NULL */
86  SCIP_Bool* lpcandroundup, /**< array to remember whether the preferred branching direction is upwards */
87  int* nviollpcands, /**< pointer to store the number of LP candidates whose solution value already violates local bounds */
88  int nlpcands, /**< number of current LP cands */
89  SCIP_Bool* enfosuccess, /**< pointer to store whether a candidate was sucessfully found */
90  SCIP_Bool* infeasible /**< pointer to store whether the diving can be immediately aborted because it is infeasible */
91  )
92 {
93  assert(scip != NULL);
94  assert(worksol != NULL);
95  assert(!onlylpbranchcands || lpcandsscores != NULL);
96  assert(!onlylpbranchcands || lpcandroundup != NULL);
97  assert(enfosuccess != NULL);
98  assert(infeasible != NULL);
99  assert(nviollpcands != NULL);
100 
101  *nviollpcands = 0;
102  /* we use diving solution enforcement provided by the constraint handlers */
103  if( !onlylpbranchcands )
104  {
105  SCIP_CALL( SCIPgetDiveBoundChanges(scip, diveset, worksol, enfosuccess, infeasible) );
106  }
107  else
108  {
109  int c;
110  int bestcandidx;
111  SCIP_Real bestscore;
112  SCIP_Real score;
113 
114  bestscore = SCIP_REAL_MIN;
115  bestcandidx = -1;
116 
118 
119  /* search for the candidate that maximizes the dive set score function and whose solution value is still feasible */
120  for( c = 0; c < nlpcands; ++c )
121  {
122  assert(SCIPgetSolVal(scip, worksol, lpcands[c]) == lpcandssol[c]); /*lint !e777 doesn't like comparing floats for equality */
123 
124  /* scores are kept in arrays for faster reuse */
125  if( storelpcandscores )
126  {
127  SCIP_CALL( SCIPgetDivesetScore(scip, diveset, SCIP_DIVETYPE_INTEGRALITY, lpcands[c], lpcandssol[c], lpcandsfrac[c], &lpcandsscores[c], &lpcandroundup[c]) );
128  }
129 
130  score = lpcandsscores[c];
131  /* update the best candidate if it has a higher score and a solution value which does not violate one of the local bounds */
132  if( SCIPisLE(scip, SCIPvarGetLbLocal(lpcands[c]), lpcandssol[c]) && SCIPisGE(scip, SCIPvarGetUbLocal(lpcands[c]), lpcandssol[c]) )
133  {
134  if( score > bestscore )
135  {
136  bestcandidx = c;
137  bestscore = score;
138  }
139  }
140  else
141  ++(*nviollpcands);
142  }
143 
144  /* there is no guarantee that a candidate is found since local bounds might render all solution values infeasible */
145  *enfosuccess = (bestcandidx >= 0);
146  if( *enfosuccess )
147  {
148  /* if we want to round up the best candidate, it is added as the preferred bound change */
149  SCIP_CALL( SCIPaddDiveBoundChange(scip, lpcands[bestcandidx], SCIP_BRANCHDIR_UPWARDS,
150  SCIPceil(scip, lpcandssol[bestcandidx]), lpcandroundup[bestcandidx]) );
151  SCIP_CALL( SCIPaddDiveBoundChange(scip, lpcands[bestcandidx], SCIP_BRANCHDIR_DOWNWARDS,
152  SCIPfloor(scip, lpcandssol[bestcandidx]), ! lpcandroundup[bestcandidx]) );
153  }
154  }
155  return SCIP_OKAY;
156 }
157 
158 
159 
160 /** performs a diving within the limits of the diveset parameters
161  *
162  * This method performs a diving according to the settings defined by the diving settings @p diveset; Contrary to the
163  * name, SCIP enters probing mode (not diving mode) and dives along a path into the tree. Domain propagation
164  * is applied at every node in the tree, whereas probing LPs might be solved less frequently.
165  *
166  * Starting from the current LP solution, the algorithm selects candidates which maximize the
167  * score defined by the @p diveset and whose solution value has not yet been rendered infeasible by propagation,
168  * and propagates the bound change on this candidate.
169  *
170  * The algorithm iteratively selects the the next (unfixed) candidate in the list, until either enough domain changes
171  * or the resolve frequency of the LP trigger an LP resolve (and hence, the set of potential candidates changes),
172  * or the last node is proven to be infeasible. It optionally backtracks and tries the
173  * other branching direction.
174  *
175  * After the set of remaining candidates is empty or the targeted depth is reached, the node LP is
176  * solved, and the old candidates are replaced by the new LP candidates.
177  *
178  * @see heur_guideddiving.c for an example implementation of a dive set controlling the diving algorithm.
179  *
180  * @note the node from where the algorithm is called is checked for a basic LP solution. If the solution
181  * is non-basic, e.g., when barrier without crossover is used, the method returns without performing a dive.
182  *
183  * @note currently, when multiple diving heuristics call this method and solve an LP at the same node, only the first
184  * call will be executed, @see SCIPgetLastDiveNode()
185  *
186  * @todo generalize method to work correctly with pseudo or external branching/diving candidates
187  */
189  SCIP* scip, /**< SCIP data structure */
190  SCIP_DIVESET* diveset, /**< settings for diving */
191  SCIP_SOL* worksol, /**< non-NULL working solution */
192  SCIP_HEUR* heur, /**< the calling primal heuristic */
193  SCIP_RESULT* result, /**< SCIP result pointer */
194  SCIP_Bool nodeinfeasible /**< is the current node known to be infeasible? */
195  )
196 {
197  SCIP_CONSHDLR* indconshdlr; /* constraint handler for indicator constraints */
198  SCIP_CONSHDLR* sos1conshdlr; /* constraint handler for SOS1 constraints */
199  SCIP_VAR** lpcands;
200  SCIP_Real* lpcandssol;
201 
202  SCIP_VAR** previouscands;
203  SCIP_Real* lpcandsscores;
204  SCIP_Real* previousvals;
205  SCIP_Real* lpcandsfrac;
206  SCIP_Bool* lpcandroundup;
207  SCIP_Real searchubbound;
208  SCIP_Real searchavgbound;
209  SCIP_Real searchbound;
210  SCIP_Real nextcandsol;
211  SCIP_Real ubquot;
212  SCIP_Real avgquot;
213  SCIP_Longint ncalls;
214  SCIP_Longint oldsolsuccess;
215  SCIP_Longint nlpiterations;
216  SCIP_Longint maxnlpiterations;
217  SCIP_Longint domreds;
218  int startndivecands;
219  int depth;
220  int maxdepth;
221  int maxdivedepth;
222  int totalnbacktracks;
223  int totalnprobingnodes;
224  int lastlpdepth;
225  int previouscandssize;
226  int lpcandsscoressize;
227  int nviollpcands;
228  SCIP_Longint oldnsolsfound;
229  SCIP_Longint oldnbestsolsfound;
230 
231  SCIP_Bool success;
232  SCIP_Bool enfosuccess;
233  SCIP_Bool lperror;
234  SCIP_Bool cutoff;
235  SCIP_Bool backtracked;
236  SCIP_Bool backtrack;
237  SCIP_Bool onlylpbranchcands;
238 
239  int nlpcands;
240  int lpsolvefreq;
241 
242  assert(scip != NULL);
243  assert(result != NULL);
244  assert(worksol != NULL);
245 
246  *result = SCIP_DELAYED;
247 
248  /* do not call heuristic in node that was already detected to be infeasible */
249  if( nodeinfeasible )
250  return SCIP_OKAY;
251 
252  /* only call heuristic, if an optimal LP solution is at hand */
254  return SCIP_OKAY;
255 
256  /* only call heuristic, if the LP objective value is smaller than the cutoff bound */
257  if( SCIPisGE(scip, SCIPgetLPObjval(scip), SCIPgetCutoffbound(scip)) )
258  return SCIP_OKAY;
259 
260  /* only call heuristic, if the LP solution is basic (which allows fast resolve in diving) */
261  if( !SCIPisLPSolBasic(scip) )
262  return SCIP_OKAY;
263 
264  /* don't dive two times at the same node */
265  if( SCIPgetLastDivenode(scip) == SCIPgetNNodes(scip) && SCIPgetDepth(scip) > 0 )
266  return SCIP_OKAY;
267 
268  *result = SCIP_DIDNOTRUN;
269 
270  /* only try to dive, if we are in the correct part of the tree, given by minreldepth and maxreldepth */
271  depth = SCIPgetDepth(scip);
272  maxdepth = SCIPgetMaxDepth(scip);
273  maxdepth = MAX(maxdepth, 30);
274  if( depth < SCIPdivesetGetMinRelDepth(diveset) * maxdepth || depth > SCIPdivesetGetMaxRelDepth(diveset) * maxdepth )
275  return SCIP_OKAY;
276 
277  /* calculate the maximal number of LP iterations until heuristic is aborted */
278  nlpiterations = SCIPgetNNodeLPIterations(scip);
279  ncalls = SCIPdivesetGetNCalls(diveset);
280  oldsolsuccess = SCIPdivesetGetSolSuccess(diveset);
281 
282  /*todo another factor of 10, REALLY? */
283  maxnlpiterations = (SCIP_Longint)((1.0 + 10*(oldsolsuccess+1.0)/(ncalls+1.0)) * SCIPdivesetGetMaxLPIterQuot(diveset) * nlpiterations);
284  maxnlpiterations += SCIPdivesetGetMaxLPIterOffset(diveset);
285 
286 
287 
288  /* don't try to dive, if we took too many LP iterations during diving */
289  if( SCIPdivesetGetNLPIterations(diveset) >= maxnlpiterations )
290  return SCIP_OKAY;
291 
292  /* allow at least a certain number of LP iterations in this dive */
293  if( SCIPdivesetGetNLPIterations(diveset) + MINLPITER > maxnlpiterations )
294  maxnlpiterations = SCIPdivesetGetNLPIterations(diveset) + MINLPITER;
295 
296  /* these constraint handlers are required for polishing an LP relaxation solution beyond rounding */
297  indconshdlr = SCIPfindConshdlr(scip, "indicator");
298  sos1conshdlr = SCIPfindConshdlr(scip, "SOS1");
299 
300  SCIP_CALL( SCIPgetLPBranchCands(scip, &lpcands, &lpcandssol, &lpcandsfrac, &nlpcands, NULL, NULL) );
301 
302  onlylpbranchcands = SCIPdivesetUseOnlyLPBranchcands(diveset);
303  /* don't try to dive, if there are no diving candidates */
304  if( onlylpbranchcands && nlpcands == 0 )
305  return SCIP_OKAY;
306 
307  /* calculate the objective search bound */
308  if( SCIPgetNSolsFound(scip) == 0 )
309  {
310  ubquot = SCIPdivesetGetUbQuotNoSol(diveset);
311  avgquot = SCIPdivesetGetAvgQuotNoSol(diveset);
312  }
313  else
314  {
315  ubquot = SCIPdivesetGetUbQuot(diveset);
316  avgquot = SCIPdivesetGetAvgQuot(diveset);
317  }
318 
319  if( ubquot > 0.0 )
320  searchubbound = SCIPgetLowerbound(scip) + ubquot * (SCIPgetCutoffbound(scip) - SCIPgetLowerbound(scip));
321  else
322  searchubbound = SCIPinfinity(scip);
323 
324  if( avgquot > 0.0 )
325  searchavgbound = SCIPgetLowerbound(scip) + avgquot * (SCIPgetAvgLowerbound(scip) - SCIPgetLowerbound(scip));
326  else
327  searchavgbound = SCIPinfinity(scip);
328 
329  searchbound = MIN(searchubbound, searchavgbound);
330 
331  if( SCIPisObjIntegral(scip) )
332  searchbound = SCIPceil(scip, searchbound);
333 
334  /* calculate the maximal diving depth: 10 * min{number of integer variables, max depth} */
335  maxdivedepth = SCIPgetNBinVars(scip) + SCIPgetNIntVars(scip);
336  if ( sos1conshdlr != NULL )
337  maxdivedepth += SCIPgetNSOS1Vars(sos1conshdlr);
338  maxdivedepth = MIN(maxdivedepth, maxdepth);
339  maxdivedepth *= 10;
340 
341  *result = SCIP_DIDNOTFIND;
342 
343  /* start probing mode */
344  SCIP_CALL( SCIPstartProbing(scip) );
345 
346  /* enables collection of variable statistics during probing */
347  SCIPenableVarHistory(scip);
348 
349  SCIPdebugMessage("(node %" SCIP_LONGINT_FORMAT ") executing %s heuristic: depth=%d, %d fractionals, dualbound=%g, avgbound=%g, cutoffbound=%g, searchbound=%g\n",
350  SCIPgetNNodes(scip), SCIPheurGetName(heur), SCIPgetDepth(scip), nlpcands, SCIPgetDualbound(scip), SCIPgetAvgDualbound(scip),
351  SCIPretransformObj(scip, SCIPgetCutoffbound(scip)), SCIPretransformObj(scip, searchbound));
352 
353 
354  /* allocate buffer storage for previous candidates and their branching values for pseudo cost updates */
355  lpsolvefreq = SCIPdivesetGetLPSolveFreq(diveset);
356  previouscandssize = MAX(1, lpsolvefreq);
357  SCIP_CALL( SCIPallocBufferArray(scip, &previouscands, previouscandssize) );
358  SCIP_CALL( SCIPallocBufferArray(scip, &previousvals, previouscandssize) );
359 
360  /* keep some statistics */
361  lperror = FALSE;
362  cutoff = FALSE;
363  lastlpdepth = -1;
364  startndivecands = nlpcands;
365  totalnbacktracks = 0;
366  totalnprobingnodes = 0;
367  oldnsolsfound = SCIPgetNSolsFound(scip);
368  oldnbestsolsfound = SCIPgetNBestSolsFound(scip);
369 
370  /* link the working solution to the dive set */
371  SCIPdivesetSetWorkSolution(diveset, worksol);
372 
373  if( onlylpbranchcands )
374  {
375  SCIP_CALL( SCIPallocBufferArray(scip, &lpcandsscores, nlpcands) );
376  SCIP_CALL( SCIPallocBufferArray(scip, &lpcandroundup, nlpcands) );
377 
378  lpcandsscoressize = nlpcands;
379  }
380  else
381  {
382  lpcandroundup = NULL;
383  lpcandsscores = NULL;
384  lpcandsscoressize = 0;
385  }
386 
387  enfosuccess = TRUE;
388 
389  /* LP loop; every time a new LP was solved, conditions are checked
390  * dive as long we are in the given objective, depth and iteration limits and fractional variables exist, but
391  * - if possible, we dive at least with the depth 10
392  * - if the number of fractional variables decreased at least with 1 variable per 2 dive depths, we continue diving
393  */
394  while( !lperror && !cutoff && SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL && enfosuccess
395  && (SCIPgetProbingDepth(scip) < 10
396  || nlpcands <= startndivecands - SCIPgetProbingDepth(scip) / 2
397  || (SCIPgetProbingDepth(scip) < maxdivedepth && SCIPdivesetGetNLPIterations(diveset) < maxnlpiterations && SCIPgetLPObjval(scip) < searchbound))
398  && !SCIPisStopped(scip) )
399  {
400  SCIP_Real lastlpobjval;
401  int c;
402  SCIP_Bool allroundable;
403  SCIP_Bool infeasible;
404  int prevcandsinsertidx;
405 
406  /* remember the last LP depth */
407  assert(lastlpdepth < SCIPgetProbingDepth(scip));
408  lastlpdepth = SCIPgetProbingDepth(scip);
409  domreds = 0;
410 
411  SCIPdebugMessage("%s heuristic continues diving at depth %d, %d candidates left\n",
412  SCIPdivesetGetName(diveset), lastlpdepth, nlpcands);
413 
414 
415  /* loop over candidates and determine if they are roundable */
416  allroundable = TRUE;
417  c = 0;
418  while( allroundable && c < nlpcands )
419  {
420  if( SCIPvarMayRoundDown(lpcands[c]) || SCIPvarMayRoundUp(lpcands[c]) )
421  allroundable = TRUE;
422  else
423  allroundable = FALSE;
424  ++c;
425  }
426 
427  /* if all candidates are roundable, try to round the solution */
428  if( allroundable )
429  {
430  success = FALSE;
431 
432  /* working solution must be linked to LP solution */
433  SCIP_CALL( SCIPlinkLPSol(scip, worksol) );
434  /* create solution from diving LP and try to round it */
435  SCIP_CALL( SCIProundSol(scip, worksol, &success) );
436 
437  /* adjust SOS1 constraints */
438  if( success && sos1conshdlr != NULL )
439  {
440  SCIP_Bool changed;
441  SCIP_CALL( SCIPmakeSOS1sFeasible(scip, sos1conshdlr, worksol, &changed, &success) );
442  }
443 
444  /* succesfully rounded solutions are tried for primal feasibility */
445  if( success )
446  {
447  SCIP_Bool changed = FALSE;
448  SCIPdebugMessage("%s found roundable primal solution: obj=%g\n", SCIPdivesetGetName(diveset), SCIPgetSolOrigObj(scip, worksol));
449 
450  /* adjust indicator constraints */
451  if( indconshdlr != NULL )
452  {
453  SCIP_CALL( SCIPmakeIndicatorsFeasible(scip, indconshdlr, worksol, &changed) );
454  }
455 
456  success = FALSE;
457  /* try to add solution to SCIP */
458  SCIP_CALL( SCIPtrySol(scip, worksol, FALSE, FALSE, FALSE, FALSE, &success) );
459 
460  /* check, if solution was feasible and good enough */
461  if( success )
462  {
463  SCIPdebugMessage(" -> solution was feasible and good enough\n");
464  *result = SCIP_FOUNDSOL;
465 
466  /* the rounded solution found above led to a cutoff of the node LP solution */
468  {
469  cutoff = TRUE;
470  break;
471  }
472  }
473  }
474  }
475 
476  /* working solution must be linked to LP solution */
477  assert(SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL);
478  lastlpobjval = SCIPgetLPObjval(scip);
479  SCIP_CALL( SCIPlinkLPSol(scip, worksol) );
480 
481  /* in case we do not solve LP's at every probing node, we must explicitly store the solution values by unlinking the
482  * solution, otherwise, the working solution may contain wrong entries, if, e.g., a backtrack occurred after an
483  * intermediate LP resolve
484  */
485  if( lpsolvefreq != 1 )
486  {
487  SCIP_CALL( SCIPunlinkSol(scip, worksol) );
488  }
489 
490 
491  /* ensure array sizes for the diving on the fractional variables */
492  if( onlylpbranchcands && nlpcands > lpcandsscoressize )
493  {
494  assert(nlpcands > 0);
495  assert(lpcandsscores != NULL);
496  assert(lpcandroundup != NULL);
497 
498  SCIP_CALL( SCIPreallocBufferArray(scip, &lpcandsscores, nlpcands) );
499  SCIP_CALL( SCIPreallocBufferArray(scip, &lpcandroundup, nlpcands) );
500 
501  lpcandsscoressize = nlpcands;
502  }
503 
504 
505  nextcandsol = SCIP_INVALID;
506  enfosuccess = FALSE;
507  /* select the next diving action by selecting appropriate dive bound changes for the preferred and alternative child */
508  SCIP_CALL( selectNextDiving(scip, diveset, worksol, onlylpbranchcands, SCIPgetProbingDepth(scip) == lastlpdepth,
509  lpcands, lpcandssol, lpcandsfrac, lpcandsscores, lpcandroundup, &nviollpcands, nlpcands,
510  &enfosuccess, &infeasible) );
511 
512  /* if we did not succeed finding an enforcement, the solution is potentially feasible and we break immediately */
513  if( ! enfosuccess )
514  break;
515 
516  prevcandsinsertidx = -1;
517 
518  /* start propagating candidate variables
519  * - until the desired targetdepth is reached,
520  * - or there is no further candidate variable left because of intermediate bound changes,
521  * - or a cutoff is detected
522  */
523  do
524  {
525  SCIP_VAR* bdchgvar;
526  SCIP_Real bdchgvalue;
527  SCIP_Longint localdomreds;
528  SCIP_BRANCHDIR bdchgdir;
529  int nbdchanges;
530 
531  /* ensure that a new candidate was successfully determined (usually at the end of the previous loop iteration) */
532  assert(enfosuccess);
533  bdchgvar = NULL;
534  bdchgvalue = SCIP_INVALID;
535  bdchgdir = SCIP_BRANCHDIR_AUTO;
536 
537  backtracked = FALSE;
538  do
539  {
540  int d;
541  SCIP_VAR** bdchgvars;
542  SCIP_BRANCHDIR* bdchgdirs;
543  SCIP_Real* bdchgvals;
544 
545  nbdchanges = 0;
546  /* get the bound change information stored in the dive set */
547  SCIPgetDiveBoundChangeData(scip, &bdchgvars, &bdchgdirs, &bdchgvals, &nbdchanges, !backtracked);
548 
549  assert(nbdchanges > 0);
550  assert(bdchgvars != NULL);
551  assert(bdchgdirs != NULL);
552  assert(bdchgvals != NULL);
553 
554  /* dive deeper into the tree */
555  SCIP_CALL( SCIPnewProbingNode(scip) );
556  ++totalnprobingnodes;
557 
558  /* apply all suggested domain changes of the variables */
559  for( d = 0; d < nbdchanges; ++d )
560  {
561  SCIP_Real lblocal;
562  SCIP_Real ublocal;
563 
564  bdchgvar = bdchgvars[d];
565  bdchgvalue = bdchgvals[d];
566  nextcandsol = SCIPgetSolVal(scip, worksol, bdchgvar);
567  bdchgdir = bdchgdirs[d];
568 
569  assert(bdchgvar != NULL);
570  lblocal = SCIPvarGetLbLocal(bdchgvar);
571  ublocal = SCIPvarGetUbLocal(bdchgvar);
572 
573  /* if the variable is already fixed or if the solution value is outside the domain, numerical troubles may have
574  * occured or variable was fixed by propagation while backtracking => Abort diving!
575  */
576  if( (bdchgdir == SCIP_BRANCHDIR_UPWARDS && SCIPisFeasLE(scip, bdchgvalue, lblocal)) ||
577  (bdchgdir == SCIP_BRANCHDIR_DOWNWARDS && SCIPisFeasGE(scip, bdchgvalue, ublocal)) ||
578  (bdchgdir == SCIP_BRANCHDIR_FIXED &&
579  ( SCIPisFeasLT(scip, bdchgvalue, lblocal) ||
580  SCIPisFeasGT(scip, bdchgvalue, ublocal) ||
581  ( SCIPisFeasEQ(scip, lblocal, ublocal) && nbdchanges < 2 ))) )
582  {
583  SCIPdebugMessage("Selected variable <%s> already fixed to [%g,%g] (solval: %.9f), diving aborted \n",
584  SCIPvarGetName(bdchgvar), lblocal, ublocal, nextcandsol);
585  cutoff = TRUE;
586  break;
587  }
588 
589  if( SCIPisFeasLT(scip, nextcandsol, lblocal) || SCIPisFeasGT(scip, nextcandsol, ublocal) )
590  {
591  SCIPdebugMessage("selected variable's <%s> solution value is outside the domain [%g,%g] (solval: %.9f), diving aborted\n",
592  SCIPvarGetName(bdchgvar), lblocal, ublocal, nextcandsol);
593  cutoff = TRUE;
594  break;
595  }
596 
597  SCIPdebugMessage(" dive %d/%d, LP iter %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ": var <%s>, sol=%g, oldbounds=[%g,%g],",
598  SCIPgetProbingDepth(scip), maxdivedepth, SCIPdivesetGetNLPIterations(diveset), maxnlpiterations,
599  SCIPvarGetName(bdchgvar), nextcandsol, lblocal, ublocal);
600 
601  /* tighten the lower and/or upper bound depending on the bound change type */
602  switch( bdchgdir )
603  {
605  /* round variable up */
606  SCIP_CALL( SCIPchgVarLbProbing(scip, bdchgvar, bdchgvalue) );
607  break;
609  SCIP_CALL( SCIPchgVarUbProbing(scip, bdchgvar, bdchgvalue) );
610  break;
612  if( SCIPisFeasLT(scip, lblocal, bdchgvalue) )
613  {
614  SCIP_CALL( SCIPchgVarLbProbing(scip, bdchgvar, bdchgvalue) );
615  }
616  if( SCIPisFeasGT(scip, ublocal, bdchgvalue) )
617  {
618  SCIP_CALL( SCIPchgVarUbProbing(scip, bdchgvar, bdchgvalue) );
619  }
620  break;
621  case SCIP_BRANCHDIR_AUTO:
622  default:
623  SCIPerrorMessage("Error: Unsupported bound change direction <%d> specified for diving, aborting\n",bdchgdirs[d]);
624  SCIPABORT();
625  return SCIP_INVALIDDATA; /*lint !e527*/
626  }
627 
628  SCIPdebugMessage("newbounds=[%g,%g]\n",
629  lblocal, ublocal);
630  }
631  /* break loop immediately if we detected a cutoff */
632  if( cutoff )
633  break;
634 
635  /* apply domain propagation */
636  localdomreds = 0;
637  SCIP_CALL( SCIPpropagateProbing(scip, 0, &cutoff, &localdomreds) );
638 
639  /* add the number of bound changes we applied by ourselves after propagation, otherwise the counter would have been reset */
640  localdomreds += nbdchanges;
641 
642  /* resolve the diving LP if the diving resolve frequency is reached or a sufficient number of intermediate bound changes
643  * was reached
644  */
645  if( ! cutoff
646  && ((lpsolvefreq > 0 && ((SCIPgetProbingDepth(scip) - lastlpdepth) % lpsolvefreq) == 0)
647  || (domreds + localdomreds > SCIPdivesetGetLPResolveDomChgQuot(diveset) * SCIPgetNVars(scip))
648  || (onlylpbranchcands && nviollpcands > (int)(SCIPdivesetGetLPResolveDomChgQuot(diveset) * nlpcands))) )
649  {
650  SCIP_CALL( solveLP(scip, diveset, maxnlpiterations, &lperror, &cutoff) );
651 
652  /* lp errors lead to early termination */
653  if( lperror )
654  {
655  cutoff = TRUE;
656  break;
657  }
658  }
659 
660  /* perform backtracking if a cutoff was detected */
661  if( cutoff && !backtracked && SCIPdivesetUseBacktrack(diveset) )
662  {
663  SCIPdebugMessage(" *** cutoff detected at level %d - backtracking\n", SCIPgetProbingDepth(scip));
665  ++totalnbacktracks;
666  backtracked = TRUE;
667  backtrack = TRUE;
668  cutoff = FALSE;
669  }
670  else
671  backtrack = FALSE;
672  }
673  while( backtrack );
674 
675  /* we add the domain reductions from the last evaluated node */
676  domreds += localdomreds; /*lint !e771 lint thinks localdomreds has not been initialized */
677 
678  /* store candidate for pseudo cost update and choose next candidate only if no cutoff was detected */
679  if( ! cutoff )
680  {
681  if( nbdchanges == 1 && (bdchgdir == SCIP_BRANCHDIR_UPWARDS || bdchgdir == SCIP_BRANCHDIR_DOWNWARDS) )
682  {
683  ++prevcandsinsertidx;
684  assert(prevcandsinsertidx <= SCIPgetProbingDepth(scip) - lastlpdepth - 1);
685  assert(SCIPgetProbingDepth(scip) > 0);
686  assert(bdchgvar != NULL);
687  assert(bdchgvalue != SCIP_INVALID); /*lint !e777 doesn't like comparing floats for equality */
688 
689  /* extend array in case of a dynamic, domain change based LP resolve strategy */
690  if( prevcandsinsertidx >= previouscandssize )
691  {
692  previouscandssize *= 2;
693  SCIP_CALL( SCIPreallocBufferArray(scip, &previouscands, previouscandssize) );
694  SCIP_CALL( SCIPreallocBufferArray(scip, &previousvals, previouscandssize) );
695  }
696  assert(previouscandssize > prevcandsinsertidx);
697 
698  /* store candidate for pseudo cost update */
699  previouscands[prevcandsinsertidx] = bdchgvar;
700  previousvals[prevcandsinsertidx] = bdchgvalue;
701  }
702 
703  /* choose next candidate variable and resolve the LP if none is found. */
705  {
706  assert(SCIPgetProbingDepth(scip) > lastlpdepth);
707  enfosuccess = FALSE;
708 
709  /* select the next diving action */
710  SCIP_CALL( selectNextDiving(scip, diveset, worksol, onlylpbranchcands, SCIPgetProbingDepth(scip) == lastlpdepth,
711  lpcands, lpcandssol, lpcandsfrac, lpcandsscores, lpcandroundup, &nviollpcands, nlpcands,
712  &enfosuccess, &infeasible) );
713 
714 
715  /* in case of an unsuccesful candidate search, we solve the node LP */
716  if( !enfosuccess )
717  {
718  SCIP_CALL( solveLP(scip, diveset, maxnlpiterations, &lperror, &cutoff) );
719 
720  /* check for an LP error and terminate in this case, cutoffs lead to termination anyway */
721  if( lperror )
722  cutoff = TRUE;
723 
724  /* enfosuccess must be set to TRUE for entering the main LP loop again */
725  enfosuccess = TRUE;
726  }
727  }
728  }
729  }
730  while( !cutoff && SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_NOTSOLVED );
731 
732  assert(cutoff || lperror || SCIPgetLPSolstat(scip) != SCIP_LPSOLSTAT_NOTSOLVED);
733 
736 
737 
738  /* check new LP candidates and use the LP Objective gain to update pseudo cost information */
739  if( ! cutoff && SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL )
740  {
741  int v;
742  SCIP_Real gain;
743 
744  SCIP_CALL( SCIPgetLPBranchCands(scip, &lpcands, &lpcandssol, NULL, &nlpcands, NULL, NULL) );
745 
746  /* distribute the gain equally over all variables that we rounded since the last LP */
747  gain = SCIPgetLPObjval(scip) - lastlpobjval;
748  gain = MAX(gain, 0.0);
749  gain /= (1.0 * (SCIPgetProbingDepth(scip) - lastlpdepth));
750 
751  /* loop over previously fixed candidates and share gain improvement */
752  for( v = 0; v <= prevcandsinsertidx; ++v )
753  {
754  SCIP_VAR* cand = previouscands[v];
755  SCIP_Real val = previousvals[v];
756  SCIP_Real solval = SCIPgetSolVal(scip, worksol, cand);
757 
758  /* todo: should the gain be shared with a smaller weight, instead of dividing the gain itself? */
759  /* it may happen that a variable had an integral solution value beforehand, e.g., for indicator variables */
760  if( ! SCIPisZero(scip, val - solval) )
761  {
762  SCIP_CALL( SCIPupdateVarPseudocost(scip, cand, val - solval, gain, 1.0) );
763  }
764  }
765  }
766  else
767  nlpcands = 0;
768  SCIPdebugMessage(" -> lpsolstat=%d, objval=%g/%g, nfrac=%d\n", SCIPgetLPSolstat(scip), SCIPgetLPObjval(scip), searchbound, nlpcands);
769  }
770 
771  success = FALSE;
772  /* check if a solution has been found */
773  if( !enfosuccess && !lperror && !cutoff && SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL )
774  {
775  /* create solution from diving LP */
776  SCIP_CALL( SCIPlinkLPSol(scip, worksol) );
777  SCIPdebugMessage("%s found primal solution: obj=%g\n", SCIPdivesetGetName(diveset), SCIPgetSolOrigObj(scip, worksol));
778 
779  /* try to add solution to SCIP */
780  SCIP_CALL( SCIPtrySol(scip, worksol, FALSE, FALSE, FALSE, FALSE, &success) );
781 
782  /* check, if solution was feasible and good enough */
783  if( success )
784  {
785  SCIPdebugMessage(" -> solution was feasible and good enough\n");
786  *result = SCIP_FOUNDSOL;
787  }
788  }
789 
790  SCIPupdateDivesetStats(scip, diveset, totalnprobingnodes, totalnbacktracks, SCIPgetNSolsFound(scip) - oldnsolsfound,
791  SCIPgetNBestSolsFound(scip) - oldnbestsolsfound, success);
792 
793  SCIPdebugMessage("(node %" SCIP_LONGINT_FORMAT ") finished %s heuristic: %d fractionals, dive %d/%d, LP iter %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", objval=%g/%g, lpsolstat=%d, cutoff=%u\n",
794  SCIPgetNNodes(scip), SCIPdivesetGetName(diveset), nlpcands, SCIPgetProbingDepth(scip), maxdivedepth, SCIPdivesetGetNLPIterations(diveset), maxnlpiterations,
795  SCIPretransformObj(scip, SCIPgetLPObjval(scip)), SCIPretransformObj(scip, searchbound), SCIPgetLPSolstat(scip), cutoff);
796 
797  /* end probing mode */
798  SCIP_CALL( SCIPendProbing(scip) );
799 
801 
802  if( onlylpbranchcands )
803  {
804  SCIPfreeBufferArray(scip, &lpcandroundup);
805  SCIPfreeBufferArray(scip, &lpcandsscores);
806  }
807  SCIPfreeBufferArray(scip, &previousvals);
808  SCIPfreeBufferArray(scip, &previouscands);
809 
810  return SCIP_OKAY;
811 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:51
SCIP_RETCODE SCIPunlinkSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:34422
SCIP_RETCODE SCIPsolveProbingLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition: scip.c:32398
SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
Definition: scip.c:32735
SCIP_RETCODE SCIPaddDiveBoundChange(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Real value, SCIP_Bool preferred)
Definition: scip.c:32649
SCIP_Real SCIPgetAvgLowerbound(SCIP *scip)
Definition: scip.c:37936
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
Definition: scip.c:41293
int SCIPgetNVars(SCIP *scip)
Definition: scip.c:10735
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip.c:5847
int SCIPdivesetGetLPSolveFreq(SCIP_DIVESET *diveset)
Definition: heur.c:530
void SCIPupdateDivesetLPStats(SCIP *scip, SCIP_DIVESET *diveset, SCIP_Longint niterstoadd)
Definition: scip.c:32535
SCIP_RETCODE SCIPmakeIndicatorsFeasible(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_SOL *sol, SCIP_Bool *changed)
SCIP_RETCODE SCIPmakeSOS1sFeasible(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_SOL *sol, SCIP_Bool *changed, SCIP_Bool *success)
Definition: cons_sos1.c:9923
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16341
SCIP_Bool SCIPdivesetUseBacktrack(SCIP_DIVESET *diveset)
Definition: heur.c:522
void SCIPclearDiveBoundChanges(SCIP *scip)
Definition: scip.c:32702
const char * SCIPdivesetGetName(SCIP_DIVESET *diveset)
Definition: heur.c:331
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition: heur.c:1147
SCIP_RETCODE SCIPbacktrackProbing(SCIP *scip, int probingdepth)
Definition: scip.c:31860
SCIP_Bool SCIPvarMayRoundDown(SCIP_VAR *var)
Definition: var.c:3259
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip.c:1220
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41528
SCIP_Longint SCIPgetNLPIterations(SCIP *scip)
Definition: scip.c:37064
library methods for diving heuristics
void SCIPenableVarHistory(SCIP *scip)
Definition: scip.c:23132
#define NULL
Definition: lpi_spx.cpp:130
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17011
SCIP_Real SCIPdivesetGetUbQuot(SCIP_DIVESET *diveset)
Definition: heur.c:506
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip.c:1125
constraint handler for indicator constraints
static SCIP_RETCODE solveLP(SCIP *scip, SCIP_DIVESET *diveset, SCIP_Longint maxnlpiterations, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition: dive.c:33
SCIP_Real SCIPdivesetGetLPResolveDomChgQuot(SCIP_DIVESET *diveset)
Definition: heur.c:540
SCIP_RETCODE SCIPpropagateProbing(SCIP *scip, int maxproprounds, SCIP_Bool *cutoff, SCIP_Longint *ndomredsfound)
Definition: scip.c:32162
#define FALSE
Definition: def.h:53
int SCIPgetNBinVars(SCIP *scip)
Definition: scip.c:10780
#define TRUE
Definition: def.h:52
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_RETCODE SCIPupdateVarPseudocost(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
Definition: scip.c:23171
#define MINLPITER
Definition: dive.c:28
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
Definition: scip.c:38147
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip.c:26426
#define SCIPdebugMessage
Definition: pub_message.h:77
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip.c:34593
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:20414
int SCIPdivesetGetNCalls(SCIP_DIVESET *diveset)
Definition: heur.c:365
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip.h:20418
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition: scip.c:26469
SCIP_Real SCIPgetLowerbound(SCIP *scip)
Definition: scip.c:37979
void SCIPupdateDivesetStats(SCIP *scip, SCIP_DIVESET *diveset, int nprobingnodes, int nbacktracks, SCIP_Longint nsolsfound, SCIP_Longint nbestsolsfound, SCIP_Bool leavewassol)
Definition: scip.c:32548
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:34676
SCIP_Real SCIPdivesetGetAvgQuot(SCIP_DIVESET *diveset)
Definition: heur.c:514
enum SCIP_BranchDir SCIP_BRANCHDIR
Definition: type_history.h:39
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41193
SCIP_Real SCIPgetAvgDualbound(SCIP *scip)
Definition: scip.c:37917
SCIP_Real SCIPgetDualbound(SCIP *scip)
Definition: scip.c:37958
SCIP_Real SCIPdivesetGetMaxLPIterQuot(SCIP_DIVESET *diveset)
Definition: heur.c:475
#define SCIPerrorMessage
Definition: pub_message.h:45
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:20426
SCIP_Bool SCIPisObjIntegral(SCIP *scip)
Definition: scip.c:10347
int SCIPgetProbingDepth(SCIP *scip)
Definition: scip.c:31833
int SCIPgetMaxDepth(SCIP *scip)
Definition: scip.c:37800
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41206
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41515
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
Definition: scip.c:41366
SCIP_Real SCIPinfinity(SCIP *scip)
Definition: scip.c:41245
#define SCIP_CALL(x)
Definition: def.h:263
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
Definition: scip.c:26341
SCIP_RETCODE SCIPgetDivesetScore(SCIP *scip, SCIP_DIVESET *diveset, SCIP_DIVETYPE divetype, SCIP_VAR *divecand, SCIP_Real divecandsol, SCIP_Real divecandfrac, SCIP_Real *candscore, SCIP_Bool *roundup)
Definition: scip.c:32511
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41554
SCIP_Longint SCIPgetLastDivenode(SCIP *scip)
Definition: scip.c:31677
SCIP_RETCODE SCIPgetDiveBoundChanges(SCIP *scip, SCIP_DIVESET *diveset, SCIP_SOL *sol, SCIP_Bool *success, SCIP_Bool *infeasible)
Definition: scip.c:32588
static SCIP_RETCODE selectNextDiving(SCIP *scip, SCIP_DIVESET *diveset, SCIP_SOL *worksol, SCIP_Bool onlylpbranchcands, SCIP_Bool storelpcandscores, SCIP_VAR **lpcands, SCIP_Real *lpcandssol, SCIP_Real *lpcandsfrac, SCIP_Real *lpcandsscores, SCIP_Bool *lpcandroundup, int *nviollpcands, int nlpcands, SCIP_Bool *enfosuccess, SCIP_Bool *infeasible)
Definition: dive.c:76
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17021
void SCIPgetDiveBoundChangeData(SCIP *scip, SCIP_VAR ***variables, SCIP_BRANCHDIR **directions, SCIP_Real **values, int *ndivebdchgs, SCIP_Bool preferred)
Definition: scip.c:32675
#define SCIP_Bool
Definition: def.h:50
SCIP_Real SCIPdivesetGetUbQuotNoSol(SCIP_DIVESET *diveset)
Definition: heur.c:491
SCIP_Real SCIPretransformObj(SCIP *scip, SCIP_Real obj)
Definition: scip.c:34808
SCIP_Real SCIPdivesetGetMaxRelDepth(SCIP_DIVESET *diveset)
Definition: heur.c:349
#define MAX(x, y)
Definition: tclique_def.h:75
SCIP_Real SCIPdivesetGetMinRelDepth(SCIP_DIVESET *diveset)
Definition: heur.c:341
SCIP_RETCODE SCIPstartProbing(SCIP *scip)
Definition: scip.c:31763
SCIP_RETCODE SCIPendProbing(SCIP *scip)
Definition: scip.c:31895
SCIP_Longint SCIPdivesetGetNLPIterations(SCIP_DIVESET *diveset)
Definition: heur.c:445
int SCIPgetDepth(SCIP *scip)
Definition: scip.c:37750
SCIP_RETCODE SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:34258
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41232
#define SCIP_REAL_MIN
Definition: def.h:126
void SCIPdivesetSetWorkSolution(SCIP_DIVESET *diveset, SCIP_SOL *sol)
Definition: heur.c:320
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
Definition: scip.c:41378
SCIP_RETCODE SCIPperformGenericDivingAlgorithm(SCIP *scip, SCIP_DIVESET *diveset, SCIP_SOL *worksol, SCIP_HEUR *heur, SCIP_RESULT *result, SCIP_Bool nodeinfeasible)
Definition: dive.c:188
SCIP_Longint SCIPgetNSolsFound(SCIP *scip)
Definition: scip.c:38328
int SCIPgetNIntVars(SCIP *scip)
Definition: scip.c:10825
SCIP_RETCODE SCIPchgVarUbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip.c:31962
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41541
#define SCIP_Real
Definition: def.h:124
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
Definition: scip.c:31800
SCIP_RETCODE SCIPchgVarLbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip.c:31928
#define MIN(x, y)
Definition: memory.c:63
int SCIPgetNSOS1Vars(SCIP_CONSHDLR *conshdlr)
Definition: cons_sos1.c:9821
constraint handler for SOS type 1 constraints
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41567
SCIP_Bool SCIPvarMayRoundUp(SCIP_VAR *var)
Definition: var.c:3267
#define SCIP_INVALID
Definition: def.h:144
#define SCIP_Longint
Definition: def.h:109
SCIP_Real SCIPdivesetGetAvgQuotNoSol(SCIP_DIVESET *diveset)
Definition: heur.c:499
int SCIPdivesetGetMaxLPIterOffset(SCIP_DIVESET *diveset)
Definition: heur.c:483
SCIP_Bool SCIPisLPSolBasic(SCIP *scip)
Definition: scip.c:26834
public methods for primal heuristics
SCIP_Longint SCIPgetNNodeLPIterations(SCIP *scip)
Definition: scip.c:37359
#define SCIP_DIVETYPE_INTEGRALITY
Definition: type_heur.h:45
#define SCIPABORT()
Definition: def.h:235
SCIP_Longint SCIPdivesetGetSolSuccess(SCIP_DIVESET *diveset)
Definition: heur.c:357
SCIP_RETCODE SCIPtrySol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition: scip.c:35827
SCIP_Longint SCIPgetNNodes(SCIP *scip)
Definition: scip.c:36982
SCIP_Bool SCIPdivesetUseOnlyLPBranchcands(SCIP_DIVESET *diveset)
Definition: heur.c:552
SCIP_Longint SCIPgetNBestSolsFound(SCIP *scip)
Definition: scip.c:38376
SCIP_RETCODE SCIProundSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
Definition: scip.c:35519