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-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.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 
40 
41 /** compares two heuristics w. r. to their delay positions and their priority */
42 SCIP_DECL_SORTPTRCOMP(SCIPheurComp)
43 { /*lint --e{715}*/
44  SCIP_HEUR* heur1 = (SCIP_HEUR*)elem1;
45  SCIP_HEUR* heur2 = (SCIP_HEUR*)elem2;
46 
47  assert(heur1 != NULL);
48  assert(heur2 != NULL);
49 
50  if( heur1->delaypos == heur2->delaypos )
51  return heur2->priority - heur1->priority; /* prefer higher priorities */
52  else if( heur1->delaypos == -1 )
53  return +1; /* prefer delayed heuristics */
54  else if( heur2->delaypos == -1 )
55  return -1; /* prefer delayed heuristics */
56  else if( heur1->ncalls * heur1->freq > heur2->ncalls * heur2->freq )
57  return +1;
58  else if( heur1->ncalls * heur1->freq < heur2->ncalls * heur2->freq )
59  return -1;
60  else
61  return heur1->delaypos - heur2->delaypos; /* prefer lower delay positions */
62 }
63 
64 
65 /** comparison method for sorting heuristics w.r.t. to their name */
66 SCIP_DECL_SORTPTRCOMP(SCIPheurCompName)
67 {
68  return strcmp(SCIPheurGetName((SCIP_HEUR*)elem1), SCIPheurGetName((SCIP_HEUR*)elem2));
69 }
70 
71 /** method to call, when the priority of a heuristic was changed */
72 static
73 SCIP_DECL_PARAMCHGD(paramChgdHeurPriority)
74 { /*lint --e{715}*/
75  SCIP_PARAMDATA* paramdata;
76 
77  paramdata = SCIPparamGetData(param);
78  assert(paramdata != NULL);
79 
80  /* use SCIPsetHeurPriority() to mark the heuristics unsorted */
81  SCIP_CALL( SCIPsetHeurPriority(scip, (SCIP_HEUR*)paramdata, SCIPparamGetInt(param)) ); /*lint !e740*/
82 
83  return SCIP_OKAY;
84 }
85 
86 /** copies the given primal heuristic to a new scip */
88  SCIP_HEUR* heur, /**< primal heuristic */
89  SCIP_SET* set /**< SCIP_SET of SCIP to copy to */
90  )
91 {
92  assert(heur != NULL);
93  assert(set != NULL);
94  assert(set->scip != NULL);
95 
96  if( heur->heurcopy != NULL )
97  {
98  SCIPdebugMessage("including heur %s in subscip %p\n", SCIPheurGetName(heur), (void*)set->scip);
99  SCIP_CALL( heur->heurcopy(set->scip, heur) );
100  }
101 
102  return SCIP_OKAY;
103 }
104 
105 /** creates a primal heuristic */
107  SCIP_HEUR** heur, /**< pointer to primal heuristic data structure */
108  SCIP_SET* set, /**< global SCIP settings */
109  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
110  BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
111  const char* name, /**< name of primal heuristic */
112  const char* desc, /**< description of primal heuristic */
113  char dispchar, /**< display character of primal heuristic */
114  int priority, /**< priority of the primal heuristic */
115  int freq, /**< frequency for calling primal heuristic */
116  int freqofs, /**< frequency offset for calling primal heuristic */
117  int maxdepth, /**< maximal depth level to call heuristic at (-1: no limit) */
118  unsigned int timingmask, /**< positions in the node solving loop where heuristic should be executed */
119  SCIP_Bool usessubscip, /**< does the heuristic use a secondary SCIP instance? */
120  SCIP_DECL_HEURCOPY ((*heurcopy)), /**< copy method of primal heuristic or NULL if you don't want to copy your plugin into sub-SCIPs */
121  SCIP_DECL_HEURFREE ((*heurfree)), /**< destructor of primal heuristic */
122  SCIP_DECL_HEURINIT ((*heurinit)), /**< initialize primal heuristic */
123  SCIP_DECL_HEUREXIT ((*heurexit)), /**< deinitialize primal heuristic */
124  SCIP_DECL_HEURINITSOL ((*heurinitsol)), /**< solving process initialization method of primal heuristic */
125  SCIP_DECL_HEUREXITSOL ((*heurexitsol)), /**< solving process deinitialization method of primal heuristic */
126  SCIP_DECL_HEUREXEC ((*heurexec)), /**< execution method of primal heuristic */
127  SCIP_HEURDATA* heurdata /**< primal heuristic data */
128  )
129 {
131  char paramdesc[SCIP_MAXSTRLEN];
132 
133  assert(heur != NULL);
134  assert(name != NULL);
135  assert(desc != NULL);
136  assert(freq >= -1);
137  assert(freqofs >= 0);
138  assert(heurexec != NULL);
139 
140  SCIP_ALLOC( BMSallocMemory(heur) );
141  SCIP_ALLOC( BMSduplicateMemoryArray(&(*heur)->name, name, strlen(name)+1) );
142  SCIP_ALLOC( BMSduplicateMemoryArray(&(*heur)->desc, desc, strlen(desc)+1) );
143  (*heur)->dispchar = dispchar;
144  (*heur)->priority = priority;
145  (*heur)->freq = freq;
146  (*heur)->freqofs = freqofs;
147  (*heur)->maxdepth = maxdepth;
148  (*heur)->delaypos = -1;
149  (*heur)->timingmask = timingmask;
150  (*heur)->usessubscip = usessubscip;
151  (*heur)->heurcopy = heurcopy;
152  (*heur)->heurfree = heurfree;
153  (*heur)->heurinit = heurinit;
154  (*heur)->heurexit = heurexit;
155  (*heur)->heurinitsol = heurinitsol;
156  (*heur)->heurexitsol = heurexitsol;
157  (*heur)->heurexec = heurexec;
158  (*heur)->heurdata = heurdata;
159  SCIP_CALL( SCIPclockCreate(&(*heur)->setuptime, SCIP_CLOCKTYPE_DEFAULT) );
160  SCIP_CALL( SCIPclockCreate(&(*heur)->heurclock, SCIP_CLOCKTYPE_DEFAULT) );
161  (*heur)->ncalls = 0;
162  (*heur)->nsolsfound = 0;
163  (*heur)->nbestsolsfound = 0;
164  (*heur)->initialized = FALSE;
165 
166  /* add parameters */
167  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/priority", name);
168  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of heuristic <%s>", name);
169  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
170  &(*heur)->priority, TRUE, priority, INT_MIN/4, INT_MAX/4,
171  paramChgdHeurPriority, (SCIP_PARAMDATA*)(*heur)) ); /*lint !e740*/
172  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/freq", name);
173  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "frequency for calling primal heuristic <%s> (-1: never, 0: only at depth freqofs)", name);
174  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
175  &(*heur)->freq, FALSE, freq, -1, INT_MAX, NULL, NULL) );
176  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/freqofs", name);
177  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "frequency offset for calling primal heuristic <%s>", name);
178  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
179  &(*heur)->freqofs, FALSE, freqofs, 0, INT_MAX, NULL, NULL) );
180  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxdepth", name);
181  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "maximal depth level to call primal heuristic <%s> (-1: no limit)", name);
182  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
183  &(*heur)->maxdepth, TRUE, maxdepth, -1, INT_MAX, NULL, NULL) );
184 
185  return SCIP_OKAY;
186 }
187 
188 /** calls destructor and frees memory of primal heuristic */
190  SCIP_HEUR** heur, /**< pointer to primal heuristic data structure */
191  SCIP_SET* set /**< global SCIP settings */
192  )
193 {
194  assert(heur != NULL);
195  assert(*heur != NULL);
196  assert(!(*heur)->initialized);
197  assert(set != NULL);
198 
199  /* call destructor of primal heuristic */
200  if( (*heur)->heurfree != NULL )
201  {
202  SCIP_CALL( (*heur)->heurfree(set->scip, *heur) );
203  }
204 
205  SCIPclockFree(&(*heur)->heurclock);
206  SCIPclockFree(&(*heur)->setuptime);
207  BMSfreeMemoryArray(&(*heur)->name);
208  BMSfreeMemoryArray(&(*heur)->desc);
209  BMSfreeMemory(heur);
210 
211  return SCIP_OKAY;
212 }
213 
214 /** initializes primal heuristic */
216  SCIP_HEUR* heur, /**< primal heuristic */
217  SCIP_SET* set /**< global SCIP settings */
218  )
219 {
220  assert(heur != NULL);
221  assert(set != NULL);
222 
223  if( heur->initialized )
224  {
225  SCIPerrorMessage("primal heuristic <%s> already initialized\n", heur->name);
226  return SCIP_INVALIDCALL;
227  }
228 
229  if( set->misc_resetstat )
230  {
231  SCIPclockReset(heur->setuptime);
232  SCIPclockReset(heur->heurclock);
233 
234  heur->delaypos = -1;
235  heur->ncalls = 0;
236  heur->nsolsfound = 0;
237  heur->nbestsolsfound = 0;
238  }
239 
240  if( heur->heurinit != NULL )
241  {
242  /* start timing */
243  SCIPclockStart(heur->setuptime, set);
244 
245  SCIP_CALL( heur->heurinit(set->scip, heur) );
246 
247  /* stop timing */
248  SCIPclockStop(heur->setuptime, set);
249  }
250  heur->initialized = TRUE;
251 
252  return SCIP_OKAY;
253 }
254 
255 /** calls exit method of primal heuristic */
257  SCIP_HEUR* heur, /**< primal heuristic */
258  SCIP_SET* set /**< global SCIP settings */
259  )
260 {
261  assert(heur != NULL);
262  assert(set != NULL);
263 
264  if( !heur->initialized )
265  {
266  SCIPerrorMessage("primal heuristic <%s> not initialized\n", heur->name);
267  return SCIP_INVALIDCALL;
268  }
269 
270  if( heur->heurexit != NULL )
271  {
272  /* start timing */
273  SCIPclockStart(heur->setuptime, set);
274 
275  SCIP_CALL( heur->heurexit(set->scip, heur) );
276 
277  /* stop timing */
278  SCIPclockStop(heur->setuptime, set);
279  }
280  heur->initialized = FALSE;
281 
282  return SCIP_OKAY;
283 }
284 
285 /** informs primal heuristic that the branch and bound process is being started */
287  SCIP_HEUR* heur, /**< primal heuristic */
288  SCIP_SET* set /**< global SCIP settings */
289  )
290 {
291  assert(heur != NULL);
292  assert(set != NULL);
293 
294  if( heur->delaypos != -1 )
295  {
296  heur->delaypos = -1;
297  set->heurssorted = FALSE;
298  }
299 
300  /* call solving process initialization method of primal heuristic */
301  if( heur->heurinitsol != NULL )
302  {
303  /* start timing */
304  SCIPclockStart(heur->setuptime, set);
305 
306  SCIP_CALL( heur->heurinitsol(set->scip, heur) );
307 
308  /* stop timing */
309  SCIPclockStop(heur->setuptime, set);
310  }
311 
312  return SCIP_OKAY;
313 }
314 
315 /** informs primal heuristic that the branch and bound process data is being freed */
317  SCIP_HEUR* heur, /**< primal heuristic */
318  SCIP_SET* set /**< global SCIP settings */
319  )
320 {
321  assert(heur != NULL);
322  assert(set != NULL);
323 
324  /* call solving process deinitialization method of primal heuristic */
325  if( heur->heurexitsol != NULL )
326  {
327  /* start timing */
328  SCIPclockStart(heur->setuptime, set);
329 
330  SCIP_CALL( heur->heurexitsol(set->scip, heur) );
331 
332  /* stop timing */
333  SCIPclockStop(heur->setuptime, set);
334  }
335 
336  return SCIP_OKAY;
337 }
338 
339 /** should the heuristic be executed at the given depth, frequency, timing, ... */
341  SCIP_HEUR* heur, /**< primal heuristic */
342  int depth, /**< depth of current node */
343  int lpstateforkdepth, /**< depth of the last node with solved LP */
344  SCIP_HEURTIMING heurtiming, /**< current point in the node solving process */
345  SCIP_Bool* delayed /**< pointer to store whether the heuristic should be delayed */
346  )
347 {
348  SCIP_Bool execute;
349 
352  {
353  /* heuristic may be executed before/during presolving. Do so, if it was not disabled by setting the frequency to -1 */
354  execute = heur->freq >= 0;
355  }
356  else if( (heur->timingmask & SCIP_HEURTIMING_AFTERPSEUDONODE) == 0
357  && (heurtiming == SCIP_HEURTIMING_AFTERLPNODE || heurtiming == SCIP_HEURTIMING_AFTERLPPLUNGE) )
358  {
359  /* heuristic was skipped on intermediate pseudo nodes: check, if a node matching the execution frequency lies
360  * between the current node and the last LP node of the path
361  */
362  execute = (heur->freq > 0 && depth >= heur->freqofs
363  && ((depth + heur->freq - heur->freqofs) / heur->freq
364  != (lpstateforkdepth + heur->freq - heur->freqofs) / heur->freq));
365  }
366  else
367  {
368  /* heuristic may be executed on every node: check, if the current depth matches the execution frequency and offset */
369  execute = (heur->freq > 0 && depth >= heur->freqofs && (depth - heur->freqofs) % heur->freq == 0);
370  }
371 
372  /* if frequency is zero, execute heuristic only at the depth level of the frequency offset */
373  execute = execute || (depth == heur->freqofs && heur->freq == 0);
374 
375  /* compare current depth against heuristic's maximal depth level */
376  execute = execute && (heur->maxdepth == -1 || depth <= heur->maxdepth);
377 
378  /* if the heuristic was delayed, execute it anyway */
379  execute = execute || (heur->delaypos >= 0);
380 
381  /* if the heuristic should be called after plunging but not during plunging, delay it if we are in plunging */
382  if( execute
383  && ((heurtiming == SCIP_HEURTIMING_AFTERLPNODE
384  && (heur->timingmask & SCIP_HEURTIMING_AFTERLPNODE) == 0
385  && (heur->timingmask & SCIP_HEURTIMING_AFTERLPPLUNGE) > 0)
386  || (heurtiming == SCIP_HEURTIMING_AFTERPSEUDONODE
388  && (heur->timingmask & SCIP_HEURTIMING_AFTERPSEUDOPLUNGE) > 0)) )
389  {
390  /* the heuristic should be delayed until plunging is finished */
391  execute = FALSE;
392  *delayed = TRUE;
393  }
394 
395  /* execute heuristic only if its timing mask fits the current point in the node solving process */
396  execute = execute && (heur->timingmask & heurtiming) > 0;
397 
398  return execute;
399 }
400 
401 /** calls execution method of primal heuristic */
403  SCIP_HEUR* heur, /**< primal heuristic */
404  SCIP_SET* set, /**< global SCIP settings */
405  SCIP_PRIMAL* primal, /**< primal data */
406  int depth, /**< depth of current node */
407  int lpstateforkdepth, /**< depth of the last node with solved LP */
408  SCIP_HEURTIMING heurtiming, /**< current point in the node solving process */
409  SCIP_Bool nodeinfeasible, /**< was the current node already detected to be infeasible? */
410  int* ndelayedheurs, /**< pointer to count the number of delayed heuristics */
411  SCIP_RESULT* result /**< pointer to store the result of the callback method */
412  )
413 {
414  SCIP_Bool execute;
415  SCIP_Bool delayed;
416 
417  assert(heur != NULL);
418  assert(heur->heurexec != NULL);
419  assert(heur->freq >= -1);
420  assert(heur->freqofs >= 0);
421  assert(heur->maxdepth >= -1);
422  assert(set != NULL);
423  assert(set->scip != NULL);
424  assert(primal != NULL);
425  assert(depth >= 0 || heurtiming == SCIP_HEURTIMING_BEFOREPRESOL || heurtiming == SCIP_HEURTIMING_DURINGPRESOLLOOP);
426  assert(ndelayedheurs != NULL);
427  assert(result != NULL);
428 
429  *result = SCIP_DIDNOTRUN;
430 
431  delayed = FALSE;
432  execute = SCIPheurShouldBeExecuted(heur, depth, lpstateforkdepth, heurtiming, &delayed);
433 
434  if( delayed )
435  {
436  assert(!execute);
437  *result = SCIP_DELAYED;
438  }
439 
440  if( execute )
441  {
442  SCIP_Longint oldnsolsfound;
443  SCIP_Longint oldnbestsolsfound;
444 
445  SCIPdebugMessage("executing primal heuristic <%s> in depth %d (delaypos: %d)\n", heur->name, depth, heur->delaypos);
446 
447  oldnsolsfound = primal->nsolsfound;
448  oldnbestsolsfound = primal->nbestsolsfound;
449 
450  /* start timing */
451  SCIPclockStart(heur->heurclock, set);
452 
453  /* call external method */
454  SCIP_CALL( heur->heurexec(set->scip, heur, heurtiming, nodeinfeasible, result) );
455 
456  /* stop timing */
457  SCIPclockStop(heur->heurclock, set);
458 
459  /* evaluate result */
460  if( *result != SCIP_FOUNDSOL
461  && *result != SCIP_DIDNOTFIND
462  && *result != SCIP_DIDNOTRUN
463  && *result != SCIP_DELAYED )
464  {
465  SCIPerrorMessage("execution method of primal heuristic <%s> returned invalid result <%d>\n",
466  heur->name, *result);
467  return SCIP_INVALIDRESULT;
468  }
469  if( *result != SCIP_DIDNOTRUN && *result != SCIP_DELAYED )
470  heur->ncalls++;
471  heur->nsolsfound += primal->nsolsfound - oldnsolsfound;
472  heur->nbestsolsfound += primal->nbestsolsfound - oldnbestsolsfound;
473 
474  /* update delay position of heuristic */
475  if( *result != SCIP_DELAYED && heur->delaypos != -1 )
476  {
477  heur->delaypos = -1;
478  set->heurssorted = FALSE;
479  }
480  }
481  assert(*result == SCIP_DIDNOTRUN || *result == SCIP_DELAYED || heur->delaypos == -1);
482 
483  /* check if the heuristic was (still) delayed */
484  if( *result == SCIP_DELAYED || heur->delaypos >= 0 )
485  {
486  SCIPdebugMessage("delaying execution of primal heuristic <%s> in depth %d (delaypos: %d), heur was%s delayed before, had delaypos %d\n",
487  heur->name, depth, *ndelayedheurs, heur->delaypos >= 0 ? "" : " not", heur->delaypos);
488 
489  /* mark the heuristic delayed */
490  if( heur->delaypos != *ndelayedheurs )
491  {
492  heur->delaypos = *ndelayedheurs;
493  set->heurssorted = FALSE;
494  }
495  (*ndelayedheurs)++;
496  }
497 
498  return SCIP_OKAY;
499 }
500 
501 /** gets user data of primal heuristic */
503  SCIP_HEUR* heur /**< primal heuristic */
504  )
505 {
506  assert(heur != NULL);
507 
508  return heur->heurdata;
509 }
510 
511 /** sets user data of primal heuristic; user has to free old data in advance! */
513  SCIP_HEUR* heur, /**< primal heuristic */
514  SCIP_HEURDATA* heurdata /**< new primal heuristic user data */
515  )
516 {
517  assert(heur != NULL);
518 
519  heur->heurdata = heurdata;
520 }
521 
522 /* new callback setter methods */
523 
524 /** sets copy callback of primal heuristic */
526  SCIP_HEUR* heur, /**< primal heuristic */
527  SCIP_DECL_HEURCOPY ((*heurcopy)) /**< copy callback of primal heuristic or NULL if you don't want to copy your plugin into sub-SCIPs */
528  )
529 {
530  assert(heur != NULL);
531 
532  heur->heurcopy = heurcopy;
533 }
534 
535 /** sets destructor callback of primal heuristic */
537  SCIP_HEUR* heur, /**< primal heuristic */
538  SCIP_DECL_HEURFREE ((*heurfree)) /**< destructor of primal heuristic */
539  )
540 {
541  assert(heur != NULL);
542 
543  heur->heurfree = heurfree;
544 }
545 
546 /** sets initialization callback of primal heuristic */
548  SCIP_HEUR* heur, /**< primal heuristic */
549  SCIP_DECL_HEURINIT ((*heurinit)) /**< initialize primal heuristic */
550  )
551 {
552  assert(heur != NULL);
553 
554  heur->heurinit = heurinit;
555 }
556 
557 /** sets deinitialization callback of primal heuristic */
559  SCIP_HEUR* heur, /**< primal heuristic */
560  SCIP_DECL_HEUREXIT ((*heurexit)) /**< deinitialize primal heuristic */
561  )
562 {
563  assert(heur != NULL);
564 
565  heur->heurexit = heurexit;
566 }
567 
568 /** sets solving process initialization callback of primal heuristic */
570  SCIP_HEUR* heur, /**< primal heuristic */
571  SCIP_DECL_HEURINITSOL ((*heurinitsol)) /**< solving process initialization callback of primal heuristic */
572  )
573 {
574  assert(heur != NULL);
575 
576  heur->heurinitsol = heurinitsol;
577 }
578 
579 /** sets solving process deinitialization callback of primal heuristic */
581  SCIP_HEUR* heur, /**< primal heuristic */
582  SCIP_DECL_HEUREXITSOL ((*heurexitsol)) /**< solving process deinitialization callback of primal heuristic */
583  )
584 {
585  assert(heur != NULL);
586 
587  heur->heurexitsol = heurexitsol;
588 }
589 
590 /** gets name of primal heuristic */
591 const char* SCIPheurGetName(
592  SCIP_HEUR* heur /**< primal heuristic */
593  )
594 {
595  assert(heur != NULL);
596 
597  return heur->name;
598 }
599 
600 /** gets description of primal heuristic */
601 const char* SCIPheurGetDesc(
602  SCIP_HEUR* heur /**< primal heuristic */
603  )
604 {
605  assert(heur != NULL);
606 
607  return heur->desc;
608 }
609 
610 /** gets display character of primal heuristic */
612  SCIP_HEUR* heur /**< primal heuristic */
613  )
614 {
615  assert(heur != NULL);
616 
617  return heur->dispchar;
618 }
619 
620 /** returns the timing mask of the heuristic */
622  SCIP_HEUR* heur /**< primal heuristic */
623  )
624 {
625  assert(heur != NULL);
626 
627  return heur->timingmask;
628 }
629 
630 /** sets new timing mask for heuristic */
632  SCIP_HEUR* heur, /**< primal heuristic */
633  SCIP_HEURTIMING timingmask /**< new timing mask of heuristic */
634  )
635 {
636  assert(heur != NULL);
637 
638  heur->timingmask = timingmask;
639 }
640 
641 /** does the heuristic use a secondary SCIP instance? */
643  SCIP_HEUR* heur /**< primal heuristic */
644  )
645 {
646  assert(heur != NULL);
647 
648  return heur->usessubscip;
649 }
650 
651 /** gets priority of primal heuristic */
653  SCIP_HEUR* heur /**< primal heuristic */
654  )
655 {
656  assert(heur != NULL);
657 
658  return heur->priority;
659 }
660 
661 /** sets priority of primal heuristic */
663  SCIP_HEUR* heur, /**< primal heuristic */
664  SCIP_SET* set, /**< global SCIP settings */
665  int priority /**< new priority of the primal heuristic */
666  )
667 {
668  assert(heur != NULL);
669  assert(set != NULL);
670 
671  heur->priority = priority;
672  set->heurssorted = FALSE;
673 }
674 
675 /** gets frequency of primal heuristic */
677  SCIP_HEUR* heur /**< primal heuristic */
678  )
679 {
680  assert(heur != NULL);
681 
682  return heur->freq;
683 }
684 
685 /** sets frequency of primal heuristic */
687  SCIP_HEUR* heur, /**< primal heuristic */
688  int freq /**< new frequency of heuristic */
689  )
690 {
691  assert(heur != NULL);
692 
693  heur->freq = freq;
694 }
695 
696 /** gets frequency offset of primal heuristic */
698  SCIP_HEUR* heur /**< primal heuristic */
699  )
700 {
701  assert(heur != NULL);
702 
703  return heur->freqofs;
704 }
705 
706 /** gets maximal depth level for calling primal heuristic (returns -1, if no depth limit exists) */
708  SCIP_HEUR* heur /**< primal heuristic */
709  )
710 {
711  assert(heur != NULL);
712 
713  return heur->maxdepth;
714 }
715 
716 /** gets the number of times, the heuristic was called and tried to find a solution */
718  SCIP_HEUR* heur /**< primal heuristic */
719  )
720 {
721  assert(heur != NULL);
722 
723  return heur->ncalls;
724 }
725 
726 /** gets the number of primal feasible solutions found by this heuristic */
728  SCIP_HEUR* heur /**< primal heuristic */
729  )
730 {
731  assert(heur != NULL);
732 
733  return heur->nsolsfound;
734 }
735 
736 /** gets the number of new best primal feasible solutions found by this heuristic */
738  SCIP_HEUR* heur /**< primal heuristic */
739  )
740 {
741  assert(heur != NULL);
742 
743  return heur->nbestsolsfound;
744 }
745 
746 /** is primal heuristic initialized? */
748  SCIP_HEUR* heur /**< primal heuristic */
749  )
750 {
751  assert(heur != NULL);
752 
753  return heur->initialized;
754 }
755 
756 /** gets time in seconds used in this heuristic for setting up for next stages */
758  SCIP_HEUR* heur /**< primal heuristic */
759  )
760 {
761  assert(heur != NULL);
762 
763  return SCIPclockGetTime(heur->setuptime);
764 }
765 
766 /** gets time in seconds used in this heuristic */
768  SCIP_HEUR* heur /**< primal heuristic */
769  )
770 {
771  assert(heur != NULL);
772 
773  return SCIPclockGetTime(heur->heurclock);
774 }
775