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