SCIP Doxygen Documentation
Loading...
Searching...
No Matches
heur_guideddiving.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_guideddiving.c
26 * @ingroup DEFPLUGINS_HEUR
27 * @brief LP diving heuristic that chooses fixings in direction of incumbent solutions
28 * @author Tobias Achterberg
29 */
30
31/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
32
34#include "scip/heuristics.h"
35#include "scip/pub_heur.h"
36#include "scip/pub_message.h"
37#include "scip/pub_sol.h"
38#include "scip/pub_var.h"
39#include "scip/scip_heur.h"
40#include "scip/scip_lp.h"
41#include "scip/scip_mem.h"
42#include "scip/scip_numerics.h"
43#include "scip/scip_prob.h"
44#include "scip/scip_sol.h"
45
46
47#define HEUR_NAME "guideddiving"
48#define HEUR_DESC "LP diving heuristic that chooses fixings in direction of incumbent solutions"
49#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_DIVING
50#define HEUR_PRIORITY -1007000
51#define HEUR_FREQ 10
52#define HEUR_FREQOFS 7
53#define HEUR_MAXDEPTH -1
54#define HEUR_TIMING SCIP_HEURTIMING_AFTERLPPLUNGE
55#define HEUR_USESSUBSCIP FALSE /**< does the heuristic use a secondary SCIP instance? */
56#define DIVESET_DIVETYPES SCIP_DIVETYPE_INTEGRALITY /**< bit mask that represents all supported dive types */
57#define DIVESET_ISPUBLIC TRUE /**< is this dive set publicly available (ie., can be used by other primal heuristics?) */
58
59
60/*
61 * Default parameter settings
62 */
63
64#define DEFAULT_MINRELDEPTH 0.0 /**< minimal relative depth to start diving */
65#define DEFAULT_MAXRELDEPTH 1.0 /**< maximal relative depth to start diving */
66#define DEFAULT_MAXLPITERQUOT 0.05 /**< maximal fraction of diving LP iterations compared to node LP iterations */
67#define DEFAULT_MAXLPITEROFS 1000 /**< additional number of allowed LP iterations */
68#define DEFAULT_MAXDIVEUBQUOT 0.8 /**< maximal quotient (curlowerbound - lowerbound)/(cutoffbound - lowerbound)
69 * where diving is performed (0.0: no limit) */
70#define DEFAULT_MAXDIVEAVGQUOT 0.0 /**< maximal quotient (curlowerbound - lowerbound)/(avglowerbound - lowerbound)
71 * where diving is performed (0.0: no limit) */
72#define DEFAULT_BACKTRACK TRUE /**< use one level of backtracking if infeasibility is encountered? */
73#define DEFAULT_LPRESOLVEDOMCHGQUOT 0.15 /**< percentage of immediate domain changes during probing to trigger LP resolve */
74#define DEFAULT_LPSOLVEFREQ 0 /**< LP solve frequency for diving heuristics */
75#define DEFAULT_ONLYLPBRANCHCANDS FALSE /**< should only LP branching candidates be considered instead of the slower but
76 * more general constraint handler diving variable selection? */
77#define DEFAULT_RANDSEED 127 /**< initial seed for random number generation */
78
79/* locally defined heuristic data */
80struct SCIP_HeurData
81{
82 SCIP_SOL* sol; /**< working solution */
83};
84
85/*
86 * local methods
87 */
88
89/*
90 * Callback methods
91 */
92
93/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
94static
95SCIP_DECL_HEURCOPY(heurCopyGuideddiving)
96{ /*lint --e{715}*/
97 assert(scip != NULL);
98 assert(heur != NULL);
99
101
102 /* call inclusion method of primal heuristic */
104
105 return SCIP_OKAY;
106}
107
108/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
109static
110SCIP_DECL_HEURFREE(heurFreeGuideddiving) /*lint --e{715}*/
111{ /*lint --e{715}*/
113
114 assert(heur != NULL);
116
118
119 /* free heuristic data */
122
125
126 return SCIP_OKAY;
127}
128
129
130/** initialization method of primal heuristic (called after problem was transformed) */
131static
132SCIP_DECL_HEURINIT(heurInitGuideddiving) /*lint --e{715}*/
133{ /*lint --e{715}*/
135
136 assert(heur != NULL);
137
139
140 /* get heuristic data */
142 assert(heurdata != NULL);
143
144 /* create working solution */
146
147 return SCIP_OKAY;
148}
149
150
151/** deinitialization method of primal heuristic (called before transformed problem is freed) */
152static
153SCIP_DECL_HEUREXIT(heurExitGuideddiving) /*lint --e{715}*/
154{ /*lint --e{715}*/
156
157 assert(heur != NULL);
158
160
161 /* get heuristic data */
163 assert(heurdata != NULL);
164
165 /* free working solution */
167
168 return SCIP_OKAY;
169}
170
171
172/** execution method of primal heuristic */
173static
174SCIP_DECL_HEUREXEC(heurExecGuideddiving) /*lint --e{715}*/
175{ /*lint --e{715}*/
178
179 assert(heur != NULL);
180 assert(scip != NULL);
183
185
187
188 /* don't dive, if no feasible solutions exist */
189 if( SCIPgetNSols(scip) == 0 )
190 return SCIP_OKAY;
191
192 /* get best solution that should guide the search; if this solution lives in the original variable space,
193 * we cannot use it since it might violate the global bounds of the current problem
194 */
196 return SCIP_OKAY;
197
198 /* get heuristic's data */
200 assert(heurdata != NULL);
201
202 /* if there are no integer variables (note that, e.g., SOS1 variables may be present) */
204 return SCIP_OKAY;
205
206 assert(SCIPheurGetNDivesets(heur) > 0);
208 diveset = SCIPheurGetDivesets(heur)[0];
209 assert(diveset != NULL);
210
211 /* call generic diving algorithm */
212 SCIP_CALL( SCIPperformGenericDivingAlgorithm(scip, diveset, heurdata->sol, heur, result, nodeinfeasible, -1L, -1, -1.0, SCIP_DIVECONTEXT_SINGLE) );
213
214 return SCIP_OKAY;
215}
216
217/* callbacks for diving */
218
219/** calculate score and preferred rounding direction for the candidate variable; the best candidate maximizes the
220 * score
221 */
222static
223SCIP_DECL_DIVESETGETSCORE(divesetGetScoreGuideddiving)
224{
225 SCIP_SOL* bestsol;
226 SCIP_Real bestsolval;
228 SCIP_Real objnorm;
229 SCIP_Real objgain;
230
231 bestsol = SCIPgetBestSol(scip);
232 assert(bestsol != NULL);
233 assert(!SCIPsolIsOriginal(bestsol));
234
235 bestsolval = SCIPgetSolVal(scip, bestsol, cand);
236
237 /* variable should be rounded (guided) into the direction of its incumbent solution value */
238 if( candsol < bestsolval )
239 *roundup = TRUE;
240 else
241 *roundup = FALSE;
242
243 obj = SCIPvarGetObj(cand);
244 objnorm = SCIPgetObjNorm(scip);
245
246 /* divide by objective norm to normalize obj into [-1,1] */
247 if( SCIPisPositive(scip, objnorm) )
248 obj /= objnorm;
249
250 /* calculate objective gain and fractionality for the selected rounding direction */
251 if( *roundup )
252 {
253 candsfrac = 1.0 - candsfrac;
254 objgain = obj * candsfrac;
255 }
256 else
257 objgain = -obj * candsfrac;
258
259 assert(objgain >= -1.0 && objgain <= 1.0);
260
261 /* penalize too small fractions */
262 if( candsfrac < 0.01 )
263 candsfrac *= 0.1;
264
265 /* prefer decisions on binary variables */
266 if( !SCIPvarIsBinary(cand) )
267 candsfrac *= 0.1;
268
269 /* prefer variables which cannot be rounded by scoring their fractionality */
270 if( !(SCIPvarMayRoundDown(cand) || SCIPvarMayRoundUp(cand)) )
271 *score = -candsfrac;
272 else
273 *score = -2.0 - objgain;
274
275 return SCIP_OKAY;
276}
277
278/** callback to check preconditions for diving, e.g., if an incumbent solution is available */
279static
280SCIP_DECL_DIVESETAVAILABLE(divesetAvailableGuideddiving)
281{
282 /* don't dive with guided diving if no feasible solutions exists or
283 * if this solution lives in the original variable space,
284 * because it might violate the global bounds of the current problem
285 */
287 *available = FALSE;
288 else
289 *available = TRUE;
290
291 return SCIP_OKAY;
292}
293
294/*
295 * heuristic specific interface methods
296 */
297
298/** creates the guideddiving heuristic and includes it in SCIP */
300 SCIP* scip /**< SCIP data structure */
301 )
302{
304 SCIP_HEUR* heur;
305
306 /* create Guideddiving primal heuristic data */
308
309 /* include primal heuristic */
312 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecGuideddiving, heurdata) );
313
314 assert(heur != NULL);
315
316 /* primal heuristic is safe to use in exact solving mode */
317 SCIPheurMarkExact(heur);
318
319 /* set non-NULL pointers to callback methods */
320 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyGuideddiving) );
321 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeGuideddiving) );
322 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitGuideddiving) );
323 SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitGuideddiving) );
324
325 /* create a diveset (this will automatically install some additional parameters for the heuristic)*/
329 divesetGetScoreGuideddiving, divesetAvailableGuideddiving) );
330
331 return SCIP_OKAY;
332}
#define DEFAULT_RANDSEED
#define NULL
Definition def.h:257
#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 SCIP_CALL(x)
Definition def.h:364
int SCIPgetNContVars(SCIP *scip)
Definition scip_prob.c:2569
int SCIPgetNVars(SCIP *scip)
Definition scip_prob.c:2246
SCIP_Real SCIPgetObjNorm(SCIP *scip)
Definition scip_prob.c:1880
int SCIPgetNContImplVars(SCIP *scip)
Definition scip_prob.c:2522
SCIP_RETCODE SCIPincludeHeurGuideddiving(SCIP *scip)
SCIP_RETCODE SCIPcreateDiveset(SCIP *scip, SCIP_DIVESET **diveset, SCIP_HEUR *heur, const char *name, SCIP_Real minreldepth, SCIP_Real maxreldepth, SCIP_Real maxlpiterquot, SCIP_Real maxdiveubquot, SCIP_Real maxdiveavgquot, SCIP_Real maxdiveubquotnosol, SCIP_Real maxdiveavgquotnosol, SCIP_Real lpresolvedomchgquot, int lpsolvefreq, int maxlpiterofs, unsigned int initialseed, SCIP_Bool backtrack, SCIP_Bool onlylpbranchcands, SCIP_Bool ispublic, SCIP_Bool specificsos1score, SCIP_DECL_DIVESETGETSCORE((*divesetgetscore)),)
Definition scip_heur.c:323
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:183
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition heur.c:1368
SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
Definition scip_heur.c:122
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:167
int SCIPheurGetNDivesets(SCIP_HEUR *heur)
Definition heur.c:1675
void SCIPheurMarkExact(SCIP_HEUR *heur)
Definition heur.c:1457
SCIP_RETCODE SCIPsetHeurExit(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:215
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:199
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition heur.c:1467
SCIP_DIVESET ** SCIPheurGetDivesets(SCIP_HEUR *heur)
Definition heur.c:1665
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
Definition scip_lp.c:87
#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_Bool SCIPsolIsOriginal(SCIP_SOL *sol)
Definition sol.c:4155
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition scip_sol.c:1763
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPvarMayRoundUp(SCIP_VAR *var)
Definition var.c:4478
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition var.c:23510
SCIP_Bool SCIPvarMayRoundDown(SCIP_VAR *var)
Definition var.c:4467
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition var.c:23932
#define DEFAULT_ONLYLPBRANCHCANDS
#define DEFAULT_MAXDIVEUBQUOT
#define DEFAULT_LPRESOLVEDOMCHGQUOT
#define HEUR_TIMING
return SCIP_OKAY
#define DEFAULT_MAXLPITERQUOT
#define HEUR_FREQOFS
#define HEUR_DESC
#define DEFAULT_MAXDIVEAVGQUOT
#define DEFAULT_LPSOLVEFREQ
#define DEFAULT_BACKTRACK
#define HEUR_DISPCHAR
#define HEUR_MAXDEPTH
#define HEUR_PRIORITY
#define DEFAULT_MAXRELDEPTH
#define DEFAULT_MAXLPITEROFS
#define HEUR_NAME
#define DIVESET_DIVETYPES
#define DIVESET_ISPUBLIC
#define HEUR_FREQ
#define DEFAULT_MINRELDEPTH
#define HEUR_USESSUBSCIP
static SCIP_DIVESET * diveset
SCIPperformGenericDivingAlgorithm(scip, diveset, heurdata->sol, heur, result, nodeinfeasible, lpiterlimit, -1, -1.0, SCIP_DIVECONTEXT_ADAPTIVE))
SCIPheurSetData(heur, NULL)
SCIPfreeSol(scip, &heurdata->sol))
SCIPcreateSol(scip, &heurdata->sol, heur))
LP diving heuristic that chooses fixings in direction of incumbent solutions.
static SCIP_SOL * sol
SCIP_Real obj
assert(minobj< SCIPgetCutoffbound(scip))
SCIP_Bool roundup
methods commonly used by primal heuristics
public methods for primal heuristics
public methods for message output
public methods for primal CIP solutions
public methods for problem variables
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 numerical tolerances
public methods for global and local (sub)problems
public methods for solutions
#define SCIP_DECL_DIVESETAVAILABLE(x)
Definition type_heur.h:199
#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
struct SCIP_Diveset SCIP_DIVESET
Definition type_heur.h:78
#define SCIP_DECL_HEUREXIT(x)
Definition type_heur.h:121
#define SCIP_DECL_HEURFREE(x)
Definition type_heur.h:105
#define SCIP_DECL_DIVESETGETSCORE(x)
Definition type_heur.h:184
#define SCIP_DECL_HEUREXEC(x)
Definition type_heur.h:163
@ SCIP_DIVECONTEXT_SINGLE
Definition type_heur.h:69
@ SCIP_DIDNOTRUN
Definition type_result.h:42
@ 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