Scippy

SCIP

Solving Constraint Integer Programs

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-2025 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#include <string.h>
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
356 lb = SCIPvarGetLbLocal(var);
357 ub = SCIPvarGetUbLocal(var);
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;
443 SCIP_Real frac;
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 */
569 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
570
571 /* for copying a solution we need an explicit mapping */
572 SCIP_CALL( SCIPallocBufferArray(scip, &subvars, nvars) );
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 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
590
591 /* call inclusion method of primal heuristic */
593
594 return SCIP_OKAY;
595}
596
597/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
598static
599SCIP_DECL_HEURFREE(heurFreeFeaspump)
600{
601 SCIP_HEURDATA* heurdata;
602
603 assert(heur != NULL);
604 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
605 assert(scip != NULL);
606
607 /* free heuristic data */
608 heurdata = SCIPheurGetData(heur);
609 assert(heurdata != NULL);
610 SCIPfreeBlockMemory(scip, &heurdata);
611 SCIPheurSetData(heur, NULL);
612
613 return SCIP_OKAY;
614}
615
616
617/** initialization method of primal heuristic (called after problem was transformed) */
618static
619SCIP_DECL_HEURINIT(heurInitFeaspump)
620{
621 SCIP_HEURDATA* heurdata;
622
623 assert(heur != NULL);
624 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
625
626 /* get heuristic data */
627 heurdata = SCIPheurGetData(heur);
628 assert(heurdata != NULL);
629
630 /* create working solution */
631 SCIP_CALL( SCIPcreateSol(scip, &heurdata->sol, heur) );
632 SCIP_CALL( SCIPcreateSol(scip, &heurdata->roundedsol, heur) );
633
634 /* initialize data */
635 heurdata->nlpiterations = 0;
636 heurdata->nsuccess = 0;
637
638 /* create random number generator */
639 SCIP_CALL( SCIPcreateRandom(scip, &heurdata->randnumgen,
641
642 return SCIP_OKAY;
643}
644
645/** deinitialization method of primal heuristic (called before transformed problem is freed) */
646static
647SCIP_DECL_HEUREXIT(heurExitFeaspump)
648{
649 SCIP_HEURDATA* heurdata;
650
651 assert(heur != NULL);
652 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
653
654 /* get heuristic data */
655 heurdata = SCIPheurGetData(heur);
656 assert(heurdata != NULL);
657
658 /* free working solution */
659 SCIP_CALL( SCIPfreeSol(scip, &heurdata->sol) );
660 SCIP_CALL( SCIPfreeSol(scip, &heurdata->roundedsol) );
661
662 /* free random number generator */
663 SCIPfreeRandom(scip, &heurdata->randnumgen);
664
665 return SCIP_OKAY;
666}
667
668
669/** solving process initialization method of primal heuristic (called when branch and bound process is about to begin) */
670static
671SCIP_DECL_HEURINITSOL(heurInitsolFeaspump)
672{
673 SCIP_HEURDATA* heurdata;
674
675 heurdata = SCIPheurGetData(heur);
676 assert(heurdata != NULL);
677
678 /* if the heuristic is called at the root node, we may want to be called directly after the initial root LP solve */
679 if( heurdata->beforecuts && SCIPheurGetFreqofs(heur) == 0 )
681
682 return SCIP_OKAY;
683}
684
685
686/** solving process deinitialization method of primal heuristic (called before branch and bound process data is freed) */
687static
688SCIP_DECL_HEUREXITSOL(heurExitsolFeaspump)
689{
690 /* reset the timing mask to its default value */
692
693 return SCIP_OKAY;
694}
695
696/** calculates an adjusted maximal number of LP iterations */
697static
699 SCIP_Longint maxnlpiterations, /**< regular maximal number of LP iterations */
700 SCIP_Longint nsolsfound, /**< total number of solutions found so far by SCIP */
701 int nstallloops /**< current number of stalling rounds */
702 )
703{
704 if( nstallloops <= 1 )
705 {
706 if( nsolsfound == 0 )
707 return 4*maxnlpiterations;
708 else
709 return 2*maxnlpiterations;
710 }
711 else
712 return maxnlpiterations;
713}
714
715/** execution method of primal heuristic */
716static
717SCIP_DECL_HEUREXEC(heurExecFeaspump)
718{
719 SCIP_HEURDATA* heurdata;
720 SCIP_SOL* tmpsol; /* only used for swapping */
721 SCIP_SOL** lastroundedsols;/* solutions of the last pumping rounds (depending on heurdata->cyclelength) */
722 SCIP_SOL* closestsol; /* rounded solution closest to the LP relaxation: used for stage3 */
723 SCIP_Real* lastalphas; /* alpha values associated to solutions in lastroundedsols */
724
725 SCIP* probingscip; /* copied SCIP structure, used for round-and-propagate loop of feasibility pump 2.0 */
726 SCIP_HASHMAP* varmapfw; /* mapping of SCIP variables to sub-SCIP variables */
727
728 SCIP_VAR** vars;
729 SCIP_VAR** pseudocands;
730 SCIP_VAR** tmppseudocands;
731 SCIP_VAR** mostfracvars; /* the 30 most fractional variables, needed to avoid 1-cycles */
732 SCIP_VAR* var;
733
734 SCIP_Real* mostfracvals; /* the values of the variables above */
735 SCIP_Real oldsolval; /* one value of the last solution */
736 SCIP_Real solval; /* one value of the actual solution */
737 SCIP_Real frac; /* the fractional part of the value above */
738 SCIP_Real objfactor; /* factor by which the regard of the objective is decreased in each round, in [0,0.99] */
739 SCIP_Real alpha; /* factor how the original objective is regarded, used for convex combination of two functions */
740 SCIP_Real objnorm; /* Euclidean norm of the objective function, used for scaling */
741 SCIP_Real scalingfactor; /* factor to scale the original objective function with */
742 SCIP_Real mindistance; /* distance of the closest rounded solution from the LP relaxation: used for stage3 */
743
744 SCIP_Longint nlpiterations; /* number of LP iterations done during one pumping round */
745 SCIP_Longint maxnlpiterations; /* maximum number of LP iterations for this heuristic */
746 SCIP_Longint nsolsfound; /* number of solutions found by this heuristic */
747 SCIP_Longint ncalls; /* number of calls of this heuristic */
748 SCIP_Longint nbestsolsfound; /* current total number of best solution updates in SCIP */
749
750 SCIP_LPSOLSTAT lpsolstat; /* status of the LP solution */
751
752 int nvars; /* number of variables */
753 int nenfovars; /* number of enforced integral variables */
754 int nfracs; /* number of fractional variables updated after each pumping round*/
755 int nflipcands; /* how many flipcands (most frac. var.) have been found */
756 int npseudocands;
757 int maxnflipcands; /* maximal number of candidates to flip in the current pumping round */
758 int nloops; /* how many pumping rounds have been made */
759 int maxflips; /* maximum number of flips, if a 1-cycle is found (depending on heurdata->minflips) */
760 int maxloops; /* maximum number of pumping rounds */
761 int nstallloops; /* number of loops without reducing the current best number of factional variables */
762 int maxstallloops; /* maximal number of allowed stalling loops */
763 int bestnfracs; /* best number of fractional variables */
764 int i;
765 int j;
766
767 SCIP_Bool success;
768 SCIP_Bool lperror;
769 SCIP_Bool* cycles; /* are there short cycles */
770
771 SCIP_RETCODE retcode;
772
773 assert(heur != NULL);
774 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
775 assert(scip != NULL);
776 assert(result != NULL);
777 assert(SCIPhasCurrentNodeLP(scip));
778
779 *result = SCIP_DELAYED;
780
781 /* do not call heuristic of node was already detected to be infeasible */
782 if( nodeinfeasible )
783 return SCIP_OKAY;
784
785 /* only call heuristic, if an optimal LP solution is at hand */
787 return SCIP_OKAY;
788
789 /* only call heuristic, if the LP objective value is smaller than the cutoff bound */
791 return SCIP_OKAY;
792
793 /* only call heuristic, if the LP solution is basic (which allows fast resolve in diving) */
794 if( !SCIPisLPSolBasic(scip) )
795 return SCIP_OKAY;
796
797 *result = SCIP_DIDNOTRUN;
798
799 /* don't dive two times at the same node */
801 return SCIP_OKAY;
802
803 /* only call feaspump once at the root */
804 if( SCIPgetDepth(scip) == 0 && SCIPheurGetNCalls(heur) > 0 )
805 return SCIP_OKAY;
806
807 /* reset the timing mask to its default value (at the root node it could be different) */
809
810 /* only call the heuristic before cutting planes if we do not have an incumbent and no pricer exists */
811 if( heurtiming == SCIP_HEURTIMING_DURINGLPLOOP && SCIPgetNSolsFound(scip) > 0 && SCIPgetNPricers(scip) == 0 )
812 return SCIP_OKAY;
813
814 /* get heuristic's data */
815 heurdata = SCIPheurGetData(heur);
816 assert(heurdata != NULL);
817
818 /* only apply heuristic, if only a few solutions have been found and no pricer exists */
819 if( heurdata->maxsols >= 0 && SCIPgetNSolsFound(scip) > heurdata->maxsols && SCIPgetNPricers(scip) == 0 )
820 return SCIP_OKAY;
821
822 /* get all variables of LP and number of fractional variables in LP solution that should be integral */
823 vars = SCIPgetVars(scip);
824 nvars = SCIPgetNVars(scip);
825 nenfovars = nvars - SCIPgetNContVars(scip) - SCIPgetNContImplVars(scip);
826 assert(nenfovars >= 0);
827 nfracs = SCIPgetNLPBranchCands(scip);
828 assert(0 <= nfracs && nfracs <= nenfovars);
829 if( nfracs == 0 )
830 return SCIP_OKAY;
831
832 /* calculate the maximal number of LP iterations until heuristic is aborted */
833 nlpiterations = SCIPgetNNodeLPIterations(scip);
834 ncalls = SCIPheurGetNCalls(heur);
835 nsolsfound = 10*SCIPheurGetNBestSolsFound(heur) + heurdata->nsuccess;
836 maxnlpiterations = (SCIP_Longint)(((nsolsfound+1.0)/(ncalls+1.0)) * heurdata->maxlpiterquot * nlpiterations);
837 maxnlpiterations += heurdata->maxlpiterofs;
838
839 /* don't try to dive, if we took too many LP iterations during diving */
840 if( heurdata->nlpiterations >= maxnlpiterations )
841 return SCIP_OKAY;
842
843 /* at the first root call, allow more iterations if there is no feasible solution yet */
844 if( SCIPheurGetNCalls(heur) == 0 && SCIPgetNSolsFound(scip) == 0 && SCIPgetDepth(scip) == 0 )
845 maxnlpiterations += nlpiterations;
846
847 /* allow at least a certain number of LP iterations in this dive */
848 maxnlpiterations = MAX(maxnlpiterations, heurdata->nlpiterations + MINLPITER);
849
850 /* calculate maximal number of flips and loops */
851 maxflips = 3*heurdata->minflips;
852 maxloops = (heurdata->maxloops == -1 ? INT_MAX : heurdata->maxloops);
853 maxstallloops = (heurdata->maxstallloops == -1 ? INT_MAX : heurdata->maxstallloops);
854
855 SCIPdebugMsg(scip, "executing feasibility pump heuristic, nlpiters=%" SCIP_LONGINT_FORMAT ", maxnlpit:%" SCIP_LONGINT_FORMAT ", maxflips:%d \n",
856 nlpiterations, maxnlpiterations, maxflips);
857
858 *result = SCIP_DIDNOTFIND;
859
860 probingscip = NULL;
861 varmapfw = NULL;
862
863 if( heurdata->usefp20 )
864 {
865 SCIP_Bool valid;
866
867 /* ignore value of valid */
868 SCIP_CALL( setupProbingSCIP(scip, &probingscip, &varmapfw, heurdata->copycuts, &valid) );
869
870 if( probingscip != NULL )
871 {
872 SCIP_CALL( setupSCIPparamsFP2(scip, probingscip) );
873
874 retcode = SCIPsolve(probingscip);
875
876 /* errors in solving the subproblem should not kill the overall solving process;
877 * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop. */
878 if( retcode != SCIP_OKAY )
879 {
880#ifndef NDEBUG
881 SCIP_CALL( retcode );
882#endif
883 SCIPwarningMessage(scip, "Error while solving subproblem in feaspump heuristic; sub-SCIP terminated with code <%d>\n", retcode);
884
885 /* free hash map and copied SCIP */
886 SCIPhashmapFree(&varmapfw);
887 SCIP_CALL( SCIPfree(&probingscip) );
888 return SCIP_OKAY;
889 }
890
891 if( SCIPgetStage(probingscip) != SCIP_STAGE_SOLVING)
892 {
893 SCIP_STATUS probingstatus = SCIPgetStatus(probingscip);
894
895 if( probingstatus == SCIP_STATUS_OPTIMAL )
896 {
897 assert( SCIPgetNSols(probingscip) > 0 );
898 SCIP_CALL( createNewSols(scip, probingscip, varmapfw, heur, &success) );
899 if( success )
900 *result = SCIP_FOUNDSOL;
901 }
902
903 /* free hash map and copied SCIP */
904 SCIPhashmapFree(&varmapfw);
905 SCIP_CALL( SCIPfree(&probingscip) );
906 return SCIP_OKAY;
907 }
908 SCIP_CALL( SCIPsetLongintParam(probingscip, "limits/nodes", 2LL) );
909
910 /* set SCIP into probing mode and create root node of the probing tree */
911 SCIP_CALL( SCIPstartProbing(probingscip) );
912
913 /* this should always be fulfilled */
914 assert(SCIP_MAXTREEDEPTH > SCIPgetDepth(probingscip));
915
916 SCIP_CALL( SCIPnewProbingNode(probingscip) );
917
918 SCIPdebugMsg(scip, "successfully copied SCIP instance -> feasibility pump 2.0 can be used.\n");
919 }
920 else
921 {
922 assert(varmapfw == NULL);
923
924 SCIPdebugMsg(scip, "SCIP reached the depth limit -> skip heuristic\n");
925 return SCIP_OKAY;
926 }
927 } /*lint !e438*/
928
929 /* memory allocation */
930 SCIP_CALL( SCIPallocBufferArray(scip, &mostfracvars, maxflips) );
931 SCIP_CALL( SCIPallocBufferArray(scip, &mostfracvals, maxflips) );
932 SCIP_CALL( SCIPallocBufferArray(scip, &lastroundedsols, heurdata->cyclelength) );
933 SCIP_CALL( SCIPallocBufferArray(scip, &lastalphas, heurdata->cyclelength) );
934 SCIP_CALL( SCIPallocBufferArray(scip, &cycles, heurdata->cyclelength) );
935
936 for( j = 0; j < heurdata->cyclelength; j++ )
937 {
938 SCIP_CALL( SCIPcreateSol(scip, &lastroundedsols[j], heur) );
939 }
940
941 closestsol = NULL;
942 if( heurdata->stage3 )
943 {
944 SCIP_CALL( SCIPcreateSol(scip, &closestsol, heur) );
945 }
946
947 /* start diving */
949
950 /* lp was solved optimal */
951 lperror = FALSE;
952 lpsolstat = SCIP_LPSOLSTAT_OPTIMAL;
953
954 /* pumping rounds */
955 nsolsfound = SCIPgetNBestSolsFound(scip);
956 if( heurdata->objfactor == 1.0 )
957 objfactor = MIN(1.0 - 0.1 / (SCIP_Real)(1 + nsolsfound), 0.999);
958 else
959 objfactor = heurdata->objfactor;
960
961 /* scale distance function and original objective to the same norm */
962 objnorm = SCIPgetObjNorm(scip);
963 objnorm = MAX(objnorm, 1.0);
964 scalingfactor = sqrt((SCIP_Real)nenfovars) / objnorm;
965
966 /* data initialization */
967 alpha = heurdata->alpha;
968 nloops = 0;
969 nstallloops = 0;
970 nbestsolsfound = SCIPgetNBestSolsFound(scip);
971 bestnfracs = INT_MAX;
972 mindistance = SCIPinfinity(scip);
973
974 /* pumping loop */
975 while( nfracs > 0
976 && heurdata->nlpiterations < adjustedMaxNLPIterations(maxnlpiterations, nsolsfound, nstallloops)
977 && nloops < maxloops && nstallloops < maxstallloops
978 && !SCIPisStopped(scip) )
979 {
980 int minimum;
981 SCIP_Real* pseudocandsfrac;
982 SCIP_Longint nlpiterationsleft;
983 int iterlimit;
984
985 /* decrease convex combination scalar */
986 nloops++;
987 alpha *= objfactor;
988
989 SCIPdebugMsg(scip, "feasibility pump loop %d: %d fractional variables (alpha: %.4f, stall: %d/%d)\n",
990 nloops, nfracs, alpha, nstallloops, maxstallloops);
991
992 success = FALSE;
993
994 SCIP_CALL( SCIPlinkLPSol(scip, heurdata->roundedsol) );
995
996 /* randomly choose maximum number of variables to flip in current pumping round in case of a 1-cycle */
997 maxnflipcands = SCIPrandomGetInt(heurdata->randnumgen, MIN(nfracs/2+1, heurdata->minflips), MIN(nfracs, maxflips));
998 nflipcands = 0;
999
1000 /* get all unfixed integer variables */
1001 SCIP_CALL( SCIPgetPseudoBranchCands(scip, &tmppseudocands, &npseudocands, NULL) );
1002 SCIP_CALL( SCIPduplicateBufferArray(scip, &pseudocands, tmppseudocands, npseudocands) );
1003
1004 /* get array of all fractional variables and sort it w.r.t. their fractionalities */
1005 if( heurdata->usefp20 )
1006 {
1007 SCIP_CALL( SCIPallocBufferArray(scip, &pseudocandsfrac, npseudocands) );
1008
1009 for( i = 0; i < npseudocands; i++ )
1010 {
1011 frac = SCIPfeasFrac(scip, SCIPvarGetLPSol(pseudocands[i]));
1012 pseudocandsfrac[i] = MIN(frac, 1.0-frac); /* always a number between 0 and 0.5 */
1013 if( SCIPvarGetType(pseudocands[i]) == SCIP_VARTYPE_BINARY && !SCIPvarIsImpliedIntegral(pseudocands[i]) )
1014 pseudocandsfrac[i] -= 10.0; /* binaries always come first */
1015 }
1016 SCIPsortRealPtr(pseudocandsfrac, (void**)pseudocands, npseudocands);
1017 SCIPfreeBufferArray(scip, &pseudocandsfrac);
1018
1019 SCIPdebugMsg(scip, "iteratively fix and propagate variables\n");
1020 }
1021
1022 for( i = 0; i < npseudocands; i++ )
1023 {
1024 SCIP_VAR* probingvar;
1025 SCIP_Bool infeasible;
1026 SCIP_Longint ndomreds;
1027
1028 var = pseudocands[i];
1029
1030 /* round the LP solution */
1031 solval = SCIPvarGetLPSol(var);
1032 frac = SCIPfeasFrac(scip, solval);
1033
1034 /* round randomly if the value is close to 0.5 */
1035 if( SCIPisEQ(scip, frac, 0.5) )
1036 {
1037 if( SCIPrandomGetReal(heurdata->randnumgen, 0.0, 1.0) <= 0.5 )
1038 solval = SCIPfloor(scip, solval);
1039 else
1040 solval = SCIPceil(scip, solval);
1041 }
1042 else
1043 solval = SCIPfloor(scip, solval + 0.5);
1044
1045 /* ensure, that the fixing value is inside the local domains */
1046 if( heurdata->usefp20 )
1047 {
1048 SCIP_Real lbprobing;
1049 SCIP_Real ubprobing;
1050
1051 probingvar = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, var);
1052 /* skip if variable does not exist in probingscip */
1053 if( probingvar != NULL )
1054 {
1055 lbprobing = SCIPvarGetLbLocal(probingvar);
1056 ubprobing = SCIPvarGetUbLocal(probingvar);
1057
1058 solval = MAX(solval, lbprobing);
1059 solval = MIN(solval, ubprobing);
1060
1061 /* fix the variable and propagate the domain change */
1062 if( !SCIPisFeasEQ(probingscip, lbprobing, ubprobing) && SCIPvarIsActive(SCIPvarGetTransVar(probingvar)) )
1063 {
1064 assert(SCIPisFeasLE(probingscip, lbprobing, ubprobing));
1065 SCIPdebugMsg(scip, "try to fix variable <%s> (domain [%f,%f] to %f\n", SCIPvarGetName(probingvar), lbprobing, ubprobing,
1066 solval);
1067 SCIP_CALL( SCIPfixVarProbing(probingscip, probingvar, solval) );
1068 SCIP_CALL( SCIPpropagateProbing(probingscip, -1, &infeasible, &ndomreds) );
1069 SCIPdebugMsg(scip, " -> reduced %" SCIP_LONGINT_FORMAT " domains\n", ndomreds);
1070
1071 if( infeasible )
1072 {
1073 SCIPdebugMsg(scip, " -> infeasible!\n");
1074 SCIP_CALL( SCIPbacktrackProbing(probingscip, 0) );
1075 }
1076 }
1077 else
1078 {
1079 SCIPdebugMsg(scip, "variable <%s> is already fixed to %f\n", SCIPvarGetName(probingvar), solval);
1080 }
1081 }
1082 }
1083
1084 SCIP_CALL( updateVariableRounding(scip, heurdata, var, solval, alpha, scalingfactor) );
1085
1086 /* check whether the variable is one of the most fractionals and label if so */
1087 if( SCIPisFeasPositive(scip, frac) )
1088 insertFlipCand(mostfracvars, mostfracvals, &nflipcands, maxnflipcands, var, frac);
1089 }
1090
1091 if( heurdata->usefp20 )
1092 {
1093 SCIP_CALL( SCIPbacktrackProbing(probingscip, 0) );
1094 }
1095
1096 /* change objective coefficients for continuous variables */
1097 for( i = nenfovars; i < nvars; i++ )
1098 {
1099 SCIP_CALL( SCIPchgVarObjDive(scip, vars[i], alpha * SCIPvarGetObj(vars[i])) );
1100 }
1101
1102 SCIPfreeBufferArray(scip, &pseudocands);
1103
1104 /* initialize cycle check */
1105 minimum = MIN(heurdata->cyclelength, nloops-1);
1106 for( j = 0; j < heurdata->cyclelength; j++ )
1107 cycles[j] = (nloops > j+1) && (REALABS(lastalphas[j] - alpha) < heurdata->alphadiff);
1108
1109 /* check for j-cycles */
1110 for( i = 0; i < nenfovars; i++ )
1111 {
1112 solval = SCIPgetSolVal(scip, heurdata->roundedsol, vars[i]);
1113
1114 /* cycles exist, iff all solution values are equal */
1115 for( j = 0; j < minimum; j++ )
1116 {
1117 oldsolval = SCIPgetSolVal(scip, lastroundedsols[j], vars[i]);
1118 cycles[j] = cycles[j] && SCIPisFeasEQ(scip, solval, oldsolval);
1119 }
1120 }
1121
1122 /* force to flip variables at random after a couple of pumping rounds,
1123 * or if a new best solution in the current region has been found
1124 */
1125 assert(heurdata->perturbfreq > 0);
1126 if( nloops % heurdata->perturbfreq == 0 || (heurdata->pertsolfound && SCIPgetNBestSolsFound(scip) > nbestsolsfound) )
1127 {
1128 SCIPdebugMsg(scip, " -> random perturbation\n");
1129 SCIP_CALL( handleCycle(scip, heurdata, vars, nenfovars, alpha, scalingfactor) );
1130 nbestsolsfound = SCIPgetNBestSolsFound(scip);
1131 }
1132 else
1133 {
1134 minimum = MIN(heurdata->cyclelength, nloops-1);
1135
1136 for( j = 0; j < minimum; j++ )
1137 {
1138 /* if we got the same rounded solution as in some step before, we have to flip some variables */
1139 if( cycles[j] )
1140 {
1141 /* 1-cycles have a special flipping rule (flip most fractional variables) */
1142 if( j == 0 )
1143 {
1144 SCIPdebugMsg(scip, " -> avoiding 1-cycle: flipping %d candidates\n", nflipcands);
1145 SCIP_CALL( handle1Cycle(scip, heurdata, mostfracvars, nflipcands, alpha, scalingfactor) );
1146 }
1147 else
1148 {
1149 SCIPdebugMsg(scip, " -> avoiding %d-cycle by random flip\n", j+1);
1150 SCIP_CALL( handleCycle(scip, heurdata, vars, nenfovars, alpha, scalingfactor) );
1151 }
1152 break;
1153 }
1154 }
1155 }
1156
1157 /* the LP with the new (distance) objective is solved */
1158 nlpiterations = SCIPgetNLPIterations(scip);
1159 nlpiterationsleft = adjustedMaxNLPIterations(maxnlpiterations, nsolsfound, nstallloops) - heurdata->nlpiterations;
1160 iterlimit = MAX((int)nlpiterationsleft, MINLPITER);
1161 SCIPdebugMsg(scip, " -> solve LP with iteration limit %d\n", iterlimit);
1162
1163 if( heurdata->stage3 )
1164 {
1165 SCIP_CALL( SCIPunlinkSol(scip, heurdata->roundedsol) );
1166 }
1167
1168 retcode = SCIPsolveDiveLP(scip, iterlimit, &lperror, NULL);
1169 lpsolstat = SCIPgetLPSolstat(scip);
1170
1171 /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
1172 * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
1173 */
1174 if( retcode != SCIP_OKAY )
1175 {
1176#ifndef NDEBUG
1177 if( lpsolstat != SCIP_LPSOLSTAT_UNBOUNDEDRAY )
1178 {
1179 SCIP_CALL( retcode );
1180 }
1181#endif
1182 SCIPwarningMessage(scip, "Error while solving LP in Feaspump heuristic; LP solve terminated with code <%d>\n", retcode);
1183 SCIPwarningMessage(scip, "This does not affect the remaining solution procedure --> continue\n");
1184 }
1185
1186 /* update iteration count */
1187 heurdata->nlpiterations += SCIPgetNLPIterations(scip) - nlpiterations;
1188 SCIPdebugMsg(scip, " -> number of iterations: %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", lperror=%u, lpsolstat=%d\n",
1189 heurdata->nlpiterations, adjustedMaxNLPIterations(maxnlpiterations, nsolsfound, nstallloops), lperror, lpsolstat);
1190
1191 /* check whether LP was solved optimal */
1192 if( lperror || lpsolstat != SCIP_LPSOLSTAT_OPTIMAL )
1193 break;
1194
1195 if( heurdata->stage3 )
1196 {
1197 SCIP_Real distance; /* distance of the current rounded solution from the LP solution */
1198
1199 assert(closestsol != NULL);
1200
1201 /* calculate distance */
1202 distance = 0.0;
1203 for( i = 0; i < nenfovars; i++ )
1204 {
1205 SCIP_Real roundedval;
1206 SCIP_Real lpval;
1207
1208 roundedval = SCIPgetSolVal(scip, heurdata->roundedsol, vars[i]);
1209 lpval = SCIPvarGetLPSol(vars[i]);
1210 distance += REALABS(roundedval - lpval);
1211 }
1212
1213 /* copy solution and update minimum distance */
1214 if( SCIPisLT(scip, distance, mindistance) )
1215 {
1216 for( i = 0; i < nenfovars; i++ )
1217 {
1218 assert(SCIPisIntegral(scip,SCIPgetSolVal(scip, heurdata->roundedsol, vars[i])));
1219 SCIP_CALL( SCIPsetSolVal(scip, closestsol, vars[i], SCIPgetSolVal(scip, heurdata->roundedsol, vars[i])) );
1220 }
1221 mindistance = distance;
1222 }
1223 }
1224
1225 /* swap the last solutions */
1226 SCIP_CALL( SCIPunlinkSol(scip, heurdata->roundedsol) );
1227 tmpsol = lastroundedsols[heurdata->cyclelength-1];
1228 for( j = heurdata->cyclelength-1; j > 0; j-- )
1229 {
1230 lastroundedsols[j] = lastroundedsols[j-1];
1231 lastalphas[j] = lastalphas[j-1];
1232 }
1233 lastroundedsols[0] = heurdata->roundedsol;
1234 lastalphas[0] = alpha;
1235 heurdata->roundedsol = tmpsol;
1236
1237 /* check for improvement in number of fractionals */
1238 nfracs = SCIPgetNLPBranchCands(scip);
1239 if( nfracs < bestnfracs )
1240 {
1241 bestnfracs = nfracs;
1242 nstallloops = 0;
1243 }
1244 else
1245 nstallloops++;
1246
1247 SCIPdebugMsg(scip, " -> loop finished: %d fractional variables (stall: %d/%d, iterations: %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ")\n",
1248 nfracs, nstallloops, maxstallloops, heurdata->nlpiterations, adjustedMaxNLPIterations(maxnlpiterations, nsolsfound, nstallloops));
1249 }
1250
1251 /* try final solution, if no more fractional variables are left */
1252 if( nfracs == 0 && !lperror && lpsolstat == SCIP_LPSOLSTAT_OPTIMAL )
1253 {
1254 success = FALSE;
1255
1256 SCIP_CALL( SCIPlinkLPSol(scip, heurdata->sol) );
1257
1258 /* in exact mode we have to end diving prior to trying the solution */
1259 if( SCIPisExact(scip) )
1260 {
1261 SCIP_CALL( SCIPunlinkSol(scip, heurdata->sol) );
1263 }
1264
1265 SCIPdebugMsg(scip, "feasibility pump found solution (%d fractional variables)\n", nfracs);
1266 SCIP_CALL( SCIPtrySol(scip, heurdata->sol, FALSE, FALSE, FALSE, FALSE, FALSE, &success) );
1267 if( success )
1268 *result = SCIP_FOUNDSOL;
1269 }
1270
1271 /* end diving */
1272 if( SCIPinDive(scip) )
1273 {
1275 }
1276
1277 /* end probing in order to be able to apply stage 3 */
1278 if( heurdata->usefp20 )
1279 {
1280 SCIP_CALL( SCIPendProbing(probingscip) );
1281 }
1282
1283 /* only do stage 3 if we have not found a solution yet */
1284 /* only do stage 3 if the distance of the closest infeasible solution to the polyhedron is below a certain threshold */
1285 if( heurdata->stage3 && (*result != SCIP_FOUNDSOL) && SCIPisLE(scip, mindistance, (SCIP_Real) heurdata->neighborhoodsize) )
1286 {
1287 SCIP_Bool cancopy;
1288 assert(closestsol != NULL);
1289 assert(!SCIPisInfinity(scip, mindistance) || nloops == 0);
1290
1291 /* if we do not use feasibility pump 2.0, we have not created a copied SCIP instance yet */
1292 if( heurdata->usefp20 )
1293 {
1294 assert(probingscip != NULL);
1295 SCIP_CALL( SCIPfreeTransform(probingscip) );
1296 }
1297 else
1298 {
1299 assert(probingscip == NULL);
1300 SCIP_CALL( setupProbingSCIP(scip, &probingscip, &varmapfw, heurdata->copycuts, &success) );
1301 }
1302
1303 /* check whether there is enough time and memory left */
1304 SCIP_CALL( SCIPcheckCopyLimits(scip, &cancopy) );
1305
1306 if( cancopy )
1307 {
1308 SCIP_CALL( setupSCIPparamsStage3(scip, probingscip) );
1309
1310 /* the neighborhood size is double the distance plus another ten percent */
1311 mindistance = SCIPceil(scip, 2.2*mindistance);
1312
1313 SCIP_CALL( addLocalBranchingConstraint(scip, probingscip, varmapfw, closestsol, mindistance) );
1314
1315 /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
1316 * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
1317 */
1318 SCIP_CALL_ABORT( SCIPsolve(probingscip) );
1319
1320 /* check, whether a solution was found */
1321 if( SCIPgetNSols(probingscip) > 0 )
1322 {
1323 success = FALSE;
1324 SCIP_CALL( createNewSols(scip, probingscip, varmapfw, heur, &success) );
1325 if( success )
1326 *result = SCIP_FOUNDSOL;
1327 }
1328 }
1329 }
1330
1331 if( *result == SCIP_FOUNDSOL )
1332 heurdata->nsuccess++;
1333
1334 /* free hash map and copied SCIP */
1335 if( varmapfw != NULL )
1336 SCIPhashmapFree(&varmapfw);
1337
1338 if( probingscip != NULL )
1339 {
1340 SCIP_CALL( SCIPfree(&probingscip) );
1341 }
1342
1343 if( heurdata->stage3 )
1344 {
1345 SCIP_CALL( SCIPfreeSol(scip, &closestsol) );
1346 }
1347
1348 /* free memory */
1349 for( j = 0; j < heurdata->cyclelength; j++ )
1350 {
1351 SCIP_CALL( SCIPfreeSol(scip, &lastroundedsols[j]) );
1352 }
1353
1354 SCIPfreeBufferArray(scip, &cycles);
1355 SCIPfreeBufferArray(scip, &lastalphas);
1356 SCIPfreeBufferArray(scip, &lastroundedsols);
1357 SCIPfreeBufferArray(scip, &mostfracvals);
1358 SCIPfreeBufferArray(scip, &mostfracvars);
1359
1360 SCIPdebugMsg(scip, "feasibility pump finished [%d iterations done].\n", nloops);
1361
1362#ifdef SCIP_STATISTIC
1363 if( nfracs == 0 )
1364 {
1365 double objval;
1366 double primalBound;
1367
1368 objval = SCIPgetSolOrigObj(scip, heurdata->sol);
1369 primalBound = SCIPgetPrimalbound(scip);
1370 SCIPstatisticMessage("feasibility pump found: 1, objval: %f, iterations: %d, primal bound: %f\n", objval, nloops, primalBound);
1371 }
1372 else
1373 {
1374 double primalBound;
1375
1376 primalBound = SCIPgetPrimalbound(scip);
1377 SCIPstatisticMessage("feasibility pump found: 0, objval: +inf, iterations: %d, primal bound: %f\n", nloops, primalBound);
1378 }
1379
1380#endif /* SCIP_STATISTIC */
1381
1382 return SCIP_OKAY;
1383}
1384
1385
1386/*
1387 * primal heuristic specific interface methods
1388 */
1389
1390/** creates the feaspump primal heuristic and includes it in SCIP */
1392 SCIP* scip /**< SCIP data structure */
1393 )
1394{
1395 SCIP_HEURDATA* heurdata;
1396 SCIP_HEUR* heur;
1397
1398 /* create Feaspump primal heuristic data */
1399 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
1400
1401 /* include primal heuristic */
1404 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecFeaspump, heurdata) );
1405
1406 assert(heur != NULL);
1407
1408 /* primal heuristic is safe to use in exact solving mode */
1409 SCIPheurMarkExact(heur);
1410
1411 /* set non-NULL pointers to callback methods */
1412 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyFeaspump) );
1413 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeFeaspump) );
1414 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitFeaspump) );
1415 SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitFeaspump) );
1416 SCIP_CALL( SCIPsetHeurInitsol(scip, heur, heurInitsolFeaspump) );
1417 SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolFeaspump) );
1418
1419 /* add feaspump primal heuristic parameters */
1421 "heuristics/" HEUR_NAME "/maxlpiterquot",
1422 "maximal fraction of diving LP iterations compared to node LP iterations",
1423 &heurdata->maxlpiterquot, FALSE, DEFAULT_MAXLPITERQUOT, 0.0, SCIP_REAL_MAX, NULL, NULL) );
1425 "heuristics/" HEUR_NAME "/objfactor",
1426 "factor by which the regard of the objective is decreased in each round, 1.0 for dynamic",
1427 &heurdata->objfactor, FALSE, DEFAULT_OBJFACTOR, 0.0, 1.0, NULL, NULL) );
1429 "heuristics/" HEUR_NAME "/alpha",
1430 "initial weight of the objective function in the convex combination",
1431 &heurdata->alpha, FALSE, DEFAULT_ALPHA, 0.0, 1.0, NULL, NULL) );
1433 "heuristics/" HEUR_NAME "/alphadiff",
1434 "threshold difference for the convex parameter to perform perturbation",
1435 &heurdata->alphadiff, FALSE, DEFAULT_ALPHADIFF, 0.0, 1.0, NULL, NULL) );
1436
1438 "heuristics/" HEUR_NAME "/maxlpiterofs",
1439 "additional number of allowed LP iterations",
1440 &heurdata->maxlpiterofs, FALSE, DEFAULT_MAXLPITEROFS, 0, INT_MAX, NULL, NULL) );
1442 "heuristics/" HEUR_NAME "/maxsols",
1443 "total number of feasible solutions found up to which heuristic is called (-1: no limit)",
1444 &heurdata->maxsols, TRUE, DEFAULT_MAXSOLS, -1, INT_MAX, NULL, NULL) );
1446 "heuristics/" HEUR_NAME "/maxloops",
1447 "maximal number of pumping loops (-1: no limit)",
1448 &heurdata->maxloops, TRUE, DEFAULT_MAXLOOPS, -1, INT_MAX, NULL, NULL) );
1450 "heuristics/" HEUR_NAME "/maxstallloops",
1451 "maximal number of pumping rounds without fractionality improvement (-1: no limit)",
1452 &heurdata->maxstallloops, TRUE, DEFAULT_MAXSTALLLOOPS, -1, INT_MAX, NULL, NULL) );
1454 "heuristics/" HEUR_NAME "/minflips",
1455 "minimum number of random variables to flip, if a 1-cycle is encountered",
1456 &heurdata->minflips, TRUE, DEFAULT_MINFLIPS, 1, INT_MAX, NULL, NULL) );
1458 "heuristics/" HEUR_NAME "/cyclelength",
1459 "maximum length of cycles to be checked explicitly in each round",
1460 &heurdata->cyclelength, TRUE, DEFAULT_CYCLELENGTH, 1, 100, NULL, NULL) );
1462 "heuristics/" HEUR_NAME "/perturbfreq",
1463 "number of iterations until a random perturbation is forced",
1464 &heurdata->perturbfreq, TRUE, DEFAULT_PERTURBFREQ, 1, INT_MAX, NULL, NULL) );
1465 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/neighborhoodsize",
1466 "radius (using Manhattan metric) of the neighborhood to be searched in stage 3",
1467 &heurdata->neighborhoodsize, FALSE, DEFAULT_NEIGHBORHOODSIZE, 1, INT_MAX, NULL, NULL) );
1468
1470 "heuristics/" HEUR_NAME "/beforecuts",
1471 "should the feasibility pump be called at root node before cut separation?",
1472 &heurdata->beforecuts, FALSE, DEFAULT_BEFORECUTS, NULL, NULL) );
1474 "heuristics/" HEUR_NAME "/usefp20",
1475 "should an iterative round-and-propagate scheme be used to find the integral points?",
1476 &heurdata->usefp20, FALSE, DEFAULT_USEFP20, NULL, NULL) );
1478 "heuristics/" HEUR_NAME "/pertsolfound",
1479 "should a random perturbation be performed if a feasible solution was found?",
1480 &heurdata->pertsolfound, FALSE, DEFAULT_PERTSOLFOUND, NULL, NULL) );
1482 "heuristics/" HEUR_NAME "/stage3",
1483 "should we solve a local branching sub-MIP if no solution could be found?",
1484 &heurdata->stage3, FALSE, DEFAULT_STAGE3, NULL, NULL) );
1485 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/copycuts",
1486 "should all active cuts from cutpool be copied to constraints in subproblem?",
1487 &heurdata->copycuts, TRUE, DEFAULT_COPYCUTS, NULL, NULL) );
1488
1489 return SCIP_OKAY;
1490}
Constraint handler for linear constraints in their most general form, .
#define NULL
Definition: def.h:248
#define SCIP_MAXSTRLEN
Definition: def.h:269
#define SCIP_Longint
Definition: def.h:141
#define SCIP_MAXTREEDEPTH
Definition: def.h:297
#define SCIP_REAL_MAX
Definition: def.h:158
#define SCIP_Bool
Definition: def.h:91
#define MIN(x, y)
Definition: def.h:224
#define SCIP_Real
Definition: def.h:156
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define MAX(x, y)
Definition: def.h:220
#define SCIP_CALL_ABORT(x)
Definition: def.h:334
#define SCIP_LONGINT_FORMAT
Definition: def.h:148
#define REALABS(x)
Definition: def.h:182
#define SCIP_CALL(x)
Definition: def.h:355
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:1437
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:2961
SCIP_RETCODE SCIPcheckCopyLimits(SCIP *sourcescip, SCIP_Bool *success)
Definition: scip_copy.c:3249
SCIP_RETCODE SCIPcopyCuts(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, int *ncutsadded)
Definition: scip_copy.c:2113
SCIP_RETCODE SCIPcopyParamSettings(SCIP *sourcescip, SCIP *targetscip)
Definition: scip_copy.c:2547
SCIP_RETCODE SCIPcopyLimits(SCIP *sourcescip, SCIP *targetscip)
Definition: scip_copy.c:3292
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip_general.c:759
SCIP_RETCODE SCIPfree(SCIP **scip)
Definition: scip_general.c:402
SCIP_RETCODE SCIPcreate(SCIP **scip)
Definition: scip_general.c:370
SCIP_STATUS SCIPgetStatus(SCIP *scip)
Definition: scip_general.c:562
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:444
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
Definition: scip_message.h:78
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
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)
Definition: scip_branch.c:304
int SCIPgetNLPBranchCands(SCIP *scip)
Definition: scip_branch.c:436
SCIP_RETCODE SCIPgetPseudoBranchCands(SCIP *scip, SCIP_VAR ***pseudocands, int *npseudocands, int *npriopseudocands)
Definition: scip_branch.c:741
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 SCIPsetHeurExitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXITSOL((*heurexitsol)))
Definition: scip_heur.c:247
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
Definition: scip_heur.c:167
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 SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
Definition: scip_heur.c:183
SCIP_RETCODE SCIPsetHeurExit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXIT((*heurexit)))
Definition: scip_heur.c:215
SCIP_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
Definition: heur.c:1613
void SCIPheurSetTimingmask(SCIP_HEUR *heur, SCIP_HEURTIMING timingmask)
Definition: heur.c:1507
SCIP_Longint SCIPheurGetNCalls(SCIP_HEUR *heur)
Definition: heur.c:1593
SCIP_RETCODE SCIPsetHeurInitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINITSOL((*heurinitsol)))
Definition: scip_heur.c:231
int SCIPheurGetFreqofs(SCIP_HEUR *heur)
Definition: heur.c:1573
void SCIPheurMarkExact(SCIP_HEUR *heur)
Definition: heur.c:1457
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINIT((*heurinit)))
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)
Definition: scip_nodesel.c:242
int SCIPgetNPricers(SCIP *scip)
Definition: scip_pricer.c:337
SCIP_RETCODE SCIPpropagateProbing(SCIP *scip, int maxproprounds, SCIP_Bool *cutoff, SCIP_Longint *ndomredsfound)
Definition: scip_probing.c:581
SCIP_RETCODE SCIPbacktrackProbing(SCIP *scip, int probingdepth)
Definition: scip_probing.c:226
SCIP_RETCODE SCIPstartProbing(SCIP *scip)
Definition: scip_probing.c:120
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
Definition: scip_probing.c:166
SCIP_RETCODE SCIPfixVarProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval)
Definition: scip_probing.c:419
SCIP_RETCODE SCIPendProbing(SCIP *scip)
Definition: scip_probing.c:261
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip_sol.c:516
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip_sol.c:1252
int SCIPgetNSols(SCIP *scip)
Definition: scip_sol.c:2882
SCIP_RETCODE SCIPunlinkSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip_sol.c:1506
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:4012
SCIP_RETCODE SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip_sol.c:1295
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip_sol.c:1892
SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
Definition: scip_sol.c:1571
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1765
SCIP_RETCODE SCIPfreeTransform(SCIP *scip)
Definition: scip_solve.c:3462
SCIP_RETCODE SCIPsolve(SCIP *scip)
Definition: scip_solve.c:2635
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:23642
SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
Definition: var.c:23498
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:24268
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:23900
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:23453
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:23267
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
Definition: var.c:24664
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:24234
SCIP_VAR * SCIPvarGetTransVar(SCIP_VAR *var)
Definition: var.c:23672
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:5372
void SCIPfreeRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen)
SCIP_Real SCIPrandomGetReal(SCIP_RANDNUMGEN *randnumgen, SCIP_Real minrandval, SCIP_Real maxrandval)
Definition: misc.c:10245
SCIP_RETCODE SCIPcreateRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen, unsigned int initialseed, SCIP_Bool useglobalseed)
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 DEFAULT_STAGE3
Definition: heur_feaspump.c:91
#define DEFAULT_CYCLELENGTH
Definition: heur_feaspump.c:82
static SCIP_RETCODE setupProbingSCIP(SCIP *scip, SCIP **probingscip, SCIP_HASHMAP **varmapfw, SCIP_Bool copycuts, SCIP_Bool *success)
static SCIP_DECL_HEURINITSOL(heurInitsolFeaspump)
#define DEFAULT_MINFLIPS
Definition: heur_feaspump.c:81
#define DEFAULT_COPYCUTS
Definition: heur_feaspump.c:93
#define HEUR_TIMING
Definition: heur_feaspump.c:72
#define DEFAULT_ALPHADIFF
Definition: heur_feaspump.c:87
#define DEFAULT_MAXLPITERQUOT
Definition: heur_feaspump.c:75
#define HEUR_FREQOFS
Definition: heur_feaspump.c:70
#define HEUR_DESC
Definition: heur_feaspump.c:66
#define MINLPITER
Definition: heur_feaspump.c:97
static SCIP_DECL_HEURFREE(heurFreeFeaspump)
#define DEFAULT_NEIGHBORHOODSIZE
Definition: heur_feaspump.c:92
static SCIP_DECL_HEUREXIT(heurExitFeaspump)
static SCIP_DECL_HEUREXEC(heurExecFeaspump)
static SCIP_RETCODE handle1Cycle(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_VAR **mostfracvars, int nflipcands, SCIP_Real alpha, SCIP_Real scalingfactor)
static SCIP_DECL_HEUREXITSOL(heurExitsolFeaspump)
#define DEFAULT_USEFP20
Definition: heur_feaspump.c:89
#define HEUR_DISPCHAR
Definition: heur_feaspump.c:67
#define HEUR_MAXDEPTH
Definition: heur_feaspump.c:71
#define HEUR_PRIORITY
Definition: heur_feaspump.c:68
#define DEFAULT_MAXLPITEROFS
Definition: heur_feaspump.c:76
#define DEFAULT_MAXSTALLLOOPS
Definition: heur_feaspump.c:80
#define DEFAULT_PERTURBFREQ
Definition: heur_feaspump.c:83
#define DEFAULT_PERTSOLFOUND
Definition: heur_feaspump.c:90
#define HEUR_NAME
Definition: heur_feaspump.c:65
static void insertFlipCand(SCIP_VAR **mostfracvars, SCIP_Real *mostfracvals, int *nflipcands, int maxnflipcands, SCIP_VAR *var, SCIP_Real frac)
#define DEFAULT_ALPHA
Definition: heur_feaspump.c:86
#define DEFAULT_RANDSEED
Definition: heur_feaspump.c:99
static SCIP_DECL_HEURINIT(heurInitFeaspump)
static SCIP_RETCODE setupSCIPparamsFP2(SCIP *scip, SCIP *probingscip)
static SCIP_Longint adjustedMaxNLPIterations(SCIP_Longint maxnlpiterations, SCIP_Longint nsolsfound, int nstallloops)
#define HEUR_FREQ
Definition: heur_feaspump.c:69
#define DEFAULT_MAXSOLS
Definition: heur_feaspump.c:77
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
Definition: heur_feaspump.c:88
#define HEUR_USESSUBSCIP
Definition: heur_feaspump.c:73
static SCIP_RETCODE handleCycle(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_VAR **vars, int nbinandintvars, SCIP_Real alpha, SCIP_Real scalingfactor)
static SCIP_DECL_HEURCOPY(heurCopyFeaspump)
#define DEFAULT_MAXLOOPS
Definition: heur_feaspump.c:79
#define DEFAULT_OBJFACTOR
Definition: heur_feaspump.c:84
static SCIP_RETCODE createNewSols(SCIP *scip, SCIP *subscip, SCIP_HASHMAP *varmapfw, SCIP_HEUR *heur, SCIP_Bool *success)
Objective Feasibility Pump 2.0.
memory allocation routines
public methods for primal heuristics
public methods for message output
#define SCIPstatisticMessage
Definition: pub_message.h:123
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_HeurData SCIP_HEURDATA
Definition: type_heur.h:77
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
@ SCIP_PARAMSETTING_OFF
Definition: type_paramset.h:63
@ SCIP_PARAMSETTING_FAST
Definition: type_paramset.h:62
@ 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_OKAY
Definition: type_retcode.h:42
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
@ SCIP_STAGE_SOLVING
Definition: type_set.h:53
@ 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
@ SCIP_VARTYPE_BINARY
Definition: type_var.h:64