SCIP Doxygen Documentation
Loading...
Searching...
No Matches
heur_proximity.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 heur_proximity.c
26 * @ingroup DEFPLUGINS_HEUR
27 * @brief improvement heuristic which uses an auxiliary objective instead of the original objective function which
28 * is itself added as a constraint to a sub-SCIP instance. The heuristic was presented by Matteo Fischetti
29 * and Michele Monaci.
30 * @author Gregor Hendel
31 */
32
33/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
34
36#include "scip/cons_linear.h"
37#include "scip/heuristics.h"
38#include "scip/heur_proximity.h"
39#include "scip/pub_event.h"
40#include "scip/pub_heur.h"
41#include "scip/pub_message.h"
42#include "scip/pub_misc.h"
43#include "scip/pub_sol.h"
44#include "scip/pub_var.h"
45#include "scip/scip_branch.h"
46#include "scip/scip_cons.h"
47#include "scip/scip_copy.h"
48#include "scip/scip_event.h"
49#include "scip/scip_exact.h"
50#include "scip/scip_general.h"
51#include "scip/scip_heur.h"
52#include "scip/scip_lp.h"
53#include "scip/scip_mem.h"
54#include "scip/scip_message.h"
55#include "scip/scip_nlp.h"
56#include "scip/scip_nodesel.h"
57#include "scip/scip_numerics.h"
58#include "scip/scip_param.h"
59#include "scip/scip_prob.h"
60#include "scip/scip_sol.h"
61#include "scip/scip_solve.h"
63#include "scip/scip_timing.h"
64#include "scip/scip_var.h"
65
66
67#define HEUR_NAME "proximity"
68#define HEUR_DESC "heuristic trying to improve the incumbent by an auxiliary proximity objective function"
69#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_LNS
70#define HEUR_PRIORITY -2000000
71#define HEUR_FREQ -1
72#define HEUR_FREQOFS 0
73#define HEUR_MAXDEPTH -1
74#define HEUR_TIMING SCIP_HEURTIMING_AFTERNODE
75#define HEUR_USESSUBSCIP TRUE /**< does the heuristic use a secondary SCIP instance? */
76
77/* event handler properties */
78#define EVENTHDLR_NAME "Proximity"
79#define EVENTHDLR_DESC "LP event handler for " HEUR_NAME " heuristic"
80
81/* default values for proximity-specific parameters */
82/* todo refine these values */
83#define DEFAULT_MAXNODES 10000LL /**< maximum number of nodes to regard in the subproblem */
84#define DEFAULT_MINIMPROVE 0.02 /**< factor by which proximity should at least improve the incumbent */
85#define DEFAULT_MINGAP 0.01 /**< minimum primal-dual gap for which the heuristic is executed */
86#define DEFAULT_MINNODES 1LL /**< minimum number of nodes to regard in the subproblem */
87#define DEFAULT_MINLPITERS 200LL /**< minimum number of LP iterations to perform in one sub-mip */
88#define DEFAULT_MAXLPITERS 100000LL /**< maximum number of LP iterations to be performed in the subproblem */
89#define DEFAULT_NODESOFS 50LL /**< number of nodes added to the contingent of the total nodes */
90#define DEFAULT_WAITINGNODES 100LL /**< default waiting nodes since last incumbent before heuristic is executed */
91#define DEFAULT_NODESQUOT 0.1 /**< default quotient of sub-MIP nodes with respect to number of processed nodes*/
92#define DEFAULT_USELPROWS FALSE /**< should subproblem be constructed based on LP row information? */
93#define DEFAULT_BINVARQUOT 0.1 /**< default threshold for percentage of binary variables required to start */
94#define DEFAULT_RESTART TRUE /**< should the heuristic immediately run again on its newly found solution? */
95#define DEFAULT_USEFINALLP FALSE /**< should the heuristic solve a final LP in case of continuous objective variables? */
96#define DEFAULT_LPITERSQUOT 0.2 /**< default quotient of sub-MIP LP iterations with respect to LP iterations so far */
97#define DEFAULT_USEUCT FALSE /**< should uct node selection be used at the beginning of the search? */
98
99/*
100 * Data structures
101 */
102
103/** primal heuristic data */
104struct SCIP_HeurData
105{
106 SCIP_Longint maxnodes; /**< maximum number of nodes to regard in the subproblem */
107 SCIP_Longint minnodes; /**< minimum number of nodes to regard in the subproblem */
108 SCIP_Longint maxlpiters; /**< maximum number of LP iterations to be performed in the subproblem */
109 SCIP_Longint nusedlpiters; /**< number of actually performed LP iterations */
110 SCIP_Longint minlpiters; /**< minimum number of LP iterations to perform in one sub-mip */
111 SCIP_Longint nodesofs; /**< number of nodes added to the contingent of the total nodes */
112 SCIP_Longint usednodes; /**< nodes already used by proximity in earlier calls */
113 SCIP_Longint waitingnodes; /**< waiting nodes since last incumbent before heuristic is executed */
114 SCIP_Real lpitersquot; /**< quotient of sub-MIP LP iterations with respect to LP iterations so far */
115 SCIP_Real minimprove; /**< factor by which proximity should at least improve the incumbent */
116 SCIP_Real mingap; /**< minimum primal-dual gap for which the heuristic is executed */
117 SCIP_Real nodesquot; /**< quotient of sub-MIP nodes with respect to number of processed nodes */
118 SCIP_Real binvarquot; /**< threshold for percantage of binary variables required to start */
119
120 SCIP* subscip; /**< the subscip used by the heuristic */
121 SCIP_HASHMAP* varmapfw; /**< map between scip variables and subscip variables */
122 SCIP_VAR** subvars; /**< variables in subscip */
123 SCIP_CONS* objcons; /**< the objective cutoff constraint of the subproblem */
124
125 int nsubvars; /**< the number of subvars */
126 int lastsolidx; /**< index of last solution on which the heuristic was processed */
127 int subprobidx; /**< counter for the subproblem index to be solved by proximity */
128
129 SCIP_Bool uselprows; /**< should subproblem be constructed based on LP row information? */
130 SCIP_Bool restart; /**< should the heuristic immediately run again on its newly found solution? */
131 SCIP_Bool usefinallp; /**< should the heuristic solve a final LP in case of continuous objective variables? */
132 SCIP_Bool useuct; /**< should uct node selection be used at the beginning of the search? */
133};
134
135
136/*
137 * Local methods
138 */
139
140/** optimizes the continuous variables in an LP diving by fixing all integer variables to the given solution values */
141static
143 SCIP* scip, /**< SCIP data structure */
144 SCIP_SOL* sol, /**< candidate solution for which continuous variables should be optimized */
145 SCIP_Bool* success /**< was the dive successful? */
146 )
147{
148 SCIP_VAR** vars;
149 SCIP_RETCODE retstat;
150
151 int v;
152 int nvars;
153 int ncontvars;
154 int nintvars;
155
157 SCIP_Bool requiresnlp;
158
159 assert(success != NULL);
160
161 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, &ncontvars) );
162
163 nintvars = nvars - ncontvars;
164
165 /**@todo in case of an MINLP, if SCIPisNLPConstructed() is TRUE rather solve the NLP instead of the LP */
166 requiresnlp = SCIPisNLPConstructed(scip);
167 if( requiresnlp || ncontvars == 0 )
168 return SCIP_OKAY;
169
170 /* start diving to calculate the LP relaxation */
172
173 /* set the bounds of the variables: fixed for integers, global bounds for continuous */
174 for( v = 0; v < nvars; ++v )
175 {
177 {
180 }
181 }
182
183 /* apply this after global bounds to not cause an error with intermediate empty domains */
184 for( v = 0; v < nintvars; ++v )
185 {
187 {
188 SCIP_Real solval;
189
190 solval = SCIPgetSolVal(scip, sol, vars[v]);
191 SCIP_CALL( SCIPchgVarLbDive(scip, vars[v], solval) );
192 SCIP_CALL( SCIPchgVarUbDive(scip, vars[v], solval) );
193 }
194 }
195
196 /* solve LP */
197 SCIPdebugMsg(scip, " -> old LP iterations: %" SCIP_LONGINT_FORMAT "\n", SCIPgetNLPIterations(scip));
198
199 /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
200 * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
201 */
202 retstat = SCIPsolveDiveLP(scip, -1, &lperror, NULL);
203 if( retstat != SCIP_OKAY )
204 {
205#ifdef NDEBUG
206 SCIPwarningMessage(scip, "Error while solving LP in Proximity heuristic; LP solve terminated with code <%d>\n",retstat);
207#else
208 SCIP_CALL( retstat );
209#endif
210 }
211
212 SCIPdebugMsg(scip, " -> new LP iterations: %" SCIP_LONGINT_FORMAT "\n", SCIPgetNLPIterations(scip));
213 SCIPdebugMsg(scip, " -> error=%u, status=%d\n", lperror, SCIPgetLPSolstat(scip));
215 {
217
218 /* in exact mode we have to end diving prior to trying the solution */
219 if( SCIPisExact(scip) )
220 {
223 }
224
225 SCIP_CALL( SCIPtrySol(scip, sol, FALSE, FALSE, TRUE, TRUE, TRUE, success) );
226 }
227
228 /* terminate diving mode */
229 if( SCIPinDive(scip) )
230 {
232 }
233
234 return SCIP_OKAY;
235}
236
237/** creates a new solution for the original problem by copying the solution of the subproblem */
238static
240 SCIP* scip, /**< original SCIP data structure */
241 SCIP* subscip, /**< SCIP structure of the subproblem */
242 SCIP_VAR** subvars, /**< the variables of the subproblem */
243 SCIP_HEUR* heur, /**< proximity heuristic structure */
244 SCIP_SOL* subsol, /**< solution of the subproblem */
245 SCIP_Bool usefinallp, /**< should continuous variables be optimized by a final LP */
246 SCIP_Bool* success /**< used to store whether new solution was found or not */
247 )
248{
249 SCIP_VAR** vars; /* the original problem's variables */
250 int nvars; /* the original problem's number of variables */
251 int ncontvars; /* the original problem's number of continuous variables */
252 SCIP_Real* subsolvals; /* solution values of the subproblem */
253 SCIP_SOL* newsol; /* solution to be created for the original problem */
254 int i;
255
256 assert(scip != NULL);
257 assert(subscip != NULL);
258 assert(subvars != NULL);
259 assert(subsol != NULL);
260 assert(success != NULL);
261
262 /* get variables' data */
263 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, &ncontvars) );
264
265 SCIP_CALL( SCIPallocBufferArray(scip, &subsolvals, nvars) );
266
267 /* copy the solution */
268 for( i = 0; i < nvars; ++i )
269 {
270 if( subvars[i] == NULL )
271 subsolvals[i] = MIN(MAX(0.0, SCIPvarGetLbLocal(vars[i])), SCIPvarGetUbLocal(vars[i])); /*lint !e666*/
272 else
273 subsolvals[i] = SCIPgetSolVal(subscip, subsol, subvars[i]);
274 }
275
276 /* create new solution for the original problem */
277 SCIP_CALL( SCIPcreateSol(scip, &newsol, heur) );
278 SCIP_CALL( SCIPsetSolVals(scip, newsol, nvars, vars, subsolvals) );
279
280 *success = FALSE;
281
282 /* solve an LP with all integer variables fixed to improve solution quality */
283 if( ncontvars > 0 && usefinallp && SCIPisLPConstructed(scip) )
284 {
285 int v;
286 int ncontobjvars = 0; /* does the problem instance have continuous variables with nonzero objective coefficients? */
287 SCIP_Real sumofobjsquares = 0.0;
288
289 /* check if continuous variables with nonzero objective coefficient are present */
290 for( v = nvars - 1; v >= nvars - ncontvars; --v )
291 {
292 SCIP_VAR* var;
293
294 var = vars[v];
295 assert(vars[v] != NULL);
297
299 {
300 ++ncontobjvars;
301 sumofobjsquares += SCIPvarGetObj(var) * SCIPvarGetObj(var);
302 }
303 }
304
305 SCIPstatisticMessage(" Continuous Objective variables: %d, Euclidean OBJ: %g total, %g continuous\n", ncontobjvars, SCIPgetObjNorm(scip), sumofobjsquares);
306
307 /* solve a final LP to optimize solution values of continuous problem variables */
308 SCIPstatisticMessage("Solution Value before LP resolve: %g\n", SCIPgetSolOrigObj(scip, newsol));
309 SCIP_CALL( solveLp(scip, newsol, success) );
310
311 /* if the LP solve was not successful, reset the solution */
312 if( !*success )
313 {
314 for( v = nvars - 1; v >= nvars - ncontvars; --v )
315 {
316 SCIP_CALL( SCIPsetSolVal(scip, newsol, vars[v], subsolvals[v]) );
317 }
318 }
319 }
320
321 /* try to add new solution to SCIP and free it immediately */
322 if( !*success )
323 {
324 SCIP_CALL( SCIPtrySol(scip, newsol, FALSE, FALSE, TRUE, TRUE, TRUE, success) );
325 }
326 SCIP_CALL( SCIPfreeSol(scip, &newsol) );
327
328 SCIPfreeBufferArray(scip, &subsolvals);
329
330 return SCIP_OKAY;
331}
332
333/** sets solving parameters for the subproblem created by the heuristic */
334static
336 SCIP_HEURDATA* heurdata, /**< heuristic data structure */
337 SCIP* subscip /**< copied SCIP data structure */
338 )
339{
340 assert(subscip != NULL);
341
342 /* do not abort subproblem on CTRL-C */
343 SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
344
345#ifdef SCIP_DEBUG
346 /* for debugging, enable full output */
347 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 5) );
348 SCIP_CALL( SCIPsetIntParam(subscip, "display/freq", 100000000) );
349#else
350 /* disable statistic timing inside sub SCIP and output to console */
351 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) );
352 SCIP_CALL( SCIPsetBoolParam(subscip, "timing/statistictiming", FALSE) );
353#endif
354
355 /* forbid recursive call of heuristics and separators solving sub-SCIPs */
356 SCIP_CALL( SCIPsetSubscipsOff(subscip, TRUE) );
357
358 /* use restart dfs node selection */
359 if( SCIPfindNodesel(subscip, "restartdfs") != NULL && !SCIPisParamFixed(subscip, "nodeselection/restartdfs/stdpriority") )
360 {
361 SCIP_CALL( SCIPsetIntParam(subscip, "nodeselection/restartdfs/stdpriority", INT_MAX/4) );
362 }
363
364 /* activate uct node selection at the top of the tree */
365 if( heurdata->useuct && SCIPfindNodesel(subscip, "uct") != NULL && !SCIPisParamFixed(subscip, "nodeselection/uct/stdpriority") )
366 {
367 SCIP_CALL( SCIPsetIntParam(subscip, "nodeselection/uct/stdpriority", INT_MAX/2) );
368 }
369
370 /* disable expensive presolving
371 * todo maybe presolving can be entirely turned off here - parameter???
372 */
374
375 /* SCIP_CALL( SCIPsetPresolving(scip, SCIP_PARAMSETTING_OFF, TRUE) ); */
376 if( !SCIPisParamFixed(subscip, "presolving/maxrounds") )
377 {
378 SCIP_CALL( SCIPsetIntParam(subscip, "presolving/maxrounds", 50) );
379 }
380
381 /* disable cutting plane separation */
383
384 /* todo: check branching rule in sub-SCIP */
385 if( SCIPfindBranchrule(subscip, "inference") != NULL && !SCIPisParamFixed(subscip, "branching/inference/priority") )
386 {
387 SCIP_CALL( SCIPsetIntParam(subscip, "branching/inference/priority", INT_MAX/4) );
388 }
389
390 /* disable feasibility pump and fractional diving */
391 if( !SCIPisParamFixed(subscip, "heuristics/feaspump/freq") )
392 {
393 SCIP_CALL( SCIPsetIntParam(subscip, "heuristics/feaspump/freq", -1) );
394 }
395 if( !SCIPisParamFixed(subscip, "heuristics/fracdiving/freq") )
396 {
397 SCIP_CALL( SCIPsetIntParam(subscip, "heuristics/fracdiving/freq", -1) );
398 }
399
400 /* todo check if
401 * SCIP_CALL( SCIPsetEmphasis(subscip, SCIP_PARAMEMPHASIS_FEASIBILITY, TRUE) );
402 * improves performance */
403
404 return SCIP_OKAY;
405}
406
407/** frees the subproblem */
408static
410 SCIP* scip, /**< SCIP data structure */
411 SCIP_HEURDATA* heurdata /**< heuristic data */
412 )
413{
414 /* free remaining memory from heuristic execution */
415 if( heurdata->subscip != NULL )
416 {
417 assert(heurdata->varmapfw != NULL);
418 assert(heurdata->subvars != NULL);
419 assert(heurdata->objcons != NULL);
420
421 SCIPdebugMsg(scip, "Freeing subproblem of proximity heuristic\n");
422 SCIPfreeBlockMemoryArray(scip, &heurdata->subvars, heurdata->nsubvars);
423 SCIPhashmapFree(&heurdata->varmapfw);
424 SCIP_CALL( SCIPreleaseCons(heurdata->subscip, &heurdata->objcons) );
425 SCIP_CALL( SCIPfree(&heurdata->subscip) );
426
427 heurdata->subscip = NULL;
428 heurdata->varmapfw = NULL;
429 heurdata->subvars = NULL;
430 heurdata->objcons = NULL;
431 }
432 return SCIP_OKAY;
433}
434
435/* ---------------- Callback methods of event handler ---------------- */
436
437/** exec the event handler
438 *
439 * We interrupt the solution process.
440 */
441static
442SCIP_DECL_EVENTEXEC(eventExecProximity)
443{
445
446 assert(eventhdlr != NULL);
447 assert(eventdata != NULL);
448 assert(event != NULL);
450
452
453 heurdata = (SCIP_HEURDATA*)eventdata;
454 assert(heurdata != NULL);
455
456 /* interrupt solution process of sub-SCIP
457 * todo adjust interruption limit */
459 {
461 }
462
463 return SCIP_OKAY;
464}
465
466
467/* ---------------- Callback methods of primal heuristic ---------------- */
468
469/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
470static
471SCIP_DECL_HEURCOPY(heurCopyProximity)
472{ /*lint --e{715}*/
473 assert(scip != NULL);
474 assert(heur != NULL);
475
477
478 /* call inclusion method of primal heuristic */
480
481 return SCIP_OKAY;
482}
483
484/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
485static
486SCIP_DECL_HEURFREE(heurFreeProximity)
487{ /*lint --e{715}*/
489
490 assert( heur != NULL );
491 assert( scip != NULL );
492
493 /* get heuristic data */
495 assert( heurdata != NULL );
496
497 /* free heuristic data */
499 SCIPheurSetData(heur, NULL);
500
501 return SCIP_OKAY;
502}
503
504
505/** initialization method of primal heuristic (called after problem was transformed) */
506static
507SCIP_DECL_HEURINIT(heurInitProximity)
508{ /*lint --e{715}*/
510
511 assert( heur != NULL );
512 assert( scip != NULL );
513
514 /* get heuristic data */
516 assert( heurdata != NULL );
517
518 /* initialize data */
519 heurdata->usednodes = 0LL;
520 heurdata->lastsolidx = -1;
521 heurdata->nusedlpiters = 0LL;
522 heurdata->subprobidx = 0;
523
524 heurdata->subscip = NULL;
525 heurdata->varmapfw = NULL;
526 heurdata->subvars = NULL;
527 heurdata->objcons = NULL;
528
529 heurdata->nsubvars = 0;
530
531 return SCIP_OKAY;
532}
533
534/** solution process exiting method of proximity heuristic */
535static
536SCIP_DECL_HEUREXITSOL(heurExitsolProximity)
537{
539
540 assert( heur != NULL );
541 assert( scip != NULL );
542
543 /* get heuristic data */
545 assert( heurdata != NULL );
546
548
549 assert(heurdata->subscip == NULL && heurdata->varmapfw == NULL && heurdata->subvars == NULL && heurdata->objcons == NULL);
550
551 return SCIP_OKAY;
552}
553
554/** execution method of primal heuristic */
555static
556SCIP_DECL_HEUREXEC(heurExecProximity)
557{ /*lint --e{715}*/
558 SCIP_HEURDATA* heurdata; /* heuristic's data */
559 SCIP_Longint nnodes; /* number of stalling nodes for the subproblem */
560 SCIP_Longint nlpiters; /* lp iteration limit for the subproblem */
561 SCIP_Bool foundsol = FALSE;
562
563 assert(heur != NULL);
564 assert(scip != NULL);
565 assert(result != NULL);
566
568
569 /* get heuristic data */
571 assert(heurdata != NULL);
572
573 /* do not run heuristic when there are only few binary varables */
574 if( SCIPgetNBinVars(scip) < heurdata->binvarquot * SCIPgetNVars(scip) )
575 return SCIP_OKAY;
576
577 /* calculate branching node limit for sub problem */
578 /* todo maybe treat root node differently */
579 nnodes = (SCIP_Longint) (heurdata->nodesquot * SCIPgetNNodes(scip));
580 nnodes += heurdata->nodesofs;
581
582 /* determine the node and LP iteration limit for the solve of the sub-SCIP */
583 nnodes -= heurdata->usednodes;
584 nnodes = MIN(nnodes, heurdata->maxnodes);
585
586 nlpiters = (SCIP_Longint) (heurdata->lpitersquot * SCIPgetNRootFirstLPIterations(scip));
587 nlpiters = MIN(nlpiters, heurdata->maxlpiters);
588
589 /* check whether we have enough nodes left to call subproblem solving */
590 if( nnodes < heurdata->minnodes )
591 {
592 SCIPdebugMsg(scip, "skipping proximity: nnodes=%" SCIP_LONGINT_FORMAT ", minnodes=%" SCIP_LONGINT_FORMAT "\n", nnodes, heurdata->minnodes);
593 return SCIP_OKAY;
594 }
595
596 /* do not run proximity, if the problem does not have an objective function anyway */
597 if( SCIPgetNObjVars(scip) == 0 )
598 {
599 SCIPdebugMsg(scip, "skipping proximity: pure feasibility problem anyway\n");
600 return SCIP_OKAY;
601 }
602
603 do
604 {
605 /* main loop of proximity: in every iteration, a new subproblem is set up and solved until no improved solution
606 * is found or one of the heuristic limits on nodes or LP iterations is hit
607 * heuristic performs only one iteration if restart parameter is set to FALSE
608 */
609 SCIP_Longint nusednodes = 0LL;
610 SCIP_Longint nusedlpiters = 0LL;
611
612 nlpiters = MAX(nlpiters, heurdata->minlpiters);
613
614 /* define and solve the proximity subproblem */
615 SCIP_CALL( SCIPapplyProximity(scip, heur, result, heurdata->minimprove, nnodes, nlpiters, &nusednodes, &nusedlpiters, FALSE) );
616
617 /* adjust node limit and LP iteration limit for future iterations */
618 assert(nusednodes <= nnodes);
619 heurdata->usednodes += nusednodes;
620 nnodes -= nusednodes;
621
622 nlpiters -= nusedlpiters;
623 heurdata->nusedlpiters += nusedlpiters;
624
625 /* memorize if a new solution has been found in at least one iteration */
626 if( *result == SCIP_FOUNDSOL )
627 foundsol = TRUE;
628 }
629 while( *result == SCIP_FOUNDSOL && heurdata->restart && !SCIPisStopped(scip) && nnodes > 0 );
630
631 /* reset result pointer if solution has been found in previous iteration */
632 if( foundsol )
634
635 /* free the occupied memory */
636 if( heurdata->subscip != NULL )
637 {
638 /* just for testing the library method, in debug mode, we call the wrapper method for the actual delete method */
639#ifndef NDEBUG
641#else
643#endif
644 }
645 return SCIP_OKAY;
646}
647
648
649/*
650 * primal heuristic specific interface methods
651 */
652
653/** frees the sub-MIP created by proximity */
655 SCIP* scip /** SCIP data structure */
656 )
657{
658 SCIP_HEUR* heur;
660
661 assert(scip != NULL);
662
663 heur = SCIPfindHeur(scip, HEUR_NAME);
664 assert(heur != NULL);
665
667 if( heurdata != NULL )
668 {
670 }
671
672 return SCIP_OKAY;
673}
674
675/** main procedure of the proximity heuristic, creates and solves a sub-SCIP
676 *
677 * @note The method can be applied in an iterative way, keeping the same subscip in between. If the @p freesubscip
678 * parameter is set to FALSE, the heuristic will keep the subscip data structures. Always set this parameter
679 * to TRUE, or call SCIPdeleteSubproblemProximity() afterwards.
680 */
682 SCIP* scip, /**< original SCIP data structure */
683 SCIP_HEUR* heur, /**< heuristic data structure */
684 SCIP_RESULT* result, /**< result data structure */
685 SCIP_Real minimprove, /**< factor by which proximity should at least improve the incumbent */
686 SCIP_Longint nnodes, /**< node limit for the subproblem */
687 SCIP_Longint nlpiters, /**< LP iteration limit for the subproblem */
688 SCIP_Longint* nusednodes, /**< pointer to store number of used nodes in subscip */
689 SCIP_Longint* nusedlpiters, /**< pointer to store number of used LP iterations in subscip */
690 SCIP_Bool freesubscip /**< should the created sub-MIP be freed at the end of the method? */
691 )
692{
693 SCIP* subscip; /* the subproblem created by proximity */
694 SCIP_HASHMAP* varmapfw; /* mapping of SCIP variables to sub-SCIP variables */
695 SCIP_VAR** vars; /* original problem's variables */
696 SCIP_VAR** subvars; /* subproblem's variables */
697 SCIP_HEURDATA* heurdata; /* heuristic's private data structure */
698 SCIP_EVENTHDLR* eventhdlr; /* event handler for LP events */
699
700 SCIP_SOL* incumbent;
701 SCIP_CONS* objcons;
702 SCIP_Longint iterlim;
703
704 SCIP_Real large;
705 SCIP_Real inf;
706
707 SCIP_Real bestobj;
708 SCIP_Real objcutoff;
709 SCIP_Real lowerbound;
710
711 int nvars; /* number of original problem's variables */
712 int nfixedvars;
713 int nsubsols;
714 int solidx;
715 int i;
716
718 SCIP_Bool success;
719
720 assert(scip != NULL);
721 assert(heur != NULL);
722 assert(result != NULL);
723
724 assert(nnodes >= 0);
725 assert(0.0 <= minimprove && minimprove <= 1.0);
726
728
729 /* get heuristic data */
731 assert(heurdata != NULL);
732
733 /* only call the heuristic if we have an incumbent */
734 if( SCIPgetNSolsFound(scip) == 0 )
735 return SCIP_OKAY;
736
737 /* do not use heuristic on problems without binary variables */
738 if( SCIPgetNBinVars(scip) == 0 )
739 return SCIP_OKAY;
740
741 incumbent = SCIPgetBestSol(scip);
742 assert(incumbent != NULL);
743
744 /* make sure that the incumbent is valid for the transformed space, otherwise terminate */
745 if( SCIPsolIsOriginal(incumbent) )
746 return SCIP_OKAY;
747
748 solidx = SCIPsolGetIndex(incumbent);
749
750 if( heurdata->lastsolidx == solidx )
751 return SCIP_OKAY;
752
753 /* only call heuristic, if the best solution does not come from trivial heuristic */
754 if( SCIPsolGetHeur(incumbent) != NULL && strcmp(SCIPheurGetName(SCIPsolGetHeur(incumbent)), "trivial") == 0 )
755 return SCIP_OKAY;
756
757 /* waitingnodes parameter defines the minimum number of nodes to wait before a new incumbent is processed */
758 if( SCIPgetNNodes(scip) > 1 && SCIPgetNNodes(scip) - SCIPsolGetNodenum(incumbent) < heurdata->waitingnodes )
759 return SCIP_OKAY;
760
761 bestobj = SCIPgetSolTransObj(scip, incumbent);
762 lowerbound = SCIPgetLowerbound(scip);
763
764 /* use knowledge about integrality of objective to round up lower bound */
766 {
767 SCIPdebugMsg(scip, " Rounding up lower bound: %f --> %f \n", lowerbound, SCIPfeasCeil(scip, lowerbound));
768 lowerbound = SCIPfeasCeil(scip, lowerbound);
769 }
770
771 /* do not trigger heuristic if primal and dual bound are already close together */
772 if( SCIPisFeasLE(scip, bestobj, lowerbound) || SCIPgetGap(scip) <= heurdata->mingap )
773 return SCIP_OKAY;
774
775 /* calculate the minimum improvement for a heuristic solution in terms of the distance between incumbent objective
776 * and the lower bound */
777 if( SCIPisInfinity(scip, REALABS(lowerbound)) )
778 {
779 if( SCIPisZero(scip, bestobj) )
780 objcutoff = bestobj - 1;
781 else
782 objcutoff = (1 - minimprove) * bestobj;
783 }
784 else
785 objcutoff = minimprove * lowerbound + (1 - minimprove) * (bestobj);
786
787 /* use integrality of the objective function to round down (and thus strengthen) the objective cutoff */
789 objcutoff = SCIPfeasFloor(scip, objcutoff);
790
791 if( SCIPisFeasLT(scip, objcutoff, lowerbound) )
792 objcutoff = lowerbound;
793
794 /* exit execution if the right hand side of the objective constraint does not change (suggests that the heuristic
795 * was not successful in a previous iteration) */
796 if( heurdata->objcons != NULL && SCIPisFeasEQ(scip, SCIPgetRhsLinear(heurdata->subscip, heurdata->objcons), objcutoff) )
797 return SCIP_OKAY;
798
799 /* check whether there is enough time and memory left */
801
802 if( ! valid )
803 return SCIP_OKAY;
804
806
807 heurdata->lastsolidx = solidx;
808
809 /* get variable data */
811
812 /* create a subscip and copy the original scip instance into it */
813 if( heurdata->subscip == NULL )
814 {
815 assert(heurdata->varmapfw == NULL);
816 assert(heurdata->objcons == NULL);
817
818 /* initialize the subproblem */
819 SCIP_CALL( SCIPcreate(&subscip) );
820
821 /* create the variable mapping hash map */
822 SCIP_CALL( SCIPhashmapCreate(&varmapfw, SCIPblkmem(subscip), nvars) );
824
825 /* copy complete SCIP instance */
826 valid = FALSE;
827
828 /* create a problem copy as sub SCIP */
829 SCIP_CALL( SCIPcopyLargeNeighborhoodSearch(scip, subscip, varmapfw, "proximity", NULL, NULL, 0, heurdata->uselprows, TRUE,
830 &success, &valid) );
831
832 SCIPdebugMsg(scip, "Copying the SCIP instance was %s complete.\n", valid ? "" : "not ");
833
834 /* create event handler for LP events */
835 eventhdlr = NULL;
836 SCIP_CALL( SCIPincludeEventhdlrBasic(subscip, &eventhdlr, EVENTHDLR_NAME, EVENTHDLR_DESC, eventExecProximity, NULL) );
837 if( eventhdlr == NULL )
838 {
839 SCIPerrorMessage("event handler for " HEUR_NAME " heuristic not found.\n");
840 return SCIP_PLUGINNOTFOUND;
841 }
842
843 /* set up parameters for the copied instance */
845
846 /* create the objective constraint in the sub scip, first without variables and values which will be added later */
847 SCIP_CALL( SCIPcreateConsBasicLinear(subscip, &objcons, "objbound_of_origscip", 0, NULL, NULL, -SCIPinfinity(subscip), SCIPinfinity(subscip)) );
848
849 /* determine large value to set variable bounds to, safe-guard to avoid fixings to infinite values */
850 large = SCIPinfinity(scip);
851 if( !SCIPisInfinity(scip, 0.1 / SCIPfeastol(scip)) )
852 large = 0.1 / SCIPfeastol(scip);
853 inf = SCIPinfinity(subscip);
854
855 /* get variable image and change objective to proximity function (Manhattan distance) in sub-SCIP */
856 for( i = 0; i < nvars; i++ )
857 {
858 SCIP_Real adjustedbound;
859 SCIP_Real lb;
860 SCIP_Real ub;
861
862 subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, vars[i]);
863
864 if( subvars[i] == NULL )
865 continue;
866
867 SCIP_CALL( SCIPchgVarObj(subscip, subvars[i], 0.0) );
868
869 lb = SCIPvarGetLbGlobal(subvars[i]);
870 ub = SCIPvarGetUbGlobal(subvars[i]);
871
872 /* adjust infinite bounds in order to avoid that variables with non-zero objective
873 * get fixed to infinite value in proximity subproblem
874 */
875 if( SCIPisInfinity(subscip, ub) )
876 {
877 adjustedbound = MAX(large, lb + large);
878 adjustedbound = MIN(adjustedbound, inf);
879 SCIP_CALL( SCIPchgVarUbGlobal(subscip, subvars[i], adjustedbound) );
880 }
881 if( SCIPisInfinity(subscip, -lb) )
882 {
883 adjustedbound = MIN(-large, ub - large);
884 adjustedbound = MAX(adjustedbound, -inf);
885 SCIP_CALL( SCIPchgVarLbGlobal(subscip, subvars[i], adjustedbound) );
886 }
887
888 /* add all nonzero objective coefficients to the objective constraint */
889 if( !SCIPisFeasZero(subscip, SCIPvarGetObj(vars[i])) )
890 {
891 SCIP_CALL( SCIPaddCoefLinear(subscip, objcons, subvars[i], SCIPvarGetObj(vars[i])) );
892 }
893 }
894
895 /* add objective constraint to the subscip */
896 SCIP_CALL( SCIPaddCons(subscip, objcons) );
897 }
898 else
899 {
900 /* the instance, event handler, hash map and variable array were already copied in a previous iteration
901 * and stored in heuristic data
902 */
903 assert(heurdata->varmapfw != NULL);
904 assert(heurdata->subvars != NULL);
905 assert(heurdata->objcons != NULL);
906
907 subscip = heurdata->subscip;
908 varmapfw = heurdata->varmapfw;
909 subvars = heurdata->subvars;
910 objcons = heurdata->objcons;
911
912 eventhdlr = SCIPfindEventhdlr(subscip, EVENTHDLR_NAME);
913 assert(eventhdlr != NULL);
914 }
915
916 SCIP_CALL( SCIPchgRhsLinear(subscip, objcons, objcutoff) );
917
918 for( i = 0; i < SCIPgetNBinVars(scip); ++i )
919 {
920 SCIP_Real solval;
921
922 if( subvars[i] == NULL )
923 continue;
924
925 /* objective coefficients are only set for binary variables of the problem */
926 assert(SCIPvarIsBinary(subvars[i]));
927
928 solval = SCIPgetSolVal(scip, incumbent, vars[i]);
929 assert(SCIPisFeasGE(scip, solval, 0.0));
930 assert(SCIPisFeasLE(scip, solval, 1.0));
932
933 if( solval < 0.5 )
934 {
935 SCIP_CALL( SCIPchgVarObj(subscip, subvars[i], 1.0) );
936 }
937 else
938 {
939 SCIP_CALL( SCIPchgVarObj(subscip, subvars[i], -1.0) );
940 }
941 }
942
943 /* set limits for the subproblem */
944 SCIP_CALL( SCIPcopyLimits(scip, subscip) );
945 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", nnodes) );
946 SCIP_CALL( SCIPsetIntParam(subscip, "limits/solutions", 1) );
947
948 /* restrict LP iterations */
949 /* todo set iterations limit depending on the number of iterations of the original problem root */
950 iterlim = nlpiters;
951 SCIP_CALL( SCIPsetLongintParam(subscip, "lp/iterlim", MAX(1, iterlim / MIN(10, nnodes))) );
952 SCIP_CALL( SCIPsetLongintParam(subscip, "lp/rootiterlim", iterlim) );
953
954 /* catch LP events of sub-SCIP */
955 SCIP_CALL( SCIPtransformProb(subscip) );
957
958 SCIPstatisticMessage("solving subproblem at Node: %" SCIP_LONGINT_FORMAT " "
959 "nnodes: %" SCIP_LONGINT_FORMAT " "
960 "iterlim: %" SCIP_LONGINT_FORMAT "\n", SCIPgetNNodes(scip), nnodes, iterlim);
961
962 /* solve the subproblem with all previously adjusted parameters */
963 nfixedvars = SCIPgetNFixedVars(subscip);
964
965 SCIP_CALL( SCIPpresolve(subscip) );
966
967 nfixedvars = SCIPgetNFixedVars(subscip) - nfixedvars;
968 assert(nfixedvars >= 0);
969 SCIPstatisticMessage("presolve fixings %d: %d\n", ++(heurdata->subprobidx), nfixedvars);
970
971 /* errors in solving the subproblem should not kill the overall solving process;
972 * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
973 */
974 SCIP_CALL_ABORT( SCIPsolve(subscip) );
975
976 /* print solving statistics of subproblem if we are in SCIP's debug mode */
978 SCIPstatisticMessage("solve of subscip %d:"
979 "usednodes: %" SCIP_LONGINT_FORMAT " "
980 "lp iters: %" SCIP_LONGINT_FORMAT " "
981 "root iters: %" SCIP_LONGINT_FORMAT " "
982 "Presolving Time: %.2f\n", heurdata->subprobidx,
984
985 SCIPstatisticMessage("Solving Time %d: %.2f\n", heurdata->subprobidx, SCIPgetSolvingTime(subscip) );
986
987 /* drop LP events of sub-SCIP */
989
990 /* keep track of relevant information for future runs of heuristic */
991 if( nusednodes != NULL )
992 *nusednodes = SCIPgetNNodes(subscip);
993 if( nusedlpiters != NULL )
994 *nusedlpiters = SCIPgetNLPIterations(subscip);
995
996 /* check whether a solution was found */
997 nsubsols = SCIPgetNSols(subscip);
998 incumbent = SCIPgetBestSol(subscip);
999 assert(nsubsols == 0 || incumbent != NULL);
1000
1001 SCIPstatisticMessage("primal bound before subproblem %d: %g\n", heurdata->subprobidx, SCIPgetPrimalbound(scip));
1002 if( nsubsols > 0 )
1003 {
1004 /* try to translate the sub problem solution to the original scip instance */
1005 success = FALSE;
1006 SCIP_CALL( createNewSol(scip, subscip, subvars, heur, incumbent, heurdata->usefinallp, &success) );
1007
1008 if( success )
1010 }
1011 SCIPstatisticMessage("primal bound after subproblem %d: %g\n", heurdata->subprobidx, SCIPgetPrimalbound(scip));
1012
1013 /* free the transformed subproblem data */
1014 SCIP_CALL( SCIPfreeTransform(subscip) );
1015
1016 /* save subproblem in heuristic data for subsequent runs if it has been successful, otherwise free subproblem */
1017 heurdata->subscip = subscip;
1018 heurdata->varmapfw = varmapfw;
1019 heurdata->subvars = subvars;
1020 heurdata->objcons = objcons;
1021 heurdata->nsubvars = nvars;
1022
1023 /* delete the sub problem */
1024 if( freesubscip )
1025 {
1027 }
1028
1029 return SCIP_OKAY;
1030}
1031
1032
1033/** creates the proximity primal heuristic and includes it in SCIP */
1035 SCIP* scip /**< SCIP data structure */
1036 )
1037{
1039 SCIP_HEUR* heur = NULL;
1040
1041 /* create heuristic data */
1043
1044 /* include primal heuristic */
1047 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecProximity, heurdata) );
1048 assert(heur != NULL);
1049
1050 /* primal heuristic is safe to use in exact solving mode */
1051 SCIPheurMarkExact(heur);
1052
1053 /* set non-NULL pointers to callback methods */
1054 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyProximity) );
1055 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeProximity) );
1056 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitProximity) );
1057 SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolProximity) );
1058
1059 /* add proximity primal heuristic parameters */
1060 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/uselprows",
1061 "should subproblem be constructed based on LP row information?",
1062 &heurdata->uselprows, TRUE, DEFAULT_USELPROWS, NULL, NULL) );
1063
1064 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/restart",
1065 "should the heuristic immediately run again on its newly found solution?",
1066 &heurdata->restart, TRUE, DEFAULT_RESTART, NULL, NULL) );
1067
1068 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/usefinallp",
1069 "should the heuristic solve a final LP in case of continuous objective variables?",
1070 &heurdata->usefinallp, TRUE, DEFAULT_USEFINALLP, NULL, NULL) );
1071
1072 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxnodes",
1073 "maximum number of nodes to regard in the subproblem",
1074 &heurdata->maxnodes, TRUE,DEFAULT_MAXNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1075
1076 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/nodesofs",
1077 "number of nodes added to the contingent of the total nodes",
1078 &heurdata->nodesofs, TRUE, DEFAULT_NODESOFS, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1079
1080 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/minnodes",
1081 "minimum number of nodes required to start the subproblem",
1082 &heurdata->minnodes, TRUE, DEFAULT_MINNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1083
1084 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxlpiters",
1085 "maximum number of LP iterations to be performed in the subproblem",
1086 &heurdata->maxlpiters, TRUE, DEFAULT_MAXLPITERS, -1LL, SCIP_LONGINT_MAX, NULL, NULL) );
1087
1088 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/minlpiters",
1089 "minimum number of LP iterations performed in subproblem",
1090 &heurdata->minlpiters, TRUE, DEFAULT_MINLPITERS, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1091
1092 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/waitingnodes",
1093 "waiting nodes since last incumbent before heuristic is executed",
1094 &heurdata->waitingnodes, TRUE, DEFAULT_WAITINGNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1095
1096 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minimprove",
1097 "factor by which proximity should at least improve the incumbent",
1098 &heurdata->minimprove, TRUE, DEFAULT_MINIMPROVE, 0.0, 1.0, NULL, NULL) );
1099
1100 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/nodesquot",
1101 "sub-MIP node limit w.r.t number of original nodes",
1102 &heurdata->nodesquot, TRUE, DEFAULT_NODESQUOT, 0.0, SCIPinfinity(scip), NULL, NULL) );
1103
1104 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/binvarquot",
1105 "threshold for percentage of binary variables required to start",
1106 &heurdata->binvarquot, TRUE, DEFAULT_BINVARQUOT, 0.0, 1.0, NULL, NULL) );
1107
1108 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/lpitersquot",
1109 "quotient of sub-MIP LP iterations with respect to LP iterations so far",
1110 &heurdata->lpitersquot, TRUE, DEFAULT_LPITERSQUOT, 0.0, 1.0, NULL, NULL) );
1111
1112 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/mingap",
1113 "minimum primal-dual gap for which the heuristic is executed",
1114 &heurdata->mingap, TRUE, DEFAULT_MINGAP, 0.0, SCIPinfinity(scip), NULL, NULL) );
1115
1116 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/useuct",
1117 "should uct node selection be used at the beginning of the search?",
1118 &heurdata->useuct, TRUE, DEFAULT_USEUCT, NULL, NULL) );
1119
1120 return SCIP_OKAY;
1121}
#define EVENTHDLR_NAME
#define EVENTHDLR_DESC
#define DEFAULT_MAXNODES
#define DEFAULT_MINIMPROVE
Constraint handler for linear constraints in their most general form, .
#define NULL
Definition def.h:257
#define SCIP_Longint
Definition def.h:150
#define SCIP_Bool
Definition def.h:100
#define MIN(x, y)
Definition def.h:233
#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 SCIP_CALL_ABORT(x)
Definition def.h:343
#define SCIP_LONGINT_FORMAT
Definition def.h:157
#define REALABS(x)
Definition def.h:191
#define SCIP_LONGINT_MAX
Definition def.h:151
#define SCIP_CALL(x)
Definition def.h:364
#define DEFAULT_MINNODES
#define nnodes
Definition gastrans.c:74
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPchgRhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
SCIP_RETCODE SCIPcreateConsBasicLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs)
SCIP_RETCODE SCIPcheckCopyLimits(SCIP *sourcescip, SCIP_Bool *success)
Definition scip_copy.c:3250
SCIP_RETCODE SCIPcopyLimits(SCIP *sourcescip, SCIP *targetscip)
Definition scip_copy.c:3293
SCIP_Bool SCIPisStopped(SCIP *scip)
SCIP_RETCODE SCIPfree(SCIP **scip)
SCIP_RETCODE SCIPcreate(SCIP **scip)
int SCIPgetNObjVars(SCIP *scip)
Definition scip_prob.c:2616
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition scip_prob.c:2115
int SCIPgetNVars(SCIP *scip)
Definition scip_prob.c:2246
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition scip_prob.c:3274
SCIP_Real SCIPgetObjNorm(SCIP *scip)
Definition scip_prob.c:1880
int SCIPgetNFixedVars(SCIP *scip)
Definition scip_prob.c:2705
int SCIPgetNBinVars(SCIP *scip)
Definition scip_prob.c:2293
SCIP_Bool SCIPisObjIntegral(SCIP *scip)
Definition scip_prob.c:1801
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition misc.c:3095
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition misc.c:3284
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition misc.c:3061
#define SCIPdebugMsg
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
SCIP_RETCODE SCIPdeleteSubproblemProximity(SCIP *scip)
SCIP_RETCODE SCIPapplyProximity(SCIP *scip, SCIP_HEUR *heur, SCIP_RESULT *result, SCIP_Real minimprove, SCIP_Longint nnodes, SCIP_Longint nlpiters, SCIP_Longint *nusednodes, SCIP_Longint *nusedlpiters, SCIP_Bool freesubscip)
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_Bool SCIPisParamFixed(SCIP *scip, const char *name)
Definition scip_param.c:219
SCIP_RETCODE SCIPsetLongintParam(SCIP *scip, const char *name, SCIP_Longint value)
Definition scip_param.c:545
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 SCIPsetIntParam(SCIP *scip, const char *name, int value)
Definition scip_param.c:487
SCIP_RETCODE SCIPsetSubscipsOff(SCIP *scip, SCIP_Bool quiet)
Definition scip_param.c:904
SCIP_RETCODE SCIPsetPresolving(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition scip_param.c:956
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 SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
Definition scip_param.c:429
SCIP_RETCODE SCIPsetSeparating(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition scip_param.c:985
SCIP_RETCODE SCIPincludeHeurProximity(SCIP *scip)
SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition scip_cons.c:1173
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_EVENTHDLR * SCIPfindEventhdlr(SCIP *scip, const char *name)
Definition scip_event.c:241
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition event.c:396
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_RETCODE SCIPdropEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition scip_event.c:333
SCIP_Bool SCIPisExact(SCIP *scip)
Definition scip_exact.c:193
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:183
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition heur.c:1368
SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
Definition scip_heur.c:122
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:167
SCIP_RETCODE SCIPsetHeurExitsol(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:247
SCIP_HEUR * SCIPfindHeur(SCIP *scip, const char *name)
Definition scip_heur.c:263
void SCIPheurMarkExact(SCIP_HEUR *heur)
Definition heur.c:1457
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:199
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition heur.c:1467
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition heur.c:1378
SCIP_RETCODE SCIPchgVarLbDive(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition scip_lp.c:2384
SCIP_RETCODE SCIPchgVarUbDive(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition scip_lp.c:2416
SCIP_RETCODE SCIPstartDive(SCIP *scip)
Definition scip_lp.c:2206
SCIP_RETCODE SCIPsolveDiveLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition scip_lp.c:2643
SCIP_RETCODE SCIPendDive(SCIP *scip)
Definition scip_lp.c:2255
SCIP_Bool SCIPinDive(SCIP *scip)
Definition scip_lp.c:2740
SCIP_Bool SCIPisLPConstructed(SCIP *scip)
Definition scip_lp.c:105
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition scip_lp.c:174
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition scip_mem.h:110
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition scip_mem.c:57
#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 SCIPfreeBlockMemory(scip, ptr)
Definition scip_mem.h:108
#define SCIPallocBlockMemory(scip, ptr)
Definition scip_mem.h:89
SCIP_Bool SCIPisNLPConstructed(SCIP *scip)
Definition scip_nlp.c:110
SCIP_NODESEL * SCIPfindNodesel(SCIP *scip, const char *name)
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
Definition scip_sol.c:2986
SCIP_Longint SCIPsolGetNodenum(SCIP_SOL *sol)
Definition sol.c:4254
int SCIPgetNSols(SCIP *scip)
Definition scip_sol.c:2887
SCIP_HEUR * SCIPsolGetHeur(SCIP_SOL *sol)
Definition sol.c:4274
SCIP_RETCODE SCIPunlinkSol(SCIP *scip, SCIP_SOL *sol)
Definition scip_sol.c:1504
SCIP_Bool SCIPsolIsOriginal(SCIP_SOL *sol)
Definition sol.c:4155
int SCIPsolGetIndex(SCIP_SOL *sol)
Definition sol.c:4305
SCIP_RETCODE SCIPsetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition scip_sol.c:1660
SCIP_RETCODE SCIPtrySol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition scip_sol.c:4017
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
Definition scip_sol.c:1890
SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
Definition scip_sol.c:1569
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition scip_sol.c:1763
SCIP_Real SCIPgetSolTransObj(SCIP *scip, SCIP_SOL *sol)
Definition scip_sol.c:2003
SCIP_RETCODE SCIPtransformProb(SCIP *scip)
Definition scip_solve.c:232
SCIP_RETCODE SCIPpresolve(SCIP *scip)
SCIP_RETCODE SCIPfreeTransform(SCIP *scip)
SCIP_RETCODE SCIPinterruptSolve(SCIP *scip)
SCIP_RETCODE SCIPsolve(SCIP *scip)
SCIP_Longint SCIPgetNSolsFound(SCIP *scip)
SCIP_Real SCIPgetPrimalbound(SCIP *scip)
SCIP_Real SCIPgetGap(SCIP *scip)
SCIP_Longint SCIPgetNNodes(SCIP *scip)
SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
SCIP_Real SCIPgetLowerbound(SCIP *scip)
SCIP_Longint SCIPgetNRootLPIterations(SCIP *scip)
SCIP_Longint SCIPgetNRootFirstLPIterations(SCIP *scip)
SCIP_Longint SCIPgetNLPIterations(SCIP *scip)
SCIP_RETCODE SCIPcopyLargeNeighborhoodSearch(SCIP *sourcescip, SCIP *subscip, SCIP_HASHMAP *varmap, const char *suffix, SCIP_VAR **fixedvars, SCIP_Real *fixedvals, int nfixedvars, SCIP_Bool uselprows, SCIP_Bool copycuts, SCIP_Bool *success, SCIP_Bool *valid)
Definition heuristics.c:953
SCIP_Real SCIPgetSolvingTime(SCIP *scip)
SCIP_Real SCIPgetPresolvingTime(SCIP *scip)
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPfeastol(SCIP *scip)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition var.c:23510
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition var.c:23418
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition var.c:24300
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition var.c:23932
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition var.c:24174
SCIP_RETCODE SCIPchgVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition scip_var.c:6141
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition var.c:23522
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition var.c:24266
SCIP_RETCODE SCIPchgVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition scip_var.c:6230
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition var.c:24152
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition scip_var.c:5372
#define HEUR_TIMING
return SCIP_OKAY
#define HEUR_FREQOFS
#define HEUR_DESC
#define HEUR_DISPCHAR
#define HEUR_MAXDEPTH
#define HEUR_PRIORITY
SCIPfreeSol(scip, &heurdata->sol))
#define HEUR_NAME
#define HEUR_FREQ
#define HEUR_USESSUBSCIP
SCIPcreateSol(scip, &heurdata->sol, heur))
#define DEFAULT_NODESQUOT
Definition heur_alns.c:90
#define DEFAULT_WAITINGNODES
Definition heur_alns.c:96
#define DEFAULT_NODESOFS
Definition heur_clique.c:94
#define DEFAULT_USEUCT
#define DEFAULT_USELPROWS
#define DEFAULT_MINGAP
SCIP_Bool lperror
static SCIP_SOL * sol
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
SCIPlinkLPSol(scip, sol))
heurdata usednodes
Definition heur_locks.c:163
SCIP_VAR * var
static SCIP_RETCODE solveLp(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
#define DEFAULT_RESTART
static SCIP_RETCODE createNewSol(SCIP *scip, SCIP *subscip, SCIP_VAR **subvars, SCIP_HEUR *heur, SCIP_SOL *subsol, SCIP_Bool usefinallp, SCIP_Bool *success)
#define DEFAULT_BINVARQUOT
#define DEFAULT_USEFINALLP
static SCIP_RETCODE setupSubproblem(SCIP_HEURDATA *heurdata, SCIP *subscip)
static SCIP_RETCODE deleteSubproblem(SCIP *scip, SCIP_HEURDATA *heurdata)
#define DEFAULT_LPITERSQUOT
#define DEFAULT_MAXLPITERS
#define DEFAULT_MINLPITERS
improvement heuristic which uses an auxiliary objective instead of the original objective function wh...
static SCIP_VAR ** vars
methods commonly used by primal heuristics
memory allocation routines
public methods for managing events
public methods for primal heuristics
public methods for message output
#define SCIPerrorMessage
Definition pub_message.h:64
#define SCIPstatisticMessage
#define SCIPdebug(x)
Definition pub_message.h:93
public data structures and miscellaneous methods
public methods for primal CIP solutions
public methods for problem variables
public methods for branching rule plugins and branching
public methods for constraint handler plugins and constraints
public methods for problem copies
public methods for event handler plugins and event handlers
public methods for exact solving
general public methods
public methods for primal heuristic plugins and divesets
public methods for the LP relaxation, rows and columns
public methods for memory management
public methods for message handling
public methods for nonlinear relaxation
public methods for node selector plugins
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for global and local (sub)problems
public methods for solutions
public solving methods
public methods for querying solving statistics
public methods for timing
public methods for SCIP variables
struct SCIP_Cons SCIP_CONS
Definition type_cons.h:63
struct SCIP_Eventhdlr SCIP_EVENTHDLR
Definition type_event.h:159
struct SCIP_EventData SCIP_EVENTDATA
Definition type_event.h:179
#define SCIP_DECL_EVENTEXEC(x)
Definition type_event.h:259
#define SCIP_EVENTTYPE_NODESOLVED
Definition type_event.h:138
#define SCIP_DECL_HEURCOPY(x)
Definition type_heur.h:97
struct SCIP_HeurData SCIP_HEURDATA
Definition type_heur.h:77
struct SCIP_Heur SCIP_HEUR
Definition type_heur.h:76
#define SCIP_DECL_HEURINIT(x)
Definition type_heur.h:113
#define SCIP_DECL_HEURFREE(x)
Definition type_heur.h:105
#define SCIP_DECL_HEUREXITSOL(x)
Definition type_heur.h:143
#define SCIP_DECL_HEUREXEC(x)
Definition type_heur.h:163
@ SCIP_LPSOLSTAT_OPTIMAL
Definition type_lp.h:44
@ SCIP_LPSOLSTAT_ITERLIMIT
Definition type_lp.h:48
struct SCIP_HashMap SCIP_HASHMAP
Definition type_misc.h:106
@ SCIP_PARAMSETTING_OFF
@ SCIP_PARAMSETTING_FAST
@ SCIP_DIDNOTRUN
Definition type_result.h:42
@ SCIP_DIDNOTFIND
Definition type_result.h:44
@ SCIP_FOUNDSOL
Definition type_result.h:56
enum SCIP_Result SCIP_RESULT
Definition type_result.h:61
@ SCIP_PLUGINNOTFOUND
@ SCIP_INVALIDCALL
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
struct SCIP_Sol SCIP_SOL
Definition type_sol.h:57
struct SCIP_Var SCIP_VAR
Definition type_var.h:166
@ SCIP_VARSTATUS_COLUMN
Definition type_var.h:53