Scippy

    SCIP

    Solving Constraint Integer Programs

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