SCIP Doxygen Documentation
Loading...
Searching...
No Matches
heur_ofins.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_ofins.c
26 * @ingroup DEFPLUGINS_HEUR
27 * @brief OFINS - Objective Function Induced Neighborhood Search - a primal heuristic for reoptimization
28 * @author Jakob Witzig
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_ofins.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_copy.h"
44#include "scip/scip_event.h"
45#include "scip/scip_general.h"
46#include "scip/scip_heur.h"
47#include "scip/scip_mem.h"
48#include "scip/scip_message.h"
49#include "scip/scip_nodesel.h"
50#include "scip/scip_numerics.h"
51#include "scip/scip_param.h"
52#include "scip/scip_prob.h"
53#include "scip/scip_sol.h"
54#include "scip/scip_solve.h"
56#include "scip/scip_timing.h"
57
58
59#define HEUR_NAME "ofins"
60#define HEUR_DESC "primal heuristic for reoptimization, objective function induced neighborhood search"
61#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_LNS
62#define HEUR_PRIORITY 60000
63#define HEUR_FREQ 0
64#define HEUR_FREQOFS 0
65#define HEUR_MAXDEPTH 0
66#define HEUR_TIMING SCIP_HEURTIMING_BEFORENODE
67#define HEUR_USESSUBSCIP TRUE /**< does the heuristic use a secondary SCIP instance? */
68
69/* default values for OFINS-specific plugins */
70#define DEFAULT_MAXNODES 5000LL /**< maximum number of nodes to regard in the subproblem */
71#define DEFAULT_MAXCHGRATE 0.50 /**< maximum percentage of changed objective coefficients */
72#define DEFAULT_COPYCUTS TRUE /**< if DEFAULT_USELPROWS is FALSE, then should all active cuts from the cutpool
73 * of the original scip be copied to constraints of the subscip */
74#define DEFAULT_MAXCHANGE 0.04 /**< maximal rate of change per coefficient to get fixed */
75#define DEFAULT_MINIMPROVE 0.01 /**< factor by which OFINS should at least improve the incumbent */
76#define DEFAULT_ADDALLSOLS FALSE /**< should all subproblem solutions be added to the original SCIP? */
77#define DEFAULT_MINNODES 50LL /**< minimum number of nodes to regard in the subproblem */
78#define DEFAULT_NODESOFS 500LL /**< number of nodes added to the contingent of the total nodes */
79#define DEFAULT_NODESQUOT 0.1 /**< subproblem nodes in relation to nodes of the original problem */
80#define DEFAULT_LPLIMFAC 2.0 /**< factor by which the limit on the number of LP depends on the node limit */
81
82/* event handler properties */
83#define EVENTHDLR_NAME "Ofins"
84#define EVENTHDLR_DESC "LP event handler for " HEUR_NAME " heuristic"
85
86
87/** primal heuristic data */
88struct SCIP_HeurData
89{
90 SCIP_Real maxchangerate; /**< maximal rate of changed coefficients in the objective function */
91 SCIP_Longint maxnodes; /**< maximum number of nodes to regard in the subproblem */
92 SCIP_Bool copycuts; /**< should all active cuts from cutpool be copied to constraints in subproblem? */
93 SCIP_Bool addallsols; /**< should all subproblem solutions be added to the original SCIP? */
94 SCIP_Longint minnodes; /**< minimum number of nodes to regard in the subproblem */
95 SCIP_Longint nodesofs; /**< number of nodes added to the contingent of the total nodes */
96 SCIP_Real maxchange; /**< maximal rate of change per coefficient to get fixed */
97 SCIP_Real minimprove; /**< factor by which OFINS should at least improve the incumbent */
98 SCIP_Real nodesquot; /**< subproblem nodes in relation to nodes of the original problem */
99 SCIP_Real nodelimit; /**< the nodelimit employed in the current sub-SCIP, for the event handler*/
100 SCIP_Real lplimfac; /**< factor by which the limit on the number of LP depends on the node limit */
101};
102
103/* ---------------- Callback methods of event handler ---------------- */
104
105/* exec the event handler
106 *
107 * we interrupt the solution process
108 */
109static
110SCIP_DECL_EVENTEXEC(eventExecOfins)
111{
113
114 assert(eventhdlr != NULL);
115 assert(eventdata != NULL);
116 assert(event != NULL);
118
120
121 heurdata = (SCIP_HEURDATA*)eventdata;
122 assert(heurdata != NULL);
123
124 /* interrupt solution process of sub-SCIP */
125 if( SCIPgetNLPs(scip) > heurdata->lplimfac * heurdata->nodelimit )
126 {
127 SCIPdebugMsg(scip, "interrupt after %" SCIP_LONGINT_FORMAT " LPs\n",SCIPgetNLPs(scip));
129 }
130
131 return SCIP_OKAY;
132}
133
134/* setup and solve the sub-SCIP */
135static
137 SCIP* scip, /**< original SCIP data structure */
138 SCIP* subscip, /**< sub-SCIP data structure */
139 SCIP_HEUR* heur, /**< heuristic data structure */
140 SCIP_HEURDATA* heurdata, /**< euristic's private data structure */
141 SCIP_RESULT* result, /**< result data structure */
142 SCIP_Longint nstallnodes, /**< number of stalling nodes for the subproblem */
143 SCIP_Bool* chgcoeffs /**< array of changed coefficients */
144
145 )
146{
147 SCIP_HASHMAP* varmapfw;
148 SCIP_VAR** vars;
149 SCIP_VAR** subvars;
150 SCIP_EVENTHDLR* eventhdlr;
151
152 SCIP_SOL* sol;
153 SCIP_VAR** fixedvars;
154 SCIP_Real* fixedvals;
155 int nfixedvars;
156
157 int nvars;
158 int nintvars;
159 int i;
160
161 SCIP_SOL** subsols;
162 int nsubsols = 0;
163
164 SCIP_Bool success;
165 SCIP_RETCODE retcode;
166 SCIP_STATUS status;
167
168 assert(scip != NULL);
169 assert(subscip != NULL);
170 assert(heur != NULL);
171 assert(heurdata != NULL);
172 assert(result != NULL);
173 assert(chgcoeffs != NULL);
174
175 SCIPdebugMsg(scip, "+---+ Start OFINS heuristic +---+\n");
176
177 /* get variable data */
180
181 /* create the variable mapping hash map */
182 SCIP_CALL( SCIPhashmapCreate(&varmapfw, SCIPblkmem(subscip), nvars) );
183
184 /* get optimal solution of the last iteration */
186
187 /* if the solution is NULL the last problem was infeasible */
188 if( sol == NULL )
189 return SCIP_OKAY;
190
192 SCIP_CALL( SCIPallocBufferArray(scip, &fixedvars, nvars) );
193 SCIP_CALL( SCIPallocBufferArray(scip, &fixedvals, nvars) );
194
195 /* determine variables to fix in the sub-SCIP */
196 nfixedvars = 0;
197 for( i = 0; i < nintvars; i++ )
198 {
199 if( !chgcoeffs[i] )
200 {
201 fixedvars[nfixedvars] = vars[i];
202 fixedvals[nfixedvars] = SCIPgetSolVal(scip, sol, vars[i]);
203 ++nfixedvars;
204 }
205 }
206
207 /* create a problem copy as sub SCIP */
208 SCIP_CALL( SCIPcopyLargeNeighborhoodSearch(scip, subscip, varmapfw, "ofins", fixedvars, fixedvals, nfixedvars, FALSE,
209 FALSE, &success, NULL) );
210 assert(success);
211
212 SCIPfreeBufferArrayNull(scip, &fixedvals);
213 SCIPfreeBufferArrayNull(scip, &fixedvars);
214
215 /* create event handler for LP events */
216 eventhdlr = NULL;
217 SCIP_CALL( SCIPincludeEventhdlrBasic(subscip, &eventhdlr, EVENTHDLR_NAME, EVENTHDLR_DESC, eventExecOfins, NULL) );
218 if( eventhdlr == NULL )
219 {
220 SCIPerrorMessage("event handler for " HEUR_NAME " heuristic not found.\n");
221 return SCIP_PLUGINNOTFOUND;
222 }
223
225 for( i = 0; i < nvars; i++ )
226 subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, vars[i]);
227
228 /* free hash map */
229 SCIPhashmapFree(&varmapfw);
230
231 /* set an objective limit */
232 SCIPdebugMsg(scip, "set objective limit of %g to sub-SCIP\n", SCIPgetUpperbound(scip));
234
235 SCIPdebugMsg(scip, "OFINS subproblem: %d vars, %d cons\n", SCIPgetNVars(subscip), SCIPgetNConss(subscip));
236
237 /* do not abort subproblem on CTRL-C */
238 SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
239
240#ifdef SCIP_DEBUG
241 /* for debugging, enable full output */
242 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 5) );
243 SCIP_CALL( SCIPsetIntParam(subscip, "display/freq", 100000000) );
244#else
245 /* disable statistic timing inside sub SCIP and output to console */
246 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) );
247 SCIP_CALL( SCIPsetBoolParam(subscip, "timing/statistictiming", FALSE) );
248#endif
249
250 /* set limits for the subproblem */
251 SCIP_CALL( SCIPcopyLimits(scip, subscip) );
252 heurdata->nodelimit = heurdata->maxnodes;
253 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/stallnodes", nstallnodes) );
254 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", heurdata->maxnodes) );
255
256 /* forbid recursive call of heuristics and separators solving sub-SCIPs */
257 SCIP_CALL( SCIPsetSubscipsOff(subscip, TRUE) );
258
259 /* disable cutting plane separation */
261
262 /* disable expensive presolving */
264
265 /* use best estimate node selection */
266 if( SCIPfindNodesel(subscip, "estimate") != NULL && !SCIPisParamFixed(subscip, "nodeselection/estimate/stdpriority") )
267 {
268 SCIP_CALL( SCIPsetIntParam(subscip, "nodeselection/estimate/stdpriority", INT_MAX/4) );
269 }
270
271 /* use inference branching */
272 if( SCIPfindBranchrule(subscip, "inference") != NULL && !SCIPisParamFixed(subscip, "branching/inference/priority") )
273 {
274 SCIP_CALL( SCIPsetIntParam(subscip, "branching/inference/priority", INT_MAX/4) );
275 }
276
277 /* disable conflict analysis */
278 if( !SCIPisParamFixed(subscip, "conflict/enable") )
279 {
280 SCIP_CALL( SCIPsetBoolParam(subscip, "conflict/enable", FALSE) );
281 }
282
283 /* speed up sub-SCIP by not checking dual LP feasibility */
284 SCIP_CALL( SCIPsetBoolParam(subscip, "lp/checkdualfeas", FALSE) );
285
286 /* presolve the subproblem */
287 retcode = SCIPpresolve(subscip);
288
289 /* errors in solving the subproblem should not kill the overall solving process;
290 * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
291 */
292 if( retcode != SCIP_OKAY )
293 {
294 SCIPwarningMessage(scip, "Error while presolving subproblem in %s heuristic; sub-SCIP terminated with code <%d>\n", HEUR_NAME, retcode);
295
296 SCIPABORT(); /*lint --e{527}*/
297
298 /* free */
299 SCIPfreeBufferArray(scip, &subvars);
300 return SCIP_OKAY;
301 }
302
303 SCIPdebugMsg(scip, "%s presolved subproblem: %d vars, %d cons\n", HEUR_NAME, SCIPgetNVars(subscip), SCIPgetNConss(subscip));
304
305 assert(eventhdlr != NULL);
306
307 SCIP_CALL( SCIPtransformProb(subscip) );
309
310 /* solve the subproblem */
311 SCIPdebugMsg(scip, "solving subproblem: nstallnodes=%" SCIP_LONGINT_FORMAT ", maxnodes=%" SCIP_LONGINT_FORMAT "\n", nstallnodes, heurdata->maxnodes);
312
313 /* errors in solving the subproblem should not kill the overall solving process;
314 * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
315 */
316 SCIP_CALL_ABORT( SCIPsolve(subscip) );
317
319
320 /* print solving statistics of subproblem if we are in SCIP's debug mode */
322
323 status = SCIPgetStatus(subscip);
324
325 switch (status) {
327 break;
330 {
331 /* transfer the primal ray from the sub-SCIP to the main SCIP */
332 if( SCIPhasPrimalRay(subscip) )
333 {
334 SCIP_SOL* primalray;
335
336 SCIP_CALL( SCIPcreateSol(scip, &primalray, heur) );
337
338 /* transform the ray into the space of the source scip */
339 for( i = 0; i < nvars; i++ )
340 {
341 SCIP_CALL( SCIPsetSolVal(scip, primalray, vars[i],
342 subvars[i] != NULL ? SCIPgetPrimalRayVal(subscip, subvars[i]) : 0.0) );
343 }
344
345 SCIPdebug( SCIP_CALL( SCIPprintRay(scip, primalray, 0, FALSE) ); );
346
347 /* update the primal ray of the source scip */
348 SCIP_CALL( SCIPupdatePrimalRay(scip, primalray) );
349 SCIP_CALL( SCIPfreeSol(scip, &primalray) );
350
352 }
353
354 break;
355 }
356 default:
357 /* check, whether a solution was found;
358 * due to numerics, it might happen that not all solutions are feasible -> try all solutions until one was accepted
359 */
360 nsubsols = SCIPgetNSols(subscip);
361 subsols = SCIPgetSols(subscip);
362 success = FALSE;
363 for( i = 0; i < nsubsols && (!success || heurdata->addallsols); i++ )
364 {
365 SCIP_SOL* newsol;
366
367 SCIP_CALL( SCIPtranslateSubSol(scip, subscip, subsols[i], heur, subvars, &newsol) );
368
369 /* try to add new solution to scip and free it immediately */
370 SCIP_CALL( SCIPtrySolFree(scip, &newsol, FALSE, FALSE, TRUE, TRUE, TRUE, &success) );
371
372 if( success )
374 }
375 break;
376 } /*lint !e788*/
377
378 SCIPstatisticPrintf("%s statistic: fixed %6.3f integer variables, needed %6.1f seconds, %" SCIP_LONGINT_FORMAT " nodes, solution %10.4f found at node %" SCIP_LONGINT_FORMAT "\n",
379 HEUR_NAME, 0.0, SCIPgetSolvingTime(subscip), SCIPgetNNodes(subscip), success ? SCIPgetPrimalbound(scip) : SCIPinfinity(scip),
380 nsubsols > 0 ? SCIPsolGetNodenum(SCIPgetBestSol(subscip)) : -1 );
381
382 /* free subproblem */
383 SCIPfreeBufferArray(scip, &subvars);
384
385 return SCIP_OKAY;
386}
387
388/** main procedure of the OFINS heuristic, creates and solves a sub-SCIP */
389static
391 SCIP* scip, /**< original SCIP data structure */
392 SCIP_HEUR* heur, /**< heuristic data structure */
393 SCIP_HEURDATA* heurdata, /**< euristic's private data structure */
394 SCIP_RESULT* result, /**< result data structure */
395 SCIP_Longint nstallnodes, /**< number of stalling nodes for the subproblem */
396 SCIP_Bool* chgcoeffs /**< array of changed coefficients */
397 )
398{
399 SCIP* subscip;
400 SCIP_RETCODE retcode;
401 SCIP_Bool success;
402
403 assert(scip != NULL);
404 assert(heur != NULL);
405 assert(heurdata != NULL);
406 assert(result != NULL);
407 assert(chgcoeffs != NULL);
408
410
411 /* check whether there is enough time and memory left */
412 SCIP_CALL( SCIPcheckCopyLimits(scip, &success) );
413
414 if( !success )
415 return SCIP_OKAY;
416
418
419 /* do not run, if no solution was found */
421 return SCIP_OKAY;
422
423 /* initialize the subproblem */
424 SCIP_CALL( SCIPcreate(&subscip) );
425
426 retcode = setupAndSolve(scip, subscip, heur, heurdata, result, nstallnodes, chgcoeffs);
427
428 SCIP_CALL( SCIPfree(&subscip) );
429
430 SCIP_CALL( retcode );
431
432 return SCIP_OKAY;
433}
434
435
436
437
438/*
439 * Callback methods of primal heuristic
440 */
441
442/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
443static
444SCIP_DECL_HEURCOPY(heurCopyOfins)
445{ /*lint --e{715}*/
446 assert(scip != NULL);
447 assert(heur != NULL);
448
450
451 /* call inclusion method of primal heuristic */
453
454 return SCIP_OKAY;
455}
456
457/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
458static
459SCIP_DECL_HEURFREE(heurFreeOfins)
460{ /*lint --e{715}*/
462
463 assert(heur != NULL);
464 assert(scip != NULL);
465
466 /* get heuristic data */
468 assert(heurdata != NULL);
469
470 /* free heuristic data */
472 SCIPheurSetData(heur, NULL);
473
474 return SCIP_OKAY;
475}
476
477/** execution method of primal heuristic */
478static
479SCIP_DECL_HEUREXEC(heurExecOfins)
480{/*lint --e{715}*/
482 SCIP_VAR** vars;
483 SCIP_Bool* chgcoeffs;
484 SCIP_Longint nstallnodes;
485 int nchgcoefs;
486 int nvars;
487 int v;
488
489 assert( scip != NULL );
490 assert( heur != NULL );
491 assert( result != NULL );
492
493 /* only call heuristic if reoptimization is enabled */
495 {
497 return SCIP_OKAY;
498 }
499
501
502 /* only call the heuristic if we are in run >= 2 */
503 if( SCIPgetNReoptRuns(scip) <= 1 )
504 return SCIP_OKAY;
505
506 /* do not call heuristic if node was already detected to be infeasible */
507 if( nodeinfeasible )
508 return SCIP_OKAY;
509
511
512 if( SCIPisStopped(scip) )
513 return SCIP_OKAY;
514
515 /* get heuristic data */
517 assert( heurdata != NULL );
518
519 /* calculate the maximal number of branching nodes until heuristic is aborted */
520 nstallnodes = (SCIP_Longint)(heurdata->nodesquot * SCIPgetNNodes(scip));
521
522 /* reward OFINS if it succeeded often */
523 nstallnodes = (SCIP_Longint)(nstallnodes * 3.0 * (SCIPheurGetNBestSolsFound(heur)+1.0)/(SCIPheurGetNCalls(heur) + 1.0));
524 nstallnodes -= 100 * SCIPheurGetNCalls(heur); /* count the setup costs for the sub-SCIP as 100 nodes */
525 nstallnodes += heurdata->nodesofs;
526
527 /* determine the node limit for the current process */
528 nstallnodes = MIN(nstallnodes, heurdata->maxnodes);
529
530 /* check whether we have enough nodes left to call subproblem solving */
531 if( nstallnodes < heurdata->minnodes )
532 {
533 SCIPdebugMsg(scip, "skipping OFINS: nstallnodes=%" SCIP_LONGINT_FORMAT ", minnodes=%" SCIP_LONGINT_FORMAT "\n", nstallnodes, heurdata->minnodes);
534 return SCIP_OKAY;
535 }
536
537 /* get variable data and check which coefficient has changed */
540 nchgcoefs = 0;
541
542 SCIP_CALL( SCIPallocBufferArray(scip, &chgcoeffs, nvars) );
543
544 for( v = 0; v < nvars; v++ )
545 {
546 SCIP_Real newcoef;
547 SCIP_Real oldcoef;
548 SCIP_Real newcoefabs;
549 SCIP_Real oldcoefabs;
551
552 /* we only want to count variables that are unfixed after the presolving */
555
558 newcoefabs = REALABS(newcoef);
559 oldcoefabs = REALABS(oldcoef);
560
561 /* if both coefficients are zero nothing has changed */
562 if( SCIPisZero(scip, newcoef) && SCIPisZero(scip, oldcoef) )
563 {
564 frac = 0;
565 }
566 /* if exactly one coefficient is zero, the other need to be close to zero */
567 else if( SCIPisZero(scip, newcoef) || SCIPisZero(scip, oldcoef) )
568 {
569 assert(SCIPisZero(scip, newcoef) != SCIPisZero(scip, oldcoef));
570 if( !SCIPisZero(scip, newcoef) )
571 frac = MIN(1, newcoefabs);
572 else
573 frac = MIN(1, oldcoefabs);
574 }
575 /* if both coefficients have the same sign we calculate the quotient
576 * MIN(newcoefabs, oldcoefabs)/MAX(newcoefabs, oldcoefabs)
577 */
578 else if( SCIPisPositive(scip, newcoef) == SCIPisPositive(scip, oldcoef) )
579 {
580 frac = 1.0 - MIN(newcoefabs, oldcoefabs)/MAX(newcoefabs, oldcoefabs);
581 }
582 /* if both coefficients have a different sign, we set frac = 1 */
583 else
584 {
585 assert((SCIPisPositive(scip, newcoef) && SCIPisNegative(scip, oldcoef))
586 || (SCIPisNegative(scip, newcoef) && SCIPisPositive(scip, oldcoef)));
587
588 frac = 1;
589 }
590
591 if( frac > heurdata->maxchange )
592 {
593 chgcoeffs[v] = TRUE;
594 nchgcoefs++;
595 }
596 else
597 chgcoeffs[v] = FALSE;
598 }
599
600 SCIPdebugMsg(scip, "%d (rate %.4f) changed coefficients\n", nchgcoefs, nchgcoefs/((SCIP_Real)nvars));
601
602 /* we only want to run the heuristic if there at least 3 changed coefficients.
603 * if the number of changed coefficients is 2 the trivialnegation heuristic will construct an
604 * optimal solution without solving a MIP.
605 */
606 if( nchgcoefs < 3 )
607 goto TERMINATE;
608
609 /* run the heuristic if not too many coefficients have changed */
610 if( nchgcoefs/((SCIP_Real)nvars) > heurdata->maxchangerate )
611 goto TERMINATE;
612
613 SCIP_CALL( applyOfins(scip, heur, heurdata, result, nstallnodes, chgcoeffs) );
614
615 TERMINATE:
616 SCIPfreeBufferArray(scip, &chgcoeffs);
617
618 return SCIP_OKAY;
619}
620
621
622/*
623 * primal heuristic specific interface methods
624 */
625
626/** creates the ofins primal heuristic and includes it in SCIP */
628 SCIP* scip /**< SCIP data structure */
629 )
630{
632 SCIP_HEUR* heur;
633
634 /* create ofins primal heuristic data */
636 assert(heurdata != NULL);
637
638 /* include primal heuristic */
642
643 assert(heur != NULL);
644
645 /* primal heuristic is safe to use in exact solving mode */
646 SCIPheurMarkExact(heur);
647
648 /* set non fundamental callbacks via setter functions */
649 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyOfins) );
650 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeOfins) );
651
652 /* add ofins primal heuristic parameters */
653
654 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxnodes",
655 "maximum number of nodes to regard in the subproblem",
656 &heurdata->maxnodes, TRUE, DEFAULT_MAXNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
657
658 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/minnodes",
659 "minimum number of nodes required to start the subproblem",
660 &heurdata->minnodes, TRUE, DEFAULT_MINNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
661
662 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/maxchangerate",
663 "maximal rate of changed coefficients",
664 &heurdata->maxchangerate, FALSE, DEFAULT_MAXCHGRATE, 0.0, 1.0, NULL, NULL) );
665
666 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/maxchange",
667 "maximal rate of change per coefficient to get fixed",
668 &heurdata->maxchange, FALSE, DEFAULT_MAXCHANGE, 0.0, 1.0, NULL, NULL) );
669
670 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/copycuts",
671 "should all active cuts from cutpool be copied to constraints in subproblem?",
672 &heurdata->copycuts, TRUE, DEFAULT_COPYCUTS, NULL, NULL) );
673
674 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/addallsols",
675 "should all subproblem solutions be added to the original SCIP?",
676 &heurdata->addallsols, TRUE, DEFAULT_ADDALLSOLS, NULL, NULL) );
677
678 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/nodesofs",
679 "number of nodes added to the contingent of the total nodes",
681
682 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/nodesquot",
683 "contingent of sub problem nodes in relation to the number of nodes of the original problem",
684 &heurdata->nodesquot, FALSE, DEFAULT_NODESQUOT, 0.0, 1.0, NULL, NULL) );
685
686 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minimprove",
687 "factor by which RENS should at least improve the incumbent",
688 &heurdata->minimprove, TRUE, DEFAULT_MINIMPROVE, 0.0, 1.0, NULL, NULL) );
689
690 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/lplimfac",
691 "factor by which the limit on the number of LP depends on the node limit",
692 &heurdata->lplimfac, TRUE, DEFAULT_LPLIMFAC, 1.0, SCIP_REAL_MAX, NULL, NULL) );
693
694 return SCIP_OKAY;
695}
#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_CALL_ABORT(x)
Definition def.h:343
#define SCIP_LONGINT_FORMAT
Definition def.h:157
#define SCIPABORT()
Definition def.h:336
#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
SCIP_RETCODE SCIPcheckCopyLimits(SCIP *sourcescip, SCIP_Bool *success)
Definition scip_copy.c:3250
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)
SCIP_STATUS SCIPgetStatus(SCIP *scip)
int SCIPgetNIntVars(SCIP *scip)
Definition scip_prob.c:2340
int SCIPgetNImplVars(SCIP *scip)
Definition scip_prob.c:2387
SCIP_RETCODE SCIPsetObjlimit(SCIP *scip, SCIP_Real objlimit)
Definition scip_prob.c:1661
int SCIPgetNVars(SCIP *scip)
Definition scip_prob.c:2246
int SCIPgetNConss(SCIP *scip)
Definition scip_prob.c:3620
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition scip_prob.c:2201
int 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 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 SCIPincludeHeurOfins(SCIP *scip)
Definition heur_ofins.c:627
SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
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
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition heur.c:1467
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition heur.c:1378
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 SCIPfreeBufferArrayNull(scip, ptr)
Definition scip_mem.h:137
#define SCIPallocBlockMemory(scip, ptr)
Definition scip_mem.h:89
SCIP_NODESEL * SCIPfindNodesel(SCIP *scip, const char *name)
SCIP_SOL * SCIPgetReoptLastOptSol(SCIP *scip)
SCIP_RETCODE SCIPgetReoptOldObjCoef(SCIP *scip, SCIP_VAR *var, int run, SCIP_Real *objcoef)
SCIP_Bool SCIPisReoptEnabled(SCIP *scip)
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
Definition scip_sol.c:2986
SCIP_RETCODE SCIPprintRay(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
Definition scip_sol.c:2850
SCIP_Longint SCIPsolGetNodenum(SCIP_SOL *sol)
Definition sol.c:4254
int SCIPgetNSols(SCIP *scip)
Definition scip_sol.c:2887
SCIP_Real SCIPgetPrimalRayVal(SCIP *scip, SCIP_VAR *var)
Definition scip_sol.c:4450
SCIP_SOL ** SCIPgetSols(SCIP *scip)
Definition scip_sol.c:2936
SCIP_Bool SCIPhasPrimalRay(SCIP *scip)
Definition scip_sol.c:4432
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 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_RETCODE SCIPupdatePrimalRay(SCIP *scip, SCIP_SOL *primalray)
Definition scip_sol.c:4478
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_Longint SCIPgetNLPs(SCIP *scip)
int SCIPgetNReoptRuns(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 SCIPisPositive(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition var.c:23674
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition var.c:23418
#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_COPYCUTS
Definition heur_alns.c:147
#define DEFAULT_NODESOFS
Definition heur_clique.c:94
#define DEFAULT_LPLIMFAC
#define DEFAULT_ADDALLSOLS
static SCIP_SOL * sol
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
SCIP_Real frac
#define DEFAULT_MAXCHGRATE
Definition heur_ofins.c:71
#define DEFAULT_MAXCHANGE
Definition heur_ofins.c:74
static SCIP_RETCODE setupAndSolve(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, SCIP_RESULT *result, SCIP_Longint nstallnodes, SCIP_Bool *chgcoeffs)
Definition heur_ofins.c:136
static SCIP_RETCODE applyOfins(SCIP *scip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, SCIP_RESULT *result, SCIP_Longint nstallnodes, SCIP_Bool *chgcoeffs)
Definition heur_ofins.c:390
OFINS - Objective Function Induced Neighborhood Search - a primal heuristic for reoptimization.
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 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 memory management
public methods for message handling
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
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_HEURFREE(x)
Definition type_heur.h:105
#define SCIP_DECL_HEUREXEC(x)
Definition type_heur.h:163
struct SCIP_HashMap SCIP_HASHMAP
Definition type_misc.h:106
@ 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_UNBOUNDED
Definition type_result.h:47
@ 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
@ SCIP_STATUS_UNBOUNDED
Definition type_stat.h:45
@ SCIP_STATUS_INFORUNBD
Definition type_stat.h:46
@ SCIP_STATUS_INFEASIBLE
Definition type_stat.h:44
enum SCIP_Status SCIP_STATUS
Definition type_stat.h:64
struct SCIP_Var SCIP_VAR
Definition type_var.h:166
@ SCIP_VARSTATUS_ORIGINAL
Definition type_var.h:51