SCIP Doxygen Documentation
Loading...
Searching...
No Matches
heur_trustregion.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_trustregion.c
26 * @ingroup DEFPLUGINS_HEUR
27 * @brief Large neighborhood search heuristic for Benders' decomposition based on trust region methods
28 * @author Stephen J. Maher
29 *
30 * The Trust Region heuristic draws upon trust region methods for solving optimization problems, especially in the
31 * context of Benders' decomposition. This heuristic has been developed to improve the heuristic performance of the
32 * Benders' decomposition algorithm within SCIP.
33 *
34 * The Trust Region heuristic copies the original SCIP instance and adds a constraint to penalize changes from the
35 * incumbent solution. Consider a problem that includes a set of binary variables \f$\mathcal{B}\f$. Given a feasible
36 * solution \f$\hat{x}\f$ to the original problem, we define the set \f$\mathcal{B}^{+}\f$ as the index set for the
37 * binary variables that are 1 in the input solution and \f$\mathcal{B}^{-}\f$ as the index set for binary variables
38 * that are 0. The trust region constraint, which is added to the sub-SCIP, is given by
39 *
40 * \f[
41 * \sum_{i \in \mathcal{B}^{+}}(1 - x_{i}) + \sum_{i \in \mathcal{B}^{-}}x_{i} \le \theta
42 * \f]
43 *
44 * The variable \f$\theta\f$ measure the distance, in terms of the binary variables, of candidate solutions to the input
45 * solution.
46 *
47 * In addition, an upper bounding constraint is explicitly added to enforce a minimum improvement from the heuristic,
48 * given by \f$f(x) \le f(\hat{x}) - \epsilon\f$. The parameter \f$\epsilon \ge 0\f$ denotes the minimum improvement
49 * that must be achieved by the heuristic.
50 *
51 * The objective function is then modified to \f$f(x) + M\theta\f$, where \f$M\f$ is a parameter for penalizing the
52 * distance of solutions from the input solution \f$\hat{x}\f$.
53 *
54 * If a new incumbent solution is found by this heuristic, then the Trust Region heuristic is immediately
55 * re-executed with this new incumbent solution.
56 */
57
58/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
59
61#include "scip/cons_linear.h"
62#include "scip/heuristics.h"
64#include "scip/pub_event.h"
65#include "scip/pub_heur.h"
66#include "scip/pub_message.h"
67#include "scip/pub_misc.h"
68#include "scip/pub_sol.h"
69#include "scip/pub_var.h"
70#include "scip/scip_branch.h"
71#include "scip/scip_cons.h"
72#include "scip/scip_copy.h"
73#include "scip/scip_event.h"
74#include "scip/scip_general.h"
75#include "scip/scip_heur.h"
76#include "scip/scip_mem.h"
77#include "scip/scip_message.h"
78#include "scip/scip_nodesel.h"
79#include "scip/scip_numerics.h"
80#include "scip/scip_param.h"
81#include "scip/scip_prob.h"
82#include "scip/scip_sol.h"
83#include "scip/scip_solve.h"
85#include "scip/scip_var.h"
86
87
88#define HEUR_NAME "trustregion"
89#define HEUR_DESC "LNS heuristic for Benders' decomposition based on trust region methods"
90#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_LNS
91#define HEUR_PRIORITY -1102010
92#define HEUR_FREQ -1
93#define HEUR_FREQOFS 0
94#define HEUR_MAXDEPTH -1
95#define HEUR_TIMING SCIP_HEURTIMING_AFTERNODE
96#define HEUR_USESSUBSCIP TRUE /**< does the heuristic use a secondary SCIP instance? */
97
98#define DEFAULT_MINBINVARS 10 /**< the minimum number of binary variables necessary to run the heuristic */
99#define DEFAULT_NODESOFS 1000 /**< number of nodes added to the contingent of the total nodes */
100#define DEFAULT_MAXNODES 10000 /**< maximum number of nodes to regard in the subproblem */
101#define DEFAULT_MINNODES 100 /**< minimum number of nodes required to start the subproblem */
102#define DEFAULT_NODESQUOT 0.05 /**< contingent of sub problem nodes in relation to original nodes */
103#define DEFAULT_LPLIMFAC 1.5 /**< factor by which the limit on the number of LP depends on the node limit */
104#define DEFAULT_NWAITINGNODES 1 /**< number of nodes without incumbent change that heuristic should wait */
105#define DEFAULT_USELPROWS FALSE /**< should subproblem be created out of the rows in the LP rows,
106 * otherwise, the copy constructors of the constraints handlers are used */
107#define DEFAULT_COPYCUTS TRUE /**< if DEFAULT_USELPROWS is FALSE, then should all active cuts from the cutpool
108 * of the original scip be copied to constraints of the subscip */
109#define DEFAULT_BESTSOLLIMIT 3 /**< limit on number of improving incumbent solutions in sub-CIP */
110
111#define DEFAULT_VIOLPENALTY 100.0 /**< the penalty for violating the trust region */
112#define DEFAULT_OBJMINIMPROVE 1e-2 /**< the minimum absolute improvement in the objective function value */
113
114/* event handler properties */
115#define EVENTHDLR_NAME "Trustregion"
116#define EVENTHDLR_DESC "LP event handler for " HEUR_NAME " heuristic"
117
118
119#define EXECUTE 0
120#define WAITFORNEWSOL 1
121
122
123/*
124 * Data structures
125 */
126
127/** primal heuristic data */
128struct SCIP_HeurData
129{
130 SCIP_SOL* lastsol; /**< the last incumbent trustregion used as reference point */
131 SCIP_Longint usednodes; /**< amount of nodes trust region used during all calls */
132 SCIP_Real nodesquot; /**< contingent of sub problem nodes in relation to original nodes */
133 SCIP_Real nodelimit; /**< the nodelimit employed in the current sub-SCIP, for the event handler*/
134 SCIP_Real lplimfac; /**< factor by which the limit on the number of LP depends on the node limit */
135 SCIP_Real violpenalty; /**< the penalty for violating the trust region */
136 SCIP_Real objminimprove; /**< the minimum absolute improvement in the objective function value */
137 int nwaitingnodes; /**< number of nodes without incumbent change that heuristic should wait */
138 int nodesofs; /**< number of nodes added to the contingent of the total nodes */
139 int minnodes; /**< minimum number of nodes required to start the subproblem */
140 int maxnodes; /**< maximum number of nodes to regard in the subproblem */
141 int minbinvars; /**< minimum number of binary variables necessary to run the heuristic */
142 int callstatus; /**< current status of trustregion heuristic */
143 int curminnodes; /**< current minimal number of nodes required to start the subproblem */
144 int bestsollimit; /**< limit on number of improving incumbent solutions in sub-CIP */
145 SCIP_Bool uselprows; /**< should subproblem be created out of the rows in the LP rows? */
146 SCIP_Bool copycuts; /**< if uselprows == FALSE, should all active cuts from cutpool be copied
147 * to constraints in subproblem? */
148};
149
150
151/*
152 * Local methods
153 */
154
155/** create the extra constraint of trust region and add it to \p subscip */
156static
158 SCIP* scip, /**< SCIP data structure of the original problem */
159 SCIP* subscip, /**< SCIP data structure of the subproblem */
160 SCIP_VAR** subvars, /**< variables of the subproblem */
161 SCIP_HEURDATA* heurdata /**< heuristic's data structure */
162 )
163{
164 SCIP_CONS* cons; /* trust region constraint to create */
165 SCIP_VAR** consvars;
166 SCIP_VAR** vars;
167 SCIP_SOL* bestsol;
168
169 int nvars;
170 int nbinvars;
171 int nconsvars;
172 int i;
173 SCIP_Real lhs;
174 SCIP_Real rhs;
175 SCIP_Real* consvals;
176 char name[SCIP_MAXSTRLEN];
177
178 /* adding the neighborhood constraint for the trust region heuristic */
179 SCIP_CALL( SCIPaddTrustregionNeighborhoodConstraint(scip, subscip, subvars, heurdata->violpenalty) );
180
181 /* get the data of the variables and the best solution */
182 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, &nbinvars, NULL, NULL, NULL) );
183 bestsol = SCIPgetBestSol(scip);
184 assert( bestsol != NULL );
185
186 /* memory allocation */
187 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nvars + 1) );
188 SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nvars + 1) );
189 nconsvars = 0;
190
191 /* create the upper bounding constraint. An absolute minimum improvement is used for this heuristic. This is
192 * different to other LNS heuristics, where a relative improvement is used. The absolute improvement tries to take
193 * into account problem specific information that is available to the user, such as a minimum step in the objective
194 * limit if the objective function is integer
195 */
196 lhs = -SCIPinfinity(subscip);
197 rhs = SCIPgetSolTransObj(scip, bestsol) - heurdata->objminimprove;
198
199 /* if the objective function is integer, then the floor of the RHS is taken */
201 rhs = SCIPfeasFloor(scip, rhs);
202
203 /* adding the coefficients to the upper bounding constraint */
204 for( i = 0; i < nvars; i++ )
205 {
206 if( subvars[i] == NULL )
207 continue;
208 consvals[nconsvars] = SCIPvarGetObj(subvars[i]);
209 consvars[nconsvars] = subvars[i];
210 ++nconsvars;
211 }
212
213 /* creates trustregion constraint and adds it to subscip */
214 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_upperboundcons", SCIPgetProbName(scip));
215
216 SCIP_CALL( SCIPcreateConsLinear(subscip, &cons, name, nconsvars, consvars, consvals,
217 lhs, rhs, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE) );
218 SCIP_CALL( SCIPaddCons(subscip, cons) );
219 SCIP_CALL( SCIPreleaseCons(subscip, &cons) );
220
221 /* free local memory */
222 SCIPfreeBufferArray(scip, &consvals);
223 SCIPfreeBufferArray(scip, &consvars);
224
225 return SCIP_OKAY;
226}
227
228
229/* ---------------- Callback methods of event handler ---------------- */
230
231/** event handler execution callback to interrupt the solution process */
232static
233SCIP_DECL_EVENTEXEC(eventExecTrustregion)
234{
236
237 assert(eventhdlr != NULL);
238 assert(eventdata != NULL);
239 assert(event != NULL);
241
243
244 heurdata = (SCIP_HEURDATA*)eventdata;
245 assert(heurdata != NULL);
246
247 /* interrupt solution process of sub-SCIP */
248 if( SCIPgetNLPs(scip) > heurdata->lplimfac * heurdata->nodelimit )
249 {
250 SCIPdebugMsg(scip, "interrupt after %" SCIP_LONGINT_FORMAT " LPs\n",SCIPgetNLPs(scip));
252 }
253
254 return SCIP_OKAY;
255}
256
257
258/*
259 * Callback methods of primal heuristic
260 */
261
262/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
263static
264SCIP_DECL_HEURCOPY(heurCopyTrustregion)
265{ /*lint --e{715}*/
266 assert(scip != NULL);
267 assert(heur != NULL);
268
270
271 /* call inclusion method of primal heuristic */
273
274 return SCIP_OKAY;
275}
276
277/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
278static
279SCIP_DECL_HEURFREE(heurFreeTrustregion)
280{ /*lint --e{715}*/
282
283 assert( heur != NULL );
284 assert( scip != NULL );
285
286 /* get heuristic data */
288 assert( heurdata != NULL );
289
290 /* free heuristic data */
292 SCIPheurSetData(heur, NULL);
293
294 return SCIP_OKAY;
295}
296
297
298/** initialization method of primal heuristic (called after problem was transformed) */
299static
300SCIP_DECL_HEURINIT(heurInitTrustregion)
301{ /*lint --e{715}*/
303
304 assert( heur != NULL );
305 assert( scip != NULL );
306
307 /* get heuristic's data */
309 assert( heurdata != NULL );
310
311 /* with a little abuse we initialize the heurdata as if trustregion would have finished its last step regularly */
312 heurdata->callstatus = WAITFORNEWSOL;
313 heurdata->lastsol = NULL;
314 heurdata->usednodes = 0;
315 heurdata->curminnodes = heurdata->minnodes;
316
317 return SCIP_OKAY;
318}
319
320/** sets up and solves the sub SCIP for the Trust Region heuristic */
321static
323 SCIP* scip, /**< SCIP data structure */
324 SCIP* subscip, /**< the subproblem created by trustregion */
325 SCIP_HEUR* heur, /**< trustregion heuristic */
326 SCIP_Longint nsubnodes, /**< nodelimit for subscip */
327 SCIP_RESULT* result /**< result pointer */
328 )
329{
330 SCIP_VAR** subvars;
331 SCIP_EVENTHDLR* eventhdlr;
333 SCIP_HASHMAP* varmapfw;
334 SCIP_VAR** vars;
335
336 int nvars;
337 int i;
338
339 SCIP_Bool success;
340
341 assert(scip != NULL);
342 assert(subscip != NULL);
343 assert(heur != NULL);
344
346 assert(heurdata != NULL);
347
348 /* get the data of the variables and the best solution */
350
351 /* create the variable mapping hash map */
352 SCIP_CALL( SCIPhashmapCreate(&varmapfw, SCIPblkmem(subscip), nvars) );
353 success = FALSE;
354
355 /* create a problem copy as sub SCIP */
356 SCIP_CALL( SCIPcopyLargeNeighborhoodSearch(scip, subscip, varmapfw, "trustregion", NULL, NULL, 0, heurdata->uselprows,
357 heurdata->copycuts, &success, NULL) );
358
359 SCIPdebugMsg(scip, "Copying SCIP was %s successful.\n", success ? "" : "not ");
360
361 /* if the subproblem could not be created, free memory and return */
362 if( !success )
363 {
365 goto TERMINATE;
366 }
367
368 /* create event handler for LP events */
369 eventhdlr = NULL;
370 SCIP_CALL( SCIPincludeEventhdlrBasic(subscip, &eventhdlr, EVENTHDLR_NAME, EVENTHDLR_DESC, eventExecTrustregion, NULL) );
371 if( eventhdlr == NULL )
372 {
373 /* free hash map */
374 SCIPhashmapFree(&varmapfw);
375
376 SCIPerrorMessage("event handler for " HEUR_NAME " heuristic not found.\n");
377 return SCIP_PLUGINNOTFOUND;
378 }
379
381 for (i = 0; i < nvars; ++i)
382 subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, vars[i]);
383
384 /* free hash map */
385 SCIPhashmapFree(&varmapfw);
386
387 heurdata->nodelimit = nsubnodes;
388 SCIP_CALL( SCIPsetCommonSubscipParams(scip, subscip, nsubnodes, MAX(10, nsubnodes/10), heurdata->bestsollimit) );
389
390 SCIP_CALL( addTrustRegionConstraints(scip, subscip, subvars, heurdata) );
391
392 /* catch LP events of sub-SCIP */
393 if( !heurdata->uselprows )
394 {
395 assert(eventhdlr != NULL);
396
397 SCIP_CALL( SCIPtransformProb(subscip) );
399 }
400
401 /* solve the subproblem */
402 SCIPdebugMsg(scip, "solving trust region subproblem with maxnodes %" SCIP_LONGINT_FORMAT "\n", nsubnodes);
403
404 SCIP_CALL( SCIPsetIntParam(subscip, "heuristics/trysol/priority", 100000) );
405
406 /* Errors in solving the subproblem should not kill the overall solving process
407 * Hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
408 */
409 SCIP_CALL_ABORT( SCIPsolve(subscip) );
410
411 /* drop LP events of sub-SCIP */
412 if( !heurdata->uselprows )
413 {
414 assert(eventhdlr != NULL);
415
417 }
418
419 /* print solving statistics of subproblem if we are in SCIP's debug mode */
421
422 heurdata->usednodes += SCIPgetNNodes(subscip);
423 SCIPdebugMsg(scip, "trust region used %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT " nodes\n",
424 SCIPgetNNodes(subscip), nsubnodes);
425
426 /* checks the solutions of the sub SCIP and adds them to the main SCIP if feasible */
427 SCIP_CALL( SCIPtranslateSubSols(scip, subscip, heur, subvars, &success, NULL) );
428
429 if( success )
431
432 /* checking the status of the subscip */
433 heurdata->callstatus = WAITFORNEWSOL;
436 {
437 heurdata->callstatus = EXECUTE;
438 heurdata->curminnodes *= 2;
439 }
440
441 TERMINATE:
442 /* free subproblem */
443 SCIPfreeBufferArray(scip, &subvars);
444
445 return SCIP_OKAY;
446}
447
448
449/** execution method of primal heuristic */
450static
451SCIP_DECL_HEUREXEC(heurExecTrustregion)
452{ /*lint --e{715}*/
453 SCIP_Longint maxnnodes;
454 SCIP_Longint nsubnodes;
455
457 SCIP* subscip;
458
459 SCIP_SOL* bestsol;
460
461 SCIP_Bool success;
462 SCIP_RETCODE retcode;
463
464 assert(heur != NULL);
465 assert(scip != NULL);
466 assert(result != NULL);
467
469
470 /* get heuristic's data */
472 assert( heurdata != NULL );
473
474 /* there should be enough binary variables that a trust region constraint makes sense */
475 if( SCIPgetNBinVars(scip) < heurdata->minbinvars )
476 return SCIP_OKAY;
477
479
480 /* only call heuristic, if an IP solution is at hand */
481 if( SCIPgetNSols(scip) <= 0 )
482 return SCIP_OKAY;
483
484 bestsol = SCIPgetBestSol(scip);
485 assert(bestsol != NULL);
486
487 /* only call heuristic, if the best solution comes from transformed problem */
488 if( SCIPsolIsOriginal(bestsol) )
489 return SCIP_OKAY;
490
491 /* only call heuristic, if enough nodes were processed since last incumbent */
492 if( SCIPgetNNodes(scip) - SCIPgetSolNodenum(scip, bestsol) < heurdata->nwaitingnodes)
493 return SCIP_OKAY;
494
495 /* only call heuristic, if the best solution does not come from trivial heuristic */
496 if( SCIPsolGetHeur(bestsol) != NULL && strcmp(SCIPheurGetName(SCIPsolGetHeur(bestsol)), "trivial") == 0 )
497 return SCIP_OKAY;
498
499 /* calculate the maximal number of branching nodes until heuristic is aborted */
500 maxnnodes = (SCIP_Longint)(heurdata->nodesquot * SCIPgetNNodes(scip));
501
502 /* reward trust region if it found solutions often.
503 * In this case, the trust region heuristic is designed for Benders' decomposition and solutions found may not be
504 * added by this heuristic but by trysol. So we don't reward finding best solutions, but finding any solution. */
505 maxnnodes = (SCIP_Longint)(maxnnodes * (1.0 + 2.0*(SCIPheurGetNSolsFound(heur)+1.0)/(SCIPheurGetNCalls(heur)+1.0)));
506 maxnnodes -= 100 * SCIPheurGetNCalls(heur); /* count the setup costs for the sub-MIP as 100 nodes */
507 maxnnodes += heurdata->nodesofs;
508
510
511 /* we continue to execute the trust region heuristic until no new best solution is found */
512 do
513 {
514 SCIP_RESULT heurresult;
515
516 /* storing the best solution again since it is needed for the execution loop */
517 bestsol = SCIPgetBestSol(scip);
518
519 /* reset minnodes if new solution was found */
520 if( heurdata->lastsol != bestsol )
521 {
522 heurdata->curminnodes = heurdata->minnodes;
523 heurdata->callstatus = EXECUTE;
524 heurdata->lastsol = bestsol;
525 }
526
527 /* if no new solution was found and trust region also seems to fail, just keep on waiting */
528 if( heurdata->callstatus == WAITFORNEWSOL )
529 return SCIP_OKAY;
530
531 /* determine the node limit for the current process */
532 nsubnodes = maxnnodes - heurdata->usednodes;
533 nsubnodes = MIN(nsubnodes, heurdata->maxnodes);
534
535 /* check whether we have enough nodes left to call sub problem solving */
536 if( nsubnodes < heurdata->curminnodes )
537 return SCIP_OKAY;
538
539 if( SCIPisStopped(scip) )
540 return SCIP_OKAY;
541
542 /* check whether there is enough time and memory left */
543 SCIP_CALL( SCIPcheckCopyLimits(scip, &success) );
544
545 /* abort if no time is left or there is not enough memory to create a copy of SCIP */
546 if( !success )
547 return SCIP_OKAY;
548
549 heurresult = SCIP_DIDNOTFIND;
550
551 SCIPdebugMsg(scip, "running trust region heuristic ...\n");
552
553 SCIP_CALL( SCIPcreate(&subscip) );
554
555 retcode = setupAndSolveSubscipTrustregion(scip, subscip, heur, nsubnodes, &heurresult);
556
557 SCIP_CALL( SCIPfree(&subscip) );
558
559 /* if the result is FOUNDSOL, this means that a solution was found during a previous execution of the heuristic.
560 * So the heuristic result should only be updated if the result is not FOUNDSOL.
561 */
562 if( *result != SCIP_FOUNDSOL )
563 *result = heurresult;
564 }
565 while( bestsol != SCIPgetBestSol(scip) && retcode == SCIP_OKAY );
566
567 return retcode;
568}
569
570
571/*
572 * primal heuristic specific interface methods
573 */
574
575/** creates the trustregion primal heuristic and includes it in SCIP */
577 SCIP* scip /**< SCIP data structure */
578 )
579{
581 SCIP_HEUR* heur;
582
583 /* create Trustregion primal heuristic data */
585
586 /* include primal heuristic */
589 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecTrustregion, heurdata) );
590
591 assert(heur != NULL);
592
593 /* primal heuristic is safe to use in exact solving mode */
594 SCIPheurMarkExact(heur);
595
596 /* set non-NULL pointers to callback methods */
597 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyTrustregion) );
598 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeTrustregion) );
599 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitTrustregion) );
600
601 /* add trustregion primal heuristic parameters */
602 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/nodesofs",
603 "number of nodes added to the contingent of the total nodes",
604 &heurdata->nodesofs, FALSE, DEFAULT_NODESOFS, 0, INT_MAX, NULL, NULL) );
605
606 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/minbinvars",
607 "the number of binary variables necessary to run the heuristic",
608 &heurdata->minbinvars, FALSE, DEFAULT_MINBINVARS, 1, INT_MAX, NULL, NULL) );
609
610 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/nodesquot",
611 "contingent of sub problem nodes in relation to the number of nodes of the original problem",
612 &heurdata->nodesquot, FALSE, DEFAULT_NODESQUOT, 0.0, 1.0, NULL, NULL) );
613
614 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/lplimfac",
615 "factor by which the limit on the number of LP depends on the node limit",
616 &heurdata->lplimfac, TRUE, DEFAULT_LPLIMFAC, 1.0, SCIP_REAL_MAX, NULL, NULL) );
617
618 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/minnodes",
619 "minimum number of nodes required to start the subproblem",
620 &heurdata->minnodes, TRUE, DEFAULT_MINNODES, 0, INT_MAX, NULL, NULL) );
621
622 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxnodes",
623 "maximum number of nodes to regard in the subproblem",
624 &heurdata->maxnodes, TRUE, DEFAULT_MAXNODES, 0, INT_MAX, NULL, NULL) );
625
626 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/nwaitingnodes",
627 "number of nodes without incumbent change that heuristic should wait",
628 &heurdata->nwaitingnodes, TRUE, DEFAULT_NWAITINGNODES, 0, INT_MAX, NULL, NULL) );
629
630 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/uselprows",
631 "should subproblem be created out of the rows in the LP rows?",
632 &heurdata->uselprows, TRUE, DEFAULT_USELPROWS, NULL, NULL) );
633
634 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/copycuts",
635 "if uselprows == FALSE, should all active cuts from cutpool be copied to constraints in subproblem?",
636 &heurdata->copycuts, TRUE, DEFAULT_COPYCUTS, NULL, NULL) );
637
638 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/bestsollimit",
639 "limit on number of improving incumbent solutions in sub-CIP",
640 &heurdata->bestsollimit, FALSE, DEFAULT_BESTSOLLIMIT, -1, INT_MAX, NULL, NULL) );
641
642 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/violpenalty",
643 "the penalty for each change in the binary variables from the candidate solution",
644 &heurdata->violpenalty, FALSE, DEFAULT_VIOLPENALTY, 0.0, SCIP_REAL_MAX, NULL, NULL) );
645
646 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/objminimprove",
647 "the minimum absolute improvement in the objective function value",
648 &heurdata->objminimprove, FALSE, DEFAULT_OBJMINIMPROVE, 0.0, SCIP_REAL_MAX, NULL, NULL) );
649
650 return SCIP_OKAY;
651}
#define EVENTHDLR_NAME
#define EVENTHDLR_DESC
#define DEFAULT_MAXNODES
Constraint handler for linear constraints in their most general form, .
#define NULL
Definition def.h:257
#define SCIP_MAXSTRLEN
Definition def.h:278
#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 SCIP_CALL(x)
Definition def.h:364
#define DEFAULT_MINNODES
SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPtranslateSubSols(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_VAR **subvars, SCIP_Bool *success, int *solindex)
Definition scip_copy.c:1438
SCIP_RETCODE SCIPsetCommonSubscipParams(SCIP *sourcescip, SCIP *subscip, SCIP_Longint nsubnodes, SCIP_Longint nstallnodes, int bestsollimit)
Definition scip_copy.c:3336
SCIP_RETCODE SCIPcheckCopyLimits(SCIP *sourcescip, SCIP_Bool *success)
Definition scip_copy.c:3250
SCIP_Bool SCIPisStopped(SCIP *scip)
SCIP_RETCODE SCIPfree(SCIP **scip)
SCIP_RETCODE SCIPcreate(SCIP **scip)
SCIP_STATUS SCIPgetStatus(SCIP *scip)
const char * SCIPgetProbName(SCIP *scip)
Definition scip_prob.c:1242
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition scip_prob.c:2115
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition scip_prob.c:3274
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
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 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 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 SCIPincludeHeurTrustregion(SCIP *scip)
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
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 SCIPheurGetNSolsFound(SCIP_HEUR *heur)
Definition heur.c:1603
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
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
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
Definition scip_sol.c:2986
int SCIPgetNSols(SCIP *scip)
Definition scip_sol.c:2887
SCIP_HEUR * SCIPsolGetHeur(SCIP_SOL *sol)
Definition sol.c:4274
SCIP_Bool SCIPsolIsOriginal(SCIP_SOL *sol)
Definition sol.c:4155
SCIP_Longint SCIPgetSolNodenum(SCIP *scip, SCIP_SOL *sol)
Definition scip_sol.c:2221
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 SCIPinterruptSolve(SCIP *scip)
SCIP_RETCODE SCIPsolve(SCIP *scip)
SCIP_Longint SCIPgetNNodes(SCIP *scip)
SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
SCIP_Longint SCIPgetNLPs(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_RETCODE SCIPaddTrustregionNeighborhoodConstraint(SCIP *sourcescip, SCIP *targetscip, SCIP_VAR **subvars, SCIP_Real violpenalty)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition var.c:23932
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition misc.c:10827
#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_NWAITINGNODES
#define DEFAULT_USELPROWS
#define DEFAULT_BESTSOLLIMIT
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
#define EXECUTE
#define WAITFORNEWSOL
heurdata usednodes
Definition heur_locks.c:163
static SCIP_VAR ** vars
static SCIP_RETCODE setupAndSolveSubscipTrustregion(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_Longint nsubnodes, SCIP_RESULT *result)
static SCIP_RETCODE addTrustRegionConstraints(SCIP *scip, SCIP *subscip, SCIP_VAR **subvars, SCIP_HEURDATA *heurdata)
#define DEFAULT_OBJMINIMPROVE
#define DEFAULT_VIOLPENALTY
#define DEFAULT_MINBINVARS
Large neighborhood search heuristic for Benders' decomposition based on trust region methods.
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
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 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 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_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
struct SCIP_HashMap SCIP_HASHMAP
Definition type_misc.h:106
@ 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
@ SCIP_STATUS_TOTALNODELIMIT
Definition type_stat.h:50
@ SCIP_STATUS_STALLNODELIMIT
Definition type_stat.h:52
@ SCIP_STATUS_NODELIMIT
Definition type_stat.h:49
struct SCIP_Var SCIP_VAR
Definition type_var.h:166