Scippy

SCIP

Solving Constraint Integer Programs

heur.c
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-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 heur.c
26 * @ingroup OTHER_CFILES
27 * @brief methods for primal heuristics
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/clock.h"
40#include "scip/paramset.h"
41#include "scip/primal.h"
42#include "scip/scip.h"
43#include "scip/heur.h"
44#include "scip/pub_message.h"
45#include "scip/pub_misc.h"
46#include "scip/misc.h"
47
48#include "scip/struct_heur.h"
49
50/** compares two heuristics w.r.t. to their delay positions and priorities */
52{ /*lint --e{715}*/
53 SCIP_HEUR* heur1 = (SCIP_HEUR*)elem1;
54 SCIP_HEUR* heur2 = (SCIP_HEUR*)elem2;
55
56 assert(heur1 != NULL);
57 assert(heur2 != NULL);
58
59 if( heur1->delaypos == heur2->delaypos )
60 if( heur1->priority != heur2->priority )
61 return heur2->priority - heur1->priority; /* prefer higher priorities */
62 else
63 return (strcmp(heur1->name, heur2->name)); /* tiebreaker */
64 else if( heur1->delaypos == -1 )
65 return +1; /* prefer delayed heuristics */
66 else if( heur2->delaypos == -1 )
67 return -1; /* prefer delayed heuristics */
68 else if( heur1->ncalls * heur1->freq > heur2->ncalls * heur2->freq )
69 return +1;
70 else if( heur1->ncalls * heur1->freq < heur2->ncalls * heur2->freq )
71 return -1;
72 else
73 return heur1->delaypos - heur2->delaypos; /* prefer lower delay positions */
74}
75
76/** compares two heuristics w.r.t. to their priority values */
77SCIP_DECL_SORTPTRCOMP(SCIPheurCompPriority)
78{
79 return SCIPheurGetPriority((SCIP_HEUR*)elem2) -
81}
82
83/** comparison method for sorting heuristics w.r.t. to their name */
84SCIP_DECL_SORTPTRCOMP(SCIPheurCompName)
85{
86 return strcmp(SCIPheurGetName((SCIP_HEUR*)elem1), SCIPheurGetName((SCIP_HEUR*)elem2));
87}
88
89/** method to call, when the priority of a heuristic was changed */
90static
91SCIP_DECL_PARAMCHGD(paramChgdHeurPriority)
92{ /*lint --e{715}*/
93 SCIP_PARAMDATA* paramdata;
94
95 paramdata = SCIPparamGetData(param);
96 assert(paramdata != NULL);
97
98 /* use SCIPsetHeurPriority() to mark the heuristics unsorted */
99 SCIP_CALL( SCIPsetHeurPriority(scip, (SCIP_HEUR*)paramdata, SCIPparamGetInt(param)) ); /*lint !e740*/
100
101 return SCIP_OKAY;
102}
103
104/** resets diving statistics */
105static
107 SCIP_DIVESETSTATS* divesetstats /**< dive set statistics */
108 )
109{
110 assert(divesetstats != NULL);
111
112 divesetstats->nlpiterations = 0L;
113 divesetstats->totaldepth = 0L;
114 divesetstats->totalsoldepth = 0L;
115 divesetstats->totalnnodes = 0L;
116 divesetstats->totalnbacktracks = 0L;
117 divesetstats->minsoldepth = INT_MAX;
118 divesetstats->maxsoldepth = -1;
119 divesetstats->mindepth = INT_MAX;
120 divesetstats->maxdepth = -1;
121 divesetstats->nlps = 0;
122 divesetstats->nsolsfound = 0;
123 divesetstats->nbestsolsfound = 0;
124 divesetstats->nconflictsfound = 0;
125 divesetstats->ncalls = 0;
126 divesetstats->nsolcalls = 0;
127}
128
129/* resets diving settings counters */
131 SCIP_DIVESET* diveset, /**< diveset to be reset */
132 SCIP_SET* set /**< global SCIP settings */
133 )
134{
135 int d;
136
137 assert(diveset != NULL);
138 assert(diveset->randnumgen != NULL);
139
140 /* reset diveset statistics for all contexts */
141 for( d = 0; d < 4; ++d )
142 {
143 resetDivesetStats(diveset->divesetstats[d]);
144 }
145
146 /* reset the random number generator */
148
149 return SCIP_OKAY;
150}
151
152/** update dive set statistics */
153static
155 SCIP_DIVESETSTATS* divesetstats, /**< dive set statistics */
156 int depth, /**< the depth reached this time */
157 int nprobingnodes, /**< the number of probing nodes explored this time */
158 int nbacktracks, /**< the number of backtracks during probing this time */
159 SCIP_Longint nsolsfound, /**< number of new solutions found this time */
160 SCIP_Longint nbestsolsfound, /**< number of new best solutions found this time */
161 SCIP_Longint nconflictsfound, /**< number of new conflicts found this time */
162 SCIP_Bool leavesol /**< has the diving heuristic reached a feasible leaf */
163 )
164{
165 divesetstats->totaldepth += depth;
166 divesetstats->mindepth = MIN(divesetstats->mindepth, depth);
167 divesetstats->maxdepth = MAX(divesetstats->maxdepth, depth);
168 divesetstats->totalnnodes += nprobingnodes;
169 divesetstats->totalnbacktracks += nbacktracks;
170 divesetstats->ncalls++;
171
172 /* update solution statistics only if a solution was found */
173 if( leavesol )
174 {
175 divesetstats->totalsoldepth += depth;
176 divesetstats->minsoldepth = MIN(divesetstats->minsoldepth, depth);
177 divesetstats->maxsoldepth = MAX(divesetstats->maxsoldepth, depth);
178 divesetstats->nsolcalls++;
179 }
180
181 divesetstats->nsolsfound += nsolsfound;
182 divesetstats->nbestsolsfound += nbestsolsfound;
183 divesetstats->nconflictsfound += nconflictsfound;
184}
185
186/** returns the dive set statistics for the given context */
187static
189 SCIP_DIVESET* diveset, /**< diveset to be reset */
190 SCIP_DIVECONTEXT divecontext /**< context for diving statistics */
191 )
192{
193 assert(diveset != NULL);
194 assert(divecontext == SCIP_DIVECONTEXT_ADAPTIVE ||
195 divecontext == SCIP_DIVECONTEXT_SINGLE ||
196 divecontext == SCIP_DIVECONTEXT_TOTAL ||
197 divecontext == SCIP_DIVECONTEXT_SCHEDULER );
198
199 return diveset->divesetstats[(int)divecontext];
200}
201
202/** update diveset statistics and global diveset statistics */
204 SCIP_DIVESET* diveset, /**< diveset to be reset */
205 SCIP_STAT* stat, /**< global SCIP statistics */
206 int depth, /**< the depth reached this time */
207 int nprobingnodes, /**< the number of probing nodes explored this time */
208 int nbacktracks, /**< the number of backtracks during probing this time */
209 SCIP_Longint nsolsfound, /**< number of new solutions found this time */
210 SCIP_Longint nbestsolsfound, /**< number of new best solutions found this time */
211 SCIP_Longint nconflictsfound, /**< number of new conflicts found this time */
212 SCIP_Bool leavesol, /**< has the diving heuristic reached a feasible leaf */
213 SCIP_DIVECONTEXT divecontext /**< context for diving statistics */
214 )
215{
216 int c;
217 SCIP_DIVECONTEXT updatecontexts[] = {SCIP_DIVECONTEXT_TOTAL, divecontext};
218
219 assert(diveset != NULL);
220 assert(divecontext == SCIP_DIVECONTEXT_ADAPTIVE || divecontext == SCIP_DIVECONTEXT_SINGLE
221 || divecontext == SCIP_DIVECONTEXT_SCHEDULER);
222
223 /* update statistics for total context and given context */
224 for( c = 0; c < 2; ++c )
225 {
226 updateDivesetstats(divesetGetStats(diveset, updatecontexts[c]), depth, nprobingnodes,
227 nbacktracks, nsolsfound, nbestsolsfound, nconflictsfound, leavesol);
228 }
229
230 stat->totaldivesetdepth += depth;
231 stat->ndivesetcalls++;
232}
233
234/** append diveset to heuristic array of divesets */
235static
237 SCIP_HEUR* heur, /**< the heuristic to which this dive setting belongs */
238 SCIP_DIVESET* diveset /**< pointer to the freshly created diveset */
239 )
240{
241 assert(heur != NULL);
242 assert(diveset != NULL);
243 assert(diveset->heur == NULL);
244
245 diveset->heur = heur;
246
247 if( heur->divesets == NULL )
248 {
249 assert(heur->ndivesets == 0);
251 }
252 else
253 {
254 assert(heur->ndivesets > 0);
255 SCIP_ALLOC( BMSreallocMemoryArray(&heur->divesets, heur->ndivesets + 1) ); /*lint !e776 I expect no overflow here */
256 }
257
258 /* append diveset to the end of the array */
259 heur->divesets[heur->ndivesets] = diveset;
260 heur->ndivesets++;
261
262 return SCIP_OKAY;
263}
264
265/** create a set of diving heuristic settings */
267 SCIP_DIVESET** divesetptr, /**< pointer to the freshly created diveset */
268 SCIP_HEUR* heur, /**< the heuristic to which this dive setting belongs */
269 const char* name, /**< name for the diveset, or NULL if the name of the heuristic should be used */
270 SCIP_SET* set, /**< global SCIP settings */
271 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
272 BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
273 SCIP_Real minreldepth, /**< minimal relative depth to start diving */
274 SCIP_Real maxreldepth, /**< maximal relative depth to start diving */
275 SCIP_Real maxlpiterquot, /**< maximal fraction of diving LP iterations compared to node LP iterations */
276 SCIP_Real maxdiveubquot, /**< maximal quotient (curlowerbound - lowerbound)/(cutoffbound - lowerbound)
277 * where diving is performed (0.0: no limit) */
278 SCIP_Real maxdiveavgquot, /**< maximal quotient (curlowerbound - lowerbound)/(avglowerbound - lowerbound)
279 * where diving is performed (0.0: no limit) */
280 SCIP_Real maxdiveubquotnosol, /**< maximal UBQUOT when no solution was found yet (0.0: no limit) */
281 SCIP_Real maxdiveavgquotnosol,/**< maximal AVGQUOT when no solution was found yet (0.0: no limit) */
282 SCIP_Real lpresolvedomchgquot,/**< percentage of immediate domain changes during probing to trigger LP resolve */
283 int lpsolvefreq, /**< LP solve frequency for (0: only if enough domain reductions are found by propagation)*/
284 int maxlpiterofs, /**< additional number of allowed LP iterations */
285 unsigned int initialseed, /**< initial seed for random number generation */
286 SCIP_Bool backtrack, /**< use one level of backtracking if infeasibility is encountered? */
287 SCIP_Bool onlylpbranchcands, /**< should only LP branching candidates be considered instead of the slower but
288 * more general constraint handler diving variable selection? */
289 SCIP_Bool ispublic, /**< is this dive set publicly available (ie., can be used by other primal heuristics?) */
290 SCIP_DIVETYPE divetypemask, /**< bit mask that represents the supported dive types by this dive set */
291 SCIP_DECL_DIVESETGETSCORE((*divesetgetscore)), /**< method for candidate score and rounding direction */
292 SCIP_DECL_DIVESETAVAILABLE((*divesetavailable)) /**< callback to check availability of dive set at the current stage, or NULL if always available */
293 )
294{
295 int c;
297 const char* divesetname;
298 SCIP_DIVESET* diveset;
299
300 assert(divesetptr != NULL);
301 assert(set != NULL);
302 assert(divesetgetscore != NULL);
303 assert(heur != NULL);
304 assert(blkmem != NULL);
305
306 SCIP_ALLOC( BMSallocBlockMemory(blkmem, divesetptr) );
307 diveset = *divesetptr;
308
309 /* allocate random number generator. Note that we must make explicit use of random seed initialization because
310 * we create the random number generator directly, not through the public SCIP API
311 */
312 diveset->initialseed = initialseed;
313
314 /* simply use 0 as initial seed, the seed is reset in SCIPdivesetReset, anyway */
315 SCIP_CALL( SCIPrandomCreate(&diveset->randnumgen, blkmem, 0) );
316
317 /* for convenience, the name gets inferred from the heuristic to which the diveset is added if no name is provided */
318 divesetname = (name == NULL ? SCIPheurGetName(heur) : name);
319 SCIP_ALLOC( BMSduplicateMemoryArray(&diveset->name, divesetname, strlen(divesetname)+1) );
320 diveset->heur = NULL;
321
322 /* scoring callbacks */
323 diveset->divesetgetscore = divesetgetscore;
324 diveset->divesetavailable = divesetavailable;
325
326 SCIP_CALL( heurAddDiveset(heur, diveset) );
327 diveset->sol = NULL;
328 diveset->divetypemask = divetypemask;
329 diveset->ispublic = ispublic;
330
331 /* allocate memory for diveset statistics */
332 for( c = 0; c < 4; ++c )
333 {
334 SCIP_DIVESETSTATS** divesetstatsptr = &diveset->divesetstats[c];
335 SCIP_ALLOC( BMSallocBlockMemory(blkmem, divesetstatsptr) );
336 }
337
338 SCIP_CALL( SCIPdivesetReset(diveset, set) );
339
340 /* add collection of diving heuristic specific parameters */
341 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/minreldepth", diveset->name);
342 SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem,
343 paramname, "minimal relative depth to start diving",
344 &diveset->minreldepth, TRUE, minreldepth, 0.0, 1.0, NULL, NULL) );
345
346 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxreldepth", diveset->name);
347 SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname,
348 "maximal relative depth to start diving",
349 &diveset->maxreldepth, TRUE, maxreldepth, 0.0, 1.0, NULL, NULL) );
350
351 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxlpiterquot", diveset->name);
352 SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem,
353 paramname,
354 "maximal fraction of diving LP iterations compared to node LP iterations",
355 &diveset->maxlpiterquot, FALSE, maxlpiterquot, 0.0, SCIP_REAL_MAX, NULL, NULL) );
356
357 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxlpiterofs", diveset->name);
358 SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem,
359 paramname,
360 "additional number of allowed LP iterations",
361 &diveset->maxlpiterofs, FALSE, maxlpiterofs, 0, INT_MAX, NULL, NULL) );
362
363 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxdiveubquot", diveset->name);
364 SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem,
365 paramname,
366 "maximal quotient (curlowerbound - lowerbound)/(cutoffbound - lowerbound) where diving is performed (0.0: no limit)",
367 &diveset->maxdiveubquot, TRUE, maxdiveubquot, 0.0, 1.0, NULL, NULL) );
368
369 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxdiveavgquot", diveset->name);
370 SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem,
371 paramname,
372 "maximal quotient (curlowerbound - lowerbound)/(avglowerbound - lowerbound) where diving is performed (0.0: no limit)",
373 &diveset->maxdiveavgquot, TRUE, maxdiveavgquot, 0.0, SCIP_REAL_MAX, NULL, NULL) );
374
375 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxdiveubquotnosol", diveset->name);
376 SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem,
377 paramname,
378 "maximal UBQUOT when no solution was found yet (0.0: no limit)",
379 &diveset->maxdiveubquotnosol, TRUE, maxdiveubquotnosol, 0.0, 1.0, NULL, NULL) );
380
381 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxdiveavgquotnosol", diveset->name);
382 SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem,
383 paramname,
384 "maximal AVGQUOT when no solution was found yet (0.0: no limit)",
385 &diveset->maxdiveavgquotnosol, TRUE, maxdiveavgquotnosol, 0.0, SCIP_REAL_MAX, NULL, NULL) );
386
387 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/backtrack", diveset->name);
388 SCIP_CALL( SCIPsetAddBoolParam(set, messagehdlr, blkmem,
389 paramname,
390 "use one level of backtracking if infeasibility is encountered?",
391 &diveset->backtrack, FALSE, backtrack, NULL, NULL) );
392
393 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/lpresolvedomchgquot", diveset->name);
394 SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname,
395 "percentage of immediate domain changes during probing to trigger LP resolve",
396 &diveset->lpresolvedomchgquot, FALSE, lpresolvedomchgquot, 0.0, SCIP_REAL_MAX, NULL, NULL) );
397
398 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/lpsolvefreq", diveset->name);
399 SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem,
400 paramname,
401 "LP solve frequency for diving heuristics (0: only after enough domain changes have been found)",
402 &diveset->lpsolvefreq, FALSE, lpsolvefreq, 0, INT_MAX,
403 NULL, NULL) );
404
405 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/onlylpbranchcands", diveset->name);
406 SCIP_CALL( SCIPsetAddBoolParam(set, messagehdlr, blkmem,
407 paramname,
408 "should only LP branching candidates be considered instead of the slower but "
409 "more general constraint handler diving variable selection?",
410 &diveset->onlylpbranchcands, FALSE, onlylpbranchcands, NULL, NULL) );
411
412 return SCIP_OKAY;
413}
414
415/** get the heuristic to which this diving setting belongs */
417 SCIP_DIVESET* diveset /**< diving settings */
418 )
419{
420 return diveset->heur;
421}
422
423/** get the working solution of this dive set */
425 SCIP_DIVESET* diveset /**< diving settings */
426 )
427{
428 assert(diveset != NULL);
429
430 return diveset->sol;
431}
432
433/** set the working solution for this dive set */
435 SCIP_DIVESET* diveset, /**< diving settings */
436 SCIP_SOL* sol /**< new working solution for this dive set, or NULL */
437 )
438{
439 assert(diveset != NULL);
440
441 diveset->sol = sol;
442}
443
444/** get the name of the dive set */
446 SCIP_DIVESET* diveset /**< diving settings */
447 )
448{
449 assert(diveset != NULL);
450
451 return diveset->name;
452}
453
454/** get the minimum relative depth of the diving settings */
456 SCIP_DIVESET* diveset /**< diving settings */
457 )
458{
459 return diveset->minreldepth;
460}
461
462/** get the maximum relative depth of the diving settings */
464 SCIP_DIVESET* diveset /**< diving settings */
465 )
466{
467 return diveset->maxreldepth;
468}
469
470/** get the number of successful runs of the diving settings */
472 SCIP_DIVESET* diveset, /**< diving settings */
473 SCIP_DIVECONTEXT divecontext /**< context for diving statistics */
474
475 )
476{
477 SCIP_DIVESETSTATS* divesetstats = divesetGetStats(diveset, divecontext);
478
479 assert(divesetstats != NULL);
480
481 return 10 * divesetstats->nbestsolsfound + divesetstats->nsolsfound;
482}
483
484/** get the number of calls to this dive set */
486 SCIP_DIVESET* diveset, /**< diving settings */
487 SCIP_DIVECONTEXT divecontext /**< context for diving statistics */
488 )
489{
490 SCIP_DIVESETSTATS* divesetstats = divesetGetStats(diveset, divecontext);
491
492 assert(divesetstats != NULL);
493
494 return divesetstats->ncalls;
495}
496
497/** get the number of calls successfully terminated at a feasible leaf node */
499 SCIP_DIVESET* diveset, /**< diving settings */
500 SCIP_DIVECONTEXT divecontext /**< context for diving statistics */
501 )
502{
503 SCIP_DIVESETSTATS* divesetstats = divesetGetStats(diveset, divecontext);
504
505 assert(diveset != NULL);
506
507 return divesetstats->nsolcalls;
508}
509
510/** get the minimum depth reached by this dive set */
512 SCIP_DIVESET* diveset, /**< diving settings */
513 SCIP_DIVECONTEXT divecontext /**< context for diving statistics */
514 )
515{
516 SCIP_DIVESETSTATS* divesetstats = divesetGetStats(diveset, divecontext);
517
518 assert(divesetstats != NULL);
519
520 return divesetstats->mindepth;
521}
522
523/** get the maximum depth reached by this dive set */
525 SCIP_DIVESET* diveset, /**< diving settings */
526 SCIP_DIVECONTEXT divecontext /**< context for diving statistics */
527 )
528{
529 SCIP_DIVESETSTATS* divesetstats = divesetGetStats(diveset, divecontext);
530
531 assert(divesetstats != NULL);
532
533 return divesetstats->maxdepth;
534}
535
536/** get the average depth this dive set reached during execution */
538 SCIP_DIVESET* diveset, /**< diving settings */
539 SCIP_DIVECONTEXT divecontext /**< context for diving statistics */
540 )
541{
542 SCIP_DIVESETSTATS* divesetstats = divesetGetStats(diveset, divecontext);
543
544 assert(divesetstats != NULL);
545
546 return (divesetstats->ncalls == 0 ? 0.0 : divesetstats->totaldepth / (SCIP_Real)divesetstats->ncalls);
547}
548
549/** get the minimum depth at which this dive set found a solution */
551 SCIP_DIVESET* diveset, /**< diving settings */
552 SCIP_DIVECONTEXT divecontext /**< context for diving statistics */
553 )
554{
555 SCIP_DIVESETSTATS* divesetstats = divesetGetStats(diveset, divecontext);
556
557 assert(divesetstats != NULL);
558
559 return divesetstats->minsoldepth;
560}
561
562/** get the maximum depth at which this dive set found a solution */
564 SCIP_DIVESET* diveset, /**< diving settings */
565 SCIP_DIVECONTEXT divecontext /**< context for diving statistics */
566 )
567{
568 SCIP_DIVESETSTATS* divesetstats = divesetGetStats(diveset, divecontext);
569
570 assert(divesetstats != NULL);
571
572 return divesetstats->maxsoldepth;
573}
574
575/** get the average depth at which this dive set found a solution */
577 SCIP_DIVESET* diveset, /**< diving settings */
578 SCIP_DIVECONTEXT divecontext /**< context for diving statistics */
579 )
580{
581 SCIP_DIVESETSTATS* divesetstats = divesetGetStats(diveset, divecontext);
582
583 assert(divesetstats != NULL);
584
585 return (divesetstats->nsolcalls == 0 ? 0.0 : divesetstats->totalsoldepth / (SCIP_Real)divesetstats->nsolcalls);
586}
587
588/** get the total number of LP iterations used by this dive set */
590 SCIP_DIVESET* diveset, /**< diving settings */
591 SCIP_DIVECONTEXT divecontext /**< context for diving statistics */
592 )
593{
594 SCIP_DIVESETSTATS* divesetstats = divesetGetStats(diveset, divecontext);
595
596 assert(divesetstats != NULL);
597
598 return divesetstats->nlpiterations;
599}
600
601/** get the total number of probing nodes used by this dive set */
603 SCIP_DIVESET* diveset, /**< diving settings */
604 SCIP_DIVECONTEXT divecontext /**< context for diving statistics */
605 )
606{
607 SCIP_DIVESETSTATS* divesetstats = divesetGetStats(diveset, divecontext);
608
609 assert(divesetstats != NULL);
610
611 return divesetstats->totalnnodes;
612}
613
614/** get the total number of backtracks performed by this dive set */
616 SCIP_DIVESET* diveset, /**< diving settings */
617 SCIP_DIVECONTEXT divecontext /**< context for diving statistics */
618 )
619{
620 SCIP_DIVESETSTATS* divesetstats = divesetGetStats(diveset, divecontext);
621
622 assert(divesetstats != NULL);
623
624 return divesetstats->totalnbacktracks;
625}
626
627/** get the total number of conflicts found by this dive set */
629 SCIP_DIVESET* diveset, /**< diving settings */
630 SCIP_DIVECONTEXT divecontext /**< context for diving statistics */
631 )
632{
633 SCIP_DIVESETSTATS* divesetstats = divesetGetStats(diveset, divecontext);
634
635 assert(divesetstats != NULL);
636
637 return divesetstats->nconflictsfound;
638}
639
640/** get the total number of solutions (leaf and rounded solutions) found by the dive set */
642 SCIP_DIVESET* diveset, /**< diving settings */
643 SCIP_DIVECONTEXT divecontext /**< context for diving statistics */
644 )
645{
646 SCIP_DIVESETSTATS* divesetstats = divesetGetStats(diveset, divecontext);
647
648 assert(divesetstats != NULL);
649
650 return divesetstats->nsolsfound;
651}
652
653
654/** get the maximum LP iterations quotient of the diving settings */
656 SCIP_DIVESET* diveset /**< diving settings */
657 )
658{
659 return diveset->maxlpiterquot;
660}
661
662/** get the maximum LP iterations offset of the diving settings */
664 SCIP_DIVESET* diveset /**< diving settings */
665 )
666{
667 return diveset->maxlpiterofs;
668}
669
670/** get the maximum upper bound quotient parameter of the diving settings if no solution is available */
672 SCIP_DIVESET* diveset /**< diving settings */
673 )
674{
675 return diveset->maxdiveubquotnosol;
676}
677
678/** get the average quotient parameter of the diving settings if no solution is available */
680 SCIP_DIVESET* diveset /**< diving settings */
681 )
682{
683 return diveset->maxdiveavgquotnosol;
684}
685/** get the maximum upper bound quotient parameter of the diving settings if an incumbent solution exists */
687 SCIP_DIVESET* diveset /**< diving settings */
688 )
689{
690 return diveset->maxdiveubquot;
691}
692
693/** get the average upper bound quotient parameter of the diving settings if an incumbent solution exists */
695 SCIP_DIVESET* diveset /**< diving settings */
696 )
697{
698 return diveset->maxdiveavgquot;
699}
700
701/** should backtracking be applied? */
703 SCIP_DIVESET* diveset /**< diving settings */
704 )
705{
706 return diveset->backtrack;
707}
708
709/** returns the LP solve frequency for diving LPs (0: dynamically based on number of intermediate domain reductions) */
711 SCIP_DIVESET* diveset /**< diving settings */
712 )
713{
714 assert(diveset != NULL);
715
716 return diveset->lpsolvefreq;
717}
718
719/** returns the random number generator of this \p diveset for tie-breaking */
721 SCIP_DIVESET* diveset /**< diving settings */
722 )
723{
724 assert(diveset != NULL);
725 assert(diveset->randnumgen != NULL);
726
727 return diveset->randnumgen;
728}
729
730/** returns the domain reduction quotient for triggering an immediate resolve of the diving LP (0.0: always resolve)*/
732 SCIP_DIVESET* diveset /**< diving settings */
733 )
734{
735 assert(diveset != NULL);
736
737 return diveset->lpresolvedomchgquot;
738}
739
740/** should only LP branching candidates be considered instead of the slower but
741 * more general constraint handler diving variable selection?
742 */
744 SCIP_DIVESET* diveset /**< diving settings */
745 )
746{
747 assert(diveset != NULL);
748
749 return diveset->onlylpbranchcands;
750}
751
752/** returns TRUE if dive set supports diving of the specified type */
754 SCIP_DIVESET* diveset, /**< diving settings */
755 SCIP_DIVETYPE divetype /**< bit mask that represents the supported dive types by this dive set */
756 )
757{
758 assert(diveset != NULL);
759
760 return (divetype & diveset->divetypemask);
761}
762
763/** is this dive set publicly available (ie., can be used by other primal heuristics?) */
765 SCIP_DIVESET* diveset /**< diving settings */
766 )
767{
768 assert(diveset != NULL);
769
770 return diveset->ispublic;
771}
772
773/** updates LP related diveset statistics */
774static
776 SCIP_DIVESETSTATS* divesetstats, /**< diving settings */
777 SCIP_Longint niterstoadd /**< additional number of LP iterations to be added */
778 )
779{
780 assert(divesetstats != NULL);
781
782 divesetstats->nlpiterations += niterstoadd;
783 divesetstats->nlps++;
784}
785
786/** update diveset LP statistics, should be called after every LP solved by this diving heuristic */
788 SCIP_DIVESET* diveset, /**< diving settings */
789 SCIP_STAT* stat, /**< global SCIP statistics */
790 SCIP_Longint niterstoadd, /**< additional number of LP iterations to be added */
791 SCIP_DIVECONTEXT divecontext /**< context for diving statistics */
792 )
793{
794 assert(diveset != NULL);
795 assert(divecontext == SCIP_DIVECONTEXT_ADAPTIVE || divecontext == SCIP_DIVECONTEXT_SINGLE
796 || divecontext == SCIP_DIVECONTEXT_SCHEDULER);
797
798 /* update statistics for total context and given context */
799 updateDivesetstatsLP(divesetGetStats(diveset, divecontext), niterstoadd);
801
802 stat->ndivesetlpiterations += niterstoadd;
803 stat->ndivesetlps++;
804}
805
806/** frees memory of a diveset */
807static
809 SCIP_DIVESET** divesetptr, /**< general diving settings */
810 BMS_BLKMEM* blkmem /**< block memory for parameter settings */
811 )
812{
813 int c;
814 SCIP_DIVESET* diveset = *divesetptr;
815
816 assert(diveset != NULL);
817 assert(diveset->name != NULL);
818 assert(diveset->randnumgen != NULL);
819
820 SCIPrandomFree(&diveset->randnumgen, blkmem);
821
822 /* free all diveset statistics */
823 for( c = 0; c < 4; ++c )
824 {
825 SCIP_DIVESETSTATS** divesetstatsptr = &diveset->divesetstats[c];
826 BMSfreeBlockMemory(blkmem, divesetstatsptr);
827 }
828
829 BMSfreeMemoryArray(&diveset->name);
830 BMSfreeBlockMemory(blkmem, divesetptr);
831}
832
833/** get the candidate score and preferred rounding direction for a candidate variable */
835 SCIP_DIVESET* diveset, /**< general diving settings */
836 SCIP_SET* set, /**< SCIP settings */
837 SCIP_DIVETYPE divetype, /**< the type of diving that should be applied */
838 SCIP_VAR* divecand, /**< the candidate for which the branching direction is requested */
839 SCIP_Real divecandsol, /**< LP solution value of the candidate */
840 SCIP_Real divecandfrac, /**< fractionality of the candidate */
841 SCIP_Real* candscore, /**< pointer to store the candidate score */
842 SCIP_Bool* roundup /**< pointer to store whether preferred direction for diving is upwards */
843 )
844{
845 assert(diveset->divesetgetscore != NULL);
846 assert(candscore != NULL);
847 assert(roundup != NULL);
848 assert(divecand != NULL);
849 assert(divetype & diveset->divetypemask);
850
851 SCIP_CALL( diveset->divesetgetscore(set->scip, diveset, divetype, divecand, divecandsol, divecandfrac,
852 candscore, roundup) );
853
854 return SCIP_OKAY;
855}
856
857/** check specific preconditions for diving, e.g., if an incumbent solution is available */
859 SCIP_DIVESET* diveset, /**< diving heuristic settings */
860 SCIP_SET* set, /**< SCIP settings */
861 SCIP_Bool* available /**< pointer to store if the diving can run at the current solving stage */
862 )
863{
864 assert(set != NULL);
865 assert(diveset != NULL);
866 assert(available != NULL);
867
868 if( diveset->divesetavailable == NULL )
869 *available = TRUE;
870 else
871 {
872 *available = FALSE;
873 SCIP_CALL( diveset->divesetavailable(set->scip, diveset, available) );
874 }
875
876 return SCIP_OKAY;
877}
878
879
880
881/** copies the given primal heuristic to a new scip */
883 SCIP_HEUR* heur, /**< primal heuristic */
884 SCIP_SET* set /**< SCIP_SET of SCIP to copy to */
885 )
886{
887 assert(heur != NULL);
888 assert(set != NULL);
889 assert(set->scip != NULL);
890
891 if( heur->heurcopy != NULL )
892 {
893 SCIPsetDebugMsg(set, "including heur %s in subscip %p\n", SCIPheurGetName(heur), (void*)set->scip);
894 SCIP_CALL( heur->heurcopy(set->scip, heur) );
895 }
896
897 return SCIP_OKAY;
898}
899
900/** internal method for creating a primal heuristic */
901static
903 SCIP_HEUR** heur, /**< pointer to primal heuristic data structure */
904 SCIP_SET* set, /**< global SCIP settings */
905 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
906 BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
907 const char* name, /**< name of primal heuristic */
908 const char* desc, /**< description of primal heuristic */
909 char dispchar, /**< display character of primal heuristic */
910 int priority, /**< priority of the primal heuristic */
911 int freq, /**< frequency for calling primal heuristic */
912 int freqofs, /**< frequency offset for calling primal heuristic */
913 int maxdepth, /**< maximal depth level to call heuristic at (-1: no limit) */
914 SCIP_HEURTIMING timingmask, /**< positions in the node solving loop where heuristic should be executed */
915 SCIP_Bool usessubscip, /**< does the heuristic use a secondary SCIP instance? */
916 SCIP_DECL_HEURCOPY ((*heurcopy)), /**< copy method of primal heuristic or NULL if you don't want to copy your plugin into sub-SCIPs */
917 SCIP_DECL_HEURFREE ((*heurfree)), /**< destructor of primal heuristic */
918 SCIP_DECL_HEURINIT ((*heurinit)), /**< initialize primal heuristic */
919 SCIP_DECL_HEUREXIT ((*heurexit)), /**< deinitialize primal heuristic */
920 SCIP_DECL_HEURINITSOL ((*heurinitsol)), /**< solving process initialization method of primal heuristic */
921 SCIP_DECL_HEUREXITSOL ((*heurexitsol)), /**< solving process deinitialization method of primal heuristic */
922 SCIP_DECL_HEUREXEC ((*heurexec)), /**< execution method of primal heuristic */
923 SCIP_HEURDATA* heurdata /**< primal heuristic data */
924 )
925{
927 char paramdesc[SCIP_MAXSTRLEN];
928
929 assert(heur != NULL);
930 assert(name != NULL);
931 assert(desc != NULL);
932 assert(freq >= -1);
933 assert(freqofs >= 0);
934 assert(heurexec != NULL);
935
936 SCIP_ALLOC( BMSallocMemory(heur) );
937 BMSclearMemory(*heur);
938
939 SCIP_ALLOC( BMSduplicateMemoryArray(&(*heur)->name, name, strlen(name)+1) );
940 SCIP_ALLOC( BMSduplicateMemoryArray(&(*heur)->desc, desc, strlen(desc)+1) );
941 (*heur)->dispchar = dispchar;
942 (*heur)->priority = priority;
943 (*heur)->freq = freq;
944 (*heur)->freqofs = freqofs;
945 (*heur)->maxdepth = maxdepth;
946 (*heur)->delaypos = -1;
947 (*heur)->timingmask = timingmask;
948 (*heur)->usessubscip = usessubscip;
949 (*heur)->heurcopy = heurcopy;
950 (*heur)->heurfree = heurfree;
951 (*heur)->heurinit = heurinit;
952 (*heur)->heurexit = heurexit;
953 (*heur)->heurinitsol = heurinitsol;
954 (*heur)->heurexitsol = heurexitsol;
955 (*heur)->heurexec = heurexec;
956 (*heur)->heurdata = heurdata;
957 SCIP_CALL( SCIPclockCreate(&(*heur)->setuptime, SCIP_CLOCKTYPE_DEFAULT) );
958 SCIP_CALL( SCIPclockCreate(&(*heur)->heurclock, SCIP_CLOCKTYPE_DEFAULT) );
959 (*heur)->ncalls = 0;
960 (*heur)->nsolsfound = 0;
961 (*heur)->nbestsolsfound = 0;
962 (*heur)->exact = FALSE;
963 (*heur)->initialized = FALSE;
964 (*heur)->divesets = NULL;
965 (*heur)->ndivesets = 0;
966
967 /* add parameters */
968 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/priority", name);
969 (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of heuristic <%s>", name);
970 SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
971 &(*heur)->priority, TRUE, priority, INT_MIN/4, INT_MAX/4,
972 paramChgdHeurPriority, (SCIP_PARAMDATA*)(*heur)) ); /*lint !e740*/
973 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/freq", name);
974 (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "frequency for calling primal heuristic <%s> (-1: never, 0: only at depth freqofs)", name);
975 SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
976 &(*heur)->freq, FALSE, freq, -1, SCIP_MAXTREEDEPTH, NULL, NULL) );
977 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/freqofs", name);
978 (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "frequency offset for calling primal heuristic <%s>", name);
979 SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
980 &(*heur)->freqofs, FALSE, freqofs, 0, SCIP_MAXTREEDEPTH, NULL, NULL) );
981 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxdepth", name);
982 (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "maximal depth level to call primal heuristic <%s> (-1: no limit)", name);
983 SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
984 &(*heur)->maxdepth, TRUE, maxdepth, -1, SCIP_MAXTREEDEPTH, NULL, NULL) );
985
986 return SCIP_OKAY;
987}
988
989/** creates a primal heuristic */
991 SCIP_HEUR** heur, /**< pointer to primal heuristic data structure */
992 SCIP_SET* set, /**< global SCIP settings */
993 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
994 BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
995 const char* name, /**< name of primal heuristic */
996 const char* desc, /**< description of primal heuristic */
997 char dispchar, /**< display character of primal heuristic */
998 int priority, /**< priority of the primal heuristic */
999 int freq, /**< frequency for calling primal heuristic */
1000 int freqofs, /**< frequency offset for calling primal heuristic */
1001 int maxdepth, /**< maximal depth level to call heuristic at (-1: no limit) */
1002 SCIP_HEURTIMING timingmask, /**< positions in the node solving loop where heuristic should be executed */
1003 SCIP_Bool usessubscip, /**< does the heuristic use a secondary SCIP instance? */
1004 SCIP_DECL_HEURCOPY ((*heurcopy)), /**< copy method of primal heuristic or NULL if you don't want to copy your plugin into sub-SCIPs */
1005 SCIP_DECL_HEURFREE ((*heurfree)), /**< destructor of primal heuristic */
1006 SCIP_DECL_HEURINIT ((*heurinit)), /**< initialize primal heuristic */
1007 SCIP_DECL_HEUREXIT ((*heurexit)), /**< deinitialize primal heuristic */
1008 SCIP_DECL_HEURINITSOL ((*heurinitsol)), /**< solving process initialization method of primal heuristic */
1009 SCIP_DECL_HEUREXITSOL ((*heurexitsol)), /**< solving process deinitialization method of primal heuristic */
1010 SCIP_DECL_HEUREXEC ((*heurexec)), /**< execution method of primal heuristic */
1011 SCIP_HEURDATA* heurdata /**< primal heuristic data */
1012 )
1013{
1014 assert(heur != NULL);
1015 assert(name != NULL);
1016 assert(desc != NULL);
1017 assert(freq >= -1);
1018 assert(freqofs >= 0);
1019 assert(heurexec != NULL);
1020
1021 SCIP_CALL_FINALLY( doHeurCreate(heur, set, messagehdlr, blkmem, name, desc, dispchar, priority, freq, freqofs,
1022 maxdepth, timingmask, usessubscip, heurcopy, heurfree, heurinit, heurexit, heurinitsol, heurexitsol, heurexec,
1023 heurdata), (void) SCIPheurFree(heur, set, blkmem) );
1024
1025 return SCIP_OKAY;
1026}
1027
1028/** calls destructor and frees memory of primal heuristic */
1030 SCIP_HEUR** heur, /**< pointer to primal heuristic data structure */
1031 SCIP_SET* set, /**< global SCIP settings */
1032 BMS_BLKMEM* blkmem /**< block memory */
1033 )
1034{
1035 int d;
1036 assert(heur != NULL);
1037 if( *heur == NULL )
1038 return SCIP_OKAY;
1039 assert(!(*heur)->initialized);
1040 assert(set != NULL);
1041 assert((*heur)->divesets != NULL || (*heur)->ndivesets == 0);
1042
1043 /* call destructor of primal heuristic */
1044 if( (*heur)->heurfree != NULL )
1045 {
1046 SCIP_CALL( (*heur)->heurfree(set->scip, *heur) );
1047 }
1048
1049 for( d = 0; d < (*heur)->ndivesets; ++d )
1050 {
1051 assert((*heur)->divesets[d] != NULL);
1052 divesetFree(&((*heur)->divesets[d]), blkmem);
1053 }
1054 BMSfreeMemoryArrayNull(&(*heur)->divesets);
1055 SCIPclockFree(&(*heur)->heurclock);
1056 SCIPclockFree(&(*heur)->setuptime);
1057 BMSfreeMemoryArrayNull(&(*heur)->name);
1058 BMSfreeMemoryArrayNull(&(*heur)->desc);
1059 BMSfreeMemory(heur);
1060
1061 return SCIP_OKAY;
1062}
1063
1064/** initializes primal heuristic */
1066 SCIP_HEUR* heur, /**< primal heuristic */
1067 SCIP_SET* set /**< global SCIP settings */
1068 )
1069{
1070 int d;
1071 assert(heur != NULL);
1072 assert(set != NULL);
1073
1074 if( heur->initialized )
1075 {
1076 SCIPerrorMessage("primal heuristic <%s> already initialized\n", heur->name);
1077 return SCIP_INVALIDCALL;
1078 }
1079
1080 if( set->misc_resetstat )
1081 {
1084
1085 heur->delaypos = -1;
1086 heur->ncalls = 0;
1087 heur->nsolsfound = 0;
1088 heur->nbestsolsfound = 0;
1089
1090 set->heurssorted = FALSE;
1091 set->heursnamesorted = FALSE;
1092 }
1093
1094 if( heur->heurinit != NULL )
1095 {
1096 /* start timing */
1098
1099 SCIP_CALL( heur->heurinit(set->scip, heur) );
1100
1101 /* stop timing */
1102 SCIPclockStop(heur->setuptime, set);
1103 }
1104
1105 /* reset dive sets */
1106 for( d = 0; d < heur->ndivesets; ++d )
1107 {
1108 assert(heur->divesets[d] != NULL);
1109 SCIP_CALL( SCIPdivesetReset(heur->divesets[d], set) );
1110 }
1111
1112 heur->initialized = TRUE;
1113
1114 return SCIP_OKAY;
1115}
1116
1117/** calls exit method of primal heuristic */
1119 SCIP_HEUR* heur, /**< primal heuristic */
1120 SCIP_SET* set /**< global SCIP settings */
1121 )
1122{
1123 assert(heur != NULL);
1124 assert(set != NULL);
1125
1126 if( !heur->initialized )
1127 {
1128 SCIPerrorMessage("primal heuristic <%s> not initialized\n", heur->name);
1129 return SCIP_INVALIDCALL;
1130 }
1131
1132 if( heur->heurexit != NULL )
1133 {
1134 /* start timing */
1136
1137 SCIP_CALL( heur->heurexit(set->scip, heur) );
1138
1139 /* stop timing */
1140 SCIPclockStop(heur->setuptime, set);
1141 }
1142 heur->initialized = FALSE;
1143
1144 return SCIP_OKAY;
1145}
1146
1147/** informs primal heuristic that the branch and bound process is being started */
1149 SCIP_HEUR* heur, /**< primal heuristic */
1150 SCIP_SET* set /**< global SCIP settings */
1151 )
1152{
1153 assert(heur != NULL);
1154 assert(set != NULL);
1155
1156 if( heur->delaypos != -1 )
1157 {
1158 heur->delaypos = -1;
1159 set->heurssorted = FALSE;
1160 }
1161
1162 /* call solving process initialization method of primal heuristic */
1163 if( heur->heurinitsol != NULL )
1164 {
1165 /* start timing */
1167
1168 SCIP_CALL( heur->heurinitsol(set->scip, heur) );
1169
1170 /* stop timing */
1171 SCIPclockStop(heur->setuptime, set);
1172 }
1173
1174 return SCIP_OKAY;
1175}
1176
1177/** informs primal heuristic that the branch and bound process data is being freed */
1179 SCIP_HEUR* heur, /**< primal heuristic */
1180 SCIP_SET* set /**< global SCIP settings */
1181 )
1182{
1183 assert(heur != NULL);
1184 assert(set != NULL);
1185
1186 /* call solving process deinitialization method of primal heuristic */
1187 if( heur->heurexitsol != NULL )
1188 {
1189 /* start timing */
1191
1192 SCIP_CALL( heur->heurexitsol(set->scip, heur) );
1193
1194 /* stop timing */
1195 SCIPclockStop(heur->setuptime, set);
1196 }
1197
1198 return SCIP_OKAY;
1199}
1200
1201/** should the heuristic be executed at the given depth, frequency, timing, ... */
1203 SCIP_HEUR* heur, /**< primal heuristic */
1204 int depth, /**< depth of current node */
1205 int lpstateforkdepth, /**< depth of the last node with solved LP */
1206 SCIP_HEURTIMING heurtiming, /**< current point in the node solving process */
1207 SCIP_Bool* delayed /**< pointer to store whether the heuristic should be delayed */
1208 )
1209{
1210 SCIP_Bool execute;
1211
1214 {
1215 /* heuristic may be executed before/during presolving. Do so, if it was not disabled by setting the frequency to -1 */
1216 execute = heur->freq >= 0;
1217 }
1218 else if( (heur->timingmask & SCIP_HEURTIMING_AFTERPSEUDONODE) == 0
1219 && (heurtiming == SCIP_HEURTIMING_AFTERLPNODE || heurtiming == SCIP_HEURTIMING_AFTERLPPLUNGE) )
1220 {
1221 /* heuristic was skipped on intermediate pseudo nodes: check, if a node matching the execution frequency lies
1222 * between the current node and the last LP node of the path
1223 */
1224 execute = (heur->freq > 0 && depth >= heur->freqofs
1225 && ((depth + heur->freq - heur->freqofs) / heur->freq
1226 != (lpstateforkdepth + heur->freq - heur->freqofs) / heur->freq));
1227 }
1228 else
1229 {
1230 /* heuristic may be executed on every node: check, if the current depth matches the execution frequency and offset */
1231 execute = (heur->freq > 0 && depth >= heur->freqofs && (depth - heur->freqofs) % heur->freq == 0);
1232 }
1233
1234 /* if frequency is zero, execute heuristic only at the depth level of the frequency offset */
1235 execute = execute || (depth == heur->freqofs && heur->freq == 0);
1236
1237 /* compare current depth against heuristic's maximal depth level */
1238 execute = execute && (heur->maxdepth == -1 || depth <= heur->maxdepth);
1239
1240 /* if the heuristic was delayed, execute it anyway */
1241 execute = execute || (heur->delaypos >= 0);
1242
1243 /* if the heuristic should be called after plunging but not during plunging, delay it if we are in plunging */
1244 if( execute
1245 && ((heurtiming == SCIP_HEURTIMING_AFTERLPNODE
1246 && (heur->timingmask & SCIP_HEURTIMING_AFTERLPNODE) == 0
1248 || (heurtiming == SCIP_HEURTIMING_AFTERPSEUDONODE
1251 {
1252 /* the heuristic should be delayed until plunging is finished */
1253 execute = FALSE;
1254 *delayed = TRUE;
1255 }
1256
1257 /* execute heuristic only if its timing mask fits the current point in the node solving process */
1258 execute = execute && (heur->timingmask & heurtiming) > 0;
1259
1260 return execute;
1261}
1262
1263/** calls execution method of primal heuristic */
1265 SCIP_HEUR* heur, /**< primal heuristic */
1266 SCIP_SET* set, /**< global SCIP settings */
1267 SCIP_PRIMAL* primal, /**< primal data */
1268 int depth, /**< depth of current node */
1269 int lpstateforkdepth, /**< depth of the last node with solved LP */
1270 SCIP_HEURTIMING heurtiming, /**< current point in the node solving process */
1271 SCIP_Bool nodeinfeasible, /**< was the current node already detected to be infeasible? */
1272 int* ndelayedheurs, /**< pointer to count the number of delayed heuristics */
1273 SCIP_RESULT* result /**< pointer to store the result of the callback method */
1274 )
1275{
1276 SCIP_Bool execute;
1277 SCIP_Bool delayed;
1278
1279 assert(heur != NULL);
1280 assert(heur->heurexec != NULL);
1281 assert(heur->freq >= -1);
1282 assert(heur->freqofs >= 0);
1283 assert(heur->maxdepth >= -1);
1284 assert(set != NULL);
1285 assert(set->scip != NULL);
1286 assert(primal != NULL);
1287 assert(depth >= 0 || heurtiming == SCIP_HEURTIMING_BEFOREPRESOL || heurtiming == SCIP_HEURTIMING_DURINGPRESOLLOOP);
1288 assert(ndelayedheurs != NULL);
1289 assert(result != NULL);
1290
1291 *result = SCIP_DIDNOTRUN;
1292
1293 if( set->exact_enable && !heur->exact )
1294 return SCIP_OKAY;
1295
1296 delayed = FALSE;
1297 execute = SCIPheurShouldBeExecuted(heur, depth, lpstateforkdepth, heurtiming, &delayed);
1298
1299 if( delayed )
1300 {
1301 assert(!execute);
1302 *result = SCIP_DELAYED;
1303 }
1304
1305 if( execute )
1306 {
1307 SCIP_Longint oldnsolsfound;
1308 SCIP_Longint oldnbestsolsfound;
1309
1310 SCIPsetDebugMsg(set, "executing primal heuristic <%s> in depth %d (delaypos: %d)\n", heur->name, depth, heur->delaypos);
1311
1312 oldnsolsfound = primal->nsolsfound;
1313 oldnbestsolsfound = primal->nbestsolsfound;
1314
1315 /* start timing */
1317
1318 /* call external method */
1319 SCIP_CALL( heur->heurexec(set->scip, heur, heurtiming, nodeinfeasible, result) );
1320
1321 /* stop timing */
1322 SCIPclockStop(heur->heurclock, set);
1323
1324 /* evaluate result */
1325 if( *result != SCIP_FOUNDSOL
1326 && *result != SCIP_DIDNOTFIND
1327 && *result != SCIP_DIDNOTRUN
1328 && *result != SCIP_DELAYED
1329 && *result != SCIP_UNBOUNDED )
1330 {
1331 SCIPerrorMessage("execution method of primal heuristic <%s> returned invalid result <%d>\n",
1332 heur->name, *result);
1333 return SCIP_INVALIDRESULT;
1334 }
1335 if( *result != SCIP_DIDNOTRUN && *result != SCIP_DELAYED )
1336 heur->ncalls++;
1337 heur->nsolsfound += primal->nsolsfound - oldnsolsfound;
1338 heur->nbestsolsfound += primal->nbestsolsfound - oldnbestsolsfound;
1339
1340 /* update delay position of heuristic */
1341 if( *result != SCIP_DELAYED && heur->delaypos != -1 )
1342 {
1343 heur->delaypos = -1;
1344 set->heurssorted = FALSE;
1345 }
1346 }
1347 assert(*result == SCIP_DIDNOTRUN || *result == SCIP_DELAYED || *result == SCIP_UNBOUNDED || heur->delaypos == -1);
1348
1349 /* check if the heuristic was (still) delayed */
1350 if( *result == SCIP_DELAYED || heur->delaypos >= 0 )
1351 {
1352 SCIPsetDebugMsg(set, "delaying execution of primal heuristic <%s> in depth %d (delaypos: %d), heur was%s delayed before, had delaypos %d\n",
1353 heur->name, depth, *ndelayedheurs, heur->delaypos >= 0 ? "" : " not", heur->delaypos);
1354
1355 /* mark the heuristic delayed */
1356 if( heur->delaypos != *ndelayedheurs )
1357 {
1358 heur->delaypos = *ndelayedheurs;
1359 set->heurssorted = FALSE;
1360 }
1361 (*ndelayedheurs)++;
1362 }
1363
1364 return SCIP_OKAY;
1365}
1366
1367/** gets user data of primal heuristic */
1369 SCIP_HEUR* heur /**< primal heuristic */
1370 )
1371{
1372 assert(heur != NULL);
1373
1374 return heur->heurdata;
1375}
1376
1377/** sets user data of primal heuristic; user has to free old data in advance! */
1379 SCIP_HEUR* heur, /**< primal heuristic */
1380 SCIP_HEURDATA* heurdata /**< new primal heuristic user data */
1381 )
1382{
1383 assert(heur != NULL);
1384
1385 heur->heurdata = heurdata;
1386}
1387
1388/* new callback setter methods */
1389
1390/** sets copy callback of primal heuristic */
1392 SCIP_HEUR* heur, /**< primal heuristic */
1393 SCIP_DECL_HEURCOPY ((*heurcopy)) /**< copy callback of primal heuristic or NULL if you don't want to copy your plugin into sub-SCIPs */
1394 )
1395{
1396 assert(heur != NULL);
1397
1398 heur->heurcopy = heurcopy;
1399}
1400
1401/** sets destructor callback of primal heuristic */
1403 SCIP_HEUR* heur, /**< primal heuristic */
1404 SCIP_DECL_HEURFREE ((*heurfree)) /**< destructor of primal heuristic */
1405 )
1406{
1407 assert(heur != NULL);
1408
1409 heur->heurfree = heurfree;
1410}
1411
1412/** sets initialization callback of primal heuristic */
1414 SCIP_HEUR* heur, /**< primal heuristic */
1415 SCIP_DECL_HEURINIT ((*heurinit)) /**< initialize primal heuristic */
1416 )
1417{
1418 assert(heur != NULL);
1419
1420 heur->heurinit = heurinit;
1421}
1422
1423/** sets deinitialization callback of primal heuristic */
1425 SCIP_HEUR* heur, /**< primal heuristic */
1426 SCIP_DECL_HEUREXIT ((*heurexit)) /**< deinitialize primal heuristic */
1427 )
1428{
1429 assert(heur != NULL);
1430
1431 heur->heurexit = heurexit;
1432}
1433
1434/** sets solving process initialization callback of primal heuristic */
1436 SCIP_HEUR* heur, /**< primal heuristic */
1437 SCIP_DECL_HEURINITSOL ((*heurinitsol)) /**< solving process initialization callback of primal heuristic */
1438 )
1439{
1440 assert(heur != NULL);
1441
1442 heur->heurinitsol = heurinitsol;
1443}
1444
1445/** sets solving process deinitialization callback of primal heuristic */
1447 SCIP_HEUR* heur, /**< primal heuristic */
1448 SCIP_DECL_HEUREXITSOL ((*heurexitsol)) /**< solving process deinitialization callback of primal heuristic */
1449 )
1450{
1451 assert(heur != NULL);
1452
1453 heur->heurexitsol = heurexitsol;
1454}
1455
1456/** marks the primal heuristic as safe to use in exact solving mode */
1458 SCIP_HEUR* heur /**< primal heuristic */
1459 )
1460{
1461 assert(heur != NULL);
1462
1463 heur->exact = TRUE;
1464}
1465
1466/** gets name of primal heuristic */
1468 SCIP_HEUR* heur /**< primal heuristic */
1469 )
1470{
1471 assert(heur != NULL);
1472
1473 return heur->name;
1474}
1475
1476/** gets description of primal heuristic */
1478 SCIP_HEUR* heur /**< primal heuristic */
1479 )
1480{
1481 assert(heur != NULL);
1482
1483 return heur->desc;
1484}
1485
1486/** gets display character of primal heuristic */
1488 SCIP_HEUR* heur /**< primal heuristic */
1489 )
1490{
1491 assert(heur != NULL);
1492
1493 return heur->dispchar;
1494}
1495
1496/** returns the timing mask of the heuristic */
1498 SCIP_HEUR* heur /**< primal heuristic */
1499 )
1500{
1501 assert(heur != NULL);
1502
1503 return heur->timingmask;
1504}
1505
1506/** sets new timing mask for heuristic */
1508 SCIP_HEUR* heur, /**< primal heuristic */
1509 SCIP_HEURTIMING timingmask /**< new timing mask of heuristic */
1510 )
1511{
1512 assert(heur != NULL);
1513
1514 heur->timingmask = timingmask;
1515}
1516
1517/** does the heuristic use a secondary SCIP instance? */
1519 SCIP_HEUR* heur /**< primal heuristic */
1520 )
1521{
1522 assert(heur != NULL);
1523
1524 return heur->usessubscip;
1525}
1526
1527/** gets priority of primal heuristic */
1529 SCIP_HEUR* heur /**< primal heuristic */
1530 )
1531{
1532 assert(heur != NULL);
1533
1534 return heur->priority;
1535}
1536
1537/** sets priority of primal heuristic */
1539 SCIP_HEUR* heur, /**< primal heuristic */
1540 SCIP_SET* set, /**< global SCIP settings */
1541 int priority /**< new priority of the primal heuristic */
1542 )
1543{
1544 assert(heur != NULL);
1545 assert(set != NULL);
1546
1547 heur->priority = priority;
1548 set->heurssorted = FALSE;
1549}
1550
1551/** gets frequency of primal heuristic */
1553 SCIP_HEUR* heur /**< primal heuristic */
1554 )
1555{
1556 assert(heur != NULL);
1557
1558 return heur->freq;
1559}
1560
1561/** sets frequency of primal heuristic */
1563 SCIP_HEUR* heur, /**< primal heuristic */
1564 int freq /**< new frequency of heuristic */
1565 )
1566{
1567 assert(heur != NULL);
1568
1569 heur->freq = freq;
1570}
1571
1572/** gets frequency offset of primal heuristic */
1574 SCIP_HEUR* heur /**< primal heuristic */
1575 )
1576{
1577 assert(heur != NULL);
1578
1579 return heur->freqofs;
1580}
1581
1582/** gets maximal depth level for calling primal heuristic (returns -1, if no depth limit exists) */
1584 SCIP_HEUR* heur /**< primal heuristic */
1585 )
1586{
1587 assert(heur != NULL);
1588
1589 return heur->maxdepth;
1590}
1591
1592/** gets the number of times, the heuristic was called and tried to find a solution */
1594 SCIP_HEUR* heur /**< primal heuristic */
1595 )
1596{
1597 assert(heur != NULL);
1598
1599 return heur->ncalls;
1600}
1601
1602/** gets the number of primal feasible solutions found by this heuristic */
1604 SCIP_HEUR* heur /**< primal heuristic */
1605 )
1606{
1607 assert(heur != NULL);
1608
1609 return heur->nsolsfound;
1610}
1611
1612/** gets the number of new best primal feasible solutions found by this heuristic */
1614 SCIP_HEUR* heur /**< primal heuristic */
1615 )
1616{
1617 assert(heur != NULL);
1618
1619 return heur->nbestsolsfound;
1620}
1621
1622/** is primal heuristic initialized? */
1624 SCIP_HEUR* heur /**< primal heuristic */
1625 )
1626{
1627 assert(heur != NULL);
1628
1629 return heur->initialized;
1630}
1631
1632/** enables or disables all clocks of \p heur, depending on the value of the flag */
1634 SCIP_HEUR* heur, /**< the heuristic for which all clocks should be enabled or disabled */
1635 SCIP_Bool enable /**< should the clocks of the heuristic be enabled? */
1636 )
1637{
1638 assert(heur != NULL);
1639
1640 SCIPclockEnableOrDisable(heur->setuptime, enable);
1641 SCIPclockEnableOrDisable(heur->heurclock, enable);
1642}
1643
1644/** gets time in seconds used in this heuristic for setting up for next stages */
1646 SCIP_HEUR* heur /**< primal heuristic */
1647 )
1648{
1649 assert(heur != NULL);
1650
1651 return SCIPclockGetTime(heur->setuptime);
1652}
1653
1654/** gets time in seconds used in this heuristic */
1656 SCIP_HEUR* heur /**< primal heuristic */
1657 )
1658{
1659 assert(heur != NULL);
1660
1661 return SCIPclockGetTime(heur->heurclock);
1662}
1663
1664/** returns array of divesets of this primal heuristic, or NULL if it has no divesets */
1666 SCIP_HEUR* heur /**< primal heuristic */
1667 )
1668{
1669 assert(heur != NULL);
1670
1671 return heur->divesets;
1672}
1673
1674/** returns the number of divesets of this primal heuristic */
1676 SCIP_HEUR* heur /**< primal heuristic */
1677 )
1678{
1679 assert(heur != NULL);
1680
1681 return heur->ndivesets;
1682}
1683
1684/** Perform breadth-first (BFS) search on the variable constraint graph.
1685 *
1686 * The result of the algorithm is that the \p distances array contains the correct distances for
1687 * every variable from the start variables. The distance of a variable can then be accessed through its
1688 * problem index (calling SCIPvarGetProbindex()).
1689 * Hence, The method assumes that the length of \p distances is at least
1690 * SCIPgetNVars().
1691 * Variables that are not connected through constraints to the start variables have a distance of -1.
1692 *
1693 * Limits can be provided to further restrict the breadth-first search. If a distance limit is given,
1694 * the search will be performed until the first variable at this distance is popped from the queue, i.e.,
1695 * all variables with a distance < maxdistance have been labeled by the search.
1696 * If a variable limit is given, the search stops after it completes the distance level at which
1697 * the limit was reached. Hence, more variables may be actually labeled.
1698 * The start variables are accounted for those variable limits.
1699 *
1700 * If no variable variable constraint graph is provided, the method will create one and free it at the end
1701 * This is useful for a single use of the variable constraint graph. For several consecutive uses,
1702 * it is advised to create a variable constraint graph via SCIPvariableGraphCreate().
1703 */
1705 SCIP* scip, /**< SCIP data structure */
1706 SCIP_VGRAPH* vargraph, /**< pointer to the variable graph, or NULL to let the function create a local graph */
1707 SCIP_VAR** startvars, /**< array of start variables to calculate distance from */
1708 int nstartvars, /**< number of starting variables, at least 1 */
1709 int* distances, /**< array to keep distance in vargraph from start variables for every variable */
1710 int maxdistance, /**< maximum distance >= 0 from start variable (INT_MAX for complete BFS) */
1711 int maxvars, /**< maximum number of variables to compute distance for */
1712 int maxbinintvars /**< maximum number of binary or integer variables to compute distance for */
1713 )
1714{
1715 SCIP_VAR** vars;
1716 SCIP_VAR** varbuffer;
1717 int* queue;
1718 SCIP_Bool localvargraph;
1719 int nvars;
1720 int nbinintvars;
1721 int currlvlidx;
1722 int nextlvlidx;
1723 int increment = 1;
1724 int currentdistance;
1725 int nbinintvarshit;
1726 int nvarshit;
1727 int i;
1728
1729 assert(scip != NULL);
1730 assert(startvars != NULL);
1731 assert(nstartvars >= 1);
1732 assert(distances != NULL);
1733 assert(maxdistance >= 0);
1734
1735 /* get variable data */
1736 vars = SCIPgetVars(scip);
1737 nvars = SCIPgetNVars(scip);
1738
1739 if( nvars == 0 )
1740 return SCIP_OKAY;
1741
1742 nbinintvars = nvars - SCIPgetNContVars(scip) - SCIPgetNContImplVars(scip);
1743 assert(nbinintvars >= 0);
1744
1745 SCIP_CALL( SCIPallocBufferArray(scip, &queue, nvars) );
1746 SCIP_CALL( SCIPallocClearBufferArray(scip, &varbuffer, nvars) );
1747
1748 /* create a variable graph locally for this method, if none is provided */
1749 if( vargraph == NULL )
1750 {
1751 SCIP_CALL( SCIPvariableGraphCreate(scip, &vargraph, FALSE, 1.0, NULL) );
1752 assert(vargraph != NULL);
1753 localvargraph = TRUE;
1754 }
1755 else
1756 localvargraph = FALSE;
1757
1758 /* coverity[var_deref_op] */
1760
1761 /* initialize distances to -1 */
1762 for( i = 0; i < nvars; ++i )
1763 {
1764 queue[i] = -1;
1765 distances[i] = -1;
1766 }
1767
1768 nvarshit = 0;
1769 nbinintvarshit = 0;
1770 /* initialize distances for starting variables and add them to the queue */
1771 for( i = 0; i < nstartvars; ++i )
1772 {
1773 int probindex = SCIPvarGetProbindex(startvars[i]);
1774 assert(probindex >= 0);
1775 /* start variables have a distance of 0 */
1776 distances[probindex] = 0;
1777 queue[i] = probindex;
1778 nvarshit++;
1779
1780 if( probindex < nbinintvars )
1781 nbinintvarshit++;
1782 }
1783 currlvlidx = 0;
1784 nextlvlidx = nvars - 1;
1785
1786 /* loop over the queue and pop the next variable, starting with start variables */
1787 do
1788 {
1789 SCIP_VAR* currvar;
1790 int c;
1791 int varpos;
1792
1793 currvar = vars[queue[currlvlidx]];
1794 varpos = SCIPvarGetProbindex(currvar);
1795 currentdistance = distances[varpos];
1796 assert(currentdistance >= 0);
1797
1798 /* distances must only be computed up to maxdistance */
1799 assert(currentdistance <= maxdistance);
1800
1801 /* check for termination because maximum distance has been reached */
1802 if( currentdistance == maxdistance )
1803 break;
1804
1805 assert(varpos >= 0);
1806
1807 /* loop over variable constraints and enqueue variables that were not visited yet */
1808 for( c = 0; c < vargraph->nvarconss[varpos]; ++c )
1809 {
1810 int nconsvars;
1811 int v;
1812 SCIP_Bool success;
1813 SCIP_CONS* cons = vargraph->varconss[varpos][c];
1814
1815 /* check first if this constraint has already been visited */
1816 if( SCIPhashtableExists(vargraph->visitedconss, (void *)cons) )
1817 continue;
1818
1819 /* request number of constraint variables */
1820 SCIP_CALL( SCIPgetConsNVars(scip, cons, &nconsvars, &success) );
1821
1822 if( !success )
1823 continue;
1824
1825 /* collect constraint variables in buffer */
1826 SCIP_CALL( SCIPgetConsVars(scip, cons, varbuffer, nvars, &success) );
1827
1828 if( !success )
1829 continue;
1830
1831 /* collect previously unvisited variables of the constraint and enqueue them for breadth-first search */
1832 for( v = 0; v < nconsvars; ++v )
1833 {
1834 SCIP_VAR* nextvar = varbuffer[v];
1835 int nextvarpos;
1836 assert(nextvar != NULL);
1837 if( !SCIPvarIsActive(nextvar) )
1838 continue;
1839
1840 nextvarpos = SCIPvarGetProbindex(nextvar);
1841 assert(nextvarpos >= 0);
1842
1843 /* insert variables that were not considered yet into the next level queue */
1844 if( distances[nextvarpos] == -1 )
1845 {
1846 distances[nextvarpos] = currentdistance + 1;
1847 queue[nextlvlidx] = nextvarpos;
1848 nextlvlidx -= increment;
1849
1850 nvarshit++;
1851 if( nextvarpos < nbinintvars )
1852 ++nbinintvarshit;
1853 }
1854 } /* end constraint variables loop */
1855
1856 /* mark the constraint as visited */
1857 SCIP_CALL( SCIPhashtableInsert(vargraph->visitedconss, (void *)cons) );
1858 } /* end constraint loop */
1859
1860 queue[currlvlidx] = -1;
1861 currlvlidx += increment;
1862
1863 /* check if we need to swap current and next level index and reverse the increment */
1864 if( currlvlidx == nvars || currlvlidx == 0 || queue[currlvlidx] == -1 || currlvlidx == nextlvlidx )
1865 {
1866 /* break early if the distance has been determined for enough variables */
1867 if( nvarshit >= maxvars || nbinintvarshit >= maxbinintvars )
1868 break;
1869
1870 /* increment knows whether we are currently looping upwards (all variables with odd distance) or downwards the
1871 * queue
1872 */
1873 if( increment == +1 )
1874 {
1875 currlvlidx = nvars - 1;
1876 nextlvlidx = 0;
1877 increment = -1;
1878 }
1879 else
1880 {
1881 currlvlidx = 0;
1882 nextlvlidx = nvars - 1;
1883 increment = +1;
1884 }
1885 }
1886 }
1887 while( queue[currlvlidx] != -1 && distances[queue[currlvlidx]] >= currentdistance );
1888
1889 SCIPfreeBufferArray(scip, &varbuffer);
1890 SCIPfreeBufferArray(scip, &queue);
1891
1892 /* free also the variable graph, if it wasn't provided by the caller */
1893 if( localvargraph )
1894 {
1895 SCIPvariableGraphFree(scip, &vargraph);
1896 }
1897
1898 return SCIP_OKAY;
1899}
1900
1901/* fills variable graph data structure
1902 *
1903 * loops over global problem constraints and creates a mapping from the variables to their respective constraints
1904 */
1905static
1907 SCIP* scip, /**< SCIP data structure */
1908 SCIP_VGRAPH* vargraph, /**< variable graph data structure for breadth-first-search neighborhoods */
1909 SCIP_Bool relaxdenseconss, /**< should dense constraints (at least as dense as \p density) be
1910 * ignored by connectivity graph? */
1911 SCIP_Real relaxdensity, /**< density (with respect to number of variables) to relax constraint from graph */
1912 int* nrelaxedconstraints /**< pointer to store the number of constraints that were relaxed, or NULL if not needed */
1913 )
1914{
1915 SCIP_CONS** conss;
1916 int nconss;
1917 int nvars;
1918 int c;
1919 int relaxlimit;
1920 SCIP_VAR** varbuffer;
1921
1922 assert(scip != NULL);
1923 assert(vargraph != NULL);
1924
1925 conss = SCIPgetConss(scip);
1926 nconss = SCIPgetNConss(scip);
1927
1928 nvars = SCIPgetNVars(scip);
1929 SCIP_CALL( SCIPallocBufferArray(scip, &varbuffer, nvars) );
1930
1931 if( nrelaxedconstraints != NULL )
1932 *nrelaxedconstraints = 0;
1933
1934 relaxlimit = (int)(relaxdensity * nvars);
1935
1936 for( c = 0; c < nconss; ++c )
1937 {
1938 int nconsvars;
1939 int v;
1940 SCIP_Bool success;
1941 SCIP_CONS* cons = conss[c];
1942
1943 /* we only consider constraints that are checkable */
1944 if( !SCIPconsIsChecked(cons) )
1945 continue;
1946
1947 /* request number of variables */
1948 SCIP_CALL( SCIPgetConsNVars(scip, cons, &nconsvars, &success) );
1949
1950 if( !success )
1951 continue;
1952
1953 /* relax constraints with density above the allowed number of free variables */
1954 if( relaxdenseconss && nconsvars >= relaxlimit )
1955 {
1956 if( nrelaxedconstraints != NULL )
1957 ++(*nrelaxedconstraints);
1958
1959 continue;
1960 }
1961
1962 /* collect constraint variables in buffer */
1963 SCIP_CALL( SCIPgetConsVars(scip, cons, varbuffer, nvars, &success) );
1964
1965 if( !success )
1966 continue;
1967
1968 /* loop over constraint variables and add this constraint to them if they are active */
1969 for( v = 0; v < nconsvars; ++v )
1970 {
1971 int varpos = SCIPvarGetProbindex(varbuffer[v]);
1972
1973 /* skip inactive variables */
1974 if( varpos == -1 )
1975 continue;
1976
1977 /* ensure array size */
1978 if( vargraph->varconssize[varpos] == vargraph->nvarconss[varpos] )
1979 {
1980 int newmem = SCIPcalcMemGrowSize(scip, vargraph->nvarconss[varpos] + 1);
1981
1982 assert(newmem > vargraph->varconssize[varpos]);
1983
1984 if( vargraph->varconss[varpos] == NULL )
1985 {
1986 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &vargraph->varconss[varpos], newmem) );
1987 }
1988 else
1989 {
1990 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &vargraph->varconss[varpos], vargraph->varconssize[varpos], newmem) ); /*lint !e866*/
1991 }
1992 vargraph->varconssize[varpos] = newmem;
1993 }
1994
1995 assert(vargraph->nvarconss[varpos] < vargraph->varconssize[varpos]);
1996
1997 /* add constraint to constraint array for this variable */
1998 vargraph->varconss[varpos][vargraph->nvarconss[varpos]] = cons;
1999 vargraph->nvarconss[varpos] += 1;
2000 }
2001 }
2002
2003 /* free the buffer */
2004 SCIPfreeBufferArray(scip, &varbuffer);
2005
2006 return SCIP_OKAY;
2007}
2008
2009/** initialization method of variable graph data structure */
2011 SCIP* scip, /**< SCIP data structure */
2012 SCIP_VGRAPH** vargraph, /**< pointer to the variable graph */
2013 SCIP_Bool relaxdenseconss, /**< should dense constraints (at least as dense as \p density) be
2014 * ignored by connectivity graph? */
2015 SCIP_Real relaxdensity, /**< density (with respect to number of variables) to relax constraint from graph */
2016 int* nrelaxedconstraints /**< pointer to store the number of constraints that were relaxed, or NULL if not needed */
2017 )
2018{
2019 int nvars;
2020 int nconss;
2021
2022 assert(scip != NULL);
2023 assert(vargraph != NULL);
2024
2025 nvars = SCIPgetNVars(scip);
2026 nconss = SCIPgetNConss(scip);
2027
2028 if( nvars == 0 )
2029 return SCIP_OKAY;
2030
2031 SCIP_CALL( SCIPallocBlockMemory(scip, vargraph) );
2032
2033 SCIP_CALL( SCIPhashtableCreate(&(*vargraph)->visitedconss, SCIPblkmem(scip), 2 * nconss, SCIPhashGetKeyStandard,
2034 SCIPhashKeyEqPtr, SCIPhashKeyValPtr, NULL) );
2035
2036 /* allocate and clear memory */
2037 SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &(*vargraph)->varconss, nvars) );
2038 SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &(*vargraph)->nvarconss, nvars) );
2039 SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &(*vargraph)->varconssize, nvars) );
2040
2041 /* fill the variable graph with variable-constraint mapping for breadth-first search*/
2042 SCIP_CALL( fillVariableGraph(scip, *vargraph, relaxdenseconss, relaxdensity, nrelaxedconstraints) );
2043
2044 return SCIP_OKAY;
2045}
2046
2047/** deinitialization method of variable graph data structure */
2049 SCIP* scip, /**< SCIP data structure */
2050 SCIP_VGRAPH** vargraph /**< pointer to the variable graph */
2051 )
2052{
2053 int nvars;
2054 int v;
2055 assert(scip != NULL);
2056 assert(vargraph != NULL);
2057
2058 nvars = SCIPgetNVars(scip);
2059
2060 for( v = nvars - 1; v >= 0; --v )
2061 {
2062 SCIPfreeBlockMemoryArrayNull(scip, &(*vargraph)->varconss[v], (*vargraph)->varconssize[v]); /*lint !e866*/
2063 }
2064
2065 /* allocate and clear memory */
2066 SCIPfreeBlockMemoryArray(scip, &(*vargraph)->varconssize, nvars);
2067 SCIPfreeBlockMemoryArray(scip, &(*vargraph)->nvarconss, nvars);
2068 SCIPfreeBlockMemoryArray(scip, &(*vargraph)->varconss, nvars);
2069
2070 SCIPhashtableFree(&(*vargraph)->visitedconss);
2071
2072 SCIPfreeBlockMemory(scip, vargraph);
2073}
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_REAL_MAX
Definition: def.h:158
#define SCIP_Bool
Definition: def.h:91
#define MIN(x, y)
Definition: def.h:224
#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 MAX(x, y)
Definition: def.h:220
#define SCIP_CALL(x)
Definition: def.h:355
#define SCIP_CALL_FINALLY(x, y)
Definition: def.h:397
int SCIPgetNContVars(SCIP *scip)
Definition: scip_prob.c:2569
SCIP_CONS ** SCIPgetConss(SCIP *scip)
Definition: scip_prob.c:3666
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:2246
int SCIPgetNConss(SCIP *scip)
Definition: scip_prob.c:3620
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:2201
int SCIPgetNContImplVars(SCIP *scip)
Definition: scip_prob.c:2522
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
Definition: misc.c:2348
SCIP_Bool SCIPhashtableExists(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2647
SCIP_RETCODE SCIPhashtableCreate(SCIP_HASHTABLE **hashtable, BMS_BLKMEM *blkmem, int tablesize, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr)
Definition: misc.c:2298
void SCIPhashtableRemoveAll(SCIP_HASHTABLE *hashtable)
Definition: misc.c:2743
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2535
SCIP_RETCODE SCIPgetConsNVars(SCIP *scip, SCIP_CONS *cons, int *nvars, SCIP_Bool *success)
Definition: scip_cons.c:2621
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:8588
SCIP_RETCODE SCIPgetConsVars(SCIP *scip, SCIP_CONS *cons, SCIP_VAR **vars, int varssize, SCIP_Bool *success)
Definition: scip_cons.c:2577
SCIP_Real SCIPdivesetGetMaxLPIterQuot(SCIP_DIVESET *diveset)
Definition: heur.c:655
SCIP_Bool SCIPdivesetIsPublic(SCIP_DIVESET *diveset)
Definition: heur.c:764
SCIP_Real SCIPdivesetGetUbQuotNoSol(SCIP_DIVESET *diveset)
Definition: heur.c:671
SCIP_Real SCIPdivesetGetMaxRelDepth(SCIP_DIVESET *diveset)
Definition: heur.c:463
SCIP_Longint SCIPdivesetGetNBacktracks(SCIP_DIVESET *diveset, SCIP_DIVECONTEXT divecontext)
Definition: heur.c:615
SCIP_Longint SCIPdivesetGetNSols(SCIP_DIVESET *diveset, SCIP_DIVECONTEXT divecontext)
Definition: heur.c:641
int SCIPdivesetGetMaxSolutionDepth(SCIP_DIVESET *diveset, SCIP_DIVECONTEXT divecontext)
Definition: heur.c:563
SCIP_Longint SCIPdivesetGetNConflicts(SCIP_DIVESET *diveset, SCIP_DIVECONTEXT divecontext)
Definition: heur.c:628
SCIP_Real SCIPdivesetGetAvgQuot(SCIP_DIVESET *diveset)
Definition: heur.c:694
SCIP_Bool SCIPdivesetUseBacktrack(SCIP_DIVESET *diveset)
Definition: heur.c:702
int SCIPdivesetGetLPSolveFreq(SCIP_DIVESET *diveset)
Definition: heur.c:710
SCIP_Real SCIPdivesetGetMinRelDepth(SCIP_DIVESET *diveset)
Definition: heur.c:455
SCIP_Real SCIPdivesetGetUbQuot(SCIP_DIVESET *diveset)
Definition: heur.c:686
SCIP_Real SCIPdivesetGetAvgSolutionDepth(SCIP_DIVESET *diveset, SCIP_DIVECONTEXT divecontext)
Definition: heur.c:576
int SCIPdivesetGetMaxDepth(SCIP_DIVESET *diveset, SCIP_DIVECONTEXT divecontext)
Definition: heur.c:524
int SCIPdivesetGetMinDepth(SCIP_DIVESET *diveset, SCIP_DIVECONTEXT divecontext)
Definition: heur.c:511
SCIP_Bool SCIPdivesetSupportsType(SCIP_DIVESET *diveset, SCIP_DIVETYPE divetype)
Definition: heur.c:753
SCIP_Real SCIPdivesetGetAvgDepth(SCIP_DIVESET *diveset, SCIP_DIVECONTEXT divecontext)
Definition: heur.c:537
SCIP_Bool SCIPdivesetUseOnlyLPBranchcands(SCIP_DIVESET *diveset)
Definition: heur.c:743
SCIP_Longint SCIPdivesetGetNLPIterations(SCIP_DIVESET *diveset, SCIP_DIVECONTEXT divecontext)
Definition: heur.c:589
SCIP_Longint SCIPdivesetGetSolSuccess(SCIP_DIVESET *diveset, SCIP_DIVECONTEXT divecontext)
Definition: heur.c:471
int SCIPdivesetGetMinSolutionDepth(SCIP_DIVESET *diveset, SCIP_DIVECONTEXT divecontext)
Definition: heur.c:550
const char * SCIPdivesetGetName(SCIP_DIVESET *diveset)
Definition: heur.c:445
int SCIPdivesetGetNCalls(SCIP_DIVESET *diveset, SCIP_DIVECONTEXT divecontext)
Definition: heur.c:485
SCIP_Real SCIPdivesetGetAvgQuotNoSol(SCIP_DIVESET *diveset)
Definition: heur.c:679
SCIP_RANDNUMGEN * SCIPdivesetGetRandnumgen(SCIP_DIVESET *diveset)
Definition: heur.c:720
SCIP_Longint SCIPdivesetGetNProbingNodes(SCIP_DIVESET *diveset, SCIP_DIVECONTEXT divecontext)
Definition: heur.c:602
SCIP_Real SCIPdivesetGetLPResolveDomChgQuot(SCIP_DIVESET *diveset)
Definition: heur.c:731
int SCIPdivesetGetNSolutionCalls(SCIP_DIVESET *diveset, SCIP_DIVECONTEXT divecontext)
Definition: heur.c:498
int SCIPdivesetGetMaxLPIterOffset(SCIP_DIVESET *diveset)
Definition: heur.c:663
SCIP_RETCODE SCIPsetHeurPriority(SCIP *scip, SCIP_HEUR *heur, int priority)
Definition: scip_heur.c:298
char SCIPheurGetDispchar(SCIP_HEUR *heur)
Definition: heur.c:1487
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition: heur.c:1368
SCIP_HEURTIMING SCIPheurGetTimingmask(SCIP_HEUR *heur)
Definition: heur.c:1497
const char * SCIPheurGetDesc(SCIP_HEUR *heur)
Definition: heur.c:1477
SCIP_Longint SCIPheurGetNSolsFound(SCIP_HEUR *heur)
Definition: heur.c:1603
int SCIPheurGetPriority(SCIP_HEUR *heur)
Definition: heur.c:1528
SCIP_Bool SCIPheurUsesSubscip(SCIP_HEUR *heur)
Definition: heur.c:1518
SCIP_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
Definition: heur.c:1613
void SCIPheurSetFreq(SCIP_HEUR *heur, int freq)
Definition: heur.c:1562
void SCIPheurSetTimingmask(SCIP_HEUR *heur, SCIP_HEURTIMING timingmask)
Definition: heur.c:1507
SCIP_Longint SCIPheurGetNCalls(SCIP_HEUR *heur)
Definition: heur.c:1593
int SCIPheurGetFreqofs(SCIP_HEUR *heur)
Definition: heur.c:1573
SCIP_DECL_SORTPTRCOMP(SCIPheurComp)
Definition: heur.c:51
SCIP_Real SCIPheurGetSetupTime(SCIP_HEUR *heur)
Definition: heur.c:1645
int SCIPheurGetMaxdepth(SCIP_HEUR *heur)
Definition: heur.c:1583
int SCIPheurGetNDivesets(SCIP_HEUR *heur)
Definition: heur.c:1675
void SCIPheurMarkExact(SCIP_HEUR *heur)
Definition: heur.c:1457
int SCIPheurGetFreq(SCIP_HEUR *heur)
Definition: heur.c:1552
SCIP_Real SCIPheurGetTime(SCIP_HEUR *heur)
Definition: heur.c:1655
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition: heur.c:1467
SCIP_Bool SCIPheurIsInitialized(SCIP_HEUR *heur)
Definition: heur.c:1623
SCIP_DIVESET ** SCIPheurGetDivesets(SCIP_HEUR *heur)
Definition: heur.c:1665
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition: heur.c:1378
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:110
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:57
#define SCIPallocClearBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:97
#define SCIPallocClearBufferArray(scip, ptr, num)
Definition: scip_mem.h:126
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:139
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
#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
void SCIPvariableGraphFree(SCIP *scip, SCIP_VGRAPH **vargraph)
Definition: heur.c:2048
SCIP_RETCODE SCIPvariablegraphBreadthFirst(SCIP *scip, SCIP_VGRAPH *vargraph, SCIP_VAR **startvars, int nstartvars, int *distances, int maxdistance, int maxvars, int maxbinintvars)
Definition: heur.c:1704
SCIP_RETCODE SCIPvariableGraphCreate(SCIP *scip, SCIP_VGRAPH **vargraph, SCIP_Bool relaxdenseconss, SCIP_Real relaxdensity, int *nrelaxedconstraints)
Definition: heur.c:2010
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:23642
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:23662
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10827
void SCIPheurSetCopy(SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
Definition: heur.c:1391
void SCIPheurSetInitsol(SCIP_HEUR *heur, SCIP_DECL_HEURINITSOL((*heurinitsol)))
Definition: heur.c:1435
SCIP_RETCODE SCIPdivesetCreate(SCIP_DIVESET **divesetptr, SCIP_HEUR *heur, const char *name, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, SCIP_Real minreldepth, SCIP_Real maxreldepth, SCIP_Real maxlpiterquot, SCIP_Real maxdiveubquot, SCIP_Real maxdiveavgquot, SCIP_Real maxdiveubquotnosol, SCIP_Real maxdiveavgquotnosol, SCIP_Real lpresolvedomchgquot, int lpsolvefreq, int maxlpiterofs, unsigned int initialseed, SCIP_Bool backtrack, SCIP_Bool onlylpbranchcands, SCIP_Bool ispublic, SCIP_DIVETYPE divetypemask, SCIP_DECL_DIVESETGETSCORE((*divesetgetscore)), SCIP_DECL_DIVESETAVAILABLE((*divesetavailable)))
Definition: heur.c:266
void SCIPheurEnableOrDisableClocks(SCIP_HEUR *heur, SCIP_Bool enable)
Definition: heur.c:1633
SCIP_RETCODE SCIPdivesetIsAvailable(SCIP_DIVESET *diveset, SCIP_SET *set, SCIP_Bool *available)
Definition: heur.c:858
void SCIPheurSetFree(SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
Definition: heur.c:1402
void SCIPheurSetPriority(SCIP_HEUR *heur, SCIP_SET *set, int priority)
Definition: heur.c:1538
SCIP_RETCODE SCIPheurInit(SCIP_HEUR *heur, SCIP_SET *set)
Definition: heur.c:1065
static SCIP_RETCODE heurAddDiveset(SCIP_HEUR *heur, SCIP_DIVESET *diveset)
Definition: heur.c:236
SCIP_RETCODE SCIPdivesetReset(SCIP_DIVESET *diveset, SCIP_SET *set)
Definition: heur.c:130
void SCIPdivesetUpdateLPStats(SCIP_DIVESET *diveset, SCIP_STAT *stat, SCIP_Longint niterstoadd, SCIP_DIVECONTEXT divecontext)
Definition: heur.c:787
static void divesetFree(SCIP_DIVESET **divesetptr, BMS_BLKMEM *blkmem)
Definition: heur.c:808
static SCIP_DIVESETSTATS * divesetGetStats(SCIP_DIVESET *diveset, SCIP_DIVECONTEXT divecontext)
Definition: heur.c:188
void SCIPheurSetInit(SCIP_HEUR *heur, SCIP_DECL_HEURINIT((*heurinit)))
Definition: heur.c:1413
static SCIP_RETCODE doHeurCreate(SCIP_HEUR **heur, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEURCOPY((*heurcopy)), SCIP_DECL_HEURFREE((*heurfree)), SCIP_DECL_HEURINIT((*heurinit)), SCIP_DECL_HEUREXIT((*heurexit)), SCIP_DECL_HEURINITSOL((*heurinitsol)), SCIP_DECL_HEUREXITSOL((*heurexitsol)), SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
Definition: heur.c:902
SCIP_RETCODE SCIPheurExec(SCIP_HEUR *heur, SCIP_SET *set, SCIP_PRIMAL *primal, int depth, int lpstateforkdepth, SCIP_HEURTIMING heurtiming, SCIP_Bool nodeinfeasible, int *ndelayedheurs, SCIP_RESULT *result)
Definition: heur.c:1264
static void resetDivesetStats(SCIP_DIVESETSTATS *divesetstats)
Definition: heur.c:106
SCIP_RETCODE SCIPheurCreate(SCIP_HEUR **heur, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEURCOPY((*heurcopy)), SCIP_DECL_HEURFREE((*heurfree)), SCIP_DECL_HEURINIT((*heurinit)), SCIP_DECL_HEUREXIT((*heurexit)), SCIP_DECL_HEURINITSOL((*heurinitsol)), SCIP_DECL_HEUREXITSOL((*heurexitsol)), SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
Definition: heur.c:990
SCIP_RETCODE SCIPheurCopyInclude(SCIP_HEUR *heur, SCIP_SET *set)
Definition: heur.c:882
void SCIPheurSetExitsol(SCIP_HEUR *heur, SCIP_DECL_HEUREXITSOL((*heurexitsol)))
Definition: heur.c:1446
void SCIPheurSetExit(SCIP_HEUR *heur, SCIP_DECL_HEUREXIT((*heurexit)))
Definition: heur.c:1424
void SCIPdivesetUpdateStats(SCIP_DIVESET *diveset, SCIP_STAT *stat, int depth, int nprobingnodes, int nbacktracks, SCIP_Longint nsolsfound, SCIP_Longint nbestsolsfound, SCIP_Longint nconflictsfound, SCIP_Bool leavesol, SCIP_DIVECONTEXT divecontext)
Definition: heur.c:203
SCIP_RETCODE SCIPheurInitsol(SCIP_HEUR *heur, SCIP_SET *set)
Definition: heur.c:1148
SCIP_RETCODE SCIPheurExitsol(SCIP_HEUR *heur, SCIP_SET *set)
Definition: heur.c:1178
static void updateDivesetstats(SCIP_DIVESETSTATS *divesetstats, int depth, int nprobingnodes, int nbacktracks, SCIP_Longint nsolsfound, SCIP_Longint nbestsolsfound, SCIP_Longint nconflictsfound, SCIP_Bool leavesol)
Definition: heur.c:154
SCIP_Bool SCIPheurShouldBeExecuted(SCIP_HEUR *heur, int depth, int lpstateforkdepth, SCIP_HEURTIMING heurtiming, SCIP_Bool *delayed)
Definition: heur.c:1202
SCIP_HEUR * SCIPdivesetGetHeur(SCIP_DIVESET *diveset)
Definition: heur.c:416
SCIP_SOL * SCIPdivesetGetWorkSolution(SCIP_DIVESET *diveset)
Definition: heur.c:424
SCIP_RETCODE SCIPdivesetGetScore(SCIP_DIVESET *diveset, SCIP_SET *set, SCIP_DIVETYPE divetype, SCIP_VAR *divecand, SCIP_Real divecandsol, SCIP_Real divecandfrac, SCIP_Real *candscore, SCIP_Bool *roundup)
Definition: heur.c:834
void SCIPdivesetSetWorkSolution(SCIP_DIVESET *diveset, SCIP_SOL *sol)
Definition: heur.c:434
static SCIP_DECL_PARAMCHGD(paramChgdHeurPriority)
Definition: heur.c:91
static void updateDivesetstatsLP(SCIP_DIVESETSTATS *divesetstats, SCIP_Longint niterstoadd)
Definition: heur.c:775
static SCIP_RETCODE fillVariableGraph(SCIP *scip, SCIP_VGRAPH *vargraph, SCIP_Bool relaxdenseconss, SCIP_Real relaxdensity, int *nrelaxedconstraints)
Definition: heur.c:1906
SCIP_RETCODE SCIPheurFree(SCIP_HEUR **heur, SCIP_SET *set, BMS_BLKMEM *blkmem)
Definition: heur.c:1029
SCIP_RETCODE SCIPheurExit(SCIP_HEUR *heur, SCIP_SET *set)
Definition: heur.c:1118
internal methods for primal heuristics
static const char * paramname[]
Definition: lpi_msk.c:5172
#define BMSfreeMemory(ptr)
Definition: memory.h:145
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:465
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:451
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:127
#define BMSduplicateMemoryArray(ptr, source, num)
Definition: memory.h:143
#define BMSclearMemory(ptr)
Definition: memory.h:129
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:123
#define BMSfreeMemoryArray(ptr)
Definition: memory.h:147
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:437
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:148
#define BMSallocMemory(ptr)
Definition: memory.h:118
void SCIPrandomFree(SCIP_RANDNUMGEN **randnumgen, BMS_BLKMEM *blkmem)
Definition: misc.c:10209
SCIP_RETCODE SCIPrandomCreate(SCIP_RANDNUMGEN **randnumgen, BMS_BLKMEM *blkmem, unsigned int initialseed)
Definition: misc.c:10193
void SCIPrandomSetSeed(SCIP_RANDNUMGEN *randnumgen, unsigned int initseed)
Definition: misc.c:10139
internal miscellaneous methods
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
internal methods for collecting primal CIP solutions and primal informations
public methods for message output
#define SCIPerrorMessage
Definition: pub_message.h:64
public data structures and miscellaneous methods
SCIP callable library.
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_RETCODE SCIPsetAddBoolParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: set.c:3207
SCIP_RETCODE SCIPsetAddRealParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, 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: set.c:3277
unsigned int SCIPsetInitializeRandomSeed(SCIP_SET *set, unsigned int initialseedvalue)
Definition: set.c:7800
internal methods for global SCIP settings
#define SCIPsetDebugMsg
Definition: set.h:1811
SCIP_Longint totaldepth
Definition: struct_heur.h:50
SCIP_Longint nlpiterations
Definition: struct_heur.h:48
SCIP_Longint totalsoldepth
Definition: struct_heur.h:51
SCIP_Longint nlps
Definition: struct_heur.h:49
SCIP_Longint totalnbacktracks
Definition: struct_heur.h:53
SCIP_Longint nconflictsfound
Definition: struct_heur.h:56
SCIP_Longint nbestsolsfound
Definition: struct_heur.h:55
SCIP_Longint totalnnodes
Definition: struct_heur.h:52
SCIP_Longint nsolsfound
Definition: struct_heur.h:54
SCIP_RANDNUMGEN * randnumgen
Definition: struct_heur.h:72
SCIP_Bool backtrack
Definition: struct_heur.h:87
SCIP_DIVETYPE divetypemask
Definition: struct_heur.h:91
SCIP_Real maxlpiterquot
Definition: struct_heur.h:76
SCIP_Bool ispublic
Definition: struct_heur.h:90
SCIP_Real minreldepth
Definition: struct_heur.h:74
int maxlpiterofs
Definition: struct_heur.h:85
SCIP_SOL * sol
Definition: struct_heur.h:71
SCIP_Real maxdiveavgquotnosol
Definition: struct_heur.h:82
SCIP_Real maxdiveavgquot
Definition: struct_heur.h:79
SCIP_Real maxdiveubquotnosol
Definition: struct_heur.h:81
SCIP_Real maxdiveubquot
Definition: struct_heur.h:77
unsigned int initialseed
Definition: struct_heur.h:86
SCIP_Real maxreldepth
Definition: struct_heur.h:75
char * name
Definition: struct_heur.h:70
SCIP_DIVESETSTATS * divesetstats[4]
Definition: struct_heur.h:73
SCIP_Real lpresolvedomchgquot
Definition: struct_heur.h:83
SCIP_HEUR * heur
Definition: struct_heur.h:69
SCIP_Bool onlylpbranchcands
Definition: struct_heur.h:88
int delaypos
Definition: struct_heur.h:119
SCIP_DIVESET ** divesets
Definition: struct_heur.h:112
SCIP_HEURDATA * heurdata
Definition: struct_heur.h:111
SCIP_Bool exact
Definition: struct_heur.h:123
SCIP_CLOCK * heurclock
Definition: struct_heur.h:114
char dispchar
Definition: struct_heur.h:125
int priority
Definition: struct_heur.h:115
SCIP_CLOCK * setuptime
Definition: struct_heur.h:113
char * name
Definition: struct_heur.h:102
SCIP_Bool initialized
Definition: struct_heur.h:124
SCIP_HEURTIMING timingmask
Definition: struct_heur.h:121
SCIP_Longint ncalls
Definition: struct_heur.h:99
int maxdepth
Definition: struct_heur.h:118
char * desc
Definition: struct_heur.h:103
SCIP_Longint nsolsfound
Definition: struct_heur.h:100
int ndivesets
Definition: struct_heur.h:120
SCIP_Bool usessubscip
Definition: struct_heur.h:122
SCIP_Longint nbestsolsfound
Definition: struct_heur.h:101
SCIP_Longint nbestsolsfound
Definition: struct_primal.h:52
SCIP_Longint nsolsfound
Definition: struct_primal.h:49
int ndivesetcalls
Definition: struct_stat.h:254
SCIP_Longint ndivesetlpiterations
Definition: struct_stat.h:77
SCIP_Longint ndivesetlps
Definition: struct_stat.h:223
SCIP_Longint totaldivesetdepth
Definition: struct_stat.h:252
int * nvarconss
Definition: struct_heur.h:138
SCIP_HASHTABLE * visitedconss
Definition: struct_heur.h:137
SCIP_CONS *** varconss
Definition: struct_heur.h:136
int * varconssize
Definition: struct_heur.h:139
datastructures for primal heuristics
Definition: heur_padm.c:135
@ SCIP_CLOCKTYPE_DEFAULT
Definition: type_clock.h:43
#define SCIP_DECL_DIVESETAVAILABLE(x)
Definition: type_heur.h:199
#define SCIP_DECL_HEURINITSOL(x)
Definition: type_heur.h:132
#define SCIP_DECL_HEURCOPY(x)
Definition: type_heur.h:97
enum SCIP_DiveContext SCIP_DIVECONTEXT
Definition: type_heur.h:73
struct SCIP_HeurData SCIP_HEURDATA
Definition: type_heur.h:77
#define SCIP_DECL_HEURINIT(x)
Definition: type_heur.h:113
#define SCIP_DECL_HEUREXIT(x)
Definition: type_heur.h:121
unsigned int SCIP_DIVETYPE
Definition: type_heur.h:63
#define SCIP_DECL_HEURFREE(x)
Definition: type_heur.h:105
#define SCIP_DECL_DIVESETGETSCORE(x)
Definition: type_heur.h:184
#define SCIP_DECL_HEUREXITSOL(x)
Definition: type_heur.h:143
#define SCIP_DECL_HEUREXEC(x)
Definition: type_heur.h:163
@ SCIP_DIVECONTEXT_SINGLE
Definition: type_heur.h:69
@ SCIP_DIVECONTEXT_TOTAL
Definition: type_heur.h:68
@ SCIP_DIVECONTEXT_ADAPTIVE
Definition: type_heur.h:70
@ SCIP_DIVECONTEXT_SCHEDULER
Definition: type_heur.h:71
struct SCIP_ParamData SCIP_PARAMDATA
Definition: type_paramset.h:87
@ SCIP_DIDNOTRUN
Definition: type_result.h:42
@ SCIP_DELAYED
Definition: type_result.h:43
@ SCIP_DIDNOTFIND
Definition: type_result.h:44
@ SCIP_UNBOUNDED
Definition: type_result.h:47
@ SCIP_FOUNDSOL
Definition: type_result.h:56
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
#define SCIP_HEURTIMING_BEFOREPRESOL
Definition: type_timing.h:92
#define SCIP_HEURTIMING_AFTERPSEUDONODE
Definition: type_timing.h:85
unsigned int SCIP_HEURTIMING
Definition: type_timing.h:103
#define SCIP_HEURTIMING_DURINGPRESOLLOOP
Definition: type_timing.h:93
#define SCIP_HEURTIMING_AFTERLPPLUNGE
Definition: type_timing.h:87
#define SCIP_HEURTIMING_AFTERPSEUDOPLUNGE
Definition: type_timing.h:89
#define SCIP_HEURTIMING_AFTERLPNODE
Definition: type_timing.h:83