SCIP Doxygen Documentation
Loading...
Searching...
No Matches
event_solvingphase.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-2026 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 event_solvingphase.c
26 * @ingroup DEFPLUGINS_EVENT
27 * @brief event handler for solving phase dependent parameter adjustment
28 * @author Gregor Hendel
29 *
30 * this event handler provides methods to support parameter adjustment at every new of the three solving phases:
31 * - Feasibility phase - before the first solution is found
32 * - Improvement phase - after the first solution was found until an optimal solution is found or believed to be found
33 * - Proof phase - the remaining time of the solution process after an optimal or believed-to-be optimal incumbent has been found.
34 *
35 * Of course, this event handler cannot detect by itself whether a given incumbent is optimal prior to termination of the
36 * solution process. It rather uses heuristic transitions based on properties of the search tree in order to
37 * determine the appropriate stage. Settings files can be passed to this event handler for each of the three phases.
38 *
39 * This approach of phase-based parameter adjustment was first presented in
40 *
41 * Gregor Hendel
42 * Empirical Analysis of Solving Phases in Mixed-Integer Programming
43 * Master thesis, Technical University Berlin (2014)
44 *
45 * with the main results also available from
46 *
47 * Gregor Hendel
48 * Exploiting solving phases in mixed-integer programs (2015)
49 */
50
51/*--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
52
54#include "scip/pub_disp.h"
55#include "scip/pub_event.h"
56#include "scip/pub_message.h"
57#include "scip/pub_misc.h"
58#include "scip/pub_misc_sort.h"
59#include "scip/pub_paramset.h"
60#include "scip/pub_tree.h"
61#include "scip/scip_disp.h"
62#include "scip/scip_event.h"
63#include "scip/scip_general.h"
64#include "scip/scip_mem.h"
65#include "scip/scip_message.h"
66#include "scip/scip_numerics.h"
67#include "scip/scip_param.h"
68#include "scip/scip_sol.h"
69#include "scip/scip_solve.h"
71#include "scip/scip_timing.h"
72#include "scip/scip_tree.h"
73
74
75#define EVENTHDLR_NAME "solvingphase"
76#define EVENTHDLR_DESC "event handler to adjust settings depending on current stage"
77
78#define EVENTHDLR_EVENT SCIP_EVENTTYPE_BESTSOLFOUND | SCIP_EVENTTYPE_NODEBRANCHED | SCIP_EVENTTYPE_NODEFOCUSED /**< the actual event to be caught */
79#define TRANSITIONMETHODS "elor" /**< which heuristic transition method: (e)stimate based, (l)ogarithmic regression based, (o)ptimal value based (cheat!),
80 * (r)ank-1 node based? */
81#define DEFAULT_SETNAME "-" /**< default settings file name for solving phase setting files */
82#define DEFAULT_TRANSITIONMETHOD 'r' /**< the default transition method */
83#define DEFAULT_NODEOFFSET 50L /**< default node offset before transition to proof phase is active */
84#define DEFAULT_FALLBACK FALSE /**< should the phase transition fall back to suboptimal phase? */
85#define DEFAULT_INTERRUPTOPTIMAL FALSE /**< should solving process be interrupted if optimal solution was found? */
86
87#define DEFAULT_ENABLED FALSE /**< should the event handler be executed? */
88#define DEFAULT_TESTMODE FALSE /**< should the event handler test the criteria? */
89
90#define DEFAULT_USERESTART1TO2 FALSE /**< should a restart be applied between the feasibility and improvement phase? */
91#define DEFAULT_USERESTART2TO3 FALSE /**< should a restart be applied between the improvement and the proof phase? */
92#define DEFAULT_USEEMPHSETTINGS TRUE /**< should emphasis settings be used for the different solving phases, or settings files? */
93
94/* logarithmic regression settings */
95#define DEFAULT_LOGREGRESSION_XTYPE 'n' /**< default type to use for log regression - (t)ime, (n)odes, (l)p iterations */
96#define LOGREGRESSION_XTYPES "lnt" /**< available types for log regression - (t)ime, (n)odes, (l)p iterations */
97/*
98 * Data structures
99 */
100
101/** depth information structure */
103{
104 int nsolvednodes; /**< number of nodes that were solved so far at this depth */
105 SCIP_Real minestimate; /**< the minimum estimate of a solved node */
106 SCIP_NODE** minnodes; /**< points to the rank-1 nodes at this depth (open nodes whose estimate is lower than current
107 minimum estimate over solved nodes) */
108 int nminnodes; /**< the number of minimum nodes */
109 int minnodescapacity; /**< the capacity of the min nodes array */
110};
111
112typedef struct DepthInfo DEPTHINFO;
113
114/** event handler data */
115struct SCIP_EventhdlrData
116{
117 char logregression_xtype;/**< type to use for log regression - (t)ime, (n)odes, (l)p iterations */
118 SCIP_Bool enabled; /**< should the event handler be executed? */
119 char* feassetname; /**< settings file parameter for the feasibility phase -- precedence over emphasis settings */
120 char* improvesetname; /**< settings file parameter for the improvement phase -- precedence over emphasis settings */
121 char* proofsetname; /**< settings file parameter for the proof phase -- precedence over emphasis settings */
122 SCIP_Real optimalvalue; /**< value of optimal solution of the problem */
123 SCIP_Longint nnodesleft; /**< store the number of open nodes that are considered internally to update data */
124 SCIP_SOLVINGPHASE solvingphase; /**< the current solving phase */
125 SCIP_SOLVINGPHASEFLAG phaseflags; /**< bit field of reached transition criteria */
126 char transitionmethod; /**< transition method from improvement phase -> proof phase?
127 * (e)stimate based, (l)ogarithmic regression based, (o)ptimal value based (cheat!),
128 * (r)ank-1 node based */
129 SCIP_Longint nodeoffset; /**< node offset for triggering rank-1 node based phased transition */
130 SCIP_Longint lastndelayedcutoffs; /**< the number of delayed cutoffs since the last update of a focus node */
131 SCIP_Bool fallback; /**< should the phase transition fall back to improvement phase? */
132 SCIP_Bool interruptoptimal; /**< interrupt after optimal solution was found */
133 SCIP_Bool userestart1to2; /**< should a restart be applied between the feasibility and improvement phase? */
134 SCIP_Bool userestart2to3; /**< should a restart be applied between the improvement and the proof phase? */
135 SCIP_Bool useemphsettings; /**< should emphasis settings for the solving phases be used, or settings files? */
136 SCIP_Bool testmode; /**< should transitions be tested only, but not triggered? */
137 SCIP_Bool newbestsol; /**< has a new incumbent been found since the last node was solved? */
138
139 SCIP_REGRESSION* regression; /**< regression data for log linear regression of the incumbent solutions */
140 SCIP_Real lastx; /**< X-value of last observation */
141 SCIP_Real lasty; /**< Y-value of last observation */
142 SCIP_PARAM** nondefaultparams; /**< parameters with non-default values during problem initialization */
143 int nnondefaultparams; /**< number of parameters with non-default values during problem initialization */
144 int nondefaultparamssize;/**< capacity of the array of non-default parameters */
145 int eventfilterpos; /**< the event filter position, or -1, if event has not (yet) been caught */
146 DEPTHINFO** depthinfos; /**< array of depth infos for every depth of the search tree */
147 int maxdepth; /**< maximum depth so far */
148 int nrank1nodes; /**< number of rank-1 nodes */
149 int nnodesbelowincumbent;/**< number of open nodes with an estimate lower than the current incumbent */
150};
151
152
153/*
154 * methods for rank-1 and active estimate transition
155 */
156
157/** nodes are sorted first by their estimates, and if estimates are equal, by their number */
158static
159SCIP_DECL_SORTPTRCOMP(sortCompTreeinfo)
160{
161 SCIP_NODE* node1;
162 SCIP_NODE* node2;
163 SCIP_Real estim1;
164 SCIP_Real estim2;
165 node1 = (SCIP_NODE*)elem1;
166 node2 = (SCIP_NODE*)elem2;
167
168 estim1 = SCIPnodeGetEstimate(node1);
169 estim2 = SCIPnodeGetEstimate(node2);
170
171 /* compare estimates */
172 if( estim1 < estim2 )
173 return -1;
174 else if( estim1 > estim2 )
175 return 1;
176 else
177 {
178 SCIP_Longint number1;
179 SCIP_Longint number2;
180
181 number1 = SCIPnodeGetNumber(node1);
182 number2 = SCIPnodeGetNumber(node2);
183
184 /* compare numbers */
185 if( number1 < number2 )
186 return -1;
187 else if( number1 > number2 )
188 return 1;
189 }
190
191 return 0;
192}
193
194/** insert an array of open nodes (leaves/siblings/children) into the event handler data structures and update the transition information */
195static
197 SCIP* scip, /**< SCIP data structure */
198 SCIP_EVENTHDLRDATA* eventhdlrdata, /**< event handler data */
199 SCIP_NODE** nodes, /**< array of nodes */
200 int nnodes /**< number of nodes */
201 )
202{
203 int n;
204
205 assert(nnodes == 0 || nodes != NULL);
206 assert(scip != NULL);
207 assert(eventhdlrdata->depthinfos != NULL);
208
209 /* store every relevant node in the data structure for its depth */
210 for( n = 0; n < nnodes; ++n )
211 {
212 SCIP_NODE* node = nodes[n];
213 DEPTHINFO* depthinfo = eventhdlrdata->depthinfos[SCIPnodeGetDepth(node)];
214 SCIP_Real estim = SCIPnodeGetEstimate(node);
215
218
219 /* an open node has rank 1 if it has an estimate at least as small as the best solved node at this depth */
220 if( depthinfo->nsolvednodes == 0 || SCIPisGE(scip, depthinfo->minestimate, SCIPnodeGetEstimate(node)) )
221 {
222 int pos;
223
224 /* allocate additional memory to hold new node */
225 if( depthinfo->nminnodes == depthinfo->minnodescapacity )
226 {
227 int oldcapacity = depthinfo->minnodescapacity;
228 depthinfo->minnodescapacity *= 2;
229 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &depthinfo->minnodes, oldcapacity, depthinfo->minnodescapacity) );
230 }
231
232 /* find correct insert position */
233 SCIPsortedvecInsertPtr((void **)depthinfo->minnodes, sortCompTreeinfo, (void*)node, &depthinfo->nminnodes, &pos);
234 assert(pos >= 0 && pos < depthinfo->nminnodes);
235 assert(depthinfo->minnodes[pos] == node);
236
237 /* update rank 1 node information */
238 ++eventhdlrdata->nrank1nodes;
239 }
240
241 /* update active estimate information by bookkeeping nodes with an estimate smaller than the current incumbent */
242 if( SCIPisLT(scip, estim, SCIPgetUpperbound(scip) ) )
243 ++eventhdlrdata->nnodesbelowincumbent;
244 }
245
246 /* update the number of open search nodes */
247 eventhdlrdata->nnodesleft += nnodes;
248
249 return SCIP_OKAY;
250}
251
252/** remove a node from the data structures of the event handler */
253static
255 SCIP_NODE* node, /**< node that should be removed */
256 SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */
257 )
258{
259 DEPTHINFO* depthinfo;
260 int pos;
261 SCIP_Bool contained;
262
263 assert(node != NULL);
264
265 /* get depth information for the depth of this node */
266 depthinfo = eventhdlrdata->depthinfos[SCIPnodeGetDepth(node)];
267
268 /* no node is saved at this depth */
269 if( depthinfo->nminnodes == 0 )
270 return;
271
272 /* search for the node by using binary search */
273 contained = SCIPsortedvecFindPtr((void **)depthinfo->minnodes, sortCompTreeinfo, (void *)node, depthinfo->nminnodes, &pos);
274
275 /* remove the node if it is contained */
276 if( contained )
277 {
278 SCIPsortedvecDelPosPtr((void **)depthinfo->minnodes, sortCompTreeinfo, pos, &(depthinfo->nminnodes));
279 --eventhdlrdata->nrank1nodes;
280 }
281}
282
283/** returns the current number of rank 1 nodes in the tree */
284static
286 SCIP* scip /**< SCIP data structure */
287 )
288{
289 SCIP_EVENTHDLRDATA* eventhdlrdata;
290
291 assert(scip != NULL);
292
294
295 /* return the stored number of rank 1 nodes only during solving stage */
297 return eventhdlrdata->nrank1nodes;
298 else
299 return -1;
300}
301
302/** returns the current number of open nodes which have an estimate lower than the incumbent solution */
303static
305 SCIP* scip /**< SCIP data structure */
306 )
307{
308 SCIP_EVENTHDLRDATA* eventhdlrdata;
309
310 assert(scip != NULL);
311
313
314 /* return the stored number of nodes only during solving stage */
316 return eventhdlrdata->nnodesbelowincumbent;
317 else
318 return -1;
319}
320
321/** discards all previous node information and renews it */
322static
324 SCIP* scip, /**< SCIP data structure */
325 SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */
326 )
327{
328 SCIP_NODE** leaves;
329 SCIP_NODE** children;
330 SCIP_NODE** siblings;
331
332 int nleaves;
333 int nchildren;
334 int nsiblings;
335 int d;
336
337 /* the required node information is only available after solving started */
339 return SCIP_OKAY;
340
341 assert(eventhdlrdata != NULL);
342
343 /* reset depth information */
344 for( d = 0; d < eventhdlrdata->maxdepth; ++d )
345 eventhdlrdata->depthinfos[d]->nminnodes = 0;
346
347 eventhdlrdata->nrank1nodes = 0;
348 eventhdlrdata->nnodesbelowincumbent = 0;
349 eventhdlrdata->nnodesleft = 0;
350
351 nleaves = nchildren = nsiblings = 0;
352
353 /* get leaves, children, and sibling arrays and update the event handler data structures */
354 SCIP_CALL( SCIPgetOpenNodesData(scip, &leaves, &children, &siblings, &nleaves, &nchildren, &nsiblings) );
355
356 SCIP_CALL ( addNodesInformation(scip, eventhdlrdata, children, nchildren) );
357
358 SCIP_CALL ( addNodesInformation(scip, eventhdlrdata, siblings, nsiblings) );
359
360 SCIP_CALL ( addNodesInformation(scip, eventhdlrdata, leaves, nleaves) );
361
362 /* information needs to be recomputed from scratch if a new incumbent is found */
363 eventhdlrdata->newbestsol = FALSE;
364
365 return SCIP_OKAY;
366}
367
368/** allocates memory for a depth info */
369static
371 SCIP* scip, /**< SCIP data structure */
372 DEPTHINFO** depthinfo /**< pointer to depth information structure */
373 )
374{
375 assert(scip != NULL);
376 assert(depthinfo != NULL);
377
378 /* allocate the necessary memory */
379 SCIP_CALL( SCIPallocBlockMemory(scip, depthinfo) );
380
381 /* reset the depth information */
382 (*depthinfo)->minestimate = SCIPinfinity(scip);
383 (*depthinfo)->nsolvednodes = 0;
384 (*depthinfo)->nminnodes = 0;
385 (*depthinfo)->minnodescapacity = 2;
386
387 /* allocate array to store nodes */
388 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(*depthinfo)->minnodes, (*depthinfo)->minnodescapacity) );
389
390 return SCIP_OKAY;
391}
392
393/** frees depth information data structure */
394static
396 SCIP* scip, /**< SCIP data structure */
397 DEPTHINFO** depthinfo /**< pointer to depth information structure */
398 )
399{
400 assert(scip != NULL);
401 assert(depthinfo != NULL);
402 assert(*depthinfo != NULL);
403 assert((*depthinfo)->minnodes != NULL);
404
405 /* free nodes data structure and then the structure itself */
406 SCIPfreeBlockMemoryArray(scip, &(*depthinfo)->minnodes, (*depthinfo)->minnodescapacity);
407 SCIPfreeBlockMemory(scip, depthinfo);
408
409 return SCIP_OKAY;
410}
411
412/** removes the node itself and updates the data if this node defined an active estimate globally or locally at its depth level */
413static
415 SCIP* scip, /**< SCIP data structure */
416 SCIP_EVENTHDLRDATA* eventhdlrdata, /**< event handler data */
417 SCIP_NODE* node /**< node to be removed from the data structures of the event handler */
418 )
419{
420 DEPTHINFO* depthinfo;
421
422 assert(scip != NULL);
423 assert(node != NULL);
424 assert(eventhdlrdata != NULL);
425
426 /* get the correct depth info at the node depth */
427 depthinfo = eventhdlrdata->depthinfos[SCIPnodeGetDepth(node)];
428 assert(depthinfo != NULL);
429
430 /* remove the node from the data structures */
431 removeNode(node, eventhdlrdata);
432
433 /* compare the node estimate to the minimum estimate of the particular depth */
434 if( SCIPisLT(scip, SCIPnodeGetEstimate(node), depthinfo->minestimate) )
435 depthinfo->minestimate = SCIPnodeGetEstimate(node);
436
437 /* decrease counter of active estimate nodes if node has an estimate that is below the current incumbent */
439 eventhdlrdata->nnodesbelowincumbent--;
440
441 /* loop over remaining, unsolved nodes and decide whether they are still rank-1 nodes */
442 while( depthinfo->nminnodes > 0 && SCIPisGT(scip, SCIPnodeGetEstimate(depthinfo->minnodes[depthinfo->nminnodes - 1]), depthinfo->minestimate) )
443 {
444 /* forget about node */
445 --(depthinfo->nminnodes);
446 --(eventhdlrdata->nrank1nodes);
447 }
448
449 /* increase the number of solved nodes at this depth */
450 ++(depthinfo->nsolvednodes);
451
452 /* decrease the counter for the number of open nodes */
453 --eventhdlrdata->nnodesleft;
454}
455
456/** ensures sufficient size for depthInfo array */
457static
459 SCIP* scip, /**< SCIP data structure */
460 SCIP_EVENTHDLRDATA* eventhdlrdata, /**< event handler data */
461 SCIP_NODE* node /**< node to be removed from the data structures of the event handler */
462 )
463{
464 int nodedepth;
465 int newsize;
466 int oldsize;
467 nodedepth = SCIPnodeGetDepth(node);
468 oldsize = eventhdlrdata->maxdepth;
469 newsize = oldsize;
470
471 /* create depth info array with small initial size or enlarge the existing array if new node is deeper */
472 if( oldsize == 0 )
473 {
474 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &eventhdlrdata->depthinfos, 10) );
475 newsize = 10;
476 }
477 else if( nodedepth + 1 >= eventhdlrdata->maxdepth )
478 {
479 assert(nodedepth > 0);
480 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &eventhdlrdata->depthinfos, oldsize, 2 * nodedepth) ); /*lint !e647*/
481 newsize = 2 * nodedepth;
482 }
483
484 /* create the according depth information pointers */
485 if( newsize > oldsize )
486 {
487 int c;
488
489 for( c = oldsize; c < newsize; ++c )
490 {
491 SCIP_CALL( createDepthinfo(scip, &(eventhdlrdata->depthinfos[c])) );
492 }
493
494 eventhdlrdata->maxdepth = newsize;
495 }
496 assert(newsize > nodedepth);
497
498 return SCIP_OKAY;
499}
500
501/** ensures the capacity of the event handler data structures and removes the current node */
502static
504 SCIP* scip, /**< SCIP data structure */
505 SCIP_EVENTHDLRDATA* eventhdlrdata, /**< event handler data */
506 SCIP_NODE* node /**< node to be removed from the data structures of the event handler */
507 )
508{
509 assert(scip != NULL);
510 assert(node != NULL);
511 assert(eventhdlrdata != NULL);
512
513 /* ensure the depth info data structure can hold this node */
514 SCIP_CALL( ensureDepthInfoArraySize(scip, eventhdlrdata, node) );
515
516 /* in case that selected nodes were cut off in between two calls to this method, build data structures from scratch again */
517 if( SCIPgetNDelayedCutoffs(scip) > eventhdlrdata->lastndelayedcutoffs || eventhdlrdata->newbestsol
518 || eventhdlrdata->nnodesleft - 1 != SCIPgetNNodesLeft(scip) )
519 {
520 SCIP_CALL( recomputeNodeInformation(scip, eventhdlrdata) );
521
522 eventhdlrdata->lastndelayedcutoffs = SCIPgetNDelayedCutoffs(scip);
523 }
524 else
525 {
526 /* remove the node from the data structures */
527 releaseNodeFromDepthInfo(scip, eventhdlrdata, node);
528 }
529
530 assert(eventhdlrdata->nnodesleft == SCIPgetNNodesLeft(scip));
531
532 return SCIP_OKAY;
533}
534
535#ifndef NDEBUG
536/** ensures correctness of counters by explicitly summing up all children, leaves, and siblings with small estimates */
537static
539 SCIP* scip
540 )
541{
542 SCIP_NODE** nodes;
543 SCIP_RETCODE retcode;
544 int nnodes;
545 int n;
546 SCIP_Real upperbound = SCIPgetUpperbound(scip);
547 int nodesbelow = 0;
548
549 /* compare children estimate and current upper bound */
550 retcode = SCIPgetChildren(scip, &nodes, &nnodes);
551 assert(retcode == SCIP_OKAY);
552
553 for( n = 0; n < nnodes; ++n )
554 {
555 if( SCIPisLT(scip, SCIPnodeGetEstimate(nodes[n]), upperbound) )
556 ++nodesbelow;
557 }
558
559 /* compare sibling estimate and current upper bound */
560 retcode = SCIPgetSiblings(scip, &nodes, &nnodes);
561 assert(retcode == SCIP_OKAY);
562
563 for( n = 0; n < nnodes; ++n )
564 {
565 if( SCIPisLT(scip, SCIPnodeGetEstimate(nodes[n]), upperbound) )
566 ++nodesbelow;
567 }
568
569 /* compare leaf node and current upper bound */
570 retcode = SCIPgetLeaves(scip, &nodes, &nnodes);
571 assert(retcode == SCIP_OKAY);
572
573 for( n = 0; n < nnodes; ++n )
574 {
575 if( SCIPisLT(scip, SCIPnodeGetEstimate(nodes[n]), upperbound) )
576 ++nodesbelow;
577 }
578
579 assert(nodesbelow <= SCIPgetNNodesLeft(scip));
580 return nodesbelow;
581}
582#endif
583
584/** get the point of the X axis for the regression according to the user choice of X type (time/nodes/iterations)*/
585static
587 SCIP* scip, /**< SCIP data structure */
588 SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */
589 )
590{
591 SCIP_Real x;
592
593 switch( eventhdlrdata->logregression_xtype )
594 {
595 case 'l':
596 /* get number of LP iterations so far */
599 else
600 x = 1.0;
601 break;
602 case 'n':
603 /* get total number of solving nodes so far */
606 else
607 x = 1.0;
608 break;
609 case 't':
610 /* get solving time */
612 break;
613 default:
614 x = 1.0;
615 break;
616 }
617
618 /* prevent the calculation of logarithm too close to zero */
619 x = MAX(x, .1);
620 x = log(x);
621
622 return x;
623}
624
625
626
627
628
629/** get axis intercept of current tangent to logarithmic regression curve */
630static
632 SCIP* scip, /**< SCIP data structure */
633 SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data structure */
634 )
635{
636 SCIP_REGRESSION* regression;
637 SCIP_Real currentx;
638 SCIP_Real regressionslope;
639
640 assert(scip != NULL);
641 assert(eventhdlrdata != NULL);
642
643 regression = eventhdlrdata->regression;
644 assert(regression != NULL);
645
646 /* don't rely on too few (<= 2) observations */
647 if( SCIPregressionGetNObservations(regression) <= 2 )
648 return SCIPinfinity(scip);
649
650 currentx = getX(scip, eventhdlrdata);
651 regressionslope = SCIPregressionGetSlope(regression);
652
653 return regressionslope * currentx + SCIPregressionGetIntercept(regression) - regressionslope;
654}
655
656/*
657 * Local methods
658 */
659
660/** checks if rank-1 transition has been reached, that is, when all open nodes have a best-estimate higher than the best
661 * previously checked node at this depth
662 */
663static
665 SCIP* scip, /**< SCIP data structure */
666 SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */
667 )
668{
669 /* at least one solution is required for the transition */
670 if( SCIPgetNSols(scip) > 0 )
671 return (SCIPgetNNodes(scip) > eventhdlrdata->nodeoffset && getNRank1Nodes(scip) == 0);
672 else
673 return FALSE;
674}
675
676/** check if Best-Estimate criterion was reached, that is, when the active estimate is not better than the current incumbent solution */
677static
679 SCIP* scip, /**< SCIP data structure */
680 SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */
681 )
682{
683 if( SCIPgetNSols(scip) > 0 )
684 return ((SCIPgetNNodes(scip) > eventhdlrdata->nodeoffset) && (eventhdlrdata->nnodesbelowincumbent == 0));
685 else
686 return FALSE;
687}
688
689/** check if logarithmic phase transition has been reached.
690 *
691 * the logarithmic phase transition is reached when the slope of the logarithmic primal progress (as a function of the number of
692 * LP iterations or solving nodes) becomes gentle. More concretely, we measure the slope by calculating the axis intercept of the tangent of
693 * the logarithmic primal progress. We then compare this axis intercept to the first and current primal bound and say that
694 * the logarithmic phase transition is reached as soon as the axis intercept passes the current primal bound so that the
695 * scalar becomes negative.
696 *
697 * While it would be enough to directly compare the primal bound and the axis intercept of the
698 * tangent to check the criterion, the scalar allows for a continuous indicator how far the phase transition is still ahead
699 */
700static
702 SCIP* scip, /**< SCIP data structure */
703 SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */
704 )
705{
706 if( SCIPgetNSols(scip) > 0 )
707 {
708 SCIP_Real axisintercept = getCurrentRegressionTangentAxisIntercept(scip, eventhdlrdata);
709 if( !SCIPisInfinity(scip, axisintercept) )
710 {
711 SCIP_Real primalbound;
712 SCIP_Real lambda;
713 SCIP_Real firstprimalbound = SCIPgetFirstPrimalBound(scip);
714
715 primalbound = SCIPgetPrimalbound(scip);
716
717 /* lambda is the scalar to describe the axis intercept as a linear combination of the current and the first primal bound
718 * as intercept = pb_0 + lambda * (pb - pb_0) */
719 lambda = (axisintercept - primalbound) / (firstprimalbound - primalbound);
720
721 if( SCIPisNegative(scip, lambda) )
722 return TRUE;
723 }
724 }
725 return FALSE;
726}
727
728/** check if incumbent solution is nearly optimal; we allow a relative deviation of 10^-9 */
729static
731 SCIP* scip, /**< SCIP data structure */
732 SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */
733 )
734{
735 SCIP_Real referencevalue;
736 SCIP_Real primalbound;
737
738 referencevalue = eventhdlrdata->optimalvalue;
739 primalbound = SCIPgetPrimalbound(scip);
740
741 if(!SCIPisInfinity(scip, REALABS(primalbound)) && !SCIPisInfinity(scip, referencevalue) )
742 {
743 SCIP_Real max = MAX3(1.0, REALABS(primalbound), REALABS(referencevalue)); /*lint !e666*/
744
745 if( EPSZ((primalbound - referencevalue)/max, 1e-9) )
746 return TRUE;
747 }
748 return FALSE;
749}
750
751/** check if we are in the proof phase */
752static
754 SCIP* scip, /**< SCIP data structure */
755 SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */
756 )
757{
758 if( eventhdlrdata->solvingphase == SCIP_SOLVINGPHASE_PROOF && !eventhdlrdata->fallback )
759 return TRUE;
760
761 /* check criterion based on selected transition method */
762 switch( eventhdlrdata->transitionmethod )
763 {
764 case 'r':
765
766 /* check rank-1 transition */
767 if( checkRankOneTransition(scip, eventhdlrdata) )
768 {
769 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "reached rank-1 transition: nodes: %lld, rank-1: %d bound: %9.5g time: %.2f\n",
771 return TRUE;
772 }
773 break;
774 case 'o':
775
776 /* cheat and use knowledge about optimal solution */
777 if( checkOptimalSolution(scip, eventhdlrdata) )
778 {
779 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "optimal solution found: %lld, bound: %9.5g time: %.2f\n",
781 return TRUE;
782 }
783 break;
784 case 'e':
785
786 /* check best-estimate transition */
787 if( checkEstimateCriterion(scip, eventhdlrdata) )
788 {
789 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "reached best-estimate transition: nodes: %lld, estimate: %d bound: %9.5g time: %.2f\n",
790 SCIPgetNNodes(scip), eventhdlrdata->nnodesbelowincumbent, SCIPgetPrimalbound(scip), SCIPgetSolvingTime(scip));
791 return TRUE;
792 }
793 return FALSE;
794 case 'l':
795
796 /* check logarithmic transition */
797 if( checkLogCriterion(scip, eventhdlrdata) )
798 {
799 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "reached a logarithmic phase transition: %.2f\n", SCIPgetSolvingTime(scip));
800 return TRUE;
801 }
802 break;
803 default:
804 return FALSE;
805 }
806
807 return FALSE;
808}
809
810/* determine the solving phase: feasibility phase if no solution was found yet, otherwise improvement phase or proof phase
811 * depending on whether selected transition criterion was already reached and fallback is active or not
812 */
813static
815 SCIP* scip, /**< SCIP data structure */
816 SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */
817 )
818{
819 /* without solution, we are in the feasibility phase */
820 if( SCIPgetNSols(scip) == 0 )
821 eventhdlrdata->solvingphase = SCIP_SOLVINGPHASE_FEASIBILITY;
822 else if( eventhdlrdata->solvingphase != SCIP_SOLVINGPHASE_PROOF || eventhdlrdata->fallback )
823 eventhdlrdata->solvingphase = SCIP_SOLVINGPHASE_IMPROVEMENT;
824
825 if( eventhdlrdata->solvingphase == SCIP_SOLVINGPHASE_IMPROVEMENT && transitionPhase3(scip, eventhdlrdata) )
826 eventhdlrdata->solvingphase = SCIP_SOLVINGPHASE_PROOF;
827}
828
829/** changes parameters by using emphasis settings */
830static
832 SCIP* scip, /**< SCIP data structure */
833 SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */
834 )
835{
836 SCIP_PARAMEMPHASIS paramemphasis;
837
838 /* choose the appropriate emphasis settings for the new solving phase */
839 switch(eventhdlrdata->solvingphase)
840 {
842 paramemphasis = SCIP_PARAMEMPHASIS_PHASEFEAS;
843 break;
845 paramemphasis = SCIP_PARAMEMPHASIS_PHASEIMPROVE;
846 break;
848 paramemphasis = SCIP_PARAMEMPHASIS_PHASEPROOF;
849 break;
851 default:
852 SCIPdebugMsg(scip, "Unknown solving phase: %d -> ABORT!\n ", eventhdlrdata->solvingphase);
853 SCIPABORT();
854 paramemphasis = SCIP_PARAMEMPHASIS_DEFAULT;
855 break;
856 }
857
858 SCIP_CALL( SCIPsetEmphasis(scip, paramemphasis, FALSE) );
859
860 return SCIP_OKAY;
861}
862
863/** change general solving strategy of SCIP depending on the phase by reading from settings file */
864static
866 SCIP* scip, /**< SCIP data structure */
867 SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */
868 )
869{
870 FILE* file;
871 char* paramfilename = NULL;
872
873 /* choose the settings file for the new solving phase */
874 switch(eventhdlrdata->solvingphase)
875 {
877 paramfilename = eventhdlrdata->feassetname;
878 break;
880 paramfilename = eventhdlrdata->improvesetname;
881 break;
883 paramfilename = eventhdlrdata->proofsetname;
884 break;
886 default:
887 SCIPdebugMsg(scip, "Unknown solving phase: %d -> ABORT!\n ", eventhdlrdata->solvingphase);
888 return SCIP_INVALIDCALL;
889 }
890
891 assert(paramfilename != NULL);
892
893 /* return if no there is no user-specified settings file for the current phase */
894 if( strcmp(paramfilename, DEFAULT_SETNAME) == 0 )
895 return SCIP_OKAY;
896
897 file = fopen(paramfilename, "r");
898
899 /* test if file could be found and print a warning if not */
900 if( file == NULL )
901 {
902 SCIPwarningMessage(scip, "Parameter file <%s> not found--keeping settings as before.\n", paramfilename);
903 }
904 else
905 {
906 /* we can close the file */
907 fclose(file);
908
909 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "Reading parameters from file <%s>\n", paramfilename);
910
911 SCIP_CALL( SCIPreadParams(scip, paramfilename) );
912 }
913
914 return SCIP_OKAY;
915} /*lint !e593*/
916
917/** fix/unfix relevant solving parameters that should not accidentally be set to default values */
918static
920 SCIP* scip, /**< SCIP data structure */
921 SCIP_EVENTHDLRDATA* eventhdlrdata, /**< event handler data */
922 SCIP_Bool fix /**< should the parameters be fixed (true) or unfixed? */
923 )
924{
925 int p;
926 const char* relevantparams[] = {
927 "limits/time",
928 "limits/nodes",
929 "limits/totalnodes",
930 "limits/stallnodes",
931 "limits/memory",
932 "limits/gap",
933 "limits/absgap",
934 "limits/solutions",
935 "limits/bestsol",
936 "limits/maxsol",
937 "limits/maxorigsol",
938 "limits/restarts",
939 "limits/autorestartnodes",
940 "limits/softtime",
941 "solvingphases/enabled",
942 "solvingphases/fallback",
943 "solvingphases/interruptoptimal",
944 "solvingphases/nodeoffset",
945 "solvingphases/feassetname",
946 "solvingphases/proofsetname",
947 "solvingphases/optimalvalue",
948 "solvingphases/improvesetname",
949 "solvingphases/testmode",
950 "solvingphases/transitionmethod",
951 "solvingphases/useemphsettings",
952 "solvingphases/userestart1to2",
953 "solvingphases/userestart2to3",
954 "solvingphases/xtype"
955 };
956 int nrelevantparams = 28;
957
958 /* fix or unfix all specified limit parameters */
959 for( p = 0; p < nrelevantparams; ++p )
960 {
961 if( fix )
962 {
963 SCIP_CALL( SCIPfixParam(scip, relevantparams[p]) );
964 }
965 else
966 {
967 SCIP_CALL( SCIPunfixParam(scip, relevantparams[p]) );
968 }
969 }
970
971 /* fix or unfix all collected, non-default parameters after problem transformation */
972 for( p = 0; p < eventhdlrdata->nnondefaultparams; ++p )
973 {
974 if( fix && ! SCIPparamIsFixed(eventhdlrdata->nondefaultparams[p]) )
975 {
976 SCIP_CALL( SCIPfixParam(scip, SCIPparamGetName(eventhdlrdata->nondefaultparams[p])) );
977 }
978 else if( ! fix && SCIPparamIsFixed(eventhdlrdata->nondefaultparams[p]) )
979 {
980 SCIP_CALL( SCIPunfixParam(scip, SCIPparamGetName(eventhdlrdata->nondefaultparams[p])) );
981 }
982 }
983
984 return SCIP_OKAY;
985}
986
987/** change settings depending whether emphasis settings should be used, or settings files */
988static
990 SCIP* scip, /**< SCIP data structure */
991 SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */
992 )
993{
994 /* fix relevant parameters such that they are not overwritten */
996
997 /* change settings using emphasis */
998 if( eventhdlrdata->useemphsettings )
999 {
1000 SCIP_CALL( changeEmphasisParameters(scip, eventhdlrdata) );
1001 }
1002 else
1003 {
1004 /* reset to default settings; this happens automatically when using emphasis settings */
1006 }
1007
1008 /* read optional, phase-specific settings */
1010
1011 /* unfix relevant parameters that have been fixed for changing emphasis */
1013
1014 return SCIP_OKAY;
1015}
1016
1017/* apply the user-specified phase-based settings: A phase transition invokes the read of phase-specific settings from a file */
1018static
1020 SCIP* scip, /**< SCIP data structure */
1021 SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */
1022 )
1023{
1024 SCIP_SOLVINGPHASE oldsolvingphase;
1025 SCIP_Bool restart;
1026
1027 /* return immediately if we are in the proof phase */
1028 if( eventhdlrdata->solvingphase == SCIP_SOLVINGPHASE_PROOF && !eventhdlrdata->fallback )
1029 return SCIP_OKAY;
1030
1031 /* save current solving phase */
1032 oldsolvingphase = eventhdlrdata->solvingphase;
1033
1034 /* determine current solving phase */
1035 determineSolvingPhase(scip, eventhdlrdata);
1036
1037 /* nothing has changed */
1038 if( oldsolvingphase == eventhdlrdata->solvingphase )
1039 return SCIP_OKAY;
1040
1041 /* check if the solving process should be interrupted when the current solution is optimal */
1042 if( eventhdlrdata->solvingphase == SCIP_SOLVINGPHASE_PROOF && eventhdlrdata->transitionmethod == 'o' &&
1043 eventhdlrdata->interruptoptimal )
1044 {
1045 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "Solution is optimal. Calling user interruption.\n");
1046
1047 /* we call interrupt solve but do not return yet because user-specified settings for the proof phase are applied first */
1049 }
1050
1051 /* check if a restart should be performed after phase transition */
1052 if( eventhdlrdata->solvingphase == SCIP_SOLVINGPHASE_IMPROVEMENT && eventhdlrdata->userestart1to2 )
1053 restart = TRUE;
1054 else if( eventhdlrdata->solvingphase == SCIP_SOLVINGPHASE_PROOF && eventhdlrdata->userestart2to3 )
1055 restart = TRUE;
1056 else
1057 restart = FALSE;
1058
1059 /* inform SCIP that a restart should be performed */
1060 if( restart )
1061 {
1063 }
1064
1065 /* change general solving settings depending on solving strategy */
1066 SCIP_CALL( adaptSolverBehavior(scip, eventhdlrdata) );
1067
1068 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL,"Changed solving phase to phase %d.\n", eventhdlrdata->solvingphase);
1069
1070 return SCIP_OKAY;
1071}
1072
1073/** update the logarithmic regression */
1074static
1076 SCIP* scip, /**< SCIP data structure */
1077 SCIP_EVENTHDLRDATA* eventhdlrdata /**< data of event handler */
1078 )
1079{
1080 SCIP_Real regressionx;
1081 SCIP_Real regressiony;
1082
1083 regressionx = getX(scip, eventhdlrdata);
1084 regressiony = SCIPgetPrimalbound(scip);
1085
1086 /* remove the last observation if it has been observed at the same x */
1087 if( SCIPisEQ(scip, eventhdlrdata->lastx, regressionx) )
1088 {
1089 SCIPregressionRemoveObservation(eventhdlrdata->regression, eventhdlrdata->lastx, eventhdlrdata->lasty);
1090 }
1091
1092 /* add the new observation to the regression and save it if another update is necessary */
1093 SCIPregressionAddObservation(eventhdlrdata->regression, regressionx, regressiony);
1094 eventhdlrdata->lastx = regressionx;
1095 eventhdlrdata->lasty = regressiony;
1096
1097 return SCIP_OKAY;
1098}
1099
1100/** update data structures based on the event type caught */
1101static
1103 SCIP* scip, /**< SCIP data structure */
1104 SCIP_EVENTHDLRDATA* eventhdlrdata, /**< data of event handler */
1105 SCIP_EVENTTYPE eventtype /**< type of the caught event */
1106 )
1107{
1108 SCIP_NODE** children;
1109 int nchildren;
1110
1111 switch( eventtype )
1112 {
1113 /* store that a new best solution was found, but delay the update of node information until a node was solved */
1115 eventhdlrdata->newbestsol = TRUE;
1116
1117 /* update logarithmic regression of solution process */
1118 SCIP_CALL( updateLogRegression(scip, eventhdlrdata) );
1119
1120 break;
1121
1122 /* release the focus node from the open node data structures */
1125
1127 assert(eventhdlrdata->nnodesbelowincumbent <= SCIPgetNNodesLeft(scip));
1128
1129 break;
1130
1131 /* store node information for child nodes */
1134
1135 /* if we lost track of exact number of open search nodes, we recompute node information from scratch */
1136 if( eventhdlrdata->newbestsol || eventhdlrdata->nnodesleft + SCIPgetNChildren(scip) != SCIPgetNNodesLeft(scip) )
1137 {
1138 SCIP_CALL( recomputeNodeInformation(scip, eventhdlrdata) );
1139 eventhdlrdata->newbestsol = FALSE;
1140
1141 return SCIP_OKAY;
1142 }
1143 else
1144 {
1145 SCIP_CALL( SCIPgetChildren(scip, &children, &nchildren) );
1146 SCIP_CALL( addNodesInformation(scip, eventhdlrdata, children, nchildren) );
1147 }
1148
1149 assert(eventhdlrdata->nnodesleft == SCIPgetNNodesLeft(scip));
1150 break;
1151
1152 default:
1153 break;
1154 }
1155
1156 /* ensure that required tree information was correctly computed; only available in solving stage and at the beginning
1157 * or end of a node solution process because we delay the recomputation of the node information)
1158 */
1160 (eventtype == SCIP_EVENTTYPE_BESTSOLFOUND) ||
1161 (eventhdlrdata->nnodesleft == SCIPgetNNodesLeft(scip) && eventhdlrdata->nnodesbelowincumbent == checkLeavesBelowIncumbent(scip)));
1162
1163 return SCIP_OKAY;
1164}
1165
1166/** test all criteria whether they have been reached */
1167static
1169 SCIP* scip, /**< SCIP data structure */
1170 SCIP_EVENTHDLRDATA* eventhdlrdata /**< data of event handler */
1171 )
1172{
1173 assert(scip != NULL);
1174 assert(eventhdlrdata != NULL);
1175
1176 if( !(eventhdlrdata->phaseflags & SCIP_SOLVINGPHASEFLAG_LOG) && checkLogCriterion(scip, eventhdlrdata) )
1177 {
1178 eventhdlrdata->phaseflags |= SCIP_SOLVINGPHASEFLAG_LOG;
1179 if( eventhdlrdata->testmode )
1180 {
1181 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " Log criterion reached after %lld nodes, %.2f sec.\n",
1183 }
1184 }
1185 if( !(eventhdlrdata->phaseflags & SCIP_SOLVINGPHASEFLAG_RANK1) && checkRankOneTransition(scip, eventhdlrdata) )
1186 {
1187 eventhdlrdata->phaseflags |= SCIP_SOLVINGPHASEFLAG_RANK1;
1188 if( eventhdlrdata->testmode )
1189 {
1190 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " Rank 1 criterion reached after %lld nodes, %.2f sec.\n",
1192 }
1193 }
1194
1195 if( !(eventhdlrdata->phaseflags & SCIP_SOLVINGPHASEFLAG_ESTIMATE) && checkEstimateCriterion(scip, eventhdlrdata) )
1196 {
1197 eventhdlrdata->phaseflags |= SCIP_SOLVINGPHASEFLAG_ESTIMATE;
1198 if( eventhdlrdata->testmode )
1199 {
1200 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " Estimate criterion reached after %lld nodes, %.2f sec.\n",
1202 }
1203 }
1204
1205 if( !(eventhdlrdata->phaseflags & SCIP_SOLVINGPHASEFLAG_OPTIMAL) && checkOptimalSolution(scip, eventhdlrdata) )
1206 {
1207 eventhdlrdata->phaseflags |= SCIP_SOLVINGPHASEFLAG_OPTIMAL;
1208 if( eventhdlrdata->testmode )
1209 {
1210 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " Optimum reached after %lld nodes, %.2f sec.\n",
1212 }
1213 }
1214}
1215
1216/*
1217 * Callback methods of event handler
1218 */
1219
1220/** copy method for event handler (called when SCIP copies plugins) */
1221/* @todo: this code needs to stay disabled as long as the soft limit event handler is not copied, because we save
1222 * the soft time limit parameter but this will crash as soon as we are in a SCIP copy */
1223#ifdef SCIP_DISABLED_CODE
1224static
1226{ /*lint --e{715}*/
1227 assert(scip != NULL);
1228 assert(eventhdlr != NULL);
1229
1231
1232 /* call inclusion method of event handler */
1234
1235 return SCIP_OKAY;
1236}
1237#else
1238#define eventCopySolvingphase NULL
1239#endif
1240
1241/** destructor of event handler to free user data (called when SCIP is exiting) */
1242static
1243SCIP_DECL_EVENTFREE(eventFreeSolvingphase)
1244{
1245 SCIP_EVENTHDLRDATA* eventhdlrdata;
1246
1247 assert(scip != NULL);
1248 assert(eventhdlr != NULL);
1249
1251
1252 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
1253 assert(eventhdlrdata != NULL);
1254
1255 SCIPregressionFree(&eventhdlrdata->regression);
1256
1257 SCIPfreeBlockMemory(scip, &eventhdlrdata);
1258 SCIPeventhdlrSetData(eventhdlr, NULL);
1259
1260 return SCIP_OKAY;
1261}
1262
1263/** initialization method of event handler (called after problem was transformed) */
1264static
1265SCIP_DECL_EVENTINITSOL(eventInitsolSolvingphase)
1266{ /*lint --e{715}*/
1267 SCIP_EVENTHDLRDATA* eventhdlrdata;
1268
1269 assert(scip != NULL);
1270 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
1271 eventhdlrdata->depthinfos = NULL;
1272 eventhdlrdata->maxdepth = 0;
1273 eventhdlrdata->nnodesbelowincumbent = 0;
1274 eventhdlrdata->nnodesleft = 0;
1275 eventhdlrdata->nrank1nodes = 0;
1276 eventhdlrdata->lastndelayedcutoffs = SCIPgetNDelayedCutoffs(scip);
1277 eventhdlrdata->newbestsol = FALSE;
1278
1279 return SCIP_OKAY;
1280}
1281
1282/** solving process deinitialization method of event handler (called before branch and bound process data is freed) */
1283static
1284SCIP_DECL_EVENTEXITSOL(eventExitsolSolvingphase)
1285{
1286 SCIP_EVENTHDLRDATA* eventhdlrdata;
1287
1288 assert(scip != NULL);
1289 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
1290
1291 /* free all data storage acquired during this branch-and-bound run */
1292 if( eventhdlrdata->maxdepth > 0 )
1293 {
1294 int c;
1295
1296 /* free depth information */
1297 for( c = 0; c < eventhdlrdata->maxdepth; ++c )
1298 {
1299 SCIP_CALL( freeDepthinfo(scip, &(eventhdlrdata->depthinfos[c])) );
1300 }
1301
1302 /* free depth information array */
1303 SCIPfreeBlockMemoryArray(scip, &eventhdlrdata->depthinfos, eventhdlrdata->maxdepth);
1304 eventhdlrdata->maxdepth = 0;
1305 }
1306
1307 return SCIP_OKAY;
1308}
1309
1310/** collects all parameters that are set to non-default values and stores them in eventhdlrdata */
1311static
1313 SCIP* scip, /**< SCIP data structure */
1314 SCIP_EVENTHDLRDATA* eventhdlrdata /**< data of event handler */
1315 )
1316{
1317 SCIP_PARAM** params;
1318 int nparams;
1319 int p;
1320
1321 params = SCIPgetParams(scip);
1322 nparams = SCIPgetNParams(scip);
1323
1324 eventhdlrdata->nnondefaultparams = 0;
1325 eventhdlrdata->nondefaultparams = NULL;
1326 eventhdlrdata->nondefaultparamssize = 0;
1327
1328 /* loop over parameters and store the non-default ones */
1329 for( p = 0; p < nparams; ++p )
1330 {
1331 SCIP_PARAM* param = params[p];
1332
1333 /* collect parameter if it is nondefault */
1334 if( ! SCIPparamIsDefault(param) )
1335 {
1336 if( eventhdlrdata->nnondefaultparams == 0 )
1337 {
1338 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &eventhdlrdata->nondefaultparams, 8) );
1339 eventhdlrdata->nondefaultparamssize = 8;
1340 }
1341 else if( eventhdlrdata->nnondefaultparams == eventhdlrdata->nondefaultparamssize )
1342 {
1343 eventhdlrdata->nondefaultparamssize *= 2;
1344 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &eventhdlrdata->nondefaultparams, \
1345 eventhdlrdata->nnondefaultparams, eventhdlrdata->nondefaultparamssize) );
1346 }
1347
1348 eventhdlrdata->nondefaultparams[eventhdlrdata->nnondefaultparams++] = param;
1349 }
1350 }
1351
1352 return SCIP_OKAY;
1353}
1354
1355/** initialization method of event handler (called after problem was transformed) */
1356static
1357SCIP_DECL_EVENTINIT(eventInitSolvingphase)
1358{ /*lint --e{715}*/
1359 SCIP_EVENTHDLRDATA* eventhdlrdata;
1360
1361 assert(scip != NULL);
1362 assert(eventhdlr != NULL);
1363
1365
1366 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
1367 assert(eventhdlrdata != NULL);
1368
1369 /* initialize the solving phase */
1370 eventhdlrdata->solvingphase = SCIP_SOLVINGPHASE_UNINITIALIZED;
1371
1372 /* none of the transitions is reached yet */
1373 eventhdlrdata->phaseflags = SCIP_SOLVINGPHASEFLAG_NONE;
1374 eventhdlrdata->nnondefaultparams = 0;
1375 eventhdlrdata->nondefaultparams = NULL;
1376 eventhdlrdata->nondefaultparamssize = 0;
1377
1378 /* in test mode we only determine the phase without changing solver settings */
1379 if( eventhdlrdata->testmode )
1380 determineSolvingPhase(scip, eventhdlrdata);
1381 else if( eventhdlrdata->enabled )
1382 {
1383 /* collect non-default parameters */
1384 SCIP_CALL( collectNondefaultParams(scip, eventhdlrdata) );
1385
1386 SCIP_CALL( applySolvingPhase(scip, eventhdlrdata) );
1387 }
1388
1389 /* only start catching events if event handler is enabled or in test mode */
1390 if( eventhdlrdata->enabled || eventhdlrdata->testmode )
1391 {
1392 SCIP_CALL( SCIPcatchEvent(scip, EVENTHDLR_EVENT, eventhdlr, NULL, &eventhdlrdata->eventfilterpos) );
1393 }
1394
1395 /* reset solving regression */
1396 SCIPregressionReset(eventhdlrdata->regression);
1397 eventhdlrdata->lastx = SCIP_INVALID;
1398 eventhdlrdata->lasty = SCIP_INVALID;
1399
1400 return SCIP_OKAY;
1401}
1402/** deinitialization method of event handler (called before problem is freed) */
1403static
1404SCIP_DECL_EVENTEXIT(eventExitSolvingphase)
1405{
1406 SCIP_EVENTHDLRDATA* eventhdlrdata;
1407
1408 assert(scip != NULL);
1409 assert(eventhdlr != NULL);
1410
1412
1413 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
1414 assert(eventhdlrdata != NULL);
1415
1416 /* free collected, non-default parameters */
1417 SCIPfreeBlockMemoryArrayNull(scip, &eventhdlrdata->nondefaultparams, eventhdlrdata->nondefaultparamssize);
1418
1419 return SCIP_OKAY;
1420}
1421
1422
1423/** execution method of event handler */
1424static
1425SCIP_DECL_EVENTEXEC(eventExecSolvingphase)
1426{ /*lint --e{715}*/
1427 SCIP_EVENTHDLRDATA* eventhdlrdata;
1428 SCIP_EVENTTYPE eventtype;
1429
1430 assert(scip != NULL);
1431 assert(eventhdlr != NULL);
1432
1433 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
1434 assert(eventhdlrdata != NULL);
1435 eventtype = SCIPeventGetType(event);
1436 assert(eventtype & (EVENTHDLR_EVENT));
1438
1439 /* update data structures depending on the event */
1440 SCIP_CALL( updateDataStructures(scip, eventhdlrdata, eventtype) );
1441
1442 /* in test mode we only determine the phase without changing solver settings */
1443 if( eventhdlrdata->testmode )
1444 determineSolvingPhase(scip, eventhdlrdata);
1445 else
1446 {
1447 assert(eventhdlrdata->enabled);
1448 SCIP_CALL( applySolvingPhase(scip, eventhdlrdata) );
1449 }
1450
1451 /* update the bit field of reached transition criteria */
1452 testCriteria(scip, eventhdlrdata);
1453
1454 return SCIP_OKAY;
1455}
1456
1457/*
1458 * displays that come with this event handler
1459 */
1460
1461/* defines for the rank 1 node display */
1462#define DISP_NAME_NRANK1NODES "nrank1nodes"
1463#define DISP_DESC_NRANK1NODES "current number of rank1 nodes left"
1464#define DISP_HEAD_NRANK1NODES "rank1"
1465#define DISP_WIDT_NRANK1NODES 7
1466#define DISP_PRIO_NRANK1NODES 40000
1467#define DISP_POSI_NRANK1NODES 500
1468#define DISP_STRI_NRANK1NODES TRUE
1469
1470/** output method of display column to output file stream 'file' */
1471static
1472SCIP_DECL_DISPOUTPUT(dispOutputNRank1Nodes)
1473{
1474 assert(disp != NULL);
1475 assert(scip != NULL);
1476
1478
1479 /* ouput number of rank 1 nodes */
1481
1482 return SCIP_OKAY;
1483}
1484
1485/* display for the number of nodes below the current incumbent */
1486#define DISP_NAME_NNODESBELOWINC "nnodesbelowinc"
1487#define DISP_DESC_NNODESBELOWINC "current number of nodes with an estimate better than the current incumbent"
1488#define DISP_HEAD_NNODESBELOWINC "nbInc"
1489#define DISP_WIDT_NNODESBELOWINC 6
1490#define DISP_PRIO_NNODESBELOWINC 40000
1491#define DISP_POSI_NNODESBELOWINC 550
1492#define DISP_STRI_NNODESBELOWINC TRUE
1493
1494/** output method of display column to output file stream 'file' */
1495static
1496SCIP_DECL_DISPOUTPUT(dispOutputNnodesbelowinc)
1497{
1498 assert(disp != NULL);
1499 assert(scip != NULL);
1500
1502
1503 /* display the number of nodes with an estimate below the the current incumbent */
1505
1506 return SCIP_OKAY;
1507}
1508
1509/** creates event handler for Solvingphase event */
1511 SCIP* scip /**< SCIP data structure */
1512 )
1513{
1514 SCIP_EVENTHDLRDATA* eventhdlrdata;
1515 SCIP_EVENTHDLR* eventhdlr;
1516
1517 /* create solving phase event handler data */
1518 eventhdlrdata = NULL;
1519 SCIP_CALL( SCIPallocBlockMemory(scip, &eventhdlrdata) );
1520 assert(eventhdlrdata != NULL);
1521
1522 eventhdlrdata->feassetname = NULL;
1523 eventhdlrdata->improvesetname = NULL;
1524 eventhdlrdata->proofsetname = NULL;
1525
1526 eventhdlrdata->depthinfos = NULL;
1527 eventhdlrdata->maxdepth = 0;
1528 eventhdlrdata->eventfilterpos = -1;
1529
1530 /* create a regression */
1531 eventhdlrdata->regression = NULL;
1532 SCIP_CALL( SCIPregressionCreate(&eventhdlrdata->regression) );
1533
1534 eventhdlr = NULL;
1535
1536 /* include event handler into SCIP */
1538 eventExecSolvingphase, eventhdlrdata) );
1539 assert(eventhdlr != NULL);
1540
1541 /* include the new displays into scip */
1548
1549 /* set non fundamental callbacks via setter functions */
1551 SCIP_CALL( SCIPsetEventhdlrFree(scip, eventhdlr, eventFreeSolvingphase) );
1552 SCIP_CALL( SCIPsetEventhdlrInit(scip, eventhdlr, eventInitSolvingphase) );
1553 SCIP_CALL( SCIPsetEventhdlrExit(scip, eventhdlr, eventExitSolvingphase) );
1554 SCIP_CALL( SCIPsetEventhdlrInitsol(scip, eventhdlr, eventInitsolSolvingphase) );
1555 SCIP_CALL( SCIPsetEventhdlrExitsol(scip, eventhdlr, eventExitsolSolvingphase) );
1556
1557 /* add Solvingphase event handler parameters */
1558 SCIP_CALL( SCIPaddBoolParam(scip, EVENTHDLR_NAME "s/enabled", "is the event handler enabled?",
1559 &eventhdlrdata->enabled, FALSE, DEFAULT_ENABLED, NULL, NULL) );
1560
1561 SCIP_CALL( SCIPaddBoolParam(scip, EVENTHDLR_NAME "s/testmode", "should the event handler only determine phase transitions, suppressing settings changes?",
1562 &eventhdlrdata->testmode, FALSE, DEFAULT_TESTMODE, NULL, NULL) );
1563
1564 SCIP_CALL( SCIPaddStringParam(scip, EVENTHDLR_NAME "s/feassetname", "settings file for feasibility phase -- precedence over emphasis settings",
1565 &eventhdlrdata->feassetname, FALSE, DEFAULT_SETNAME, NULL, NULL) );
1566
1567 SCIP_CALL( SCIPaddStringParam(scip, EVENTHDLR_NAME "s/improvesetname", "settings file for improvement phase -- precedence over emphasis settings",
1568 &eventhdlrdata->improvesetname, FALSE, DEFAULT_SETNAME, NULL, NULL) );
1569
1570 SCIP_CALL( SCIPaddStringParam(scip, EVENTHDLR_NAME "s/proofsetname", "settings file for proof phase -- precedence over emphasis settings",
1571 &eventhdlrdata->proofsetname, FALSE, DEFAULT_SETNAME, NULL, NULL) );
1572
1573 SCIP_CALL( SCIPaddLongintParam(scip, EVENTHDLR_NAME "s/nodeoffset", "node offset for rank-1 and estimate transitions", &eventhdlrdata->nodeoffset,
1575 SCIP_CALL( SCIPaddBoolParam(scip, EVENTHDLR_NAME "s/fallback", "should the event handler fall back from optimal phase?",
1576 &eventhdlrdata->fallback, FALSE, DEFAULT_FALLBACK, NULL, NULL) );
1577 SCIP_CALL( SCIPaddCharParam(scip ,EVENTHDLR_NAME "s/transitionmethod",
1578 "transition method: Possible options are 'e'stimate,'l'ogarithmic regression,'o'ptimal-value based,'r'ank-1",
1579 &eventhdlrdata->transitionmethod, FALSE, DEFAULT_TRANSITIONMETHOD, TRANSITIONMETHODS, NULL, NULL) );
1580 SCIP_CALL( SCIPaddBoolParam(scip, EVENTHDLR_NAME "s/interruptoptimal",
1581 "should the event handler interrupt the solving process after optimal solution was found?",
1582 &eventhdlrdata->interruptoptimal, FALSE, DEFAULT_INTERRUPTOPTIMAL, NULL, NULL) );
1583
1584 SCIP_CALL( SCIPaddBoolParam(scip, EVENTHDLR_NAME "s/userestart1to2",
1585 "should a restart be applied between the feasibility and improvement phase?",
1586 &eventhdlrdata->userestart1to2, FALSE, DEFAULT_USERESTART1TO2, NULL, NULL) );
1587
1588 SCIP_CALL( SCIPaddBoolParam(scip, EVENTHDLR_NAME "s/userestart2to3",
1589 "should a restart be applied between the improvement and the proof phase?",
1590 &eventhdlrdata->userestart2to3, FALSE, DEFAULT_USERESTART2TO3, NULL, NULL) );
1591
1592 SCIP_CALL( SCIPaddRealParam(scip, EVENTHDLR_NAME "s/optimalvalue", "optimal solution value for problem",
1593 &eventhdlrdata->optimalvalue, FALSE, SCIP_INVALID, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
1594
1595 /* add parameter for logarithmic regression */
1596 SCIP_CALL( SCIPaddCharParam(scip, EVENTHDLR_NAME "s/xtype", "x-type for logarithmic regression - (t)ime, (n)odes, (l)p iterations",
1597 &eventhdlrdata->logregression_xtype, FALSE, DEFAULT_LOGREGRESSION_XTYPE, LOGREGRESSION_XTYPES, NULL, NULL) );
1598
1599 SCIP_CALL( SCIPaddBoolParam(scip, EVENTHDLR_NAME "s/useemphsettings",
1600 "should emphasis settings for the solving phases be used, or settings files?",
1601 &eventhdlrdata->useemphsettings, FALSE, DEFAULT_USEEMPHSETTINGS, NULL, NULL) );
1602
1603 return SCIP_OKAY;
1604}
1605
1606/** returns the current solving phase tracked by the solvingphase event handler */
1608 SCIP* scip /**< SCIP data structure */
1609 )
1610{
1611 SCIP_EVENTHDLR* eventhdlr;
1612 SCIP_EVENTHDLRDATA* eventhdlrdata;
1613
1614 assert(scip != NULL);
1615
1617 if( eventhdlr == NULL )
1619
1620 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
1621 assert(eventhdlrdata != NULL);
1622
1623 return eventhdlrdata->solvingphase;
1624}
1625
1626/** returns the bit field of reached transition criteria */
1628 SCIP* scip /**< SCIP data structure */
1629 )
1630{
1631 SCIP_EVENTHDLR* eventhdlr;
1632 SCIP_EVENTHDLRDATA* eventhdlrdata;
1633
1634 assert(scip != NULL);
1635
1637 if( eventhdlr == NULL )
1639
1640 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
1641 assert(eventhdlrdata != NULL);
1642
1643 return eventhdlrdata->phaseflags;
1644}
#define EVENTHDLR_NAME
SCIP_VAR ** x
#define EVENTHDLR_DESC
#define DEFAULT_ENABLED
#define NULL
Definition def.h:257
#define SCIP_Longint
Definition def.h:150
#define SCIP_REAL_MAX
Definition def.h:167
#define SCIP_INVALID
Definition def.h:187
#define SCIP_Bool
Definition def.h:100
#define MAX3(x, y, z)
Definition def.h:237
#define SCIP_STRINGEQ(name, reference, retcode)
Definition def.h:454
#define SCIP_Real
Definition def.h:165
#define TRUE
Definition def.h:102
#define FALSE
Definition def.h:103
#define MAX(x, y)
Definition def.h:229
#define SCIPABORT()
Definition def.h:336
#define SCIP_REAL_MIN
Definition def.h:168
#define REALABS(x)
Definition def.h:191
#define SCIP_LONGINT_MAX
Definition def.h:151
#define EPSZ(x, eps)
Definition def.h:197
#define SCIP_CALL(x)
Definition def.h:364
#define DEFAULT_USEEMPHSETTINGS
static SCIP_Bool checkRankOneTransition(SCIP *scip, SCIP_EVENTHDLRDATA *eventhdlrdata)
static SCIP_RETCODE releaseNodeInformation(SCIP *scip, SCIP_EVENTHDLRDATA *eventhdlrdata, SCIP_NODE *node)
#define DISP_PRIO_NNODESBELOWINC
#define DEFAULT_LOGREGRESSION_XTYPE
#define DISP_POSI_NRANK1NODES
#define DEFAULT_USERESTART1TO2
#define DEFAULT_INTERRUPTOPTIMAL
static SCIP_Bool transitionPhase3(SCIP *scip, SCIP_EVENTHDLRDATA *eventhdlrdata)
static SCIP_RETCODE applySolvingPhase(SCIP *scip, SCIP_EVENTHDLRDATA *eventhdlrdata)
#define DISP_DESC_NRANK1NODES
static SCIP_Bool checkEstimateCriterion(SCIP *scip, SCIP_EVENTHDLRDATA *eventhdlrdata)
SCIP_SOLVINGPHASEFLAG SCIPgetSolvingPhaseFlags(SCIP *scip)
static SCIP_RETCODE adaptSolverBehavior(SCIP *scip, SCIP_EVENTHDLRDATA *eventhdlrdata)
#define DISP_HEAD_NNODESBELOWINC
static SCIP_RETCODE addNodesInformation(SCIP *scip, SCIP_EVENTHDLRDATA *eventhdlrdata, SCIP_NODE **nodes, int nnodes)
#define EVENTHDLR_EVENT
#define DEFAULT_TESTMODE
#define LOGREGRESSION_XTYPES
static SCIP_Bool checkLogCriterion(SCIP *scip, SCIP_EVENTHDLRDATA *eventhdlrdata)
static void testCriteria(SCIP *scip, SCIP_EVENTHDLRDATA *eventhdlrdata)
#define DEFAULT_SETNAME
static int getNRank1Nodes(SCIP *scip)
static SCIP_Real getX(SCIP *scip, SCIP_EVENTHDLRDATA *eventhdlrdata)
#define DISP_NAME_NNODESBELOWINC
#define DISP_WIDT_NNODESBELOWINC
SCIP_SOLVINGPHASE SCIPgetSolvingPhase(SCIP *scip)
#define DEFAULT_NODEOFFSET
static SCIP_RETCODE collectNondefaultParams(SCIP *scip, SCIP_EVENTHDLRDATA *eventhdlrdata)
static void releaseNodeFromDepthInfo(SCIP *scip, SCIP_EVENTHDLRDATA *eventhdlrdata, SCIP_NODE *node)
static SCIP_RETCODE fixOrUnfixRelevantParameters(SCIP *scip, SCIP_EVENTHDLRDATA *eventhdlrdata, SCIP_Bool fix)
#define DEFAULT_FALLBACK
static void determineSolvingPhase(SCIP *scip, SCIP_EVENTHDLRDATA *eventhdlrdata)
#define DISP_HEAD_NRANK1NODES
#define DEFAULT_TRANSITIONMETHOD
#define DISP_STRI_NRANK1NODES
static int getNNodesBelowIncumbent(SCIP *scip)
static void removeNode(SCIP_NODE *node, SCIP_EVENTHDLRDATA *eventhdlrdata)
#define DISP_PRIO_NRANK1NODES
SCIP_RETCODE SCIPincludeEventHdlrSolvingphase(SCIP *scip)
struct DepthInfo DEPTHINFO
static SCIP_RETCODE changeEmphasisParameters(SCIP *scip, SCIP_EVENTHDLRDATA *eventhdlrdata)
#define DISP_WIDT_NRANK1NODES
static SCIP_RETCODE createDepthinfo(SCIP *scip, DEPTHINFO **depthinfo)
static int checkLeavesBelowIncumbent(SCIP *scip)
static SCIP_Real getCurrentRegressionTangentAxisIntercept(SCIP *scip, SCIP_EVENTHDLRDATA *eventhdlrdata)
#define DEFAULT_USERESTART2TO3
#define DISP_POSI_NNODESBELOWINC
#define DISP_NAME_NRANK1NODES
#define eventCopySolvingphase
#define DISP_DESC_NNODESBELOWINC
static SCIP_RETCODE updateLogRegression(SCIP *scip, SCIP_EVENTHDLRDATA *eventhdlrdata)
static SCIP_RETCODE freeDepthinfo(SCIP *scip, DEPTHINFO **depthinfo)
static SCIP_RETCODE recomputeNodeInformation(SCIP *scip, SCIP_EVENTHDLRDATA *eventhdlrdata)
#define DISP_STRI_NNODESBELOWINC
static SCIP_RETCODE updateDataStructures(SCIP *scip, SCIP_EVENTHDLRDATA *eventhdlrdata, SCIP_EVENTTYPE eventtype)
static SCIP_RETCODE ensureDepthInfoArraySize(SCIP *scip, SCIP_EVENTHDLRDATA *eventhdlrdata, SCIP_NODE *node)
static SCIP_RETCODE changeParametersUsingSettingsFiles(SCIP *scip, SCIP_EVENTHDLRDATA *eventhdlrdata)
static SCIP_Bool checkOptimalSolution(SCIP *scip, SCIP_EVENTHDLRDATA *eventhdlrdata)
#define TRANSITIONMETHODS
eventhdlr for solving phase dependent parameter adjustment
#define SCIP_SOLVINGPHASEFLAG_OPTIMAL
#define SCIP_SOLVINGPHASEFLAG_LOG
@ SCIP_SOLVINGPHASE_IMPROVEMENT
@ SCIP_SOLVINGPHASE_PROOF
@ SCIP_SOLVINGPHASE_FEASIBILITY
@ SCIP_SOLVINGPHASE_UNINITIALIZED
#define SCIP_SOLVINGPHASEFLAG_NONE
#define SCIP_SOLVINGPHASEFLAG_ESTIMATE
#define SCIP_SOLVINGPHASEFLAG_RANK1
uint8_t SCIP_SOLVINGPHASEFLAG
enum SCIP_SolvingPhase SCIP_SOLVINGPHASE
#define nnodes
Definition gastrans.c:74
SCIP_STAGE SCIPgetStage(SCIP *scip)
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
SCIP_MESSAGEHDLR * SCIPgetMessagehdlr(SCIP *scip)
#define SCIPdebugMsg
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
SCIP_RETCODE SCIPaddLongintParam(SCIP *scip, const char *name, const char *desc, SCIP_Longint *valueptr, SCIP_Bool isadvanced, SCIP_Longint defaultvalue, SCIP_Longint minvalue, SCIP_Longint maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:111
SCIP_RETCODE SCIPaddCharParam(SCIP *scip, const char *name, const char *desc, char *valueptr, SCIP_Bool isadvanced, char defaultvalue, const char *allowedvalues, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:167
int SCIPgetNParams(SCIP *scip)
SCIP_RETCODE SCIPaddStringParam(SCIP *scip, const char *name, const char *desc, char **valueptr, SCIP_Bool isadvanced, const char *defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:194
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:139
SCIP_RETCODE SCIPreadParams(SCIP *scip, const char *filename)
Definition scip_param.c:772
SCIP_RETCODE SCIPunfixParam(SCIP *scip, const char *name)
Definition scip_param.c:385
SCIP_RETCODE SCIPsetEmphasis(SCIP *scip, SCIP_PARAMEMPHASIS paramemphasis, SCIP_Bool quiet)
Definition scip_param.c:882
SCIP_PARAM ** SCIPgetParams(SCIP *scip)
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:57
SCIP_RETCODE SCIPfixParam(SCIP *scip, const char *name)
Definition scip_param.c:367
const char * SCIPdispGetName(SCIP_DISP *disp)
Definition disp.c:335
void SCIPdispInt(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, int val, int width)
Definition disp.c:627
SCIP_RETCODE SCIPincludeDisp(SCIP *scip, const char *name, const char *desc, const char *header, SCIP_DISPSTATUS dispstatus, SCIP_DECL_DISPCOPY((*dispcopy)), SCIP_DECL_DISPFREE((*dispfree)), SCIP_DECL_DISPINIT((*dispinit)), SCIP_DECL_DISPEXIT((*dispexit)), SCIP_DECL_DISPINITSOL((*dispinitsol)), SCIP_DECL_DISPEXITSOL((*dispexitsol)), SCIP_DECL_DISPOUTPUT((*dispoutput)), SCIP_DISPDATA *dispdata, int width, int priority, int position, SCIP_Bool stripline)
Definition scip_disp.c:55
SCIP_RETCODE SCIPsetEventhdlrFree(SCIP *scip, SCIP_EVENTHDLR *eventhdlr,)
Definition scip_event.c:157
SCIP_RETCODE SCIPsetEventhdlrInitsol(SCIP *scip, SCIP_EVENTHDLR *eventhdlr,)
Definition scip_event.c:199
SCIP_RETCODE SCIPsetEventhdlrCopy(SCIP *scip, SCIP_EVENTHDLR *eventhdlr,)
Definition scip_event.c:143
SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition scip_event.c:111
SCIP_RETCODE SCIPsetEventhdlrExit(SCIP *scip, SCIP_EVENTHDLR *eventhdlr,)
Definition scip_event.c:185
SCIP_EVENTHDLR * SCIPfindEventhdlr(SCIP *scip, const char *name)
Definition scip_event.c:241
SCIP_RETCODE SCIPsetEventhdlrExitsol(SCIP *scip, SCIP_EVENTHDLR *eventhdlr,)
Definition scip_event.c:213
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition event.c:396
SCIP_EVENTHDLRDATA * SCIPeventhdlrGetData(SCIP_EVENTHDLR *eventhdlr)
Definition event.c:406
SCIP_RETCODE SCIPsetEventhdlrInit(SCIP *scip, SCIP_EVENTHDLR *eventhdlr,)
Definition scip_event.c:171
void SCIPeventhdlrSetData(SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition event.c:416
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition event.c:1194
SCIP_RETCODE SCIPcatchEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition scip_event.c:293
SCIP_NODE * SCIPeventGetNode(SCIP_EVENT *event)
Definition event.c:1530
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition scip_mem.h:110
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition scip_mem.h:93
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition scip_mem.h:99
#define SCIPfreeBlockMemory(scip, ptr)
Definition scip_mem.h:108
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition scip_mem.h:111
#define SCIPallocBlockMemory(scip, ptr)
Definition scip_mem.h:89
SCIP_NODETYPE SCIPnodeGetType(SCIP_NODE *node)
Definition tree.c:8503
SCIP_Longint SCIPnodeGetNumber(SCIP_NODE *node)
Definition tree.c:8513
SCIP_Real SCIPnodeGetEstimate(SCIP_NODE *node)
Definition tree.c:8553
int SCIPnodeGetDepth(SCIP_NODE *node)
Definition tree.c:8523
int SCIPgetNSols(SCIP *scip)
Definition scip_sol.c:2887
SCIP_RETCODE SCIPrestartSolve(SCIP *scip)
SCIP_RETCODE SCIPinterruptSolve(SCIP *scip)
SCIP_Real SCIPgetPrimalbound(SCIP *scip)
SCIP_Real SCIPgetUpperbound(SCIP *scip)
SCIP_Longint SCIPgetNNodes(SCIP *scip)
SCIP_Real SCIPgetFirstPrimalBound(SCIP *scip)
SCIP_Longint SCIPgetNTotalNodes(SCIP *scip)
SCIP_Longint SCIPgetNDelayedCutoffs(SCIP *scip)
SCIP_Longint SCIPgetNLPIterations(SCIP *scip)
SCIP_Real SCIPgetSolvingTime(SCIP *scip)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
int SCIPgetNChildren(SCIP *scip)
Definition scip_tree.c:188
SCIP_RETCODE SCIPgetOpenNodesData(SCIP *scip, SCIP_NODE ***leaves, SCIP_NODE ***children, SCIP_NODE ***siblings, int *nleaves, int *nchildren, int *nsiblings)
Definition scip_tree.c:398
SCIP_RETCODE SCIPgetChildren(SCIP *scip, SCIP_NODE ***children, int *nchildren)
Definition scip_tree.c:164
int SCIPgetNNodesLeft(SCIP *scip)
Definition scip_tree.c:646
SCIP_RETCODE SCIPgetLeaves(SCIP *scip, SCIP_NODE ***leaves, int *nleaves)
Definition scip_tree.c:248
SCIP_RETCODE SCIPgetSiblings(SCIP *scip, SCIP_NODE ***siblings, int *nsiblings)
Definition scip_tree.c:206
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition scip_tree.c:91
void SCIPregressionRemoveObservation(SCIP_REGRESSION *regression, SCIP_Real x, SCIP_Real y)
Definition misc.c:353
void SCIPregressionAddObservation(SCIP_REGRESSION *regression, SCIP_Real x, SCIP_Real y)
Definition misc.c:385
SCIP_Real SCIPregressionGetIntercept(SCIP_REGRESSION *regression)
Definition misc.c:278
int SCIPregressionGetNObservations(SCIP_REGRESSION *regression)
Definition misc.c:258
void SCIPregressionFree(SCIP_REGRESSION **regression)
Definition misc.c:436
SCIP_RETCODE SCIPregressionCreate(SCIP_REGRESSION **regression)
Definition misc.c:420
void SCIPregressionReset(SCIP_REGRESSION *regression)
Definition misc.c:404
SCIP_Real SCIPregressionGetSlope(SCIP_REGRESSION *regression)
Definition misc.c:268
SCIP_Bool SCIPsortedvecFindPtr(void **ptrarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), void *val, int len, int *pos)
void SCIPsortedvecInsertPtr(void **ptrarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), void *keyval, int *len, int *pos)
void SCIPsortedvecDelPosPtr(void **ptrarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int pos, int *len)
return SCIP_OKAY
int c
int maxdepth
assert(minobj< SCIPgetCutoffbound(scip))
SCIP_Bool SCIPparamIsDefault(SCIP_PARAM *param)
Definition paramset.c:933
const char * SCIPparamGetName(SCIP_PARAM *param)
Definition paramset.c:656
SCIP_Bool SCIPparamIsFixed(SCIP_PARAM *param)
Definition paramset.c:696
public methods for displaying runtime statistics
public methods for managing events
public methods for message output
public data structures and miscellaneous methods
methods for sorting joint arrays of various types
public methods for handling parameter settings
public methods for branch and bound tree
public methods for display handler plugins
public methods for event handler plugins and event handlers
general public methods
public methods for memory management
public methods for message handling
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for solutions
public solving methods
public methods for querying solving statistics
public methods for timing
public methods for the branch-and-bound tree
SCIP_NODE ** minnodes
SCIP_Real minestimate
#define SCIP_DECL_DISPOUTPUT(x)
Definition type_disp.h:140
@ SCIP_DISPSTATUS_OFF
Definition type_disp.h:60
struct SCIP_Eventhdlr SCIP_EVENTHDLR
Definition type_event.h:159
#define SCIP_DECL_EVENTINITSOL(x)
Definition type_event.h:224
#define SCIP_DECL_EVENTEXIT(x)
Definition type_event.h:213
#define SCIP_EVENTTYPE_NODEFOCUSED
Definition type_event.h:93
struct SCIP_EventhdlrData SCIP_EVENTHDLRDATA
Definition type_event.h:160
#define SCIP_DECL_EVENTEXEC(x)
Definition type_event.h:259
#define SCIP_EVENTTYPE_NODEBRANCHED
Definition type_event.h:96
#define SCIP_DECL_EVENTCOPY(x)
Definition type_event.h:189
#define SCIP_DECL_EVENTINIT(x)
Definition type_event.h:205
#define SCIP_EVENTTYPE_BESTSOLFOUND
Definition type_event.h:106
#define SCIP_DECL_EVENTFREE(x)
Definition type_event.h:197
uint64_t SCIP_EVENTTYPE
Definition type_event.h:156
#define SCIP_DECL_EVENTEXITSOL(x)
Definition type_event.h:235
@ SCIP_VERBLEVEL_NORMAL
struct SCIP_Regression SCIP_REGRESSION
Definition type_misc.h:160
#define SCIP_DECL_SORTPTRCOMP(x)
Definition type_misc.h:189
@ SCIP_PARAMEMPHASIS_DEFAULT
@ SCIP_PARAMEMPHASIS_PHASEIMPROVE
@ SCIP_PARAMEMPHASIS_PHASEPROOF
@ SCIP_PARAMEMPHASIS_PHASEFEAS
struct SCIP_Param SCIP_PARAM
enum SCIP_ParamEmphasis SCIP_PARAMEMPHASIS
@ SCIP_INVALIDCALL
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
@ SCIP_STAGE_SOLVED
Definition type_set.h:54
@ SCIP_STAGE_SOLVING
Definition type_set.h:53
struct SCIP_Node SCIP_NODE
Definition type_tree.h:63
@ SCIP_NODETYPE_CHILD
Definition type_tree.h:44
@ SCIP_NODETYPE_SIBLING
Definition type_tree.h:43
@ SCIP_NODETYPE_LEAF
Definition type_tree.h:45