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