SCIP Doxygen Documentation
Loading...
Searching...
No Matches
heur_rens.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_rens.c
26 * @ingroup DEFPLUGINS_HEUR
27 * @brief LNS heuristic that finds the optimal rounding to a given point
28 * @author Timo Berthold
29 */
30
31/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
32
34#include "scip/heuristics.h"
35#include "scip/heur_rens.h"
36#include "scip/pub_event.h"
37#include "scip/pub_heur.h"
38#include "scip/pub_message.h"
39#include "scip/pub_misc.h"
40#include "scip/pub_sol.h"
41#include "scip/pub_var.h"
42#include "scip/scip_branch.h"
43#include "scip/scip_cons.h"
44#include "scip/scip_copy.h"
45#include "scip/scip_event.h"
46#include "scip/scip_general.h"
47#include "scip/scip_heur.h"
48#include "scip/scip_lp.h"
49#include "scip/scip_mem.h"
50#include "scip/scip_message.h"
51#include "scip/scip_nlp.h"
52#include "scip/scip_nlpi.h"
53#include "scip/scip_nodesel.h"
54#include "scip/scip_numerics.h"
55#include "scip/scip_param.h"
56#include "scip/scip_prob.h"
57#include "scip/scip_sol.h"
58#include "scip/scip_solve.h"
60#include "scip/scip_timing.h"
61#include "scip/scip_var.h"
62
63
64/* default values for standard parameters that every primal heuristic has in SCIP */
65#define HEUR_NAME "rens"
66#define HEUR_DESC "LNS exploring fractional neighborhood of relaxation's optimum"
67#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_LNS
68#define HEUR_PRIORITY -1100000
69#define HEUR_FREQ 0
70#define HEUR_FREQOFS 0
71#define HEUR_MAXDEPTH -1
72#define HEUR_TIMING SCIP_HEURTIMING_AFTERLPNODE
73#define HEUR_USESSUBSCIP TRUE /**< does the heuristic use a secondary SCIP instance? */
74
75/* default values for RENS-specific plugins */
76#define DEFAULT_BINARYBOUNDS TRUE /* should general integers get binary bounds [floor(.),ceil(.)] ? */
77#define DEFAULT_MAXNODES 5000LL /* maximum number of nodes to regard in the subproblem */
78#define DEFAULT_MINFIXINGRATE 0.5 /* minimum percentage of integer variables that have to be fixed */
79#define DEFAULT_MINIMPROVE 0.01 /* factor by which RENS should at least improve the incumbent */
80#define DEFAULT_MINNODES 50LL /* minimum number of nodes to regard in the subproblem */
81#define DEFAULT_NODESOFS 500LL /* number of nodes added to the contingent of the total nodes */
82#define DEFAULT_NODESQUOT 0.1 /* subproblem nodes in relation to nodes of the original problem */
83#define DEFAULT_LPLIMFAC 2.0 /* factor by which the limit on the number of LP depends on the node limit */
84#define DEFAULT_STARTSOL 'l' /* solution that is used for fixing values */
85#define STARTSOL_CHOICES "nl" /* possible values for startsol ('l'p relaxation, 'n'lp relaxation) */
86#define DEFAULT_USELPROWS FALSE /* should subproblem be created out of the rows in the LP rows,
87 * otherwise, the copy constructors of the constraints handlers are used */
88#define DEFAULT_COPYCUTS TRUE /* if DEFAULT_USELPROWS is FALSE, then should all active cuts from the cutpool
89 * of the original scip be copied to constraints of the subscip
90 */
91#define DEFAULT_EXTRATIME FALSE /* should the RENS sub-CIP get its own full time limit? This is only
92 * implemented for testing and not recommended to be used!
93 */
94#define DEFAULT_ADDALLSOLS FALSE /* should all subproblem solutions be added to the original SCIP? */
95
96#define DEFAULT_FULLSCALE FALSE /* should the RENS sub-CIP be solved with full-scale SCIP settings, including
97 * techniques that merely work on the dual bound, e.g., cuts? This is only
98 * implemented for testing and not recommended to be used!
99 */
100#define DEFAULT_BESTSOLLIMIT -1 /* limit on number of improving incumbent solutions in sub-CIP */
101#define DEFAULT_USEUCT FALSE /* should uct node selection be used at the beginning of the search? */
102
103/* event handler properties */
104#define EVENTHDLR_NAME "Rens"
105#define EVENTHDLR_DESC "LP event handler for " HEUR_NAME " heuristic"
106
107/*
108 * Data structures
109 */
110
111/** primal heuristic data */
112struct SCIP_HeurData
113{
114 SCIP_Longint maxnodes; /**< maximum number of nodes to regard in the subproblem */
115 SCIP_Longint minnodes; /**< minimum number of nodes to regard in the subproblem */
116 SCIP_Longint nodesofs; /**< number of nodes added to the contingent of the total nodes */
117 SCIP_Longint usednodes; /**< nodes already used by RENS in earlier calls */
118 SCIP_Real minfixingrate; /**< minimum percentage of integer variables that have to be fixed */
119 SCIP_Real minimprove; /**< factor by which RENS should at least improve the incumbent */
120 SCIP_Real nodesquot; /**< subproblem nodes in relation to nodes of the original problem */
121 SCIP_Real nodelimit; /**< the nodelimit employed in the current sub-SCIP, for the event handler*/
122 SCIP_Real lplimfac; /**< factor by which the limit on the number of LP depends on the node limit */
123 char startsol; /**< solution used for fixing values ('l'p relaxation, 'n'lp relaxation) */
124 SCIP_Bool binarybounds; /**< should general integers get binary bounds [floor(.),ceil(.)] ? */
125 SCIP_Bool uselprows; /**< should subproblem be created out of the rows in the LP rows? */
126 SCIP_Bool copycuts; /**< if uselprows == FALSE, should all active cuts from cutpool be copied
127 * to constraints in subproblem? */
128 SCIP_Bool extratime; /**< should the RENS sub-CIP get its own full time limit? This is only
129 * implemented for testing and not recommended to be used! */
130 SCIP_Bool addallsols; /**< should all subproblem solutions be added to the original SCIP? */
131 SCIP_Bool fullscale; /**< should the RENS sub-CIP be solved with full-scale SCIP settings,
132 * including techniques that merely work on the dual bound, e.g., cuts?
133 * This is only implemented for testing and not recommended to be used! */
134 int bestsollimit; /**< limit on number of improving incumbent solutions in sub-CIP */
135 SCIP_Bool useuct; /**< should uct node selection be used at the beginning of the search? */
136};
138
139/*
140 * Local methods
141 */
142
143/** compute the number of initial fixings and check whether the fixing rate exceeds the minimum fixing rate */
144static
146 SCIP* scip, /**< SCIP data structure */
147 SCIP_VAR** fixedvars, /**< array to store source SCIP variables whose copies should be fixed in the sub-SCIP */
148 SCIP_Real* fixedvals, /**< array to store solution values for variable fixing */
149 int* nfixedvars, /**< pointer to store the number of fixed variables */
150 int fixedvarssize, /**< size of the arrays to store fixing variables */
151 SCIP_Real minfixingrate, /**< percentage of integer variables that have to be fixed */
152 char* startsol, /**< pointer to solution used for fixing values ('l'p relaxation, 'n'lp relaxation) */
153 SCIP_Real* fixingrate, /**< percentage of integers that get actually fixed */
154 SCIP_Bool* success /**< pointer to store whether minimum fixingrate is exceeded */
155 )
156{
157 SCIP_VAR** vars;
158 int nintvars;
159 int nbinvars;
160 int i;
161
162 assert(fixedvars != NULL);
163 assert(fixedvals != NULL);
164 assert(nfixedvars != NULL);
165
166 *fixingrate = 1.0;
167 *success = FALSE;
168
169 /* if there is no NLP relaxation available (e.g., because the presolved problem is linear), use LP relaxation */
171 {
172 SCIPdebugMsg(scip, "no NLP present, use LP relaxation instead\n");
173 (*startsol) = 'l';
174 }
175
176 /* get required variable data */
177 SCIP_CALL( SCIPgetVarsData(scip, &vars, NULL, &nbinvars, &nintvars, NULL, NULL) );
178 assert(fixedvarssize >= nbinvars + nintvars);
179 (*nfixedvars) = 0;
180
181 /* try to solve NLP relaxation */
182 if( (*startsol) == 'n' )
183 {
184 SCIP_NLPSOLSTAT stat;
185
186 /* only call this function if NLP relaxation is available */
188
189 SCIPdebugMsg(scip, "try to solve NLP relaxation to obtain fixing values\n");
190
191 /* set starting point to LP solution */
193
194 /* solve NLP relaxation
195 * TODO pick some less arbitrary iterlimit
196 */
197 SCIP_CALL( SCIPsolveNLP(scip, .iterlimit = 3000) ); /*lint !e666*/
198
199 /* get solution status of NLP solver */
200 stat = SCIPgetNLPSolstat(scip);
201 *success = (stat == SCIP_NLPSOLSTAT_GLOBOPT) || (stat == SCIP_NLPSOLSTAT_LOCOPT) || stat == (SCIP_NLPSOLSTAT_FEASIBLE);
202 SCIPdebugMsg(scip, "solving NLP relaxation was %s successful (stat=%d)\n", *success ? "" : "not", stat);
203
204 /* it the NLP was not successfully solved we stop the heuristic right away */
205 if( !(*success) )
206 return SCIP_OKAY;
207 }
208 else
209 {
210 assert(*startsol == 'l');
211 }
212
213 /* count the number of variables with integral solution values in the current NLP or LP solution */
214 for( i = 0; i < nbinvars + nintvars; ++i )
215 {
216 SCIP_Real solval;
217
218 /* get solution value in the relaxation in question */
219 solval = (*startsol == 'l') ? SCIPvarGetLPSol(vars[i]) : SCIPvarGetNLPSol(vars[i]);
220
221 /* append variable to the buffer storage for integer variables with integer solution values */
222 if( SCIPisFeasIntegral(scip, solval) )
223 {
224 /* fix variables to current LP/NLP solution if it is integral,
225 * use exact integral value, if the variable is only integral within numerical tolerances
226 */
227 solval = SCIPfloor(scip, solval+0.5);
228 fixedvars[(*nfixedvars)] = vars[i];
229 fixedvals[(*nfixedvars)] = solval;
230 (*nfixedvars)++;
231 }
232 }
233
234 /* abort, if all integer variables were fixed (which should not happen for MIP),
235 * but frequently happens for MINLPs using an LP relaxation
236 */
237 if( (*nfixedvars) == nbinvars + nintvars )
238 return SCIP_OKAY;
239
240 *fixingrate = (*nfixedvars) / (SCIP_Real)(MAX(nbinvars + nintvars, 1));
241
242 /* abort, if the amount of fixed variables is insufficient */
243 if( *fixingrate < minfixingrate )
244 return SCIP_OKAY;
245
246 *success = TRUE;
247 return SCIP_OKAY;
248}
249
250/** fixes bounds of unfixed integer variables to binary bounds */
251static
253 SCIP* scip, /**< original SCIP data structure */
254 SCIP* subscip, /**< SCIP data structure for the subproblem */
255 SCIP_VAR** subvars, /**< the variables of the subproblem */
256 char startsol /**< solution used for fixing values ('l'p relaxation, 'n'lp relaxation) */
257 )
258{
259 SCIP_VAR** vars; /* original SCIP variables */
260
261 int nbinvars;
262 int nintvars;
263 int i;
264
265 assert(scip != NULL);
266 assert(subscip != NULL);
267 assert(subvars != NULL);
268
269 assert(startsol == 'l' || startsol == 'n');
270
271 /* get required variable data */
272 SCIP_CALL( SCIPgetVarsData(scip, &vars, NULL, &nbinvars, &nintvars, NULL, NULL) );
273
274 /* change bounds of integer variables of the subproblem */
275 for( i = nbinvars; i < nbinvars + nintvars; i++ )
276 {
277 SCIP_Real solval;
278 SCIP_Real lb;
279 SCIP_Real ub;
280
281 if( subvars[i] == NULL )
282 continue;
283
284 /* get the current LP/NLP solution for each variable */
285 if( startsol == 'l')
286 solval = SCIPvarGetLPSol(vars[i]);
287 else
288 solval = SCIPvarGetNLPSol(vars[i]);
289
290 /* restrict bounds to nearest integers if the solution value is not already integer */
291 if( !SCIPisFeasIntegral(scip, solval) )
292 {
293 lb = SCIPfeasFloor(scip, solval);
294 ub = SCIPfeasCeil(scip, solval);
295
296 /* perform the bound change */
297 SCIP_CALL( SCIPchgVarLbGlobal(subscip, subvars[i], lb) );
298 SCIP_CALL( SCIPchgVarUbGlobal(subscip, subvars[i], ub) );
299 }
300 else
301 {
302 /* the variable bounds should be already fixed to this solution value */
303 assert(SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(subvars[i]), SCIPfloor(scip, solval+0.5)));
304 assert(SCIPisFeasEQ(scip, SCIPvarGetUbGlobal(subvars[i]), SCIPfloor(scip, solval+0.5)));
305 }
306 }
307
308 return SCIP_OKAY;
309}
310
312/* ---------------- Callback methods of event handler ---------------- */
313
314/* exec the event handler
315 *
316 * we interrupt the solution process
317 */
318static
319SCIP_DECL_EVENTEXEC(eventExecRens)
320{
322
323 assert(eventhdlr != NULL);
324 assert(eventdata != NULL);
325 assert(event != NULL);
327
329
330 heurdata = (SCIP_HEURDATA*)eventdata;
331 assert(heurdata != NULL);
332
333 /* interrupt solution process of sub-SCIP */
334 if( SCIPgetNLPs(scip) > heurdata->lplimfac * heurdata->nodelimit )
335 {
336 SCIPdebugMsg(scip, "interrupt after %" SCIP_LONGINT_FORMAT " LPs\n",SCIPgetNLPs(scip));
338 }
339
340 return SCIP_OKAY;
341}
342
343/** setup and solve the RENS sub-SCIP */
344static
346 SCIP* scip, /**< SCIP data structure */
347 SCIP* subscip, /**< sub SCIP data structure */
348 SCIP_RESULT* result, /**< result pointer */
349 SCIP_HEUR* heur, /**< heuristic data structure */
350 SCIP_VAR** fixedvars, /**< array of variables that should be fixed */
351 SCIP_Real* fixedvals, /**< array of fixing values */
352 int nfixedvars, /**< number of variables that should be fixed */
353 SCIP_Real intfixingrate, /**< percentage of integer variables fixed */
354 SCIP_Real minfixingrate, /**< minimum percentage of integer variables that have to be fixed */
355 SCIP_Real minimprove, /**< factor by which RENS should at least improve the incumbent */
356 SCIP_Longint maxnodes, /**< maximum number of nodes for the subproblem */
357 SCIP_Longint nstallnodes, /**< number of stalling nodes for the subproblem */
358 char startsol, /**< solution used for fixing values ('l'p relaxation, 'n'lp relaxation) */
359 SCIP_Bool binarybounds, /**< should general integers get binary bounds [floor(.),ceil(.)]? */
360 SCIP_Bool uselprows /**< should subproblem be created out of the rows in the LP rows? */
361 )
362{
363 SCIP_VAR** vars; /* original problem's variables */
364 SCIP_VAR** subvars; /* subproblem's variables */
365 SCIP_HEURDATA* heurdata; /* heuristic data */
366 SCIP_EVENTHDLR* eventhdlr; /* event handler for LP events */
367 SCIP_HASHMAP* varmapfw; /* mapping of SCIP variables to sub-SCIP variables */
368 SCIP_Real cutoff; /* objective cutoff for the subproblem */
369 SCIP_Real allfixingrate; /* percentage of all variables fixed */
370 SCIP_Bool success;
371 int i;
372 int nvars; /* number of original problem's variables */
373 SCIP_RETCODE retcode;
374
375 assert(scip != NULL);
376 assert(subscip != NULL);
377 assert(heur != NULL);
378 assert(result != NULL);
379
381 assert(heurdata != NULL);
382
383 /* get variable data */
385
386 /* create the variable mapping hash map */
387 SCIP_CALL( SCIPhashmapCreate(&varmapfw, SCIPblkmem(subscip), nvars) );
388
389 /* create a problem copy as sub SCIP */
390 SCIP_CALL( SCIPcopyLargeNeighborhoodSearch(scip, subscip, varmapfw, "rens", fixedvars, fixedvals, nfixedvars, uselprows,
391 heurdata->copycuts, &success, NULL) );
392
393 eventhdlr = NULL;
394 /* create event handler for LP events */
395 SCIP_CALL( SCIPincludeEventhdlrBasic(subscip, &eventhdlr, EVENTHDLR_NAME, EVENTHDLR_DESC, eventExecRens, NULL) );
396 if( eventhdlr == NULL )
397 {
398 SCIPerrorMessage("event handler for " HEUR_NAME " heuristic not found.\n");
399 return SCIP_PLUGINNOTFOUND;
400 }
401
402 /* copy subproblem variables into the same order as the source SCIP variables */
404 for( i = 0; i < nvars; i++ )
405 subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, vars[i]);
406
407 /* free hash map */
408 SCIPhashmapFree(&varmapfw);
409
410 /* restrict the integer variables to binary bounds */
411 if( binarybounds )
412 {
413 SCIP_CALL( restrictToBinaryBounds(scip, subscip, subvars, startsol) );
414 }
415
416 SCIPdebugMsg(scip, "RENS subproblem: %d vars, %d cons\n", SCIPgetNVars(subscip), SCIPgetNConss(subscip));
417
418 /* do not abort subproblem on CTRL-C */
419 SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
420
421#ifdef SCIP_DEBUG
422 /* for debugging, enable full output */
423 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 5) );
424 SCIP_CALL( SCIPsetIntParam(subscip, "display/freq", 100000000) );
425#else
426 /* disable statistic timing inside sub SCIP and output to console */
427 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) );
428 SCIP_CALL( SCIPsetBoolParam(subscip, "timing/statistictiming", FALSE) );
429#endif
430
431 /* set limits for the subproblem */
432 SCIP_CALL( SCIPcopyLimits(scip, subscip) );
433 heurdata->nodelimit = maxnodes;
434 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/stallnodes", nstallnodes) );
435 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", maxnodes) );
436 SCIP_CALL( SCIPsetIntParam(subscip, "limits/bestsol", heurdata->bestsollimit) );
437
438 /* forbid recursive call of heuristics and separators solving sub-SCIPs */
439 SCIP_CALL( SCIPsetSubscipsOff(subscip, TRUE) );
440
441 /* disable expensive techniques that merely work on the dual bound */
442 if( !heurdata->fullscale )
443 {
444 /* disable cutting plane separation */
446
447 /* disable expensive presolving */
449
450 /* use best estimate node selection */
451 if( SCIPfindNodesel(subscip, "estimate") != NULL && !SCIPisParamFixed(subscip, "nodeselection/estimate/stdpriority") )
452 {
453 SCIP_CALL( SCIPsetIntParam(subscip, "nodeselection/estimate/stdpriority", INT_MAX/4) );
454 }
455
456 /* activate uct node selection at the top of the tree */
457 if( heurdata->useuct && SCIPfindNodesel(subscip, "uct") != NULL && !SCIPisParamFixed(subscip, "nodeselection/uct/stdpriority") )
458 {
459 SCIP_CALL( SCIPsetIntParam(subscip, "nodeselection/uct/stdpriority", INT_MAX/2) );
460 }
461
462 /* use inference branching */
463 if( SCIPfindBranchrule(subscip, "inference") != NULL && !SCIPisParamFixed(subscip, "branching/inference/priority") )
464 {
465 SCIP_CALL( SCIPsetIntParam(subscip, "branching/inference/priority", INT_MAX/4) );
466 }
467
468 /* enable conflict analysis, disable analysis of boundexceeding LPs, and restrict conflict pool */
469 if( !SCIPisParamFixed(subscip, "conflict/enable") )
470 {
471 SCIP_CALL( SCIPsetBoolParam(subscip, "conflict/enable", TRUE) );
472 }
473 if( !SCIPisParamFixed(subscip, "conflict/useboundlp") )
474 {
475 SCIP_CALL( SCIPsetCharParam(subscip, "conflict/useboundlp", 'o') );
476 }
477 if( !SCIPisParamFixed(subscip, "conflict/maxstoresize") )
478 {
479 SCIP_CALL( SCIPsetIntParam(subscip, "conflict/maxstoresize", 100) );
480 }
481
482 /* speed up sub-SCIP by not checking dual LP feasibility */
483 SCIP_CALL( SCIPsetBoolParam(subscip, "lp/checkdualfeas", FALSE) );
484 }
485
486 /* if there is already a solution, add an objective cutoff */
487 if( SCIPgetNSols(scip) > 0 )
488 {
489 SCIP_Real upperbound;
491
492 upperbound = SCIPgetUpperbound(scip) - SCIPsumepsilon(scip);
493
495 {
496 cutoff = (1 - minimprove) * SCIPgetUpperbound(scip)
497 + minimprove * SCIPgetLowerbound(scip);
498 }
499 else
500 {
501 if( SCIPgetUpperbound(scip) >= 0 )
502 cutoff = (1 - minimprove) * SCIPgetUpperbound(scip);
503 else
504 cutoff = (1 + minimprove) * SCIPgetUpperbound(scip);
505 }
506 cutoff = MIN(upperbound, cutoff);
507 SCIP_CALL( SCIPsetObjlimit(subscip, cutoff) );
508 }
509
510 /* presolve the subproblem */
511 retcode = SCIPpresolve(subscip);
512
513 /* errors in solving the subproblem should not kill the overall solving process;
514 * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
515 */
516 if( retcode != SCIP_OKAY )
517 {
518 SCIPwarningMessage(scip, "Error while presolving subproblem in RENS heuristic; sub-SCIP terminated with code <%d>\n", retcode);
519 SCIPABORT(); /*lint --e{527}*/
520 goto TERMINATE;
521 }
522
523 SCIPdebugMsg(scip, "RENS presolved subproblem: %d vars, %d cons, success=%u\n", SCIPgetNVars(subscip), SCIPgetNConss(subscip), success);
524
525 allfixingrate = (SCIPgetNOrigVars(subscip) - SCIPgetNVars(subscip)) / (SCIP_Real)SCIPgetNOrigVars(subscip);
526
527 /* additional variables added in presolving may lead to the subSCIP having more variables than the original */
528 allfixingrate = MAX(allfixingrate, 0.0);
529
530 /* after presolving, we should have at least reached a certain fixing rate over ALL variables (including continuous)
531 * to ensure that not only the MIP but also the LP relaxation is easy enough
532 */
533 if( allfixingrate >= minfixingrate / 2.0 )
534 {
535 SCIP_SOL** subsols;
536 int nsubsols;
537
538 /* catch LP events of sub-SCIP */
539 assert(eventhdlr != NULL);
540 SCIP_CALL( SCIPtransformProb(subscip) );
542
543 /* solve the subproblem */
544 SCIPdebugMsg(scip, "solving subproblem: nstallnodes=%" SCIP_LONGINT_FORMAT ", maxnodes=%" SCIP_LONGINT_FORMAT "\n", nstallnodes, maxnodes);
545 retcode = SCIPsolve(subscip);
546
547 /* drop LP events of sub-SCIP */
549
550 /* errors in solving the subproblem should not kill the overall solving process;
551 * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
552 */
553 if( retcode != SCIP_OKAY )
554 {
555 SCIPwarningMessage(scip, "Error while solving subproblem in RENS heuristic; sub-SCIP terminated with code <%d>\n", retcode);
556 SCIPABORT();
557 goto TERMINATE;
558 }
559 else
560 {
561 /* transfer variable statistics from sub-SCIP */
562 SCIP_CALL( SCIPmergeVariableStatistics(subscip, scip, subvars, vars, nvars) );
563 }
564
565 /* print solving statistics of subproblem if we are in SCIP's debug mode */
567
568 /* check, whether a solution was found;
569 * due to numerics, it might happen that not all solutions are feasible -> try all solutions until one was accepted
570 */
571 nsubsols = SCIPgetNSols(subscip);
572 subsols = SCIPgetSols(subscip);
573 success = FALSE;
574 for( i = 0; i < nsubsols && (!success || heurdata->addallsols); ++i )
575 {
576 SCIP_SOL* newsol;
577
578 SCIP_CALL( SCIPtranslateSubSol(scip, subscip, subsols[i], heur, subvars, &newsol) );
579
580 SCIP_CALL( SCIPtrySolFree(scip, &newsol, FALSE, FALSE, TRUE, TRUE, TRUE, &success) );
581 if( success )
583 }
584
585 SCIPstatisticPrintf("RENS statistic: fixed %6.3f integer variables, %6.3f all variables, needed %6.1f seconds, %" SCIP_LONGINT_FORMAT " nodes, solution %10.4f found at node %" SCIP_LONGINT_FORMAT "\n",
586 intfixingrate, allfixingrate, SCIPgetSolvingTime(subscip), SCIPgetNNodes(subscip), success ? SCIPgetPrimalbound(scip) : SCIPinfinity(scip),
587 nsubsols > 0 ? SCIPsolGetNodenum(SCIPgetBestSol(subscip)) : -1 );
588 }
589 else
590 {
591 SCIPstatisticPrintf("RENS statistic: fixed only %6.3f integer variables, %6.3f all variables --> abort \n", intfixingrate, allfixingrate);
592 }
593
594TERMINATE:
595 /* free sub problem data */
597
598 return SCIP_OKAY;
599}
600
601/* ---------------- external methods of RENS heuristic ---------------- */
602
603/** main procedure of the RENS heuristic, creates and solves a sub-SCIP */
605 SCIP* scip, /**< original SCIP data structure */
606 SCIP_HEUR* heur, /**< heuristic data structure */
607 SCIP_RESULT* result, /**< result data structure */
608 SCIP_Real minfixingrate, /**< minimum percentage of integer variables that have to be fixed */
609 SCIP_Real minimprove, /**< factor by which RENS should at least improve the incumbent */
610 SCIP_Longint maxnodes, /**< maximum number of nodes for the subproblem */
611 SCIP_Longint nstallnodes, /**< number of stalling nodes for the subproblem */
612 char startsol, /**< solution used for fixing values ('l'p relaxation, 'n'lp relaxation) */
613 SCIP_Bool binarybounds, /**< should general integers get binary bounds [floor(.),ceil(.)]? */
614 SCIP_Bool uselprows /**< should subproblem be created out of the rows in the LP rows? */
615 )
616{
617 SCIP* subscip; /* the subproblem created by RENS */
618
619 SCIP_Real intfixingrate; /* percentage of integer variables fixed */
620
621 SCIP_VAR** fixedvars;
622 SCIP_Real* fixedvals;
623 int nfixedvars;
624 int fixedvarssize;
625 int nbinvars;
626 int nintvars;
627
628 SCIP_Bool success;
629 SCIP_RETCODE retcode;
630
631 assert(scip != NULL);
632 assert(heur != NULL);
633 assert(result != NULL);
634
635 assert(maxnodes >= 0);
636 assert(nstallnodes >= 0);
637
638 assert(0.0 <= minfixingrate && minfixingrate <= 1.0);
639 assert(0.0 <= minimprove && minimprove <= 1.0);
640 assert(startsol == 'l' || startsol == 'n');
641
643
644 nbinvars = SCIPgetNBinVars(scip);
645 nintvars = SCIPgetNIntVars(scip);
646
647 /* allocate buffer storage to keep fixings for the variables in the sub SCIP */
648 fixedvarssize = nbinvars + nintvars;
649 SCIP_CALL( SCIPallocBufferArray(scip, &fixedvars, fixedvarssize) );
650 SCIP_CALL( SCIPallocBufferArray(scip, &fixedvals, fixedvarssize) );
651 nfixedvars = 0;
652
653 /* compute the number of initial fixings and check if the fixing rate exceeds the minimum fixing rate */
654 SCIP_CALL( computeFixingrate(scip, fixedvars, fixedvals, &nfixedvars, fixedvarssize, minfixingrate, &startsol, &intfixingrate, &success) );
655
656 if( !success )
657 {
658 SCIPstatisticPrintf("RENS statistic: fixed only %5.2f integer variables --> abort \n", intfixingrate);
659 goto TERMINATE;
660 }
661
662 /* check whether there is enough time and memory left */
663 SCIP_CALL( SCIPcheckCopyLimits(scip, &success) );
664
665 if( !success )
666 goto TERMINATE;
667
669
670 /* initialize the subproblem */
671 SCIP_CALL( SCIPcreate(&subscip) );
672
673 retcode = setupAndSolveSubscip(scip, subscip, result, heur, fixedvars, fixedvals, nfixedvars, intfixingrate, minfixingrate, minimprove, maxnodes, nstallnodes, startsol, binarybounds, uselprows);
674
675 SCIP_CALL( SCIPfree(&subscip) );
676
677 SCIP_CALL( retcode );
678
679TERMINATE:
680 /* free buffer storage for variable fixings */
681 SCIPfreeBufferArray(scip, &fixedvals);
682 SCIPfreeBufferArray(scip, &fixedvars);
683
684 return SCIP_OKAY;
685}
687
688/*
689 * Callback methods of primal heuristic
690 */
691
692/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
693static
694SCIP_DECL_HEURCOPY(heurCopyRens)
695{ /*lint --e{715}*/
696 assert(scip != NULL);
697 assert(heur != NULL);
698
700
701 /* call inclusion method of primal heuristic */
703
704 return SCIP_OKAY;
705}
706
707/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
708static
709SCIP_DECL_HEURFREE(heurFreeRens)
710{ /*lint --e{715}*/
712
713 assert( heur != NULL );
714 assert( scip != NULL );
715
716 /* get heuristic data */
718 assert( heurdata != NULL );
719
720 /* free heuristic data */
722 SCIPheurSetData(heur, NULL);
723
724 return SCIP_OKAY;
725}
726
727/** initialization method of primal heuristic (called after problem was transformed) */
728static
729SCIP_DECL_HEURINIT(heurInitRens)
730{ /*lint --e{715}*/
732
733 assert( heur != NULL );
734 assert( scip != NULL );
735
736 /* get heuristic data */
738 assert( heurdata != NULL );
739
740 /* initialize data */
741 heurdata->usednodes = 0;
742
743 return SCIP_OKAY;
744}
745
746
747/** execution method of primal heuristic */
748static
749SCIP_DECL_HEUREXEC(heurExecRens)
750{ /*lint --e{715}*/
751 SCIP_HEURDATA* heurdata; /* heuristic's data */
752 SCIP_Longint nstallnodes; /* number of stalling nodes for the subproblem */
753
754 assert( heur != NULL );
755 assert( scip != NULL );
756 assert( result != NULL );
758
760
761 /* do not call heuristic of node was already detected to be infeasible */
762 if( nodeinfeasible )
763 return SCIP_OKAY;
764
765 /* get heuristic data */
767 assert( heurdata != NULL );
768
769 /* only call heuristic, if an optimal LP solution is at hand */
770 if( heurdata->startsol == 'l' && SCIPgetLPSolstat(scip) != SCIP_LPSOLSTAT_OPTIMAL )
771 return SCIP_OKAY;
772
773 /* only call heuristic, if the LP objective value is smaller than the cutoff bound */
774 if( heurdata->startsol == 'l' && SCIPisGE(scip, SCIPgetLPObjval(scip), SCIPgetCutoffbound(scip)) )
775 return SCIP_OKAY;
776
777 /* only continue with some fractional variables */
778 if( heurdata->startsol == 'l' && SCIPgetNLPBranchCands(scip) == 0 )
779 return SCIP_OKAY;
780
781 /* do not proceed, when we should use the NLP relaxation, but there is no NLP solver included in SCIP */
782 if( heurdata->startsol == 'n' && SCIPgetNNlpis(scip) == 0 )
783 return SCIP_OKAY;
784
786
787 /* calculate the maximal number of branching nodes until heuristic is aborted */
788 nstallnodes = (SCIP_Longint)(heurdata->nodesquot * SCIPgetNNodes(scip));
789
790 /* reward RENS if it succeeded often */
791 nstallnodes = (SCIP_Longint)(nstallnodes * 3.0 * (SCIPheurGetNBestSolsFound(heur)+1.0)/(SCIPheurGetNCalls(heur) + 1.0));
792 nstallnodes -= 100 * SCIPheurGetNCalls(heur); /* count the setup costs for the sub-SCIP as 100 nodes */
793 nstallnodes += heurdata->nodesofs;
794
795 /* determine the node limit for the current process */
796 nstallnodes -= heurdata->usednodes;
797 nstallnodes = MIN(nstallnodes, heurdata->maxnodes);
798
799 /* check whether we have enough nodes left to call subproblem solving */
800 if( nstallnodes < heurdata->minnodes )
801 {
802 SCIPdebugMsg(scip, "skipping RENS: nstallnodes=%" SCIP_LONGINT_FORMAT ", minnodes=%" SCIP_LONGINT_FORMAT "\n", nstallnodes, heurdata->minnodes);
803 return SCIP_OKAY;
804 }
805
806 if( SCIPisStopped(scip) && !heurdata->extratime )
807 return SCIP_OKAY;
808
809 SCIP_CALL( SCIPapplyRens(scip, heur, result, heurdata->minfixingrate, heurdata->minimprove,
810 heurdata->maxnodes, nstallnodes, heurdata->startsol, heurdata->binarybounds, heurdata->uselprows) );
811
812 return SCIP_OKAY;
814
815
816/*
817 * primal heuristic specific interface methods
818 */
819
820/** creates the rens primal heuristic and includes it in SCIP */
822 SCIP* scip /**< SCIP data structure */
823 )
824{
826 SCIP_HEUR* heur;
827
828 /* create Rens primal heuristic data */
830
831 /* include primal heuristic */
835
836 assert(heur != NULL);
837
838 /* primal heuristic is safe to use in exact solving mode */
839 SCIPheurMarkExact(heur);
840
841 /* set non-NULL pointers to callback methods */
842 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyRens) );
843 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeRens) );
844 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitRens) );
845
846 /* add rens primal heuristic parameters */
847
848 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minfixingrate",
849 "minimum percentage of integer variables that have to be fixable",
850 &heurdata->minfixingrate, FALSE, DEFAULT_MINFIXINGRATE, 0.0, 1.0, NULL, NULL) );
851
852 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxnodes",
853 "maximum number of nodes to regard in the subproblem",
855
856 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/nodesofs",
857 "number of nodes added to the contingent of the total nodes",
859
860 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/minnodes",
861 "minimum number of nodes required to start the subproblem",
862 &heurdata->minnodes, TRUE, DEFAULT_MINNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
863
864 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/nodesquot",
865 "contingent of sub problem nodes in relation to the number of nodes of the original problem",
866 &heurdata->nodesquot, FALSE, DEFAULT_NODESQUOT, 0.0, 1.0, NULL, NULL) );
867
868 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minimprove",
869 "factor by which RENS should at least improve the incumbent",
870 &heurdata->minimprove, TRUE, DEFAULT_MINIMPROVE, 0.0, 1.0, NULL, NULL) );
871
872 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/lplimfac",
873 "factor by which the limit on the number of LP depends on the node limit",
874 &heurdata->lplimfac, TRUE, DEFAULT_LPLIMFAC, 1.0, SCIP_REAL_MAX, NULL, NULL) );
875
876 SCIP_CALL( SCIPaddCharParam(scip, "heuristics/" HEUR_NAME "/startsol",
877 "solution that is used for fixing values ('l'p relaxation, 'n'lp relaxation)",
879
880 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/binarybounds",
881 "should general integers get binary bounds [floor(.),ceil(.)] ?",
882 &heurdata->binarybounds, TRUE, DEFAULT_BINARYBOUNDS, NULL, NULL) );
883
884 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/uselprows",
885 "should subproblem be created out of the rows in the LP rows?",
886 &heurdata->uselprows, TRUE, DEFAULT_USELPROWS, NULL, NULL) );
887
888 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/copycuts",
889 "if uselprows == FALSE, should all active cuts from cutpool be copied to constraints in subproblem?",
890 &heurdata->copycuts, TRUE, DEFAULT_COPYCUTS, NULL, NULL) );
891
892 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/extratime",
893 "should the RENS sub-CIP get its own full time limit? This is only for testing and not recommended!",
894 &heurdata->extratime, TRUE, DEFAULT_EXTRATIME, NULL, NULL) );
895
896 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/addallsols",
897 "should all subproblem solutions be added to the original SCIP?",
898 &heurdata->addallsols, TRUE, DEFAULT_ADDALLSOLS, NULL, NULL) );
899
900 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/fullscale",
901 "should the RENS sub-CIP be solved with cuts, conflicts, strong branching,... This is only for testing and not recommended!",
902 &heurdata->fullscale, TRUE, DEFAULT_FULLSCALE, NULL, NULL) );
903
904 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/bestsollimit",
905 "limit on number of improving incumbent solutions in sub-CIP",
906 &heurdata->bestsollimit, FALSE, DEFAULT_BESTSOLLIMIT, -1, INT_MAX, NULL, NULL) );
907
908 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/useuct",
909 "should uct node selection be used at the beginning of the search?",
910 &heurdata->useuct, TRUE, DEFAULT_USEUCT, NULL, NULL) );
911
912 return SCIP_OKAY;
913}
#define EVENTHDLR_NAME
#define EVENTHDLR_DESC
#define DEFAULT_MAXNODES
#define DEFAULT_MINIMPROVE
#define NULL
Definition def.h:257
#define SCIP_Longint
Definition def.h:150
#define SCIP_REAL_MAX
Definition def.h:167
#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_LONGINT_FORMAT
Definition def.h:157
#define SCIPABORT()
Definition def.h:336
#define SCIP_LONGINT_MAX
Definition def.h:151
#define SCIP_CALL(x)
Definition def.h:364
#define DEFAULT_MINNODES
SCIP_RETCODE SCIPcheckCopyLimits(SCIP *sourcescip, SCIP_Bool *success)
Definition scip_copy.c:3250
SCIP_RETCODE SCIPmergeVariableStatistics(SCIP *sourcescip, SCIP *targetscip, SCIP_VAR **sourcevars, SCIP_VAR **targetvars, int nvars)
Definition scip_copy.c:1255
SCIP_RETCODE SCIPtranslateSubSol(SCIP *scip, SCIP *subscip, SCIP_SOL *subsol, SCIP_HEUR *heur, SCIP_VAR **subvars, SCIP_SOL **newsol)
Definition scip_copy.c:1398
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 SCIPgetNIntVars(SCIP *scip)
Definition scip_prob.c:2340
SCIP_RETCODE SCIPsetObjlimit(SCIP *scip, SCIP_Real objlimit)
Definition scip_prob.c:1661
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
int SCIPgetNConss(SCIP *scip)
Definition scip_prob.c:3620
int SCIPgetNOrigVars(SCIP *scip)
Definition scip_prob.c:2838
int SCIPgetNBinVars(SCIP *scip)
Definition scip_prob.c:2293
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 SCIPapplyRens(SCIP *scip, SCIP_HEUR *heur, SCIP_RESULT *result, SCIP_Real minfixingrate, SCIP_Real minimprove, SCIP_Longint maxnodes, SCIP_Longint nstallnodes, char startsol, SCIP_Bool binarybounds, SCIP_Bool uselprows)
Definition heur_rens.c:596
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 SCIPaddCharParam(SCIP *scip, const char *name, const char *desc, char *valueptr, SCIP_Bool isadvanced, char defaultvalue, const char *allowedvalues, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:167
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, 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 scip_param.c:83
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 SCIPsetCharParam(SCIP *scip, const char *name, char value)
Definition scip_param.c:661
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 SCIPincludeHeurRens(SCIP *scip)
Definition heur_rens.c:813
SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
int SCIPgetNLPBranchCands(SCIP *scip)
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
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_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_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
Definition heur.c:1613
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:167
SCIP_Longint SCIPheurGetNCalls(SCIP_HEUR *heur)
Definition heur.c:1593
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_Bool SCIPhasCurrentNodeLP(SCIP *scip)
Definition scip_lp.c:87
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition scip_lp.c:174
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition scip_lp.c:253
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 SCIPfreeBlockMemory(scip, ptr)
Definition scip_mem.h:108
#define SCIPallocBlockMemory(scip, ptr)
Definition scip_mem.h:89
int SCIPgetNNlpis(SCIP *scip)
Definition scip_nlpi.c:205
SCIP_Bool SCIPisNLPConstructed(SCIP *scip)
Definition scip_nlp.c:110
SCIP_NLPSOLSTAT SCIPgetNLPSolstat(SCIP *scip)
Definition scip_nlp.c:574
#define SCIPsolveNLP(...)
Definition scip_nlp.h:361
SCIP_RETCODE SCIPsetNLPInitialGuessSol(SCIP *scip, SCIP_SOL *sol)
Definition scip_nlp.c:501
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_SOL ** SCIPgetSols(SCIP *scip)
Definition scip_sol.c:2936
SCIP_RETCODE SCIPtrySolFree(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:4114
SCIP_RETCODE SCIPtransformProb(SCIP *scip)
Definition scip_solve.c:232
SCIP_RETCODE SCIPpresolve(SCIP *scip)
SCIP_RETCODE SCIPinterruptSolve(SCIP *scip)
SCIP_RETCODE SCIPsolve(SCIP *scip)
SCIP_Real SCIPgetPrimalbound(SCIP *scip)
SCIP_Real SCIPgetUpperbound(SCIP *scip)
SCIP_Longint SCIPgetNNodes(SCIP *scip)
SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
SCIP_Real SCIPgetLowerbound(SCIP *scip)
SCIP_Longint SCIPgetNLPs(SCIP *scip)
SCIP_Real SCIPgetCutoffbound(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 SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPsumepsilon(SCIP *scip)
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_Real SCIPvarGetLPSol(SCIP_VAR *var)
Definition var.c:24696
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_Real SCIPvarGetNLPSol(SCIP_VAR *var)
Definition var.c:24723
#define HEUR_TIMING
return SCIP_OKAY
#define HEUR_FREQOFS
#define HEUR_DESC
#define HEUR_DISPCHAR
#define HEUR_MAXDEPTH
#define HEUR_PRIORITY
#define HEUR_NAME
#define HEUR_FREQ
#define HEUR_USESSUBSCIP
#define DEFAULT_NODESQUOT
Definition heur_alns.c:90
#define DEFAULT_COPYCUTS
Definition heur_alns.c:147
#define DEFAULT_NODESOFS
Definition heur_clique.c:94
#define DEFAULT_LPLIMFAC
#define DEFAULT_ADDALLSOLS
#define DEFAULT_MINFIXINGRATE
#define DEFAULT_USEUCT
#define DEFAULT_USELPROWS
#define DEFAULT_BESTSOLLIMIT
SCIP_Bool cutoff
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
heurdata usednodes
Definition heur_locks.c:163
#define DEFAULT_FULLSCALE
Definition heur_rens.c:91
#define DEFAULT_STARTSOL
Definition heur_rens.c:84
static SCIP_RETCODE setupAndSolveSubscip(SCIP *scip, SCIP *subscip, SCIP_RESULT *result, SCIP_HEUR *heur, SCIP_VAR **fixedvars, SCIP_Real *fixedvals, int nfixedvars, SCIP_Real intfixingrate, SCIP_Real minfixingrate, SCIP_Real minimprove, SCIP_Longint maxnodes, SCIP_Longint nstallnodes, char startsol, SCIP_Bool binarybounds, SCIP_Bool uselprows)
Definition heur_rens.c:337
#define DEFAULT_BINARYBOUNDS
Definition heur_rens.c:76
#define DEFAULT_EXTRATIME
Definition heur_rens.c:88
#define STARTSOL_CHOICES
Definition heur_rens.c:85
static SCIP_RETCODE restrictToBinaryBounds(SCIP *scip, SCIP *subscip, SCIP_VAR **subvars, char startsol)
Definition heur_rens.c:244
static SCIP_RETCODE computeFixingrate(SCIP *scip, SCIP_VAR **fixedvars, SCIP_Real *fixedvals, int *nfixedvars, int fixedvarssize, SCIP_Real minfixingrate, char *startsol, SCIP_Real *fixingrate, SCIP_Bool *success)
Definition heur_rens.c:137
LNS heuristic that finds the optimal rounding to a given point.
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 SCIPdebug(x)
Definition pub_message.h:93
#define SCIPstatisticPrintf
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
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 NLPI solver interfaces
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_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_LPSOLVED
Definition type_event.h:102
#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_HEUREXEC(x)
Definition type_heur.h:163
@ SCIP_LPSOLSTAT_OPTIMAL
Definition type_lp.h:44
struct SCIP_HashMap SCIP_HASHMAP
Definition type_misc.h:106
enum SCIP_NlpSolStat SCIP_NLPSOLSTAT
Definition type_nlpi.h:168
@ SCIP_NLPSOLSTAT_FEASIBLE
Definition type_nlpi.h:162
@ SCIP_NLPSOLSTAT_LOCOPT
Definition type_nlpi.h:161
@ SCIP_NLPSOLSTAT_GLOBOPT
Definition type_nlpi.h:160
@ SCIP_PARAMSETTING_OFF
@ SCIP_PARAMSETTING_FAST
@ SCIP_DIDNOTRUN
Definition type_result.h:42
@ SCIP_DELAYED
Definition type_result.h:43
@ 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