SCIP Doxygen Documentation
Loading...
Searching...
No Matches
heur_feaspump.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_feaspump.c
26 * @ingroup DEFPLUGINS_HEUR
27 * @brief Objective Feasibility Pump 2.0
28 * @author Timo Berthold
29 * @author Domenico Salvagnin
30 */
31
32/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
33
35#include "scip/cons_linear.h"
36#include "scip/heur_feaspump.h"
37#include "scip/pub_heur.h"
38#include "scip/pub_message.h"
39#include "scip/pub_misc.h"
40#include "scip/pub_misc_sort.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_exact.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_nodesel.h"
52#include "scip/scip_numerics.h"
53#include "scip/scip_param.h"
54#include "scip/scip_pricer.h"
55#include "scip/scip_prob.h"
56#include "scip/scip_probing.h"
58#include "scip/scip_sol.h"
59#include "scip/scip_solve.h"
61#include "scip/scip_tree.h"
62#include "scip/scip_var.h"
63
64
65#define HEUR_NAME "feaspump"
66#define HEUR_DESC "objective feasibility pump 2.0"
67#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_OBJDIVING
68#define HEUR_PRIORITY -1000000
69#define HEUR_FREQ 20
70#define HEUR_FREQOFS 0
71#define HEUR_MAXDEPTH -1
72#define HEUR_TIMING SCIP_HEURTIMING_AFTERLPPLUNGE
73#define HEUR_USESSUBSCIP FALSE /**< does the heuristic use a secondary SCIP instance? */
74
75#define DEFAULT_MAXLPITERQUOT 0.05 /**< maximal fraction of diving LP iterations compared to node LP iterations */
76#define DEFAULT_MAXLPITEROFS 1000 /**< additional number of allowed LP iterations */
77#define DEFAULT_MAXSOLS 10 /**< total number of feasible solutions found up to which heuristic is called
78 * (-1: no limit) */
79#define DEFAULT_MAXLOOPS 10000 /**< maximal number of pumping rounds (-1: no limit) */
80#define DEFAULT_MAXSTALLLOOPS 10 /**< maximal number of pumping rounds without fractionality improvement (-1: no limit) */
81#define DEFAULT_MINFLIPS 10 /**< minimum number of random variables to flip, if a 1-cycle is encountered */
82#define DEFAULT_CYCLELENGTH 3 /**< maximum length of cycles to be checked explicitly in each round */
83#define DEFAULT_PERTURBFREQ 100 /**< number of iterations until a random perturbation is forced */
84#define DEFAULT_OBJFACTOR 0.1 /**< factor by which the regard of the objective is decreased in each round,
85 * 1.0 for dynamic, depending on solutions already found */
86#define DEFAULT_ALPHA 1.0 /**< initial weight of the objective function in the convex combination */
87#define DEFAULT_ALPHADIFF 1.0 /**< threshold difference for the convex parameter to perform perturbation */
88#define DEFAULT_BEFORECUTS TRUE /**< should the feasibility pump be called at root node before cut separation? */
89#define DEFAULT_USEFP20 FALSE /**< should an iterative round-and-propagate scheme be used to find the integral points? */
90#define DEFAULT_PERTSOLFOUND TRUE /**< should a random perturbation be performed if a feasible solution was found? */
91#define DEFAULT_STAGE3 FALSE /**< should we solve a local branching sub-MIP if no solution could be found? */
92#define DEFAULT_NEIGHBORHOODSIZE 18 /**< radius of the neighborhood to be searched in stage 3 */
93#define DEFAULT_COPYCUTS TRUE /**< should all active cuts from the cutpool of the original SCIP be copied to
94 * constraints of the subscip
95 */
96
97#define MINLPITER 5000 /**< minimal number of LP iterations allowed in each LP solving call */
98
99#define DEFAULT_RANDSEED 13 /**< initial random seed */
100
101/** primal heuristic data */
102struct SCIP_HeurData
103{
104 SCIP_SOL* sol; /**< working solution */
105 SCIP_SOL* roundedsol; /**< rounded solution */
106 SCIP_Longint nlpiterations; /**< number of LP iterations used in this heuristic */
107 SCIP_Real maxlpiterquot; /**< maximal fraction of diving LP iterations compared to node LP iterations */
108 SCIP_Real objfactor; /**< factor by which the regard of the objective is decreased in each round,
109 * 1.0 for dynamic, depending on solutions already found */
110 SCIP_Real alpha; /**< initial weight of the objective function in the convex combination */
111 SCIP_Real alphadiff; /**< threshold difference for the convex parameter to perform perturbation */
112
113 int maxlpiterofs; /**< additional number of allowed LP iterations */
114 int maxsols; /**< total number of feasible solutions found up to which heuristic is called
115 * (-1: no limit) */
116 int maxloops; /**< maximum number of loops (-1: no limit) */
117 int maxstallloops; /**< maximal number of pumping rounds without fractionality improvement (-1: no limit) */
118 int minflips; /**< minimum number of random variables to flip, if a 1-cycle is encountered */
119 int cyclelength; /**< maximum length of cycles to be checked explicitly in each round */
120 int perturbfreq; /**< number of iterations until a random perturbation is forced */
121 int nsuccess; /**< number of runs that produced at least one feasible solution */
122 int neighborhoodsize; /**< radius of the neighborhood to be searched in stage 3 */
123
124 SCIP_RANDNUMGEN* randnumgen; /**< random number generator */
125 SCIP_Bool beforecuts; /**< should the feasibility pump be called at root node before cut separation? */
126 SCIP_Bool usefp20; /**< should an iterative round-and-propagate scheme be used to find the integral points? */
127 SCIP_Bool pertsolfound; /**< should a random perturbation be performed if a feasible solution was found? */
128 SCIP_Bool stage3; /**< should we solve a local branching sub-MIP if no solution could be found? */
129 SCIP_Bool copycuts; /**< should all active cuts from cutpool be copied to constraints in
130 * subproblem?
131 */
132};
133
134/* copies SCIP to probing SCIP and creates variable hashmap */
135static
137 SCIP* scip, /**< SCIP data structure */
138 SCIP** probingscip, /**< sub-SCIP data structure */
139 SCIP_HASHMAP** varmapfw, /**< mapping of SCIP variables to sub-SCIP variables */
140 SCIP_Bool copycuts, /**< should all active cuts from cutpool of scip copied to constraints in subscip */
141 SCIP_Bool* success /**< was copying successful? */
142 )
143{
144 /* check if we are already at the maximal tree depth */
146 {
147 *success = FALSE;
148 return SCIP_OKAY;
149 }
150
151 /* initializing the subproblem */
152 SCIP_CALL( SCIPcreate(probingscip) );
153
154 /* create the variable mapping hash map */
155 SCIP_CALL( SCIPhashmapCreate(varmapfw, SCIPblkmem(*probingscip), SCIPgetNVars(scip)) );
156 *success = FALSE;
157
158 /* copy SCIP instance */
159 SCIP_CALL( SCIPcopyConsCompression(scip, *probingscip, *varmapfw, NULL, "feaspump", NULL, NULL, 0, FALSE, FALSE,
160 FALSE, TRUE, success) );
161 assert(!SCIPisExact(*probingscip));
162
163 if( copycuts )
164 {
165 /* copies all active cuts from cutpool of sourcescip to linear constraints in targetscip */
166 SCIP_CALL( SCIPcopyCuts(scip, *probingscip, *varmapfw, NULL, FALSE, NULL) );
167 }
168
169 return SCIP_OKAY;
170}
171
172/** set appropriate parameters for probing SCIP in FP2 */
173static
175 SCIP* scip, /**< SCIP data structure */
176 SCIP* probingscip /**< sub-SCIP data structure */
177 )
178{
179 if( SCIPisParamFixed(probingscip, "heuristics/" HEUR_NAME "/freq") )
180 {
181 SCIPwarningMessage(scip, "unfixing parameter heuristics/" HEUR_NAME "/freq in probingscip of " HEUR_NAME " heuristic to avoid recursive calls\n");
182 SCIP_CALL( SCIPunfixParam(probingscip, "heuristics/" HEUR_NAME "/freq") );
183 }
184 SCIP_CALL( SCIPsetIntParam(probingscip, "heuristics/" HEUR_NAME "/freq", -1) );
185
186 /* do not abort subproblem on CTRL-C */
187 SCIP_CALL( SCIPsetBoolParam(probingscip, "misc/catchctrlc", FALSE) );
188
189#ifndef SCIP_DEBUG
190 /* disable output to console */
191 SCIP_CALL( SCIPsetIntParam(probingscip, "display/verblevel", 0) );
192#endif
193
194 /* do not multiaggregate variables, because otherwise they have to be skipped in the fix-and-propagate loop */
195 SCIP_CALL( SCIPsetBoolParam(probingscip, "presolving/donotmultaggr", TRUE) );
196
197 /* limit to root node solving */
198 SCIP_CALL( SCIPsetLongintParam(probingscip, "limits/nodes", 1LL) );
199
200 /* disable LP solving and expensive techniques */
201 if( SCIPisParamFixed(probingscip, "lp/solvefreq") )
202 {
203 SCIPwarningMessage(scip, "unfixing parameter lp/solvefreq in probingscip of " HEUR_NAME " heuristic to speed up propagation\n");
204 SCIP_CALL( SCIPunfixParam(probingscip, "lp/solvefreq") );
205 }
206 SCIP_CALL( SCIPsetIntParam(probingscip, "lp/solvefreq", -1) );
207 SCIP_CALL( SCIPsetBoolParam(probingscip, "conflict/enable", FALSE) );
208 SCIP_CALL( SCIPsetBoolParam(probingscip, "constraints/disableenfops", TRUE) );
209 SCIP_CALL( SCIPsetBoolParam(probingscip, "constraints/knapsack/negatedclique", FALSE) );
212
213 return SCIP_OKAY;
214}
215
216/** set appropriate parameters for probing SCIP in Stage 3 */
217static
219 SCIP* scip, /**< SCIP data structure */
220 SCIP* probingscip /**< sub-SCIP data structure */
221 )
222{
223 /**@todo restore the copied settings that were changed in setupSCIPparamsFP2() without copying all parameters, since
224 * this triggers an error message that exact solving cannot be enabled/disabled in or after problem creation stage
225 */
226 SCIP_CALL( SCIPcopyParamSettings(scip, probingscip) );
227 assert(!SCIPisExact(probingscip));
228
229 /* do not abort subproblem on CTRL-C */
230 SCIP_CALL( SCIPsetBoolParam(probingscip, "misc/catchctrlc", FALSE) );
231
232#ifndef SCIP_DEBUG
233 /* disable output to console */
234 SCIP_CALL( SCIPsetIntParam(probingscip, "display/verblevel", 0) );
235#endif
236 /* set limits for the subproblem */
237 SCIP_CALL( SCIPcopyLimits(scip, probingscip) );
238 SCIP_CALL( SCIPsetLongintParam(probingscip, "limits/nodes", 1000LL) );
239 SCIP_CALL( SCIPsetLongintParam(probingscip, "limits/stallnodes", 100LL) );
240
241 /* forbid recursive call of heuristics and separators solving sub-SCIPs */
242 SCIP_CALL( SCIPsetSubscipsOff(probingscip, TRUE) );
243 if( SCIPisParamFixed(probingscip, "heuristics/" HEUR_NAME "/freq") )
244 {
245 SCIPwarningMessage(scip,"unfixing parameter heuristics/" HEUR_NAME "/freq in probingscip of " HEUR_NAME " heuristic to avoid recursive calls\n");
246 SCIP_CALL( SCIPunfixParam(probingscip, "heuristics/" HEUR_NAME "/freq") );
247 }
248 SCIP_CALL( SCIPsetIntParam(probingscip, "heuristics/feaspump/freq", -1) );
249
250 /* disable heuristics which aim to feasibility instead of optimality */
251 if( !SCIPisParamFixed(probingscip, "heuristics/octane/freq") )
252 {
253 SCIP_CALL( SCIPsetIntParam(probingscip, "heuristics/octane/freq", -1) );
254 }
255 if( !SCIPisParamFixed(probingscip, "heuristics/objpscostdiving/freq") )
256 {
257 SCIP_CALL( SCIPsetIntParam(probingscip, "heuristics/objpscostdiving/freq", -1) );
258 }
259 if( !SCIPisParamFixed(probingscip, "heuristics/rootsoldiving/freq") )
260 {
261 SCIP_CALL( SCIPsetIntParam(probingscip, "heuristics/rootsoldiving/freq", -1) );
262 }
263
264 /* disable cutting plane separation */
266
267 /* disable expensive presolving */
269
270 /* use best estimate node selection */
271 if( SCIPfindNodesel(probingscip, "estimate") != NULL && !SCIPisParamFixed(probingscip, "nodeselection/estimate/stdpriority") )
272 {
273 SCIP_CALL( SCIPsetIntParam(probingscip, "nodeselection/estimate/stdpriority", INT_MAX/4) );
274 }
275
276 /* use inference branching */
277 if( SCIPfindBranchrule(probingscip, "inference") != NULL && !SCIPisParamFixed(probingscip, "branching/inference/priority") )
278 {
279 SCIP_CALL( SCIPsetIntParam(probingscip, "branching/inference/priority", INT_MAX/4) );
280 }
281
282 /* disable conflict analysis */
283 if( !SCIPisParamFixed(probingscip, "conflict/enable") )
284 {
285 SCIP_CALL( SCIPsetBoolParam(probingscip, "conflict/enable", FALSE) );
286 }
287
288 return SCIP_OKAY;
289}
290
291/** checks whether a variable is one of the currently most fractional ones */
292static
294 SCIP_VAR** mostfracvars, /**< sorted array of the currently most fractional variables */
295 SCIP_Real* mostfracvals, /**< array of their fractionality, decreasingly sorted */
296 int* nflipcands, /**< number of fractional variables already labeled to be flipped*/
297 int maxnflipcands, /**< typically randomized number of maximum amount of variables to flip */
298 SCIP_VAR* var, /**< variable to be checked */
299 SCIP_Real frac /**< fractional value of the variable */
300 )
301{
302 int i;
303
304 assert(mostfracvars != NULL);
305 assert(mostfracvals != NULL);
306 assert(nflipcands != NULL);
307
308 /* instead of the fractional value use the fractionality */
309 if( frac > 0.5 )
310 frac = 1 - frac;
311
312 /* if there are already enough candidates and the variable is less fractional, return, else reserve the last entry */
313 if( *nflipcands >= maxnflipcands )
314 {
315 if( frac <= mostfracvals[*nflipcands-1] )
316 return;
317 else
318 (*nflipcands)--;
319 }
320
321 /* shifting var and frac through the (sorted) arrays */
322 for( i = *nflipcands; i > 0 && mostfracvals[i-1] < frac; i-- )
323 {
324 mostfracvars[i] = mostfracvars[i-1];
325 mostfracvals[i] = mostfracvals[i-1];
326 }
327 assert(0 <= i && i <= *nflipcands && *nflipcands < maxnflipcands);
328
329 /* insert the variable and its fractionality */
330 mostfracvars[i] = var;
331 mostfracvals[i] = frac;
332
333 /* we've found another candidate */
334 (*nflipcands)++;
335}
336
337/** set solution value in rounded solution and update objective coefficient accordingly */
338static
340 SCIP* scip, /**< SCIP data structure */
341 SCIP_HEURDATA* heurdata, /**< heuristic data structure */
342 SCIP_VAR* var, /**< variable */
343 SCIP_Real solval, /**< solution value for this variable */
344 SCIP_Real alpha, /**< weight of original objective function */
345 SCIP_Real scalingfactor /**< factor to scale the original objective function with */
346 )
347{
348 SCIP_Real lb;
349 SCIP_Real ub;
350 SCIP_Real newobjcoeff;
351 SCIP_Real orgobjcoeff;
352
353 assert(heurdata != NULL);
354 assert(var != NULL);
355
358
359 /* update rounded solution */
360 assert(SCIPisFeasLE(scip, lb, solval) && SCIPisFeasLE(scip, solval, ub));
361 assert(SCIPisIntegral(scip,solval));
362 SCIP_CALL( SCIPsetSolVal(scip, heurdata->roundedsol, var, solval) );
363
364 /* modify objective towards rounded solution value if it is at one of the variable bounds */
365 orgobjcoeff = SCIPvarGetObj(var);
366 if( SCIPisEQ(scip, solval, lb) )
367 newobjcoeff = (1.0 - alpha)/scalingfactor + alpha * orgobjcoeff;
368 else if( SCIPisEQ(scip, solval, ub) )
369 newobjcoeff = - (1.0 - alpha)/scalingfactor + alpha * orgobjcoeff;
370 else
371 newobjcoeff = alpha * orgobjcoeff;
372
373 SCIP_CALL( SCIPchgVarObjDive(scip, var, newobjcoeff) );
374
375 return SCIP_OKAY;
376}
377
378
379/** flips the roundings of the most fractional variables, if a 1-cycle was found */
380static
382 SCIP* scip, /**< SCIP data structure */
383 SCIP_HEURDATA* heurdata, /**< data of this special heuristic */
384 SCIP_VAR** mostfracvars, /**< sorted array of the currently most fractional variables */
385 int nflipcands, /**< number of variables to flip */
386 SCIP_Real alpha, /**< factor how much the original objective is regarded */
387 SCIP_Real scalingfactor /**< factor to scale the original objective function with */
388 )
389{
390 int i;
391
392 /* flip rounding to the opposite side */
393 for( i = 0; i < nflipcands; i++ )
394 {
395 SCIP_VAR* var;
396 SCIP_Real solval;
397 SCIP_Real roundedsolval;
398
399 var = mostfracvars[i];
400 solval = SCIPvarGetLPSol(var);
401 roundedsolval = SCIPgetSolVal(scip, heurdata->roundedsol, var);
402
403 assert(! SCIPisFeasIntegral(scip, solval));
404 assert(SCIPisFeasIntegral(scip, roundedsolval));
405
406 /* flip to the opposite rounded solution value */
407 if( roundedsolval > solval )
408 solval = SCIPfeasFloor(scip, solval);
409 else
410 {
411 solval = SCIPfeasCeil(scip, solval);
412 }
413
414 SCIPdebugMsg(scip, "1-cycle flip: variable <%s> [%g,%g] LP sol %.15g sol %.15g -> %.15g\n",
416 SCIPvarGetLPSol(var), SCIPgetSolVal(scip, heurdata->roundedsol, var), solval);
417
418 SCIP_CALL( updateVariableRounding(scip, heurdata, var, solval, alpha, scalingfactor) );
419 }
420 return SCIP_OKAY;
421}
422
423/** flips the roundings of randomly chosen fractional variables, preferring highly fractional ones,
424 * if a longer cycle was found
425 */
426static
428 SCIP* scip, /**< SCIP data structure */
429 SCIP_HEURDATA* heurdata, /**< data of this special heuristic */
430 SCIP_VAR** vars, /**< array of all variables */
431 int nbinandintvars, /**< number of general integer and 0-1 variables */
432 SCIP_Real alpha, /**< factor how much the original objective is regarded */
433 SCIP_Real scalingfactor /**< factor to scale the original objective function with */
434 )
435{
436 int i;
437
438 /* flip variables randomized biased on their fractionality */
439 for( i = 0; i < nbinandintvars; i++ )
440 {
441 SCIP_VAR* var;
442 SCIP_Real solval;
444 SCIP_Real flipprob;
445 SCIP_Real roundedsolval;
446
447 var = vars[i];
448 solval = SCIPvarGetLPSol(var);
449
450 /* skip variables with integral solution values */
451 if( SCIPisFeasIntegral(scip, solval) )
452 continue;
453
454 frac = SCIPfeasFrac(scip, solval);
455 flipprob = SCIPrandomGetReal(heurdata->randnumgen, -0.3, 0.7);
456
457 /* flip, iff the sum of the randomized number and the fractionality is big enough */
458 if( MIN(frac, 1.0 - frac) + MAX(flipprob, 0.0) > 0.5 )
459 {
460 roundedsolval = SCIPgetSolVal(scip, heurdata->roundedsol, var);
461 assert(SCIPisFeasIntegral(scip, roundedsolval));
462
463 /* flip the solution to the opposite side */
464 if( roundedsolval > solval )
465 solval = SCIPfloor(scip, solval);
466 else
467 solval = SCIPceil(scip, solval);
468
469 /* update rounded solution value and objective coefficient */
470 SCIP_CALL( updateVariableRounding(scip, heurdata, var, solval, alpha, scalingfactor) );
471 }
472 }
473
474 return SCIP_OKAY;
475}
476
477/** create the extra constraint of local branching and add it to subscip */
478static
480 SCIP* scip, /**< SCIP data structure of the original problem */
481 SCIP* probingscip, /**< SCIP data structure of the subproblem */
482 SCIP_HASHMAP* varmapfw, /**< mapping of SCIP variables to sub-SCIP variables */
483 SCIP_SOL* bestsol, /**< SCIP solution */
484 SCIP_Real neighborhoodsize /**< rhs for LB constraint */
485 )
486{
487 SCIP_CONS* cons; /* local branching constraint to create */
488 SCIP_VAR** consvars;
489 SCIP_VAR** vars;
490
491 int nbinvars;
492 int nconsvars;
493 int i;
494 SCIP_Real lhs;
495 SCIP_Real rhs;
496 SCIP_Real* consvals;
497 char consname[SCIP_MAXSTRLEN];
498
499 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_localbranchcons", SCIPgetProbName(scip));
500
501 /* get vars data */
502 SCIP_CALL( SCIPgetVarsData(scip, &vars, NULL, &nbinvars, NULL, NULL, NULL) );
503 /* memory allocation */
504 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nbinvars) );
505 SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nbinvars) );
506 nconsvars = 0;
507
508 /* set initial left and right hand sides of local branching constraint */
509 lhs = 0.0;
510 rhs = neighborhoodsize;
511
512 /* create the distance (to incumbent) function of the binary variables */
513 for( i = 0; i < nbinvars; i++ )
514 {
515 SCIP_Real solval;
516
517 solval = SCIPgetSolVal(scip, bestsol, vars[i]);
518 assert( SCIPisFeasIntegral(scip, solval) );
519
520 /* is variable i part of the binary support of closest sol? */
521 if( SCIPisFeasEQ(scip,solval,1.0) )
522 {
523 consvals[nconsvars] = -1.0;
524 rhs -= 1.0;
525 lhs -= 1.0;
526 }
527 else
528 consvals[nconsvars] = 1.0;
529 consvars[nconsvars] = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, vars[i]);
530 if( consvars[nconsvars] == NULL )
531 continue;
532 SCIP_CALL( SCIPchgVarObj(probingscip, consvars[nconsvars], consvals[nconsvars]) );
533 assert( SCIPvarGetType(consvars[nconsvars]) == SCIP_VARTYPE_BINARY && !SCIPvarIsImpliedIntegral(consvars[nconsvars]) );
534 ++nconsvars;
535 }
536
537 /* creates localbranching constraint and adds it to subscip */
538 SCIP_CALL( SCIPcreateConsLinear(probingscip, &cons, consname, nconsvars, consvars, consvals,
539 lhs, rhs, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) );
540 SCIP_CALL( SCIPaddCons(probingscip, cons) );
541 SCIP_CALL( SCIPreleaseCons(probingscip, &cons) );
542
543 /* free local memory */
544 SCIPfreeBufferArray(scip, &consvals);
545 SCIPfreeBufferArray(scip, &consvars);
546
547 return SCIP_OKAY;
548}
549
550/** creates new solutions for the original problem by copying the solutions of the subproblem */
551static
553 SCIP* scip, /**< original SCIP data structure */
554 SCIP* subscip, /**< SCIP structure of the subproblem */
555 SCIP_HASHMAP* varmapfw, /**< mapping of SCIP variables to sub-SCIP variables */
556 SCIP_HEUR* heur, /**< heuristic structure */
557 SCIP_Bool* success /**< used to store whether new solution was found or not */
558 )
559{
560 SCIP_VAR** vars; /* the original problem's variables */
561 int nvars;
562 SCIP_VAR** subvars;
563 int i;
564
565 assert(scip != NULL);
566 assert(subscip != NULL);
567
568 /* get variables' data */
570
571 /* for copying a solution we need an explicit mapping */
573 for( i = 0; i < nvars; i++ )
574 subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, vars[i]);
575
576 SCIP_CALL( SCIPtranslateSubSols(scip, subscip, heur, subvars, success, NULL) );
577
578 SCIPfreeBufferArray(scip, &subvars);
579
580 return SCIP_OKAY;
581}
582
583/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
584static
585SCIP_DECL_HEURCOPY(heurCopyFeaspump)
586{
587 assert(scip != NULL);
588 assert(heur != NULL);
589
591
592 /* call inclusion method of primal heuristic */
594
595 return SCIP_OKAY;
596}
597
598/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
599static
600SCIP_DECL_HEURFREE(heurFreeFeaspump)
601{
603
604 assert(heur != NULL);
605 assert(scip != NULL);
606
608
609 /* free heuristic data */
611 assert(heurdata != NULL);
613 SCIPheurSetData(heur, NULL);
614
615 return SCIP_OKAY;
616}
617
618
619/** initialization method of primal heuristic (called after problem was transformed) */
620static
621SCIP_DECL_HEURINIT(heurInitFeaspump)
622{
624
625 assert(heur != NULL);
626
628
629 /* get heuristic data */
631 assert(heurdata != NULL);
632
633 /* create working solution */
634 SCIP_CALL( SCIPcreateSol(scip, &heurdata->sol, heur) );
635 SCIP_CALL( SCIPcreateSol(scip, &heurdata->roundedsol, heur) );
636
637 /* initialize data */
638 heurdata->nlpiterations = 0;
639 heurdata->nsuccess = 0;
640
641 /* create random number generator */
644
645 return SCIP_OKAY;
646}
647
648/** deinitialization method of primal heuristic (called before transformed problem is freed) */
649static
650SCIP_DECL_HEUREXIT(heurExitFeaspump)
651{
653
654 assert(heur != NULL);
655
657
658 /* get heuristic data */
660 assert(heurdata != NULL);
661
662 /* free working solution */
664 SCIP_CALL( SCIPfreeSol(scip, &heurdata->roundedsol) );
665
666 /* free random number generator */
667 SCIPfreeRandom(scip, &heurdata->randnumgen);
668
669 return SCIP_OKAY;
670}
671
672
673/** solving process initialization method of primal heuristic (called when branch and bound process is about to begin) */
674static
675SCIP_DECL_HEURINITSOL(heurInitsolFeaspump)
676{
678
680 assert(heurdata != NULL);
681
682 /* if the heuristic is called at the root node, we may want to be called directly after the initial root LP solve */
683 if( heurdata->beforecuts && SCIPheurGetFreqofs(heur) == 0 )
685
686 return SCIP_OKAY;
687}
688
689
690/** solving process deinitialization method of primal heuristic (called before branch and bound process data is freed) */
691static
692SCIP_DECL_HEUREXITSOL(heurExitsolFeaspump)
693{
694 /* reset the timing mask to its default value */
696
697 return SCIP_OKAY;
698}
699
700/** calculates an adjusted maximal number of LP iterations */
701static
703 SCIP_Longint maxnlpiterations, /**< regular maximal number of LP iterations */
704 SCIP_Longint nsolsfound, /**< total number of solutions found so far by SCIP */
705 int nstallloops /**< current number of stalling rounds */
706 )
707{
708 if( nstallloops <= 1 )
709 {
710 if( nsolsfound == 0 )
711 return 4*maxnlpiterations;
712 else
713 return 2*maxnlpiterations;
714 }
715 else
716 return maxnlpiterations;
717}
718
719/** execution method of primal heuristic */
720static
721SCIP_DECL_HEUREXEC(heurExecFeaspump)
722{
724 SCIP_SOL* tmpsol; /* only used for swapping */
725 SCIP_SOL** lastroundedsols;/* solutions of the last pumping rounds (depending on heurdata->cyclelength) */
726 SCIP_SOL* closestsol; /* rounded solution closest to the LP relaxation: used for stage3 */
727 SCIP_Real* lastalphas; /* alpha values associated to solutions in lastroundedsols */
728
729 SCIP* probingscip; /* copied SCIP structure, used for round-and-propagate loop of feasibility pump 2.0 */
730 SCIP_HASHMAP* varmapfw; /* mapping of SCIP variables to sub-SCIP variables */
731
732 SCIP_VAR** vars;
734 SCIP_VAR** tmppseudocands;
735 SCIP_VAR** mostfracvars; /* the 30 most fractional variables, needed to avoid 1-cycles */
736 SCIP_VAR* var;
737
738 SCIP_Real* mostfracvals; /* the values of the variables above */
739 SCIP_Real oldsolval; /* one value of the last solution */
740 SCIP_Real solval; /* one value of the actual solution */
741 SCIP_Real frac; /* the fractional part of the value above */
742 SCIP_Real objfactor; /* factor by which the regard of the objective is decreased in each round, in [0,0.99] */
743 SCIP_Real alpha; /* factor how the original objective is regarded, used for convex combination of two functions */
744 SCIP_Real objnorm; /* Euclidean norm of the objective function, used for scaling */
745 SCIP_Real scalingfactor; /* factor to scale the original objective function with */
746 SCIP_Real mindistance; /* distance of the closest rounded solution from the LP relaxation: used for stage3 */
747
748 SCIP_Longint nlpiterations; /* number of LP iterations done during one pumping round */
749 SCIP_Longint maxnlpiterations; /* maximum number of LP iterations for this heuristic */
750 SCIP_Longint nsolsfound; /* number of solutions found by this heuristic */
751 SCIP_Longint ncalls; /* number of calls of this heuristic */
752 SCIP_Longint nbestsolsfound; /* current total number of best solution updates in SCIP */
753
754 SCIP_LPSOLSTAT lpsolstat; /* status of the LP solution */
755
756 int nvars; /* number of variables */
757 int nenfovars; /* number of enforced integral variables */
758 int nfracs; /* number of fractional variables updated after each pumping round*/
759 int nflipcands; /* how many flipcands (most frac. var.) have been found */
760 int npseudocands;
761 int maxnflipcands; /* maximal number of candidates to flip in the current pumping round */
762 int nloops; /* how many pumping rounds have been made */
763 int maxflips; /* maximum number of flips, if a 1-cycle is found (depending on heurdata->minflips) */
764 int maxloops; /* maximum number of pumping rounds */
765 int nstallloops; /* number of loops without reducing the current best number of factional variables */
766 int maxstallloops; /* maximal number of allowed stalling loops */
767 int bestnfracs; /* best number of fractional variables */
768 int i;
769 int j;
770
771 SCIP_Bool success;
773 SCIP_Bool* cycles; /* are there short cycles */
774
775 SCIP_RETCODE retcode;
776
777 assert(heur != NULL);
778 assert(scip != NULL);
779 assert(result != NULL);
781
783
785
786 /* do not call heuristic of node was already detected to be infeasible */
787 if( nodeinfeasible )
788 return SCIP_OKAY;
789
790 /* only call heuristic, if an optimal LP solution is at hand */
792 return SCIP_OKAY;
793
794 /* only call heuristic, if the LP objective value is smaller than the cutoff bound */
796 return SCIP_OKAY;
797
798 /* only call heuristic, if the LP solution is basic (which allows fast resolve in diving) */
799 if( !SCIPisLPSolBasic(scip) )
800 return SCIP_OKAY;
801
803
804 /* don't dive two times at the same node */
806 return SCIP_OKAY;
807
808 /* only call feaspump once at the root */
809 if( SCIPgetDepth(scip) == 0 && SCIPheurGetNCalls(heur) > 0 )
810 return SCIP_OKAY;
811
812 /* reset the timing mask to its default value (at the root node it could be different) */
814
815 /* only call the heuristic before cutting planes if we do not have an incumbent and no pricer exists */
816 if( heurtiming == SCIP_HEURTIMING_DURINGLPLOOP && SCIPgetNSolsFound(scip) > 0 && SCIPgetNPricers(scip) == 0 )
817 return SCIP_OKAY;
818
819 /* get heuristic's data */
821 assert(heurdata != NULL);
822
823 /* only apply heuristic, if only a few solutions have been found and no pricer exists */
824 if( heurdata->maxsols >= 0 && SCIPgetNSolsFound(scip) > heurdata->maxsols && SCIPgetNPricers(scip) == 0 )
825 return SCIP_OKAY;
826
827 /* get all variables of LP and number of fractional variables in LP solution that should be integral */
831 assert(nenfovars >= 0);
832 nfracs = SCIPgetNLPBranchCands(scip);
833 assert(0 <= nfracs && nfracs <= nenfovars);
834 if( nfracs == 0 )
835 return SCIP_OKAY;
836
837 /* calculate the maximal number of LP iterations until heuristic is aborted */
840 nsolsfound = 10*SCIPheurGetNBestSolsFound(heur) + heurdata->nsuccess;
841 maxnlpiterations = (SCIP_Longint)(((nsolsfound+1.0)/(ncalls+1.0)) * heurdata->maxlpiterquot * nlpiterations);
842 maxnlpiterations += heurdata->maxlpiterofs;
843
844 /* don't try to dive, if we took too many LP iterations during diving */
845 if( heurdata->nlpiterations >= maxnlpiterations )
846 return SCIP_OKAY;
847
848 /* at the first root call, allow more iterations if there is no feasible solution yet */
849 if( SCIPheurGetNCalls(heur) == 0 && SCIPgetNSolsFound(scip) == 0 && SCIPgetDepth(scip) == 0 )
851
852 /* allow at least a certain number of LP iterations in this dive */
854
855 /* calculate maximal number of flips and loops */
856 maxflips = 3*heurdata->minflips;
857 maxloops = (heurdata->maxloops == -1 ? INT_MAX : heurdata->maxloops);
858 maxstallloops = (heurdata->maxstallloops == -1 ? INT_MAX : heurdata->maxstallloops);
859
860 SCIPdebugMsg(scip, "executing feasibility pump heuristic, nlpiters=%" SCIP_LONGINT_FORMAT ", maxnlpit:%" SCIP_LONGINT_FORMAT ", maxflips:%d \n",
862
864
865 probingscip = NULL;
866 varmapfw = NULL;
867
868 if( heurdata->usefp20 )
869 {
871
872 /* ignore value of valid */
873 SCIP_CALL( setupProbingSCIP(scip, &probingscip, &varmapfw, heurdata->copycuts, &valid) );
874
875 if( probingscip != NULL )
876 {
877 SCIP_CALL( setupSCIPparamsFP2(scip, probingscip) );
878
879 retcode = SCIPsolve(probingscip);
880
881 /* errors in solving the subproblem should not kill the overall solving process;
882 * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop. */
883 if( retcode != SCIP_OKAY )
884 {
885#ifndef NDEBUG
886 SCIP_CALL( retcode );
887#endif
888 SCIPwarningMessage(scip, "Error while solving subproblem in feaspump heuristic; sub-SCIP terminated with code <%d>\n", retcode);
889
890 /* free hash map and copied SCIP */
891 SCIPhashmapFree(&varmapfw);
892 SCIP_CALL( SCIPfree(&probingscip) );
893 return SCIP_OKAY;
894 }
895
896 if( SCIPgetStage(probingscip) != SCIP_STAGE_SOLVING)
897 {
898 SCIP_STATUS probingstatus = SCIPgetStatus(probingscip);
899
900 if( probingstatus == SCIP_STATUS_OPTIMAL )
901 {
902 assert( SCIPgetNSols(probingscip) > 0 );
903 SCIP_CALL( createNewSols(scip, probingscip, varmapfw, heur, &success) );
904 if( success )
906 }
907
908 /* free hash map and copied SCIP */
909 SCIPhashmapFree(&varmapfw);
910 SCIP_CALL( SCIPfree(&probingscip) );
911 return SCIP_OKAY;
912 }
913 SCIP_CALL( SCIPsetLongintParam(probingscip, "limits/nodes", 2LL) );
914
915 /* set SCIP into probing mode and create root node of the probing tree */
916 SCIP_CALL( SCIPstartProbing(probingscip) );
917
918 /* this should always be fulfilled */
919 assert(SCIP_MAXTREEDEPTH > SCIPgetDepth(probingscip));
920
921 SCIP_CALL( SCIPnewProbingNode(probingscip) );
922
923 SCIPdebugMsg(scip, "successfully copied SCIP instance -> feasibility pump 2.0 can be used.\n");
924 }
925 else
926 {
927 assert(varmapfw == NULL);
928
929 SCIPdebugMsg(scip, "SCIP reached the depth limit -> skip heuristic\n");
930 return SCIP_OKAY;
931 }
932 } /*lint !e438*/
933
934 /* memory allocation */
935 SCIP_CALL( SCIPallocBufferArray(scip, &mostfracvars, maxflips) );
936 SCIP_CALL( SCIPallocBufferArray(scip, &mostfracvals, maxflips) );
937 SCIP_CALL( SCIPallocBufferArray(scip, &lastroundedsols, heurdata->cyclelength) );
938 SCIP_CALL( SCIPallocBufferArray(scip, &lastalphas, heurdata->cyclelength) );
939 SCIP_CALL( SCIPallocBufferArray(scip, &cycles, heurdata->cyclelength) );
940
941 for( j = 0; j < heurdata->cyclelength; j++ )
942 {
943 SCIP_CALL( SCIPcreateSol(scip, &lastroundedsols[j], heur) );
944 }
945
946 closestsol = NULL;
947 if( heurdata->stage3 )
948 {
949 SCIP_CALL( SCIPcreateSol(scip, &closestsol, heur) );
950 }
951
952 /* start diving */
954
955 /* lp was solved optimal */
956 lperror = FALSE;
958
959 /* pumping rounds */
961 if( heurdata->objfactor == 1.0 )
962 objfactor = MIN(1.0 - 0.1 / (SCIP_Real)(1 + nsolsfound), 0.999);
963 else
964 objfactor = heurdata->objfactor;
965
966 /* scale distance function and original objective to the same norm */
967 objnorm = SCIPgetObjNorm(scip);
968 objnorm = MAX(objnorm, 1.0);
969 scalingfactor = sqrt((SCIP_Real)nenfovars) / objnorm;
970
971 /* data initialization */
972 alpha = heurdata->alpha;
973 nloops = 0;
974 nstallloops = 0;
975 nbestsolsfound = SCIPgetNBestSolsFound(scip);
976 bestnfracs = INT_MAX;
977 mindistance = SCIPinfinity(scip);
978
979 /* pumping loop */
980 while( nfracs > 0
981 && heurdata->nlpiterations < adjustedMaxNLPIterations(maxnlpiterations, nsolsfound, nstallloops)
982 && nloops < maxloops && nstallloops < maxstallloops
983 && !SCIPisStopped(scip) )
984 {
985 int minimum;
986 SCIP_Real* pseudocandsfrac;
987 SCIP_Longint nlpiterationsleft;
988 int iterlimit;
989
990 /* decrease convex combination scalar */
991 nloops++;
992 alpha *= objfactor;
993
994 SCIPdebugMsg(scip, "feasibility pump loop %d: %d fractional variables (alpha: %.4f, stall: %d/%d)\n",
995 nloops, nfracs, alpha, nstallloops, maxstallloops);
996
997 success = FALSE;
998
999 SCIP_CALL( SCIPlinkLPSol(scip, heurdata->roundedsol) );
1000
1001 /* randomly choose maximum number of variables to flip in current pumping round in case of a 1-cycle */
1002 maxnflipcands = SCIPrandomGetInt(heurdata->randnumgen, MIN(nfracs/2+1, heurdata->minflips), MIN(nfracs, maxflips));
1003 nflipcands = 0;
1004
1005 /* get all unfixed integer variables */
1006 SCIP_CALL( SCIPgetPseudoBranchCands(scip, &tmppseudocands, &npseudocands, NULL) );
1007 SCIP_CALL( SCIPduplicateBufferArray(scip, &pseudocands, tmppseudocands, npseudocands) );
1008
1009 /* get array of all fractional variables and sort it w.r.t. their fractionalities */
1010 if( heurdata->usefp20 )
1011 {
1012 SCIP_CALL( SCIPallocBufferArray(scip, &pseudocandsfrac, npseudocands) );
1013
1014 for( i = 0; i < npseudocands; i++ )
1015 {
1017 pseudocandsfrac[i] = MIN(frac, 1.0-frac); /* always a number between 0 and 0.5 */
1019 pseudocandsfrac[i] -= 10.0; /* binaries always come first */
1020 }
1021 SCIPsortRealPtr(pseudocandsfrac, (void**)pseudocands, npseudocands);
1022 SCIPfreeBufferArray(scip, &pseudocandsfrac);
1023
1024 SCIPdebugMsg(scip, "iteratively fix and propagate variables\n");
1025 }
1026
1027 for( i = 0; i < npseudocands; i++ )
1028 {
1029 SCIP_VAR* probingvar;
1030 SCIP_Bool infeasible;
1031 SCIP_Longint ndomreds;
1032
1033 var = pseudocands[i];
1034
1035 /* round the LP solution */
1036 solval = SCIPvarGetLPSol(var);
1037 frac = SCIPfeasFrac(scip, solval);
1038
1039 /* round randomly if the value is close to 0.5 */
1040 if( SCIPisEQ(scip, frac, 0.5) )
1041 {
1042 if( SCIPrandomGetReal(heurdata->randnumgen, 0.0, 1.0) <= 0.5 )
1043 solval = SCIPfloor(scip, solval);
1044 else
1045 solval = SCIPceil(scip, solval);
1046 }
1047 else
1048 solval = SCIPfloor(scip, solval + 0.5);
1049
1050 /* ensure, that the fixing value is inside the local domains */
1051 if( heurdata->usefp20 )
1052 {
1053 SCIP_Real lbprobing;
1054 SCIP_Real ubprobing;
1055
1056 probingvar = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, var);
1057 /* skip if variable does not exist in probingscip */
1058 if( probingvar != NULL )
1059 {
1060 lbprobing = SCIPvarGetLbLocal(probingvar);
1061 ubprobing = SCIPvarGetUbLocal(probingvar);
1062
1063 solval = MAX(solval, lbprobing);
1064 solval = MIN(solval, ubprobing);
1065
1066 /* fix the variable and propagate the domain change */
1067 if( !SCIPisFeasEQ(probingscip, lbprobing, ubprobing) && SCIPvarIsActive(SCIPvarGetTransVar(probingvar)) )
1068 {
1069 assert(SCIPisFeasLE(probingscip, lbprobing, ubprobing));
1070 SCIPdebugMsg(scip, "try to fix variable <%s> (domain [%f,%f] to %f\n", SCIPvarGetName(probingvar), lbprobing, ubprobing,
1071 solval);
1072 SCIP_CALL( SCIPfixVarProbing(probingscip, probingvar, solval) );
1073 SCIP_CALL( SCIPpropagateProbing(probingscip, -1, &infeasible, &ndomreds) );
1074 SCIPdebugMsg(scip, " -> reduced %" SCIP_LONGINT_FORMAT " domains\n", ndomreds);
1075
1076 if( infeasible )
1077 {
1078 SCIPdebugMsg(scip, " -> infeasible!\n");
1079 SCIP_CALL( SCIPbacktrackProbing(probingscip, 0) );
1080 }
1081 }
1082 else
1083 {
1084 SCIPdebugMsg(scip, "variable <%s> is already fixed to %f\n", SCIPvarGetName(probingvar), solval);
1085 }
1086 }
1087 }
1088
1089 SCIP_CALL( updateVariableRounding(scip, heurdata, var, solval, alpha, scalingfactor) );
1090
1091 /* check whether the variable is one of the most fractionals and label if so */
1093 insertFlipCand(mostfracvars, mostfracvals, &nflipcands, maxnflipcands, var, frac);
1094 }
1095
1096 if( heurdata->usefp20 )
1097 {
1098 SCIP_CALL( SCIPbacktrackProbing(probingscip, 0) );
1099 }
1100
1101 /* change objective coefficients for continuous variables */
1102 for( i = nenfovars; i < nvars; i++ )
1103 {
1105 }
1106
1108
1109 /* initialize cycle check */
1110 minimum = MIN(heurdata->cyclelength, nloops-1);
1111 for( j = 0; j < heurdata->cyclelength; j++ )
1112 cycles[j] = (nloops > j+1) && (REALABS(lastalphas[j] - alpha) < heurdata->alphadiff);
1113
1114 /* check for j-cycles */
1115 for( i = 0; i < nenfovars; i++ )
1116 {
1117 solval = SCIPgetSolVal(scip, heurdata->roundedsol, vars[i]);
1118
1119 /* cycles exist, iff all solution values are equal */
1120 for( j = 0; j < minimum; j++ )
1121 {
1122 oldsolval = SCIPgetSolVal(scip, lastroundedsols[j], vars[i]);
1123 cycles[j] = cycles[j] && SCIPisFeasEQ(scip, solval, oldsolval);
1124 }
1125 }
1126
1127 /* force to flip variables at random after a couple of pumping rounds,
1128 * or if a new best solution in the current region has been found
1129 */
1130 assert(heurdata->perturbfreq > 0);
1131 if( nloops % heurdata->perturbfreq == 0 || (heurdata->pertsolfound && SCIPgetNBestSolsFound(scip) > nbestsolsfound) )
1132 {
1133 SCIPdebugMsg(scip, " -> random perturbation\n");
1134 SCIP_CALL( handleCycle(scip, heurdata, vars, nenfovars, alpha, scalingfactor) );
1135 nbestsolsfound = SCIPgetNBestSolsFound(scip);
1136 }
1137 else
1138 {
1139 minimum = MIN(heurdata->cyclelength, nloops-1);
1140
1141 for( j = 0; j < minimum; j++ )
1142 {
1143 /* if we got the same rounded solution as in some step before, we have to flip some variables */
1144 if( cycles[j] )
1145 {
1146 /* 1-cycles have a special flipping rule (flip most fractional variables) */
1147 if( j == 0 )
1148 {
1149 SCIPdebugMsg(scip, " -> avoiding 1-cycle: flipping %d candidates\n", nflipcands);
1150 SCIP_CALL( handle1Cycle(scip, heurdata, mostfracvars, nflipcands, alpha, scalingfactor) );
1151 }
1152 else
1153 {
1154 SCIPdebugMsg(scip, " -> avoiding %d-cycle by random flip\n", j+1);
1155 SCIP_CALL( handleCycle(scip, heurdata, vars, nenfovars, alpha, scalingfactor) );
1156 }
1157 break;
1158 }
1159 }
1160 }
1161
1162 /* the LP with the new (distance) objective is solved */
1164 nlpiterationsleft = adjustedMaxNLPIterations(maxnlpiterations, nsolsfound, nstallloops) - heurdata->nlpiterations;
1165 iterlimit = MAX((int)nlpiterationsleft, MINLPITER);
1166 SCIPdebugMsg(scip, " -> solve LP with iteration limit %d\n", iterlimit);
1167
1168 if( heurdata->stage3 )
1169 {
1170 SCIP_CALL( SCIPunlinkSol(scip, heurdata->roundedsol) );
1171 }
1172
1173 retcode = SCIPsolveDiveLP(scip, iterlimit, &lperror, NULL);
1175
1176 /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
1177 * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
1178 */
1179 if( retcode != SCIP_OKAY )
1180 {
1181#ifndef NDEBUG
1183 {
1184 SCIP_CALL( retcode );
1185 }
1186#endif
1187 SCIPwarningMessage(scip, "Error while solving LP in Feaspump heuristic; LP solve terminated with code <%d>\n", retcode);
1188 SCIPwarningMessage(scip, "This does not affect the remaining solution procedure --> continue\n");
1189 }
1190
1191 /* update iteration count */
1192 heurdata->nlpiterations += SCIPgetNLPIterations(scip) - nlpiterations;
1193 SCIPdebugMsg(scip, " -> number of iterations: %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", lperror=%u, lpsolstat=%d\n",
1195
1196 /* check whether LP was solved optimal */
1198 break;
1199
1200 if( heurdata->stage3 )
1201 {
1202 SCIP_Real distance; /* distance of the current rounded solution from the LP solution */
1203
1204 assert(closestsol != NULL);
1205
1206 /* calculate distance */
1207 distance = 0.0;
1208 for( i = 0; i < nenfovars; i++ )
1209 {
1210 SCIP_Real roundedval;
1211 SCIP_Real lpval;
1212
1213 roundedval = SCIPgetSolVal(scip, heurdata->roundedsol, vars[i]);
1214 lpval = SCIPvarGetLPSol(vars[i]);
1215 distance += REALABS(roundedval - lpval);
1216 }
1217
1218 /* copy solution and update minimum distance */
1219 if( SCIPisLT(scip, distance, mindistance) )
1220 {
1221 for( i = 0; i < nenfovars; i++ )
1222 {
1224 SCIP_CALL( SCIPsetSolVal(scip, closestsol, vars[i], SCIPgetSolVal(scip, heurdata->roundedsol, vars[i])) );
1225 }
1226 mindistance = distance;
1227 }
1228 }
1229
1230 /* swap the last solutions */
1231 SCIP_CALL( SCIPunlinkSol(scip, heurdata->roundedsol) );
1232 tmpsol = lastroundedsols[heurdata->cyclelength-1];
1233 for( j = heurdata->cyclelength-1; j > 0; j-- )
1234 {
1235 lastroundedsols[j] = lastroundedsols[j-1];
1236 lastalphas[j] = lastalphas[j-1];
1237 }
1238 lastroundedsols[0] = heurdata->roundedsol;
1239 lastalphas[0] = alpha;
1240 heurdata->roundedsol = tmpsol;
1241
1242 /* check for improvement in number of fractionals */
1243 nfracs = SCIPgetNLPBranchCands(scip);
1244 if( nfracs < bestnfracs )
1245 {
1246 bestnfracs = nfracs;
1247 nstallloops = 0;
1248 }
1249 else
1250 nstallloops++;
1251
1252 SCIPdebugMsg(scip, " -> loop finished: %d fractional variables (stall: %d/%d, iterations: %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ")\n",
1253 nfracs, nstallloops, maxstallloops, heurdata->nlpiterations, adjustedMaxNLPIterations(maxnlpiterations, nsolsfound, nstallloops));
1254 }
1255
1256 /* try final solution, if no more fractional variables are left */
1257 if( nfracs == 0 && !lperror && lpsolstat == SCIP_LPSOLSTAT_OPTIMAL )
1258 {
1259 success = FALSE;
1260
1262
1263 /* in exact mode we have to end diving prior to trying the solution */
1264 if( SCIPisExact(scip) )
1265 {
1268 }
1269
1270 SCIPdebugMsg(scip, "feasibility pump found solution (%d fractional variables)\n", nfracs);
1271 SCIP_CALL( SCIPtrySol(scip, heurdata->sol, FALSE, FALSE, FALSE, FALSE, FALSE, &success) );
1272 if( success )
1274 }
1275
1276 /* end diving */
1277 if( SCIPinDive(scip) )
1278 {
1280 }
1281
1282 /* end probing in order to be able to apply stage 3 */
1283 if( heurdata->usefp20 )
1284 {
1285 SCIP_CALL( SCIPendProbing(probingscip) );
1286 }
1287
1288 /* only do stage 3 if we have not found a solution yet */
1289 /* only do stage 3 if the distance of the closest infeasible solution to the polyhedron is below a certain threshold */
1290 if( heurdata->stage3 && (*result != SCIP_FOUNDSOL) && SCIPisLE(scip, mindistance, (SCIP_Real) heurdata->neighborhoodsize) )
1291 {
1292 SCIP_Bool cancopy;
1293 assert(closestsol != NULL);
1294 assert(!SCIPisInfinity(scip, mindistance) || nloops == 0);
1295
1296 /* if we do not use feasibility pump 2.0, we have not created a copied SCIP instance yet */
1297 if( heurdata->usefp20 )
1298 {
1299 assert(probingscip != NULL);
1300 SCIP_CALL( SCIPfreeTransform(probingscip) );
1301 }
1302 else
1303 {
1304 assert(probingscip == NULL);
1305 SCIP_CALL( setupProbingSCIP(scip, &probingscip, &varmapfw, heurdata->copycuts, &success) );
1306 }
1307
1308 /* check whether there is enough time and memory left */
1309 SCIP_CALL( SCIPcheckCopyLimits(scip, &cancopy) );
1310
1311 if( cancopy )
1312 {
1313 SCIP_CALL( setupSCIPparamsStage3(scip, probingscip) );
1314
1315 /* the neighborhood size is double the distance plus another ten percent */
1316 mindistance = SCIPceil(scip, 2.2*mindistance);
1317
1318 SCIP_CALL( addLocalBranchingConstraint(scip, probingscip, varmapfw, closestsol, mindistance) );
1319
1320 /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
1321 * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
1322 */
1323 SCIP_CALL_ABORT( SCIPsolve(probingscip) );
1324
1325 /* check, whether a solution was found */
1326 if( SCIPgetNSols(probingscip) > 0 )
1327 {
1328 success = FALSE;
1329 SCIP_CALL( createNewSols(scip, probingscip, varmapfw, heur, &success) );
1330 if( success )
1332 }
1333 }
1334 }
1335
1336 if( *result == SCIP_FOUNDSOL )
1337 heurdata->nsuccess++;
1338
1339 /* free hash map and copied SCIP */
1340 if( varmapfw != NULL )
1341 SCIPhashmapFree(&varmapfw);
1342
1343 if( probingscip != NULL )
1344 {
1345 SCIP_CALL( SCIPfree(&probingscip) );
1346 }
1347
1348 if( heurdata->stage3 )
1349 {
1350 SCIP_CALL( SCIPfreeSol(scip, &closestsol) );
1351 }
1352
1353 /* free memory */
1354 for( j = 0; j < heurdata->cyclelength; j++ )
1355 {
1356 SCIP_CALL( SCIPfreeSol(scip, &lastroundedsols[j]) );
1357 }
1358
1359 SCIPfreeBufferArray(scip, &cycles);
1360 SCIPfreeBufferArray(scip, &lastalphas);
1361 SCIPfreeBufferArray(scip, &lastroundedsols);
1362 SCIPfreeBufferArray(scip, &mostfracvals);
1363 SCIPfreeBufferArray(scip, &mostfracvars);
1364
1365 SCIPdebugMsg(scip, "feasibility pump finished [%d iterations done].\n", nloops);
1366
1367#ifdef SCIP_STATISTIC
1368 if( nfracs == 0 )
1369 {
1370 double objval;
1371 double primalBound;
1372
1374 primalBound = SCIPgetPrimalbound(scip);
1375 SCIPstatisticMessage("feasibility pump found: 1, objval: %f, iterations: %d, primal bound: %f\n", objval, nloops, primalBound);
1376 }
1377 else
1378 {
1379 double primalBound;
1380
1381 primalBound = SCIPgetPrimalbound(scip);
1382 SCIPstatisticMessage("feasibility pump found: 0, objval: +inf, iterations: %d, primal bound: %f\n", nloops, primalBound);
1383 }
1384
1385#endif /* SCIP_STATISTIC */
1386
1387 return SCIP_OKAY;
1388}
1389
1390
1391/*
1392 * primal heuristic specific interface methods
1393 */
1394
1395/** creates the feaspump primal heuristic and includes it in SCIP */
1397 SCIP* scip /**< SCIP data structure */
1398 )
1399{
1401 SCIP_HEUR* heur;
1402
1403 /* create Feaspump primal heuristic data */
1405
1406 /* include primal heuristic */
1409 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecFeaspump, heurdata) );
1410
1411 assert(heur != NULL);
1412
1413 /* primal heuristic is safe to use in exact solving mode */
1414 SCIPheurMarkExact(heur);
1415
1416 /* set non-NULL pointers to callback methods */
1417 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyFeaspump) );
1418 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeFeaspump) );
1419 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitFeaspump) );
1420 SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitFeaspump) );
1421 SCIP_CALL( SCIPsetHeurInitsol(scip, heur, heurInitsolFeaspump) );
1422 SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolFeaspump) );
1423
1424 /* add feaspump primal heuristic parameters */
1426 "heuristics/" HEUR_NAME "/maxlpiterquot",
1427 "maximal fraction of diving LP iterations compared to node LP iterations",
1428 &heurdata->maxlpiterquot, FALSE, DEFAULT_MAXLPITERQUOT, 0.0, SCIP_REAL_MAX, NULL, NULL) );
1430 "heuristics/" HEUR_NAME "/objfactor",
1431 "factor by which the regard of the objective is decreased in each round, 1.0 for dynamic",
1432 &heurdata->objfactor, FALSE, DEFAULT_OBJFACTOR, 0.0, 1.0, NULL, NULL) );
1434 "heuristics/" HEUR_NAME "/alpha",
1435 "initial weight of the objective function in the convex combination",
1436 &heurdata->alpha, FALSE, DEFAULT_ALPHA, 0.0, 1.0, NULL, NULL) );
1438 "heuristics/" HEUR_NAME "/alphadiff",
1439 "threshold difference for the convex parameter to perform perturbation",
1440 &heurdata->alphadiff, FALSE, DEFAULT_ALPHADIFF, 0.0, 1.0, NULL, NULL) );
1441
1443 "heuristics/" HEUR_NAME "/maxlpiterofs",
1444 "additional number of allowed LP iterations",
1445 &heurdata->maxlpiterofs, FALSE, DEFAULT_MAXLPITEROFS, 0, INT_MAX, NULL, NULL) );
1447 "heuristics/" HEUR_NAME "/maxsols",
1448 "total number of feasible solutions found up to which heuristic is called (-1: no limit)",
1449 &heurdata->maxsols, TRUE, DEFAULT_MAXSOLS, -1, INT_MAX, NULL, NULL) );
1451 "heuristics/" HEUR_NAME "/maxloops",
1452 "maximal number of pumping loops (-1: no limit)",
1453 &heurdata->maxloops, TRUE, DEFAULT_MAXLOOPS, -1, INT_MAX, NULL, NULL) );
1455 "heuristics/" HEUR_NAME "/maxstallloops",
1456 "maximal number of pumping rounds without fractionality improvement (-1: no limit)",
1457 &heurdata->maxstallloops, TRUE, DEFAULT_MAXSTALLLOOPS, -1, INT_MAX, NULL, NULL) );
1459 "heuristics/" HEUR_NAME "/minflips",
1460 "minimum number of random variables to flip, if a 1-cycle is encountered",
1461 &heurdata->minflips, TRUE, DEFAULT_MINFLIPS, 1, INT_MAX, NULL, NULL) );
1463 "heuristics/" HEUR_NAME "/cyclelength",
1464 "maximum length of cycles to be checked explicitly in each round",
1465 &heurdata->cyclelength, TRUE, DEFAULT_CYCLELENGTH, 1, 100, NULL, NULL) );
1467 "heuristics/" HEUR_NAME "/perturbfreq",
1468 "number of iterations until a random perturbation is forced",
1469 &heurdata->perturbfreq, TRUE, DEFAULT_PERTURBFREQ, 1, INT_MAX, NULL, NULL) );
1470 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/neighborhoodsize",
1471 "radius (using Manhattan metric) of the neighborhood to be searched in stage 3",
1472 &heurdata->neighborhoodsize, FALSE, DEFAULT_NEIGHBORHOODSIZE, 1, INT_MAX, NULL, NULL) );
1473
1475 "heuristics/" HEUR_NAME "/beforecuts",
1476 "should the feasibility pump be called at root node before cut separation?",
1477 &heurdata->beforecuts, FALSE, DEFAULT_BEFORECUTS, NULL, NULL) );
1479 "heuristics/" HEUR_NAME "/usefp20",
1480 "should an iterative round-and-propagate scheme be used to find the integral points?",
1481 &heurdata->usefp20, FALSE, DEFAULT_USEFP20, NULL, NULL) );
1483 "heuristics/" HEUR_NAME "/pertsolfound",
1484 "should a random perturbation be performed if a feasible solution was found?",
1485 &heurdata->pertsolfound, FALSE, DEFAULT_PERTSOLFOUND, NULL, NULL) );
1487 "heuristics/" HEUR_NAME "/stage3",
1488 "should we solve a local branching sub-MIP if no solution could be found?",
1489 &heurdata->stage3, FALSE, DEFAULT_STAGE3, NULL, NULL) );
1490 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/copycuts",
1491 "should all active cuts from cutpool be copied to constraints in subproblem?",
1492 &heurdata->copycuts, TRUE, DEFAULT_COPYCUTS, NULL, NULL) );
1493
1494 return SCIP_OKAY;
1495}
Constraint handler for linear constraints in their most general form, .
#define DEFAULT_RANDSEED
#define NULL
Definition def.h:257
#define SCIP_MAXSTRLEN
Definition def.h:278
#define SCIP_Longint
Definition def.h:150
#define SCIP_MAXTREEDEPTH
Definition def.h:306
#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 REALABS(x)
Definition def.h:191
#define SCIP_CALL(x)
Definition def.h:364
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 SCIPcopyConsCompression(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, const char *suffix, SCIP_VAR **fixedvars, SCIP_Real *fixedvals, int nfixedvars, SCIP_Bool global, SCIP_Bool enablepricing, SCIP_Bool threadsafe, SCIP_Bool passmessagehdlr, SCIP_Bool *valid)
Definition scip_copy.c:2962
SCIP_RETCODE SCIPcheckCopyLimits(SCIP *sourcescip, SCIP_Bool *success)
Definition scip_copy.c:3250
SCIP_RETCODE SCIPcopyCuts(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, int *ncutsadded)
Definition scip_copy.c:2114
SCIP_RETCODE SCIPcopyParamSettings(SCIP *sourcescip, SCIP *targetscip)
Definition scip_copy.c:2548
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)
SCIP_STAGE SCIPgetStage(SCIP *scip)
const char * SCIPgetProbName(SCIP *scip)
Definition scip_prob.c:1242
int SCIPgetNContVars(SCIP *scip)
Definition scip_prob.c:2569
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition scip_prob.c:2115
int SCIPgetNVars(SCIP *scip)
Definition scip_prob.c:2246
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition scip_prob.c:3274
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition scip_prob.c:2201
SCIP_Real SCIPgetObjNorm(SCIP *scip)
Definition scip_prob.c:1880
int SCIPgetNContImplVars(SCIP *scip)
Definition scip_prob.c:2522
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_Bool SCIPisParamFixed(SCIP *scip, const char *name)
Definition scip_param.c:219
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 SCIPsetHeuristics(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition scip_param.c:930
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 SCIPunfixParam(SCIP *scip, const char *name)
Definition scip_param.c:385
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 SCIPincludeHeurFeaspump(SCIP *scip)
SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
int SCIPgetNLPBranchCands(SCIP *scip)
SCIP_RETCODE SCIPgetPseudoBranchCands(SCIP *scip, SCIP_VAR ***pseudocands, int *npseudocands, int *npriopseudocands)
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition scip_cons.c:1173
SCIP_Bool SCIPisExact(SCIP *scip)
Definition scip_exact.c:193
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:183
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition heur.c:1368
SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
Definition scip_heur.c:122
SCIP_RETCODE SCIPsetHeurInitsol(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:231
SCIP_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
Definition heur.c:1613
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:167
void SCIPheurSetTimingmask(SCIP_HEUR *heur, SCIP_HEURTIMING timingmask)
Definition heur.c:1507
SCIP_Longint SCIPheurGetNCalls(SCIP_HEUR *heur)
Definition heur.c:1593
int SCIPheurGetFreqofs(SCIP_HEUR *heur)
Definition heur.c:1573
SCIP_RETCODE SCIPsetHeurExitsol(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:247
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
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition heur.c:1378
SCIP_RETCODE SCIPstartDive(SCIP *scip)
Definition scip_lp.c:2206
SCIP_RETCODE SCIPchgVarObjDive(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition scip_lp.c:2343
SCIP_RETCODE SCIPsolveDiveLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition scip_lp.c:2643
SCIP_RETCODE SCIPendDive(SCIP *scip)
Definition scip_lp.c:2255
SCIP_Bool SCIPinDive(SCIP *scip)
Definition scip_lp.c:2740
SCIP_Longint SCIPgetLastDivenode(SCIP *scip)
Definition scip_lp.c:2710
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
SCIP_Bool SCIPisLPSolBasic(SCIP *scip)
Definition scip_lp.c:673
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 SCIPduplicateBufferArray(scip, ptr, source, num)
Definition scip_mem.h:132
#define SCIPfreeBlockMemory(scip, ptr)
Definition scip_mem.h:108
#define SCIPallocBlockMemory(scip, ptr)
Definition scip_mem.h:89
SCIP_NODESEL * SCIPfindNodesel(SCIP *scip, const char *name)
int SCIPgetNPricers(SCIP *scip)
SCIP_RETCODE SCIPpropagateProbing(SCIP *scip, int maxproprounds, SCIP_Bool *cutoff, SCIP_Longint *ndomredsfound)
SCIP_RETCODE SCIPbacktrackProbing(SCIP *scip, int probingdepth)
SCIP_RETCODE SCIPstartProbing(SCIP *scip)
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
SCIP_RETCODE SCIPfixVarProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval)
int SCIPgetNSols(SCIP *scip)
Definition scip_sol.c:2887
SCIP_RETCODE SCIPunlinkSol(SCIP *scip, SCIP_SOL *sol)
Definition scip_sol.c:1504
SCIP_RETCODE SCIPtrySol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition scip_sol.c:4017
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
Definition scip_sol.c:1890
SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
Definition scip_sol.c:1569
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition scip_sol.c:1763
SCIP_RETCODE SCIPfreeTransform(SCIP *scip)
SCIP_RETCODE SCIPsolve(SCIP *scip)
SCIP_Longint SCIPgetNSolsFound(SCIP *scip)
SCIP_Real SCIPgetPrimalbound(SCIP *scip)
SCIP_Longint SCIPgetNNodes(SCIP *scip)
SCIP_Longint SCIPgetNNodeLPIterations(SCIP *scip)
SCIP_Longint SCIPgetNBestSolsFound(SCIP *scip)
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
SCIP_Longint SCIPgetNLPIterations(SCIP *scip)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPfeasFrac(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
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 SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasPositive(SCIP *scip, SCIP_Real val)
int SCIPgetDepth(SCIP *scip)
Definition scip_tree.c:672
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition var.c:23674
SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
Definition var.c:23530
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition var.c:24300
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition var.c:23932
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition var.c:23485
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:23299
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
Definition var.c:24696
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition var.c:24266
SCIP_VAR * SCIPvarGetTransVar(SCIP_VAR *var)
Definition var.c:23704
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition scip_var.c:5372
SCIP_Real SCIPrandomGetReal(SCIP_RANDNUMGEN *randnumgen, SCIP_Real minrandval, SCIP_Real maxrandval)
Definition misc.c:10245
int SCIPrandomGetInt(SCIP_RANDNUMGEN *randnumgen, int minrandval, int maxrandval)
Definition misc.c:10223
void SCIPsortRealPtr(SCIP_Real *realarray, void **ptrarray, int len)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition misc.c:10827
#define HEUR_TIMING
return SCIP_OKAY
#define DEFAULT_MAXLPITERQUOT
#define HEUR_FREQOFS
#define HEUR_DESC
#define HEUR_DISPCHAR
#define HEUR_MAXDEPTH
#define HEUR_PRIORITY
#define DEFAULT_MAXLPITEROFS
SCIPfreeSol(scip, &heurdata->sol))
#define HEUR_NAME
#define HEUR_FREQ
#define HEUR_USESSUBSCIP
SCIPcreateSol(scip, &heurdata->sol, heur))
SCIPfreeRandom(scip, &heurdata->randnumgen)
#define DEFAULT_COPYCUTS
Definition heur_alns.c:147
#define DEFAULT_ALPHA
Definition heur_alns.c:133
#define DEFAULT_NEIGHBORHOODSIZE
Definition heur_dins.c:80
#define DEFAULT_STAGE3
#define DEFAULT_CYCLELENGTH
static SCIP_RETCODE setupProbingSCIP(SCIP *scip, SCIP **probingscip, SCIP_HASHMAP **varmapfw, SCIP_Bool copycuts, SCIP_Bool *success)
#define DEFAULT_MINFLIPS
#define DEFAULT_ALPHADIFF
#define MINLPITER
static SCIP_RETCODE handle1Cycle(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_VAR **mostfracvars, int nflipcands, SCIP_Real alpha, SCIP_Real scalingfactor)
#define DEFAULT_USEFP20
#define DEFAULT_MAXSTALLLOOPS
#define DEFAULT_PERTURBFREQ
#define DEFAULT_PERTSOLFOUND
static void insertFlipCand(SCIP_VAR **mostfracvars, SCIP_Real *mostfracvals, int *nflipcands, int maxnflipcands, SCIP_VAR *var, SCIP_Real frac)
static SCIP_RETCODE setupSCIPparamsFP2(SCIP *scip, SCIP *probingscip)
static SCIP_Longint adjustedMaxNLPIterations(SCIP_Longint maxnlpiterations, SCIP_Longint nsolsfound, int nstallloops)
#define DEFAULT_MAXSOLS
static SCIP_RETCODE setupSCIPparamsStage3(SCIP *scip, SCIP *probingscip)
static SCIP_RETCODE updateVariableRounding(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_VAR *var, SCIP_Real solval, SCIP_Real alpha, SCIP_Real scalingfactor)
static SCIP_RETCODE addLocalBranchingConstraint(SCIP *scip, SCIP *probingscip, SCIP_HASHMAP *varmapfw, SCIP_SOL *bestsol, SCIP_Real neighborhoodsize)
#define DEFAULT_BEFORECUTS
static SCIP_RETCODE handleCycle(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_VAR **vars, int nbinandintvars, SCIP_Real alpha, SCIP_Real scalingfactor)
#define DEFAULT_MAXLOOPS
#define DEFAULT_OBJFACTOR
static SCIP_RETCODE createNewSols(SCIP *scip, SCIP *subscip, SCIP_HASHMAP *varmapfw, SCIP_HEUR *heur, SCIP_Bool *success)
Objective Feasibility Pump 2.0.
SCIP_VAR ** pseudocands
SCIP_Longint nsolsfound
SCIP_Bool lperror
SCIP_Longint ncalls
static SCIP_LPSOLSTAT lpsolstat
heurdata nsuccess
heurdata nlpiterations
SCIPendProbing(scip))
SCIP_Longint maxnlpiterations
SCIP_Real objval
SCIPcreateRandom(scip, &heurdata->randnumgen, DEFAULT_RANDSEED, TRUE))
static SCIP_SOL * sol
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
SCIPlinkLPSol(scip, sol))
SCIP_VAR * var
SCIP_Real frac
int nenfovars
static SCIP_VAR ** vars
SCIP_Real alpha
memory allocation routines
public methods for primal heuristics
public methods for message output
#define SCIPstatisticMessage
public data structures and miscellaneous methods
methods for sorting joint arrays of various types
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 exact solving
general public methods
public methods for primal heuristic plugins and divesets
public methods for the LP relaxation, rows and columns
public methods for memory management
public methods for message handling
public methods for node selector plugins
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for variable pricer plugins
public methods for global and local (sub)problems
public methods for the probing mode
public methods for random numbers
public methods for solutions
public solving methods
public methods for querying solving statistics
public methods for the branch-and-bound tree
public methods for SCIP variables
struct SCIP_Cons SCIP_CONS
Definition type_cons.h:63
#define SCIP_DECL_HEURINITSOL(x)
Definition type_heur.h:132
#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_HEUREXIT(x)
Definition type_heur.h:121
#define SCIP_DECL_HEURFREE(x)
Definition type_heur.h:105
#define SCIP_DECL_HEUREXITSOL(x)
Definition type_heur.h:143
#define SCIP_DECL_HEUREXEC(x)
Definition type_heur.h:163
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition type_lp.h:52
@ SCIP_LPSOLSTAT_OPTIMAL
Definition type_lp.h:44
@ SCIP_LPSOLSTAT_UNBOUNDEDRAY
Definition type_lp.h:46
struct SCIP_HashMap SCIP_HASHMAP
Definition type_misc.h:106
struct SCIP_RandNumGen SCIP_RANDNUMGEN
Definition type_misc.h:127
@ 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
@ SCIP_INVALIDCALL
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
@ SCIP_STAGE_SOLVING
Definition type_set.h:53
struct SCIP_Sol SCIP_SOL
Definition type_sol.h:57
@ SCIP_STATUS_OPTIMAL
Definition type_stat.h:43
enum SCIP_Status SCIP_STATUS
Definition type_stat.h:64
#define SCIP_HEURTIMING_DURINGLPLOOP
Definition type_timing.h:81
struct SCIP_Var SCIP_VAR
Definition type_var.h:166
@ SCIP_VARTYPE_BINARY
Definition type_var.h:64