Scippy

SCIP

Solving Constraint Integer Programs

heur_linesearchdiving.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_linesearchdiving.c
17  * @brief LP diving heuristic that fixes variables with a large difference to their root solution
18  * @author Tobias Achterberg
19  */
20 
21 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
22 
23 #include <assert.h>
24 #include <string.h>
25 
27 
28 
29 #define HEUR_NAME "linesearchdiving"
30 #define HEUR_DESC "LP diving heuristic that chooses fixings following the line from root solution to current solution"
31 #define HEUR_DISPCHAR 'l'
32 #define HEUR_PRIORITY -1006000
33 #define HEUR_FREQ 10
34 #define HEUR_FREQOFS 6
35 #define HEUR_MAXDEPTH -1
36 #define HEUR_TIMING SCIP_HEURTIMING_AFTERLPPLUNGE
37 #define HEUR_USESSUBSCIP FALSE /**< does the heuristic use a secondary SCIP instance? */
38 
39 
40 /*
41  * Default parameter settings
42  */
43 
44 #define DEFAULT_MINRELDEPTH 0.0 /**< minimal relative depth to start diving */
45 #define DEFAULT_MAXRELDEPTH 1.0 /**< maximal relative depth to start diving */
46 #define DEFAULT_MAXLPITERQUOT 0.05 /**< maximal fraction of diving LP iterations compared to node LP iterations */
47 #define DEFAULT_MAXLPITEROFS 1000 /**< additional number of allowed LP iterations */
48 #define DEFAULT_MAXDIVEUBQUOT 0.8 /**< maximal quotient (curlowerbound - lowerbound)/(cutoffbound - lowerbound)
49  * where diving is performed (0.0: no limit) */
50 #define DEFAULT_MAXDIVEAVGQUOT 0.0 /**< maximal quotient (curlowerbound - lowerbound)/(avglowerbound - lowerbound)
51  * where diving is performed (0.0: no limit) */
52 #define DEFAULT_MAXDIVEUBQUOTNOSOL 0.1 /**< maximal UBQUOT when no solution was found yet (0.0: no limit) */
53 #define DEFAULT_MAXDIVEAVGQUOTNOSOL 0.0 /**< maximal AVGQUOT when no solution was found yet (0.0: no limit) */
54 #define DEFAULT_BACKTRACK TRUE /**< use one level of backtracking if infeasibility is encountered? */
55 
56 #define MINLPITER 10000 /**< minimal number of LP iterations allowed in each LP solving call */
57 
58 
59 /*
60  * Data structures
61  */
62 
63 /** primal 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 };
81 
82 
83 /*
84  * Local methods
85  */
86 
87 
88 /*
89  * Callback methods of primal heuristic
90  */
91 
92 /** copy method for primal heuristic plugins (called when SCIP copies plugins) */
93 static
94 SCIP_DECL_HEURCOPY(heurCopyLinesearchdiving)
95 { /*lint --e{715}*/
96  assert(scip != NULL);
97  assert(heur != NULL);
98  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
99 
100  /* call inclusion method of primal heuristic */
102 
103  return SCIP_OKAY;
104 }
105 
106 /** destructor of primal heuristic to free user data (called when SCIP is exiting) */
107 static
108 SCIP_DECL_HEURFREE(heurFreeLinesearchdiving)
109 { /*lint --e{715}*/
110  SCIP_HEURDATA* heurdata;
111 
112  assert(heur != NULL);
113  assert(scip != NULL);
114 
115  /* free heuristic data */
116  heurdata = SCIPheurGetData(heur);
117  assert(heurdata != NULL);
118  SCIPfreeMemory(scip, &heurdata);
119  SCIPheurSetData(heur, NULL);
120 
121  return SCIP_OKAY;
122 }
123 
124 
125 /** initialization method of primal heuristic (called after problem was transformed) */
126 static
127 SCIP_DECL_HEURINIT(heurInitLinesearchdiving)
128 { /*lint --e{715}*/
129  SCIP_HEURDATA* heurdata;
130 
131  assert(heur != NULL);
132 
133  /* get heuristic data */
134  heurdata = SCIPheurGetData(heur);
135  assert(heurdata != NULL);
136 
137  /* create working solution */
138  SCIP_CALL( SCIPcreateSol(scip, &heurdata->sol, heur) );
139 
140  /* initialize data */
141  heurdata->nlpiterations = 0;
142  heurdata->nsuccess = 0;
143 
144  return SCIP_OKAY;
145 }
146 
147 
148 /** deinitialization method of primal heuristic (called before transformed problem is freed) */
149 static
150 SCIP_DECL_HEUREXIT(heurExitLinesearchdiving)
151 { /*lint --e{715}*/
152  SCIP_HEURDATA* heurdata;
153 
154  assert(heur != NULL);
155 
156  /* get heuristic data */
157  heurdata = SCIPheurGetData(heur);
158  assert(heurdata != NULL);
159 
160  /* free working solution */
161  SCIP_CALL( SCIPfreeSol(scip, &heurdata->sol) );
162 
163  return SCIP_OKAY;
164 }
165 
166 
167 /** execution method of primal heuristic */
168 static
169 SCIP_DECL_HEUREXEC(heurExecLinesearchdiving)
170 { /*lint --e{715}*/
171  SCIP_HEURDATA* heurdata;
172  SCIP_LPSOLSTAT lpsolstat;
173  SCIP_VAR* var;
174  SCIP_VAR** lpcands;
175  SCIP_Real* lpcandssol;
176  SCIP_Real* lpcandsfrac;
177  SCIP_Real searchubbound;
178  SCIP_Real searchavgbound;
179  SCIP_Real searchbound;
180  SCIP_Real objval;
181  SCIP_Real oldobjval;
182  SCIP_Real solval;
183  SCIP_Real rootsolval;
184  SCIP_Real distquot;
185  SCIP_Real bestdistquot;
186  SCIP_Bool roundup;
187  SCIP_Bool bestcandroundup;
188  SCIP_Bool lperror;
189  SCIP_Bool cutoff;
190  SCIP_Bool backtracked;
191  SCIP_Bool backtrack;
192  SCIP_Bool success;
193  SCIP_Longint ncalls;
194  SCIP_Longint nsolsfound;
195  SCIP_Longint nlpiterations;
196  SCIP_Longint maxnlpiterations;
197  int nlpcands;
198  int startnlpcands;
199  int depth;
200  int maxdepth;
201  int maxdivedepth;
202  int divedepth;
203  int bestcand;
204  int c;
205 
206  assert(heur != NULL);
207  assert(scip != NULL);
208  assert(result != NULL);
209  assert(SCIPhasCurrentNodeLP(scip));
210 
211  *result = SCIP_DELAYED;
212 
213  /* do not call heuristic of node was already detected to be infeasible */
214  if( nodeinfeasible )
215  return SCIP_OKAY;
216 
217  /* only call heuristic, if an optimal LP solution is at hand */
219  return SCIP_OKAY;
220 
221  /* only call heuristic, if the LP objective value is smaller than the cutoff bound */
222  if( SCIPisGE(scip, SCIPgetLPObjval(scip), SCIPgetCutoffbound(scip)) )
223  return SCIP_OKAY;
224 
225  /* only call heuristic, if the LP solution is basic (which allows fast resolve in diving) */
226  if( !SCIPisLPSolBasic(scip) )
227  return SCIP_OKAY;
228 
229  /* don't dive two times at the same node */
230  if( SCIPgetLastDivenode(scip) == SCIPgetNNodes(scip) && SCIPgetDepth(scip) > 0 )
231  return SCIP_OKAY;
232 
233  *result = SCIP_DIDNOTRUN;
234 
235  /* get heuristic's data */
236  heurdata = SCIPheurGetData(heur);
237  assert(heurdata != NULL);
238 
239  /* only try to dive, if we are in the correct part of the tree, given by minreldepth and maxreldepth */
240  depth = SCIPgetDepth(scip);
241  maxdepth = SCIPgetMaxDepth(scip);
242  maxdepth = MAX(maxdepth, 30);
243  if( depth < heurdata->minreldepth*maxdepth || depth > heurdata->maxreldepth*maxdepth )
244  return SCIP_OKAY;
245 
246  /* calculate the maximal number of LP iterations until heuristic is aborted */
247  nlpiterations = SCIPgetNNodeLPIterations(scip);
248  ncalls = SCIPheurGetNCalls(heur);
249  nsolsfound = 10*SCIPheurGetNBestSolsFound(heur) + heurdata->nsuccess;
250  maxnlpiterations = (SCIP_Longint)((1.0 + 10.0*(nsolsfound+1.0)/(ncalls+1.0)) * heurdata->maxlpiterquot * nlpiterations);
251  maxnlpiterations += heurdata->maxlpiterofs;
252 
253  /* don't try to dive, if we took too many LP iterations during diving */
254  if( heurdata->nlpiterations >= maxnlpiterations )
255  return SCIP_OKAY;
256 
257  /* allow at least a certain number of LP iterations in this dive */
258  maxnlpiterations = MAX(maxnlpiterations, heurdata->nlpiterations + MINLPITER);
259 
260  /* get fractional variables that should be integral */
261  SCIP_CALL( SCIPgetLPBranchCands(scip, &lpcands, &lpcandssol, &lpcandsfrac, &nlpcands, NULL, NULL) );
262 
263  /* don't try to dive, if there are no fractional variables */
264  if( nlpcands == 0 )
265  return SCIP_OKAY;
266 
267  /* calculate the objective search bound */
268  if( SCIPgetNSolsFound(scip) == 0 )
269  {
270  if( heurdata->maxdiveubquotnosol > 0.0 )
271  searchubbound = SCIPgetLowerbound(scip)
272  + heurdata->maxdiveubquotnosol * (SCIPgetCutoffbound(scip) - SCIPgetLowerbound(scip));
273  else
274  searchubbound = SCIPinfinity(scip);
275  if( heurdata->maxdiveavgquotnosol > 0.0 )
276  searchavgbound = SCIPgetLowerbound(scip)
277  + heurdata->maxdiveavgquotnosol * (SCIPgetAvgLowerbound(scip) - SCIPgetLowerbound(scip));
278  else
279  searchavgbound = SCIPinfinity(scip);
280  }
281  else
282  {
283  if( heurdata->maxdiveubquot > 0.0 )
284  searchubbound = SCIPgetLowerbound(scip)
285  + heurdata->maxdiveubquot * (SCIPgetCutoffbound(scip) - SCIPgetLowerbound(scip));
286  else
287  searchubbound = SCIPinfinity(scip);
288  if( heurdata->maxdiveavgquot > 0.0 )
289  searchavgbound = SCIPgetLowerbound(scip)
290  + heurdata->maxdiveavgquot * (SCIPgetAvgLowerbound(scip) - SCIPgetLowerbound(scip));
291  else
292  searchavgbound = SCIPinfinity(scip);
293  }
294  searchbound = MIN(searchubbound, searchavgbound);
295  if( SCIPisObjIntegral(scip) )
296  searchbound = SCIPceil(scip, searchbound);
297 
298  /* calculate the maximal diving depth: 10 * min{number of integer variables, max depth} */
299  maxdivedepth = SCIPgetNBinVars(scip) + SCIPgetNIntVars(scip);
300  maxdivedepth = MIN(maxdivedepth, maxdepth);
301  maxdivedepth *= 10;
302 
303  *result = SCIP_DIDNOTFIND;
304 
305  /* start diving */
306  SCIP_CALL( SCIPstartProbing(scip) );
307 
308  /* enables collection of variable statistics during probing */
309  SCIPenableVarHistory(scip);
310 
311  /* get LP objective value */
312  lpsolstat = SCIP_LPSOLSTAT_OPTIMAL;
313  objval = SCIPgetLPObjval(scip);
314 
315  SCIPdebugMessage("(node %"SCIP_LONGINT_FORMAT") executing linesearchdiving heuristic: depth=%d, %d fractionals, dualbound=%g, searchbound=%g\n",
316  SCIPgetNNodes(scip), SCIPgetDepth(scip), nlpcands, SCIPgetDualbound(scip), SCIPretransformObj(scip, searchbound));
317 
318  /* dive as long we are in the given objective, depth and iteration limits and fractional variables exist, but
319  * - if possible, we dive at least with the depth 10
320  * - if the number of fractional variables decreased at least with 1 variable per 2 dive depths, we continue diving
321  */
322  lperror = FALSE;
323  cutoff = FALSE;
324  divedepth = 0;
325  startnlpcands = nlpcands;
326  roundup = FALSE;
327 
328  while( !lperror && !cutoff && lpsolstat == SCIP_LPSOLSTAT_OPTIMAL && nlpcands > 0
329  && (divedepth < 10
330  || nlpcands <= startnlpcands - divedepth/2
331  || (divedepth < maxdivedepth && heurdata->nlpiterations < maxnlpiterations && objval < searchbound))
332  && !SCIPisStopped(scip) )
333  {
334  SCIP_CALL( SCIPnewProbingNode(scip) );
335  divedepth++;
336 
337  /* choose variable fixing:
338  * - in the projected space of fractional variables, extend the line segment connecting the root solution and
339  * the current LP solution up to the point, where one of the fractional variables becomes integral
340  * - round this variable to the integral value
341  */
342  bestcand = 0;
343  bestdistquot = SCIPinfinity(scip);
344  bestcandroundup = FALSE;
345  for( c = 0; c < nlpcands; ++c )
346  {
347  var = lpcands[c];
348  solval = lpcandssol[c];
349  rootsolval = SCIPvarGetRootSol(var);
350 
351  /* calculate distance to integral value divided by distance to root solution */
352  if( SCIPisLT(scip, solval, rootsolval) )
353  {
354  roundup = FALSE;
355  distquot = (solval - SCIPfloor(scip, solval)) / (rootsolval - solval);
356 
357  /* avoid roundable candidates */
358  if( SCIPvarMayRoundDown(var) )
359  distquot *= 1000.0;
360  }
361  else if( SCIPisGT(scip, solval, rootsolval) )
362  {
363  roundup = TRUE;
364  distquot = (SCIPceil(scip, solval) - solval) / (solval - rootsolval);
365 
366  /* avoid roundable candidates */
367  if( SCIPvarMayRoundUp(var) )
368  distquot *= 1000.0;
369  }
370  else
371  {
372  roundup = FALSE;
373  distquot = SCIPinfinity(scip);
374  }
375 
376  /* check, if candidate is new best candidate */
377  if( distquot < bestdistquot )
378  {
379  bestcand = c;
380  bestcandroundup = roundup;
381  bestdistquot = distquot;
382  }
383  }
384 
385  /* create solution from diving LP and try to round it */
386  SCIP_CALL( SCIPlinkLPSol(scip, heurdata->sol) );
387  SCIP_CALL( SCIProundSol(scip, heurdata->sol, &success) );
388  if( success )
389  {
390  SCIPdebugMessage("linesearchdiving found roundable primal solution: obj=%g\n",
391  SCIPgetSolOrigObj(scip, heurdata->sol));
392 
393  /* try to add solution to SCIP */
394  SCIP_CALL( SCIPtrySol(scip, heurdata->sol, FALSE, FALSE, FALSE, FALSE, &success) );
395 
396  /* check, if solution was feasible and good enough */
397  if( success )
398  {
399  SCIPdebugMessage(" -> solution was feasible and good enough\n");
400  *result = SCIP_FOUNDSOL;
401  }
402  }
403 
404  /* apply rounding of best candidate */
405  var = lpcands[bestcand];
406 
407  backtracked = FALSE;
408  do
409  {
410  backtrack = FALSE;
411  /* if the variable is already fixed or if the solution value is outside the domain, numerical troubles may have
412  * occured or variable was fixed by propagation while backtracking => Abort diving!
413  */
414  if( SCIPvarGetLbLocal(var) >= SCIPvarGetUbLocal(var) - 0.5 )
415  {
416  SCIPdebugMessage("selected variable <%s> already fixed to [%g,%g] (solval: %.9f), diving aborted \n",
417  SCIPvarGetName(var), SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), lpcandssol[bestcand]);
418  cutoff = TRUE;
419  break;
420  }
421  if( SCIPisFeasLT(scip, lpcandssol[bestcand], SCIPvarGetLbLocal(var)) || SCIPisFeasGT(scip, lpcandssol[bestcand], SCIPvarGetUbLocal(var)) )
422  {
423  SCIPdebugMessage("selected variable's <%s> solution value is outside the domain [%g,%g] (solval: %.9f), diving aborted\n",
424  SCIPvarGetName(var), SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), lpcandssol[bestcand]);
425  assert(backtracked);
426  break;
427  }
428 
429  /* apply rounding of best candidate */
430  if( bestcandroundup == !backtracked )
431  {
432  /* round variable up */
433  SCIPdebugMessage(" dive %d/%d, LP iter %"SCIP_LONGINT_FORMAT"/%"SCIP_LONGINT_FORMAT": var <%s>, sol=%g, root=%g, [%g,%g] -> [%g,%g]\n",
434  divedepth, maxdivedepth, heurdata->nlpiterations, maxnlpiterations,
435  SCIPvarGetName(var), lpcandssol[bestcand], SCIPvarGetRootSol(var),
437  SCIPceil(scip, lpcandssol[bestcand]), SCIPvarGetUbLocal(var));
438  SCIP_CALL( SCIPchgVarLbProbing(scip, var, SCIPceil(scip, lpcandssol[bestcand])) );
439  roundup = TRUE;
440  }
441  else
442  {
443  /* round variable down */
444  SCIPdebugMessage(" dive %d/%d, LP iter %"SCIP_LONGINT_FORMAT"/%"SCIP_LONGINT_FORMAT": var <%s>, sol=%g, root=%g, [%g,%g] -> [%g,%g]\n",
445  divedepth, maxdivedepth, heurdata->nlpiterations, maxnlpiterations,
446  SCIPvarGetName(var), lpcandssol[bestcand], SCIPvarGetRootSol(var),
448  SCIPvarGetLbLocal(var), SCIPfloor(scip, lpcandssol[bestcand]));
449 
450  SCIP_CALL( SCIPchgVarUbProbing(scip, var, SCIPfloor(scip, lpcandssol[bestcand])) );
451  roundup = FALSE;
452  }
453 
454  /* apply domain propagation */
455  SCIP_CALL( SCIPpropagateProbing(scip, 0, &cutoff, NULL) );
456  if( !cutoff )
457  {
458  /* resolve the diving LP */
459  /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
460  * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
461  */
462 #ifdef NDEBUG
463  SCIP_RETCODE retstat;
464  nlpiterations = SCIPgetNLPIterations(scip);
465  retstat = SCIPsolveProbingLP(scip, MAX((int)(maxnlpiterations - heurdata->nlpiterations), MINLPITER), &lperror, &cutoff);
466  if( retstat != SCIP_OKAY )
467  {
468  SCIPwarningMessage(scip, "Error while solving LP in Linesearchdiving heuristic; LP solve terminated with code <%d>\n",retstat);
469  }
470 #else
471  nlpiterations = SCIPgetNLPIterations(scip);
472  SCIP_CALL( SCIPsolveProbingLP(scip, MAX((int)(maxnlpiterations - heurdata->nlpiterations), MINLPITER), &lperror, &cutoff) );
473 #endif
474 
475  if( lperror )
476  break;
477 
478  /* update iteration count */
479  heurdata->nlpiterations += SCIPgetNLPIterations(scip) - nlpiterations;
480 
481  /* get LP solution status, objective value, and fractional variables, that should be integral */
482  lpsolstat = SCIPgetLPSolstat(scip);
483  assert(cutoff || (lpsolstat != SCIP_LPSOLSTAT_OBJLIMIT && lpsolstat != SCIP_LPSOLSTAT_INFEASIBLE &&
484  (lpsolstat != SCIP_LPSOLSTAT_OPTIMAL || SCIPisLT(scip, SCIPgetLPObjval(scip), SCIPgetCutoffbound(scip)))));
485  }
486 
487  /* perform backtracking if a cutoff was detected */
488  if( cutoff && !backtracked && heurdata->backtrack )
489  {
490  SCIPdebugMessage(" *** cutoff detected at level %d - backtracking\n", SCIPgetProbingDepth(scip));
492  SCIP_CALL( SCIPnewProbingNode(scip) );
493  backtracked = TRUE;
494  backtrack = TRUE;
495  }
496  else
497  backtrack = FALSE;
498  }
499  while( backtrack );
500 
501  if( !lperror && !cutoff && lpsolstat == SCIP_LPSOLSTAT_OPTIMAL )
502  {
503  /* get new objective value */
504  oldobjval = objval;
505  objval = SCIPgetLPObjval(scip);
506 
507  /* update pseudo cost values */
508  if( SCIPisGT(scip, objval, oldobjval) )
509  {
510  if( roundup )
511  {
512  assert(bestcandroundup || backtracked);
513  SCIP_CALL( SCIPupdateVarPseudocost(scip, lpcands[bestcand], 1.0-lpcandsfrac[bestcand],
514  objval - oldobjval, 1.0) );
515  }
516  else
517  {
518  assert(!bestcandroundup || backtracked);
519  SCIP_CALL( SCIPupdateVarPseudocost(scip, lpcands[bestcand], 0.0-lpcandsfrac[bestcand],
520  objval - oldobjval, 1.0) );
521  }
522  }
523 
524  /* get new fractional variables */
525  SCIP_CALL( SCIPgetLPBranchCands(scip, &lpcands, &lpcandssol, &lpcandsfrac, &nlpcands, NULL, NULL) );
526  }
527  SCIPdebugMessage(" -> lpsolstat=%d, objval=%g, nfrac=%d\n", lpsolstat, objval, nlpcands);
528  }
529 
530  /* check if a solution has been found */
531  if( nlpcands == 0 && !lperror && !cutoff && lpsolstat == SCIP_LPSOLSTAT_OPTIMAL )
532  {
533  /* create solution from diving LP */
534  SCIP_CALL( SCIPlinkLPSol(scip, heurdata->sol) );
535  SCIPdebugMessage("linesearchdiving found primal solution: obj=%g\n", SCIPgetSolOrigObj(scip, heurdata->sol));
536 
537  /* try to add solution to SCIP */
538  SCIP_CALL( SCIPtrySol(scip, heurdata->sol, FALSE, FALSE, FALSE, FALSE, &success) );
539 
540  /* check, if solution was feasible and good enough */
541  if( success )
542  {
543  SCIPdebugMessage(" -> solution was feasible and good enough\n");
544  *result = SCIP_FOUNDSOL;
545  }
546  }
547 
548  /* end diving */
549  SCIP_CALL( SCIPendProbing(scip) );
550 
551  if( *result == SCIP_FOUNDSOL )
552  heurdata->nsuccess++;
553 
554  SCIPdebugMessage("linesearchdiving heuristic finished\n");
555 
556  return SCIP_OKAY;
557 }
558 
559 
560 /*
561  * primal heuristic specific interface methods
562  */
563 
564 /** creates the linesearchdiving primal heuristic and includes it in SCIP */
566  SCIP* scip /**< SCIP data structure */
567  )
568 {
569  SCIP_HEURDATA* heurdata;
570  SCIP_HEUR* heur;
571 
572  /* create Linesearchdiving primal heuristic data */
573  SCIP_CALL( SCIPallocMemory(scip, &heurdata) );
574 
575  /* include primal heuristic */
576  SCIP_CALL( SCIPincludeHeurBasic(scip, &heur,
578  HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecLinesearchdiving, heurdata) );
579 
580  assert(heur != NULL);
581 
582  /* set non-NULL pointers to callback methods */
583  SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyLinesearchdiving) );
584  SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeLinesearchdiving) );
585  SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitLinesearchdiving) );
586  SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitLinesearchdiving) );
587 
588  /* add linesearchdiving primal heuristic parameters */
590  "heuristics/linesearchdiving/minreldepth",
591  "minimal relative depth to start diving",
592  &heurdata->minreldepth, TRUE, DEFAULT_MINRELDEPTH, 0.0, 1.0, NULL, NULL) );
594  "heuristics/linesearchdiving/maxreldepth",
595  "maximal relative depth to start diving",
596  &heurdata->maxreldepth, TRUE, DEFAULT_MAXRELDEPTH, 0.0, 1.0, NULL, NULL) );
598  "heuristics/linesearchdiving/maxlpiterquot",
599  "maximal fraction of diving LP iterations compared to node LP iterations",
600  &heurdata->maxlpiterquot, FALSE, DEFAULT_MAXLPITERQUOT, 0.0, SCIP_REAL_MAX, NULL, NULL) );
602  "heuristics/linesearchdiving/maxlpiterofs",
603  "additional number of allowed LP iterations",
604  &heurdata->maxlpiterofs, FALSE, DEFAULT_MAXLPITEROFS, 0, INT_MAX, NULL, NULL) );
606  "heuristics/linesearchdiving/maxdiveubquot",
607  "maximal quotient (curlowerbound - lowerbound)/(cutoffbound - lowerbound) where diving is performed (0.0: no limit)",
608  &heurdata->maxdiveubquot, TRUE, DEFAULT_MAXDIVEUBQUOT, 0.0, 1.0, NULL, NULL) );
610  "heuristics/linesearchdiving/maxdiveavgquot",
611  "maximal quotient (curlowerbound - lowerbound)/(avglowerbound - lowerbound) where diving is performed (0.0: no limit)",
612  &heurdata->maxdiveavgquot, TRUE, DEFAULT_MAXDIVEAVGQUOT, 0.0, SCIP_REAL_MAX, NULL, NULL) );
614  "heuristics/linesearchdiving/maxdiveubquotnosol",
615  "maximal UBQUOT when no solution was found yet (0.0: no limit)",
616  &heurdata->maxdiveubquotnosol, TRUE, DEFAULT_MAXDIVEUBQUOTNOSOL, 0.0, 1.0, NULL, NULL) );
618  "heuristics/linesearchdiving/maxdiveavgquotnosol",
619  "maximal AVGQUOT when no solution was found yet (0.0: no limit)",
620  &heurdata->maxdiveavgquotnosol, TRUE, DEFAULT_MAXDIVEAVGQUOTNOSOL, 0.0, SCIP_REAL_MAX, NULL, NULL) );
622  "heuristics/linesearchdiving/backtrack",
623  "use one level of backtracking if infeasibility is encountered?",
624  &heurdata->backtrack, FALSE, DEFAULT_BACKTRACK, NULL, NULL) );
625 
626  return SCIP_OKAY;
627 }
#define HEUR_FREQOFS
#define DEFAULT_MAXLPITEROFS
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
#define HEUR_NAME
#define HEUR_FREQ
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:15788
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 SCIPvarMayRoundDown(SCIP_VAR *var)
Definition: var.c:3269
static SCIP_DECL_HEURFREE(heurFreeLinesearchdiving)
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
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_Bool SCIPisStopped(SCIP *scip)
Definition: scip.c:1111
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_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 HEUR_DISPCHAR
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_MINRELDEPTH
struct SCIP_HeurData SCIP_HEURDATA
Definition: type_heur.h:44
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
Definition: scip.c:35229
static SCIP_DECL_HEUREXIT(heurExitLinesearchdiving)
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip.c:24136
#define SCIPdebugMessage
Definition: pub_message.h:77
static SCIP_DECL_HEURCOPY(heurCopyLinesearchdiving)
SCIP_RETCODE SCIPincludeHeurLinesearchdiving(SCIP *scip)
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition: type_lp.h:42
static SCIP_DECL_HEURINIT(heurInitLinesearchdiving)
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition: scip.c:24179
SCIP_Real SCIPgetLowerbound(SCIP *scip)
Definition: scip.c:35061
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
SCIP_Real SCIPvarGetRootSol(SCIP_VAR *var)
Definition: var.c:12536
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:38273
SCIP_Real SCIPgetDualbound(SCIP *scip)
Definition: scip.c:35040
#define HEUR_MAXDEPTH
#define DEFAULT_MAXLPITERQUOT
#define SCIPallocMemory(scip, ptr)
Definition: scip.h:19159
SCIP_Bool SCIPisObjIntegral(SCIP *scip)
Definition: scip.c:9683
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
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
Definition: scip.c:38470
#define DEFAULT_MAXRELDEPTH
SCIP_Real SCIPinfinity(SCIP *scip)
Definition: scip.c:38349
#define SCIP_CALL(x)
Definition: def.h:258
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
Definition: scip.c:24051
#define HEUR_DESC
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:38705
SCIP_Longint SCIPgetLastDivenode(SCIP *scip)
Definition: scip.c:29390
#define HEUR_PRIORITY
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition: heur.c:512
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
SCIP_Real SCIPretransformObj(SCIP *scip, SCIP_Real obj)
Definition: scip.c:31962
#define MINLPITER
#define HEUR_USESSUBSCIP
#define MAX(x, y)
Definition: tclique_def.h:75
SCIP_RETCODE SCIPstartProbing(SCIP *scip)
Definition: scip.c:29476
#define DEFAULT_BACKTRACK
SCIP_RETCODE SCIPendProbing(SCIP *scip)
Definition: scip.c:29607
int SCIPgetDepth(SCIP *scip)
Definition: scip.c:34833
#define DEFAULT_MAXDIVEAVGQUOTNOSOL
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
#define SCIP_REAL_MAX
Definition: def.h:124
LP diving heuristic that fixes variables with a large difference to their root solution.
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
static SCIP_DECL_HEUREXEC(heurExecLinesearchdiving)
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 SCIP_Real
Definition: def.h:123
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
Definition: scip.c:29513
SCIP_RETCODE SCIPchgVarLbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip.c:29640
#define MIN(x, y)
Definition: memory.c:59
#define DEFAULT_MAXDIVEUBQUOT
SCIP_Bool SCIPvarMayRoundUp(SCIP_VAR *var)
Definition: var.c:3277
#define DEFAULT_MAXDIVEUBQUOTNOSOL
#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
#define HEUR_TIMING
#define DEFAULT_MAXDIVEAVGQUOT
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
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