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-2026 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file heur_feaspump.c
    26 * @ingroup DEFPLUGINS_HEUR
    27 * @brief Objective Feasibility Pump 2.0
    28 * @author Timo Berthold
    29 * @author Domenico Salvagnin
    30 */
    31
    32/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    33
    35#include "scip/cons_linear.h"
    36#include "scip/heur_feaspump.h"
    37#include "scip/pub_heur.h"
    38#include "scip/pub_message.h"
    39#include "scip/pub_misc.h"
    40#include "scip/pub_misc_sort.h"
    41#include "scip/pub_var.h"
    42#include "scip/scip_branch.h"
    43#include "scip/scip_cons.h"
    44#include "scip/scip_copy.h"
    45#include "scip/scip_exact.h"
    46#include "scip/scip_general.h"
    47#include "scip/scip_heur.h"
    48#include "scip/scip_lp.h"
    49#include "scip/scip_mem.h"
    50#include "scip/scip_message.h"
    51#include "scip/scip_nodesel.h"
    52#include "scip/scip_numerics.h"
    53#include "scip/scip_param.h"
    54#include "scip/scip_pricer.h"
    55#include "scip/scip_prob.h"
    56#include "scip/scip_probing.h"
    58#include "scip/scip_sol.h"
    59#include "scip/scip_solve.h"
    61#include "scip/scip_tree.h"
    62#include "scip/scip_var.h"
    63
    64
    65#define HEUR_NAME "feaspump"
    66#define HEUR_DESC "objective feasibility pump 2.0"
    67#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_OBJDIVING
    68#define HEUR_PRIORITY -1000000
    69#define HEUR_FREQ 20
    70#define HEUR_FREQOFS 0
    71#define HEUR_MAXDEPTH -1
    72#define HEUR_TIMING SCIP_HEURTIMING_AFTERLPPLUNGE
    73#define HEUR_USESSUBSCIP FALSE /**< does the heuristic use a secondary SCIP instance? */
    74
    75#define DEFAULT_MAXLPITERQUOT 0.05 /**< maximal fraction of diving LP iterations compared to node LP iterations */
    76#define DEFAULT_MAXLPITEROFS 1000 /**< additional number of allowed LP iterations */
    77#define DEFAULT_MAXSOLS 10 /**< total number of feasible solutions found up to which heuristic is called
    78 * (-1: no limit) */
    79#define DEFAULT_MAXLOOPS 10000 /**< maximal number of pumping rounds (-1: no limit) */
    80#define DEFAULT_MAXSTALLLOOPS 10 /**< maximal number of pumping rounds without fractionality improvement (-1: no limit) */
    81#define DEFAULT_MINFLIPS 10 /**< minimum number of random variables to flip, if a 1-cycle is encountered */
    82#define DEFAULT_CYCLELENGTH 3 /**< maximum length of cycles to be checked explicitly in each round */
    83#define DEFAULT_PERTURBFREQ 100 /**< number of iterations until a random perturbation is forced */
    84#define DEFAULT_OBJFACTOR 0.1 /**< factor by which the regard of the objective is decreased in each round,
    85 * 1.0 for dynamic, depending on solutions already found */
    86#define DEFAULT_ALPHA 1.0 /**< initial weight of the objective function in the convex combination */
    87#define DEFAULT_ALPHADIFF 1.0 /**< threshold difference for the convex parameter to perform perturbation */
    88#define DEFAULT_BEFORECUTS TRUE /**< should the feasibility pump be called at root node before cut separation? */
    89#define DEFAULT_USEFP20 FALSE /**< should an iterative round-and-propagate scheme be used to find the integral points? */
    90#define DEFAULT_PERTSOLFOUND TRUE /**< should a random perturbation be performed if a feasible solution was found? */
    91#define DEFAULT_STAGE3 FALSE /**< should we solve a local branching sub-MIP if no solution could be found? */
    92#define DEFAULT_NEIGHBORHOODSIZE 18 /**< radius of the neighborhood to be searched in stage 3 */
    93#define DEFAULT_COPYCUTS TRUE /**< should all active cuts from the cutpool of the original SCIP be copied to
    94 * constraints of the subscip
    95 */
    96
    97#define MINLPITER 5000 /**< minimal number of LP iterations allowed in each LP solving call */
    98
    99#define DEFAULT_RANDSEED 13 /**< initial random seed */
    100
    101/** primal heuristic data */
    102struct SCIP_HeurData
    103{
    104 SCIP_SOL* sol; /**< working solution */
    105 SCIP_SOL* roundedsol; /**< rounded solution */
    106 SCIP_Longint nlpiterations; /**< number of LP iterations used in this heuristic */
    107 SCIP_Real maxlpiterquot; /**< maximal fraction of diving LP iterations compared to node LP iterations */
    108 SCIP_Real objfactor; /**< factor by which the regard of the objective is decreased in each round,
    109 * 1.0 for dynamic, depending on solutions already found */
    110 SCIP_Real alpha; /**< initial weight of the objective function in the convex combination */
    111 SCIP_Real alphadiff; /**< threshold difference for the convex parameter to perform perturbation */
    112
    113 int maxlpiterofs; /**< additional number of allowed LP iterations */
    114 int maxsols; /**< total number of feasible solutions found up to which heuristic is called
    115 * (-1: no limit) */
    116 int maxloops; /**< maximum number of loops (-1: no limit) */
    117 int maxstallloops; /**< maximal number of pumping rounds without fractionality improvement (-1: no limit) */
    118 int minflips; /**< minimum number of random variables to flip, if a 1-cycle is encountered */
    119 int cyclelength; /**< maximum length of cycles to be checked explicitly in each round */
    120 int perturbfreq; /**< number of iterations until a random perturbation is forced */
    121 int nsuccess; /**< number of runs that produced at least one feasible solution */
    122 int neighborhoodsize; /**< radius of the neighborhood to be searched in stage 3 */
    123
    124 SCIP_RANDNUMGEN* randnumgen; /**< random number generator */
    125 SCIP_Bool beforecuts; /**< should the feasibility pump be called at root node before cut separation? */
    126 SCIP_Bool usefp20; /**< should an iterative round-and-propagate scheme be used to find the integral points? */
    127 SCIP_Bool pertsolfound; /**< should a random perturbation be performed if a feasible solution was found? */
    128 SCIP_Bool stage3; /**< should we solve a local branching sub-MIP if no solution could be found? */
    129 SCIP_Bool copycuts; /**< should all active cuts from cutpool be copied to constraints in
    130 * subproblem?
    131 */
    132};
    133
    134/* copies SCIP to probing SCIP and creates variable hashmap */
    135static
    137 SCIP* scip, /**< SCIP data structure */
    138 SCIP** probingscip, /**< sub-SCIP data structure */
    139 SCIP_HASHMAP** varmapfw, /**< mapping of SCIP variables to sub-SCIP variables */
    140 SCIP_Bool copycuts, /**< should all active cuts from cutpool of scip copied to constraints in subscip */
    141 SCIP_Bool* success /**< was copying successful? */
    142 )
    143{
    144 /* check if we are already at the maximal tree depth */
    146 {
    147 *success = FALSE;
    148 return SCIP_OKAY;
    149 }
    150
    151 /* initializing the subproblem */
    152 SCIP_CALL( SCIPcreate(probingscip) );
    153
    154 /* create the variable mapping hash map */
    155 SCIP_CALL( SCIPhashmapCreate(varmapfw, SCIPblkmem(*probingscip), SCIPgetNVars(scip)) );
    156 *success = FALSE;
    157
    158 /* copy SCIP instance */
    159 SCIP_CALL( SCIPcopyConsCompression(scip, *probingscip, *varmapfw, NULL, "feaspump", NULL, NULL, 0, FALSE, FALSE,
    160 FALSE, TRUE, success) );
    161 assert(!SCIPisExact(*probingscip));
    162
    163 if( copycuts )
    164 {
    165 /* copies all active cuts from cutpool of sourcescip to linear constraints in targetscip */
    166 SCIP_CALL( SCIPcopyCuts(scip, *probingscip, *varmapfw, NULL, FALSE, NULL) );
    167 }
    168
    169 return SCIP_OKAY;
    170}
    171
    172/** set appropriate parameters for probing SCIP in FP2 */
    173static
    175 SCIP* scip, /**< SCIP data structure */
    176 SCIP* probingscip /**< sub-SCIP data structure */
    177 )
    178{
    179 if( SCIPisParamFixed(probingscip, "heuristics/" HEUR_NAME "/freq") )
    180 {
    181 SCIPwarningMessage(scip, "unfixing parameter heuristics/" HEUR_NAME "/freq in probingscip of " HEUR_NAME " heuristic to avoid recursive calls\n");
    182 SCIP_CALL( SCIPunfixParam(probingscip, "heuristics/" HEUR_NAME "/freq") );
    183 }
    184 SCIP_CALL( SCIPsetIntParam(probingscip, "heuristics/" HEUR_NAME "/freq", -1) );
    185
    186 /* do not abort subproblem on CTRL-C */
    187 SCIP_CALL( SCIPsetBoolParam(probingscip, "misc/catchctrlc", FALSE) );
    188
    189#ifndef SCIP_DEBUG
    190 /* disable output to console */
    191 SCIP_CALL( SCIPsetIntParam(probingscip, "display/verblevel", 0) );
    192#endif
    193
    194 /* do not multiaggregate variables, because otherwise they have to be skipped in the fix-and-propagate loop */
    195 SCIP_CALL( SCIPsetBoolParam(probingscip, "presolving/donotmultaggr", TRUE) );
    196
    197 /* limit to root node solving */
    198 SCIP_CALL( SCIPsetLongintParam(probingscip, "limits/nodes", 1LL) );
    199
    200 /* disable LP solving and expensive techniques */
    201 if( SCIPisParamFixed(probingscip, "lp/solvefreq") )
    202 {
    203 SCIPwarningMessage(scip, "unfixing parameter lp/solvefreq in probingscip of " HEUR_NAME " heuristic to speed up propagation\n");
    204 SCIP_CALL( SCIPunfixParam(probingscip, "lp/solvefreq") );
    205 }
    206 SCIP_CALL( SCIPsetIntParam(probingscip, "lp/solvefreq", -1) );
    207 SCIP_CALL( SCIPsetBoolParam(probingscip, "conflict/enable", FALSE) );
    208 SCIP_CALL( SCIPsetBoolParam(probingscip, "constraints/disableenfops", TRUE) );
    209 SCIP_CALL( SCIPsetBoolParam(probingscip, "constraints/knapsack/negatedclique", FALSE) );
    212
    213 return SCIP_OKAY;
    214}
    215
    216/** set appropriate parameters for probing SCIP in Stage 3 */
    217static
    219 SCIP* scip, /**< SCIP data structure */
    220 SCIP* probingscip /**< sub-SCIP data structure */
    221 )
    222{
    223 /**@todo restore the copied settings that were changed in setupSCIPparamsFP2() without copying all parameters, since
    224 * this triggers an error message that exact solving cannot be enabled/disabled in or after problem creation stage
    225 */
    226 SCIP_CALL( SCIPcopyParamSettings(scip, probingscip) );
    227 assert(!SCIPisExact(probingscip));
    228
    229 /* do not abort subproblem on CTRL-C */
    230 SCIP_CALL( SCIPsetBoolParam(probingscip, "misc/catchctrlc", FALSE) );
    231
    232#ifndef SCIP_DEBUG
    233 /* disable output to console */
    234 SCIP_CALL( SCIPsetIntParam(probingscip, "display/verblevel", 0) );
    235#endif
    236 /* set limits for the subproblem */
    237 SCIP_CALL( SCIPcopyLimits(scip, probingscip) );
    238 SCIP_CALL( SCIPsetLongintParam(probingscip, "limits/nodes", 1000LL) );
    239 SCIP_CALL( SCIPsetLongintParam(probingscip, "limits/stallnodes", 100LL) );
    240
    241 /* forbid recursive call of heuristics and separators solving sub-SCIPs */
    242 SCIP_CALL( SCIPsetSubscipsOff(probingscip, TRUE) );
    243 if( SCIPisParamFixed(probingscip, "heuristics/" HEUR_NAME "/freq") )
    244 {
    245 SCIPwarningMessage(scip,"unfixing parameter heuristics/" HEUR_NAME "/freq in probingscip of " HEUR_NAME " heuristic to avoid recursive calls\n");
    246 SCIP_CALL( SCIPunfixParam(probingscip, "heuristics/" HEUR_NAME "/freq") );
    247 }
    248 SCIP_CALL( SCIPsetIntParam(probingscip, "heuristics/feaspump/freq", -1) );
    249
    250 /* disable heuristics which aim to feasibility instead of optimality */
    251 if( !SCIPisParamFixed(probingscip, "heuristics/octane/freq") )
    252 {
    253 SCIP_CALL( SCIPsetIntParam(probingscip, "heuristics/octane/freq", -1) );
    254 }
    255 if( !SCIPisParamFixed(probingscip, "heuristics/objpscostdiving/freq") )
    256 {
    257 SCIP_CALL( SCIPsetIntParam(probingscip, "heuristics/objpscostdiving/freq", -1) );
    258 }
    259 if( !SCIPisParamFixed(probingscip, "heuristics/rootsoldiving/freq") )
    260 {
    261 SCIP_CALL( SCIPsetIntParam(probingscip, "heuristics/rootsoldiving/freq", -1) );
    262 }
    263
    264 /* disable cutting plane separation */
    266
    267 /* disable expensive presolving */
    269
    270 /* use best estimate node selection */
    271 if( SCIPfindNodesel(probingscip, "estimate") != NULL && !SCIPisParamFixed(probingscip, "nodeselection/estimate/stdpriority") )
    272 {
    273 SCIP_CALL( SCIPsetIntParam(probingscip, "nodeselection/estimate/stdpriority", INT_MAX/4) );
    274 }
    275
    276 /* use inference branching */
    277 if( SCIPfindBranchrule(probingscip, "inference") != NULL && !SCIPisParamFixed(probingscip, "branching/inference/priority") )
    278 {
    279 SCIP_CALL( SCIPsetIntParam(probingscip, "branching/inference/priority", INT_MAX/4) );
    280 }
    281
    282 /* disable conflict analysis */
    283 if( !SCIPisParamFixed(probingscip, "conflict/enable") )
    284 {
    285 SCIP_CALL( SCIPsetBoolParam(probingscip, "conflict/enable", FALSE) );
    286 }
    287
    288 return SCIP_OKAY;
    289}
    290
    291/** checks whether a variable is one of the currently most fractional ones */
    292static
    294 SCIP_VAR** mostfracvars, /**< sorted array of the currently most fractional variables */
    295 SCIP_Real* mostfracvals, /**< array of their fractionality, decreasingly sorted */
    296 int* nflipcands, /**< number of fractional variables already labeled to be flipped*/
    297 int maxnflipcands, /**< typically randomized number of maximum amount of variables to flip */
    298 SCIP_VAR* var, /**< variable to be checked */
    299 SCIP_Real frac /**< fractional value of the variable */
    300 )
    301{
    302 int i;
    303
    304 assert(mostfracvars != NULL);
    305 assert(mostfracvals != NULL);
    306 assert(nflipcands != NULL);
    307
    308 /* instead of the fractional value use the fractionality */
    309 if( frac > 0.5 )
    310 frac = 1 - frac;
    311
    312 /* if there are already enough candidates and the variable is less fractional, return, else reserve the last entry */
    313 if( *nflipcands >= maxnflipcands )
    314 {
    315 if( frac <= mostfracvals[*nflipcands-1] )
    316 return;
    317 else
    318 (*nflipcands)--;
    319 }
    320
    321 /* shifting var and frac through the (sorted) arrays */
    322 for( i = *nflipcands; i > 0 && mostfracvals[i-1] < frac; i-- )
    323 {
    324 mostfracvars[i] = mostfracvars[i-1];
    325 mostfracvals[i] = mostfracvals[i-1];
    326 }
    327 assert(0 <= i && i <= *nflipcands && *nflipcands < maxnflipcands);
    328
    329 /* insert the variable and its fractionality */
    330 mostfracvars[i] = var;
    331 mostfracvals[i] = frac;
    332
    333 /* we've found another candidate */
    334 (*nflipcands)++;
    335}
    336
    337/** set solution value in rounded solution and update objective coefficient accordingly */
    338static
    340 SCIP* scip, /**< SCIP data structure */
    341 SCIP_HEURDATA* heurdata, /**< heuristic data structure */
    342 SCIP_VAR* var, /**< variable */
    343 SCIP_Real solval, /**< solution value for this variable */
    344 SCIP_Real alpha, /**< weight of original objective function */
    345 SCIP_Real scalingfactor /**< factor to scale the original objective function with */
    346 )
    347{
    348 SCIP_Real lb;
    349 SCIP_Real ub;
    350 SCIP_Real newobjcoeff;
    351 SCIP_Real orgobjcoeff;
    352
    353 assert(heurdata != NULL);
    354 assert(var != NULL);
    355
    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
    591
    592 /* call inclusion method of primal heuristic */
    594
    595 return SCIP_OKAY;
    596}
    597
    598/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
    599static
    600SCIP_DECL_HEURFREE(heurFreeFeaspump)
    601{
    602 SCIP_HEURDATA* heurdata;
    603
    604 assert(heur != NULL);
    605 assert(scip != NULL);
    606
    608
    609 /* free heuristic data */
    610 heurdata = SCIPheurGetData(heur);
    611 assert(heurdata != NULL);
    612 SCIPfreeBlockMemory(scip, &heurdata);
    613 SCIPheurSetData(heur, NULL);
    614
    615 return SCIP_OKAY;
    616}
    617
    618
    619/** initialization method of primal heuristic (called after problem was transformed) */
    620static
    621SCIP_DECL_HEURINIT(heurInitFeaspump)
    622{
    623 SCIP_HEURDATA* heurdata;
    624
    625 assert(heur != NULL);
    626
    628
    629 /* get heuristic data */
    630 heurdata = SCIPheurGetData(heur);
    631 assert(heurdata != NULL);
    632
    633 /* create working solution */
    634 SCIP_CALL( SCIPcreateSol(scip, &heurdata->sol, heur) );
    635 SCIP_CALL( SCIPcreateSol(scip, &heurdata->roundedsol, heur) );
    636
    637 /* initialize data */
    638 heurdata->nlpiterations = 0;
    639 heurdata->nsuccess = 0;
    640
    641 /* create random number generator */
    642 SCIP_CALL( SCIPcreateRandom(scip, &heurdata->randnumgen,
    644
    645 return SCIP_OKAY;
    646}
    647
    648/** deinitialization method of primal heuristic (called before transformed problem is freed) */
    649static
    650SCIP_DECL_HEUREXIT(heurExitFeaspump)
    651{
    652 SCIP_HEURDATA* heurdata;
    653
    654 assert(heur != NULL);
    655
    657
    658 /* get heuristic data */
    659 heurdata = SCIPheurGetData(heur);
    660 assert(heurdata != NULL);
    661
    662 /* free working solution */
    663 SCIP_CALL( SCIPfreeSol(scip, &heurdata->sol) );
    664 SCIP_CALL( SCIPfreeSol(scip, &heurdata->roundedsol) );
    665
    666 /* free random number generator */
    667 SCIPfreeRandom(scip, &heurdata->randnumgen);
    668
    669 return SCIP_OKAY;
    670}
    671
    672
    673/** solving process initialization method of primal heuristic (called when branch and bound process is about to begin) */
    674static
    675SCIP_DECL_HEURINITSOL(heurInitsolFeaspump)
    676{
    677 SCIP_HEURDATA* heurdata;
    678
    679 heurdata = SCIPheurGetData(heur);
    680 assert(heurdata != NULL);
    681
    682 /* if the heuristic is called at the root node, we may want to be called directly after the initial root LP solve */
    683 if( heurdata->beforecuts && SCIPheurGetFreqofs(heur) == 0 )
    685
    686 return SCIP_OKAY;
    687}
    688
    689
    690/** solving process deinitialization method of primal heuristic (called before branch and bound process data is freed) */
    691static
    692SCIP_DECL_HEUREXITSOL(heurExitsolFeaspump)
    693{
    694 /* reset the timing mask to its default value */
    696
    697 return SCIP_OKAY;
    698}
    699
    700/** calculates an adjusted maximal number of LP iterations */
    701static
    703 SCIP_Longint maxnlpiterations, /**< regular maximal number of LP iterations */
    704 SCIP_Longint nsolsfound, /**< total number of solutions found so far by SCIP */
    705 int nstallloops /**< current number of stalling rounds */
    706 )
    707{
    708 if( nstallloops <= 1 )
    709 {
    710 if( nsolsfound == 0 )
    711 return 4*maxnlpiterations;
    712 else
    713 return 2*maxnlpiterations;
    714 }
    715 else
    716 return maxnlpiterations;
    717}
    718
    719/** execution method of primal heuristic */
    720static
    721SCIP_DECL_HEUREXEC(heurExecFeaspump)
    722{
    723 SCIP_HEURDATA* heurdata;
    724 SCIP_SOL* tmpsol; /* only used for swapping */
    725 SCIP_SOL** lastroundedsols;/* solutions of the last pumping rounds (depending on heurdata->cyclelength) */
    726 SCIP_SOL* closestsol; /* rounded solution closest to the LP relaxation: used for stage3 */
    727 SCIP_Real* lastalphas; /* alpha values associated to solutions in lastroundedsols */
    728
    729 SCIP* probingscip; /* copied SCIP structure, used for round-and-propagate loop of feasibility pump 2.0 */
    730 SCIP_HASHMAP* varmapfw; /* mapping of SCIP variables to sub-SCIP variables */
    731
    732 SCIP_VAR** vars;
    733 SCIP_VAR** pseudocands;
    734 SCIP_VAR** tmppseudocands;
    735 SCIP_VAR** mostfracvars; /* the 30 most fractional variables, needed to avoid 1-cycles */
    736 SCIP_VAR* var;
    737
    738 SCIP_Real* mostfracvals; /* the values of the variables above */
    739 SCIP_Real oldsolval; /* one value of the last solution */
    740 SCIP_Real solval; /* one value of the actual solution */
    741 SCIP_Real frac; /* the fractional part of the value above */
    742 SCIP_Real objfactor; /* factor by which the regard of the objective is decreased in each round, in [0,0.99] */
    743 SCIP_Real alpha; /* factor how the original objective is regarded, used for convex combination of two functions */
    744 SCIP_Real objnorm; /* Euclidean norm of the objective function, used for scaling */
    745 SCIP_Real scalingfactor; /* factor to scale the original objective function with */
    746 SCIP_Real mindistance; /* distance of the closest rounded solution from the LP relaxation: used for stage3 */
    747
    748 SCIP_Longint nlpiterations; /* number of LP iterations done during one pumping round */
    749 SCIP_Longint maxnlpiterations; /* maximum number of LP iterations for this heuristic */
    750 SCIP_Longint nsolsfound; /* number of solutions found by this heuristic */
    751 SCIP_Longint ncalls; /* number of calls of this heuristic */
    752 SCIP_Longint nbestsolsfound; /* current total number of best solution updates in SCIP */
    753
    754 SCIP_LPSOLSTAT lpsolstat; /* status of the LP solution */
    755
    756 int nvars; /* number of variables */
    757 int nenfovars; /* number of enforced integral variables */
    758 int nfracs; /* number of fractional variables updated after each pumping round*/
    759 int nflipcands; /* how many flipcands (most frac. var.) have been found */
    760 int npseudocands;
    761 int maxnflipcands; /* maximal number of candidates to flip in the current pumping round */
    762 int nloops; /* how many pumping rounds have been made */
    763 int maxflips; /* maximum number of flips, if a 1-cycle is found (depending on heurdata->minflips) */
    764 int maxloops; /* maximum number of pumping rounds */
    765 int nstallloops; /* number of loops without reducing the current best number of factional variables */
    766 int maxstallloops; /* maximal number of allowed stalling loops */
    767 int bestnfracs; /* best number of fractional variables */
    768 int i;
    769 int j;
    770
    771 SCIP_Bool success;
    772 SCIP_Bool lperror;
    773 SCIP_Bool* cycles; /* are there short cycles */
    774
    775 SCIP_RETCODE retcode;
    776
    777 assert(heur != NULL);
    778 assert(scip != NULL);
    779 assert(result != NULL);
    780 assert(SCIPhasCurrentNodeLP(scip));
    781
    783
    784 *result = SCIP_DELAYED;
    785
    786 /* do not call heuristic of node was already detected to be infeasible */
    787 if( nodeinfeasible )
    788 return SCIP_OKAY;
    789
    790 /* only call heuristic, if an optimal LP solution is at hand */
    792 return SCIP_OKAY;
    793
    794 /* only call heuristic, if the LP objective value is smaller than the cutoff bound */
    796 return SCIP_OKAY;
    797
    798 /* only call heuristic, if the LP solution is basic (which allows fast resolve in diving) */
    799 if( !SCIPisLPSolBasic(scip) )
    800 return SCIP_OKAY;
    801
    802 *result = SCIP_DIDNOTRUN;
    803
    804 /* don't dive two times at the same node */
    806 return SCIP_OKAY;
    807
    808 /* only call feaspump once at the root */
    809 if( SCIPgetDepth(scip) == 0 && SCIPheurGetNCalls(heur) > 0 )
    810 return SCIP_OKAY;
    811
    812 /* reset the timing mask to its default value (at the root node it could be different) */
    814
    815 /* only call the heuristic before cutting planes if we do not have an incumbent and no pricer exists */
    816 if( heurtiming == SCIP_HEURTIMING_DURINGLPLOOP && SCIPgetNSolsFound(scip) > 0 && SCIPgetNPricers(scip) == 0 )
    817 return SCIP_OKAY;
    818
    819 /* get heuristic's data */
    820 heurdata = SCIPheurGetData(heur);
    821 assert(heurdata != NULL);
    822
    823 /* only apply heuristic, if only a few solutions have been found and no pricer exists */
    824 if( heurdata->maxsols >= 0 && SCIPgetNSolsFound(scip) > heurdata->maxsols && SCIPgetNPricers(scip) == 0 )
    825 return SCIP_OKAY;
    826
    827 /* get all variables of LP and number of fractional variables in LP solution that should be integral */
    828 vars = SCIPgetVars(scip);
    829 nvars = SCIPgetNVars(scip);
    830 nenfovars = nvars - SCIPgetNContVars(scip) - SCIPgetNContImplVars(scip);
    831 assert(nenfovars >= 0);
    832 nfracs = SCIPgetNLPBranchCands(scip);
    833 assert(0 <= nfracs && nfracs <= nenfovars);
    834 if( nfracs == 0 )
    835 return SCIP_OKAY;
    836
    837 /* calculate the maximal number of LP iterations until heuristic is aborted */
    838 nlpiterations = SCIPgetNNodeLPIterations(scip);
    839 ncalls = SCIPheurGetNCalls(heur);
    840 nsolsfound = 10*SCIPheurGetNBestSolsFound(heur) + heurdata->nsuccess;
    841 maxnlpiterations = (SCIP_Longint)(((nsolsfound+1.0)/(ncalls+1.0)) * heurdata->maxlpiterquot * nlpiterations);
    842 maxnlpiterations += heurdata->maxlpiterofs;
    843
    844 /* don't try to dive, if we took too many LP iterations during diving */
    845 if( heurdata->nlpiterations >= maxnlpiterations )
    846 return SCIP_OKAY;
    847
    848 /* at the first root call, allow more iterations if there is no feasible solution yet */
    849 if( SCIPheurGetNCalls(heur) == 0 && SCIPgetNSolsFound(scip) == 0 && SCIPgetDepth(scip) == 0 )
    850 maxnlpiterations += nlpiterations;
    851
    852 /* allow at least a certain number of LP iterations in this dive */
    853 maxnlpiterations = MAX(maxnlpiterations, heurdata->nlpiterations + MINLPITER);
    854
    855 /* calculate maximal number of flips and loops */
    856 maxflips = 3*heurdata->minflips;
    857 maxloops = (heurdata->maxloops == -1 ? INT_MAX : heurdata->maxloops);
    858 maxstallloops = (heurdata->maxstallloops == -1 ? INT_MAX : heurdata->maxstallloops);
    859
    860 SCIPdebugMsg(scip, "executing feasibility pump heuristic, nlpiters=%" SCIP_LONGINT_FORMAT ", maxnlpit:%" SCIP_LONGINT_FORMAT ", maxflips:%d \n",
    861 nlpiterations, maxnlpiterations, maxflips);
    862
    863 *result = SCIP_DIDNOTFIND;
    864
    865 probingscip = NULL;
    866 varmapfw = NULL;
    867
    868 if( heurdata->usefp20 )
    869 {
    870 SCIP_Bool valid;
    871
    872 /* ignore value of valid */
    873 SCIP_CALL( setupProbingSCIP(scip, &probingscip, &varmapfw, heurdata->copycuts, &valid) );
    874
    875 if( probingscip != NULL )
    876 {
    877 SCIP_CALL( setupSCIPparamsFP2(scip, probingscip) );
    878
    879 retcode = SCIPsolve(probingscip);
    880
    881 /* errors in solving the subproblem should not kill the overall solving process;
    882 * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop. */
    883 if( retcode != SCIP_OKAY )
    884 {
    885#ifndef NDEBUG
    886 SCIP_CALL( retcode );
    887#endif
    888 SCIPwarningMessage(scip, "Error while solving subproblem in feaspump heuristic; sub-SCIP terminated with code <%d>\n", retcode);
    889
    890 /* free hash map and copied SCIP */
    891 SCIPhashmapFree(&varmapfw);
    892 SCIP_CALL( SCIPfree(&probingscip) );
    893 return SCIP_OKAY;
    894 }
    895
    896 if( SCIPgetStage(probingscip) != SCIP_STAGE_SOLVING)
    897 {
    898 SCIP_STATUS probingstatus = SCIPgetStatus(probingscip);
    899
    900 if( probingstatus == SCIP_STATUS_OPTIMAL )
    901 {
    902 assert( SCIPgetNSols(probingscip) > 0 );
    903 SCIP_CALL( createNewSols(scip, probingscip, varmapfw, heur, &success) );
    904 if( success )
    905 *result = SCIP_FOUNDSOL;
    906 }
    907
    908 /* free hash map and copied SCIP */
    909 SCIPhashmapFree(&varmapfw);
    910 SCIP_CALL( SCIPfree(&probingscip) );
    911 return SCIP_OKAY;
    912 }
    913 SCIP_CALL( SCIPsetLongintParam(probingscip, "limits/nodes", 2LL) );
    914
    915 /* set SCIP into probing mode and create root node of the probing tree */
    916 SCIP_CALL( SCIPstartProbing(probingscip) );
    917
    918 /* this should always be fulfilled */
    919 assert(SCIP_MAXTREEDEPTH > SCIPgetDepth(probingscip));
    920
    921 SCIP_CALL( SCIPnewProbingNode(probingscip) );
    922
    923 SCIPdebugMsg(scip, "successfully copied SCIP instance -> feasibility pump 2.0 can be used.\n");
    924 }
    925 else
    926 {
    927 assert(varmapfw == NULL);
    928
    929 SCIPdebugMsg(scip, "SCIP reached the depth limit -> skip heuristic\n");
    930 return SCIP_OKAY;
    931 }
    932 } /*lint !e438*/
    933
    934 /* memory allocation */
    935 SCIP_CALL( SCIPallocBufferArray(scip, &mostfracvars, maxflips) );
    936 SCIP_CALL( SCIPallocBufferArray(scip, &mostfracvals, maxflips) );
    937 SCIP_CALL( SCIPallocBufferArray(scip, &lastroundedsols, heurdata->cyclelength) );
    938 SCIP_CALL( SCIPallocBufferArray(scip, &lastalphas, heurdata->cyclelength) );
    939 SCIP_CALL( SCIPallocBufferArray(scip, &cycles, heurdata->cyclelength) );
    940
    941 for( j = 0; j < heurdata->cyclelength; j++ )
    942 {
    943 SCIP_CALL( SCIPcreateSol(scip, &lastroundedsols[j], heur) );
    944 }
    945
    946 closestsol = NULL;
    947 if( heurdata->stage3 )
    948 {
    949 SCIP_CALL( SCIPcreateSol(scip, &closestsol, heur) );
    950 }
    951
    952 /* start diving */
    954
    955 /* lp was solved optimal */
    956 lperror = FALSE;
    957 lpsolstat = SCIP_LPSOLSTAT_OPTIMAL;
    958
    959 /* pumping rounds */
    960 nsolsfound = SCIPgetNBestSolsFound(scip);
    961 if( heurdata->objfactor == 1.0 )
    962 objfactor = MIN(1.0 - 0.1 / (SCIP_Real)(1 + nsolsfound), 0.999);
    963 else
    964 objfactor = heurdata->objfactor;
    965
    966 /* scale distance function and original objective to the same norm */
    967 objnorm = SCIPgetObjNorm(scip);
    968 objnorm = MAX(objnorm, 1.0);
    969 scalingfactor = sqrt((SCIP_Real)nenfovars) / objnorm;
    970
    971 /* data initialization */
    972 alpha = heurdata->alpha;
    973 nloops = 0;
    974 nstallloops = 0;
    975 nbestsolsfound = SCIPgetNBestSolsFound(scip);
    976 bestnfracs = INT_MAX;
    977 mindistance = SCIPinfinity(scip);
    978
    979 /* pumping loop */
    980 while( nfracs > 0
    981 && heurdata->nlpiterations < adjustedMaxNLPIterations(maxnlpiterations, nsolsfound, nstallloops)
    982 && nloops < maxloops && nstallloops < maxstallloops
    983 && !SCIPisStopped(scip) )
    984 {
    985 int minimum;
    986 SCIP_Real* pseudocandsfrac;
    987 SCIP_Longint nlpiterationsleft;
    988 int iterlimit;
    989
    990 /* decrease convex combination scalar */
    991 nloops++;
    992 alpha *= objfactor;
    993
    994 SCIPdebugMsg(scip, "feasibility pump loop %d: %d fractional variables (alpha: %.4f, stall: %d/%d)\n",
    995 nloops, nfracs, alpha, nstallloops, maxstallloops);
    996
    997 success = FALSE;
    998
    999 SCIP_CALL( SCIPlinkLPSol(scip, heurdata->roundedsol) );
    1000
    1001 /* randomly choose maximum number of variables to flip in current pumping round in case of a 1-cycle */
    1002 maxnflipcands = SCIPrandomGetInt(heurdata->randnumgen, MIN(nfracs/2+1, heurdata->minflips), MIN(nfracs, maxflips));
    1003 nflipcands = 0;
    1004
    1005 /* get all unfixed integer variables */
    1006 SCIP_CALL( SCIPgetPseudoBranchCands(scip, &tmppseudocands, &npseudocands, NULL) );
    1007 SCIP_CALL( SCIPduplicateBufferArray(scip, &pseudocands, tmppseudocands, npseudocands) );
    1008
    1009 /* get array of all fractional variables and sort it w.r.t. their fractionalities */
    1010 if( heurdata->usefp20 )
    1011 {
    1012 SCIP_CALL( SCIPallocBufferArray(scip, &pseudocandsfrac, npseudocands) );
    1013
    1014 for( i = 0; i < npseudocands; i++ )
    1015 {
    1016 frac = SCIPfeasFrac(scip, SCIPvarGetLPSol(pseudocands[i]));
    1017 pseudocandsfrac[i] = MIN(frac, 1.0-frac); /* always a number between 0 and 0.5 */
    1018 if( SCIPvarGetType(pseudocands[i]) == SCIP_VARTYPE_BINARY && !SCIPvarIsImpliedIntegral(pseudocands[i]) )
    1019 pseudocandsfrac[i] -= 10.0; /* binaries always come first */
    1020 }
    1021 SCIPsortRealPtr(pseudocandsfrac, (void**)pseudocands, npseudocands);
    1022 SCIPfreeBufferArray(scip, &pseudocandsfrac);
    1023
    1024 SCIPdebugMsg(scip, "iteratively fix and propagate variables\n");
    1025 }
    1026
    1027 for( i = 0; i < npseudocands; i++ )
    1028 {
    1029 SCIP_VAR* probingvar;
    1030 SCIP_Bool infeasible;
    1031 SCIP_Longint ndomreds;
    1032
    1033 var = pseudocands[i];
    1034
    1035 /* round the LP solution */
    1036 solval = SCIPvarGetLPSol(var);
    1037 frac = SCIPfeasFrac(scip, solval);
    1038
    1039 /* round randomly if the value is close to 0.5 */
    1040 if( SCIPisEQ(scip, frac, 0.5) )
    1041 {
    1042 if( SCIPrandomGetReal(heurdata->randnumgen, 0.0, 1.0) <= 0.5 )
    1043 solval = SCIPfloor(scip, solval);
    1044 else
    1045 solval = SCIPceil(scip, solval);
    1046 }
    1047 else
    1048 solval = SCIPfloor(scip, solval + 0.5);
    1049
    1050 /* ensure, that the fixing value is inside the local domains */
    1051 if( heurdata->usefp20 )
    1052 {
    1053 SCIP_Real lbprobing;
    1054 SCIP_Real ubprobing;
    1055
    1056 probingvar = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, var);
    1057 /* skip if variable does not exist in probingscip */
    1058 if( probingvar != NULL )
    1059 {
    1060 lbprobing = SCIPvarGetLbLocal(probingvar);
    1061 ubprobing = SCIPvarGetUbLocal(probingvar);
    1062
    1063 solval = MAX(solval, lbprobing);
    1064 solval = MIN(solval, ubprobing);
    1065
    1066 /* fix the variable and propagate the domain change */
    1067 if( !SCIPisFeasEQ(probingscip, lbprobing, ubprobing) && SCIPvarIsActive(SCIPvarGetTransVar(probingvar)) )
    1068 {
    1069 assert(SCIPisFeasLE(probingscip, lbprobing, ubprobing));
    1070 SCIPdebugMsg(scip, "try to fix variable <%s> (domain [%f,%f] to %f\n", SCIPvarGetName(probingvar), lbprobing, ubprobing,
    1071 solval);
    1072 SCIP_CALL( SCIPfixVarProbing(probingscip, probingvar, solval) );
    1073 SCIP_CALL( SCIPpropagateProbing(probingscip, -1, &infeasible, &ndomreds) );
    1074 SCIPdebugMsg(scip, " -> reduced %" SCIP_LONGINT_FORMAT " domains\n", ndomreds);
    1075
    1076 if( infeasible )
    1077 {
    1078 SCIPdebugMsg(scip, " -> infeasible!\n");
    1079 SCIP_CALL( SCIPbacktrackProbing(probingscip, 0) );
    1080 }
    1081 }
    1082 else
    1083 {
    1084 SCIPdebugMsg(scip, "variable <%s> is already fixed to %f\n", SCIPvarGetName(probingvar), solval);
    1085 }
    1086 }
    1087 }
    1088
    1089 SCIP_CALL( updateVariableRounding(scip, heurdata, var, solval, alpha, scalingfactor) );
    1090
    1091 /* check whether the variable is one of the most fractionals and label if so */
    1092 if( SCIPisFeasPositive(scip, frac) )
    1093 insertFlipCand(mostfracvars, mostfracvals, &nflipcands, maxnflipcands, var, frac);
    1094 }
    1095
    1096 if( heurdata->usefp20 )
    1097 {
    1098 SCIP_CALL( SCIPbacktrackProbing(probingscip, 0) );
    1099 }
    1100
    1101 /* change objective coefficients for continuous variables */
    1102 for( i = nenfovars; i < nvars; i++ )
    1103 {
    1104 SCIP_CALL( SCIPchgVarObjDive(scip, vars[i], alpha * SCIPvarGetObj(vars[i])) );
    1105 }
    1106
    1107 SCIPfreeBufferArray(scip, &pseudocands);
    1108
    1109 /* initialize cycle check */
    1110 minimum = MIN(heurdata->cyclelength, nloops-1);
    1111 for( j = 0; j < heurdata->cyclelength; j++ )
    1112 cycles[j] = (nloops > j+1) && (REALABS(lastalphas[j] - alpha) < heurdata->alphadiff);
    1113
    1114 /* check for j-cycles */
    1115 for( i = 0; i < nenfovars; i++ )
    1116 {
    1117 solval = SCIPgetSolVal(scip, heurdata->roundedsol, vars[i]);
    1118
    1119 /* cycles exist, iff all solution values are equal */
    1120 for( j = 0; j < minimum; j++ )
    1121 {
    1122 oldsolval = SCIPgetSolVal(scip, lastroundedsols[j], vars[i]);
    1123 cycles[j] = cycles[j] && SCIPisFeasEQ(scip, solval, oldsolval);
    1124 }
    1125 }
    1126
    1127 /* force to flip variables at random after a couple of pumping rounds,
    1128 * or if a new best solution in the current region has been found
    1129 */
    1130 assert(heurdata->perturbfreq > 0);
    1131 if( nloops % heurdata->perturbfreq == 0 || (heurdata->pertsolfound && SCIPgetNBestSolsFound(scip) > nbestsolsfound) )
    1132 {
    1133 SCIPdebugMsg(scip, " -> random perturbation\n");
    1134 SCIP_CALL( handleCycle(scip, heurdata, vars, nenfovars, alpha, scalingfactor) );
    1135 nbestsolsfound = SCIPgetNBestSolsFound(scip);
    1136 }
    1137 else
    1138 {
    1139 minimum = MIN(heurdata->cyclelength, nloops-1);
    1140
    1141 for( j = 0; j < minimum; j++ )
    1142 {
    1143 /* if we got the same rounded solution as in some step before, we have to flip some variables */
    1144 if( cycles[j] )
    1145 {
    1146 /* 1-cycles have a special flipping rule (flip most fractional variables) */
    1147 if( j == 0 )
    1148 {
    1149 SCIPdebugMsg(scip, " -> avoiding 1-cycle: flipping %d candidates\n", nflipcands);
    1150 SCIP_CALL( handle1Cycle(scip, heurdata, mostfracvars, nflipcands, alpha, scalingfactor) );
    1151 }
    1152 else
    1153 {
    1154 SCIPdebugMsg(scip, " -> avoiding %d-cycle by random flip\n", j+1);
    1155 SCIP_CALL( handleCycle(scip, heurdata, vars, nenfovars, alpha, scalingfactor) );
    1156 }
    1157 break;
    1158 }
    1159 }
    1160 }
    1161
    1162 /* the LP with the new (distance) objective is solved */
    1163 nlpiterations = SCIPgetNLPIterations(scip);
    1164 nlpiterationsleft = adjustedMaxNLPIterations(maxnlpiterations, nsolsfound, nstallloops) - heurdata->nlpiterations;
    1165 iterlimit = MAX((int)nlpiterationsleft, MINLPITER);
    1166 SCIPdebugMsg(scip, " -> solve LP with iteration limit %d\n", iterlimit);
    1167
    1168 if( heurdata->stage3 )
    1169 {
    1170 SCIP_CALL( SCIPunlinkSol(scip, heurdata->roundedsol) );
    1171 }
    1172
    1173 retcode = SCIPsolveDiveLP(scip, iterlimit, &lperror, NULL);
    1174 lpsolstat = SCIPgetLPSolstat(scip);
    1175
    1176 /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
    1177 * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
    1178 */
    1179 if( retcode != SCIP_OKAY )
    1180 {
    1181#ifndef NDEBUG
    1182 if( lpsolstat != SCIP_LPSOLSTAT_UNBOUNDEDRAY )
    1183 {
    1184 SCIP_CALL( retcode );
    1185 }
    1186#endif
    1187 SCIPwarningMessage(scip, "Error while solving LP in Feaspump heuristic; LP solve terminated with code <%d>\n", retcode);
    1188 SCIPwarningMessage(scip, "This does not affect the remaining solution procedure --> continue\n");
    1189 }
    1190
    1191 /* update iteration count */
    1192 heurdata->nlpiterations += SCIPgetNLPIterations(scip) - nlpiterations;
    1193 SCIPdebugMsg(scip, " -> number of iterations: %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", lperror=%u, lpsolstat=%d\n",
    1194 heurdata->nlpiterations, adjustedMaxNLPIterations(maxnlpiterations, nsolsfound, nstallloops), lperror, lpsolstat);
    1195
    1196 /* check whether LP was solved optimal */
    1197 if( lperror || lpsolstat != SCIP_LPSOLSTAT_OPTIMAL )
    1198 break;
    1199
    1200 if( heurdata->stage3 )
    1201 {
    1202 SCIP_Real distance; /* distance of the current rounded solution from the LP solution */
    1203
    1204 assert(closestsol != NULL);
    1205
    1206 /* calculate distance */
    1207 distance = 0.0;
    1208 for( i = 0; i < nenfovars; i++ )
    1209 {
    1210 SCIP_Real roundedval;
    1211 SCIP_Real lpval;
    1212
    1213 roundedval = SCIPgetSolVal(scip, heurdata->roundedsol, vars[i]);
    1214 lpval = SCIPvarGetLPSol(vars[i]);
    1215 distance += REALABS(roundedval - lpval);
    1216 }
    1217
    1218 /* copy solution and update minimum distance */
    1219 if( SCIPisLT(scip, distance, mindistance) )
    1220 {
    1221 for( i = 0; i < nenfovars; i++ )
    1222 {
    1223 assert(SCIPisIntegral(scip,SCIPgetSolVal(scip, heurdata->roundedsol, vars[i])));
    1224 SCIP_CALL( SCIPsetSolVal(scip, closestsol, vars[i], SCIPgetSolVal(scip, heurdata->roundedsol, vars[i])) );
    1225 }
    1226 mindistance = distance;
    1227 }
    1228 }
    1229
    1230 /* swap the last solutions */
    1231 SCIP_CALL( SCIPunlinkSol(scip, heurdata->roundedsol) );
    1232 tmpsol = lastroundedsols[heurdata->cyclelength-1];
    1233 for( j = heurdata->cyclelength-1; j > 0; j-- )
    1234 {
    1235 lastroundedsols[j] = lastroundedsols[j-1];
    1236 lastalphas[j] = lastalphas[j-1];
    1237 }
    1238 lastroundedsols[0] = heurdata->roundedsol;
    1239 lastalphas[0] = alpha;
    1240 heurdata->roundedsol = tmpsol;
    1241
    1242 /* check for improvement in number of fractionals */
    1243 nfracs = SCIPgetNLPBranchCands(scip);
    1244 if( nfracs < bestnfracs )
    1245 {
    1246 bestnfracs = nfracs;
    1247 nstallloops = 0;
    1248 }
    1249 else
    1250 nstallloops++;
    1251
    1252 SCIPdebugMsg(scip, " -> loop finished: %d fractional variables (stall: %d/%d, iterations: %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ")\n",
    1253 nfracs, nstallloops, maxstallloops, heurdata->nlpiterations, adjustedMaxNLPIterations(maxnlpiterations, nsolsfound, nstallloops));
    1254 }
    1255
    1256 /* try final solution, if no more fractional variables are left */
    1257 if( nfracs == 0 && !lperror && lpsolstat == SCIP_LPSOLSTAT_OPTIMAL )
    1258 {
    1259 success = FALSE;
    1260
    1261 SCIP_CALL( SCIPlinkLPSol(scip, heurdata->sol) );
    1262
    1263 /* in exact mode we have to end diving prior to trying the solution */
    1264 if( SCIPisExact(scip) )
    1265 {
    1266 SCIP_CALL( SCIPunlinkSol(scip, heurdata->sol) );
    1268 }
    1269
    1270 SCIPdebugMsg(scip, "feasibility pump found solution (%d fractional variables)\n", nfracs);
    1271 SCIP_CALL( SCIPtrySol(scip, heurdata->sol, FALSE, FALSE, FALSE, FALSE, FALSE, &success) );
    1272 if( success )
    1273 *result = SCIP_FOUNDSOL;
    1274 }
    1275
    1276 /* end diving */
    1277 if( SCIPinDive(scip) )
    1278 {
    1280 }
    1281
    1282 /* end probing in order to be able to apply stage 3 */
    1283 if( heurdata->usefp20 )
    1284 {
    1285 SCIP_CALL( SCIPendProbing(probingscip) );
    1286 }
    1287
    1288 /* only do stage 3 if we have not found a solution yet */
    1289 /* only do stage 3 if the distance of the closest infeasible solution to the polyhedron is below a certain threshold */
    1290 if( heurdata->stage3 && (*result != SCIP_FOUNDSOL) && SCIPisLE(scip, mindistance, (SCIP_Real) heurdata->neighborhoodsize) )
    1291 {
    1292 SCIP_Bool cancopy;
    1293 assert(closestsol != NULL);
    1294 assert(!SCIPisInfinity(scip, mindistance) || nloops == 0);
    1295
    1296 /* if we do not use feasibility pump 2.0, we have not created a copied SCIP instance yet */
    1297 if( heurdata->usefp20 )
    1298 {
    1299 assert(probingscip != NULL);
    1300 SCIP_CALL( SCIPfreeTransform(probingscip) );
    1301 }
    1302 else
    1303 {
    1304 assert(probingscip == NULL);
    1305 SCIP_CALL( setupProbingSCIP(scip, &probingscip, &varmapfw, heurdata->copycuts, &success) );
    1306 }
    1307
    1308 /* check whether there is enough time and memory left */
    1309 SCIP_CALL( SCIPcheckCopyLimits(scip, &cancopy) );
    1310
    1311 if( cancopy )
    1312 {
    1313 SCIP_CALL( setupSCIPparamsStage3(scip, probingscip) );
    1314
    1315 /* the neighborhood size is double the distance plus another ten percent */
    1316 mindistance = SCIPceil(scip, 2.2*mindistance);
    1317
    1318 SCIP_CALL( addLocalBranchingConstraint(scip, probingscip, varmapfw, closestsol, mindistance) );
    1319
    1320 /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
    1321 * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
    1322 */
    1323 SCIP_CALL_ABORT( SCIPsolve(probingscip) );
    1324
    1325 /* check, whether a solution was found */
    1326 if( SCIPgetNSols(probingscip) > 0 )
    1327 {
    1328 success = FALSE;
    1329 SCIP_CALL( createNewSols(scip, probingscip, varmapfw, heur, &success) );
    1330 if( success )
    1331 *result = SCIP_FOUNDSOL;
    1332 }
    1333 }
    1334 }
    1335
    1336 if( *result == SCIP_FOUNDSOL )
    1337 heurdata->nsuccess++;
    1338
    1339 /* free hash map and copied SCIP */
    1340 if( varmapfw != NULL )
    1341 SCIPhashmapFree(&varmapfw);
    1342
    1343 if( probingscip != NULL )
    1344 {
    1345 SCIP_CALL( SCIPfree(&probingscip) );
    1346 }
    1347
    1348 if( heurdata->stage3 )
    1349 {
    1350 SCIP_CALL( SCIPfreeSol(scip, &closestsol) );
    1351 }
    1352
    1353 /* free memory */
    1354 for( j = 0; j < heurdata->cyclelength; j++ )
    1355 {
    1356 SCIP_CALL( SCIPfreeSol(scip, &lastroundedsols[j]) );
    1357 }
    1358
    1359 SCIPfreeBufferArray(scip, &cycles);
    1360 SCIPfreeBufferArray(scip, &lastalphas);
    1361 SCIPfreeBufferArray(scip, &lastroundedsols);
    1362 SCIPfreeBufferArray(scip, &mostfracvals);
    1363 SCIPfreeBufferArray(scip, &mostfracvars);
    1364
    1365 SCIPdebugMsg(scip, "feasibility pump finished [%d iterations done].\n", nloops);
    1366
    1367#ifdef SCIP_STATISTIC
    1368 if( nfracs == 0 )
    1369 {
    1370 double objval;
    1371 double primalBound;
    1372
    1373 objval = SCIPgetSolOrigObj(scip, heurdata->sol);
    1374 primalBound = SCIPgetPrimalbound(scip);
    1375 SCIPstatisticMessage("feasibility pump found: 1, objval: %f, iterations: %d, primal bound: %f\n", objval, nloops, primalBound);
    1376 }
    1377 else
    1378 {
    1379 double primalBound;
    1380
    1381 primalBound = SCIPgetPrimalbound(scip);
    1382 SCIPstatisticMessage("feasibility pump found: 0, objval: +inf, iterations: %d, primal bound: %f\n", nloops, primalBound);
    1383 }
    1384
    1385#endif /* SCIP_STATISTIC */
    1386
    1387 return SCIP_OKAY;
    1388}
    1389
    1390
    1391/*
    1392 * primal heuristic specific interface methods
    1393 */
    1394
    1395/** creates the feaspump primal heuristic and includes it in SCIP */
    1397 SCIP* scip /**< SCIP data structure */
    1398 )
    1399{
    1400 SCIP_HEURDATA* heurdata;
    1401 SCIP_HEUR* heur;
    1402
    1403 /* create Feaspump primal heuristic data */
    1404 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
    1405
    1406 /* include primal heuristic */
    1409 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecFeaspump, heurdata) );
    1410
    1411 assert(heur != NULL);
    1412
    1413 /* primal heuristic is safe to use in exact solving mode */
    1414 SCIPheurMarkExact(heur);
    1415
    1416 /* set non-NULL pointers to callback methods */
    1417 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyFeaspump) );
    1418 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeFeaspump) );
    1419 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitFeaspump) );
    1420 SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitFeaspump) );
    1421 SCIP_CALL( SCIPsetHeurInitsol(scip, heur, heurInitsolFeaspump) );
    1422 SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolFeaspump) );
    1423
    1424 /* add feaspump primal heuristic parameters */
    1426 "heuristics/" HEUR_NAME "/maxlpiterquot",
    1427 "maximal fraction of diving LP iterations compared to node LP iterations",
    1428 &heurdata->maxlpiterquot, FALSE, DEFAULT_MAXLPITERQUOT, 0.0, SCIP_REAL_MAX, NULL, NULL) );
    1430 "heuristics/" HEUR_NAME "/objfactor",
    1431 "factor by which the regard of the objective is decreased in each round, 1.0 for dynamic",
    1432 &heurdata->objfactor, FALSE, DEFAULT_OBJFACTOR, 0.0, 1.0, NULL, NULL) );
    1434 "heuristics/" HEUR_NAME "/alpha",
    1435 "initial weight of the objective function in the convex combination",
    1436 &heurdata->alpha, FALSE, DEFAULT_ALPHA, 0.0, 1.0, NULL, NULL) );
    1438 "heuristics/" HEUR_NAME "/alphadiff",
    1439 "threshold difference for the convex parameter to perform perturbation",
    1440 &heurdata->alphadiff, FALSE, DEFAULT_ALPHADIFF, 0.0, 1.0, NULL, NULL) );
    1441
    1443 "heuristics/" HEUR_NAME "/maxlpiterofs",
    1444 "additional number of allowed LP iterations",
    1445 &heurdata->maxlpiterofs, FALSE, DEFAULT_MAXLPITEROFS, 0, INT_MAX, NULL, NULL) );
    1447 "heuristics/" HEUR_NAME "/maxsols",
    1448 "total number of feasible solutions found up to which heuristic is called (-1: no limit)",
    1449 &heurdata->maxsols, TRUE, DEFAULT_MAXSOLS, -1, INT_MAX, NULL, NULL) );
    1451 "heuristics/" HEUR_NAME "/maxloops",
    1452 "maximal number of pumping loops (-1: no limit)",
    1453 &heurdata->maxloops, TRUE, DEFAULT_MAXLOOPS, -1, INT_MAX, NULL, NULL) );
    1455 "heuristics/" HEUR_NAME "/maxstallloops",
    1456 "maximal number of pumping rounds without fractionality improvement (-1: no limit)",
    1457 &heurdata->maxstallloops, TRUE, DEFAULT_MAXSTALLLOOPS, -1, INT_MAX, NULL, NULL) );
    1459 "heuristics/" HEUR_NAME "/minflips",
    1460 "minimum number of random variables to flip, if a 1-cycle is encountered",
    1461 &heurdata->minflips, TRUE, DEFAULT_MINFLIPS, 1, INT_MAX, NULL, NULL) );
    1463 "heuristics/" HEUR_NAME "/cyclelength",
    1464 "maximum length of cycles to be checked explicitly in each round",
    1465 &heurdata->cyclelength, TRUE, DEFAULT_CYCLELENGTH, 1, 100, NULL, NULL) );
    1467 "heuristics/" HEUR_NAME "/perturbfreq",
    1468 "number of iterations until a random perturbation is forced",
    1469 &heurdata->perturbfreq, TRUE, DEFAULT_PERTURBFREQ, 1, INT_MAX, NULL, NULL) );
    1470 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/neighborhoodsize",
    1471 "radius (using Manhattan metric) of the neighborhood to be searched in stage 3",
    1472 &heurdata->neighborhoodsize, FALSE, DEFAULT_NEIGHBORHOODSIZE, 1, INT_MAX, NULL, NULL) );
    1473
    1475 "heuristics/" HEUR_NAME "/beforecuts",
    1476 "should the feasibility pump be called at root node before cut separation?",
    1477 &heurdata->beforecuts, FALSE, DEFAULT_BEFORECUTS, NULL, NULL) );
    1479 "heuristics/" HEUR_NAME "/usefp20",
    1480 "should an iterative round-and-propagate scheme be used to find the integral points?",
    1481 &heurdata->usefp20, FALSE, DEFAULT_USEFP20, NULL, NULL) );
    1483 "heuristics/" HEUR_NAME "/pertsolfound",
    1484 "should a random perturbation be performed if a feasible solution was found?",
    1485 &heurdata->pertsolfound, FALSE, DEFAULT_PERTSOLFOUND, NULL, NULL) );
    1487 "heuristics/" HEUR_NAME "/stage3",
    1488 "should we solve a local branching sub-MIP if no solution could be found?",
    1489 &heurdata->stage3, FALSE, DEFAULT_STAGE3, NULL, NULL) );
    1490 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/copycuts",
    1491 "should all active cuts from cutpool be copied to constraints in subproblem?",
    1492 &heurdata->copycuts, TRUE, DEFAULT_COPYCUTS, NULL, NULL) );
    1493
    1494 return SCIP_OKAY;
    1495}
    Constraint handler for linear constraints in their most general form, .
    #define NULL
    Definition: def.h:257
    #define SCIP_MAXSTRLEN
    Definition: def.h:278
    #define SCIP_Longint
    Definition: def.h:150
    #define SCIP_MAXTREEDEPTH
    Definition: def.h:306
    #define SCIP_REAL_MAX
    Definition: def.h:167
    #define SCIP_Bool
    Definition: def.h:100
    #define MIN(x, y)
    Definition: def.h:233
    #define SCIP_STRINGEQ(name, reference, retcode)
    Definition: def.h:454
    #define SCIP_Real
    Definition: def.h:165
    #define TRUE
    Definition: def.h:102
    #define FALSE
    Definition: def.h:103
    #define MAX(x, y)
    Definition: def.h:229
    #define SCIP_CALL_ABORT(x)
    Definition: def.h:343
    #define SCIP_LONGINT_FORMAT
    Definition: def.h:157
    #define REALABS(x)
    Definition: def.h:191
    #define SCIP_CALL(x)
    Definition: def.h:364
    SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    SCIP_RETCODE SCIPtranslateSubSols(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_VAR **subvars, SCIP_Bool *success, int *solindex)
    Definition: scip_copy.c:1438
    SCIP_RETCODE SCIPcopyConsCompression(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, const char *suffix, SCIP_VAR **fixedvars, SCIP_Real *fixedvals, int nfixedvars, SCIP_Bool global, SCIP_Bool enablepricing, SCIP_Bool threadsafe, SCIP_Bool passmessagehdlr, SCIP_Bool *valid)
    Definition: scip_copy.c:2962
    SCIP_RETCODE SCIPcheckCopyLimits(SCIP *sourcescip, SCIP_Bool *success)
    Definition: scip_copy.c:3250
    SCIP_RETCODE SCIPcopyCuts(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, int *ncutsadded)
    Definition: scip_copy.c:2114
    SCIP_RETCODE SCIPcopyParamSettings(SCIP *sourcescip, SCIP *targetscip)
    Definition: scip_copy.c:2548
    SCIP_RETCODE SCIPcopyLimits(SCIP *sourcescip, SCIP *targetscip)
    Definition: scip_copy.c:3293
    SCIP_Bool SCIPisStopped(SCIP *scip)
    Definition: scip_general.c:767
    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:514
    SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
    Definition: scip_sol.c:1250
    int SCIPgetNSols(SCIP *scip)
    Definition: scip_sol.c:2887
    SCIP_RETCODE SCIPunlinkSol(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1504
    SCIP_RETCODE SCIPtrySol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
    Definition: scip_sol.c:4017
    SCIP_RETCODE SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1293
    SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1890
    SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
    Definition: scip_sol.c:1569
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1763
    SCIP_RETCODE SCIPfreeTransform(SCIP *scip)
    Definition: scip_solve.c:3475
    SCIP_RETCODE SCIPsolve(SCIP *scip)
    Definition: scip_solve.c:2611
    SCIP_Longint SCIPgetNSolsFound(SCIP *scip)
    SCIP_Real SCIPgetPrimalbound(SCIP *scip)
    SCIP_Longint SCIPgetNNodes(SCIP *scip)
    SCIP_Longint SCIPgetNNodeLPIterations(SCIP *scip)
    SCIP_Longint SCIPgetNBestSolsFound(SCIP *scip)
    SCIP_Real SCIPgetCutoffbound(SCIP *scip)
    SCIP_Longint SCIPgetNLPIterations(SCIP *scip)
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfeasFrac(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasPositive(SCIP *scip, SCIP_Real val)
    int SCIPgetDepth(SCIP *scip)
    Definition: scip_tree.c:672
    SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
    Definition: var.c:23674
    SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
    Definition: var.c:23530
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24300
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23932
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23485
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23299
    SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
    Definition: var.c:24696
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24266
    SCIP_VAR * SCIPvarGetTransVar(SCIP_VAR *var)
    Definition: var.c:23704
    SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
    Definition: scip_var.c:5372
    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
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    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