Scippy

SCIP

Solving Constraint Integer Programs

heur.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 heur.c
17  * @brief methods for primal heuristics
18  * @author Tobias Achterberg
19  * @author Timo Berthold
20  */
21 
22 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
23 
24 #include <assert.h>
25 #include <string.h>
26 
27 #include "scip/def.h"
28 #include "scip/set.h"
29 #include "scip/clock.h"
30 #include "scip/paramset.h"
31 #include "scip/primal.h"
32 #include "scip/scip.h"
33 #include "scip/heur.h"
34 #include "scip/pub_message.h"
35 #include "scip/pub_misc.h"
36 
37 #include "scip/struct_heur.h"
38 
39 /** compares two heuristics w. r. to their delay positions and their priority */
40 SCIP_DECL_SORTPTRCOMP(SCIPheurComp)
41 { /*lint --e{715}*/
42  SCIP_HEUR* heur1 = (SCIP_HEUR*)elem1;
43  SCIP_HEUR* heur2 = (SCIP_HEUR*)elem2;
44 
45  assert(heur1 != NULL);
46  assert(heur2 != NULL);
47 
48  if( heur1->delaypos == heur2->delaypos )
49  return heur2->priority - heur1->priority; /* prefer higher priorities */
50  else if( heur1->delaypos == -1 )
51  return +1; /* prefer delayed heuristics */
52  else if( heur2->delaypos == -1 )
53  return -1; /* prefer delayed heuristics */
54  else if( heur1->ncalls * heur1->freq > heur2->ncalls * heur2->freq )
55  return +1;
56  else if( heur1->ncalls * heur1->freq < heur2->ncalls * heur2->freq )
57  return -1;
58  else
59  return heur1->delaypos - heur2->delaypos; /* prefer lower delay positions */
60 }
61 
62 
63 /** comparison method for sorting heuristics w.r.t. to their name */
64 SCIP_DECL_SORTPTRCOMP(SCIPheurCompName)
65 {
66  return strcmp(SCIPheurGetName((SCIP_HEUR*)elem1), SCIPheurGetName((SCIP_HEUR*)elem2));
67 }
68 
69 /** method to call, when the priority of a heuristic was changed */
70 static
71 SCIP_DECL_PARAMCHGD(paramChgdHeurPriority)
72 { /*lint --e{715}*/
73  SCIP_PARAMDATA* paramdata;
74 
75  paramdata = SCIPparamGetData(param);
76  assert(paramdata != NULL);
77 
78  /* use SCIPsetHeurPriority() to mark the heuristics unsorted */
79  SCIP_CALL( SCIPsetHeurPriority(scip, (SCIP_HEUR*)paramdata, SCIPparamGetInt(param)) ); /*lint !e740*/
80 
81  return SCIP_OKAY;
82 }
83 
84 /* resets diving settings counters */
86  SCIP_DIVESET* diveset /**< diveset to be reset */
87  )
88 {
89  assert(diveset != NULL);
90 
91  diveset->nlpiterations = 0L;
92  diveset->totaldepth = 0L;
93  diveset->totalsoldepth = 0L;
94  diveset->totalnnodes = 0L;
95  diveset->totalnbacktracks = 0L;
96  diveset->minsoldepth = INT_MAX;
97  diveset->maxsoldepth = -1;
98  diveset->mindepth = INT_MAX;
99  diveset->maxdepth = -1;
100  diveset->nlps = 0;
101  diveset->nsolsfound = 0;
102  diveset->nbestsolsfound = 0;
103  diveset->ncalls = 0;
104  diveset->nsolcalls = 0;
105 }
106 
107 /** update diveset statistics and global diveset statistics */
109  SCIP_DIVESET* diveset, /**< diveset to be reset */
110  SCIP_STAT* stat, /**< global SCIP statistics */
111  int depth, /**< the depth reached this time */
112  int nprobingnodes, /**< the number of probing nodes explored this time */
113  int nbacktracks, /**< the number of backtracks during probing this time */
114  SCIP_Longint nsolsfound, /**< number of new solutions found this time */
115  SCIP_Longint nbestsolsfound, /**< number of new best solutions found this time */
116  SCIP_Bool leavesol /**< has the diving heuristic reached a feasible leaf */
117  )
118 {
119  assert(diveset != NULL);
120 
121  diveset->totaldepth += depth;
122  diveset->mindepth = MIN(diveset->mindepth, depth);
123  diveset->maxdepth = MAX(diveset->maxdepth, depth);
124  diveset->totalnnodes += nprobingnodes;
125  diveset->totalnbacktracks += nbacktracks;
126  diveset->ncalls++;
127 
128  /* update solution statistics only if a solution was found */
129  if( leavesol )
130  {
131  diveset->totalsoldepth += depth;
132  diveset->minsoldepth = MIN(diveset->minsoldepth, depth);
133  diveset->maxsoldepth = MAX(diveset->maxsoldepth, depth);
134  diveset->nsolcalls++;
135  }
136 
137  diveset->nsolsfound += nsolsfound;
138  diveset->nbestsolsfound += nbestsolsfound;
139 
140  stat->totaldivesetdepth += depth;
141  stat->ndivesetcalls++;
142 }
143 
144 /** append diveset to heuristic array of divesets */
145 static
147  SCIP_HEUR* heur, /**< the heuristic to which this dive setting belongs */
148  SCIP_DIVESET* diveset /**< pointer to the freshly created diveset */
149  )
150 {
151  assert(heur != NULL);
152  assert(diveset != NULL);
153  assert(diveset->heur == NULL);
154 
155  diveset->heur = heur;
156 
157  if( heur->divesets == NULL )
158  {
159  assert(heur->ndivesets == 0);
161  }
162  else
163  {
164  assert(heur->ndivesets > 0);
165  SCIP_ALLOC( BMSreallocMemoryArray(&heur->divesets, heur->ndivesets + 1) ); /*lint !e776 I expect no overflow here */
166  }
167 
168  /* append diveset to the end of the array */
169  heur->divesets[heur->ndivesets] = diveset;
170  heur->ndivesets++;
171 
172  return SCIP_OKAY;
173 }
174 
175 /** create a set of diving heuristic settings */
177  SCIP_DIVESET** diveset, /**< pointer to the freshly created diveset */
178  SCIP_HEUR* heur, /**< the heuristic to which this dive setting belongs */
179  const char* name, /**< name for the diveset, or NULL if the name of the heuristic should be used */
180  SCIP_SET* set, /**< global SCIP settings */
181  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
182  BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
183  SCIP_Real minreldepth, /**< minimal relative depth to start diving */
184  SCIP_Real maxreldepth, /**< maximal relative depth to start diving */
185  SCIP_Real maxlpiterquot, /**< maximal fraction of diving LP iterations compared to node LP iterations */
186  SCIP_Real maxdiveubquot, /**< maximal quotient (curlowerbound - lowerbound)/(cutoffbound - lowerbound)
187  * where diving is performed (0.0: no limit) */
188  SCIP_Real maxdiveavgquot, /**< maximal quotient (curlowerbound - lowerbound)/(avglowerbound - lowerbound)
189  * where diving is performed (0.0: no limit) */
190  SCIP_Real maxdiveubquotnosol, /**< maximal UBQUOT when no solution was found yet (0.0: no limit) */
191  SCIP_Real maxdiveavgquotnosol,/**< maximal AVGQUOT when no solution was found yet (0.0: no limit) */
192  SCIP_Real lpresolvedomchgquot,/**< percentage of immediate domain changes during probing to trigger LP resolve */
193  int lpsolvefreq, /**< LP solve frequency for (0: only if enough domain reductions are found by propagation)*/
194  int maxlpiterofs, /**< additional number of allowed LP iterations */
195  SCIP_Bool backtrack, /**< use one level of backtracking if infeasibility is encountered? */
196  SCIP_Bool onlylpbranchcands, /**< should only LP branching candidates be considered instead of the slower but
197  * more general constraint handler diving variable selection? */
198  SCIP_DIVETYPE divetypemask, /**< bit mask that represents the supported dive types by this dive set */
199  SCIP_DECL_DIVESETGETSCORE((*divesetgetscore)) /**< method for candidate score and rounding direction */
200  )
201 {
203  const char* divesetname;
204 
205  assert(diveset != NULL);
206  assert(set != NULL);
207  assert(divesetgetscore != NULL);
208  assert(heur != NULL);
209 
210  SCIP_ALLOC( BMSallocMemory(diveset) );
211 
212  /* for convenience, the name gets inferred from the heuristic to which the diveset is added if no name is provided */
213  divesetname = (name == NULL ? SCIPheurGetName(heur) : name);
214  SCIP_ALLOC( BMSduplicateMemoryArray(&(*diveset)->name, divesetname, strlen(divesetname)+1) );
215  (*diveset)->heur = NULL;
216 
217  /* copy callbacks */
218  (*diveset)->divesetgetscore = divesetgetscore;
219 
220  SCIP_CALL( heurAddDiveset(heur, *diveset) );
221  (*diveset)->sol = NULL;
222  (*diveset)->divetypemask = divetypemask;
223 
224  /* add collection of diving heuristic specific parameters */
225  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/minreldepth", (*diveset)->name);
226  SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem,
227  paramname, "minimal relative depth to start diving",
228  &(*diveset)->minreldepth, TRUE, minreldepth, 0.0, 1.0, NULL, NULL) );
229 
230  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxreldepth", (*diveset)->name);
231  SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname,
232  "maximal relative depth to start diving",
233  &(*diveset)->maxreldepth, TRUE, maxreldepth, 0.0, 1.0, NULL, NULL) );
234 
235  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxlpiterquot", (*diveset)->name);
236  SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem,
237  paramname,
238  "maximal fraction of diving LP iterations compared to node LP iterations",
239  &(*diveset)->maxlpiterquot, FALSE, maxlpiterquot, 0.0, SCIP_REAL_MAX, NULL, NULL) );
240 
241  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxlpiterofs", (*diveset)->name);
242  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem,
243  paramname,
244  "additional number of allowed LP iterations",
245  &(*diveset)->maxlpiterofs, FALSE, maxlpiterofs, 0, INT_MAX, NULL, NULL) );
246 
247  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxdiveubquot", (*diveset)->name);
248  SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem,
249  paramname,
250  "maximal quotient (curlowerbound - lowerbound)/(cutoffbound - lowerbound) where diving is performed (0.0: no limit)",
251  &(*diveset)->maxdiveubquot, TRUE, maxdiveubquot, 0.0, 1.0, NULL, NULL) );
252 
253  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxdiveavgquot", (*diveset)->name);
254  SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem,
255  paramname,
256  "maximal quotient (curlowerbound - lowerbound)/(avglowerbound - lowerbound) where diving is performed (0.0: no limit)",
257  &(*diveset)->maxdiveavgquot, TRUE, maxdiveavgquot, 0.0, SCIP_REAL_MAX, NULL, NULL) );
258 
259  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxdiveubquotnosol", (*diveset)->name);
260  SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem,
261  paramname,
262  "maximal UBQUOT when no solution was found yet (0.0: no limit)",
263  &(*diveset)->maxdiveubquotnosol, TRUE, maxdiveubquotnosol, 0.0, 1.0, NULL, NULL) );
264 
265  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxdiveavgquotnosol", (*diveset)->name);
266  SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem,
267  paramname,
268  "maximal AVGQUOT when no solution was found yet (0.0: no limit)",
269  &(*diveset)->maxdiveavgquotnosol, TRUE, maxdiveavgquotnosol, 0.0, SCIP_REAL_MAX, NULL, NULL) );
270 
271  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/backtrack", (*diveset)->name);
272  SCIP_CALL( SCIPsetAddBoolParam(set, messagehdlr, blkmem,
273  paramname,
274  "use one level of backtracking if infeasibility is encountered?",
275  &(*diveset)->backtrack, FALSE, backtrack, NULL, NULL) );
276 
277  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/lpresolvedomchgquot", (*diveset)->name);
278  SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname,
279  "percentage of immediate domain changes during probing to trigger LP resolve",
280  &(*diveset)->lpresolvedomchgquot, FALSE, lpresolvedomchgquot, 0.0, SCIP_REAL_MAX, NULL, NULL) );
281 
282  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/lpsolvefreq", (*diveset)->name);
283  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem,
284  paramname,
285  "LP solve frequency for diving heuristics (0: only after enough domain changes have been found)",
286  &(*diveset)->lpsolvefreq, FALSE, lpsolvefreq, 0, INT_MAX,
287  NULL, NULL) );
288 
289  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/onlylpbranchcands", (*diveset)->name);
290  SCIP_CALL( SCIPsetAddBoolParam(set, messagehdlr, blkmem,
291  paramname,
292  "should only LP branching candidates be considered instead of the slower but "
293  "more general constraint handler diving variable selection?",
294  &(*diveset)->onlylpbranchcands, FALSE, onlylpbranchcands, NULL, NULL) );
295 
296  SCIPdivesetReset(*diveset);
297 
298  return SCIP_OKAY;
299 }
300 
301 /** get the heuristic to which this diving setting belongs */
303  SCIP_DIVESET* diveset /**< diving settings */
304  )
305 {
306  return diveset->heur;
307 }
308 
309 /** get the working solution of this dive set */
311  SCIP_DIVESET* diveset /**< diving settings */
312  )
313 {
314  assert(diveset != NULL);
315 
316  return diveset->sol;
317 }
318 
319 /** set the working solution for this dive set */
321  SCIP_DIVESET* diveset, /**< diving settings */
322  SCIP_SOL* sol /**< new working solution for this dive set, or NULL */
323  )
324 {
325  assert(diveset != NULL);
326 
327  diveset->sol = sol;
328 }
329 
330 /** get the name of the dive set */
331 const char* SCIPdivesetGetName(
332  SCIP_DIVESET* diveset /**< diving settings */
333  )
334 {
335  assert(diveset != NULL);
336 
337  return diveset->name;
338 }
339 
340 /** get the minimum relative depth of the diving settings */
342  SCIP_DIVESET* diveset /**< diving settings */
343  )
344 {
345  return diveset->minreldepth;
346 }
347 
348 /** get the maximum relative depth of the diving settings */
350  SCIP_DIVESET* diveset /**< diving settings */
351  )
352 {
353  return diveset->maxreldepth;
354 }
355 
356 /** get the number of successful runs of the diving settings */
358  SCIP_DIVESET* diveset /**< diving settings */
359  )
360 {
361  return 10 * diveset->nbestsolsfound + diveset->nsolsfound;
362 }
363 
364 /** get the number of calls to this dive set */
366  SCIP_DIVESET* diveset /**< diving settings */
367  )
368 {
369  assert(diveset != NULL);
370 
371  return diveset->ncalls;
372 }
373 
374 /** get the number of calls successfully terminated at a feasible leaf node */
376  SCIP_DIVESET* diveset /**< diving settings */
377  )
378 {
379  assert(diveset != NULL);
380 
381  return diveset->nsolcalls;
382 }
383 
384 /** get the minimum depth reached by this dive set */
386  SCIP_DIVESET* diveset /**< diving settings */
387  )
388 {
389  assert(diveset != NULL);
390 
391  return diveset->mindepth;
392 }
393 
394 /** get the maximum depth reached by this dive set */
396  SCIP_DIVESET* diveset /**< diving settings */
397  )
398 {
399  assert(diveset != NULL);
400 
401  return diveset->maxdepth;
402 }
403 
404 /** get the average depth this dive set reached during execution */
406  SCIP_DIVESET* diveset /**< diving settings */
407  )
408 {
409  assert(diveset != NULL);
410 
411  return (diveset->ncalls == 0 ? 0.0 : diveset->totaldepth / (SCIP_Real)diveset->ncalls);
412 }
413 
414 /** get the minimum depth at which this dive set found a solution */
416  SCIP_DIVESET* diveset /**< diving settings */
417  )
418 {
419  assert(diveset != NULL);
420 
421  return diveset->minsoldepth;
422 }
423 
424 /** get the maximum depth at which this dive set found a solution */
426  SCIP_DIVESET* diveset /**< diving settings */
427  )
428 {
429  assert(diveset != NULL);
430 
431  return diveset->maxsoldepth;
432 }
433 
434 /** get the average depth at which this dive set found a solution */
436  SCIP_DIVESET* diveset /**< diving settings */
437  )
438 {
439  assert(diveset != NULL);
440 
441  return (diveset->nsolcalls == 0 ? 0.0 : diveset->totalsoldepth / (SCIP_Real)diveset->nsolcalls);
442 }
443 
444 /** get the total number of LP iterations used by this dive set */
446  SCIP_DIVESET* diveset /**< diving settings */
447  )
448 {
449  assert(diveset != NULL);
450 
451  return diveset->nlpiterations;
452 }
453 
454 /** get the total number of probing nodes used by this dive set */
456  SCIP_DIVESET* diveset /**< diving settings */
457  )
458 {
459  assert(diveset != NULL);
460 
461  return diveset->totalnnodes;
462 }
463 
464 /** get the total number of backtracks performed by this dive set */
466  SCIP_DIVESET* diveset /**< diving settings */
467  )
468 {
469  assert(diveset != NULL);
470 
471  return diveset->totalnbacktracks;
472 }
473 
474 /** get the maximum LP iterations quotient of the diving settings */
476  SCIP_DIVESET* diveset /**< diving settings */
477  )
478 {
479  return diveset->maxlpiterquot;
480 }
481 
482 /** get the maximum LP iterations offset of the diving settings */
484  SCIP_DIVESET* diveset /**< diving settings */
485  )
486 {
487  return diveset->maxlpiterofs;
488 }
489 
490 /** get the maximum upper bound quotient parameter of the diving settings if no solution is available */
492  SCIP_DIVESET* diveset /**< diving settings */
493  )
494 {
495  return diveset->maxdiveubquotnosol;
496 }
497 
498 /** get the average quotient parameter of the diving settings if no solution is available */
500  SCIP_DIVESET* diveset /**< diving settings */
501  )
502 {
503  return diveset->maxdiveavgquotnosol;
504 }
505 /** get the maximum upper bound quotient parameter of the diving settings if an incumbent solution exists */
507  SCIP_DIVESET* diveset /**< diving settings */
508  )
509 {
510  return diveset->maxdiveubquot;
511 }
512 
513 /** get the average upper bound quotient parameter of the diving settings if an incumbent solution exists */
515  SCIP_DIVESET* diveset /**< diving settings */
516  )
517 {
518  return diveset->maxdiveavgquot;
519 }
520 
521 /** should backtracking be applied? */
523  SCIP_DIVESET* diveset /**< diving settings */
524  )
525 {
526  return diveset->backtrack;
527 }
528 
529 /** returns the LP solve frequency for diving LPs (0: dynamically based on number of intermediate domain reductions) */
531  SCIP_DIVESET* diveset /**< diving settings */
532  )
533 {
534  assert(diveset != NULL);
535 
536  return diveset->lpsolvefreq;
537 }
538 
539 /** returns the domain reduction quotient for triggering an immediate resolve of the diving LP (0.0: always resolve)*/
541  SCIP_DIVESET* diveset /**< diving settings */
542  )
543 {
544  assert(diveset != NULL);
545 
546  return diveset->lpresolvedomchgquot;
547 }
548 
549 /** should only LP branching candidates be considered instead of the slower but
550  * more general constraint handler diving variable selection?
551  */
553  SCIP_DIVESET* diveset /**< diving settings */
554  )
555 {
556  assert(diveset != NULL);
557 
558  return diveset->onlylpbranchcands;
559 }
560 
561 /** returns TRUE if dive set supports diving of the specified type */
563  SCIP_DIVESET* diveset, /**< diving settings */
564  SCIP_DIVETYPE divetype /**< bit mask that represents the supported dive types by this dive set */
565  )
566 {
567  assert(diveset != NULL);
568 
569  return (divetype & diveset->divetypemask);
570 }
571 
572 /** update diveset LP statistics, should be called after every LP solved by this diving heuristic */
574  SCIP_DIVESET* diveset, /**< diving settings */
575  SCIP_STAT* stat, /**< global SCIP statistics */
576  SCIP_Longint niterstoadd /**< additional number of LP iterations to be added */
577  )
578 {
579  diveset->nlpiterations += niterstoadd;
580  stat->ndivesetlpiterations += niterstoadd;
581  diveset->nlps++;
582  stat->ndivesetlps++;
583 }
584 
585 /** frees memory of a diveset */
586 static
588  SCIP_DIVESET** diveset /**< general diving settings */
589  )
590 {
591  assert(*diveset != NULL);
592  assert((*diveset)->name != NULL);
593 
594  BMSfreeMemoryArray(&(*diveset)->name);
595  BMSfreeMemory(diveset);
596 }
597 
598 /** get the candidate score and preferred rounding direction for a candidate variable */
600  SCIP_DIVESET* diveset, /**< general diving settings */
601  SCIP_SET* set, /**< SCIP settings */
602  SCIP_DIVETYPE divetype, /**< the type of diving that should be applied */
603  SCIP_VAR* divecand, /**< the candidate for which the branching direction is requested */
604  SCIP_Real divecandsol, /**< LP solution value of the candidate */
605  SCIP_Real divecandfrac, /**< fractionality of the candidate */
606  SCIP_Real* candscore, /**< pointer to store the candidate score */
607  SCIP_Bool* roundup /**< pointer to store whether preferred direction for diving is upwards */
608  )
609 {
610  assert(diveset->divesetgetscore != NULL);
611  assert(candscore != NULL);
612  assert(roundup != NULL);
613  assert(divecand != NULL);
614  assert(divetype & diveset->divetypemask);
615 
616  SCIP_CALL( diveset->divesetgetscore(set->scip, diveset, divetype, divecand, divecandsol, divecandfrac, candscore, roundup) );
617 
618  return SCIP_OKAY;
619 }
620 
621 
622 
623 /** copies the given primal heuristic to a new scip */
625  SCIP_HEUR* heur, /**< primal heuristic */
626  SCIP_SET* set /**< SCIP_SET of SCIP to copy to */
627  )
628 {
629  assert(heur != NULL);
630  assert(set != NULL);
631  assert(set->scip != NULL);
632 
633  if( heur->heurcopy != NULL )
634  {
635  SCIPdebugMessage("including heur %s in subscip %p\n", SCIPheurGetName(heur), (void*)set->scip);
636  SCIP_CALL( heur->heurcopy(set->scip, heur) );
637  }
638 
639  return SCIP_OKAY;
640 }
641 
642 /** creates a primal heuristic */
644  SCIP_HEUR** heur, /**< pointer to primal heuristic data structure */
645  SCIP_SET* set, /**< global SCIP settings */
646  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
647  BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
648  const char* name, /**< name of primal heuristic */
649  const char* desc, /**< description of primal heuristic */
650  char dispchar, /**< display character of primal heuristic */
651  int priority, /**< priority of the primal heuristic */
652  int freq, /**< frequency for calling primal heuristic */
653  int freqofs, /**< frequency offset for calling primal heuristic */
654  int maxdepth, /**< maximal depth level to call heuristic at (-1: no limit) */
655  unsigned int timingmask, /**< positions in the node solving loop where heuristic should be executed */
656  SCIP_Bool usessubscip, /**< does the heuristic use a secondary SCIP instance? */
657  SCIP_DECL_HEURCOPY ((*heurcopy)), /**< copy method of primal heuristic or NULL if you don't want to copy your plugin into sub-SCIPs */
658  SCIP_DECL_HEURFREE ((*heurfree)), /**< destructor of primal heuristic */
659  SCIP_DECL_HEURINIT ((*heurinit)), /**< initialize primal heuristic */
660  SCIP_DECL_HEUREXIT ((*heurexit)), /**< deinitialize primal heuristic */
661  SCIP_DECL_HEURINITSOL ((*heurinitsol)), /**< solving process initialization method of primal heuristic */
662  SCIP_DECL_HEUREXITSOL ((*heurexitsol)), /**< solving process deinitialization method of primal heuristic */
663  SCIP_DECL_HEUREXEC ((*heurexec)), /**< execution method of primal heuristic */
664  SCIP_HEURDATA* heurdata /**< primal heuristic data */
665  )
666 {
668  char paramdesc[SCIP_MAXSTRLEN];
669 
670  assert(heur != NULL);
671  assert(name != NULL);
672  assert(desc != NULL);
673  assert(freq >= -1);
674  assert(freqofs >= 0);
675  assert(heurexec != NULL);
676 
677  SCIP_ALLOC( BMSallocMemory(heur) );
678  SCIP_ALLOC( BMSduplicateMemoryArray(&(*heur)->name, name, strlen(name)+1) );
679  SCIP_ALLOC( BMSduplicateMemoryArray(&(*heur)->desc, desc, strlen(desc)+1) );
680  (*heur)->dispchar = dispchar;
681  (*heur)->priority = priority;
682  (*heur)->freq = freq;
683  (*heur)->freqofs = freqofs;
684  (*heur)->maxdepth = maxdepth;
685  (*heur)->delaypos = -1;
686  (*heur)->timingmask = timingmask;
687  (*heur)->usessubscip = usessubscip;
688  (*heur)->heurcopy = heurcopy;
689  (*heur)->heurfree = heurfree;
690  (*heur)->heurinit = heurinit;
691  (*heur)->heurexit = heurexit;
692  (*heur)->heurinitsol = heurinitsol;
693  (*heur)->heurexitsol = heurexitsol;
694  (*heur)->heurexec = heurexec;
695  (*heur)->heurdata = heurdata;
696  SCIP_CALL( SCIPclockCreate(&(*heur)->setuptime, SCIP_CLOCKTYPE_DEFAULT) );
697  SCIP_CALL( SCIPclockCreate(&(*heur)->heurclock, SCIP_CLOCKTYPE_DEFAULT) );
698  (*heur)->ncalls = 0;
699  (*heur)->nsolsfound = 0;
700  (*heur)->nbestsolsfound = 0;
701  (*heur)->initialized = FALSE;
702  (*heur)->divesets = NULL;
703  (*heur)->ndivesets = 0;
704 
705  /* add parameters */
706  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/priority", name);
707  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of heuristic <%s>", name);
708  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
709  &(*heur)->priority, TRUE, priority, INT_MIN/4, INT_MAX/4,
710  paramChgdHeurPriority, (SCIP_PARAMDATA*)(*heur)) ); /*lint !e740*/
711  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/freq", name);
712  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "frequency for calling primal heuristic <%s> (-1: never, 0: only at depth freqofs)", name);
713  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
714  &(*heur)->freq, FALSE, freq, -1, INT_MAX, NULL, NULL) );
715  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/freqofs", name);
716  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "frequency offset for calling primal heuristic <%s>", name);
717  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
718  &(*heur)->freqofs, FALSE, freqofs, 0, INT_MAX, NULL, NULL) );
719  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxdepth", name);
720  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "maximal depth level to call primal heuristic <%s> (-1: no limit)", name);
721  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
722  &(*heur)->maxdepth, TRUE, maxdepth, -1, INT_MAX, NULL, NULL) );
723 
724  return SCIP_OKAY;
725 }
726 
727 /** calls destructor and frees memory of primal heuristic */
729  SCIP_HEUR** heur, /**< pointer to primal heuristic data structure */
730  SCIP_SET* set /**< global SCIP settings */
731  )
732 {
733  int d;
734  assert(heur != NULL);
735  assert(*heur != NULL);
736  assert(!(*heur)->initialized);
737  assert(set != NULL);
738  assert((*heur)->divesets != NULL || (*heur)->ndivesets == 0);
739 
740  /* call destructor of primal heuristic */
741  if( (*heur)->heurfree != NULL )
742  {
743  SCIP_CALL( (*heur)->heurfree(set->scip, *heur) );
744  }
745 
746  for( d = 0; d < (*heur)->ndivesets; ++d )
747  {
748  assert((*heur)->divesets[d] != NULL);
749  divesetFree(&((*heur)->divesets[d]));
750  }
751  BMSfreeMemoryArrayNull(&(*heur)->divesets);
752  SCIPclockFree(&(*heur)->heurclock);
753  SCIPclockFree(&(*heur)->setuptime);
754  BMSfreeMemoryArray(&(*heur)->name);
755  BMSfreeMemoryArray(&(*heur)->desc);
756  BMSfreeMemory(heur);
757 
758  return SCIP_OKAY;
759 }
760 
761 /** initializes primal heuristic */
763  SCIP_HEUR* heur, /**< primal heuristic */
764  SCIP_SET* set /**< global SCIP settings */
765  )
766 {
767  int d;
768  assert(heur != NULL);
769  assert(set != NULL);
770 
771  if( heur->initialized )
772  {
773  SCIPerrorMessage("primal heuristic <%s> already initialized\n", heur->name);
774  return SCIP_INVALIDCALL;
775  }
776 
777  if( set->misc_resetstat )
778  {
779  SCIPclockReset(heur->setuptime);
780  SCIPclockReset(heur->heurclock);
781 
782  heur->delaypos = -1;
783  heur->ncalls = 0;
784  heur->nsolsfound = 0;
785  heur->nbestsolsfound = 0;
786  }
787 
788  if( heur->heurinit != NULL )
789  {
790  /* start timing */
791  SCIPclockStart(heur->setuptime, set);
792 
793  SCIP_CALL( heur->heurinit(set->scip, heur) );
794 
795  /* stop timing */
796  SCIPclockStop(heur->setuptime, set);
797  }
798 
799  /* reset dive sets */
800  for( d = 0; d < heur->ndivesets; ++d )
801  {
802  assert(heur->divesets[d] != NULL);
803  SCIPdivesetReset(heur->divesets[d]);
804  }
805 
806  heur->initialized = TRUE;
807 
808  return SCIP_OKAY;
809 }
810 
811 /** calls exit method of primal heuristic */
813  SCIP_HEUR* heur, /**< primal heuristic */
814  SCIP_SET* set /**< global SCIP settings */
815  )
816 {
817  assert(heur != NULL);
818  assert(set != NULL);
819 
820  if( !heur->initialized )
821  {
822  SCIPerrorMessage("primal heuristic <%s> not initialized\n", heur->name);
823  return SCIP_INVALIDCALL;
824  }
825 
826  if( heur->heurexit != NULL )
827  {
828  /* start timing */
829  SCIPclockStart(heur->setuptime, set);
830 
831  SCIP_CALL( heur->heurexit(set->scip, heur) );
832 
833  /* stop timing */
834  SCIPclockStop(heur->setuptime, set);
835  }
836  heur->initialized = FALSE;
837 
838  return SCIP_OKAY;
839 }
840 
841 /** informs primal heuristic that the branch and bound process is being started */
843  SCIP_HEUR* heur, /**< primal heuristic */
844  SCIP_SET* set /**< global SCIP settings */
845  )
846 {
847  assert(heur != NULL);
848  assert(set != NULL);
849 
850  if( heur->delaypos != -1 )
851  {
852  heur->delaypos = -1;
853  set->heurssorted = FALSE;
854  }
855 
856  /* call solving process initialization method of primal heuristic */
857  if( heur->heurinitsol != NULL )
858  {
859  /* start timing */
860  SCIPclockStart(heur->setuptime, set);
861 
862  SCIP_CALL( heur->heurinitsol(set->scip, heur) );
863 
864  /* stop timing */
865  SCIPclockStop(heur->setuptime, set);
866  }
867 
868  return SCIP_OKAY;
869 }
870 
871 /** informs primal heuristic that the branch and bound process data is being freed */
873  SCIP_HEUR* heur, /**< primal heuristic */
874  SCIP_SET* set /**< global SCIP settings */
875  )
876 {
877  assert(heur != NULL);
878  assert(set != NULL);
879 
880  /* call solving process deinitialization method of primal heuristic */
881  if( heur->heurexitsol != NULL )
882  {
883  /* start timing */
884  SCIPclockStart(heur->setuptime, set);
885 
886  SCIP_CALL( heur->heurexitsol(set->scip, heur) );
887 
888  /* stop timing */
889  SCIPclockStop(heur->setuptime, set);
890  }
891 
892  return SCIP_OKAY;
893 }
894 
895 /** should the heuristic be executed at the given depth, frequency, timing, ... */
897  SCIP_HEUR* heur, /**< primal heuristic */
898  int depth, /**< depth of current node */
899  int lpstateforkdepth, /**< depth of the last node with solved LP */
900  SCIP_HEURTIMING heurtiming, /**< current point in the node solving process */
901  SCIP_Bool* delayed /**< pointer to store whether the heuristic should be delayed */
902  )
903 {
904  SCIP_Bool execute;
905 
908  {
909  /* heuristic may be executed before/during presolving. Do so, if it was not disabled by setting the frequency to -1 */
910  execute = heur->freq >= 0;
911  }
912  else if( (heur->timingmask & SCIP_HEURTIMING_AFTERPSEUDONODE) == 0
913  && (heurtiming == SCIP_HEURTIMING_AFTERLPNODE || heurtiming == SCIP_HEURTIMING_AFTERLPPLUNGE) )
914  {
915  /* heuristic was skipped on intermediate pseudo nodes: check, if a node matching the execution frequency lies
916  * between the current node and the last LP node of the path
917  */
918  execute = (heur->freq > 0 && depth >= heur->freqofs
919  && ((depth + heur->freq - heur->freqofs) / heur->freq
920  != (lpstateforkdepth + heur->freq - heur->freqofs) / heur->freq));
921  }
922  else
923  {
924  /* heuristic may be executed on every node: check, if the current depth matches the execution frequency and offset */
925  execute = (heur->freq > 0 && depth >= heur->freqofs && (depth - heur->freqofs) % heur->freq == 0);
926  }
927 
928  /* if frequency is zero, execute heuristic only at the depth level of the frequency offset */
929  execute = execute || (depth == heur->freqofs && heur->freq == 0);
930 
931  /* compare current depth against heuristic's maximal depth level */
932  execute = execute && (heur->maxdepth == -1 || depth <= heur->maxdepth);
933 
934  /* if the heuristic was delayed, execute it anyway */
935  execute = execute || (heur->delaypos >= 0);
936 
937  /* if the heuristic should be called after plunging but not during plunging, delay it if we are in plunging */
938  if( execute
939  && ((heurtiming == SCIP_HEURTIMING_AFTERLPNODE
940  && (heur->timingmask & SCIP_HEURTIMING_AFTERLPNODE) == 0
941  && (heur->timingmask & SCIP_HEURTIMING_AFTERLPPLUNGE) > 0)
942  || (heurtiming == SCIP_HEURTIMING_AFTERPSEUDONODE
944  && (heur->timingmask & SCIP_HEURTIMING_AFTERPSEUDOPLUNGE) > 0)) )
945  {
946  /* the heuristic should be delayed until plunging is finished */
947  execute = FALSE;
948  *delayed = TRUE;
949  }
950 
951  /* execute heuristic only if its timing mask fits the current point in the node solving process */
952  execute = execute && (heur->timingmask & heurtiming) > 0;
953 
954  return execute;
955 }
956 
957 /** calls execution method of primal heuristic */
959  SCIP_HEUR* heur, /**< primal heuristic */
960  SCIP_SET* set, /**< global SCIP settings */
961  SCIP_PRIMAL* primal, /**< primal data */
962  int depth, /**< depth of current node */
963  int lpstateforkdepth, /**< depth of the last node with solved LP */
964  SCIP_HEURTIMING heurtiming, /**< current point in the node solving process */
965  SCIP_Bool nodeinfeasible, /**< was the current node already detected to be infeasible? */
966  int* ndelayedheurs, /**< pointer to count the number of delayed heuristics */
967  SCIP_RESULT* result /**< pointer to store the result of the callback method */
968  )
969 {
970  SCIP_Bool execute;
971  SCIP_Bool delayed;
972 
973  assert(heur != NULL);
974  assert(heur->heurexec != NULL);
975  assert(heur->freq >= -1);
976  assert(heur->freqofs >= 0);
977  assert(heur->maxdepth >= -1);
978  assert(set != NULL);
979  assert(set->scip != NULL);
980  assert(primal != NULL);
981  assert(depth >= 0 || heurtiming == SCIP_HEURTIMING_BEFOREPRESOL || heurtiming == SCIP_HEURTIMING_DURINGPRESOLLOOP);
982  assert(ndelayedheurs != NULL);
983  assert(result != NULL);
984 
985  *result = SCIP_DIDNOTRUN;
986 
987  delayed = FALSE;
988  execute = SCIPheurShouldBeExecuted(heur, depth, lpstateforkdepth, heurtiming, &delayed);
989 
990  if( delayed )
991  {
992  assert(!execute);
993  *result = SCIP_DELAYED;
994  }
995 
996  if( execute )
997  {
998  SCIP_Longint oldnsolsfound;
999  SCIP_Longint oldnbestsolsfound;
1000 
1001  SCIPdebugMessage("executing primal heuristic <%s> in depth %d (delaypos: %d)\n", heur->name, depth, heur->delaypos);
1002 
1003  oldnsolsfound = primal->nsolsfound;
1004  oldnbestsolsfound = primal->nbestsolsfound;
1005 
1006  /* start timing */
1007  SCIPclockStart(heur->heurclock, set);
1008 
1009  /* call external method */
1010  SCIP_CALL( heur->heurexec(set->scip, heur, heurtiming, nodeinfeasible, result) );
1011 
1012  /* stop timing */
1013  SCIPclockStop(heur->heurclock, set);
1014 
1015  /* evaluate result */
1016  if( *result != SCIP_FOUNDSOL
1017  && *result != SCIP_DIDNOTFIND
1018  && *result != SCIP_DIDNOTRUN
1019  && *result != SCIP_DELAYED )
1020  {
1021  SCIPerrorMessage("execution method of primal heuristic <%s> returned invalid result <%d>\n",
1022  heur->name, *result);
1023  return SCIP_INVALIDRESULT;
1024  }
1025  if( *result != SCIP_DIDNOTRUN && *result != SCIP_DELAYED )
1026  heur->ncalls++;
1027  heur->nsolsfound += primal->nsolsfound - oldnsolsfound;
1028  heur->nbestsolsfound += primal->nbestsolsfound - oldnbestsolsfound;
1029 
1030  /* update delay position of heuristic */
1031  if( *result != SCIP_DELAYED && heur->delaypos != -1 )
1032  {
1033  heur->delaypos = -1;
1034  set->heurssorted = FALSE;
1035  }
1036  }
1037  assert(*result == SCIP_DIDNOTRUN || *result == SCIP_DELAYED || heur->delaypos == -1);
1038 
1039  /* check if the heuristic was (still) delayed */
1040  if( *result == SCIP_DELAYED || heur->delaypos >= 0 )
1041  {
1042  SCIPdebugMessage("delaying execution of primal heuristic <%s> in depth %d (delaypos: %d), heur was%s delayed before, had delaypos %d\n",
1043  heur->name, depth, *ndelayedheurs, heur->delaypos >= 0 ? "" : " not", heur->delaypos);
1044 
1045  /* mark the heuristic delayed */
1046  if( heur->delaypos != *ndelayedheurs )
1047  {
1048  heur->delaypos = *ndelayedheurs;
1049  set->heurssorted = FALSE;
1050  }
1051  (*ndelayedheurs)++;
1052  }
1053 
1054  return SCIP_OKAY;
1055 }
1056 
1057 /** gets user data of primal heuristic */
1059  SCIP_HEUR* heur /**< primal heuristic */
1060  )
1061 {
1062  assert(heur != NULL);
1063 
1064  return heur->heurdata;
1065 }
1066 
1067 /** sets user data of primal heuristic; user has to free old data in advance! */
1069  SCIP_HEUR* heur, /**< primal heuristic */
1070  SCIP_HEURDATA* heurdata /**< new primal heuristic user data */
1071  )
1072 {
1073  assert(heur != NULL);
1074 
1075  heur->heurdata = heurdata;
1076 }
1077 
1078 /* new callback setter methods */
1079 
1080 /** sets copy callback of primal heuristic */
1082  SCIP_HEUR* heur, /**< primal heuristic */
1083  SCIP_DECL_HEURCOPY ((*heurcopy)) /**< copy callback of primal heuristic or NULL if you don't want to copy your plugin into sub-SCIPs */
1084  )
1085 {
1086  assert(heur != NULL);
1087 
1088  heur->heurcopy = heurcopy;
1089 }
1090 
1091 /** sets destructor callback of primal heuristic */
1093  SCIP_HEUR* heur, /**< primal heuristic */
1094  SCIP_DECL_HEURFREE ((*heurfree)) /**< destructor of primal heuristic */
1095  )
1096 {
1097  assert(heur != NULL);
1098 
1099  heur->heurfree = heurfree;
1100 }
1101 
1102 /** sets initialization callback of primal heuristic */
1104  SCIP_HEUR* heur, /**< primal heuristic */
1105  SCIP_DECL_HEURINIT ((*heurinit)) /**< initialize primal heuristic */
1106  )
1107 {
1108  assert(heur != NULL);
1109 
1110  heur->heurinit = heurinit;
1111 }
1112 
1113 /** sets deinitialization callback of primal heuristic */
1115  SCIP_HEUR* heur, /**< primal heuristic */
1116  SCIP_DECL_HEUREXIT ((*heurexit)) /**< deinitialize primal heuristic */
1117  )
1118 {
1119  assert(heur != NULL);
1120 
1121  heur->heurexit = heurexit;
1122 }
1123 
1124 /** sets solving process initialization callback of primal heuristic */
1126  SCIP_HEUR* heur, /**< primal heuristic */
1127  SCIP_DECL_HEURINITSOL ((*heurinitsol)) /**< solving process initialization callback of primal heuristic */
1128  )
1129 {
1130  assert(heur != NULL);
1131 
1132  heur->heurinitsol = heurinitsol;
1133 }
1134 
1135 /** sets solving process deinitialization callback of primal heuristic */
1137  SCIP_HEUR* heur, /**< primal heuristic */
1138  SCIP_DECL_HEUREXITSOL ((*heurexitsol)) /**< solving process deinitialization callback of primal heuristic */
1139  )
1140 {
1141  assert(heur != NULL);
1142 
1143  heur->heurexitsol = heurexitsol;
1144 }
1145 
1146 /** gets name of primal heuristic */
1147 const char* SCIPheurGetName(
1148  SCIP_HEUR* heur /**< primal heuristic */
1149  )
1150 {
1151  assert(heur != NULL);
1152 
1153  return heur->name;
1154 }
1155 
1156 /** gets description of primal heuristic */
1157 const char* SCIPheurGetDesc(
1158  SCIP_HEUR* heur /**< primal heuristic */
1159  )
1160 {
1161  assert(heur != NULL);
1162 
1163  return heur->desc;
1164 }
1165 
1166 /** gets display character of primal heuristic */
1168  SCIP_HEUR* heur /**< primal heuristic */
1169  )
1170 {
1171  assert(heur != NULL);
1172 
1173  return heur->dispchar;
1174 }
1175 
1176 /** returns the timing mask of the heuristic */
1178  SCIP_HEUR* heur /**< primal heuristic */
1179  )
1180 {
1181  assert(heur != NULL);
1182 
1183  return heur->timingmask;
1184 }
1185 
1186 /** sets new timing mask for heuristic */
1188  SCIP_HEUR* heur, /**< primal heuristic */
1189  SCIP_HEURTIMING timingmask /**< new timing mask of heuristic */
1190  )
1191 {
1192  assert(heur != NULL);
1193 
1194  heur->timingmask = timingmask;
1195 }
1196 
1197 /** does the heuristic use a secondary SCIP instance? */
1199  SCIP_HEUR* heur /**< primal heuristic */
1200  )
1201 {
1202  assert(heur != NULL);
1203 
1204  return heur->usessubscip;
1205 }
1206 
1207 /** gets priority of primal heuristic */
1209  SCIP_HEUR* heur /**< primal heuristic */
1210  )
1211 {
1212  assert(heur != NULL);
1213 
1214  return heur->priority;
1215 }
1216 
1217 /** sets priority of primal heuristic */
1219  SCIP_HEUR* heur, /**< primal heuristic */
1220  SCIP_SET* set, /**< global SCIP settings */
1221  int priority /**< new priority of the primal heuristic */
1222  )
1223 {
1224  assert(heur != NULL);
1225  assert(set != NULL);
1226 
1227  heur->priority = priority;
1228  set->heurssorted = FALSE;
1229 }
1230 
1231 /** gets frequency of primal heuristic */
1233  SCIP_HEUR* heur /**< primal heuristic */
1234  )
1235 {
1236  assert(heur != NULL);
1237 
1238  return heur->freq;
1239 }
1240 
1241 /** sets frequency of primal heuristic */
1243  SCIP_HEUR* heur, /**< primal heuristic */
1244  int freq /**< new frequency of heuristic */
1245  )
1246 {
1247  assert(heur != NULL);
1248 
1249  heur->freq = freq;
1250 }
1251 
1252 /** gets frequency offset of primal heuristic */
1254  SCIP_HEUR* heur /**< primal heuristic */
1255  )
1256 {
1257  assert(heur != NULL);
1258 
1259  return heur->freqofs;
1260 }
1261 
1262 /** gets maximal depth level for calling primal heuristic (returns -1, if no depth limit exists) */
1264  SCIP_HEUR* heur /**< primal heuristic */
1265  )
1266 {
1267  assert(heur != NULL);
1268 
1269  return heur->maxdepth;
1270 }
1271 
1272 /** gets the number of times, the heuristic was called and tried to find a solution */
1274  SCIP_HEUR* heur /**< primal heuristic */
1275  )
1276 {
1277  assert(heur != NULL);
1278 
1279  return heur->ncalls;
1280 }
1281 
1282 /** gets the number of primal feasible solutions found by this heuristic */
1284  SCIP_HEUR* heur /**< primal heuristic */
1285  )
1286 {
1287  assert(heur != NULL);
1288 
1289  return heur->nsolsfound;
1290 }
1291 
1292 /** gets the number of new best primal feasible solutions found by this heuristic */
1294  SCIP_HEUR* heur /**< primal heuristic */
1295  )
1296 {
1297  assert(heur != NULL);
1298 
1299  return heur->nbestsolsfound;
1300 }
1301 
1302 /** is primal heuristic initialized? */
1304  SCIP_HEUR* heur /**< primal heuristic */
1305  )
1306 {
1307  assert(heur != NULL);
1308 
1309  return heur->initialized;
1310 }
1311 
1312 /** enables or disables all clocks of \p heur, depending on the value of the flag */
1314  SCIP_HEUR* heur, /**< the heuristic for which all clocks should be enabled or disabled */
1315  SCIP_Bool enable /**< should the clocks of the heuristic be enabled? */
1316  )
1317 {
1318  assert(heur != NULL);
1319 
1320  SCIPclockEnableOrDisable(heur->setuptime, enable);
1321  SCIPclockEnableOrDisable(heur->heurclock, enable);
1322 }
1323 
1324 /** gets time in seconds used in this heuristic for setting up for next stages */
1326  SCIP_HEUR* heur /**< primal heuristic */
1327  )
1328 {
1329  assert(heur != NULL);
1330 
1331  return SCIPclockGetTime(heur->setuptime);
1332 }
1333 
1334 /** gets time in seconds used in this heuristic */
1336  SCIP_HEUR* heur /**< primal heuristic */
1337  )
1338 {
1339  assert(heur != NULL);
1340 
1341  return SCIPclockGetTime(heur->heurclock);
1342 }
1343 
1344 /** returns array of divesets of this primal heuristic, or NULL if it has no divesets */
1346  SCIP_HEUR* heur /**< primal heuristic */
1347  )
1348 {
1349  assert(heur != NULL);
1350 
1351  return heur->divesets;
1352 }
1353 
1354 /** returns the number of divesets of this primal heuristic */
1356  SCIP_HEUR* heur /**< primal heuristic */
1357  )
1358 {
1359  assert(heur != NULL);
1360 
1361  return heur->ndivesets;
1362 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:51
SCIP_Bool onlylpbranchcands
Definition: struct_heur.h:68
SCIP_Real SCIPdivesetGetAvgDepth(SCIP_DIVESET *diveset)
Definition: heur.c:405
#define BMSfreeMemoryArray(ptr)
Definition: memory.h:102
void SCIPheurSetInitsol(SCIP_HEUR *heur, SCIP_DECL_HEURINITSOL((*heurinitsol)))
Definition: heur.c:1125
static SCIP_DECL_PARAMCHGD(paramChgdHeurPriority)
Definition: heur.c:71
int SCIPdivesetGetLPSolveFreq(SCIP_DIVESET *diveset)
Definition: heur.c:530
SCIP_Longint totalnnodes
Definition: struct_heur.h:55
#define SCIP_DECL_HEURINITSOL(x)
Definition: type_heur.h:95
SCIP_Longint SCIPdivesetGetNProbingNodes(SCIP_DIVESET *diveset)
Definition: heur.c:455
SCIP_RETCODE SCIPheurFree(SCIP_HEUR **heur, SCIP_SET *set)
Definition: heur.c:728
SCIP_Bool SCIPdivesetUseBacktrack(SCIP_DIVESET *diveset)
Definition: heur.c:522
SCIP_RETCODE SCIPdivesetGetScore(SCIP_DIVESET *diveset, SCIP_SET *set, SCIP_DIVETYPE divetype, SCIP_VAR *divecand, SCIP_Real divecandsol, SCIP_Real divecandfrac, SCIP_Real *candscore, SCIP_Bool *roundup)
Definition: heur.c:599
const char * SCIPdivesetGetName(SCIP_DIVESET *diveset)
Definition: heur.c:331
const char * SCIPheurGetDesc(SCIP_HEUR *heur)
Definition: heur.c:1157
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition: heur.c:1147
SCIP_HEUR * heur
Definition: struct_heur.h:38
SCIP_Longint SCIPheurGetNCalls(SCIP_HEUR *heur)
Definition: heur.c:1273
SCIP_Longint totalnbacktracks
Definition: struct_heur.h:56
SCIP_Longint SCIPheurGetNSolsFound(SCIP_HEUR *heur)
Definition: heur.c:1283
SCIP_DIVESET ** divesets
Definition: struct_heur.h:90
SCIP_PARAMDATA * SCIPparamGetData(SCIP_PARAM *param)
Definition: paramset.c:651
SCIP_RETCODE SCIPdivesetCreate(SCIP_DIVESET **diveset, SCIP_HEUR *heur, const char *name, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, SCIP_Real minreldepth, SCIP_Real maxreldepth, SCIP_Real maxlpiterquot, SCIP_Real maxdiveubquot, SCIP_Real maxdiveavgquot, SCIP_Real maxdiveubquotnosol, SCIP_Real maxdiveavgquotnosol, SCIP_Real lpresolvedomchgquot, int lpsolvefreq, int maxlpiterofs, SCIP_Bool backtrack, SCIP_Bool onlylpbranchcands, SCIP_DIVETYPE divetypemask, SCIP_DECL_DIVESETGETSCORE((*divesetgetscore)))
Definition: heur.c:176
static void divesetFree(SCIP_DIVESET **diveset)
Definition: heur.c:587
#define SCIP_MAXSTRLEN
Definition: def.h:201
int ndivesets
Definition: struct_heur.h:98
internal methods for clocks and timing issues
unsigned int SCIP_HEURTIMING
Definition: type_timing.h:95
#define NULL
Definition: lpi_spx.cpp:130
SCIP_Real SCIPdivesetGetUbQuot(SCIP_DIVESET *diveset)
Definition: heur.c:506
void SCIPheurSetExitsol(SCIP_HEUR *heur, SCIP_DECL_HEUREXITSOL((*heurexitsol)))
Definition: heur.c:1136
struct SCIP_ParamData SCIP_PARAMDATA
Definition: type_paramset.h:73
int delaypos
Definition: struct_heur.h:97
int SCIPdivesetGetMinDepth(SCIP_DIVESET *diveset)
Definition: heur.c:385
SCIP_Real maxreldepth
Definition: struct_heur.h:42
SCIP_Bool backtrack
Definition: struct_heur.h:67
SCIP_Longint SCIPdivesetGetNBacktracks(SCIP_DIVESET *diveset)
Definition: heur.c:465
SCIP_Real SCIPdivesetGetAvgSolutionDepth(SCIP_DIVESET *diveset)
Definition: heur.c:435
static SCIP_RETCODE heurAddDiveset(SCIP_HEUR *heur, SCIP_DIVESET *diveset)
Definition: heur.c:146
SCIP_Real maxlpiterquot
Definition: struct_heur.h:43
SCIP_Real SCIPdivesetGetLPResolveDomChgQuot(SCIP_DIVESET *diveset)
Definition: heur.c:540
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:350
void SCIPheurSetFreq(SCIP_HEUR *heur, int freq)
Definition: heur.c:1242
#define FALSE
Definition: def.h:56
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:280
SCIP_Longint nsolsfound
Definition: struct_heur.h:78
SCIP_CLOCK * heurclock
Definition: struct_heur.h:92
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:8174
SCIP_RETCODE SCIPheurExec(SCIP_HEUR *heur, SCIP_SET *set, SCIP_PRIMAL *primal, int depth, int lpstateforkdepth, SCIP_HEURTIMING heurtiming, SCIP_Bool nodeinfeasible, int *ndelayedheurs, SCIP_RESULT *result)
Definition: heur.c:958
SCIP_Longint totaldepth
Definition: struct_heur.h:53
#define TRUE
Definition: def.h:55
char * name
Definition: struct_heur.h:39
#define SCIP_DECL_HEURCOPY(x)
Definition: type_heur.h:60
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
#define SCIP_DECL_HEUREXEC(x)
Definition: type_heur.h:126
SCIP_RETCODE SCIPheurInitsol(SCIP_HEUR *heur, SCIP_SET *set)
Definition: heur.c:842
#define SCIP_CALL(x)
Definition: def.h:266
int SCIPheurGetNDivesets(SCIP_HEUR *heur)
Definition: heur.c:1355
void SCIPheurSetPriority(SCIP_HEUR *heur, SCIP_SET *set, int priority)
Definition: heur.c:1218
SCIP_CLOCK * setuptime
Definition: struct_heur.h:91
int SCIPdivesetGetMaxSolutionDepth(SCIP_DIVESET *diveset)
Definition: heur.c:425
struct SCIP_HeurData SCIP_HEURDATA
Definition: type_heur.h:51
char dispchar
Definition: struct_heur.h:102
SCIP_Longint nsolsfound
Definition: struct_primal.h:38
#define SCIPdebugMessage
Definition: pub_message.h:77
unsigned int SCIP_DIVETYPE
Definition: type_heur.h:48
int SCIPdivesetGetNCalls(SCIP_DIVESET *diveset)
Definition: heur.c:365
unsigned int timingmask
Definition: struct_heur.h:99
int SCIPheurGetMaxdepth(SCIP_HEUR *heur)
Definition: heur.c:1263
internal methods for handling parameter settings
SCIP_RETCODE SCIPheurCopyInclude(SCIP_HEUR *heur, SCIP_SET *set)
Definition: heur.c:624
void SCIPclockEnableOrDisable(SCIP_CLOCK *clck, SCIP_Bool enable)
Definition: clock.c:250
SCIP_DIVESET ** SCIPheurGetDivesets(SCIP_HEUR *heur)
Definition: heur.c:1345
SCIP_Bool usessubscip
Definition: struct_heur.h:100
#define SCIP_DECL_DIVESETGETSCORE(x)
Definition: type_heur.h:146
internal methods for collecting primal CIP solutions and primal informations
#define SCIP_HEURTIMING_AFTERPSEUDOPLUNGE
Definition: type_timing.h:80
SCIP_Real maxdiveavgquotnosol
Definition: struct_heur.h:49
SCIP_Real SCIPdivesetGetAvgQuot(SCIP_DIVESET *diveset)
Definition: heur.c:514
void SCIPdivesetUpdateLPStats(SCIP_DIVESET *diveset, SCIP_STAT *stat, SCIP_Longint niterstoadd)
Definition: heur.c:573
SCIP_HEUR * SCIPdivesetGetHeur(SCIP_DIVESET *diveset)
Definition: heur.c:302
char * name
Definition: struct_heur.h:80
SCIP_Real SCIPdivesetGetMaxLPIterQuot(SCIP_DIVESET *diveset)
Definition: heur.c:475
void SCIPdivesetReset(SCIP_DIVESET *diveset)
Definition: heur.c:85
#define SCIPerrorMessage
Definition: pub_message.h:45
SCIP_Longint nbestsolsfound
Definition: struct_primal.h:41
int ndivesetcalls
Definition: struct_stat.h:166
#define SCIP_HEURTIMING_AFTERLPNODE
Definition: type_timing.h:71
void SCIPclockReset(SCIP_CLOCK *clck)
Definition: clock.c:199
SCIP_SOL * sol
Definition: struct_heur.h:40
#define BMSallocMemory(ptr)
Definition: memory.h:74
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:428
void SCIPheurSetCopy(SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
Definition: heur.c:1081
SCIP_Real lpresolvedomchgquot
Definition: struct_heur.h:50
SCIP_Real maxdiveubquot
Definition: struct_heur.h:44
SCIP_RETCODE SCIPsetHeurPriority(SCIP *scip, SCIP_HEUR *heur, int priority)
Definition: scip.c:7430
void SCIPheurSetTimingmask(SCIP_HEUR *heur, SCIP_HEURTIMING timingmask)
Definition: heur.c:1187
internal methods for global SCIP settings
#define SCIP_HEURTIMING_DURINGPRESOLLOOP
Definition: type_timing.h:85
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:82
#define BMSfreeMemory(ptr)
Definition: memory.h:100
SCIP_Bool initialized
Definition: struct_heur.h:101
#define SCIP_HEURTIMING_BEFOREPRESOL
Definition: type_timing.h:84
SCIP_RETCODE SCIPsetAddIntParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, 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: set.c:2455
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition: heur.c:1068
SCIP_Longint nlpiterations
Definition: struct_heur.h:51
#define BMSduplicateMemoryArray(ptr, source, num)
Definition: memory.h:98
SCIP_RETCODE SCIPclockCreate(SCIP_CLOCK **clck, SCIP_CLOCKTYPE clocktype)
Definition: clock.c:160
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:103
char SCIPheurGetDispchar(SCIP_HEUR *heur)
Definition: heur.c:1167
SCIP_Bool SCIPheurUsesSubscip(SCIP_HEUR *heur)
Definition: heur.c:1198
SCIP_Longint totalsoldepth
Definition: struct_heur.h:54
datastructures for primal heuristics
SCIP_Bool SCIPheurIsInitialized(SCIP_HEUR *heur)
Definition: heur.c:1303
public data structures and miscellaneous methods
#define SCIP_Bool
Definition: def.h:53
SCIP_Bool SCIPdivesetSupportsType(SCIP_DIVESET *diveset, SCIP_DIVETYPE divetype)
Definition: heur.c:562
SCIP_Longint ndivesetlpiterations
Definition: struct_stat.h:59
SCIP_Real SCIPdivesetGetUbQuotNoSol(SCIP_DIVESET *diveset)
Definition: heur.c:491
SCIP_Longint ndivesetlps
Definition: struct_stat.h:157
SCIP_Real SCIPdivesetGetMaxRelDepth(SCIP_DIVESET *diveset)
Definition: heur.c:349
void SCIPdivesetUpdateStats(SCIP_DIVESET *diveset, SCIP_STAT *stat, int depth, int nprobingnodes, int nbacktracks, SCIP_Longint nsolsfound, SCIP_Longint nbestsolsfound, SCIP_Bool leavesol)
Definition: heur.c:108
static const char * paramname[]
Definition: lpi_msk.c:4201
void SCIPclockFree(SCIP_CLOCK **clck)
Definition: clock.c:175
SCIP_Bool SCIPheurShouldBeExecuted(SCIP_HEUR *heur, int depth, int lpstateforkdepth, SCIP_HEURTIMING heurtiming, SCIP_Bool *delayed)
Definition: heur.c:896
SCIP_RETCODE SCIPheurInit(SCIP_HEUR *heur, SCIP_SET *set)
Definition: heur.c:762
int SCIPheurGetPriority(SCIP_HEUR *heur)
Definition: heur.c:1208
#define MAX(x, y)
Definition: tclique_def.h:75
SCIP_Real SCIPdivesetGetMinRelDepth(SCIP_DIVESET *diveset)
Definition: heur.c:341
char * desc
Definition: struct_heur.h:81
void SCIPheurSetFree(SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
Definition: heur.c:1092
int priority
Definition: struct_heur.h:93
void SCIPheurEnableOrDisableClocks(SCIP_HEUR *heur, SCIP_Bool enable)
Definition: heur.c:1313
SCIP_Longint SCIPdivesetGetNLPIterations(SCIP_DIVESET *diveset)
Definition: heur.c:445
SCIP_DIVETYPE divetypemask
Definition: struct_heur.h:70
SCIP_HEURDATA * heurdata
Definition: struct_heur.h:89
SCIP_HEURTIMING SCIPheurGetTimingmask(SCIP_HEUR *heur)
Definition: heur.c:1177
int SCIPdivesetGetMinSolutionDepth(SCIP_DIVESET *diveset)
Definition: heur.c:415
int SCIPdivesetGetMaxDepth(SCIP_DIVESET *diveset)
Definition: heur.c:395
#define SCIP_REAL_MAX
Definition: def.h:128
int SCIPparamGetInt(SCIP_PARAM *param)
Definition: paramset.c:706
void SCIPdivesetSetWorkSolution(SCIP_DIVESET *diveset, SCIP_SOL *sol)
Definition: heur.c:320
SCIP_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
Definition: heur.c:1293
SCIP_Real SCIPheurGetSetupTime(SCIP_HEUR *heur)
Definition: heur.c:1325
SCIP_Real maxdiveavgquot
Definition: struct_heur.h:46
SCIP_RETCODE SCIPheurCreate(SCIP_HEUR **heur, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, unsigned int timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEURCOPY((*heurcopy)), SCIP_DECL_HEURFREE((*heurfree)), SCIP_DECL_HEURINIT((*heurinit)), SCIP_DECL_HEUREXIT((*heurexit)), SCIP_DECL_HEURINITSOL((*heurinitsol)), SCIP_DECL_HEUREXITSOL((*heurexitsol)), SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
Definition: heur.c:643
SCIP_Longint ncalls
Definition: struct_heur.h:77
void SCIPheurSetExit(SCIP_HEUR *heur, SCIP_DECL_HEUREXIT((*heurexit)))
Definition: heur.c:1114
#define SCIP_DECL_HEUREXIT(x)
Definition: type_heur.h:84
SCIP_RETCODE SCIPheurExit(SCIP_HEUR *heur, SCIP_SET *set)
Definition: heur.c:812
public methods for message output
SCIP_Longint nsolsfound
Definition: struct_heur.h:57
#define SCIP_DECL_HEURINIT(x)
Definition: type_heur.h:76
#define SCIP_HEURTIMING_AFTERPSEUDONODE
Definition: type_timing.h:74
SCIP_Longint nbestsolsfound
Definition: struct_heur.h:79
#define SCIP_Real
Definition: def.h:127
int SCIPheurGetFreq(SCIP_HEUR *heur)
Definition: heur.c:1232
SCIP_Real SCIPheurGetTime(SCIP_HEUR *heur)
Definition: heur.c:1335
void SCIPheurSetInit(SCIP_HEUR *heur, SCIP_DECL_HEURINIT((*heurinit)))
Definition: heur.c:1103
#define MIN(x, y)
Definition: memory.c:67
SCIP_Longint nbestsolsfound
Definition: struct_heur.h:58
#define SCIP_DECL_HEURFREE(x)
Definition: type_heur.h:68
#define SCIP_Longint
Definition: def.h:112
SCIP_Real SCIPdivesetGetAvgQuotNoSol(SCIP_DIVESET *diveset)
Definition: heur.c:499
SCIP_Real minreldepth
Definition: struct_heur.h:41
int SCIPdivesetGetMaxLPIterOffset(SCIP_DIVESET *diveset)
Definition: heur.c:483
int SCIPdivesetGetNSolutionCalls(SCIP_DIVESET *diveset)
Definition: heur.c:375
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition: heur.c:1058
#define SCIP_HEURTIMING_AFTERLPPLUNGE
Definition: type_timing.h:77
int maxlpiterofs
Definition: struct_heur.h:59
SCIP_Longint nlps
Definition: struct_heur.h:52
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:78
common defines and data types used in all packages of SCIP
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:392
SCIP_RETCODE SCIPsetAddRealParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, 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: set.c:2503
internal methods for primal heuristics
SCIP_RETCODE SCIPheurExitsol(SCIP_HEUR *heur, SCIP_SET *set)
Definition: heur.c:872
#define SCIP_ALLOC(x)
Definition: def.h:277
SCIP_RETCODE SCIPsetAddBoolParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: set.c:2433
#define SCIP_DECL_HEUREXITSOL(x)
Definition: type_heur.h:106
SCIP_SOL * SCIPdivesetGetWorkSolution(SCIP_DIVESET *diveset)
Definition: heur.c:310
SCIP_DECL_SORTPTRCOMP(SCIPheurComp)
Definition: heur.c:40
SCIP_Real maxdiveubquotnosol
Definition: struct_heur.h:48
SCIP_Longint SCIPdivesetGetSolSuccess(SCIP_DIVESET *diveset)
Definition: heur.c:357
SCIP callable library.
int maxdepth
Definition: struct_heur.h:96
SCIP_Bool SCIPdivesetUseOnlyLPBranchcands(SCIP_DIVESET *diveset)
Definition: heur.c:552
SCIP_Longint totaldivesetdepth
Definition: struct_stat.h:164
int SCIPheurGetFreqofs(SCIP_HEUR *heur)
Definition: heur.c:1253
int freqofs
Definition: struct_heur.h:95