Scippy

SCIP

Solving Constraint Integer Programs

heur_coefdiving.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-2014 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 heur_coefdiving.c
17  * @brief LP diving heuristic that chooses fixings w.r.t. the matrix coefficients
18  * @author Tobias Achterberg
19  * @author Marc Pfetsch
20  *
21  * Indicator constraints are taken into account if present.
22  */
23 
24 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
25 
26 #include <assert.h>
27 #include <string.h>
28 
29 #include "scip/heur_coefdiving.h"
30 #include "scip/cons_indicator.h"
31 
32 
33 #define HEUR_NAME "coefdiving"
34 #define HEUR_DESC "LP diving heuristic that chooses fixings w.r.t. the matrix coefficients"
35 #define HEUR_DISPCHAR 'c'
36 #define HEUR_PRIORITY -1001000
37 #define HEUR_FREQ 10
38 #define HEUR_FREQOFS 1
39 #define HEUR_MAXDEPTH -1
40 #define HEUR_TIMING SCIP_HEURTIMING_AFTERLPPLUNGE
41 #define HEUR_USESSUBSCIP FALSE /**< does the heuristic use a secondary SCIP instance? */
42 
43 
44 /*
45  * Default parameter settings
46  */
47 
48 #define DEFAULT_MINRELDEPTH 0.0 /**< minimal relative depth to start diving */
49 #define DEFAULT_MAXRELDEPTH 1.0 /**< maximal relative depth to start diving */
50 #define DEFAULT_MAXLPITERQUOT 0.05 /**< maximal fraction of diving LP iterations compared to node LP iterations */
51 #define DEFAULT_MAXLPITEROFS 1000 /**< additional number of allowed LP iterations */
52 #define DEFAULT_MAXDIVEUBQUOT 0.8 /**< maximal quotient (curlowerbound - lowerbound)/(cutoffbound - lowerbound)
53  * where diving is performed (0.0: no limit) */
54 #define DEFAULT_MAXDIVEAVGQUOT 0.0 /**< maximal quotient (curlowerbound - lowerbound)/(avglowerbound - lowerbound)
55  * where diving is performed (0.0: no limit) */
56 #define DEFAULT_MAXDIVEUBQUOTNOSOL 0.1 /**< maximal UBQUOT when no solution was found yet (0.0: no limit) */
57 #define DEFAULT_MAXDIVEAVGQUOTNOSOL 0.0 /**< maximal AVGQUOT when no solution was found yet (0.0: no limit) */
58 #define DEFAULT_BACKTRACK TRUE /**< use one level of backtracking if infeasibility is encountered? */
59 
60 #define MINLPITER 10000 /**< minimal number of LP iterations allowed in each LP solving call */
61 
62 
63 /* locally defined heuristic data */
64 struct SCIP_HeurData
65 {
66  SCIP_SOL* sol; /**< working solution */
67  SCIP_Real minreldepth; /**< minimal relative depth to start diving */
68  SCIP_Real maxreldepth; /**< maximal relative depth to start diving */
69  SCIP_Real maxlpiterquot; /**< maximal fraction of diving LP iterations compared to node LP iterations */
70  int maxlpiterofs; /**< additional number of allowed LP iterations */
71  SCIP_Real maxdiveubquot; /**< maximal quotient (curlowerbound - lowerbound)/(cutoffbound - lowerbound)
72  * where diving is performed (0.0: no limit) */
73  SCIP_Real maxdiveavgquot; /**< maximal quotient (curlowerbound - lowerbound)/(avglowerbound - lowerbound)
74  * where diving is performed (0.0: no limit) */
75  SCIP_Real maxdiveubquotnosol; /**< maximal UBQUOT when no solution was found yet (0.0: no limit) */
76  SCIP_Real maxdiveavgquotnosol;/**< maximal AVGQUOT when no solution was found yet (0.0: no limit) */
77  SCIP_Bool backtrack; /**< use one level of backtracking if infeasibility is encountered? */
78  SCIP_Longint nlpiterations; /**< LP iterations used in this heuristic */
79  int nsuccess; /**< number of runs that produced at least one feasible solution */
80  SCIP_CONSHDLR* indconshdlr; /**< indicator constraint handler (or NULL) */
81 };
82 
83 
84 /*
85  * local methods
86  */
87 
88 
89 /** get indicator candidate variables */
90 static
92  SCIP* scip, /**< SCIP data structure */
93  SCIP_CONS** indconss, /**< indicator constraints */
94  int nindconss, /**< number of indicator constraints */
95  SCIP_VAR** indcands, /**< indicator candidate variables */
96  SCIP_Real* indcandssol, /**< solution values of candidates */
97  SCIP_Real* indcandfrac, /**< fractionalities of candidates */
98  int* nindcands /**< number of candidates */
99  )
100 {
101  SCIP_VAR* binvar;
102  SCIP_Real val;
103  int c;
104 
105  assert( scip != NULL );
106  assert( indconss != NULL );
107  assert( indcands != NULL );
108  assert( nindcands != NULL );
109  assert( indcandssol != NULL );
110  assert( indcandfrac != NULL );
111 
112  *nindcands = 0;
113  for (c = 0; c < nindconss; ++c)
114  {
115  /* check whether constraint is violated */
116  if ( SCIPisViolatedIndicator(scip, indconss[c], NULL) )
117  {
118  binvar = SCIPgetBinaryVarIndicator(indconss[c]);
119  val = SCIPgetSolVal(scip, NULL, binvar);
120 
121  /* fractional indicator variables are treated by lpcands */
122  if ( SCIPisFeasIntegral(scip, val) )
123  {
124  indcands[*nindcands] = binvar;
125  indcandssol[*nindcands] = val;
126  indcandfrac[*nindcands] = SCIPfrac(scip, val);
127  ++(*nindcands);
128  }
129  }
130  }
131 
132  return SCIP_OKAY;
133 }
134 
135 /** choose best candidate variable */
136 static
138  SCIP* scip, /**< SCIP data structure */
139  SCIP_VAR** cands, /**< candidate variables */
140  SCIP_Real* candssol, /**< solution values of candidates */
141  SCIP_Real* candsfrac, /**< fractional solution values of candidates */
142  int ncands, /**< number of candidates */
143  int* bestcand, /**< bestcandidate */
144  int* bestnviolrows, /**< number of violated rows for best candidate */
145  SCIP_Real* bestcandsol, /**< solution of best candidate */
146  SCIP_Real* bestcandfrac, /**< fractionality of best candidate */
147  SCIP_Bool* bestcandmayrounddown,/**< whether best candidate may be rounded down */
148  SCIP_Bool* bestcandmayroundup, /**< whether best candidate may be rounded down */
149  SCIP_Bool* bestcandroundup /**< whether the best candidate should be rounded up */
150  )
151 {
152  SCIP_Bool mayrounddown;
153  SCIP_Bool mayroundup;
154  SCIP_Bool roundup;
155  SCIP_Real frac;
156  SCIP_VAR* var;
157  int nlocksdown;
158  int nlocksup;
159  int nviolrows;
160  int c;
161 
162  assert( cands != NULL );
163  assert( candsfrac != NULL );
164  assert( candssol != NULL );
165  assert( bestcand != NULL );
166  assert( bestnviolrows != NULL );
167  assert( bestcandfrac != NULL );
168  assert( bestcandsol != NULL );
169  assert( bestcandfrac != NULL );
170  assert( bestcandmayroundup != NULL );
171  assert( bestcandmayrounddown != NULL );
172  assert( bestcandroundup != NULL );
173 
174  for( c = 0; c < ncands; ++c )
175  {
176  var = cands[c];
177  mayrounddown = SCIPvarMayRoundDown(var);
178  mayroundup = SCIPvarMayRoundUp(var);
179  frac = candsfrac[c];
180  if( mayrounddown || mayroundup )
181  {
182  /* the candidate may be rounded: choose this candidate only, if the best candidate may also be rounded */
183  if( *bestcandmayrounddown || *bestcandmayroundup )
184  {
185  /* choose rounding direction:
186  * - if variable may be rounded in both directions, round corresponding to the fractionality
187  * - otherwise, round in the infeasible direction, because feasible direction is tried by rounding
188  * the current fractional solution
189  */
190  if( mayrounddown && mayroundup )
191  roundup = (frac > 0.5);
192  else
193  roundup = mayrounddown;
194 
195  if( roundup )
196  {
197  frac = 1.0 - frac;
198  nviolrows = SCIPvarGetNLocksUp(var);
199  }
200  else
201  nviolrows = SCIPvarGetNLocksDown(var);
202 
203  /* penalize too small fractions */
204  if( frac < 0.01 )
205  nviolrows *= 100;
206 
207  /* prefer decisions on binary variables */
208  if( !SCIPvarIsBinary(var) )
209  nviolrows *= 100;
210 
211  /* check, if candidate is new best candidate */
212  assert( (0.0 < frac && frac < 1.0) || SCIPvarIsBinary(var) );
213  if( nviolrows + frac < *bestnviolrows + *bestcandfrac )
214  {
215  *bestcand = c;
216  *bestnviolrows = nviolrows;
217  *bestcandsol = candssol[c];
218  *bestcandfrac = frac;
219  *bestcandmayrounddown = mayrounddown;
220  *bestcandmayroundup = mayroundup;
221  *bestcandroundup = roundup;
222  }
223  }
224  }
225  else
226  {
227  /* the candidate may not be rounded */
228  nlocksdown = SCIPvarGetNLocksDown(var);
229  nlocksup = SCIPvarGetNLocksUp(var);
230  roundup = (nlocksdown > nlocksup || (nlocksdown == nlocksup && frac > 0.5));
231  if( roundup )
232  {
233  nviolrows = nlocksup;
234  frac = 1.0 - frac;
235  }
236  else
237  nviolrows = nlocksdown;
238 
239  /* penalize too small fractions */
240  if( frac < 0.01 )
241  nviolrows *= 100;
242 
243  /* prefer decisions on binary variables */
244  if( !SCIPvarIsBinary(var) )
245  nviolrows *= 100;
246 
247  /* check, if candidate is new best candidate: prefer unroundable candidates in any case */
248  assert( (0.0 < frac && frac < 1.0) || SCIPvarIsBinary(var) );
249  if( *bestcandmayrounddown || *bestcandmayroundup || nviolrows + frac < *bestnviolrows + *bestcandfrac )
250  {
251  *bestcand = c;
252  *bestnviolrows = nviolrows;
253  *bestcandsol = candssol[c];
254  *bestcandfrac = frac;
255  *bestcandmayrounddown = FALSE;
256  *bestcandmayroundup = FALSE;
257  *bestcandroundup = roundup;
258  }
259  assert( *bestcandfrac < SCIP_INVALID );
260  }
261  }
262 
263  return SCIP_OKAY;
264 }
265 
266 
267 /*
268  * Callback methods
269  */
270 
271 /** copy method for primal heuristic plugins (called when SCIP copies plugins) */
272 static
273 SCIP_DECL_HEURCOPY(heurCopyCoefdiving)
274 { /*lint --e{715}*/
275  assert(scip != NULL);
276  assert(heur != NULL);
277  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
278 
279  /* call inclusion method of constraint handler */
281 
282  return SCIP_OKAY;
283 }
284 
285 /** destructor of primal heuristic to free user data (called when SCIP is exiting) */
286 static
287 SCIP_DECL_HEURFREE(heurFreeCoefdiving) /*lint --e{715}*/
288 { /*lint --e{715}*/
289  SCIP_HEURDATA* heurdata;
290 
291  assert(heur != NULL);
292  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
293  assert(scip != NULL);
294 
295  /* free heuristic data */
296  heurdata = SCIPheurGetData(heur);
297  assert(heurdata != NULL);
298  SCIPfreeMemory(scip, &heurdata);
299  SCIPheurSetData(heur, NULL);
300 
301  return SCIP_OKAY;
302 }
303 
304 
305 /** initialization method of primal heuristic (called after problem was transformed) */
306 static
307 SCIP_DECL_HEURINIT(heurInitCoefdiving) /*lint --e{715}*/
308 { /*lint --e{715}*/
309  SCIP_HEURDATA* heurdata;
310 
311  assert(heur != NULL);
312  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
313 
314  /* get heuristic data */
315  heurdata = SCIPheurGetData(heur);
316  assert(heurdata != NULL);
317 
318  /* create working solution */
319  SCIP_CALL( SCIPcreateSol(scip, &heurdata->sol, heur) );
320 
321  /* initialize data */
322  heurdata->nlpiterations = 0;
323  heurdata->nsuccess = 0;
324 
325  /* get indicator constraint hanlder */
326  heurdata->indconshdlr = SCIPfindConshdlr(scip, "indicator");
327 
328  return SCIP_OKAY;
329 }
330 
331 
332 /** deinitialization method of primal heuristic (called before transformed problem is freed) */
333 static
334 SCIP_DECL_HEUREXIT(heurExitCoefdiving) /*lint --e{715}*/
335 { /*lint --e{715}*/
336  SCIP_HEURDATA* heurdata;
337 
338  assert(heur != NULL);
339  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
340 
341  /* get heuristic data */
342  heurdata = SCIPheurGetData(heur);
343  assert(heurdata != NULL);
344 
345  /* free working solution */
346  SCIP_CALL( SCIPfreeSol(scip, &heurdata->sol) );
347 
348  return SCIP_OKAY;
349 }
350 
351 
352 /** execution method of primal heuristic */
353 static
354 SCIP_DECL_HEUREXEC(heurExecCoefdiving) /*lint --e{715}*/
355 { /*lint --e{715}*/
356  SCIP_HEURDATA* heurdata;
357  SCIP_LPSOLSTAT lpsolstat;
358  SCIP_CONS** indconss;
359  SCIP_VAR** indcands;
360  SCIP_VAR** lpcands;
361  SCIP_VAR* bestcandvar;
362  SCIP_Real* lpcandssol;
363  SCIP_Real* lpcandsfrac;
364  SCIP_Real* indcandssol;
365  SCIP_Real* indcandfrac;
366  SCIP_Real searchubbound;
367  SCIP_Real searchavgbound;
368  SCIP_Real searchbound;
369  SCIP_Real objval;
370  SCIP_Real oldobjval;
371  SCIP_Real bestcandsol;
372  SCIP_Real bestcandfrac;
373  SCIP_Bool bestcandmayrounddown;
374  SCIP_Bool bestcandmayroundup;
375  SCIP_Bool bestcandroundup;
376  SCIP_Bool lperror;
377  SCIP_Bool cutoff;
378  SCIP_Bool backtracked;
379  SCIP_Bool backtrack;
380  SCIP_Bool roundup;
381  SCIP_Longint ncalls;
382  SCIP_Longint nsolsfound;
383  SCIP_Longint nlpiterations;
384  SCIP_Longint maxnlpiterations;
385  int nindconss;
386  int nlpcands;
387  int nindcands;
388  int startnlpcands;
389  int depth;
390  int maxdepth;
391  int maxdivedepth;
392  int divedepth;
393  int bestnviolrows;
394  int bestindcand;
395  int bestlpcand;
396 
397  assert(heur != NULL);
398  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
399  assert(scip != NULL);
400  assert(result != NULL);
401 
402  *result = SCIP_DELAYED;
403 
404  /* do not call heuristic of node was already detected to be infeasible */
405  if( nodeinfeasible )
406  return SCIP_OKAY;
407 
408  /* only call heuristic, if an optimal LP solution is at hand */
410  return SCIP_OKAY;
411 
412  /* only call heuristic, if the LP objective value is smaller than the cutoff bound */
413  if( SCIPisGE(scip, SCIPgetLPObjval(scip), SCIPgetCutoffbound(scip)) )
414  return SCIP_OKAY;
415 
416  /* only call heuristic, if the LP solution is basic (which allows fast resolve in diving) */
417  if( !SCIPisLPSolBasic(scip) )
418  return SCIP_OKAY;
419 
420  /* don't dive two times at the same node */
421  if( SCIPgetLastDivenode(scip) == SCIPgetNNodes(scip) && SCIPgetDepth(scip) > 0 )
422  return SCIP_OKAY;
423 
424  *result = SCIP_DIDNOTRUN;
425 
426  /* get heuristic's data */
427  heurdata = SCIPheurGetData(heur);
428  assert(heurdata != NULL);
429 
430  /* only try to dive, if we are in the correct part of the tree, given by minreldepth and maxreldepth */
431  depth = SCIPgetDepth(scip);
432  maxdepth = SCIPgetMaxDepth(scip);
433  maxdepth = MAX(maxdepth, 30);
434  if( depth < heurdata->minreldepth*maxdepth || depth > heurdata->maxreldepth*maxdepth )
435  return SCIP_OKAY;
436 
437  /* calculate the maximal number of LP iterations until heuristic is aborted */
438  nlpiterations = SCIPgetNNodeLPIterations(scip);
439  ncalls = SCIPheurGetNCalls(heur);
440  nsolsfound = 10*SCIPheurGetNBestSolsFound(heur) + heurdata->nsuccess;
441  maxnlpiterations = (SCIP_Longint)((1.0 + 10.0*(nsolsfound+1.0)/(ncalls+1.0)) * heurdata->maxlpiterquot * nlpiterations);
442  maxnlpiterations += heurdata->maxlpiterofs;
443 
444  /* don't try to dive, if we took too many LP iterations during diving */
445  if( heurdata->nlpiterations >= maxnlpiterations )
446  return SCIP_OKAY;
447 
448  /* allow at least a certain number of LP iterations in this dive */
449  maxnlpiterations = MAX(maxnlpiterations, heurdata->nlpiterations + MINLPITER);
450 
451  /* get fractional variables that should be integral */
452  SCIP_CALL( SCIPgetLPBranchCands(scip, &lpcands, &lpcandssol, &lpcandsfrac, &nlpcands, NULL, NULL) );
453 
454  /* get indicator variable candidates */
455  nindconss = 0;
456  indconss = NULL;
457  nindcands = 0;
458  indcands = NULL;
459  indcandssol = NULL;
460  indcandfrac = NULL;
461  if ( heurdata->indconshdlr != NULL )
462  {
463  indconss = SCIPconshdlrGetConss(heurdata->indconshdlr);
464  nindconss = SCIPconshdlrGetNConss(heurdata->indconshdlr);
465 
466  if ( nindconss > 0 )
467  {
468  /* get storage for candidate variables */
469  SCIP_CALL( SCIPallocBufferArray(scip, &indcands, nindconss) );
470  SCIP_CALL( SCIPallocBufferArray(scip, &indcandssol, nindconss) );
471  SCIP_CALL( SCIPallocBufferArray(scip, &indcandfrac, nindconss) );
472 
473  /* get indicator canditates */
474  SCIP_CALL( getIndCandVars(scip, indconss, nindconss, indcands, indcandssol, indcandfrac, &nindcands) );
475  }
476  }
477 
478  /* don't try to dive, if there are no fractional variables and no indicator candidates */
479  if( nlpcands == 0 && nindcands == 0 )
480  {
481  SCIPfreeBufferArrayNull(scip, &indcandfrac);
482  SCIPfreeBufferArrayNull(scip, &indcandssol);
483  SCIPfreeBufferArrayNull(scip, &indcands);
484  return SCIP_OKAY;
485  }
486 
487  /* calculate the objective search bound */
488  if( SCIPgetNSolsFound(scip) == 0 )
489  {
490  if( heurdata->maxdiveubquotnosol > 0.0 )
491  searchubbound = SCIPgetLowerbound(scip)
492  + heurdata->maxdiveubquotnosol * (SCIPgetCutoffbound(scip) - SCIPgetLowerbound(scip));
493  else
494  searchubbound = SCIPinfinity(scip);
495  if( heurdata->maxdiveavgquotnosol > 0.0 )
496  searchavgbound = SCIPgetLowerbound(scip)
497  + heurdata->maxdiveavgquotnosol * (SCIPgetAvgLowerbound(scip) - SCIPgetLowerbound(scip));
498  else
499  searchavgbound = SCIPinfinity(scip);
500  }
501  else
502  {
503  if( heurdata->maxdiveubquot > 0.0 )
504  searchubbound = SCIPgetLowerbound(scip)
505  + heurdata->maxdiveubquot * (SCIPgetCutoffbound(scip) - SCIPgetLowerbound(scip));
506  else
507  searchubbound = SCIPinfinity(scip);
508  if( heurdata->maxdiveavgquot > 0.0 )
509  searchavgbound = SCIPgetLowerbound(scip)
510  + heurdata->maxdiveavgquot * (SCIPgetAvgLowerbound(scip) - SCIPgetLowerbound(scip));
511  else
512  searchavgbound = SCIPinfinity(scip);
513  }
514  searchbound = MIN(searchubbound, searchavgbound);
515  if( SCIPisObjIntegral(scip) )
516  searchbound = SCIPceil(scip, searchbound);
517 
518  /* calculate the maximal diving depth: 10 * min{number of integer variables, max depth} */
519  maxdivedepth = SCIPgetNBinVars(scip) + SCIPgetNIntVars(scip);
520  maxdivedepth = MIN(maxdivedepth, maxdepth);
521  maxdivedepth *= 10;
522 
523  *result = SCIP_DIDNOTFIND;
524 
525  /* start diving */
526  SCIP_CALL( SCIPstartProbing(scip) );
527 
528  /* enables collection of variable statistics during probing */
529  SCIPenableVarHistory(scip);
530 
531  /* get LP objective value */
532  lpsolstat = SCIP_LPSOLSTAT_OPTIMAL;
533  objval = SCIPgetLPObjval(scip);
534 
535  SCIPdebugMessage("(node %"SCIP_LONGINT_FORMAT") executing coefdiving heuristic: depth=%d, %d fractionals, dualbound=%g, avgbound=%g, cutoffbound=%g, searchbound=%g\n",
536  SCIPgetNNodes(scip), SCIPgetDepth(scip), nlpcands, SCIPgetDualbound(scip), SCIPgetAvgDualbound(scip),
537  SCIPretransformObj(scip, SCIPgetCutoffbound(scip)), SCIPretransformObj(scip, searchbound));
538 
539  /* dive as long we are in the given objective, depth and iteration limits and fractional variables exist, but
540  * - if possible, we dive at least with the depth 10
541  * - if the number of fractional variables decreased at least with 1 variable per 2 dive depths, we continue diving
542  */
543  lperror = FALSE;
544  cutoff = FALSE;
545  divedepth = 0;
546  bestcandmayrounddown = FALSE;
547  bestcandmayroundup = FALSE;
548  startnlpcands = nlpcands + nindcands;
549  roundup = FALSE;
550  while( !lperror && !cutoff && lpsolstat == SCIP_LPSOLSTAT_OPTIMAL && nlpcands > 0
551  && (divedepth < 10
552  || nlpcands <= startnlpcands - divedepth/2
553  || (divedepth < maxdivedepth && heurdata->nlpiterations < maxnlpiterations && objval < searchbound))
554  && !SCIPisStopped(scip) )
555  {
556  SCIP_CALL( SCIPnewProbingNode(scip) );
557  divedepth++;
558 
559  /* choose variable fixing:
560  * - prefer variables that may not be rounded without destroying LP feasibility:
561  * - of these variables, round variable with least number of locks in corresponding direction
562  * - if all remaining fractional variables may be rounded without destroying LP feasibility:
563  * - round variable with least number of locks in opposite of its feasible rounding direction
564  */
565  bestlpcand = -1;
566  bestindcand = -1;
567  bestcandvar = NULL;
568  bestnviolrows = INT_MAX;
569  bestcandsol = SCIP_INVALID;
570  bestcandfrac = SCIP_INVALID;
571  bestcandmayrounddown = TRUE;
572  bestcandmayroundup = TRUE;
573  bestcandroundup = FALSE;
574 
575  /* get best lp candidate */
576  if ( nlpcands > 0 )
577  {
578  SCIP_CALL( getBestCandidate(scip, lpcands, lpcandssol, lpcandsfrac, nlpcands, &bestlpcand, &bestnviolrows, &bestcandsol, &bestcandfrac,
579  &bestcandmayrounddown, &bestcandmayroundup, &bestcandroundup) );
580  bestcandvar = lpcands[bestlpcand];
581  assert(bestlpcand >= 0);
582  }
583 
584  /* get best indicator candidate */
585  if ( nindconss > 0 )
586  {
587  assert( indcands != NULL );
588  assert( indcandssol != NULL );
589  assert( indcandfrac != NULL );
590  SCIP_CALL( getBestCandidate(scip, indcands, indcandssol, indcandfrac, nindcands, &bestindcand, &bestnviolrows, &bestcandsol, &bestcandfrac,
591  &bestcandmayrounddown, &bestcandmayroundup, &bestcandroundup) );
592  if ( bestindcand >= 0 )
593  bestcandvar = indcands[bestindcand];
594  }
595 
596  /* if all candidates are roundable, try to round the solution */
597  if( bestcandmayrounddown || bestcandmayroundup )
598  {
599  SCIP_Bool success;
600 
601  /* create solution from diving LP and try to round it */
602  SCIP_CALL( SCIPlinkLPSol(scip, heurdata->sol) );
603  SCIP_CALL( SCIProundSol(scip, heurdata->sol, &success) );
604 
605  if( success )
606  {
607  SCIPdebugMessage("coefdiving found roundable primal solution: obj=%g\n", SCIPgetSolOrigObj(scip, heurdata->sol));
608 
609  /* try to correct indicator constraints */
610  if ( nindconss > 0 )
611  {
612  assert( heurdata->indconshdlr != NULL );
613  SCIP_CALL( SCIPmakeIndicatorsFeasible(scip, heurdata->indconshdlr, heurdata->sol, &success) );
614  }
615 
616  /* try to add solution to SCIP */
617  SCIP_CALL( SCIPtrySol(scip, heurdata->sol, FALSE, FALSE, FALSE, FALSE, &success) );
618 
619  /* check, if solution was feasible and good enough */
620  if( success )
621  {
622  SCIPdebugMessage(" -> solution was feasible and good enough\n");
623  *result = SCIP_FOUNDSOL;
624  }
625  }
626  }
627 
628  backtracked = FALSE;
629  do
630  {
631  backtrack = FALSE;
632  /* if the variable is already fixed or if the solution value is outside the domain, numerical troubles may have
633  * occured or variable was fixed by propagation while backtracking => Abort diving!
634  */
635  if( SCIPvarGetLbLocal(bestcandvar) >= SCIPvarGetUbLocal(bestcandvar) - 0.5 )
636  {
637  SCIPdebugMessage("Selected variable <%s> already fixed to [%g,%g] (solval: %.9f), diving aborted \n",
638  SCIPvarGetName(bestcandvar), SCIPvarGetLbLocal(bestcandvar), SCIPvarGetUbLocal(bestcandvar), bestcandsol);
639  cutoff = TRUE;
640  break;
641  }
642  if( SCIPisFeasLT(scip, bestcandsol, SCIPvarGetLbLocal(bestcandvar)) || SCIPisFeasGT(scip, bestcandsol, SCIPvarGetUbLocal(bestcandvar)) )
643  {
644  SCIPdebugMessage("selected variable's <%s> solution value is outside the domain [%g,%g] (solval: %.9f), diving aborted\n",
645  SCIPvarGetName(bestcandvar), SCIPvarGetLbLocal(bestcandvar), SCIPvarGetUbLocal(bestcandvar), bestcandsol);
646  assert(backtracked);
647  break;
648  }
649 
650  /* apply rounding of best candidate */
651  if( bestcandroundup == !backtracked )
652  {
653  SCIP_Real value = SCIPfeasCeil(scip, bestcandsol);
654 
655  if ( SCIPisFeasIntegral(scip, bestcandsol) )
656  {
657  /* only indicator variables can have integral solution value */
658  assert(SCIPvarGetType(bestcandvar) == SCIP_VARTYPE_BINARY);
659  value = 1.0;
660  }
661 
662  /* round variable up */
663  SCIPdebugMessage(" dive %d/%d, LP iter %"SCIP_LONGINT_FORMAT"/%"SCIP_LONGINT_FORMAT": var <%s>, round=%u/%u, sol=%g, oldbounds=[%g,%g], newbounds=[%g,%g]\n",
664  divedepth, maxdivedepth, heurdata->nlpiterations, maxnlpiterations,
665  SCIPvarGetName(bestcandvar), bestcandmayrounddown, bestcandmayroundup,
666  bestcandsol, SCIPvarGetLbLocal(bestcandvar), SCIPvarGetUbLocal(bestcandvar),
667  value, SCIPvarGetUbLocal(bestcandvar));
668 
669  SCIP_CALL( SCIPchgVarLbProbing(scip, bestcandvar, value) );
670  roundup = TRUE;
671  }
672  else
673  {
674  SCIP_Real value = SCIPfeasFloor(scip, bestcandsol);
675 
676  if ( SCIPisFeasIntegral(scip, bestcandsol) )
677  {
678  /* only indicator variables can have integral solution value */
679  assert(SCIPvarGetType(bestcandvar) == SCIP_VARTYPE_BINARY);
680  value = 0.0;
681  }
682 
683  /* round variable down */
684  SCIPdebugMessage(" dive %d/%d, LP iter %"SCIP_LONGINT_FORMAT"/%"SCIP_LONGINT_FORMAT": var <%s>, round=%u/%u, sol=%g, oldbounds=[%g,%g], newbounds=[%g,%g]\n",
685  divedepth, maxdivedepth, heurdata->nlpiterations, maxnlpiterations,
686  SCIPvarGetName(bestcandvar), bestcandmayrounddown, bestcandmayroundup,
687  bestcandsol, SCIPvarGetLbLocal(bestcandvar), SCIPvarGetUbLocal(bestcandvar),
688  SCIPvarGetLbLocal(bestcandvar), value);
689 
690  SCIP_CALL( SCIPchgVarUbProbing(scip, bestcandvar, value) );
691  roundup = FALSE;
692  }
693 
694  /* apply domain propagation */
695  SCIP_CALL( SCIPpropagateProbing(scip, 0, &cutoff, NULL) );
696  if( !cutoff )
697  {
698  /* resolve the diving LP */
699  /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
700  * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
701  */
702 #ifdef NDEBUG
703  SCIP_RETCODE retstat;
704  nlpiterations = SCIPgetNLPIterations(scip);
705  retstat = SCIPsolveProbingLP(scip, MAX((int)(maxnlpiterations - heurdata->nlpiterations), MINLPITER), &lperror, &cutoff);
706  if( retstat != SCIP_OKAY )
707  {
708  SCIPwarningMessage(scip, "Error while solving LP in Coefdiving heuristic; LP solve terminated with code <%d>\n",retstat);
709  }
710 #else
711  nlpiterations = SCIPgetNLPIterations(scip);
712  SCIP_CALL( SCIPsolveProbingLP(scip, MAX((int)(maxnlpiterations - heurdata->nlpiterations), MINLPITER), &lperror, &cutoff) );
713 #endif
714 
715  if( lperror )
716  break;
717 
718  /* update iteration count */
719  heurdata->nlpiterations += SCIPgetNLPIterations(scip) - nlpiterations;
720 
721  /* get LP solution status, objective value, and fractional variables, that should be integral */
722  lpsolstat = SCIPgetLPSolstat(scip);
723  assert(cutoff || (lpsolstat != SCIP_LPSOLSTAT_OBJLIMIT && lpsolstat != SCIP_LPSOLSTAT_INFEASIBLE &&
724  (lpsolstat != SCIP_LPSOLSTAT_OPTIMAL || SCIPisLT(scip, SCIPgetLPObjval(scip), SCIPgetCutoffbound(scip)))));
725  }
726 
727  /* perform backtracking if a cutoff was detected */
728  if( cutoff && !backtracked && heurdata->backtrack )
729  {
730  SCIPdebugMessage(" *** cutoff detected at level %d - backtracking\n", SCIPgetProbingDepth(scip));
732  SCIP_CALL( SCIPnewProbingNode(scip) );
733  backtracked = TRUE;
734  backtrack = TRUE;
735  }
736  else
737  backtrack = FALSE;
738  }
739  while( backtrack );
740 
741  if( !lperror && !cutoff && lpsolstat == SCIP_LPSOLSTAT_OPTIMAL )
742  {
743  /* get new objective value */
744  oldobjval = objval;
745  objval = SCIPgetLPObjval(scip);
746 
747  /* update pseudo cost values */
748  if( SCIPisGT(scip, objval, oldobjval) )
749  {
750  if( roundup )
751  {
752  assert(bestcandroundup || backtracked);
753  SCIP_CALL( SCIPupdateVarPseudocost(scip, bestcandvar, 1.0 - bestcandfrac, objval - oldobjval, 1.0) );
754  }
755  else
756  {
757  assert(!bestcandroundup || backtracked);
758  SCIP_CALL( SCIPupdateVarPseudocost(scip, bestcandvar, 0.0 - bestcandfrac, objval - oldobjval, 1.0) );
759  }
760  }
761 
762  /* get new fractional variables */
763  SCIP_CALL( SCIPgetLPBranchCands(scip, &lpcands, &lpcandssol, &lpcandsfrac, &nlpcands, NULL, NULL) );
764 
765  /* get indicator canditates */
766  if ( nindconss > 0 )
767  {
768  SCIP_CALL( getIndCandVars(scip, indconss, nindconss, indcands, indcandssol, indcandfrac, &nindcands) );
769  }
770  }
771  SCIPdebugMessage(" -> lpsolstat=%d, objval=%g/%g, nfrac=%d\n", lpsolstat, objval, searchbound, nlpcands);
772  }
773 
774  /* check if a solution has been found */
775  if( nlpcands == 0 && !lperror && !cutoff && lpsolstat == SCIP_LPSOLSTAT_OPTIMAL )
776  {
777  SCIP_Bool success;
778 
779  /* create solution from diving LP */
780  SCIP_CALL( SCIPlinkLPSol(scip, heurdata->sol) );
781  SCIPdebugMessage("coefdiving found primal solution: obj=%g\n", SCIPgetSolOrigObj(scip, heurdata->sol));
782 
783  /* try to add solution to SCIP */
784  SCIP_CALL( SCIPtrySol(scip, heurdata->sol, FALSE, FALSE, FALSE, FALSE, &success) );
785 
786  /* check, if solution was feasible and good enough */
787  if( success )
788  {
789  SCIPdebugMessage(" -> solution was feasible and good enough\n");
790  *result = SCIP_FOUNDSOL;
791  }
792  }
793 
794  /* free storage */
795  if ( nindconss > 0 )
796  {
797  assert( indconss != NULL );
798  assert( indcands != NULL );
799  assert( indcandssol != NULL );
800  assert( indcandfrac != NULL );
801 
802  SCIPfreeBufferArray(scip, &indcandfrac);
803  SCIPfreeBufferArray(scip, &indcandssol);
804  SCIPfreeBufferArray(scip, &indcands);
805  }
806 
807  /* end diving */
808  SCIP_CALL( SCIPendProbing(scip) );
809 
810  if( *result == SCIP_FOUNDSOL )
811  heurdata->nsuccess++;
812 
813  SCIPdebugMessage("(node %"SCIP_LONGINT_FORMAT") finished coefdiving heuristic: %d fractionals, dive %d/%d, LP iter %"SCIP_LONGINT_FORMAT"/%"SCIP_LONGINT_FORMAT", objval=%g/%g, lpsolstat=%d, cutoff=%u\n",
814  SCIPgetNNodes(scip), nlpcands, divedepth, maxdivedepth, heurdata->nlpiterations, maxnlpiterations,
815  SCIPretransformObj(scip, objval), SCIPretransformObj(scip, searchbound), lpsolstat, cutoff);
816 
817  return SCIP_OKAY;
818 }
819 
820 
821 /*
822  * heuristic specific interface methods
823  */
824 
825 /** creates the coefdiving heuristic and includes it in SCIP */
827  SCIP* scip /**< SCIP data structure */
828  )
829 {
830  SCIP_HEURDATA* heurdata;
831  SCIP_HEUR* heur;
832 
833  /* create coefdiving primal heuristic data */
834  SCIP_CALL( SCIPallocMemory(scip, &heurdata) );
835 
836  /* include primal heuristic */
837  SCIP_CALL( SCIPincludeHeurBasic(scip, &heur,
839  HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecCoefdiving, heurdata) );
840 
841  assert(heur != NULL);
842 
843  /* set non-NULL pointers to callback methods */
844  SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyCoefdiving) );
845  SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeCoefdiving) );
846  SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitCoefdiving) );
847  SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitCoefdiving) );
848 
849  /* coefdiving heuristic parameters */
851  "heuristics/coefdiving/minreldepth",
852  "minimal relative depth to start diving",
853  &heurdata->minreldepth, TRUE, DEFAULT_MINRELDEPTH, 0.0, 1.0, NULL, NULL) );
855  "heuristics/coefdiving/maxreldepth",
856  "maximal relative depth to start diving",
857  &heurdata->maxreldepth, TRUE, DEFAULT_MAXRELDEPTH, 0.0, 1.0, NULL, NULL) );
859  "heuristics/coefdiving/maxlpiterquot",
860  "maximal fraction of diving LP iterations compared to node LP iterations",
861  &heurdata->maxlpiterquot, FALSE, DEFAULT_MAXLPITERQUOT, 0.0, SCIP_REAL_MAX, NULL, NULL) );
863  "heuristics/coefdiving/maxlpiterofs",
864  "additional number of allowed LP iterations",
865  &heurdata->maxlpiterofs, FALSE, DEFAULT_MAXLPITEROFS, 0, INT_MAX, NULL, NULL) );
867  "heuristics/coefdiving/maxdiveubquot",
868  "maximal quotient (curlowerbound - lowerbound)/(cutoffbound - lowerbound) where diving is performed (0.0: no limit)",
869  &heurdata->maxdiveubquot, TRUE, DEFAULT_MAXDIVEUBQUOT, 0.0, 1.0, NULL, NULL) );
871  "heuristics/coefdiving/maxdiveavgquot",
872  "maximal quotient (curlowerbound - lowerbound)/(avglowerbound - lowerbound) where diving is performed (0.0: no limit)",
873  &heurdata->maxdiveavgquot, TRUE, DEFAULT_MAXDIVEAVGQUOT, 0.0, SCIP_REAL_MAX, NULL, NULL) );
875  "heuristics/coefdiving/maxdiveubquotnosol",
876  "maximal UBQUOT when no solution was found yet (0.0: no limit)",
877  &heurdata->maxdiveubquotnosol, TRUE, DEFAULT_MAXDIVEUBQUOTNOSOL, 0.0, 1.0, NULL, NULL) );
879  "heuristics/coefdiving/maxdiveavgquotnosol",
880  "maximal AVGQUOT when no solution was found yet (0.0: no limit)",
881  &heurdata->maxdiveavgquotnosol, TRUE, DEFAULT_MAXDIVEAVGQUOTNOSOL, 0.0, SCIP_REAL_MAX, NULL, NULL) );
883  "heuristics/coefdiving/backtrack",
884  "use one level of backtracking if infeasibility is encountered?",
885  &heurdata->backtrack, FALSE, DEFAULT_BACKTRACK, NULL, NULL) );
886 
887  return SCIP_OKAY;
888 }
889 
SCIP_RETCODE SCIPsolveProbingLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition: scip.c:29936
SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
Definition: scip.c:30002
SCIP_Real SCIPgetAvgLowerbound(SCIP *scip)
Definition: scip.c:35019
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip.c:5600
SCIP_RETCODE SCIPmakeIndicatorsFeasible(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_SOL *sol, SCIP_Bool *changed)
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:15788
#define DEFAULT_MINRELDEPTH
#define DEFAULT_MAXLPITERQUOT
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition: heur.c:591
SCIP_Longint SCIPheurGetNCalls(SCIP_HEUR *heur)
Definition: heur.c:717
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
Definition: scip.c:7014
SCIP_RETCODE SCIPbacktrackProbing(SCIP *scip, int probingdepth)
Definition: scip.c:29573
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:15968
SCIP_Bool SCIPvarMayRoundDown(SCIP_VAR *var)
Definition: var.c:3269
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip.c:1206
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:38667
SCIP_Longint SCIPgetNLPIterations(SCIP *scip)
Definition: scip.c:34147
int SCIPconshdlrGetNConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4239
void SCIPenableVarHistory(SCIP *scip)
Definition: scip.c:21124
#define NULL
Definition: lpi_spx.cpp:129
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:16426
SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4209
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip.c:1111
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
Definition: scip.c:38803
constraint handler for indicator constraints
SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, unsigned int timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
Definition: scip.c:6969
SCIP_VAR * SCIPgetBinaryVarIndicator(SCIP_CONS *cons)
static SCIP_DECL_HEUREXIT(heurExitCoefdiving)
#define HEUR_DESC
SCIP_RETCODE SCIPpropagateProbing(SCIP *scip, int maxproprounds, SCIP_Bool *cutoff, SCIP_Longint *ndomredsfound)
Definition: scip.c:29766
#define FALSE
Definition: def.h:52
int SCIPgetNBinVars(SCIP *scip)
Definition: scip.c:10116
#define TRUE
Definition: def.h:51
#define DEFAULT_BACKTRACK
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:21163
#define DEFAULT_MAXRELDEPTH
struct SCIP_HeurData SCIP_HEURDATA
Definition: type_heur.h:44
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
Definition: scip.c:38779
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
Definition: scip.c:35229
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip.c:24136
#define SCIPdebugMessage
Definition: pub_message.h:77
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip.c:31775
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:19214
#define DEFAULT_MAXDIVEUBQUOTNOSOL
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition: type_lp.h:42
#define HEUR_DISPCHAR
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition: scip.c:24179
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
Definition: scip.c:38815
SCIP_Real SCIPgetLowerbound(SCIP *scip)
Definition: scip.c:35061
LP diving heuristic that chooses fixings w.r.t. the matrix coefficients.
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:31855
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip.c:3388
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:3414
#define HEUR_USESSUBSCIP
#define HEUR_FREQOFS
SCIP_Bool SCIPisViolatedIndicator(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
#define HEUR_PRIORITY
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:38273
SCIP_Real SCIPgetAvgDualbound(SCIP *scip)
Definition: scip.c:35000
SCIP_Real SCIPgetDualbound(SCIP *scip)
Definition: scip.c:35040
#define SCIPallocMemory(scip, ptr)
Definition: scip.h:19159
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:19221
#define DEFAULT_MAXLPITEROFS
SCIP_Bool SCIPisObjIntegral(SCIP *scip)
Definition: scip.c:9683
#define DEFAULT_MAXDIVEUBQUOT
int SCIPgetProbingDepth(SCIP *scip)
Definition: scip.c:29546
int SCIPgetMaxDepth(SCIP *scip)
Definition: scip.c:34883
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip.c:30856
#define DEFAULT_MAXDIVEAVGQUOT
#define HEUR_FREQ
SCIP_RETCODE SCIPincludeHeurCoefdiving(SCIP *scip)
static SCIP_DECL_HEUREXEC(heurExecCoefdiving)
#define DEFAULT_MAXDIVEAVGQUOTNOSOL
int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition: var.c:3214
SCIP_Real SCIPinfinity(SCIP *scip)
Definition: scip.c:38349
#define SCIP_CALL(x)
Definition: def.h:258
static SCIP_RETCODE getIndCandVars(SCIP *scip, SCIP_CONS **indconss, int nindconss, SCIP_VAR **indcands, SCIP_Real *indcandssol, SCIP_Real *indcandfrac, int *nindcands)
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
Definition: scip.c:24051
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:38705
SCIP_Longint SCIPgetLastDivenode(SCIP *scip)
Definition: scip.c:29390
static SCIP_DECL_HEURINIT(heurInitCoefdiving)
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition: heur.c:512
static SCIP_DECL_HEURCOPY(heurCopyCoefdiving)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:38311
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:16436
#define SCIP_Bool
Definition: def.h:49
#define HEUR_TIMING
SCIP_Real SCIPretransformObj(SCIP *scip, SCIP_Real obj)
Definition: scip.c:31962
#define HEUR_NAME
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition: scip.h:19222
#define MAX(x, y)
Definition: tclique_def.h:75
SCIP_RETCODE SCIPstartProbing(SCIP *scip)
Definition: scip.c:29476
SCIP_RETCODE SCIPendProbing(SCIP *scip)
Definition: scip.c:29607
SCIP_Real SCIPfrac(SCIP *scip, SCIP_Real val)
Definition: scip.c:38506
int SCIPgetDepth(SCIP *scip)
Definition: scip.c:34833
SCIP_RETCODE SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:31444
SCIP_RETCODE SCIPsetHeurExit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXIT((*heurexit)))
Definition: scip.c:7062
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:38330
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINIT((*heurinit)))
Definition: scip.c:7046
static SCIP_RETCODE getBestCandidate(SCIP *scip, SCIP_VAR **cands, SCIP_Real *candssol, SCIP_Real *candsfrac, int ncands, int *bestcand, int *bestnviolrows, SCIP_Real *bestcandsol, SCIP_Real *bestcandfrac, SCIP_Bool *bestcandmayrounddown, SCIP_Bool *bestcandmayroundup, SCIP_Bool *bestcandroundup)
#define SCIP_REAL_MAX
Definition: def.h:124
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:15953
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
Definition: scip.c:38482
SCIP_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
Definition: heur.c:737
#define SCIPfreeMemory(scip, ptr)
Definition: scip.h:19176
SCIP_Longint SCIPgetNSolsFound(SCIP *scip)
Definition: scip.c:35410
int SCIPgetNIntVars(SCIP *scip)
Definition: scip.c:10161
SCIP_RETCODE SCIPchgVarUbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip.c:29674
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
Definition: scip.c:7030
#define HEUR_MAXDEPTH
#define SCIP_Real
Definition: def.h:123
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
Definition: scip.c:29513
static SCIP_DECL_HEURFREE(heurFreeCoefdiving)
SCIP_RETCODE SCIPchgVarLbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip.c:29640
#define MIN(x, y)
Definition: memory.c:59
SCIP_Bool SCIPvarMayRoundUp(SCIP_VAR *var)
Definition: var.c:3277
#define SCIP_INVALID
Definition: def.h:142
#define SCIP_Longint
Definition: def.h:107
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition: heur.c:502
SCIP_Bool SCIPisLPSolBasic(SCIP *scip)
Definition: scip.c:24544
SCIP_Longint SCIPgetNNodeLPIterations(SCIP *scip)
Definition: scip.c:34442
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip.c:3470
int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition: var.c:3159
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:32978
#define MINLPITER
SCIP_Longint SCIPgetNNodes(SCIP *scip)
Definition: scip.c:34065
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip.c:31403
SCIP_RETCODE SCIProundSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
Definition: scip.c:32673