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-2016 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 ubquot;
211  SCIP_Real avgquot;
212  SCIP_Longint ncalls;
213  SCIP_Longint oldsolsuccess;
214  SCIP_Longint nlpiterations;
215  SCIP_Longint maxnlpiterations;
216  SCIP_Longint domreds;
217  int startndivecands;
218  int depth;
219  int maxdepth;
220  int maxdivedepth;
221  int totalnbacktracks;
222  int totalnprobingnodes;
223  int lastlpdepth;
224  int previouscandssize;
225  int lpcandsscoressize;
226  int nviollpcands;
227  SCIP_Longint oldnsolsfound;
228  SCIP_Longint oldnbestsolsfound;
229 
230  SCIP_Bool success;
231  SCIP_Bool enfosuccess;
232  SCIP_Bool lperror;
233  SCIP_Bool cutoff;
234  SCIP_Bool backtracked;
235  SCIP_Bool backtrack;
236  SCIP_Bool onlylpbranchcands;
237 
238  int nlpcands;
239  int lpsolvefreq;
240 
241  assert(scip != NULL);
242  assert(result != NULL);
243  assert(worksol != NULL);
244 
245  *result = SCIP_DELAYED;
246 
247  /* do not call heuristic in node that was already detected to be infeasible */
248  if( nodeinfeasible )
249  return SCIP_OKAY;
250 
251  /* only call heuristic, if an optimal LP solution is at hand */
253  return SCIP_OKAY;
254 
255  /* only call heuristic, if the LP objective value is smaller than the cutoff bound */
256  if( SCIPisGE(scip, SCIPgetLPObjval(scip), SCIPgetCutoffbound(scip)) )
257  return SCIP_OKAY;
258 
259  /* only call heuristic, if the LP solution is basic (which allows fast resolve in diving) */
260  if( !SCIPisLPSolBasic(scip) )
261  return SCIP_OKAY;
262 
263  /* don't dive two times at the same node */
264  if( SCIPgetLastDivenode(scip) == SCIPgetNNodes(scip) && SCIPgetDepth(scip) > 0 )
265  return SCIP_OKAY;
266 
267  *result = SCIP_DIDNOTRUN;
268 
269  /* only try to dive, if we are in the correct part of the tree, given by minreldepth and maxreldepth */
270  depth = SCIPgetDepth(scip);
271  maxdepth = SCIPgetMaxDepth(scip);
272  maxdepth = MAX(maxdepth, 30);
273  if( depth < SCIPdivesetGetMinRelDepth(diveset) * maxdepth || depth > SCIPdivesetGetMaxRelDepth(diveset) * maxdepth )
274  return SCIP_OKAY;
275 
276  /* calculate the maximal number of LP iterations until heuristic is aborted */
277  nlpiterations = SCIPgetNNodeLPIterations(scip);
278  ncalls = SCIPdivesetGetNCalls(diveset);
279  oldsolsuccess = SCIPdivesetGetSolSuccess(diveset);
280 
281  /*todo another factor of 10, REALLY? */
282  maxnlpiterations = (SCIP_Longint)((1.0 + 10*(oldsolsuccess+1.0)/(ncalls+1.0)) * SCIPdivesetGetMaxLPIterQuot(diveset) * nlpiterations);
283  maxnlpiterations += SCIPdivesetGetMaxLPIterOffset(diveset);
284 
285 
286 
287  /* don't try to dive, if we took too many LP iterations during diving */
288  if( SCIPdivesetGetNLPIterations(diveset) >= maxnlpiterations )
289  return SCIP_OKAY;
290 
291  /* allow at least a certain number of LP iterations in this dive */
292  if( SCIPdivesetGetNLPIterations(diveset) + MINLPITER > maxnlpiterations )
293  maxnlpiterations = SCIPdivesetGetNLPIterations(diveset) + MINLPITER;
294 
295  /* these constraint handlers are required for polishing an LP relaxation solution beyond rounding */
296  indconshdlr = SCIPfindConshdlr(scip, "indicator");
297  sos1conshdlr = SCIPfindConshdlr(scip, "SOS1");
298 
299  SCIP_CALL( SCIPgetLPBranchCands(scip, &lpcands, &lpcandssol, &lpcandsfrac, &nlpcands, NULL, NULL) );
300 
301  onlylpbranchcands = SCIPdivesetUseOnlyLPBranchcands(diveset);
302  /* don't try to dive, if there are no diving candidates */
303  if( onlylpbranchcands && nlpcands == 0 )
304  return SCIP_OKAY;
305 
306  /* calculate the objective search bound */
307  if( SCIPgetNSolsFound(scip) == 0 )
308  {
309  ubquot = SCIPdivesetGetUbQuotNoSol(diveset);
310  avgquot = SCIPdivesetGetAvgQuotNoSol(diveset);
311  }
312  else
313  {
314  ubquot = SCIPdivesetGetUbQuot(diveset);
315  avgquot = SCIPdivesetGetAvgQuot(diveset);
316  }
317 
318  if( ubquot > 0.0 )
319  searchubbound = SCIPgetLowerbound(scip) + ubquot * (SCIPgetCutoffbound(scip) - SCIPgetLowerbound(scip));
320  else
321  searchubbound = SCIPinfinity(scip);
322 
323  if( avgquot > 0.0 )
324  searchavgbound = SCIPgetLowerbound(scip) + avgquot * (SCIPgetAvgLowerbound(scip) - SCIPgetLowerbound(scip));
325  else
326  searchavgbound = SCIPinfinity(scip);
327 
328  searchbound = MIN(searchubbound, searchavgbound);
329 
330  if( SCIPisObjIntegral(scip) )
331  searchbound = SCIPceil(scip, searchbound);
332 
333  /* calculate the maximal diving depth: 10 * min{number of integer variables, max depth} */
334  maxdivedepth = SCIPgetNBinVars(scip) + SCIPgetNIntVars(scip);
335  if ( sos1conshdlr != NULL )
336  maxdivedepth += SCIPgetNSOS1Vars(sos1conshdlr);
337  maxdivedepth = MIN(maxdivedepth, maxdepth);
338  maxdivedepth *= 10;
339 
340  *result = SCIP_DIDNOTFIND;
341 
342  /* start probing mode */
343  SCIP_CALL( SCIPstartProbing(scip) );
344 
345  /* enables collection of variable statistics during probing */
346  SCIPenableVarHistory(scip);
347 
348  SCIPdebugMessage("(node %" SCIP_LONGINT_FORMAT ") executing %s heuristic: depth=%d, %d fractionals, dualbound=%g, avgbound=%g, cutoffbound=%g, searchbound=%g\n",
349  SCIPgetNNodes(scip), SCIPheurGetName(heur), SCIPgetDepth(scip), nlpcands, SCIPgetDualbound(scip), SCIPgetAvgDualbound(scip),
350  SCIPretransformObj(scip, SCIPgetCutoffbound(scip)), SCIPretransformObj(scip, searchbound));
351 
352 
353  /* allocate buffer storage for previous candidates and their branching values for pseudo cost updates */
354  lpsolvefreq = SCIPdivesetGetLPSolveFreq(diveset);
355  previouscandssize = MAX(1, lpsolvefreq);
356  SCIP_CALL( SCIPallocBufferArray(scip, &previouscands, previouscandssize) );
357  SCIP_CALL( SCIPallocBufferArray(scip, &previousvals, previouscandssize) );
358 
359  /* keep some statistics */
360  lperror = FALSE;
361  cutoff = FALSE;
362  lastlpdepth = -1;
363  startndivecands = nlpcands;
364  totalnbacktracks = 0;
365  totalnprobingnodes = 0;
366  oldnsolsfound = SCIPgetNSolsFound(scip);
367  oldnbestsolsfound = SCIPgetNBestSolsFound(scip);
368 
369  /* link the working solution to the dive set */
370  SCIPdivesetSetWorkSolution(diveset, worksol);
371 
372  if( onlylpbranchcands )
373  {
374  SCIP_CALL( SCIPallocBufferArray(scip, &lpcandsscores, nlpcands) );
375  SCIP_CALL( SCIPallocBufferArray(scip, &lpcandroundup, nlpcands) );
376 
377  lpcandsscoressize = nlpcands;
378  }
379  else
380  {
381  lpcandroundup = NULL;
382  lpcandsscores = NULL;
383  lpcandsscoressize = 0;
384  }
385 
386  enfosuccess = TRUE;
387 
388  /* LP loop; every time a new LP was solved, conditions are checked
389  * dive as long we are in the given objective, depth and iteration limits and fractional variables exist, but
390  * - if possible, we dive at least with the depth 10
391  * - if the number of fractional variables decreased at least with 1 variable per 2 dive depths, we continue diving
392  */
393  while( !lperror && !cutoff && SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL && enfosuccess
394  && (SCIPgetProbingDepth(scip) < 10
395  || nlpcands <= startndivecands - SCIPgetProbingDepth(scip) / 2
396  || (SCIPgetProbingDepth(scip) < maxdivedepth && SCIPdivesetGetNLPIterations(diveset) < maxnlpiterations && SCIPgetLPObjval(scip) < searchbound))
397  && !SCIPisStopped(scip) )
398  {
399  SCIP_Real lastlpobjval;
400  int c;
401  SCIP_Bool allroundable;
402  SCIP_Bool infeasible;
403  int prevcandsinsertidx;
404 
405  /* remember the last LP depth */
406  assert(lastlpdepth < SCIPgetProbingDepth(scip));
407  lastlpdepth = SCIPgetProbingDepth(scip);
408  domreds = 0;
409 
410  SCIPdebugMessage("%s heuristic continues diving at depth %d, %d candidates left\n",
411  SCIPdivesetGetName(diveset), lastlpdepth, nlpcands);
412 
413 
414  /* loop over candidates and determine if they are roundable */
415  allroundable = TRUE;
416  c = 0;
417  while( allroundable && c < nlpcands )
418  {
419  if( SCIPvarMayRoundDown(lpcands[c]) || SCIPvarMayRoundUp(lpcands[c]) )
420  allroundable = TRUE;
421  else
422  allroundable = FALSE;
423  ++c;
424  }
425 
426  /* if all candidates are roundable, try to round the solution */
427  if( allroundable )
428  {
429  success = FALSE;
430 
431  /* working solution must be linked to LP solution */
432  SCIP_CALL( SCIPlinkLPSol(scip, worksol) );
433  /* create solution from diving LP and try to round it */
434  SCIP_CALL( SCIProundSol(scip, worksol, &success) );
435 
436  /* adjust SOS1 constraints */
437  if( success && sos1conshdlr != NULL )
438  {
439  SCIP_Bool changed;
440  SCIP_CALL( SCIPmakeSOS1sFeasible(scip, sos1conshdlr, worksol, &changed, &success) );
441  }
442 
443  /* succesfully rounded solutions are tried for primal feasibility */
444  if( success )
445  {
446  SCIP_Bool changed = FALSE;
447  SCIPdebugMessage("%s found roundable primal solution: obj=%g\n", SCIPdivesetGetName(diveset), SCIPgetSolOrigObj(scip, worksol));
448 
449  /* adjust indicator constraints */
450  if( indconshdlr != NULL )
451  {
452  SCIP_CALL( SCIPmakeIndicatorsFeasible(scip, indconshdlr, worksol, &changed) );
453  }
454 
455  success = FALSE;
456  /* try to add solution to SCIP */
457  SCIP_CALL( SCIPtrySol(scip, worksol, FALSE, FALSE, FALSE, changed, &success) );
458 
459  /* check, if solution was feasible and good enough */
460  if( success )
461  {
462  SCIPdebugMessage(" -> solution was feasible and good enough\n");
463  *result = SCIP_FOUNDSOL;
464 
465  /* the rounded solution found above led to a cutoff of the node LP solution */
467  {
468  cutoff = TRUE;
469  break;
470  }
471  }
472  }
473  }
474 
475  /* working solution must be linked to LP solution */
476  assert(SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL);
477  lastlpobjval = SCIPgetLPObjval(scip);
478  SCIP_CALL( SCIPlinkLPSol(scip, worksol) );
479 
480  /* in case we do not solve LP's at every probing node, we must explicitly store the solution values by unlinking the
481  * solution, otherwise, the working solution may contain wrong entries, if, e.g., a backtrack occurred after an
482  * intermediate LP resolve
483  */
484  if( lpsolvefreq != 1 )
485  {
486  SCIP_CALL( SCIPunlinkSol(scip, worksol) );
487  }
488 
489 
490  /* ensure array sizes for the diving on the fractional variables */
491  if( onlylpbranchcands && nlpcands > lpcandsscoressize )
492  {
493  assert(nlpcands > 0);
494  assert(lpcandsscores != NULL);
495  assert(lpcandroundup != NULL);
496 
497  SCIP_CALL( SCIPreallocBufferArray(scip, &lpcandsscores, nlpcands) );
498  SCIP_CALL( SCIPreallocBufferArray(scip, &lpcandroundup, nlpcands) );
499 
500  lpcandsscoressize = nlpcands;
501  }
502 
503 
504  enfosuccess = FALSE;
505  /* select the next diving action by selecting appropriate dive bound changes for the preferred and alternative child */
506  SCIP_CALL( selectNextDiving(scip, diveset, worksol, onlylpbranchcands, SCIPgetProbingDepth(scip) == lastlpdepth,
507  lpcands, lpcandssol, lpcandsfrac, lpcandsscores, lpcandroundup, &nviollpcands, nlpcands,
508  &enfosuccess, &infeasible) );
509 
510  /* if we did not succeed finding an enforcement, the solution is potentially feasible and we break immediately */
511  if( ! enfosuccess )
512  break;
513 
514  prevcandsinsertidx = -1;
515 
516  /* start propagating candidate variables
517  * - until the desired targetdepth is reached,
518  * - or there is no further candidate variable left because of intermediate bound changes,
519  * - or a cutoff is detected
520  */
521  do
522  {
523  SCIP_VAR* bdchgvar;
524  SCIP_Real bdchgvalue;
525  SCIP_Longint localdomreds;
526  SCIP_BRANCHDIR bdchgdir;
527  int nbdchanges;
528 
529  /* ensure that a new candidate was successfully determined (usually at the end of the previous loop iteration) */
530  assert(enfosuccess);
531  bdchgvar = NULL;
532  bdchgvalue = SCIP_INVALID;
533  bdchgdir = SCIP_BRANCHDIR_AUTO;
534 
535  backtracked = FALSE;
536  do
537  {
538  int d;
539  SCIP_VAR** bdchgvars;
540  SCIP_BRANCHDIR* bdchgdirs;
541  SCIP_Real* bdchgvals;
542 
543  nbdchanges = 0;
544  /* get the bound change information stored in the dive set */
545  SCIPgetDiveBoundChangeData(scip, &bdchgvars, &bdchgdirs, &bdchgvals, &nbdchanges, !backtracked);
546 
547  assert(nbdchanges > 0);
548  assert(bdchgvars != NULL);
549  assert(bdchgdirs != NULL);
550  assert(bdchgvals != NULL);
551 
552  /* return if we reached the depth limit */
553  if( SCIPgetDepthLimit(scip) <= SCIPgetDepth(scip) )
554  {
555  SCIPdebugMessage("depth limit reached, we stop diving immediately.\n");
556  goto TERMINATE;
557  }
558 
559  /* dive deeper into the tree */
560  SCIP_CALL( SCIPnewProbingNode(scip) );
561  ++totalnprobingnodes;
562 
563  /* apply all suggested domain changes of the variables */
564  for( d = 0; d < nbdchanges; ++d )
565  {
566  SCIP_Real lblocal;
567  SCIP_Real ublocal;
568  SCIP_Bool infeasbdchange;
569 
570  /* get the next bound change data: variable, direction, and value */
571  bdchgvar = bdchgvars[d];
572  bdchgvalue = bdchgvals[d];
573  bdchgdir = bdchgdirs[d];
574 
575  assert(bdchgvar != NULL);
576  lblocal = SCIPvarGetLbLocal(bdchgvar);
577  ublocal = SCIPvarGetUbLocal(bdchgvar);
578 
579 
580  SCIPdebugMessage(" dive %d/%d, LP iter %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ": var <%s>, oldbounds=[%g,%g],",
581  SCIPgetProbingDepth(scip), maxdivedepth, SCIPdivesetGetNLPIterations(diveset), maxnlpiterations,
582  SCIPvarGetName(bdchgvar), lblocal, ublocal);
583 
584  infeasbdchange = FALSE;
585  /* tighten the lower and/or upper bound depending on the bound change type */
586  switch( bdchgdir )
587  {
589  /* test if bound change is possible, otherwise propagation might have deduced the same
590  * bound already or numerical troubles might have occurred */
591  if( SCIPisFeasLE(scip, bdchgvalue, lblocal) )
592  infeasbdchange = TRUE;
593  else
594  {
595  /* round variable up */
596  SCIP_CALL( SCIPchgVarLbProbing(scip, bdchgvar, bdchgvalue) );
597  }
598  break;
600  /* test if bound change is possible, otherwise propagation might have deduced the same
601  * bound already or numerical troubles might have occurred */
602  if( SCIPisFeasGE(scip, bdchgvalue, ublocal) )
603  infeasbdchange = TRUE;
604  else
605  {
606  /* round variable down */
607  SCIP_CALL( SCIPchgVarUbProbing(scip, bdchgvar, bdchgvalue) );
608  }
609  break;
611  /* test if bound change is possible, otherwise propagation might have deduced the same
612  * bound already or numerical troubles might have occurred */
613  if( SCIPisFeasLT(scip, bdchgvalue, lblocal) || SCIPisFeasGT(scip, bdchgvalue, ublocal) ||
614  (SCIPisFeasEQ(scip, lblocal, ublocal) && nbdchanges < 2) )
615  infeasbdchange = TRUE;
616  else
617  {
618  /* fix variable to the bound change value */
619  if( SCIPisFeasLT(scip, lblocal, bdchgvalue) )
620  {
621  SCIP_CALL( SCIPchgVarLbProbing(scip, bdchgvar, bdchgvalue) );
622  }
623  if( SCIPisFeasGT(scip, ublocal, bdchgvalue) )
624  {
625  SCIP_CALL( SCIPchgVarUbProbing(scip, bdchgvar, bdchgvalue) );
626  }
627  }
628  break;
629  case SCIP_BRANCHDIR_AUTO:
630  default:
631  SCIPerrorMessage("Error: Unsupported bound change direction <%d> specified for diving, aborting\n",bdchgdirs[d]);
632  SCIPABORT();
633  return SCIP_INVALIDDATA; /*lint !e527*/
634  }
635  /* if the variable domain has been shrunk in the meantime, numerical troubles may have
636  * occured or variable was fixed by propagation while backtracking => Abort diving!
637  */
638  if( infeasbdchange )
639  {
640  SCIPdebugMessage("\nSelected variable <%s> domain already [%g,%g] as least as tight as desired bound change, diving aborted \n",
641  SCIPvarGetName(bdchgvar), lblocal, ublocal);
642  cutoff = TRUE;
643  break;
644  }
645 
646  SCIPdebugMessage("newbounds=[%g,%g]\n",
647  lblocal, ublocal);
648  }
649  /* break loop immediately if we detected a cutoff */
650  if( cutoff )
651  break;
652 
653  /* apply domain propagation */
654  localdomreds = 0;
655  SCIP_CALL( SCIPpropagateProbing(scip, 0, &cutoff, &localdomreds) );
656 
657  /* add the number of bound changes we applied by ourselves after propagation, otherwise the counter would have been reset */
658  localdomreds += nbdchanges;
659 
660  /* resolve the diving LP if the diving resolve frequency is reached or a sufficient number of intermediate bound changes
661  * was reached
662  */
663  if( ! cutoff
664  && ((lpsolvefreq > 0 && ((SCIPgetProbingDepth(scip) - lastlpdepth) % lpsolvefreq) == 0)
665  || (domreds + localdomreds > SCIPdivesetGetLPResolveDomChgQuot(diveset) * SCIPgetNVars(scip))
666  || (onlylpbranchcands && nviollpcands > (int)(SCIPdivesetGetLPResolveDomChgQuot(diveset) * nlpcands))) )
667  {
668  SCIP_CALL( solveLP(scip, diveset, maxnlpiterations, &lperror, &cutoff) );
669 
670  /* lp errors lead to early termination */
671  if( lperror )
672  {
673  cutoff = TRUE;
674  break;
675  }
676  }
677 
678  /* perform backtracking if a cutoff was detected */
679  if( cutoff && !backtracked && SCIPdivesetUseBacktrack(diveset) )
680  {
681  SCIPdebugMessage(" *** cutoff detected at level %d - backtracking\n", SCIPgetProbingDepth(scip));
683  ++totalnbacktracks;
684  backtracked = TRUE;
685  backtrack = TRUE;
686  cutoff = FALSE;
687  }
688  else
689  backtrack = FALSE;
690  }
691  while( backtrack );
692 
693  /* we add the domain reductions from the last evaluated node */
694  domreds += localdomreds; /*lint !e771 lint thinks localdomreds has not been initialized */
695 
696  /* store candidate for pseudo cost update and choose next candidate only if no cutoff was detected */
697  if( ! cutoff )
698  {
699  if( nbdchanges == 1 && (bdchgdir == SCIP_BRANCHDIR_UPWARDS || bdchgdir == SCIP_BRANCHDIR_DOWNWARDS) )
700  {
701  ++prevcandsinsertidx;
702  assert(prevcandsinsertidx <= SCIPgetProbingDepth(scip) - lastlpdepth - 1);
703  assert(SCIPgetProbingDepth(scip) > 0);
704  assert(bdchgvar != NULL);
705  assert(bdchgvalue != SCIP_INVALID); /*lint !e777 doesn't like comparing floats for equality */
706 
707  /* extend array in case of a dynamic, domain change based LP resolve strategy */
708  if( prevcandsinsertidx >= previouscandssize )
709  {
710  previouscandssize *= 2;
711  SCIP_CALL( SCIPreallocBufferArray(scip, &previouscands, previouscandssize) );
712  SCIP_CALL( SCIPreallocBufferArray(scip, &previousvals, previouscandssize) );
713  }
714  assert(previouscandssize > prevcandsinsertidx);
715 
716  /* store candidate for pseudo cost update */
717  previouscands[prevcandsinsertidx] = bdchgvar;
718  previousvals[prevcandsinsertidx] = bdchgvalue;
719  }
720 
721  /* choose next candidate variable and resolve the LP if none is found. */
723  {
724  assert(SCIPgetProbingDepth(scip) > lastlpdepth);
725  enfosuccess = FALSE;
726 
727  /* select the next diving action */
728  SCIP_CALL( selectNextDiving(scip, diveset, worksol, onlylpbranchcands, SCIPgetProbingDepth(scip) == lastlpdepth,
729  lpcands, lpcandssol, lpcandsfrac, lpcandsscores, lpcandroundup, &nviollpcands, nlpcands,
730  &enfosuccess, &infeasible) );
731 
732 
733  /* in case of an unsuccesful candidate search, we solve the node LP */
734  if( !enfosuccess )
735  {
736  SCIP_CALL( solveLP(scip, diveset, maxnlpiterations, &lperror, &cutoff) );
737 
738  /* check for an LP error and terminate in this case, cutoffs lead to termination anyway */
739  if( lperror )
740  cutoff = TRUE;
741 
742  /* enfosuccess must be set to TRUE for entering the main LP loop again */
743  enfosuccess = TRUE;
744  }
745  }
746  }
747  }
748  while( !cutoff && SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_NOTSOLVED );
749 
750  assert(cutoff || lperror || SCIPgetLPSolstat(scip) != SCIP_LPSOLSTAT_NOTSOLVED);
751 
754 
755 
756  /* check new LP candidates and use the LP Objective gain to update pseudo cost information */
757  if( ! cutoff && SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL )
758  {
759  int v;
760  SCIP_Real gain;
761 
762  SCIP_CALL( SCIPgetLPBranchCands(scip, &lpcands, &lpcandssol, NULL, &nlpcands, NULL, NULL) );
763 
764  /* distribute the gain equally over all variables that we rounded since the last LP */
765  gain = SCIPgetLPObjval(scip) - lastlpobjval;
766  gain = MAX(gain, 0.0);
767  gain /= (1.0 * (SCIPgetProbingDepth(scip) - lastlpdepth));
768 
769  /* loop over previously fixed candidates and share gain improvement */
770  for( v = 0; v <= prevcandsinsertidx; ++v )
771  {
772  SCIP_VAR* cand = previouscands[v];
773  SCIP_Real val = previousvals[v];
774  SCIP_Real solval = SCIPgetSolVal(scip, worksol, cand);
775 
776  /* todo: should the gain be shared with a smaller weight, instead of dividing the gain itself? */
777  /* it may happen that a variable had an integral solution value beforehand, e.g., for indicator variables */
778  if( ! SCIPisZero(scip, val - solval) )
779  {
780  SCIP_CALL( SCIPupdateVarPseudocost(scip, cand, val - solval, gain, 1.0) );
781  }
782  }
783  }
784  else
785  nlpcands = 0;
786  SCIPdebugMessage(" -> lpsolstat=%d, objval=%g/%g, nfrac=%d\n", SCIPgetLPSolstat(scip), SCIPgetLPObjval(scip), searchbound, nlpcands);
787  }
788 
789  success = FALSE;
790  /* check if a solution has been found */
791  if( !enfosuccess && !lperror && !cutoff && SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL )
792  {
793  /* create solution from diving LP */
794  SCIP_CALL( SCIPlinkLPSol(scip, worksol) );
795  SCIPdebugMessage("%s found primal solution: obj=%g\n", SCIPdivesetGetName(diveset), SCIPgetSolOrigObj(scip, worksol));
796 
797  /* try to add solution to SCIP */
798  SCIP_CALL( SCIPtrySol(scip, worksol, FALSE, FALSE, FALSE, FALSE, &success) );
799 
800  /* check, if solution was feasible and good enough */
801  if( success )
802  {
803  SCIPdebugMessage(" -> solution was feasible and good enough\n");
804  *result = SCIP_FOUNDSOL;
805  }
806  }
807 
808  SCIPupdateDivesetStats(scip, diveset, totalnprobingnodes, totalnbacktracks, SCIPgetNSolsFound(scip) - oldnsolsfound,
809  SCIPgetNBestSolsFound(scip) - oldnbestsolsfound, success);
810 
811  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",
812  SCIPgetNNodes(scip), SCIPdivesetGetName(diveset), nlpcands, SCIPgetProbingDepth(scip), maxdivedepth, SCIPdivesetGetNLPIterations(diveset), maxnlpiterations,
813  SCIPretransformObj(scip, SCIPgetLPObjval(scip)), SCIPretransformObj(scip, searchbound), SCIPgetLPSolstat(scip), cutoff);
814 
815  TERMINATE:
816  /* end probing mode */
817  SCIP_CALL( SCIPendProbing(scip) );
818 
820 
821  if( onlylpbranchcands )
822  {
823  SCIPfreeBufferArray(scip, &lpcandroundup);
824  SCIPfreeBufferArray(scip, &lpcandsscores);
825  }
826  SCIPfreeBufferArray(scip, &previousvals);
827  SCIPfreeBufferArray(scip, &previouscands);
828 
829  return SCIP_OKAY;
830 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:51
SCIP_RETCODE SCIPunlinkSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:34812
SCIP_RETCODE SCIPsolveProbingLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition: scip.c:32788
SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
Definition: scip.c:33125
SCIP_RETCODE SCIPaddDiveBoundChange(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Real value, SCIP_Bool preferred)
Definition: scip.c:33039
SCIP_Real SCIPgetAvgLowerbound(SCIP *scip)
Definition: scip.c:38350
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
Definition: scip.c:41685
int SCIPgetNVars(SCIP *scip)
Definition: scip.c:10698
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip.c:5878
int SCIPdivesetGetLPSolveFreq(SCIP_DIVESET *diveset)
Definition: heur.c:530
void SCIPupdateDivesetLPStats(SCIP *scip, SCIP_DIVESET *diveset, SCIP_Longint niterstoadd)
Definition: scip.c:32925
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:10672
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16443
SCIP_Bool SCIPdivesetUseBacktrack(SCIP_DIVESET *diveset)
Definition: heur.c:522
void SCIPclearDiveBoundChanges(SCIP *scip)
Definition: scip.c:33092
const char * SCIPdivesetGetName(SCIP_DIVESET *diveset)
Definition: heur.c:331
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip.h:20589
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition: heur.c:1147
SCIP_RETCODE SCIPbacktrackProbing(SCIP *scip, int probingdepth)
Definition: scip.c:32250
SCIP_Bool SCIPvarMayRoundDown(SCIP_VAR *var)
Definition: var.c:3259
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip.c:1248
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41920
SCIP_Longint SCIPgetNLPIterations(SCIP *scip)
Definition: scip.c:37454
library methods for diving heuristics
void SCIPenableVarHistory(SCIP *scip)
Definition: scip.c:23145
#define NULL
Definition: lpi_spx.cpp:130
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17113
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:32552
#define FALSE
Definition: def.h:56
int SCIPgetNBinVars(SCIP *scip)
Definition: scip.c:10743
#define TRUE
Definition: def.h:55
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:23184
#define SCIP_CALL(x)
Definition: def.h:266
#define MINLPITER
Definition: dive.c:28
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
Definition: scip.c:38561
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip.c:26439
#define SCIPdebugMessage
Definition: pub_message.h:77
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip.c:34983
int SCIPdivesetGetNCalls(SCIP_DIVESET *diveset)
Definition: heur.c:365
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition: scip.c:26482
SCIP_Real SCIPgetLowerbound(SCIP *scip)
Definition: scip.c:38393
void SCIPupdateDivesetStats(SCIP *scip, SCIP_DIVESET *diveset, int nprobingnodes, int nbacktracks, SCIP_Longint nsolsfound, SCIP_Longint nbestsolsfound, SCIP_Bool leavewassol)
Definition: scip.c:32938
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:35066
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:41585
SCIP_Real SCIPgetAvgDualbound(SCIP *scip)
Definition: scip.c:38331
SCIP_Real SCIPgetDualbound(SCIP *scip)
Definition: scip.c:38372
SCIP_Real SCIPdivesetGetMaxLPIterQuot(SCIP_DIVESET *diveset)
Definition: heur.c:475
#define SCIPerrorMessage
Definition: pub_message.h:45
SCIP_Bool SCIPisObjIntegral(SCIP *scip)
Definition: scip.c:10310
int SCIPgetProbingDepth(SCIP *scip)
Definition: scip.c:32223
int SCIPgetMaxDepth(SCIP *scip)
Definition: scip.c:38214
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41598
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41907
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
Definition: scip.c:41758
SCIP_Real SCIPinfinity(SCIP *scip)
Definition: scip.c:41637
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
Definition: scip.c:26354
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:32901
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41946
SCIP_Longint SCIPgetLastDivenode(SCIP *scip)
Definition: scip.c:32067
int SCIPgetDepthLimit(SCIP *scip)
Definition: scip.c:38190
SCIP_RETCODE SCIPgetDiveBoundChanges(SCIP *scip, SCIP_DIVESET *diveset, SCIP_SOL *sol, SCIP_Bool *success, SCIP_Bool *infeasible)
Definition: scip.c:32978
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:17123
void SCIPgetDiveBoundChangeData(SCIP *scip, SCIP_VAR ***variables, SCIP_BRANCHDIR **directions, SCIP_Real **values, int *ndivebdchgs, SCIP_Bool preferred)
Definition: scip.c:33065
#define SCIP_Bool
Definition: def.h:53
SCIP_Real SCIPdivesetGetUbQuotNoSol(SCIP_DIVESET *diveset)
Definition: heur.c:491
SCIP_Real SCIPretransformObj(SCIP *scip, SCIP_Real obj)
Definition: scip.c:35198
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:32153
SCIP_RETCODE SCIPendProbing(SCIP *scip)
Definition: scip.c:32285
SCIP_Longint SCIPdivesetGetNLPIterations(SCIP_DIVESET *diveset)
Definition: heur.c:445
int SCIPgetDepth(SCIP *scip)
Definition: scip.c:38140
SCIP_RETCODE SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:34648
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41624
#define SCIP_REAL_MIN
Definition: def.h:129
void SCIPdivesetSetWorkSolution(SCIP_DIVESET *diveset, SCIP_SOL *sol)
Definition: heur.c:320
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
Definition: scip.c:41770
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:20585
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:38746
int SCIPgetNIntVars(SCIP *scip)
Definition: scip.c:10788
SCIP_RETCODE SCIPchgVarUbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip.c:32352
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41933
#define SCIP_Real
Definition: def.h:127
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
Definition: scip.c:32190
SCIP_RETCODE SCIPchgVarLbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip.c:32318
#define MIN(x, y)
Definition: memory.c:67
int SCIPgetNSOS1Vars(SCIP_CONSHDLR *conshdlr)
Definition: cons_sos1.c:10570
constraint handler for SOS type 1 constraints
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41959
SCIP_Bool SCIPvarMayRoundUp(SCIP_VAR *var)
Definition: var.c:3267
#define SCIP_INVALID
Definition: def.h:147
#define SCIP_Longint
Definition: def.h:112
SCIP_Real SCIPdivesetGetAvgQuotNoSol(SCIP_DIVESET *diveset)
Definition: heur.c:499
int SCIPdivesetGetMaxLPIterOffset(SCIP_DIVESET *diveset)
Definition: heur.c:483
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:20597
SCIP_Bool SCIPisLPSolBasic(SCIP *scip)
Definition: scip.c:26847
public methods for primal heuristics
SCIP_Longint SCIPgetNNodeLPIterations(SCIP *scip)
Definition: scip.c:37749
#define SCIP_DIVETYPE_INTEGRALITY
Definition: type_heur.h:45
#define SCIPABORT()
Definition: def.h:238
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:36217
SCIP_Longint SCIPgetNNodes(SCIP *scip)
Definition: scip.c:37372
SCIP_Bool SCIPdivesetUseOnlyLPBranchcands(SCIP_DIVESET *diveset)
Definition: heur.c:552
SCIP_Longint SCIPgetNBestSolsFound(SCIP *scip)
Definition: scip.c:38794
SCIP_RETCODE SCIProundSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
Definition: scip.c:35909