Scippy

SCIP

Solving Constraint Integer Programs

relax.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-2021 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 visit scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file relax.c
17  * @ingroup OTHER_CFILES
18  * @brief methods and datastructures for relaxation handlers
19  * @author Tobias Achterberg
20  * @author Timo Berthold
21  */
22 
23 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
24 
25 #include <assert.h>
26 #include <string.h>
27 
28 #include "scip/def.h"
29 #include "scip/set.h"
30 #include "scip/tree.h"
31 #include "scip/stat.h"
32 #include "scip/clock.h"
33 #include "scip/paramset.h"
34 #include "scip/scip.h"
35 #include "scip/sol.h"
36 #include "scip/var.h"
37 #include "scip/relax.h"
38 #include "scip/pub_message.h"
39 #include "scip/pub_misc.h"
40 
41 #include "scip/struct_relax.h"
42 
43 
44 
45 /** compares two relaxation handlers w. r. to their priority */
46 SCIP_DECL_SORTPTRCOMP(SCIPrelaxComp)
47 { /*lint --e{715}*/
48  return ((SCIP_RELAX*)elem2)->priority - ((SCIP_RELAX*)elem1)->priority;
49 }
50 
51 /** comparison method for sorting relaxators w.r.t. to their name */
52 SCIP_DECL_SORTPTRCOMP(SCIPrelaxCompName)
53 {
54  return strcmp(SCIPrelaxGetName((SCIP_RELAX*)elem1), SCIPrelaxGetName((SCIP_RELAX*)elem2));
55 }
56 
57 /** method to call, when the priority of a relaxation handler was changed */
58 static
59 SCIP_DECL_PARAMCHGD(paramChgdRelaxPriority)
60 { /*lint --e{715}*/
61  SCIP_PARAMDATA* paramdata;
62 
63  paramdata = SCIPparamGetData(param);
64  assert(paramdata != NULL);
65 
66  /* use SCIPsetRelaxPriority() to mark the relaxs unsorted */
67  SCIP_CALL( SCIPsetRelaxPriority(scip, (SCIP_RELAX*)paramdata, SCIPparamGetInt(param)) ); /*lint !e740*/
68 
69  return SCIP_OKAY;
70 }
71 
72 /** copies the given relaxation handler to a new scip */
74  SCIP_RELAX* relax, /**< relaxation handler */
75  SCIP_SET* set /**< SCIP_SET of SCIP to copy to */
76  )
77 {
78  assert(relax != NULL);
79  assert(set != NULL);
80  assert(set->scip != NULL);
81 
82  if( relax->relaxcopy != NULL )
83  {
84  SCIPsetDebugMsg(set, "including relaxation handler %s in subscip %p\n", SCIPrelaxGetName(relax), (void*)set->scip);
85  SCIP_CALL( relax->relaxcopy(set->scip, relax) );
86  }
87  return SCIP_OKAY;
88 }
89 
90 /** internal method for creating a relaxation handler */
91 static
93  SCIP_RELAX** relax, /**< pointer to relaxation handler data structure */
94  SCIP_SET* set, /**< global SCIP settings */
95  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
96  BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
97  const char* name, /**< name of relaxation handler */
98  const char* desc, /**< description of relaxation handler */
99  int priority, /**< priority of the relaxation handler (negative: after LP, non-negative: before LP) */
100  int freq, /**< frequency for calling relaxation handler */
101  SCIP_DECL_RELAXCOPY ((*relaxcopy)), /**< copy method of relaxation handler or NULL if you don't want to copy your plugin into sub-SCIPs */
102  SCIP_DECL_RELAXFREE ((*relaxfree)), /**< destructor of relaxation handler */
103  SCIP_DECL_RELAXINIT ((*relaxinit)), /**< initialize relaxation handler */
104  SCIP_DECL_RELAXEXIT ((*relaxexit)), /**< deinitialize relaxation handler */
105  SCIP_DECL_RELAXINITSOL((*relaxinitsol)), /**< solving process initialization method of relaxation handler */
106  SCIP_DECL_RELAXEXITSOL((*relaxexitsol)), /**< solving process deinitialization method of relaxation handler */
107  SCIP_DECL_RELAXEXEC ((*relaxexec)), /**< execution method of relaxation handler */
108  SCIP_RELAXDATA* relaxdata /**< relaxation handler data */
109  )
110 {
112  char paramdesc[SCIP_MAXSTRLEN];
113 
114  assert(relax != NULL);
115  assert(name != NULL);
116  assert(desc != NULL);
117  assert(freq >= -1);
118  assert(relaxexec != NULL);
119 
120  SCIP_ALLOC( BMSallocMemory(relax) );
121  BMSclearMemory(*relax);
122 
123  SCIP_ALLOC( BMSduplicateMemoryArray(&(*relax)->name, name, strlen(name)+1) );
124  SCIP_ALLOC( BMSduplicateMemoryArray(&(*relax)->desc, desc, strlen(desc)+1) );
125  (*relax)->priority = priority;
126  (*relax)->freq = freq;
127  (*relax)->relaxcopy = relaxcopy;
128  (*relax)->relaxfree = relaxfree;
129  (*relax)->relaxinit = relaxinit;
130  (*relax)->relaxexit = relaxexit;
131  (*relax)->relaxinitsol = relaxinitsol;
132  (*relax)->relaxexitsol = relaxexitsol;
133  (*relax)->relaxexec = relaxexec;
134  (*relax)->relaxdata = relaxdata;
135  SCIP_CALL( SCIPclockCreate(&(*relax)->setuptime, SCIP_CLOCKTYPE_DEFAULT) );
136  SCIP_CALL( SCIPclockCreate(&(*relax)->relaxclock, SCIP_CLOCKTYPE_DEFAULT) );
137  (*relax)->ncalls = 0;
138  (*relax)->ncutoffs = 0;
139  (*relax)->nimprbounds = 0;
140  (*relax)->imprtime = 0.0;
141  (*relax)->naddedconss = 0;
142  (*relax)->nreduceddom = 0;
143  (*relax)->nseparated = 0;
144  (*relax)->lastsolvednode = -1;
145  (*relax)->initialized = FALSE;
146 
147  /* add parameters */
148  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "relaxing/%s/priority", name);
149  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of relaxation handler <%s>", name);
150  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
151  &(*relax)->priority, FALSE, priority, INT_MIN/4, INT_MAX/4,
152  paramChgdRelaxPriority, (SCIP_PARAMDATA*)(*relax)) ); /*lint !e740*/
153  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "relaxing/%s/freq", name);
154  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "frequency for calling relaxation handler <%s> (-1: never, 0: only in root node)", name);
155  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
156  &(*relax)->freq, FALSE, freq, -1, SCIP_MAXTREEDEPTH, NULL, NULL) );
157 
158  return SCIP_OKAY;
159 }
160 
161 /** creates a relaxation handler */
163  SCIP_RELAX** relax, /**< pointer to relaxation handler data structure */
164  SCIP_SET* set, /**< global SCIP settings */
165  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
166  BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
167  const char* name, /**< name of relaxation handler */
168  const char* desc, /**< description of relaxation handler */
169  int priority, /**< priority of the relaxation handler (negative: after LP, non-negative: before LP) */
170  int freq, /**< frequency for calling relaxation handler */
171  SCIP_DECL_RELAXCOPY ((*relaxcopy)), /**< copy method of relaxation handler or NULL if you don't want to copy your plugin into sub-SCIPs */
172  SCIP_DECL_RELAXFREE ((*relaxfree)), /**< destructor of relaxation handler */
173  SCIP_DECL_RELAXINIT ((*relaxinit)), /**< initialize relaxation handler */
174  SCIP_DECL_RELAXEXIT ((*relaxexit)), /**< deinitialize relaxation handler */
175  SCIP_DECL_RELAXINITSOL((*relaxinitsol)), /**< solving process initialization method of relaxation handler */
176  SCIP_DECL_RELAXEXITSOL((*relaxexitsol)), /**< solving process deinitialization method of relaxation handler */
177  SCIP_DECL_RELAXEXEC ((*relaxexec)), /**< execution method of relaxation handler */
178  SCIP_RELAXDATA* relaxdata /**< relaxation handler data */
179  )
180 {
181  assert(relax != NULL);
182  assert(name != NULL);
183  assert(desc != NULL);
184  assert(freq >= -1);
185  assert(relaxexec != NULL);
186 
187  SCIP_CALL_FINALLY( doRelaxCreate(relax, set, messagehdlr, blkmem, name, desc, priority, freq, relaxcopy, relaxfree,
188  relaxinit, relaxexit, relaxinitsol, relaxexitsol, relaxexec, relaxdata), (void) SCIPrelaxFree(relax, set) );
189 
190  return SCIP_OKAY;
191 }
192 
193 /** calls destructor and frees memory of relaxation handler */
195  SCIP_RELAX** relax, /**< pointer to relaxation handler data structure */
196  SCIP_SET* set /**< global SCIP settings */
197  )
198 {
199  assert(relax != NULL);
200  if( *relax == NULL )
201  return SCIP_OKAY;
202  assert(!(*relax)->initialized);
203  assert(set != NULL);
204 
205  /* call destructor of relaxation handler */
206  if( (*relax)->relaxfree != NULL )
207  {
208  SCIP_CALL( (*relax)->relaxfree(set->scip, *relax) );
209  }
210 
211  SCIPclockFree(&(*relax)->relaxclock);
212  SCIPclockFree(&(*relax)->setuptime);
213  BMSfreeMemoryArrayNull(&(*relax)->name);
214  BMSfreeMemoryArrayNull(&(*relax)->desc);
215  BMSfreeMemory(relax);
216 
217  return SCIP_OKAY;
218 }
219 
220 /** initializes relaxation handler */
222  SCIP_RELAX* relax, /**< relaxation handler */
223  SCIP_SET* set /**< global SCIP settings */
224  )
225 {
226  assert(relax != NULL);
227  assert(set != NULL);
228 
229  if( relax->initialized )
230  {
231  SCIPerrorMessage("relaxation handler <%s> already initialized\n", relax->name);
232  return SCIP_INVALIDCALL;
233  }
234 
235  if( set->misc_resetstat )
236  {
237  SCIPclockReset(relax->setuptime);
238  SCIPclockReset(relax->relaxclock);
239  relax->ncalls = 0;
240  relax->ncutoffs = 0;
241  relax->nimprbounds = 0;
242  relax->imprtime = 0.0;
243  relax->naddedconss = 0;
244  relax->nreduceddom = 0;
245  relax->nseparated = 0;
246  relax->lastsolvednode = -1;
247  }
248 
249  if( relax->relaxinit != NULL )
250  {
251  /* start timing */
252  SCIPclockStart(relax->setuptime, set);
253 
254  SCIP_CALL( relax->relaxinit(set->scip, relax) );
255 
256  /* stop timing */
257  SCIPclockStop(relax->setuptime, set);
258  }
259  relax->initialized = TRUE;
260 
261  return SCIP_OKAY;
262 }
263 
264 /** calls exit method of relaxation handler */
266  SCIP_RELAX* relax, /**< relaxation handler */
267  SCIP_SET* set /**< global SCIP settings */
268  )
269 {
270  assert(relax != NULL);
271  assert(set != NULL);
272 
273  if( !relax->initialized )
274  {
275  SCIPerrorMessage("relaxation handler <%s> not initialized\n", relax->name);
276  return SCIP_INVALIDCALL;
277  }
278 
279  if( relax->relaxexit != NULL )
280  {
281  /* start timing */
282  SCIPclockStart(relax->setuptime, set);
283 
284  SCIP_CALL( relax->relaxexit(set->scip, relax) );
285 
286  /* stop timing */
287  SCIPclockStop(relax->setuptime, set);
288  }
289  relax->initialized = FALSE;
290 
291  return SCIP_OKAY;
292 }
293 
294 /** informs relaxation handler that the branch and bound process is being started */
296  SCIP_RELAX* relax, /**< relaxation handler */
297  SCIP_SET* set /**< global SCIP settings */
298  )
299 {
300  assert(relax != NULL);
301  assert(set != NULL);
302 
303  /* call solving process initialization method of relaxation handler */
304  if( relax->relaxinitsol != NULL )
305  {
306  /* start timing */
307  SCIPclockStart(relax->setuptime, set);
308 
309  SCIP_CALL( relax->relaxinitsol(set->scip, relax) );
310 
311  /* stop timing */
312  SCIPclockStop(relax->setuptime, set);
313  }
314 
315  return SCIP_OKAY;
316 }
317 
318 /** informs relaxation handler that the branch and bound process data is being freed */
320  SCIP_RELAX* relax, /**< relaxation handler */
321  SCIP_SET* set /**< global SCIP settings */
322  )
323 {
324  assert(relax != NULL);
325  assert(set != NULL);
326 
327  /* call solving process deinitialization method of relaxation handler */
328  if( relax->relaxexitsol != NULL )
329  {
330  /* start timing */
331  SCIPclockStart(relax->setuptime, set);
332 
333  SCIP_CALL( relax->relaxexitsol(set->scip, relax) );
334 
335  /* stop timing */
336  SCIPclockStop(relax->setuptime, set);
337  }
338 
339  return SCIP_OKAY;
340 }
341 
342 /** calls execution method of relaxation handler */
344  SCIP_RELAX* relax, /**< relaxation handler */
345  SCIP_SET* set, /**< global SCIP settings */
346  SCIP_TREE* tree, /**< branch and bound tree */
347  SCIP_STAT* stat, /**< dynamic problem statistics */
348  int depth, /**< depth of current node */
349  SCIP_Real* lowerbound, /**< pointer to lower bound computed by the relaxation handler */
350  SCIP_RESULT* result /**< pointer to store the result of the callback method */
351  )
352 {
353  assert(relax != NULL);
354  assert(relax->relaxexec != NULL);
355  assert(relax->freq >= -1);
356  assert(set != NULL);
357  assert(set->scip != NULL);
358  assert(depth >= 0);
359  assert(result != NULL);
360 
361  *result = SCIP_DIDNOTRUN;
362 
363  /* check, if the relaxation is already solved */
364  if( relax->lastsolvednode == stat->ntotalnodes && ! SCIPinProbing(set->scip) )
365  return SCIP_OKAY;
366 
367  relax->lastsolvednode = stat->ntotalnodes;
368 
369  if( (depth == 0 && relax->freq == 0) || (relax->freq > 0 && depth % relax->freq == 0) )
370  {
371  SCIP_Real starttime;
372 
373  SCIPsetDebugMsg(set, "executing relaxation handler <%s>\n", relax->name);
374 
375  /* start timing */
376  starttime = SCIPclockGetTime(relax->relaxclock);
377  SCIPclockStart(relax->relaxclock, set);
378 
379  /* call external relaxation method */
380  SCIP_CALL( relax->relaxexec(set->scip, relax, lowerbound, result) );
381 
382  /* stop timing */
383  SCIPclockStop(relax->relaxclock, set);
384 
385  /* evaluate result */
386  if( *result != SCIP_CUTOFF
387  && *result != SCIP_CONSADDED
388  && *result != SCIP_REDUCEDDOM
389  && *result != SCIP_SEPARATED
390  && *result != SCIP_SUCCESS
391  && *result != SCIP_SUSPENDED
392  && *result != SCIP_DIDNOTRUN )
393  {
394  SCIPerrorMessage("execution method of relaxation handler <%s> returned invalid result <%d>\n",
395  relax->name, *result);
396  return SCIP_INVALIDRESULT;
397  }
398  if( *result != SCIP_DIDNOTRUN )
399  {
400  relax->ncalls++;
401  stat->relaxcount++;
402  if( *result == SCIP_SUSPENDED )
403  SCIPrelaxMarkUnsolved(relax);
404  else if( *result == SCIP_CUTOFF || SCIPsetIsInfinity(set, *lowerbound) )
405  {
406  ++relax->ncutoffs;
407  relax->imprtime += SCIPclockGetTime(relax->relaxclock) - starttime;
408  }
409  else
410  {
411  SCIP_NODE* node;
412  SCIP_Real oldlowerbound;
413 
414  node = SCIPtreeGetCurrentNode(tree);
415  if( node != NULL )
416  oldlowerbound = SCIPnodeGetLowerbound(node);
417  else
418  oldlowerbound = -SCIPsetInfinity(set);
419 
420  if( !SCIPsetIsInfinity(set, -*lowerbound) && SCIPsetIsRelGT(set, *lowerbound, oldlowerbound) )
421  {
422  ++relax->nimprbounds;
423  relax->imprtime += SCIPclockGetTime(relax->relaxclock) - starttime;
424  }
425 
426  if( *result == SCIP_CONSADDED )
427  ++relax->naddedconss;
428  else if( *result == SCIP_REDUCEDDOM )
429  ++relax->nreduceddom;
430  else if( *result == SCIP_SEPARATED )
431  ++relax->nseparated;
432  }
433  }
434  }
435 
436  return SCIP_OKAY;
437 }
438 
439 /** gets user data of relaxation handler */
441  SCIP_RELAX* relax /**< relaxation handler */
442  )
443 {
444  assert(relax != NULL);
445 
446  return relax->relaxdata;
447 }
448 
449 /** sets user data of relaxation handler; user has to free old data in advance! */
451  SCIP_RELAX* relax, /**< relaxation handler */
452  SCIP_RELAXDATA* relaxdata /**< new relaxation handler user data */
453  )
454 {
455  assert(relax != NULL);
456 
457  relax->relaxdata = relaxdata;
458 }
459 
460 /** set copy method of relaxation handler */
462  SCIP_RELAX* relax, /**< relaxation handler */
463  SCIP_DECL_RELAXCOPY ((*relaxcopy)) /**< copy method of relaxation handler */
464  )
465 {
466  assert(relax != NULL);
467 
468  relax->relaxcopy = relaxcopy;
469 }
470 
471 /** set destructor of relaxation handler */
473  SCIP_RELAX* relax, /**< relaxation handler */
474  SCIP_DECL_RELAXFREE ((*relaxfree)) /**< destructor of relaxation handler */
475  )
476 {
477  assert(relax != NULL);
478 
479  relax->relaxfree = relaxfree;
480 }
481 
482 /** set initialization method of relaxation handler */
484  SCIP_RELAX* relax, /**< relaxation handler */
485  SCIP_DECL_RELAXINIT ((*relaxinit)) /**< initialize relaxation handler */
486  )
487 {
488  assert(relax != NULL);
489 
490  relax->relaxinit = relaxinit;
491 }
492 
493 /** set deinitialization method of relaxation handler */
495  SCIP_RELAX* relax, /**< relaxation handler */
496  SCIP_DECL_RELAXEXIT ((*relaxexit)) /**< deinitialize relaxation handler */
497  )
498 {
499  assert(relax != NULL);
500 
501  relax->relaxexit = relaxexit;
502 }
503 
504 /** set solving process initialization method of relaxation handler */
506  SCIP_RELAX* relax, /**< relaxation handler */
507  SCIP_DECL_RELAXINITSOL((*relaxinitsol)) /**< solving process initialization method of relaxation handler */
508  )
509 {
510  assert(relax != NULL);
511 
512  relax->relaxinitsol = relaxinitsol;
513 }
514 
515 /** set solving process deinitialization method of relaxation handler */
517  SCIP_RELAX* relax, /**< relaxation handler */
518  SCIP_DECL_RELAXEXITSOL((*relaxexitsol)) /**< solving process deinitialization relaxation handler */
519  )
520 {
521  assert(relax != NULL);
522 
523  relax->relaxexitsol = relaxexitsol;
524 }
525 
526 /** gets name of relaxation handler */
527 const char* SCIPrelaxGetName(
528  SCIP_RELAX* relax /**< relaxation handler */
529  )
530 {
531  assert(relax != NULL);
532 
533  return relax->name;
534 }
535 
536 /** gets description of relaxation handler */
537 const char* SCIPrelaxGetDesc(
538  SCIP_RELAX* relax /**< relaxation handler */
539  )
540 {
541  assert(relax != NULL);
542 
543  return relax->desc;
544 }
545 
546 /** gets priority of relaxation handler */
548  SCIP_RELAX* relax /**< relaxation handler */
549  )
550 {
551  assert(relax != NULL);
552 
553  return relax->priority;
554 }
555 
556 /** sets priority of relaxation handler */
558  SCIP_RELAX* relax, /**< relaxation handler */
559  SCIP_SET* set, /**< global SCIP settings */
560  int priority /**< new priority of the relaxation handler */
561  )
562 {
563  assert(relax != NULL);
564  assert(set != NULL);
565 
566  relax->priority = priority;
567  set->relaxssorted = FALSE;
568 }
569 
570 /** gets frequency of relaxation handler */
572  SCIP_RELAX* relax /**< relaxation handler */
573  )
574 {
575  assert(relax != NULL);
576 
577  return relax->freq;
578 }
579 
580 /** gets time in seconds used in this relaxator for setting up for next stages */
582  SCIP_RELAX* relax /**< relaxator */
583  )
584 {
585  assert(relax != NULL);
586 
587  return SCIPclockGetTime(relax->setuptime);
588 }
589 
590 /** enables or disables all clocks of \p relax, depending on the value of the flag */
592  SCIP_RELAX* relax, /**< the relaxation handler for which all clocks should be enabled or disabled */
593  SCIP_Bool enable /**< should the clocks of the relaxation handler be enabled? */
594  )
595 {
596  assert(relax != NULL);
597 
598  SCIPclockEnableOrDisable(relax->setuptime, enable);
599  SCIPclockEnableOrDisable(relax->relaxclock, enable);
600 }
601 
602 /** gets time in seconds used in this relaxation handler */
604  SCIP_RELAX* relax /**< relaxation handler */
605  )
606 {
607  assert(relax != NULL);
608 
609  return SCIPclockGetTime(relax->relaxclock);
610 }
611 
612 /** gets the total number of times the relaxation handler was called */
614  SCIP_RELAX* relax /**< relaxation handler */
615  )
616 {
617  assert(relax != NULL);
618 
619  return relax->ncalls;
620 }
621 
622 /** gets the total number of times the relaxation handler cut off a node */
624  SCIP_RELAX* relax /**< relaxation handler */
625  )
626 {
627  assert(relax != NULL);
628 
629  return relax->ncutoffs;
630 }
631 
632 /** gets the total number of times the relaxation handler improved a node's lower bound */
634  SCIP_RELAX* relax /**< relaxation handler */
635  )
636 {
637  assert(relax != NULL);
638 
639  return relax->nimprbounds;
640 }
641 
642 /** gets the total number of times the relaxation handler added constraints */
644  SCIP_RELAX* relax /**< relaxation handler */
645  )
646 {
647  assert(relax != NULL);
648 
649  return relax->naddedconss;
650 }
651 
652 /** gets the time in seconds spent for the execution of the relaxation handler when a node's lower bound could be improved (or a cutoff was found) */
654  SCIP_RELAX* relax /**< relaxation handler */
655  )
656 {
657  assert(relax != NULL);
658 
659  return relax->imprtime;
660 }
661 
662 /** gets the total number of times the relaxation handler reduced variable domains */
664  SCIP_RELAX* relax /**< relaxation handler */
665  )
666 {
667  assert(relax != NULL);
668 
669  return relax->nreduceddom;
670 }
671 
672 /** gets the total number of times the relaxation handler separated cutting planes */
674  SCIP_RELAX* relax /**< relaxation handler */
675  )
676 {
677  assert(relax != NULL);
678 
679  return relax->nseparated;
680 }
681 
682 /** is relaxation handler initialized? */
684  SCIP_RELAX* relax /**< relaxation handler */
685  )
686 {
687  assert(relax != NULL);
688 
689  return relax->initialized;
690 }
691 
692 /** returns whether the relaxation was completely solved at the current node */
694  SCIP_RELAX* relax, /**< relaxation handler */
695  SCIP_STAT* stat /**< dynamic problem statistics */
696  )
697 {
698  assert(relax != NULL);
699  assert(stat != NULL);
700 
701  return (relax->lastsolvednode == stat->ntotalnodes);
702 }
703 
704 /** marks the current relaxation unsolved, s.t. the relaxation handler is called again in the next solving round */
706  SCIP_RELAX* relax /**< relaxation handler */
707  )
708 {
709  assert(relax != NULL);
710 
711  relax->lastsolvednode = -1;
712 }
713 
714 /*
715  * methods for the global relaxation data
716  */
717 
718 /** creates global relaxation data */
720  SCIP_RELAXATION** relaxation, /**< global relaxation data */
721  BMS_BLKMEM* blkmem, /**< block memory */
722  SCIP_SET* set, /**< global SCIP settings */
723  SCIP_STAT* stat, /**< problem statistics data */
724  SCIP_PRIMAL* primal, /**< primal data */
725  SCIP_TREE* tree /**< branch and bound tree */
726  )
727 {
728  assert(relaxation != NULL);
729  assert(blkmem != NULL);
730  assert(set != NULL);
731  assert(stat != NULL);
732  assert(primal != NULL);
733  assert(tree != NULL);
734 
735  SCIP_ALLOC( BMSallocMemory(relaxation) );
736 
737  (*relaxation)->relaxsolobjval = 0.0;
738  (*relaxation)->relaxsolvalid = FALSE;
739  (*relaxation)->relaxsolincludeslp = FALSE;
740  (*relaxation)->relaxsolzero = TRUE;
741  (*relaxation)->lastsolrelax = NULL;
742 
743  return SCIP_OKAY;
744 }
745 
746 /** frees global relaxation data */
748  SCIP_RELAXATION** relaxation /**< global relaxation data */
749  )
750 {
751  assert(relaxation != NULL);
752 
753  BMSfreeMemory(relaxation);
754 
755  return SCIP_OKAY;
756 }
757 
758 /** sets the relaxsolzero flag in the relaxation data to the given value */
760  SCIP_RELAXATION* relaxation, /**< global relaxation data */
761  SCIP_Bool iszero /**< are all values of the relaxation solution set to zero? */
762  )
763 {
764  assert(relaxation != NULL);
765 
766  relaxation->relaxsolzero = iszero;
767 }
768 
769 /** returns whether the global relaxation solution is cleared and all values are set to zero */
771  SCIP_RELAXATION* relaxation /**< global relaxation data */
772  )
773 {
774  assert(relaxation != NULL);
775 
776  return relaxation->relaxsolzero;
777 }
778 
779 /** sets the relaxsolvalid and includeslp flags in the relaxation data to the given values */
781  SCIP_RELAXATION* relaxation, /**< global relaxation data */
782  SCIP_Bool isvalid, /**< is the stored solution valid? */
783  SCIP_Bool includeslp /**< does the relaxator contain all cuts in the LP? */
784  )
785 {
786  assert(relaxation != NULL);
787 
788  relaxation->relaxsolvalid = isvalid;
789  relaxation->relaxsolincludeslp = includeslp;
790 }
791 
792 /** returns whether the global relaxation solution is valid */
794  SCIP_RELAXATION* relaxation /**< global relaxation data */
795  )
796 {
797  assert(relaxation != NULL);
798 
799  return relaxation->relaxsolvalid;
800 }
801 
802 /** returns whether the global relaxation solution was computed by a relaxator which included all LP cuts */
804  SCIP_RELAXATION* relaxation /**< global relaxation data */
805  )
806 {
807  assert(relaxation != NULL);
808 
809  return relaxation->relaxsolincludeslp;
810 }
811 
812 /** sets the objective value of the global relaxation solution */
814  SCIP_RELAXATION* relaxation, /**< global relaxation data */
815  SCIP_Real obj /**< objective value */
816  )
817 {
818  assert(relaxation != NULL);
819 
820  relaxation->relaxsolobjval = obj;
821 }
822 
823 /** returns the objective value of the global relaxation solution w.r.t. the transformed problem */
825  SCIP_RELAXATION* relaxation /**< global relaxation data */
826  )
827 {
828  assert(relaxation != NULL);
829 
830  return relaxation->relaxsolobjval;
831 }
832 
833 /** adds the given value to the global relaxation solution's objective value */
835  SCIP_RELAXATION* relaxation, /**< global relaxation data */
836  SCIP_Real val /**< value to add to the objective value */
837  )
838 {
839  assert(relaxation != NULL);
840 
841  relaxation->relaxsolobjval += val;
842 }
843 
844 /** updates objective value of current relaxation solution after change of objective coefficient */
846  SCIP_RELAXATION* relaxation, /**< global relaxation data */
847  SCIP_SET* set, /**< global SCIP settings */
848  SCIP_VAR* var, /**< variable with changed objective coefficient */
849  SCIP_Real oldobj, /**< old objective coefficient */
850  SCIP_Real newobj /**< new objective coefficient */
851  )
852 {
853  SCIP_Real relaxsolval;
854 
855  assert(relaxation != NULL);
856  assert(set != NULL);
857  assert(var != NULL);
858  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
859 
860  relaxsolval = SCIPvarGetRelaxSol(var, set);
861  relaxation->relaxsolobjval += (newobj - oldobj) * relaxsolval;
862 }
863 
864 /** store the most recent relaxation handler \p relax responsible for the solution */
866  SCIP_RELAXATION* relaxation, /**< global relaxation data */
867  SCIP_RELAX* relax /**< responsible relaxation handler, or NULL */
868  )
869 {
870  assert(relaxation != NULL);
871 
872  relaxation->lastsolrelax = relax;
873 }
874 
875 /** returns the most recent relaxation handler responsible for the solution, or NULL if unspecified */
877  SCIP_RELAXATION* relaxation /**< global relaxation data */
878  )
879 {
880  assert(relaxation != NULL);
881 
882  return relaxation->lastsolrelax;
883 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
#define SCIP_DECL_RELAXFREE(x)
Definition: type_relax.h:55
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5987
void SCIPrelaxationUpdateVarObj(SCIP_RELAXATION *relaxation, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: relax.c:845
internal methods for storing primal CIP solutions
SCIP_Longint SCIPrelaxGetNCutoffs(SCIP_RELAX *relax)
Definition: relax.c:623
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:140
SCIP_Real SCIPrelaxationGetSolObj(SCIP_RELAXATION *relaxation)
Definition: relax.c:824
char * desc
Definition: struct_relax.h:47
internal methods for branch and bound tree
SCIP_Longint relaxcount
Definition: struct_stat.h:179
SCIP_Longint ncutoffs
Definition: struct_relax.h:40
SCIP_RETCODE SCIPrelaxInit(SCIP_RELAX *relax, SCIP_SET *set)
Definition: relax.c:221
SCIP_PARAMDATA * SCIPparamGetData(SCIP_PARAM *param)
Definition: paramset.c:670
#define SCIP_MAXSTRLEN
Definition: def.h:279
internal methods for clocks and timing issues
SCIP_Longint ntotalnodes
Definition: struct_stat.h:78
struct SCIP_ParamData SCIP_PARAMDATA
Definition: type_paramset.h:77
#define SCIP_CALL_FINALLY(x, y)
Definition: def.h:412
SCIP_RELAX * lastsolrelax
Definition: struct_relax.h:71
void SCIPrelaxSetPriority(SCIP_RELAX *relax, SCIP_SET *set, int priority)
Definition: relax.c:557
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition: set.c:5852
SCIP_Longint SCIPrelaxGetNCalls(SCIP_RELAX *relax)
Definition: relax.c:613
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:351
#define FALSE
Definition: def.h:73
#define SCIP_DECL_RELAXINIT(x)
Definition: type_relax.h:63
#define SCIP_DECL_RELAXINITSOL(x)
Definition: type_relax.h:82
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:281
#define TRUE
Definition: def.h:72
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
void SCIPrelaxSetCopy(SCIP_RELAX *relax, SCIP_DECL_RELAXCOPY((*relaxcopy)))
Definition: relax.c:461
SCIP_RELAX * SCIPrelaxationGetSolRelax(SCIP_RELAXATION *relaxation)
Definition: relax.c:876
SCIP_EXPORT SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17136
SCIP_RETCODE SCIPrelaxFree(SCIP_RELAX **relax, SCIP_SET *set)
Definition: relax.c:194
void SCIPrelaxationSetSolValid(SCIP_RELAXATION *relaxation, SCIP_Bool isvalid, SCIP_Bool includeslp)
Definition: relax.c:780
internal methods for handling parameter settings
static SCIP_RETCODE doRelaxCreate(SCIP_RELAX **relax, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, int priority, int freq, SCIP_DECL_RELAXCOPY((*relaxcopy)), SCIP_DECL_RELAXFREE((*relaxfree)), SCIP_DECL_RELAXINIT((*relaxinit)), SCIP_DECL_RELAXEXIT((*relaxexit)), SCIP_DECL_RELAXINITSOL((*relaxinitsol)), SCIP_DECL_RELAXEXITSOL((*relaxexitsol)), SCIP_DECL_RELAXEXEC((*relaxexec)), SCIP_RELAXDATA *relaxdata)
Definition: relax.c:92
SCIP_Bool SCIPrelaxationIsSolValid(SCIP_RELAXATION *relaxation)
Definition: relax.c:793
void SCIPclockEnableOrDisable(SCIP_CLOCK *clck, SCIP_Bool enable)
Definition: clock.c:251
SCIP_EXPORT SCIP_Real SCIPnodeGetLowerbound(SCIP_NODE *node)
Definition: tree.c:7458
#define BMSfreeMemory(ptr)
Definition: memory.h:137
SCIP_Longint SCIPrelaxGetNAddedConss(SCIP_RELAX *relax)
Definition: relax.c:643
void SCIPrelaxMarkUnsolved(SCIP_RELAX *relax)
Definition: relax.c:705
Definition: heur_padm.c:125
#define SCIP_DECL_RELAXEXIT(x)
Definition: type_relax.h:71
SCIP_RELAXDATA * relaxdata
Definition: struct_relax.h:55
const char * SCIPrelaxGetDesc(SCIP_RELAX *relax)
Definition: relax.c:537
void SCIPrelaxSetFree(SCIP_RELAX *relax, SCIP_DECL_RELAXFREE((*relaxfree)))
Definition: relax.c:472
SCIP_CLOCK * relaxclock
Definition: struct_relax.h:57
SCIP_RETCODE SCIPrelaxCreate(SCIP_RELAX **relax, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, int priority, int freq, SCIP_DECL_RELAXCOPY((*relaxcopy)), SCIP_DECL_RELAXFREE((*relaxfree)), SCIP_DECL_RELAXINIT((*relaxinit)), SCIP_DECL_RELAXEXIT((*relaxexit)), SCIP_DECL_RELAXINITSOL((*relaxinitsol)), SCIP_DECL_RELAXEXITSOL((*relaxexitsol)), SCIP_DECL_RELAXEXEC((*relaxexec)), SCIP_RELAXDATA *relaxdata)
Definition: relax.c:162
SCIP_Longint naddedconss
Definition: struct_relax.h:42
SCIP_Real SCIPrelaxGetSetupTime(SCIP_RELAX *relax)
Definition: relax.c:581
#define SCIPerrorMessage
Definition: pub_message.h:55
SCIP_RETCODE SCIPrelaxExit(SCIP_RELAX *relax, SCIP_SET *set)
Definition: relax.c:265
SCIP_Bool relaxsolincludeslp
Definition: struct_relax.h:69
SCIP_Bool SCIPrelaxationIsSolZero(SCIP_RELAXATION *relaxation)
Definition: relax.c:770
void SCIPclockReset(SCIP_CLOCK *clck)
Definition: clock.c:200
SCIP_Real relaxsolobjval
Definition: struct_relax.h:67
int SCIPrelaxGetPriority(SCIP_RELAX *relax)
Definition: relax.c:547
SCIP_Longint SCIPrelaxGetNImprovedLowerbound(SCIP_RELAX *relax)
Definition: relax.c:633
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip_probing.c:88
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:429
#define NULL
Definition: lpi_spx1.cpp:155
#define SCIP_DECL_RELAXCOPY(x)
Definition: type_relax.h:47
SCIP_Real SCIPrelaxGetTime(SCIP_RELAX *relax)
Definition: relax.c:603
void SCIPrelaxSetInitsol(SCIP_RELAX *relax, SCIP_DECL_RELAXINITSOL((*relaxinitsol)))
Definition: relax.c:505
void SCIPrelaxSetExitsol(SCIP_RELAX *relax, SCIP_DECL_RELAXEXITSOL((*relaxexitsol)))
Definition: relax.c:516
SCIP_Bool SCIPsetIsRelGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6930
SCIP_Bool relaxsolvalid
Definition: struct_relax.h:68
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:370
SCIP_RETCODE SCIPrelaxCopyInclude(SCIP_RELAX *relax, SCIP_SET *set)
Definition: relax.c:73
SCIP_Longint nimprbounds
Definition: struct_relax.h:41
SCIP_CLOCK * setuptime
Definition: struct_relax.h:56
SCIP_RETCODE SCIPrelaxationCreate(SCIP_RELAXATION **relaxation, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree)
Definition: relax.c:719
void SCIPrelaxSetData(SCIP_RELAX *relax, SCIP_RELAXDATA *relaxdata)
Definition: relax.c:450
SCIP_RETCODE SCIPsetRelaxPriority(SCIP *scip, SCIP_RELAX *relax, int priority)
Definition: scip_relax.c:262
internal methods for relaxators
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:2956
#define BMSduplicateMemoryArray(ptr, source, num)
Definition: memory.h:135
SCIP_RETCODE SCIPclockCreate(SCIP_CLOCK **clck, SCIP_CLOCKTYPE clocktype)
Definition: clock.c:161
internal methods for problem variables
char * name
Definition: struct_relax.h:46
public data structures and miscellaneous methods
int SCIPrelaxGetFreq(SCIP_RELAX *relax)
Definition: relax.c:571
SCIP_RETCODE SCIPrelaxationFree(SCIP_RELAXATION **relaxation)
Definition: relax.c:747
void SCIPrelaxationSetSolRelax(SCIP_RELAXATION *relaxation, SCIP_RELAX *relax)
Definition: relax.c:865
#define SCIP_Bool
Definition: def.h:70
SCIP_Bool SCIPrelaxIsSolved(SCIP_RELAX *relax, SCIP_STAT *stat)
Definition: relax.c:693
SCIP_RETCODE SCIPrelaxInitsol(SCIP_RELAX *relax, SCIP_SET *set)
Definition: relax.c:295
static const char * paramname[]
Definition: lpi_msk.c:4974
void SCIPclockFree(SCIP_CLOCK **clck)
Definition: clock.c:176
SCIP_Bool initialized
Definition: struct_relax.h:61
#define SCIPsetDebugMsg
Definition: set.h:1721
SCIP_RELAXDATA * SCIPrelaxGetData(SCIP_RELAX *relax)
Definition: relax.c:440
static SCIP_DECL_PARAMCHGD(paramChgdRelaxPriority)
Definition: relax.c:59
SCIP_Longint lastsolvednode
Definition: struct_relax.h:45
void SCIPrelaxEnableOrDisableClocks(SCIP_RELAX *relax, SCIP_Bool enable)
Definition: relax.c:591
SCIP_Longint SCIPrelaxGetNSeparatedCuts(SCIP_RELAX *relax)
Definition: relax.c:673
SCIP_Real SCIPvarGetRelaxSol(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:13690
#define BMSclearMemory(ptr)
Definition: memory.h:121
void SCIPrelaxationSetSolObj(SCIP_RELAXATION *relaxation, SCIP_Real obj)
Definition: relax.c:813
#define SCIP_MAXTREEDEPTH
Definition: def.h:306
SCIP_Bool SCIPrelaxIsInitialized(SCIP_RELAX *relax)
Definition: relax.c:683
SCIP_RETCODE SCIPrelaxExec(SCIP_RELAX *relax, SCIP_SET *set, SCIP_TREE *tree, SCIP_STAT *stat, int depth, SCIP_Real *lowerbound, SCIP_RESULT *result)
Definition: relax.c:343
int SCIPparamGetInt(SCIP_PARAM *param)
Definition: paramset.c:725
SCIP_Longint ncalls
Definition: struct_relax.h:39
void SCIPrelaxationSetSolZero(SCIP_RELAXATION *relaxation, SCIP_Bool iszero)
Definition: relax.c:759
SCIP_Real imprtime
Definition: struct_relax.h:58
struct SCIP_RelaxData SCIP_RELAXDATA
Definition: type_relax.h:38
#define SCIP_DECL_RELAXEXEC(x)
Definition: type_relax.h:118
void SCIPrelaxationSolObjAdd(SCIP_RELAXATION *relaxation, SCIP_Real val)
Definition: relax.c:834
SCIP_NODE * SCIPtreeGetCurrentNode(SCIP_TREE *tree)
Definition: tree.c:8381
SCIP_Bool relaxsolzero
Definition: struct_relax.h:70
public methods for message output
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10604
SCIP_Longint nreduceddom
Definition: struct_relax.h:43
const char * SCIPrelaxGetName(SCIP_RELAX *relax)
Definition: relax.c:527
#define SCIP_Real
Definition: def.h:163
internal methods for problem statistics
SCIP_DECL_SORTPTRCOMP(SCIPrelaxComp)
Definition: relax.c:46
#define BMSallocMemory(ptr)
Definition: memory.h:111
#define SCIP_Longint
Definition: def.h:148
data structures for relaxators
#define SCIP_DECL_RELAXEXITSOL(x)
Definition: type_relax.h:93
common defines and data types used in all packages of SCIP
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:429
void SCIPrelaxSetExit(SCIP_RELAX *relax, SCIP_DECL_RELAXEXIT((*relaxexit)))
Definition: relax.c:494
#define SCIP_ALLOC(x)
Definition: def.h:381
SCIP_Longint SCIPrelaxGetNReducedDomains(SCIP_RELAX *relax)
Definition: relax.c:663
SCIP_Real SCIPrelaxGetImprovedLowerboundTime(SCIP_RELAX *relax)
Definition: relax.c:653
SCIP_Bool SCIPrelaxationIsLpIncludedForSol(SCIP_RELAXATION *relaxation)
Definition: relax.c:803
SCIP callable library.
void SCIPrelaxSetInit(SCIP_RELAX *relax, SCIP_DECL_RELAXINIT((*relaxinit)))
Definition: relax.c:483
SCIP_Longint nseparated
Definition: struct_relax.h:44
SCIP_RETCODE SCIPrelaxExitsol(SCIP_RELAX *relax, SCIP_SET *set)
Definition: relax.c:319