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-2016 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file heur_feaspump.c
17  * @brief Objective Feasibility Pump 2.0
18  * @author Timo Berthold
19  * @author Domenico Salvagnin
20  */
21 
22 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
23 
24 #include <assert.h>
25 #include <string.h>
26 
27 #include "scip/heur_feaspump.h"
28 #include "scip/cons_linear.h"
29 #include "scip/scipdefplugins.h"
30 
31 #define HEUR_NAME "feaspump"
32 #define HEUR_DESC "objective feasibility pump 2.0"
33 #define HEUR_DISPCHAR 'F'
34 #define HEUR_PRIORITY -1000000
35 #define HEUR_FREQ 20
36 #define HEUR_FREQOFS 0
37 #define HEUR_MAXDEPTH -1
38 #define HEUR_TIMING SCIP_HEURTIMING_AFTERLPPLUNGE
39 #define HEUR_USESSUBSCIP FALSE /**< does the heuristic use a secondary SCIP instance? */
40 
41 #define DEFAULT_MAXLPITERQUOT 0.01 /**< maximal fraction of diving LP iterations compared to node LP iterations */
42 #define DEFAULT_MAXLPITEROFS 1000 /**< additional number of allowed LP iterations */
43 #define DEFAULT_MAXSOLS 10 /**< total number of feasible solutions found up to which heuristic is called
44  * (-1: no limit) */
45 #define DEFAULT_MAXLOOPS 10000 /**< maximal number of pumping rounds (-1: no limit) */
46 #define DEFAULT_MAXSTALLLOOPS 10 /**< maximal number of pumping rounds without fractionality improvement (-1: no limit) */
47 #define DEFAULT_MINFLIPS 10 /**< minimum number of random variables to flip, if a 1-cycle is encountered */
48 #define DEFAULT_CYCLELENGTH 3 /**< maximum length of cycles to be checked explicitly in each round */
49 #define DEFAULT_PERTURBFREQ 100 /**< number of iterations until a random perturbation is forced */
50 #define DEFAULT_OBJFACTOR 0.1 /**< factor by which the regard of the objective is decreased in each round,
51  * 1.0 for dynamic, depending on solutions already found */
52 #define DEFAULT_ALPHA 1.0 /**< initial weight of the objective function in the convex combination */
53 #define DEFAULT_ALPHADIFF 1.0 /**< threshold difference for the convex parameter to perform perturbation */
54 #define DEFAULT_BEFORECUTS TRUE /**< should the feasibility pump be called at root node before cut separation? */
55 #define DEFAULT_USEFP20 FALSE /**< should an iterative round-and-propagate scheme be used to find the integral points? */
56 #define DEFAULT_PERTSOLFOUND TRUE /**< should a random perturbation be performed if a feasible solution was found? */
57 #define DEFAULT_STAGE3 FALSE /**< should we solve a local branching sub-MIP if no solution could be found? */
58 #define DEFAULT_NEIGHBORHOODSIZE 18 /**< radius of the neighborhood to be searched in stage 3 */
59 #define DEFAULT_COPYCUTS TRUE /**< should all active cuts from the cutpool of the original SCIP be copied to
60  * constraints of the subscip
61  */
62 
63 #define MINLPITER 5000 /**< minimal number of LP iterations allowed in each LP solving call */
64 
65 
66 /** primal heuristic data */
67 struct SCIP_HeurData
68 {
69  SCIP_SOL* sol; /**< working solution */
70  SCIP_SOL* roundedsol; /**< rounded solution */
71  SCIP_Longint nlpiterations; /**< number of LP iterations used in this heuristic */
72  SCIP_Real maxlpiterquot; /**< maximal fraction of diving LP iterations compared to node LP iterations */
73  SCIP_Real objfactor; /**< factor by which the regard of the objective is decreased in each round,
74  * 1.0 for dynamic, depending on solutions already found */
75  SCIP_Real alpha; /**< initial weight of the objective function in the convex combination */
76  SCIP_Real alphadiff; /**< threshold difference for the convex parameter to perform perturbation */
77 
78  int maxlpiterofs; /**< additional number of allowed LP iterations */
79  int maxsols; /**< total number of feasible solutions found up to which heuristic is called
80  * (-1: no limit) */
81  int maxloops; /**< maximum number of loops (-1: no limit) */
82  int maxstallloops; /**< maximal number of pumping rounds without fractionality improvement (-1: no limit) */
83  int minflips; /**< minimum number of random variables to flip, if a 1-cycle is encountered */
84  int cyclelength; /**< maximum length of cycles to be checked explicitly in each round */
85  int perturbfreq; /**< number of iterations until a random perturbation is forced */
86  int nsuccess; /**< number of runs that produced at least one feasible solution */
87  int neighborhoodsize; /**< radius of the neighborhood to be searched in stage 3 */
88 
89  unsigned int randseed; /**< seed value for random number generator */
90  SCIP_Bool beforecuts; /**< should the feasibility pump be called at root node before cut separation? */
91  SCIP_Bool usefp20; /**< should an iterative round-and-propagate scheme be used to find the integral points? */
92  SCIP_Bool pertsolfound; /**< should a random perturbation be performed if a feasible solution was found? */
93  SCIP_Bool stage3; /**< should we solve a local branching sub-MIP if no solution could be found? */
94  SCIP_Bool copycuts; /**< should all active cuts from cutpool be copied to constraints in
95  * subproblem?
96  */
97 };
98 
99 /* copies SCIP to probing SCIP and creates variable hashmap */
100 static
102  SCIP* scip, /**< SCIP data structure */
103  SCIP** probingscip, /**< sub-SCIP data structure */
104  SCIP_HASHMAP** varmapfw, /**< mapping of SCIP variables to sub-SCIP variables */
105  SCIP_Bool copycuts, /**< should all active cuts from cutpool of scip copied to constraints in subscip */
106  SCIP_Bool* success /**< was copying successful? */
107  )
108 {
109  /* check if we are already at the maximal tree depth */
110  if( SCIPgetDepthLimit(scip) <= SCIPgetDepth(scip) )
111  {
112  *success = FALSE;
113  return SCIP_OKAY;
114  }
115 
116  /* initializing the subproblem */
117  SCIP_CALL( SCIPcreate(probingscip) );
118 
119  /* create the variable mapping hash map */
120  SCIP_CALL( SCIPhashmapCreate(varmapfw, SCIPblkmem(*probingscip), SCIPgetNVars(scip)) );
121  *success = FALSE;
122 
123  /* copy SCIP instance */
124  SCIP_CALL( SCIPcopy(scip, *probingscip, *varmapfw, NULL, "feaspump", FALSE, FALSE, TRUE, success) );
125 
126  if( copycuts )
127  {
128  /* copies all active cuts from cutpool of sourcescip to linear constraints in targetscip */
129  SCIP_CALL( SCIPcopyCuts(scip, *probingscip, *varmapfw, NULL, FALSE, NULL) );
130  }
131 
132  return SCIP_OKAY;
133 }
134 
135 /** set appropriate parameters for probing SCIP in FP2 */
136 static
138  SCIP* scip, /**< SCIP data structure */
139  SCIP* probingscip /**< sub-SCIP data structure */
140  )
141 {
142  if( SCIPisParamFixed(probingscip, "heuristics/" HEUR_NAME "/freq") )
143  {
144  SCIPwarningMessage(scip, "unfixing parameter heuristics/" HEUR_NAME "/freq in probingscip of " HEUR_NAME " heuristic to avoid recursive calls\n");
145  SCIP_CALL( SCIPunfixParam(probingscip, "heuristics/" HEUR_NAME "/freq") );
146  }
147  SCIP_CALL( SCIPsetIntParam(probingscip, "heuristics/" HEUR_NAME "/freq", -1) );
148 
149  /* do not abort subproblem on CTRL-C */
150  SCIP_CALL( SCIPsetBoolParam(probingscip, "misc/catchctrlc", FALSE) );
151 
152 #ifndef SCIP_DEBUG
153  /* disable output to console */
154  SCIP_CALL( SCIPsetIntParam(probingscip, "display/verblevel", 0) );
155 #endif
156 
157  /* disable expensive and useless stuff */
158  SCIP_CALL( SCIPsetLongintParam(probingscip, "limits/nodes", 1LL) );
159  if( SCIPisParamFixed(probingscip, "lp/solvefreq") )
160  {
161  SCIPwarningMessage(scip, "unfixing parameter lp/solvefreq in probingscip of " HEUR_NAME " heuristic to speed up propagation\n");
162  SCIP_CALL( SCIPunfixParam(probingscip, "lp/solvefreq") );
163  }
164  SCIP_CALL( SCIPsetIntParam(probingscip, "lp/solvefreq", -1) );
165  SCIP_CALL( SCIPsetBoolParam(probingscip, "conflict/enable", FALSE) );
166  SCIP_CALL( SCIPsetBoolParam(probingscip, "constraints/disableenfops", TRUE) );
167  SCIP_CALL( SCIPsetBoolParam(probingscip, "constraints/knapsack/negatedclique", FALSE) );
170  return SCIP_OKAY;
171 }
172 
173 /** set appropriate parameters for probing SCIP in Stage 3 */
174 static
176  SCIP* scip, /**< SCIP data structure */
177  SCIP* probingscip, /**< sub-SCIP data structure */
178  SCIP_Real timelimit, /**< time limit for Stage3 */
179  SCIP_Real memorylimit /**< memory limit for Stage3 */
180  )
181 {
182  SCIP_CALL( SCIPcopyParamSettings(scip, probingscip) );
183  /* do not abort subproblem on CTRL-C */
184  SCIP_CALL( SCIPsetBoolParam(probingscip, "misc/catchctrlc", FALSE) );
185 
186 #ifndef SCIP_DEBUG
187  /* disable output to console */
188  SCIP_CALL( SCIPsetIntParam(probingscip, "display/verblevel", 0) );
189 #endif
190  /* set limits for the subproblem */
191  SCIP_CALL( SCIPsetLongintParam(probingscip, "limits/nodes", 1000LL) );
192  SCIP_CALL( SCIPsetLongintParam(probingscip, "limits/stallnodes", 100LL) );
193  SCIP_CALL( SCIPsetRealParam(probingscip, "limits/time", timelimit) );
194  SCIP_CALL( SCIPsetRealParam(probingscip, "limits/memory", memorylimit) );
195 
196  /* forbid recursive call of heuristics and separators solving sub-SCIPs */
197  SCIP_CALL( SCIPsetSubscipsOff(probingscip, TRUE) );
198  if( SCIPisParamFixed(probingscip, "heuristics/" HEUR_NAME "/freq") )
199  {
200  SCIPwarningMessage(scip,"unfixing parameter heuristics/" HEUR_NAME "/freq in probingscip of " HEUR_NAME " heuristic to avoid recursive calls\n");
201  SCIP_CALL( SCIPunfixParam(probingscip, "heuristics/" HEUR_NAME "/freq") );
202  }
203  SCIP_CALL( SCIPsetIntParam(probingscip, "heuristics/feaspump/freq", -1) );
204 
205  /* disable heuristics which aim to feasibility instead of optimality */
206  if( !SCIPisParamFixed(probingscip, "heuristics/octane/freq") )
207  {
208  SCIP_CALL( SCIPsetIntParam(probingscip, "heuristics/octane/freq", -1) );
209  }
210  if( !SCIPisParamFixed(probingscip, "heuristics/objpscostdiving/freq") )
211  {
212  SCIP_CALL( SCIPsetIntParam(probingscip, "heuristics/objpscostdiving/freq", -1) );
213  }
214  if( !SCIPisParamFixed(probingscip, "heuristics/rootsoldiving/freq") )
215  {
216  SCIP_CALL( SCIPsetIntParam(probingscip, "heuristics/rootsoldiving/freq", -1) );
217  }
218 
219  /* disable cutting plane separation */
221 
222  /* disable expensive presolving */
224 
225  /* use best estimate node selection */
226  if( SCIPfindNodesel(probingscip, "estimate") != NULL && !SCIPisParamFixed(probingscip, "nodeselection/estimate/stdpriority") )
227  {
228  SCIP_CALL( SCIPsetIntParam(probingscip, "nodeselection/estimate/stdpriority", INT_MAX/4) );
229  }
230 
231  /* use inference branching */
232  if( SCIPfindBranchrule(probingscip, "inference") != NULL && !SCIPisParamFixed(probingscip, "branching/inference/priority") )
233  {
234  SCIP_CALL( SCIPsetIntParam(probingscip, "branching/inference/priority", INT_MAX/4) );
235  }
236 
237  /* disable conflict analysis */
238  if( !SCIPisParamFixed(probingscip, "conflict/useprop") )
239  {
240  SCIP_CALL( SCIPsetBoolParam(probingscip, "conflict/useprop", FALSE) );
241  }
242  if( !SCIPisParamFixed(probingscip, "conflict/useinflp") )
243  {
244  SCIP_CALL( SCIPsetBoolParam(probingscip, "conflict/useinflp", FALSE) );
245  }
246  if( !SCIPisParamFixed(probingscip, "conflict/useboundlp") )
247  {
248  SCIP_CALL( SCIPsetBoolParam(probingscip, "conflict/useboundlp", FALSE) );
249  }
250  if( !SCIPisParamFixed(probingscip, "conflict/usesb") )
251  {
252  SCIP_CALL( SCIPsetBoolParam(probingscip, "conflict/usesb", FALSE) );
253  }
254  if( !SCIPisParamFixed(probingscip, "conflict/usepseudo") )
255  {
256  SCIP_CALL( SCIPsetBoolParam(probingscip, "conflict/usepseudo", FALSE) );
257  }
258 
259  return SCIP_OKAY;
260 }
261 
262 /** checks whether a variable is one of the currently most fractional ones */
263 static
264 void insertFlipCand(
265  SCIP_VAR** mostfracvars, /**< sorted array of the currently most fractional variables */
266  SCIP_Real* mostfracvals, /**< array of their fractionality, decreasingly sorted */
267  int* nflipcands, /**< number of fractional variables already labeled to be flipped*/
268  int maxnflipcands, /**< typically randomized number of maximum amount of variables to flip */
269  SCIP_VAR* var, /**< variable to be checked */
270  SCIP_Real frac /**< fractional value of the variable */
271  )
272 {
273  int i;
274 
275  assert(mostfracvars != NULL);
276  assert(mostfracvals != NULL);
277  assert(nflipcands != NULL);
278 
279  /* instead of the fractional value use the fractionality */
280  if( frac > 0.5 )
281  frac = 1 - frac;
282 
283  /* if there are already enough candidates and the variable is less fractional, return, else reserve the last entry */
284  if( *nflipcands >= maxnflipcands )
285  {
286  if( frac <= mostfracvals[*nflipcands-1] )
287  return;
288  else
289  (*nflipcands)--;
290  }
291 
292  /* shifting var and frac through the (sorted) arrays */
293  for( i = *nflipcands; i > 0 && mostfracvals[i-1] < frac; i-- )
294  {
295  mostfracvars[i] = mostfracvars[i-1];
296  mostfracvals[i] = mostfracvals[i-1];
297  }
298  assert(0 <= i && i <= *nflipcands && *nflipcands < maxnflipcands);
299 
300  /* insert the variable and its fractionality */
301  mostfracvars[i] = var;
302  mostfracvals[i] = frac;
303 
304  /* we've found another candidate */
305  (*nflipcands)++;
306 }
307 
308 /** flips the roundings of the most fractional variables, if a 1-cycle was found */
309 static
311  SCIP* scip, /**< SCIP data structure */
312  SCIP_HEURDATA* heurdata, /**< data of this special heuristic */
313  SCIP_VAR** mostfracvars, /**< sorted array of the currently most fractional variables */
314  int nflipcands, /**< number of variables to flip */
315  SCIP_Real alpha /**< factor how much the original objective is regarded */
316  )
317 {
318  SCIP_VAR* var;
319  SCIP_Real solval;
320  SCIP_Real frac;
321  SCIP_Real newobjcoeff;
322  SCIP_Real orgobjcoeff;
323  int i;
324 
325  /* just flipping the objective coefficients from +1 to -1 and the rounding from floor to ceil */
326  for( i = 0; i < nflipcands; i++ )
327  {
328  var = mostfracvars[i];
329  solval = SCIPvarGetLPSol(var);
330  orgobjcoeff = SCIPvarGetObj(var);
331  frac = SCIPfeasFrac(scip, solval);
332 
333  if( frac > 0.5 )
334  {
335  newobjcoeff = (1.0 - alpha) + alpha * orgobjcoeff;
336  solval = SCIPfeasFloor(scip, solval);
337  }
338  else
339  {
340  newobjcoeff = - (1.0 - alpha) + alpha * orgobjcoeff;
341  solval = SCIPfeasCeil(scip, solval);
342  }
343  /* updating the rounded solution and the objective */
344  SCIP_CALL( SCIPsetSolVal(scip, heurdata->roundedsol, var, solval) );
345  SCIP_CALL( SCIPchgVarObjDive(scip, var, newobjcoeff) );
346  }
347  return SCIP_OKAY;
348 }
349 
350 /** flips the roundings of randomly chosen fractional variables, preferring highly fractional ones,
351  * if a longer cycle was found
352  */
353 static
355  SCIP* scip, /**< SCIP data structure */
356  SCIP_HEURDATA* heurdata, /**< data of this special heuristic */
357  SCIP_VAR** vars, /**< array of all variables */
358  int nbinandintvars, /**< number of general integer and 0-1 variables */
359  SCIP_Real alpha /**< factor how much the original objective is regarded */
360  )
361 {
362  SCIP_VAR* var;
363  SCIP_Real solval;
364  SCIP_Real frac;
365  SCIP_Real newobjcoeff;
366  SCIP_Real orgobjcoeff;
367  SCIP_Real flipprob;
368  int i;
369 
370  /* just flipping the objective coefficients from +1 to -1 and the rounding from floor to ceil */
371  for( i = 0; i < nbinandintvars; i++ )
372  {
373  /* decide arbitrarily whether the variable will be flipped or not */
374  var = vars[i];
375  solval = SCIPvarGetLPSol(var);
376  orgobjcoeff = SCIPvarGetObj(var);
377  frac = SCIPfeasFrac(scip, solval);
378  flipprob = -0.3 + SCIPgetRandomReal(0.0, 1.0, &heurdata->randseed);
379 
380  /* flip, iff the sum of the randomized number and the fractionality is big enough */
381  if( MIN(frac, 1.0-frac) + MAX(flipprob, 0.0) > 0.5 )
382  {
383  if( frac > 0.5 )
384  {
385  newobjcoeff = (1.0 - alpha) + alpha * orgobjcoeff;
386  solval = SCIPfeasFloor(scip, solval);
387  }
388  else
389  {
390  newobjcoeff = - (1.0 - alpha) + alpha * orgobjcoeff;
391  solval = SCIPfeasCeil(scip, solval);
392  }
393  SCIP_CALL( SCIPsetSolVal(scip, heurdata->roundedsol, var, solval) );
394  SCIP_CALL( SCIPchgVarObjDive(scip, var, newobjcoeff) );
395  }
396  }
397 
398  return SCIP_OKAY;
399 }
400 
401 /** create the extra constraint of local branching and add it to subscip */
402 static
404  SCIP* scip, /**< SCIP data structure of the original problem */
405  SCIP* probingscip, /**< SCIP data structure of the subproblem */
406  SCIP_HASHMAP* varmapfw, /**< mapping of SCIP variables to sub-SCIP variables */
407  SCIP_SOL* bestsol, /**< SCIP solution */
408  SCIP_Real neighborhoodsize /**< rhs for LB constraint */
409  )
410 {
411  SCIP_CONS* cons; /* local branching constraint to create */
412  SCIP_VAR** consvars;
413  SCIP_VAR** vars;
414 
415  int nbinvars;
416  int i;
417  SCIP_Real lhs;
418  SCIP_Real rhs;
419  SCIP_Real* consvals;
420  char consname[SCIP_MAXSTRLEN];
421 
422  (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_localbranchcons", SCIPgetProbName(scip));
423 
424  /* get vars data */
425  SCIP_CALL( SCIPgetVarsData(scip, &vars, NULL, &nbinvars, NULL, NULL, NULL) );
426  /* memory allocation */
427  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nbinvars) );
428  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nbinvars) );
429 
430  /* set initial left and right hand sides of local branching constraint */
431  lhs = 0.0;
432  rhs = neighborhoodsize;
433 
434  /* create the distance (to incumbent) function of the binary variables */
435  for( i = 0; i < nbinvars; i++ )
436  {
437  SCIP_Real solval;
438 
439  solval = SCIPgetSolVal(scip, bestsol, vars[i]);
440  assert( SCIPisFeasIntegral(scip,solval) );
441 
442  /* is variable i part of the binary support of closest sol? */
443  if( SCIPisFeasEQ(scip,solval,1.0) )
444  {
445  consvals[i] = -1.0;
446  rhs -= 1.0;
447  lhs -= 1.0;
448  }
449  else
450  consvals[i] = 1.0;
451  consvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, vars[i]);
452  SCIP_CALL( SCIPchgVarObj(probingscip, consvars[i], consvals[i]) );
453  assert( SCIPvarGetType(consvars[i]) == SCIP_VARTYPE_BINARY );
454  }
455 
456  /* creates localbranching constraint and adds it to subscip */
457  SCIP_CALL( SCIPcreateConsLinear(probingscip, &cons, consname, nbinvars, consvars, consvals,
458  lhs, rhs, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) );
459  SCIP_CALL( SCIPaddCons(probingscip, cons) );
460  SCIP_CALL( SCIPreleaseCons(probingscip, &cons) );
461 
462  /* free local memory */
463  SCIPfreeBufferArray(scip, &consvals);
464  SCIPfreeBufferArray(scip, &consvars);
465 
466  return SCIP_OKAY;
467 }
468 
469 /** creates new solutions for the original problem by copying the solutions of the subproblem */
470 static
472  SCIP* scip, /**< original SCIP data structure */
473  SCIP* subscip, /**< SCIP structure of the subproblem */
474  SCIP_HASHMAP* varmapfw, /**< mapping of SCIP variables to sub-SCIP variables */
475  SCIP_HEUR* heur, /**< heuristic structure */
476  SCIP_Bool* success /**< used to store whether new solution was found or not */
477  )
478 {
479  SCIP_VAR** vars; /* the original problem's variables */
480  int nvars;
481  SCIP_SOL** subsols;
482  int nsubsols;
483  SCIP_VAR** subvars;
484  SCIP_Real* subsolvals; /* solution values of the subproblem */
485  SCIP_SOL* newsol; /* solution to be created for the original problem */
486  int i;
487 
488  assert(scip != NULL);
489  assert(subscip != NULL);
490 
491  /* get variables' data */
492  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
493 
494  /* sub-SCIP may have more variables than the number of active (transformed) variables in the main SCIP
495  * since constraint copying may have required the copy of variables that are fixed in the main SCIP
496  */
497  assert(nvars <= SCIPgetNOrigVars(subscip));
498 
499  /* for copying a solution we need an explicit mapping */
500  SCIP_CALL( SCIPallocBufferArray(scip, &subvars, nvars) );
501  for( i = 0; i < nvars; i++ )
502  subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, vars[i]);
503 
504  SCIP_CALL( SCIPallocBufferArray(scip, &subsolvals, nvars) );
505 
506  nsubsols = SCIPgetNSols(subscip);
507  subsols = SCIPgetSols(subscip);
508  *success = FALSE;
509 
510  for( i = 0; i < nsubsols && !(*success); ++i )
511  {
512  /* copy the solution */
513  SCIP_CALL( SCIPgetSolVals(subscip, subsols[i], nvars, subvars, subsolvals) );
514 
515  /* create new solution for the original problem */
516  SCIP_CALL( SCIPcreateSol(scip, &newsol, heur) );
517  SCIP_CALL( SCIPsetSolVals(scip, newsol, nvars, vars, subsolvals) );
518 
519  /* try to add new solution to scip and free it immediately */
520  SCIP_CALL( SCIPtrySolFree(scip, &newsol, FALSE, TRUE, TRUE, TRUE, success) );
521  }
522 
523  SCIPfreeBufferArray(scip, &subvars);
524  SCIPfreeBufferArray(scip, &subsolvals);
525 
526  return SCIP_OKAY;
527 }
528 
529 /** copy method for primal heuristic plugins (called when SCIP copies plugins) */
530 static
531 SCIP_DECL_HEURCOPY(heurCopyFeaspump)
532 {
533  assert(scip != NULL);
534  assert(heur != NULL);
535  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
536 
537  /* call inclusion method of primal heuristic */
539 
540  return SCIP_OKAY;
541 }
542 
543 /** destructor of primal heuristic to free user data (called when SCIP is exiting) */
544 static
545 SCIP_DECL_HEURFREE(heurFreeFeaspump)
546 {
547  SCIP_HEURDATA* heurdata;
548 
549  assert(heur != NULL);
550  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
551  assert(scip != NULL);
552 
553  /* free heuristic data */
554  heurdata = SCIPheurGetData(heur);
555  assert(heurdata != NULL);
556  SCIPfreeMemory(scip, &heurdata);
557  SCIPheurSetData(heur, NULL);
558 
559  return SCIP_OKAY;
560 }
561 
562 
563 /** initialization method of primal heuristic (called after problem was transformed) */
564 static
565 SCIP_DECL_HEURINIT(heurInitFeaspump)
566 {
567  SCIP_HEURDATA* heurdata;
568 
569  assert(heur != NULL);
570  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
571 
572  /* get heuristic data */
573  heurdata = SCIPheurGetData(heur);
574  assert(heurdata != NULL);
575 
576  /* create working solution */
577  SCIP_CALL( SCIPcreateSol(scip, &heurdata->sol, heur) );
578  SCIP_CALL( SCIPcreateSol(scip, &heurdata->roundedsol, heur) );
579 
580  /* initialize data */
581  heurdata->nlpiterations = 0;
582  heurdata->nsuccess = 0;
583  heurdata->randseed = 0;
584 
585  return SCIP_OKAY;
586 }
587 
588 /** deinitialization method of primal heuristic (called before transformed problem is freed) */
589 static
590 SCIP_DECL_HEUREXIT(heurExitFeaspump)
591 {
592  SCIP_HEURDATA* heurdata;
593 
594  assert(heur != NULL);
595  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
596 
597  /* get heuristic data */
598  heurdata = SCIPheurGetData(heur);
599  assert(heurdata != NULL);
600 
601  /* free working solution */
602  SCIP_CALL( SCIPfreeSol(scip, &heurdata->sol) );
603  SCIP_CALL( SCIPfreeSol(scip, &heurdata->roundedsol) );
604 
605  return SCIP_OKAY;
606 }
607 
608 
609 /** solving process initialization method of primal heuristic (called when branch and bound process is about to begin) */
610 static
611 SCIP_DECL_HEURINITSOL(heurInitsolFeaspump)
612 {
613  SCIP_HEURDATA* heurdata;
614 
615  heurdata = SCIPheurGetData(heur);
616  assert(heurdata != NULL);
617 
618  /* if the heuristic is called at the root node, we may want to be called directly after the initial root LP solve */
619  if( heurdata->beforecuts && SCIPheurGetFreqofs(heur) == 0 )
621 
622  return SCIP_OKAY;
623 }
624 
625 
626 /** solving process deinitialization method of primal heuristic (called before branch and bound process data is freed) */
627 static
628 SCIP_DECL_HEUREXITSOL(heurExitsolFeaspump)
629 {
630  /* reset the timing mask to its default value */
633  return SCIP_OKAY;
634 }
635 
636 /** calculates an adjusted maximal number of LP iterations */
637 static
639  SCIP_Longint maxnlpiterations, /**< regular maximal number of LP iterations */
640  SCIP_Longint nsolsfound, /**< total number of solutions found so far by SCIP */
641  int nstallloops /**< current number of stalling rounds */
642  )
643 {
644  if( nstallloops <= 1 )
645  {
646  if( nsolsfound == 0 )
647  return 4*maxnlpiterations;
648  else
649  return 2*maxnlpiterations;
650  }
651  else
652  return maxnlpiterations;
653 }
654 
655 /** execution method of primal heuristic */
656 static
657 SCIP_DECL_HEUREXEC(heurExecFeaspump)
658 {
659  SCIP_HEURDATA* heurdata;
660  SCIP_SOL* tmpsol; /* only used for swapping */
661  SCIP_SOL** lastroundedsols;/* solutions of the last pumping rounds (depending on heurdata->cyclelength) */
662  SCIP_SOL* closestsol; /* rounded solution closest to the LP relaxation: used for stage3 */
663  SCIP_Real* lastalphas; /* alpha values associated to solutions in lastroundedsols */
664 
665  SCIP* probingscip; /* copied SCIP structure, used for round-and-propagate loop of feasibility pump 2.0 */
666  SCIP_HASHMAP* varmapfw; /* mapping of SCIP variables to sub-SCIP variables */
667 
668 
669  SCIP_VAR** vars;
670  SCIP_VAR** pseudocands;
671  SCIP_VAR** tmppseudocands;
672  SCIP_VAR** mostfracvars; /* the 30 most fractional variables, needed to avoid 1-cycles */
673  SCIP_VAR* var;
674 
675  SCIP_Real* mostfracvals; /* the values of the variables above */
676  SCIP_Real newobjcoeff; /* used for changing the objective */
677  SCIP_Real orgobjcoeff; /* used for regarding the original objective */
678  SCIP_Real oldsolval; /* one value of the last solution */
679  SCIP_Real solval; /* one value of the actual solution */
680  SCIP_Real frac; /* the fractional part of the value above */
681  SCIP_Real objfactor; /* factor by which the regard of the objective is decreased in each round, in [0,0.99] */
682  SCIP_Real alpha; /* factor how the original objective is regarded, used for convex combination of two functions */
683  SCIP_Real objnorm; /* Euclidean norm of the objective function, used for scaling */
684  SCIP_Real scalingfactor; /* factor to scale the original objective function with */
685  SCIP_Real mindistance; /* distance of the closest rounded solution from the LP relaxation: used for stage3 */
686 
687  SCIP_Longint nlpiterations; /* number of LP iterations done during one pumping round */
688  SCIP_Longint maxnlpiterations; /* maximum number of LP iterations for this heuristic */
689  SCIP_Longint nsolsfound; /* number of solutions found by this heuristic */
690  SCIP_Longint ncalls; /* number of calls of this heuristic */
691  SCIP_Longint nbestsolsfound; /* current total number of best solution updates in SCIP */
692 
693  SCIP_LPSOLSTAT lpsolstat; /* status of the LP solution */
694 
695  int nvars; /* number of variables */
696  int nbinvars; /* number of 0-1-variables */
697  int nintvars; /* number of integer variables */
698  int nfracs; /* number of fractional variables updated after each pumping round*/
699  int nflipcands; /* how many flipcands (most frac. var.) have been found */
700  int npseudocands;
701  int maxnflipcands; /* maximal number of candidates to flip in the current pumping round */
702  int nloops; /* how many pumping rounds have been made */
703  int maxflips; /* maximum number of flips, if a 1-cycle is found (depending on heurdata->minflips) */
704  int maxloops; /* maximum number of pumping rounds */
705  int nstallloops; /* number of loops without reducing the current best number of factional variables */
706  int maxstallloops; /* maximal number of allowed stalling loops */
707  int bestnfracs; /* best number of fractional variables */
708  int i;
709  int j;
710 
711  SCIP_Bool success;
712  SCIP_Bool lperror;
713  SCIP_Bool* cycles; /* are there short cycles */
714 
715  SCIP_RETCODE retcode;
716 
717  assert(heur != NULL);
718  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
719  assert(scip != NULL);
720  assert(result != NULL);
721  assert(SCIPhasCurrentNodeLP(scip));
722 
723  *result = SCIP_DELAYED;
724 
725  /* do not call heuristic of node was already detected to be infeasible */
726  if( nodeinfeasible )
727  return SCIP_OKAY;
728 
729  /* only call heuristic, if an optimal LP solution is at hand */
731  return SCIP_OKAY;
732 
733  /* only call heuristic, if the LP objective value is smaller than the cutoff bound */
734  if( SCIPisGE(scip, SCIPgetLPObjval(scip), SCIPgetCutoffbound(scip)) )
735  return SCIP_OKAY;
736 
737  /* only call heuristic, if the LP solution is basic (which allows fast resolve in diving) */
738  if( !SCIPisLPSolBasic(scip) )
739  return SCIP_OKAY;
740 
741  *result = SCIP_DIDNOTRUN;
742 
743  /* don't dive two times at the same node */
744  if( SCIPgetLastDivenode(scip) == SCIPgetNNodes(scip) && SCIPgetDepth(scip) > 0 )
745  return SCIP_OKAY;
746 
747  /* only call feaspump once at the root */
748  if( SCIPgetDepth(scip) == 0 && SCIPheurGetNCalls(heur) > 0 )
749  return SCIP_OKAY;
750 
751  /* reset the timing mask to its default value (at the root node it could be different) */
753 
754  /* only call the heuristic before cutting planes if we do not have an incumbent and no pricer exists */
755  if( heurtiming == SCIP_HEURTIMING_DURINGLPLOOP && SCIPgetNSolsFound(scip) > 0 && SCIPgetNPricers(scip) == 0 )
756  return SCIP_OKAY;
757 
758  /* get heuristic's data */
759  heurdata = SCIPheurGetData(heur);
760  assert(heurdata != NULL);
761 
762  /* only apply heuristic, if only a few solutions have been found and no pricer exists */
763  if( heurdata->maxsols >= 0 && SCIPgetNSolsFound(scip) > heurdata->maxsols && SCIPgetNPricers(scip) == 0 )
764  return SCIP_OKAY;
765 
766  /* get all variables of LP and number of fractional variables in LP solution that should be integral */
767  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, &nbinvars, &nintvars, NULL, NULL) );
768  nfracs = SCIPgetNLPBranchCands(scip);
769  assert(0 <= nfracs && nfracs <= nbinvars + nintvars);
770  if( nfracs == 0 )
771  return SCIP_OKAY;
772 
773  /* calculate the maximal number of LP iterations until heuristic is aborted */
774  nlpiterations = SCIPgetNLPIterations(scip);
775  ncalls = SCIPheurGetNCalls(heur);
776  nsolsfound = 10*SCIPheurGetNBestSolsFound(heur) + heurdata->nsuccess;
777  maxnlpiterations = (SCIP_Longint)((1.0 + 10.0*(nsolsfound+1.0)/(ncalls+1.0)) * heurdata->maxlpiterquot * nlpiterations);
778  maxnlpiterations += heurdata->maxlpiterofs;
779 
780  /* don't try to dive, if we took too many LP iterations during diving */
781  if( heurdata->nlpiterations >= maxnlpiterations )
782  return SCIP_OKAY;
783 
784  /* at the first root call, allow more iterations if there is no feasible solution yet */
785  if( SCIPheurGetNCalls(heur) == 0 && SCIPgetNSolsFound(scip) == 0 && SCIPgetDepth(scip) == 0 )
786  maxnlpiterations += nlpiterations;
787 
788  /* allow at least a certain number of LP iterations in this dive */
789  maxnlpiterations = MAX(maxnlpiterations, heurdata->nlpiterations + MINLPITER);
790 
791  /* calculate maximal number of flips and loops */
792  maxflips = 3*heurdata->minflips;
793  maxloops = (heurdata->maxloops == -1 ? INT_MAX : heurdata->maxloops);
794  maxstallloops = (heurdata->maxstallloops == -1 ? INT_MAX : heurdata->maxstallloops);
795 
796  SCIPdebugMessage("executing feasibility pump heuristic, nlpiters=%" SCIP_LONGINT_FORMAT ", maxnlpit:%" SCIP_LONGINT_FORMAT ", maxflips:%d \n",
797  nlpiterations, maxnlpiterations, maxflips);
798 
799  *result = SCIP_DIDNOTFIND;
800 
801  probingscip = NULL;
802  varmapfw = NULL;
803 
804  if( heurdata->usefp20 )
805  {
806  SCIP_CALL( setupProbingSCIP(scip, &probingscip, &varmapfw, heurdata->copycuts, &success) );
807 
808  if( success )
809  {
810  SCIP_CALL( setupSCIPparamsFP2(scip, probingscip) );
811 
812  retcode = SCIPsolve(probingscip);
813 
814  /* errors in solving the subproblem should not kill the overall solving process;
815  * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop. */
816  if( retcode != SCIP_OKAY )
817  {
818 #ifndef NDEBUG
819  SCIP_CALL( retcode );
820 #endif
821  SCIPwarningMessage(scip, "Error while solving subproblem in feaspump heuristic; sub-SCIP terminated with code <%d>\n", retcode);
822 
823  /* free hash map and copied SCIP */
824  SCIPhashmapFree(&varmapfw);
825  SCIP_CALL( SCIPfree(&probingscip) );
826  return SCIP_OKAY;
827  }
828 
829  if( SCIPgetStage(probingscip) != SCIP_STAGE_SOLVING)
830  {
831  SCIP_STATUS probingstatus = SCIPgetStatus(probingscip);
832 
833  if( probingstatus == SCIP_STATUS_OPTIMAL )
834  {
835  assert( SCIPgetNSols(probingscip) > 0 );
836  SCIP_CALL( createNewSols(scip, probingscip, varmapfw, heur, &success) );
837  if( success )
838  *result = SCIP_FOUNDSOL;
839  }
840 
841  /* free hash map and copied SCIP */
842  SCIPhashmapFree(&varmapfw);
843  SCIP_CALL( SCIPfree(&probingscip) );
844  return SCIP_OKAY;
845  }
846  SCIP_CALL( SCIPsetLongintParam(probingscip, "limits/nodes", 2LL) );
847 
848  /* set SCIP into probing mode and create root node of the probing tree */
849  SCIP_CALL( SCIPstartProbing(probingscip) );
850 
851  /* this should always be fulfilled */
852  assert(SCIPgetDepthLimit(probingscip) > SCIPgetDepth(probingscip));
853 
854  SCIP_CALL( SCIPnewProbingNode(probingscip) );
855 
856  SCIPdebugMessage("successfully copied SCIP instance -> feasibility pump 2.0 can be used.\n");
857  }
858  }
859 
860  /* memory allocation */
861  SCIP_CALL( SCIPallocBufferArray(scip, &mostfracvars, maxflips) );
862  SCIP_CALL( SCIPallocBufferArray(scip, &mostfracvals, maxflips) );
863  SCIP_CALL( SCIPallocBufferArray(scip, &lastroundedsols, heurdata->cyclelength) );
864  SCIP_CALL( SCIPallocBufferArray(scip, &lastalphas, heurdata->cyclelength) );
865  SCIP_CALL( SCIPallocBufferArray(scip, &cycles, heurdata->cyclelength) );
866 
867  for( j = 0; j < heurdata->cyclelength; j++ )
868  {
869  SCIP_CALL( SCIPcreateSol(scip, &lastroundedsols[j], heur) );
870  }
871 
872  closestsol = NULL;
873  if( heurdata->stage3 )
874  {
875  SCIP_CALL( SCIPcreateSol(scip, &closestsol, heur) );
876  }
877 
878  /* start diving */
879  SCIP_CALL( SCIPstartDive(scip) );
880 
881  /* lp was solved optimal */
882  lperror = FALSE;
883  lpsolstat = SCIP_LPSOLSTAT_OPTIMAL;
884 
885  /* pumping rounds */
886  nsolsfound = SCIPgetNBestSolsFound(scip);
887  if( heurdata->objfactor == 1.0 )
888  objfactor = MIN(1.0 - 0.1 / (SCIP_Real)(1 + nsolsfound), 0.999);
889  else
890  objfactor = heurdata->objfactor;
891 
892  /* scale distance function and original objective to the same norm */
893  objnorm = SCIPgetObjNorm(scip);
894  objnorm = MAX(objnorm, 1.0);
895  scalingfactor = SQRT((SCIP_Real)(nbinvars + nintvars)) / objnorm;
896 
897  /* data initialization */
898  alpha = heurdata->alpha;
899  nloops = 0;
900  nstallloops = 0;
901  nbestsolsfound = SCIPgetNBestSolsFound(scip);
902  bestnfracs = INT_MAX;
903  mindistance = SCIPinfinity(scip);
904 
905  /* pumping loop */
906  while( nfracs > 0
907  && heurdata->nlpiterations < adjustedMaxNLPIterations(maxnlpiterations, nsolsfound, nstallloops)
908  && nloops < maxloops && nstallloops < maxstallloops
909  && !SCIPisStopped(scip) )
910  {
911  int minimum;
912  SCIP_Real* pseudocandsfrac;
913  SCIP_Longint nlpiterationsleft;
914  int iterlimit;
915 
916  /* decrease convex combination scalar */
917  nloops++;
918  alpha *= objfactor;
919 
920  SCIPdebugMessage("feasibility pump loop %d: %d fractional variables (alpha: %.4f, stall: %d/%d)\n",
921  nloops, nfracs, alpha, nstallloops, maxstallloops);
922 
923  success = FALSE;
924 
925  /* create solution from diving LP and try to round it */
926  SCIP_CALL( SCIPlinkLPSol(scip, heurdata->sol) );
927  SCIP_CALL( SCIProundSol(scip, heurdata->sol, &success) );
928 
929  /* if the rounded solution is feasible and better, add it to SCIP */
930  /*if( success )
931  {
932  SCIPdebugMessage("feasibility pump trying rounded solution\n");
933  SCIP_CALL( SCIPtrySol(scip, heurdata->sol, FALSE, FALSE, FALSE, FALSE, &success) );
934  if( success )
935  *result = SCIP_FOUNDSOL;
936  }*/
937 
938  SCIP_CALL( SCIPlinkLPSol(scip, heurdata->roundedsol) );
939 
940  /* randomly choose maximum number of variables to flip in current pumping round in case of a 1-cycle */
941  maxnflipcands = SCIPgetRandomInt(MIN(nfracs/2+1, heurdata->minflips), MIN(nfracs, maxflips), &heurdata->randseed);
942  nflipcands = 0;
943 
944  /* get all unfixed integer variables */
945  SCIP_CALL( SCIPgetPseudoBranchCands(scip, &tmppseudocands, &npseudocands, NULL) );
946  SCIP_CALL( SCIPduplicateBufferArray(scip, &pseudocands, tmppseudocands, npseudocands) );
947 
948  /* get array of all fractional variables and sort it w.r.t. their fractionalities */
949  if( heurdata->usefp20 )
950  {
951  SCIP_CALL( SCIPallocBufferArray(scip, &pseudocandsfrac, npseudocands) );
952 
953  for( i = 0; i < npseudocands; i++ )
954  {
955  frac = SCIPfeasFrac(scip, SCIPvarGetLPSol(pseudocands[i]));
956  pseudocandsfrac[i] = MIN(frac, 1.0-frac); /* always a number between 0 and 0.5 */
957  if( SCIPvarGetType(pseudocands[i]) == SCIP_VARTYPE_BINARY )
958  pseudocandsfrac[i] -= 10.0; /* binaries always come first */
959  }
960  SCIPsortRealPtr(pseudocandsfrac, (void**)pseudocands, npseudocands);
961  SCIPfreeBufferArray(scip, &pseudocandsfrac);
962 
963  SCIPdebugMessage("iteratively fix and propagate variables\n");
964  }
965 
966  for( i = 0; i < npseudocands; i++ )
967  {
968  SCIP_VAR* probingvar;
969  SCIP_Bool infeasible;
970  SCIP_Longint ndomreds;
971 
972  var = pseudocands[i];
973  orgobjcoeff = SCIPvarGetObj(var);
974 
975  /* round the LP solution */
976  solval = SCIPvarGetLPSol(var);
977  frac = SCIPfeasFrac(scip, solval);
978 
979  solval = SCIPfloor(scip, solval+0.5);
980 
981  /* ensure, that the fixing value is inside the local domains */
982  if( heurdata->usefp20 )
983  {
984  SCIP_Real lb;
985  SCIP_Real ub;
986 
987  probingvar = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, var);
988  lb = SCIPvarGetLbLocal(probingvar);
989  ub = SCIPvarGetUbLocal(probingvar);
990 
991  solval = MAX(solval, lb);
992  solval = MIN(solval, ub);
993 
994  /* fix the variable and propagate the domain change */
995  if( !SCIPisFeasEQ(probingscip, lb, ub) )
996  {
997  assert(SCIPisFeasLE(probingscip, lb, ub));
998  /* SCIP_CALL( SCIPnewProbingNode(probingscip) ); */
999  SCIPdebugMessage("try to fix variable <%s> (domain [%f,%f] to %f\n",SCIPvarGetName(probingvar), lb, ub,
1000  solval);
1001  SCIP_CALL( SCIPfixVarProbing(probingscip, probingvar, solval) );
1002  SCIP_CALL( SCIPpropagateProbing(probingscip, -1, &infeasible, &ndomreds) );
1003  SCIPdebugMessage(" -> reduced %" SCIP_LONGINT_FORMAT " domains\n", ndomreds);
1004 
1005  if( infeasible )
1006  {
1007  SCIPdebugMessage(" -> infeasible!\n");
1008  SCIP_CALL( SCIPbacktrackProbing(probingscip, 0/*SCIPgetProbingDepth(probingscip)-1*/) );
1009  }
1010  }
1011  else
1012  {
1013  SCIPdebugMessage("variable <%s> is already fixed to %f\n",SCIPvarGetName(probingvar), solval);
1014  }
1015  }
1016 
1017  assert(SCIPisFeasLE(scip, SCIPvarGetLbLocal(var), solval) && SCIPisFeasLE(scip, solval, SCIPvarGetUbLocal(var)));
1018  assert(SCIPisIntegral(scip,solval));
1019  SCIP_CALL( SCIPsetSolVal(scip, heurdata->roundedsol, var, solval) );
1020 
1021  /* variables which are already integral, are treated separately */
1022  if( SCIPisFeasZero(scip, frac) )
1023  {
1024  SCIP_Real lb;
1025  SCIP_Real ub;
1026 
1027  /* variables at their bounds should be kept there */
1028  lb = SCIPvarGetLbLocal(var);
1029  ub = SCIPvarGetUbLocal(var);
1030  if( SCIPisFeasEQ(scip, solval, lb) )
1031  newobjcoeff = (1.0 - alpha)/scalingfactor + alpha * orgobjcoeff;
1032  else if( SCIPisFeasEQ(scip, solval, ub) )
1033  newobjcoeff = - (1.0 - alpha)/scalingfactor + alpha * orgobjcoeff;
1034  else
1035  newobjcoeff = alpha * orgobjcoeff;
1036  }
1037  else
1038  {
1039  /* check whether the variable is one of the most fractionals and label if so */
1040  insertFlipCand(mostfracvars, mostfracvals, &nflipcands, maxnflipcands, var, frac);
1041 
1042  if( frac > 0.5 )
1043  newobjcoeff = - (1.0 - alpha)/scalingfactor + alpha * orgobjcoeff;
1044  else
1045  newobjcoeff = (1.0 - alpha)/scalingfactor + alpha * orgobjcoeff;
1046  }
1047 
1048  /* change one coefficient of the objective */
1049  SCIP_CALL( SCIPchgVarObjDive(scip, var, newobjcoeff) );
1050 
1051  }
1052 
1053  if( heurdata->usefp20 )
1054  {
1055  SCIP_CALL( SCIPbacktrackProbing(probingscip, 0) );
1056  }
1057 
1058  /* change objective coefficients for continuous variables */
1059  for( i = nbinvars+nintvars; i < nvars; i++ )
1060  {
1061  SCIP_CALL( SCIPchgVarObjDive(scip, vars[i], alpha * SCIPvarGetObj(vars[i])) );
1062  }
1063 
1064  SCIPfreeBufferArray(scip, &pseudocands);
1065 
1066  /* initialize cycle check */
1067  minimum = MIN(heurdata->cyclelength, nloops-1);
1068  for( j = 0; j < heurdata->cyclelength; j++ )
1069  cycles[j] = (nloops > j+1) && (REALABS(lastalphas[j] - alpha) < heurdata->alphadiff);
1070 
1071  /* check for j-cycles */
1072  for( i = 0; i < nbinvars+nintvars; i++ )
1073  {
1074  solval = SCIPgetSolVal(scip, heurdata->roundedsol, vars[i]);
1075 
1076  /* cycles exist, iff all solution values are equal */
1077  for( j = 0; j < minimum; j++ )
1078  {
1079  oldsolval = SCIPgetSolVal(scip, lastroundedsols[j], vars[i]);
1080  cycles[j] = cycles[j] && SCIPisFeasEQ(scip, solval, oldsolval);
1081  }
1082  }
1083 
1084  /* force to flip variables at random after a couple of pumping rounds,
1085  * or if a new best solution in the current region has been found
1086  */
1087  assert(heurdata->perturbfreq > 0);
1088  if( nloops % heurdata->perturbfreq == 0 || (heurdata->pertsolfound && SCIPgetNBestSolsFound(scip) > nbestsolsfound) )
1089  {
1090  SCIPdebugMessage(" -> random perturbation\n");
1091  SCIP_CALL( handleCycle(scip, heurdata, vars, nintvars+nbinvars, alpha) );
1092  nbestsolsfound = SCIPgetNBestSolsFound(scip);
1093  }
1094  else
1095  {
1096  minimum = MIN(heurdata->cyclelength, nloops-1);
1097 
1098  for( j = 0; j < minimum; j++ )
1099  {
1100  /* if we got the same rounded solution as in some step before, we have to flip some variables */
1101  if( cycles[j] )
1102  {
1103  /* 1-cycles have a special flipping rule (flip most fractional variables) */
1104  if( j == 0 )
1105  {
1106  SCIPdebugMessage(" -> avoiding 1-cycle: flipping %d candidates\n", nflipcands);
1107  SCIP_CALL( handle1Cycle(scip, heurdata, mostfracvars, nflipcands, alpha) );
1108  }
1109  else
1110  {
1111  SCIPdebugMessage(" -> avoiding %d-cycle by random flip\n", j+1);
1112  SCIP_CALL( handleCycle(scip, heurdata, vars, nintvars+nbinvars, alpha) );
1113  }
1114  break;
1115  }
1116  }
1117  }
1118 
1119  /* the LP with the new (distance) objective is solved */
1120  nlpiterations = SCIPgetNLPIterations(scip);
1121  nlpiterationsleft = adjustedMaxNLPIterations(maxnlpiterations, nsolsfound, nstallloops) - heurdata->nlpiterations;
1122  iterlimit = MAX((int)nlpiterationsleft, MINLPITER);
1123  SCIPdebugMessage(" -> solve LP with iteration limit %d\n", iterlimit);
1124 
1125  if( heurdata->stage3 )
1126  {
1127  SCIP_CALL( SCIPunlinkSol(scip, heurdata->roundedsol) );
1128  }
1129 
1130  retcode = SCIPsolveDiveLP(scip, iterlimit, &lperror, NULL);
1131  lpsolstat = SCIPgetLPSolstat(scip);
1132 
1133  /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
1134  * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
1135  */
1136  if( retcode != SCIP_OKAY )
1137  {
1138 #ifndef NDEBUG
1139  if( lpsolstat != SCIP_LPSOLSTAT_UNBOUNDEDRAY )
1140  {
1141  SCIP_CALL( retcode );
1142  }
1143 #endif
1144  SCIPwarningMessage(scip, "Error while solving LP in Feaspump heuristic; LP solve terminated with code <%d>\n", retcode);
1145  SCIPwarningMessage(scip, "This does not affect the remaining solution procedure --> continue\n");
1146  }
1147 
1148  /* update iteration count */
1149  heurdata->nlpiterations += SCIPgetNLPIterations(scip) - nlpiterations;
1150  SCIPdebugMessage(" -> number of iterations: %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", lperror=%u, lpsolstat=%d\n",
1151  heurdata->nlpiterations, adjustedMaxNLPIterations(maxnlpiterations, nsolsfound, nstallloops), lperror, lpsolstat);
1152 
1153  /* check whether LP was solved optimal */
1154  if( lperror || lpsolstat != SCIP_LPSOLSTAT_OPTIMAL )
1155  break;
1156 
1157  if( heurdata->stage3 )
1158  {
1159  SCIP_Real distance; /* distance of the current rounded solution from the LP solution */
1160 
1161  assert(closestsol != NULL);
1162 
1163  /* calculate distance */
1164  distance = 0.0;
1165  for( i = 0; i < nbinvars+nintvars; i++ )
1166  {
1167  SCIP_Real roundedval;
1168  SCIP_Real lpval;
1169 
1170  roundedval = SCIPgetSolVal(scip, heurdata->roundedsol, vars[i]);
1171  lpval = SCIPvarGetLPSol(vars[i]);
1172  distance += REALABS(roundedval - lpval);
1173  }
1174 
1175  /* copy solution and update minimum distance */
1176  if( SCIPisLT(scip, distance, mindistance) )
1177  {
1178  for( i = 0; i < nbinvars+nintvars; i++ )
1179  {
1180  assert(SCIPisIntegral(scip,SCIPgetSolVal(scip, heurdata->roundedsol, vars[i])));
1181  SCIP_CALL( SCIPsetSolVal(scip, closestsol, vars[i], SCIPgetSolVal(scip, heurdata->roundedsol, vars[i])) );
1182  }
1183  mindistance = distance;
1184  }
1185  }
1186 
1187  /* swap the last solutions */
1188  SCIP_CALL( SCIPunlinkSol(scip, heurdata->roundedsol) );
1189  tmpsol = lastroundedsols[heurdata->cyclelength-1];
1190  for( j = heurdata->cyclelength-1; j > 0; j-- )
1191  {
1192  lastroundedsols[j] = lastroundedsols[j-1];
1193  lastalphas[j] = lastalphas[j-1];
1194  }
1195  lastroundedsols[0] = heurdata->roundedsol;
1196  lastalphas[0] = alpha;
1197  heurdata->roundedsol = tmpsol;
1198 
1199  /* check for improvement in number of fractionals */
1200  nfracs = SCIPgetNLPBranchCands(scip);
1201  if( nfracs < bestnfracs )
1202  {
1203  bestnfracs = nfracs;
1204  nstallloops = 0;
1205  }
1206  else
1207  nstallloops++;
1208 
1209  SCIPdebugMessage(" -> loop finished: %d fractional variables (stall: %d/%d, iterations: %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ")\n",
1210  nfracs, nstallloops, maxstallloops, heurdata->nlpiterations, adjustedMaxNLPIterations(maxnlpiterations, nsolsfound, nstallloops));
1211  }
1212 
1213  /* try final solution, if no more fractional variables are left */
1214  if( nfracs == 0 && !lperror && lpsolstat == SCIP_LPSOLSTAT_OPTIMAL )
1215  {
1216  success = FALSE;
1217 
1218  SCIP_CALL( SCIPlinkLPSol(scip, heurdata->sol) );
1219  SCIPdebugMessage("feasibility pump found solution (%d fractional variables)\n", nfracs);
1220  SCIP_CALL( SCIPtrySol(scip, heurdata->sol, FALSE, FALSE, FALSE, FALSE, &success) );
1221  if( success )
1222  *result = SCIP_FOUNDSOL;
1223  }
1224 
1225  /* end diving */
1226  SCIP_CALL( SCIPendDive(scip) );
1227 
1228  /* end probing in order to be able to apply stage 3 */
1229  if( heurdata->usefp20 )
1230  {
1231  SCIP_CALL( SCIPendProbing(probingscip) );
1232  }
1233 
1234  /*if( heurdata->usefp20 )
1235  {
1236  SCIP_CALL( SCIPprintStatistics(probingscip, NULL) );
1237  }*/
1238 
1239  /* only do stage 3 if we have not found a solution yet */
1240  /* only do stage 3 if the distance of the closest infeasible solution to the polyhedron is below a certain threshold */
1241  if( heurdata->stage3 && (*result != SCIP_FOUNDSOL) && SCIPisLE(scip, mindistance, (SCIP_Real) heurdata->neighborhoodsize) )
1242  {
1243  /* setup some parameters for the sub-SCIP */
1244  SCIP_Real timelimit;
1245  SCIP_Real memorylimit;
1246 
1247  assert(closestsol != NULL);
1248  assert(!SCIPisInfinity(scip, mindistance) || nloops == 0);
1249 
1250  /* if we do not use feasibility pump 2.0, we have not created a copied SCIP instance yet */
1251  if( heurdata->usefp20 )
1252  {
1253  assert(probingscip != NULL);
1254  SCIP_CALL( SCIPfreeTransform(probingscip) );
1255  }
1256  else
1257  {
1258  assert(probingscip == NULL);
1259  SCIP_CALL( setupProbingSCIP(scip, &probingscip, &varmapfw, heurdata->copycuts, &success) );
1260  }
1261 
1262  /* check whether there is enough time and memory left */
1263  SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
1264  if( !SCIPisInfinity(scip, timelimit) )
1265  timelimit -= SCIPgetSolvingTime(scip);
1266  SCIP_CALL( SCIPgetRealParam(scip, "limits/memory", &memorylimit) );
1267 
1268  /* substract the memory already used by the main SCIP and the estimated memory usage of external software */
1269  if( !SCIPisInfinity(scip, memorylimit) )
1270  {
1271  memorylimit -= SCIPgetMemUsed(scip)/1048576.0;
1272  memorylimit -= SCIPgetMemExternEstim(scip)/1048576.0;
1273  }
1274 
1275  /* abort if no time is left or not enough memory to create a copy of SCIP, including external memory usage */
1276  if( timelimit > 0.0 && memorylimit > 2.0*SCIPgetMemExternEstim(scip)/1048576.0 )
1277  {
1278  SCIP_CALL( setupSCIPparamsStage3(scip, probingscip, timelimit, memorylimit) );
1279 
1280  /* the neighborhood size is double the distance plus another ten percent */
1281  mindistance = SCIPceil(scip, 2.2*mindistance);
1282 
1283  SCIP_CALL( addLocalBranchingConstraint(scip, probingscip, varmapfw, closestsol, mindistance) );
1284 
1285  /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
1286  * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
1287  */
1288 #ifdef NDEBUG
1289  retcode = SCIPsolve(probingscip);
1290  if( retcode != SCIP_OKAY )
1291  {
1292  SCIPwarningMessage(scip, "Error while solving sub-SCIP in stage 3 of feasibility pump heuristic; sub-SCIP terminated with code <%d>\n",
1293  retcode);
1294  }
1295 #else
1296  SCIP_CALL( SCIPsolve(probingscip) );
1297 #endif
1298  /* check, whether a solution was found */
1299  if( SCIPgetNSols(probingscip) > 0 )
1300  {
1301  success = FALSE;
1302  SCIP_CALL( createNewSols(scip, probingscip, varmapfw, heur, &success) );
1303  if( success )
1304  *result = SCIP_FOUNDSOL;
1305  }
1306  }
1307  }
1308 
1309  if( *result == SCIP_FOUNDSOL )
1310  heurdata->nsuccess++;
1311 
1312  /* free hash map and copied SCIP */
1313  if( varmapfw != NULL )
1314  SCIPhashmapFree(&varmapfw);
1315 
1316  if( probingscip != NULL )
1317  {
1318  SCIP_CALL( SCIPfree(&probingscip) );
1319  }
1320 
1321  if( heurdata->stage3 )
1322  {
1323  SCIP_CALL( SCIPfreeSol(scip, &closestsol) );
1324  }
1325 
1326  /* free memory */
1327  for( j = 0; j < heurdata->cyclelength; j++ )
1328  {
1329  SCIP_CALL( SCIPfreeSol(scip, &lastroundedsols[j]) );
1330  }
1331 
1332  SCIPfreeBufferArray(scip, &cycles);
1333  SCIPfreeBufferArray(scip, &lastalphas);
1334  SCIPfreeBufferArray(scip, &lastroundedsols);
1335  SCIPfreeBufferArray(scip, &mostfracvals);
1336  SCIPfreeBufferArray(scip, &mostfracvars);
1337 
1338  SCIPdebugMessage("feasibility pump finished [%d iterations done].\n", nloops);
1339 
1340 #ifdef SCIP_STATISTIC
1341  if( nfracs == 0 )
1342  {
1343  double objval;
1344  double primalBound;
1345 
1346  objval = SCIPgetSolOrigObj(scip, heurdata->sol);
1347  primalBound = SCIPgetPrimalbound(scip);
1348  SCIPstatisticMessage("feasibility pump found: 1, objval: %f, iterations: %d, primal bound: %f\n", objval, nloops, primalBound);
1349  }
1350  else
1351  {
1352  double primalBound;
1353 
1354  primalBound = SCIPgetPrimalbound(scip);
1355  SCIPstatisticMessage("feasibility pump found: 0, objval: +inf, iterations: %d, primal bound: %f\n", nloops, primalBound);
1356  }
1357 
1358 #endif /* SCIP_STATISTIC */
1359 
1360  return SCIP_OKAY;
1361 }
1362 
1363 
1364 /*
1365  * primal heuristic specific interface methods
1366  */
1367 
1368 /** creates the feaspump primal heuristic and includes it in SCIP */
1370  SCIP* scip /**< SCIP data structure */
1371  )
1372 {
1373  SCIP_HEURDATA* heurdata;
1374  SCIP_HEUR* heur;
1375 
1376  /* create Feaspump primal heuristic data */
1377  SCIP_CALL( SCIPallocMemory(scip, &heurdata) );
1378 
1379  /* include primal heuristic */
1380  SCIP_CALL( SCIPincludeHeurBasic(scip, &heur,
1382  HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecFeaspump, heurdata) );
1383 
1384  assert(heur != NULL);
1385 
1386  /* set non-NULL pointers to callback methods */
1387  SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyFeaspump) );
1388  SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeFeaspump) );
1389  SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitFeaspump) );
1390  SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitFeaspump) );
1391  SCIP_CALL( SCIPsetHeurInitsol(scip, heur, heurInitsolFeaspump) );
1392  SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolFeaspump) );
1393 
1394  /* add feaspump primal heuristic parameters */
1396  "heuristics/" HEUR_NAME "/maxlpiterquot",
1397  "maximal fraction of diving LP iterations compared to node LP iterations",
1398  &heurdata->maxlpiterquot, FALSE, DEFAULT_MAXLPITERQUOT, 0.0, SCIP_REAL_MAX, NULL, NULL) );
1400  "heuristics/" HEUR_NAME "/objfactor",
1401  "factor by which the regard of the objective is decreased in each round, 1.0 for dynamic",
1402  &heurdata->objfactor, FALSE, DEFAULT_OBJFACTOR, 0.0, 1.0, NULL, NULL) );
1404  "heuristics/" HEUR_NAME "/alpha",
1405  "initial weight of the objective function in the convex combination",
1406  &heurdata->alpha, FALSE, DEFAULT_ALPHA, 0.0, 1.0, NULL, NULL) );
1408  "heuristics/" HEUR_NAME "/alphadiff",
1409  "threshold difference for the convex parameter to perform perturbation",
1410  &heurdata->alphadiff, FALSE, DEFAULT_ALPHADIFF, 0.0, 1.0, NULL, NULL) );
1411 
1412  SCIP_CALL( SCIPaddIntParam(scip,
1413  "heuristics/" HEUR_NAME "/maxlpiterofs",
1414  "additional number of allowed LP iterations",
1415  &heurdata->maxlpiterofs, FALSE, DEFAULT_MAXLPITEROFS, 0, INT_MAX, NULL, NULL) );
1416  SCIP_CALL( SCIPaddIntParam(scip,
1417  "heuristics/" HEUR_NAME "/maxsols",
1418  "total number of feasible solutions found up to which heuristic is called (-1: no limit)",
1419  &heurdata->maxsols, TRUE, DEFAULT_MAXSOLS, -1, INT_MAX, NULL, NULL) );
1420  SCIP_CALL( SCIPaddIntParam(scip,
1421  "heuristics/" HEUR_NAME "/maxloops",
1422  "maximal number of pumping loops (-1: no limit)",
1423  &heurdata->maxloops, TRUE, DEFAULT_MAXLOOPS, -1, INT_MAX, NULL, NULL) );
1424  SCIP_CALL( SCIPaddIntParam(scip,
1425  "heuristics/" HEUR_NAME "/maxstallloops",
1426  "maximal number of pumping rounds without fractionality improvement (-1: no limit)",
1427  &heurdata->maxstallloops, TRUE, DEFAULT_MAXSTALLLOOPS, -1, INT_MAX, NULL, NULL) );
1428  SCIP_CALL( SCIPaddIntParam(scip,
1429  "heuristics/" HEUR_NAME "/minflips",
1430  "minimum number of random variables to flip, if a 1-cycle is encountered",
1431  &heurdata->minflips, TRUE, DEFAULT_MINFLIPS, 1, INT_MAX, NULL, NULL) );
1432  SCIP_CALL( SCIPaddIntParam(scip,
1433  "heuristics/" HEUR_NAME "/cyclelength",
1434  "maximum length of cycles to be checked explicitly in each round",
1435  &heurdata->cyclelength, TRUE, DEFAULT_CYCLELENGTH, 1, 100, NULL, NULL) );
1436  SCIP_CALL( SCIPaddIntParam(scip,
1437  "heuristics/" HEUR_NAME "/perturbfreq",
1438  "number of iterations until a random perturbation is forced",
1439  &heurdata->perturbfreq, TRUE, DEFAULT_PERTURBFREQ, 1, INT_MAX, NULL, NULL) );
1440  SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/neighborhoodsize",
1441  "radius (using Manhattan metric) of the neighborhood to be searched in stage 3",
1442  &heurdata->neighborhoodsize, FALSE, DEFAULT_NEIGHBORHOODSIZE, 1, INT_MAX, NULL, NULL) );
1443 
1445  "heuristics/" HEUR_NAME "/beforecuts",
1446  "should the feasibility pump be called at root node before cut separation?",
1447  &heurdata->beforecuts, FALSE, DEFAULT_BEFORECUTS, NULL, NULL) );
1449  "heuristics/" HEUR_NAME "/usefp20",
1450  "should an iterative round-and-propagate scheme be used to find the integral points?",
1451  &heurdata->usefp20, FALSE, DEFAULT_USEFP20, NULL, NULL) );
1453  "heuristics/" HEUR_NAME "/pertsolfound",
1454  "should a random perturbation be performed if a feasible solution was found?",
1455  &heurdata->pertsolfound, FALSE, DEFAULT_PERTSOLFOUND, NULL, NULL) );
1457  "heuristics/" HEUR_NAME "/stage3",
1458  "should we solve a local branching sub-MIP if no solution could be found?",
1459  &heurdata->stage3, FALSE, DEFAULT_STAGE3, NULL, NULL) );
1460  SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/copycuts",
1461  "should all active cuts from cutpool be copied to constraints in subproblem?",
1462  &heurdata->copycuts, TRUE, DEFAULT_COPYCUTS, NULL, NULL) );
1463 
1464  return SCIP_OKAY;
1465 }
SCIP_RETCODE SCIPsetHeurInitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINITSOL((*heurinitsol)))
Definition: scip.c:7361
SCIP_RETCODE SCIPunlinkSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:34812
int SCIPgetNLPBranchCands(SCIP *scip)
Definition: scip.c:33158
#define DEFAULT_NEIGHBORHOODSIZE
Definition: heur_feaspump.c:60
#define SCIP_HEURTIMING_DURINGLPLOOP
Definition: type_timing.h:69
int SCIPgetNVars(SCIP *scip)
Definition: scip.c:10698
#define SCIPallocMemory(scip, ptr)
Definition: scip.h:20526
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16443
#define DEFAULT_MAXSOLS
Definition: heur_feaspump.c:43
SCIP_STATUS SCIPgetStatus(SCIP *scip)
Definition: scip.c:908
#define HEUR_NAME
Definition: heur_feaspump.c:31
static SCIP_DECL_HEURINIT(heurInitFeaspump)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
Definition: scip.c:41648
#define HEUR_FREQOFS
Definition: heur_feaspump.c:36
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition: heur.c:1147
SCIP_Longint SCIPheurGetNCalls(SCIP_HEUR *heur)
Definition: heur.c:1273
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
Definition: scip.c:7297
SCIP_RETCODE SCIPbacktrackProbing(SCIP *scip, int probingdepth)
Definition: scip.c:32250
SCIP_Real SCIPgetObjNorm(SCIP *scip)
Definition: scip.c:10351
#define DEFAULT_ALPHA
Definition: heur_feaspump.c:54
#define DEFAULT_CYCLELENGTH
Definition: heur_feaspump.c:49
int SCIPgetNPricers(SCIP *scip)
Definition: scip.c:5006
#define DEFAULT_MAXLPITEROFS
Definition: heur_feaspump.c:42
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip.c:1248
static SCIP_RETCODE addLocalBranchingConstraint(SCIP *scip, SCIP *probingscip, SCIP_HASHMAP *varmapfw, SCIP_SOL *bestsol, SCIP_Real neighborhoodsize)
static SCIP_DECL_HEUREXITSOL(heurExitsolFeaspump)
SCIP_Longint SCIPgetNLPIterations(SCIP *scip)
Definition: scip.c:37454
#define SCIP_MAXSTRLEN
Definition: def.h:201
#define NULL
Definition: lpi_spx.cpp:130
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17113
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip.c:1125
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
Definition: scip.c:42032
SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
Definition: scip.c:34843
SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, unsigned int timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
Definition: scip.c:7252
SCIP_RETCODE SCIPunfixParam(SCIP *scip, const char *name)
Definition: scip.c:3875
SCIP_RETCODE SCIPpropagateProbing(SCIP *scip, int maxproprounds, SCIP_Bool *cutoff, SCIP_Longint *ndomredsfound)
Definition: scip.c:32552
#define FALSE
Definition: def.h:56
SCIP_Real SCIPgetSolvingTime(SCIP *scip)
Definition: scip.c:41009
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:2057
SCIP_RETCODE SCIPsetLongintParam(SCIP *scip, const char *name, SCIP_Longint value)
Definition: scip.c:4046
#define HEUR_FREQ
Definition: heur_feaspump.c:35
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:8174
#define TRUE
Definition: def.h:55
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
#define SCIPstatisticMessage
Definition: pub_message.h:104
#define SCIP_CALL(x)
Definition: def.h:266
#define DEFAULT_COPYCUTS
Definition: heur_feaspump.c:61
SCIP_RETCODE SCIPtrySolFree(SCIP *scip, SCIP_SOL **sol, SCIP_Bool printreason, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition: scip.c:36299
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
Definition: scip.c:41972
SCIP_RETCODE SCIPsetRealParam(SCIP *scip, const char *name, SCIP_Real value)
Definition: scip.c:4109
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip.c:19590
struct SCIP_HeurData SCIP_HEURDATA
Definition: type_heur.h:51
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
Definition: scip.c:42008
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
Definition: scip.c:38561
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip.c:26439
SCIP_RETCODE SCIPfreeTransform(SCIP *scip)
Definition: scip.c:15373
#define SCIPdebugMessage
Definition: pub_message.h:77
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip.c:34983
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:16905
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:2116
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition: type_lp.h:42
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip.c:24949
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition: scip.c:26482
SCIP_RETCODE SCIPstartDive(SCIP *scip)
Definition: scip.c:31575
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
Definition: scip.c:42044
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:35066
SCIP_RETCODE SCIPcopyCuts(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, int *ncutsadded)
Definition: scip.c:2883
int SCIPgetNSols(SCIP *scip)
Definition: scip.c:35668
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.c:3547
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.c:3573
int SCIPgetNOrigVars(SCIP *scip)
Definition: scip.c:11138
#define DEFAULT_MAXSTALLLOOPS
Definition: heur_feaspump.c:47
static SCIP_RETCODE setupSCIPparamsStage3(SCIP *scip, SCIP *probingscip, SCIP_Real timelimit, SCIP_Real memorylimit)
#define MINLPITER
Definition: heur_feaspump.c:67
#define SCIPfreeMemory(scip, ptr)
Definition: scip.h:20542
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41585
SCIP_RETCODE SCIPcopyParamSettings(SCIP *sourcescip, SCIP *targetscip)
Definition: scip.c:3164
#define HEUR_USESSUBSCIP
Definition: heur_feaspump.c:39
SCIP_RETCODE SCIPincludeHeurFeaspump(SCIP *scip)
SCIP_RETCODE SCIPcopy(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, const char *suffix, SCIP_Bool global, SCIP_Bool enablepricing, SCIP_Bool passmessagehdlr, SCIP_Bool *valid)
Definition: scip.c:3254
#define HEUR_DESC
Definition: heur_feaspump.c:32
#define DEFAULT_ALPHADIFF
Definition: heur_feaspump.c:55
SCIP_RETCODE SCIPchgVarObjDive(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip.c:31699
static SCIP_DECL_HEURFREE(heurFreeFeaspump)
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41598
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip.c:34002
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip.c:41353
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41907
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
Definition: scip.c:41758
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:2075
SCIP_RETCODE SCIPgetPseudoBranchCands(SCIP *scip, SCIP_VAR ***pseudocands, int *npseudocands, int *npriopseudocands)
Definition: scip.c:33464
SCIP_RETCODE SCIPsetSeparating(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition: scip.c:4457
#define DEFAULT_STAGE3
Definition: heur_feaspump.c:59
SCIP_RETCODE SCIPgetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip.c:35020
SCIP_Real SCIPinfinity(SCIP *scip)
Definition: scip.c:41637
void SCIPheurSetTimingmask(SCIP_HEUR *heur, SCIP_HEURTIMING timingmask)
Definition: heur.c:1187
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
Definition: scip.c:26354
static SCIP_DECL_HEURCOPY(heurCopyFeaspump)
SCIP_RETCODE SCIPfree(SCIP **scip)
Definition: scip.c:766
SCIP_SOL ** SCIPgetSols(SCIP *scip)
Definition: scip.c:35717
#define DEFAULT_BEFORECUTS
Definition: heur_feaspump.c:56
SCIP_Longint SCIPgetLastDivenode(SCIP *scip)
Definition: scip.c:32067
int SCIPgetDepthLimit(SCIP *scip)
Definition: scip.c:38190
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition: heur.c:1068
#define DEFAULT_OBJFACTOR
Definition: heur_feaspump.c:51
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17123
#define DEFAULT_MINFLIPS
Definition: heur_feaspump.c:48
#define SCIP_Bool
Definition: def.h:53
SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
Definition: scip.c:4001
enum SCIP_Status SCIP_STATUS
Definition: type_stat.h:57
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip.c:801
SCIP_Bool SCIPisParamFixed(SCIP *scip, const char *name)
Definition: scip.c:3709
#define DEFAULT_MAXLOOPS
Definition: heur_feaspump.c:46
SCIP_RETCODE SCIPsetSubscipsOff(SCIP *scip, SCIP_Bool quiet)
Definition: scip.c:4382
#define MAX(x, y)
Definition: tclique_def.h:75
Objective Feasibility Pump 2.0.
SCIP_Longint SCIPgetMemUsed(SCIP *scip)
Definition: scip.c:41396
SCIP_RETCODE SCIPfixVarProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval)
Definition: scip.c:32415
#define HEUR_PRIORITY
Definition: heur_feaspump.c:34
SCIP_RETCODE SCIPstartProbing(SCIP *scip)
Definition: scip.c:32153
SCIP_RETCODE SCIPsetHeurExitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXITSOL((*heurexitsol)))
Definition: scip.c:7377
SCIP_RETCODE SCIPendProbing(SCIP *scip)
Definition: scip.c:32285
static SCIP_RETCODE handle1Cycle(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_VAR **mostfracvars, int nflipcands, SCIP_Real alpha)
SCIP_RETCODE SCIPsetPresolving(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition: scip.c:4431
Constraint handler for linear constraints in their most general form, .
static SCIP_DECL_HEUREXEC(heurExecFeaspump)
int SCIPgetDepth(SCIP *scip)
Definition: scip.c:38140
SCIP_RETCODE SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:34648
static SCIP_RETCODE handleCycle(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_VAR **vars, int nbinandintvars, SCIP_Real alpha)
static SCIP_DECL_HEUREXIT(heurExitFeaspump)
SCIP_RETCODE SCIPsetHeurExit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXIT((*heurexit)))
Definition: scip.c:7345
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41624
int SCIPgetRandomInt(int minrandval, int maxrandval, unsigned int *seedp)
Definition: misc.c:7700
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINIT((*heurinit)))
Definition: scip.c:7329
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
Definition: var.c:17431
#define SCIP_REAL_MAX
Definition: def.h:128
SCIP_Real SCIPgetRandomReal(SCIP_Real minrandval, SCIP_Real maxrandval, unsigned int *seedp)
Definition: misc.c:7719
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:11477
SCIP_RETCODE SCIPsolve(SCIP *scip)
Definition: scip.c:14503
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:16608
SCIP_RETCODE SCIPsetHeuristics(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition: scip.c:4405
static void insertFlipCand(SCIP_VAR **mostfracvars, SCIP_Real *mostfracvals, int *nflipcands, int maxnflipcands, SCIP_VAR *var, SCIP_Real frac)
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
Definition: scip.c:41770
SCIP_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
Definition: heur.c:1293
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:20585
SCIP_RETCODE SCIPcreate(SCIP **scip)
Definition: scip.c:692
#define REALABS(x)
Definition: def.h:151
SCIP_Longint SCIPgetNSolsFound(SCIP *scip)
Definition: scip.c:38746
SCIP_RETCODE SCIPendDive(SCIP *scip)
Definition: scip.c:31618
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
Definition: scip.c:41721
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_Real SCIPgetPrimalbound(SCIP *scip)
Definition: scip.c:38510
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip.h:20593
#define DEFAULT_PERTURBFREQ
Definition: heur_feaspump.c:50
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41933
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
Definition: scip.c:7313
SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
Definition: scip.c:8436
#define SCIP_Real
Definition: def.h:127
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
Definition: scip.c:32190
#define DEFAULT_PERTSOLFOUND
Definition: heur_feaspump.c:58
#define MIN(x, y)
Definition: memory.c:67
#define DEFAULT_MAXLPITERQUOT
Definition: heur_feaspump.c:41
#define HEUR_MAXDEPTH
Definition: heur_feaspump.c:37
const char * SCIPgetProbName(SCIP *scip)
Definition: scip.c:9941
#define SCIP_Longint
Definition: def.h:112
void SCIPsortRealPtr(SCIP_Real *realarray, void **ptrarray, int len)
SCIP_RETCODE SCIPsetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip.c:34885
SCIP_RETCODE SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
Definition: scip.c:3938
SCIP_Real SCIPfeasFrac(SCIP *scip, SCIP_Real val)
Definition: scip.c:42068
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition: heur.c:1058
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition: scip.c:10572
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:20597
SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
Definition: scip.c:3797
SCIP_Bool SCIPisLPSolBasic(SCIP *scip)
Definition: scip.c:26847
#define DEFAULT_USEFP20
Definition: heur_feaspump.c:57
SCIP_NODESEL * SCIPfindNodesel(SCIP *scip, const char *name)
Definition: scip.c:8124
static SCIP_DECL_HEURINITSOL(heurInitsolFeaspump)
#define HEUR_DISPCHAR
Definition: heur_feaspump.c:33
SCIP_RETCODE SCIPsolveDiveLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition: scip.c:31999
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.c:3629
static SCIP_RETCODE setupSCIPparamsFP2(SCIP *scip, SCIP *probingscip)
static SCIP_Longint adjustedMaxNLPIterations(SCIP_Longint maxnlpiterations, SCIP_Longint nsolsfound, int nstallloops)
default SCIP plugins
static SCIP_RETCODE createNewSols(SCIP *scip, SCIP *subscip, SCIP_HASHMAP *varmapfw, SCIP_HEUR *heur, SCIP_Bool *success)
SCIP_RETCODE SCIPtrySol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition: scip.c:36217
static SCIP_RETCODE setupProbingSCIP(SCIP *scip, SCIP **probingscip, SCIP_HASHMAP **varmapfw, SCIP_Bool copycuts, SCIP_Bool *success)
SCIP_Longint SCIPgetNNodes(SCIP *scip)
Definition: scip.c:37372
#define HEUR_TIMING
Definition: heur_feaspump.c:38
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip.c:34607
SCIP_Longint SCIPgetNBestSolsFound(SCIP *scip)
Definition: scip.c:38794
SCIP_Longint SCIPgetMemExternEstim(SCIP *scip)
Definition: scip.c:41409
int SCIPheurGetFreqofs(SCIP_HEUR *heur)
Definition: heur.c:1253
SCIP_RETCODE SCIProundSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
Definition: scip.c:35909