Scippy

    SCIP

    Solving Constraint Integer Programs

    heur_lpface.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_lpface.c
    26 * @ingroup DEFPLUGINS_HEUR
    27 * @brief lpface primal heuristic that searches the optimal LP face inside a sub-MIP
    28 * @author Gregor Hendel
    29 */
    30
    31/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    32
    34#include "scip/cons_linear.h"
    35#include "scip/scipdefplugins.h"
    36#include "scip/heur_lpface.h"
    37#include "scip/pub_event.h"
    38#include "scip/pub_heur.h"
    39#include "scip/pub_lp.h"
    40#include "scip/pub_message.h"
    41#include "scip/pub_misc.h"
    42#include "scip/pub_sol.h"
    43#include "scip/pub_tree.h"
    44#include "scip/pub_var.h"
    45#include "scip/scip_branch.h"
    46#include "scip/scip_cons.h"
    47#include "scip/scip_copy.h"
    48#include "scip/scip_event.h"
    49#include "scip/scip_exact.h"
    50#include "scip/scip_general.h"
    51#include "scip/scip_heur.h"
    52#include "scip/scip_lp.h"
    53#include "scip/scip_mem.h"
    54#include "scip/scip_message.h"
    55#include "scip/scip_nodesel.h"
    56#include "scip/scip_numerics.h"
    57#include "scip/scip_param.h"
    58#include "scip/scip_prob.h"
    59#include "scip/scip_sol.h"
    60#include "scip/scip_solve.h"
    62#include "scip/scip_timing.h"
    63#include "scip/scip_tree.h"
    64#include "scip/scip_var.h"
    65#include <string.h>
    66
    67#define HEUR_NAME "lpface"
    68#define HEUR_DESC "LNS heuristic that searches the optimal LP face inside a sub-MIP"
    69#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_LNS
    70#define HEUR_PRIORITY -1104010
    71#define HEUR_FREQ 15
    72#define HEUR_FREQOFS 0
    73#define HEUR_MAXDEPTH -1
    74#define HEUR_TIMING SCIP_HEURTIMING_AFTERLPNODE
    75#define HEUR_USESSUBSCIP TRUE /**< does the heuristic use a secondary SCIP instance? */
    76
    77#define DEFAULT_MAXNODES 5000LL /**< maximum number of nodes to regard in the subproblem */
    78#define DEFAULT_MINNODES 50LL /**< minimum number of nodes to regard in the subproblem */
    79#define DEFAULT_MINFIXINGRATE 0.1 /**< required percentage of fixed integer variables in sub-MIP to run */
    80#define DEFAULT_NODESOFS 200LL /**< number of nodes added to the contingent of the total nodes */
    81#define DEFAULT_NODESQUOT 0.1 /**< subproblem nodes in relation to nodes of the original problem */
    82#define DEFAULT_LPLIMFAC 2.0 /**< factor by which the limit on the number of LP depends on the node limit */
    83#define DEFAULT_USELPROWS TRUE /**< should subproblem be created out of the rows in the LP rows,
    84 * otherwise, the copy constructors of the constraints handlers are used */
    85#define DEFAULT_COPYCUTS TRUE /**< if uselprows == FALSE, should all active cuts from cutpool be copied
    86 * to constraints in subproblem? */
    87#define DEFAULT_DUALBASISEQUATIONS FALSE /**< should the dually nonbasic rows be turned into equations? */
    88#define DEFAULT_KEEPSUBSCIP FALSE /**< should the heuristic continue solving the same sub-SCIP? */
    89#define DEFAULT_MINPATHLEN 5 /**< the minimum active search tree path length along which the lower bound
    90 * hasn't changed before heuristic becomes active */
    91/* event handler properties */
    92#define EVENTHDLR_NAME "Lpface"
    93#define EVENTHDLR_DESC "LP event handler for " HEUR_NAME " heuristic"
    94
    95/*
    96 * Data structures
    97 */
    98
    99/** data structure to keep sub-SCIP across runs */
    101{
    102 SCIP* subscip; /**< pointer to store sub-SCIP data structure */
    103 SCIP_VAR** subvars; /**< array of variables of the sub-problem */
    104 int nsubvars; /**< number of sub-problem variables */
    105 SCIP_Real objbound; /**< lower bound on objective for when sub SCIP was created */
    106};
    108
    109/** primal heuristic data */
    110struct SCIP_HeurData
    111{
    112 SCIP_Longint maxnodes; /**< maximum number of nodes to regard in the subproblem */
    113 SCIP_Longint minnodes; /**< minimum number of nodes to regard in the subproblem */
    114 SCIP_Longint nodesofs; /**< number of nodes added to the contingent of the total nodes */
    115 SCIP_Longint usednodes; /**< nodes already used by lpface in earlier calls */
    116 SCIP_Real nodesquot; /**< subproblem nodes in relation to nodes of the original problem */
    117
    118 unsigned int nfailures; /**< number of failures since last successful call */
    119 SCIP_Longint nextnodenumber; /**< number of nodes at which lpface should be called the next time */
    120 SCIP_Real lastlpobjinfeas; /**< last LP objective where the sub-MIP was run to proven infeasibility */
    121 SCIP_Real minfixingrate; /**< required percentage of fixed integer variables in sub-MIP to run */
    122 SCIP_Real nodelimit; /**< the nodelimit employed in the current sub-SCIP, for the event handler*/
    123 SCIP_Real lplimfac; /**< factor by which the limit on the number of LP depends on the node limit */
    124 SCIP_Bool uselprows; /**< should subproblem be created out of the rows in the LP rows? */
    125 SCIP_Bool copycuts; /**< if uselprows == FALSE, should all active cuts from cutpool be copied
    126 * to constraints in subproblem? */
    127 SCIP_Bool dualbasisequations; /**< should the dually nonbasic rows be turned into equations? */
    128 SCIP_Bool keepsubscip; /**< should the heuristic continue solving the same sub-SCIP? */
    129 char subscipobjective; /**< objective function in the sub-SCIP: (z)ero, (r)oot-LP-difference,
    130 * (i)nference, LP (f)ractionality, (o)riginal */
    131
    132 SCIP_STATUS submipstatus; /**< return status of the sub-MIP */
    133 SCIP_Longint submipnlpiters; /**< number of LP iterations of the sub-MIP */
    134 SCIP_Real submippresoltime; /**< time required to presolve the sub-MIP */
    135 int nvarsfixed; /**< the number of fixed variables by the heuristic */
    136 int minpathlen; /**< the minimum active search tree path length along which the lower bound
    137 * hasn't changed before heuristic becomes active */
    138 SUBSCIPDATA* subscipdata; /**< sub-SCIP data structure */
    139};
    140
    141/*
    142 * Local methods
    143 */
    144
    145/** determine variable fixings for sub-SCIP based on reduced costs */
    146static
    148 SCIP* scip, /**< SCIP data structure */
    149 SCIP_HEURDATA* heurdata, /**< primal heuristic data */
    150 SCIP_VAR** fixvars, /**< buffer to store variables that should be fixed */
    151 SCIP_Real* fixvals, /**< buffer to store corresponding fixing values */
    152 int* nfixvars, /**< pointer to store number of variables that should be fixed */
    153 SCIP_Bool* success /**< pointer to store whether enough integer variables were fixed */
    154 )
    155{
    156 SCIP_VAR** vars; /* original scip variables */
    157 SCIP_Real fixingrate; /* percentage of variables that are fixed */
    158 int nvars;
    159 int nbinvars;
    160 int nintvars;
    161 int i;
    162 int fixingcounter;
    163
    164 /* get required data of the main scip problem */
    165 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, &nbinvars, &nintvars, NULL, NULL) );
    166
    167 fixingcounter = 0;
    168
    169 assert(nvars >= nbinvars + nintvars);
    170
    171 *nfixvars = 0;
    172 /* loop over problem variables and fix all with nonzero reduced costs to their solution value */
    173 for( i = 0; i < nvars; i++ )
    174 {
    175 SCIP_Real solval;
    176 SCIP_COL* col;
    177 SCIP_Real redcost;
    178 SCIP_Real lbglobal;
    179 SCIP_Real ubglobal;
    180 SCIP_VAR* var;
    181
    182 var = vars[i];
    183
    184 /* skip non-column variables */
    186 continue;
    187
    188 /* skip relaxation only variables */
    189 if( SCIPvarIsRelaxationOnly(var) )
    190 continue;
    191
    192 solval = SCIPgetSolVal(scip, NULL, var);
    193 col = SCIPvarGetCol(vars[i]);
    194 assert(col != NULL);
    195 redcost = SCIPgetColRedcost(scip, col);
    196 lbglobal = SCIPvarGetLbGlobal(var);
    197 ubglobal = SCIPvarGetUbGlobal(var);
    198
    199 /* fix the variable to its solution value if variable is nonbasic (i.e., at one of its bounds)
    200 * with nonzero reduced costs
    201 */
    202 if( ! SCIPisDualfeasZero(scip, redcost) )
    203 {
    204 /* fix variable based on reduced cost information, respecting global bounds */
    205 if( (redcost > 0 && SCIPisFeasEQ(scip, solval, lbglobal)) ||
    206 (redcost < 0 && SCIPisFeasEQ(scip, solval, ubglobal)) )
    207 {
    208 assert(! SCIPisInfinity(scip, REALABS(solval)));
    209
    210 fixvars[*nfixvars] = var;
    211 fixvals[*nfixvars] = solval;
    212
    213 if( SCIPvarIsIntegral(var) )
    214 ++fixingcounter;
    215
    216 ++(*nfixvars);
    217 }
    218 }
    219 }
    220
    221 fixingrate = (SCIP_Real)fixingcounter / (SCIP_Real)(MAX(nbinvars + nintvars, 1));
    222 heurdata->nvarsfixed = fixingcounter;
    223
    224 /* if all variables were fixed or amount of fixed variables is insufficient, skip residual part of
    225 * subproblem creation and abort immediately
    226 */
    227 *success = (fixingcounter < nvars && fixingrate >= heurdata->minfixingrate);
    228
    229 SCIPdebugMsg(scip, " LP face heuristic fixed %senough variables (%d out of %d)\n",
    230 *success ? "": "not ", fixingcounter, nvars);
    231
    232 return SCIP_OKAY;
    233}
    234
    235/** creates the rows of the subproblem */
    236static
    238 SCIP* scip, /**< original SCIP data structure */
    239 SCIP* subscip, /**< SCIP data structure for the subproblem */
    240 SCIP_VAR** subvars, /**< the variables of the subproblem */
    241 SCIP_Bool dualbasisequations /**< should the dually nonbasic rows be turned into equations? */
    242 )
    243{
    244 SCIP_ROW** rows; /* original scip rows */
    245
    246 int nrows;
    247 int i;
    248
    249 /* get the rows and their number */
    250 SCIP_CALL( SCIPgetLPRowsData(scip, &rows, &nrows) );
    251
    252 /* copy all global rows to linear constraints, unless they contain relaxation-only variables */
    253 for( i = 0; i < nrows; i++ )
    254 {
    255 SCIP_VAR** consvars; /* new constraint's variables */
    256 SCIP_COL** cols; /* original row's columns */
    257 SCIP_CONS* cons; /* new constraint */
    258
    259 SCIP_Real* vals; /* variables' coefficient values of the row */
    260 SCIP_Real constant; /* constant added to the row */
    261 SCIP_Real lhs; /* left hand side of the row */
    262 SCIP_Real rhs; /* left right side of the row */
    263 SCIP_Real dualsol;
    264 SCIP_Real rowsolactivity;
    265 int j;
    266 int nnonz;
    267
    268 /* ignore rows that are only locally valid */
    269 if( SCIProwIsLocal(rows[i]) )
    270 continue;
    271
    272 /* get the row's data */
    273 constant = SCIProwGetConstant(rows[i]);
    274 vals = SCIProwGetVals(rows[i]);
    275 nnonz = SCIProwGetNNonz(rows[i]);
    276 cols = SCIProwGetCols(rows[i]);
    277
    278 /* only subtract constant if left hand side is not infinite */
    279 lhs = SCIProwGetLhs(rows[i]);
    280 if( ! SCIPisInfinity(scip, -lhs) )
    281 lhs -= constant;
    282
    283 /* only subtract constant if right hand side is not infinite */
    284 rhs = SCIProwGetRhs(rows[i]);
    285 if( ! SCIPisInfinity(scip, rhs) )
    286 rhs -= constant;
    287
    288 assert(lhs <= rhs);
    289
    290 /* allocate memory array to be filled with the corresponding subproblem variables */
    291 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nnonz) );
    292 for( j = 0; j < nnonz; j++ )
    293 {
    294 consvars[j] = subvars[SCIPvarGetProbindex(SCIPcolGetVar(cols[j]))];
    295 if( consvars[j] == NULL )
    296 break;
    297 }
    298 /* skip row if not all variables are in sub-SCIP, i.e., relaxation-only variables */
    299 if( j < nnonz )
    300 {
    301 SCIPfreeBufferArray(scip, &consvars);
    302 continue;
    303 }
    304
    305 dualsol = SCIProwGetDualsol(rows[i]);
    306 rowsolactivity = SCIPgetRowActivity(scip, rows[i]);
    307
    308 /* transform into equation if the row is sharp and has a nonzero dual solution */
    309 if( dualbasisequations && ! SCIPisDualfeasZero(scip, dualsol) )
    310 {
    311 if( dualsol > 0.0 && SCIPisFeasEQ(scip, rowsolactivity, lhs) )
    312 rhs = lhs;
    313 else if( dualsol < 0.0 && SCIPisFeasEQ(scip, rowsolactivity, rhs) )
    314 lhs = rhs;
    315 }
    316
    317 /* create a new linear constraint and add it to the subproblem */
    318 SCIP_CALL( SCIPcreateConsLinear(subscip, &cons, SCIProwGetName(rows[i]), nnonz, consvars, vals, lhs, rhs,
    320 SCIP_CALL( SCIPaddCons(subscip, cons) );
    321 SCIP_CALL( SCIPreleaseCons(subscip, &cons) );
    322
    323 /* free temporary memory */
    324 SCIPfreeBufferArray(scip, &consvars);
    325 }
    326
    327 return SCIP_OKAY;
    328}
    329
    330/** create the LP face subproblem constraints */
    331static
    333 SCIP* scip, /**< original SCIP data structure */
    334 SCIP* subscip, /**< SCIP data structure for the subproblem */
    335 SCIP_VAR** subvars, /**< the variables of the subproblem */
    336 SCIP_HEURDATA* heurdata /**< primal heuristic data */
    337 )
    338{
    339 SCIP_VAR** vars = SCIPgetVars(scip);
    340 int nvars = SCIPgetNVars(scip);
    341 SCIP_Real lowerbound;
    342 SCIP_CONS* origobjcons;
    343 int i;
    344#ifndef NDEBUG
    345 int nobjvars = 0;
    346#endif
    347
    348 /* we copy the rows of the LP, if enough variables could be fixed and we work on the MIP relaxation of the problem */
    349 if( heurdata->uselprows )
    350 {
    351 SCIP_CALL( createRows(scip, subscip, subvars, heurdata->dualbasisequations) );
    352 }
    353
    354 /* add an equation that the objective function must be equal to the lower bound */
    355 lowerbound = SCIPgetLowerbound(scip);
    356
    357 SCIP_CALL( SCIPcreateConsLinear(subscip, &origobjcons, "objbound_of_origscip", 0, NULL, NULL, lowerbound, lowerbound,
    359
    360 for( i = 0; i < nvars; ++i)
    361 {
    362 if( ! SCIPisZero(subscip, SCIPvarGetObj(vars[i])) )
    363 {
    364 assert(subvars[i] != NULL); /* a relaxation-only variable cannot have an objective coefficient */
    365 SCIP_CALL( SCIPaddCoefLinear(subscip, origobjcons, subvars[i], SCIPvarGetObj(vars[i])) );
    366#ifndef NDEBUG
    367 nobjvars++;
    368#endif
    369 }
    370 }
    371 assert(nobjvars == SCIPgetNObjVars(scip));
    372
    373 SCIP_CALL( SCIPaddCons(subscip, origobjcons) );
    374 SCIP_CALL( SCIPreleaseCons(subscip, &origobjcons) );
    375
    376 return SCIP_OKAY;
    377}
    378
    379/** updates heurdata after an unsuccessful run of lpface */
    380static
    382 SCIP* scip, /**< original SCIP data structure */
    383 SCIP_HEURDATA* heurdata /**< primal heuristic data */
    384 )
    385{
    386 /* increase number of failures, calculate next node at which lpface should be called and update actual solutions */
    387 heurdata->nfailures++;
    388 heurdata->nextnodenumber = (heurdata->nfailures <= 25
    389 ? SCIPgetNNodes(scip) + 100*(2LL << heurdata->nfailures) /*lint !e703*/
    391}
    392
    393/** calculate a node limit based on node limiting parameters of the heuristic */
    394static
    396 SCIP* scip, /**< (original) SCIP data structure */
    397 SCIP_HEUR* heur, /**< LP face heuristic */
    398 SCIP_HEURDATA* heurdata /**< primal heuristic data */
    399 )
    400{
    401 SCIP_Longint nodelimit;
    402
    403 /* calculate the maximal number of branching nodes until heuristic is aborted */
    404 nodelimit = (SCIP_Longint)(heurdata->nodesquot * SCIPgetNNodes(scip));
    405
    406 /* count the setup costs for the sub-MIP as 100 nodes */
    407 nodelimit -= 100 * SCIPheurGetNCalls(heur);
    408
    409 /* add the offset */
    410 nodelimit += heurdata->nodesofs;
    411
    412 /* subtract previously used nodes */
    413 nodelimit -= heurdata->usednodes;
    414
    415 /* do not use more than the maximum number of allowed nodes in one run */
    416 nodelimit = MIN(nodelimit, heurdata->maxnodes);
    417
    418 /* if the subscip has been kept from a previous run, add the number of already processed nodes */
    419 if( heurdata->subscipdata->subscip != NULL )
    420 nodelimit += SCIPgetNNodes(heurdata->subscipdata->subscip);
    421
    422 return nodelimit;
    423}
    424
    425/** sets node, time, and memory limit according to the parameter settings of the heuristic */
    426static
    428 SCIP* scip, /**< original SCIP data structure */
    429 SCIP* subscip, /**< data structure of the sub-problem */
    430 SCIP_HEUR* heur, /**< LP face heuristic */
    431 SCIP_HEURDATA* heurdata, /**< heuristic data structure */
    432 SCIP_Bool* success /**< did we successfully set all parameters up? */
    433 )
    434{
    435 SCIP_Real timelimit;
    436 SCIP_Real memorylimit;
    437 SCIP_Longint nodelimit;
    438 SCIP_Bool avoidmemout;
    439
    440 *success = TRUE;
    441
    442 /* check whether there is enough time and memory left */
    443 SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
    444 SCIP_CALL( SCIPgetRealParam(scip, "limits/memory", &memorylimit) );
    445 SCIP_CALL( SCIPgetBoolParam(scip, "misc/avoidmemout", &avoidmemout) );
    446
    447 if( ! SCIPisInfinity(scip, timelimit) )
    448 timelimit -= SCIPgetSolvingTime(scip);
    449
    450 /* substract the memory already used by the main SCIP and the estimated memory usage of external software */
    451 if( ! SCIPisInfinity(scip, memorylimit) )
    452 {
    453 memorylimit -= SCIPgetMemUsed(scip)/1048576.0;
    454 memorylimit -= SCIPgetMemExternEstim(scip)/1048576.0;
    455 }
    456
    457 /* abort if no time is left or not enough memory (we don't abort in this case if misc_avoidmemout == FALSE)
    458 * to create a copy of SCIP, including external memory usage */
    459 if( timelimit <= 0.0 || (avoidmemout && memorylimit <= 2.0 * SCIPgetMemExternEstim(scip) / 1048576.0) )
    460 {
    461 *success = FALSE;
    462 return SCIP_OKAY;
    463 }
    464
    465 /* calculate node limit for the subproblem */
    466 nodelimit = calcNodeLimit(scip, heur, heurdata);
    467
    468 /* we should have aborted the sub-SCIP procedure earlier if no additional nodes are allowed
    469 * with the current parameter settings
    470 */
    471 assert(nodelimit > SCIPgetNNodes(subscip));
    472
    473 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", nodelimit) );
    474 heurdata->nodelimit = nodelimit;
    475
    476 /* set also the other two limits */
    477 SCIP_CALL( SCIPsetRealParam(subscip, "limits/time", timelimit) );
    478 SCIP_CALL( SCIPsetRealParam(subscip, "limits/memory", memorylimit) );
    479
    480 /* disable bound limits */
    481 SCIP_CALL( SCIPsetRealParam(subscip, "limits/primal", SCIP_INVALID) );
    482 SCIP_CALL( SCIPsetRealParam(subscip, "limits/dual", SCIP_INVALID) );
    483
    484 return SCIP_OKAY;
    485}
    486
    487/** sets all one-time parameter settings like search strategy, but no limits */
    488static
    490 SCIP* subscip /**< data structure of the sub-problem */
    491 )
    492{
    493 /* do not abort subproblem on CTRL-C */
    494 SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
    495
    496 /* for debugging lpface, enable MIP output */
    497#ifdef SCIP_DEBUG
    498 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 5) );
    499 SCIP_CALL( SCIPsetIntParam(subscip, "display/freq", 1) );
    500#endif
    501
    502 /* disable statistic timing inside sub SCIP */
    503 SCIP_CALL( SCIPsetBoolParam(subscip, "timing/statistictiming", FALSE) );
    504
    505 /* forbid recursive call of heuristics and separators solving subMIPs */
    506 SCIP_CALL( SCIPsetSubscipsOff(subscip, TRUE) );
    507
    508 /* disable expensive cutting plane separation */
    510
    511 /* disable expensive presolving */
    513
    514 /* use restart depth first node selection */
    515 if( SCIPfindNodesel(subscip, "restartdfs") != NULL && ! SCIPisParamFixed(subscip, "nodeselection/restartdfs/stdpriority") )
    516 {
    517 SCIP_CALL( SCIPsetIntParam(subscip, "nodeselection/restartdfs/stdpriority", INT_MAX/4) );
    518 }
    519
    520 /* use inference branching */
    521 if( SCIPfindBranchrule(subscip, "inference") != NULL && ! SCIPisParamFixed(subscip, "branching/inference/priority") )
    522 {
    523 SCIP_CALL( SCIPsetIntParam(subscip, "branching/inference/priority", INT_MAX/4) );
    524 }
    525
    526 /* enable conflict analysis, disable analysis of boundexceeding LPs, and restrict conflict pool */
    527 if( !SCIPisParamFixed(subscip, "conflict/enable") )
    528 {
    529 SCIP_CALL( SCIPsetBoolParam(subscip, "conflict/enable", TRUE) );
    530 }
    531 if( !SCIPisParamFixed(subscip, "conflict/useboundlp") )
    532 {
    533 SCIP_CALL( SCIPsetCharParam(subscip, "conflict/useboundlp", 'o') );
    534 }
    535 if( !SCIPisParamFixed(subscip, "conflict/maxstoresize") )
    536 {
    537 SCIP_CALL( SCIPsetIntParam(subscip, "conflict/maxstoresize", 100) );
    538 }
    539
    540 return SCIP_OKAY;
    541}
    542
    543/** reset the sub-SCIP data to its default values */
    544static
    546 SUBSCIPDATA* subscipdata /**< data structure of the sub-problem */
    547 )
    548{
    549 subscipdata->subscip = NULL;
    550 subscipdata->subvars = NULL;
    551 subscipdata->nsubvars = 0;
    552 subscipdata->objbound = SCIP_INVALID;
    553}
    554
    555/** free the stored sub-SCIP information */
    556static
    558 SCIP* scip, /**< original SCIP data structure */
    559 SUBSCIPDATA* subscipdata /**< data structure of the sub-problem */
    560 )
    561{
    562 assert(subscipdata != NULL);
    563
    564 /* free the subscipdata's scip */
    565 if( subscipdata->subscip != NULL )
    566 {
    567 SCIP_CALL( SCIPfree(&subscipdata->subscip) );
    568 }
    569
    570 subscipdata->subscip = NULL;
    571
    572 /* free the subscip variables */
    573 if( subscipdata->subvars != NULL )
    574 {
    575 assert(subscipdata->nsubvars > 0);
    576 SCIPfreeBlockMemoryArray(scip, &subscipdata->subvars, subscipdata->nsubvars);
    577 }
    578
    579 subscipdataReset(subscipdata);
    580
    581 return SCIP_OKAY;
    582}
    583
    584/** store the sub-SCIP to the data structure */
    585static
    587 SCIP* scip, /**< original SCIP data structure */
    588 SUBSCIPDATA* subscipdata, /**< data structure of the sub-problem */
    589 SCIP* subscip, /**< sub scip data structure to keep */
    590 SCIP_VAR** subvars, /**< sub scip variable array in the order of the main SCIP variables */
    591 int nvars /**< number of sub SCIP variables */
    592 )
    593{
    594 assert(scip != NULL);
    595 assert(subscipdata != NULL);
    596 assert(subscip != NULL);
    597 assert(subvars != NULL);
    598 assert(nvars == SCIPgetNVars(scip));
    599
    600 assert(subscipdata->subscip == NULL);
    601 assert(subscipdata->subvars == NULL);
    602
    603 subscipdata->subscip = subscip;
    604 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &subscipdata->subvars, subvars, nvars) );
    605 subscipdata->nsubvars = nvars;
    606
    608
    609 return SCIP_OKAY;
    610}
    611
    612#ifdef SCIP_DEBUG
    613/** print debug message listing solving time, nodes, and status of sub-SCIP */
    614static
    615SCIP_RETCODE subscipGetInfo(
    616 SCIP* scip, /**< SCIP data structure */
    617 SCIP* subscip /**< sub SCIP data */
    618 )
    619{
    620 SCIP_Real timelimit;
    621 SCIP_Real memorylimit;
    622 SCIP_Longint nodelimit;
    623 SCIP_Real time;
    624 SCIP_Longint nodes;
    625 SCIP_STATUS status;
    626
    627 SCIP_CALL( SCIPgetRealParam(subscip, "limits/time", &timelimit) );
    628 SCIP_CALL( SCIPgetRealParam(subscip, "limits/memory", &memorylimit) );
    629 SCIP_CALL( SCIPgetLongintParam(subscip, "limits/nodes", &nodelimit) );
    630
    631 time = SCIPgetSolvingTime(subscip);
    632 nodes = SCIPgetNNodes(subscip);
    633 status = SCIPgetStatus(subscip);
    634
    635 SCIPdebugMsg(scip, "SCIP info: Time: %.1f (Limit: %.1f) Nodes: %"SCIP_LONGINT_FORMAT" (Limit: %"SCIP_LONGINT_FORMAT") Status: %d\n",
    636 time, timelimit, nodes, nodelimit, status);
    637
    638 return SCIP_OKAY;
    639}
    640#endif
    641
    642/** create the objective function based on the user selection */
    643static
    645 SCIP* scip, /**< SCIP data structure */
    646 SCIP* subscip, /**< sub-SCIP data structure */
    647 SCIP_VAR* var, /**< SCIP variable */
    648 SCIP_VAR* subvar, /**< sub-SCIP variable whose objective coefficient is changed */
    649 SCIP_HEURDATA* heurdata /**< heuristic data structure to control how the objective is changed */
    650 )
    651{
    652 SCIP_Real objcoeff;
    653 SCIP_Real upfrac;
    654 SCIP_Real downfrac;
    655 SCIP_Real lpsolval;
    656 SCIP_Real rootlpsolval;
    657
    658 /* create the objective value based on the choice of the sub-SCIP objective */
    659 switch( heurdata->subscipobjective )
    660 {
    661 /* use zero as objective function */
    662 case 'z':
    663 objcoeff = 0.0;
    664 break;
    665
    666 /* use current LP fractionality as objective */
    667 case 'f':
    668 lpsolval = SCIPvarGetLPSol(var);
    669 downfrac = SCIPfrac(scip, lpsolval);
    670 upfrac = 1.0 - downfrac;
    671
    672 objcoeff = downfrac - upfrac;
    673 break;
    674
    675 /* use root LP solution difference */
    676 case 'r':
    677 lpsolval = SCIPvarGetLPSol(var);
    678 rootlpsolval = SCIPvarGetRootSol(var);
    679 objcoeff = rootlpsolval - lpsolval;
    680 break;
    681
    682 /* use average inferences */
    683 case 'i':
    686 break;
    687
    688 /* use original objective function */
    689 case 'o':
    690 objcoeff = SCIPvarGetObj(var);
    691 break;
    692 default:
    693 objcoeff = 0.0;
    694 break;
    695 }
    696
    697 SCIP_CALL( SCIPchgVarObj(subscip, subvar, objcoeff) );
    698
    699 return SCIP_OKAY;
    700}
    701
    702/* ---------------- Callback methods of event handler ---------------- */
    703
    704/** execution callback of the event handler for Lpface sub-SCIP
    705 *
    706 * we interrupt the solution process if we hit the LP iteration limit per node
    707 */
    708static
    709SCIP_DECL_EVENTEXEC(eventExecLpface)
    710{
    711 SCIP_HEURDATA* heurdata;
    712
    713 assert(eventhdlr != NULL);
    714 assert(eventdata != NULL);
    715 assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
    716 assert(event != NULL);
    718
    719 heurdata = (SCIP_HEURDATA*)eventdata;
    720 assert(heurdata != NULL);
    721
    722 /* interrupt solution process of sub-SCIP */
    723 if( SCIPgetNLPs(scip) > heurdata->lplimfac * heurdata->nodelimit )
    724 {
    725 SCIPdebugMsg(scip, "interrupt after %" SCIP_LONGINT_FORMAT " LPs\n",SCIPgetNLPs(scip));
    727 }
    728
    729 return SCIP_OKAY;
    730}
    731
    732/** setup and solve the subproblem and catch the return code */
    733static
    735 SCIP* scip, /**< SCIP data structure */
    736 SCIP* subscip, /**< sub-SCIP data structure */
    737 SCIP_HEURDATA* heurdata, /**< heuristics data */
    738 SCIP_VAR** subvars, /**< subproblem's variables */
    739 SCIP_VAR** vars, /**< original problem's variables */
    740 SCIP_VAR** fixvars, /**< variables that should be fixed */
    741 SCIP_Real* fixvals, /**< corresponding fixing values */
    742 int nfixvars, /**< number of variables that should be fixed */
    743 int nvars /**< number of original problem's variables */
    744 )
    745{
    746 SCIP_HASHMAP* varmapfw = NULL; /* mapping of SCIP variables to sub-SCIP variables */
    747 SCIP_Bool success;
    748 int i;
    749
    750 assert( subscip != NULL );
    751 assert( heurdata != NULL );
    752 assert( vars != NULL );
    753
    754 /* create the variable hash map */
    755 SCIP_CALL( SCIPhashmapCreate(&varmapfw, SCIPblkmem(subscip), nvars) );
    756 success = FALSE;
    757
    758 if( heurdata->uselprows )
    759 {
    760 SCIP_Bool valid;
    761 char probname[SCIP_MAXSTRLEN];
    762
    763 /* copy all plugins */
    765 TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, &valid) );
    766
    767 /* copy parameter settings */
    769
    770 /* even when solving exactly, sub-SCIP heuristics should be run in floating-point mode, since the exactsol constraint
    771 * handler is in place to perform a final repair step
    772 */
    774
    775 /* get name of the original problem and add the string "_lpfacesub" */
    776 (void) SCIPsnprintf(probname, SCIP_MAXSTRLEN, "%s_lpfacesub", SCIPgetProbName(scip));
    777
    778 /* create the subproblem */
    779 SCIP_CALL( SCIPcreateProbBasic(subscip, probname) );
    781
    782 /* copy all variables */
    783 SCIP_CALL( SCIPcopyVars(scip, subscip, varmapfw, NULL, fixvars, fixvals, nfixvars, TRUE) );
    784 }
    785 else
    786 {
    787 SCIP_CALL( SCIPcopyConsCompression(scip, subscip, varmapfw, NULL, "lpface", fixvars, fixvals, nfixvars, TRUE, FALSE, FALSE, TRUE, &success) );
    788
    789 if( heurdata->copycuts )
    790 {
    791 /* copies all active cuts from cutpool of sourcescip to linear constraints in targetscip */
    792 SCIP_CALL( SCIPcopyCuts(scip, subscip, varmapfw, NULL, TRUE, NULL) );
    793 }
    794 }
    795 assert(!SCIPisExact(subscip));
    796
    797 /* fill subvars array with mapping from original variables and set the objective coefficient to the desired value */
    798 for( i = 0; i < nvars; i++ )
    799 {
    800 subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, vars[i]);
    801
    802 if( subvars[i] != NULL )
    803 {
    804 SCIP_CALL( changeSubvariableObjective(scip, subscip, vars[i], subvars[i], heurdata) );
    805 }
    806 }
    807
    808 /* free hash map */
    809 SCIPhashmapFree(&varmapfw);
    810
    811 /* disable output to console */
    812 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) );
    813
    814 /* fix variables that are at their bounds and have nonzero reduced costs */
    815 SCIP_CALL( setupSubproblem(scip, subscip, subvars, heurdata) );
    816
    817 /* set up sub-SCIP parameters */
    819
    820 return SCIP_OKAY;
    821}
    822
    823/** setup and solve the subproblem and catch the return code */
    824static
    826 SCIP* scip, /**< SCIP data structure */
    827 SCIP* subscip, /**< sub-SCIP data structure */
    828 SCIP_HEUR* heur, /**< mutation heuristic */
    829 SCIP_HEURDATA* heurdata, /**< heuristics data */
    830 SCIP_VAR** subvars, /**< subproblem's variables */
    831 SCIP_RESULT* result, /**< pointer to store the result */
    832 SCIP_Real focusnodelb, /**< lower bound of the focus node */
    833 SCIP_Bool* keepthisscip /**< should the subscip be kept or deleted? */
    834 )
    835{
    836 SCIP_EVENTHDLR* eventhdlr;
    837 SCIP_Bool success;
    838
    839 assert( scip != NULL );
    840 assert( subscip != NULL );
    841 assert( heur != NULL );
    842 assert( heurdata != NULL );
    843 assert( subvars != NULL );
    844
    845 /* create event handler for LP events */
    846 SCIP_CALL( SCIPincludeEventhdlrBasic(subscip, &eventhdlr, EVENTHDLR_NAME, EVENTHDLR_DESC, eventExecLpface, NULL) );
    847 if( eventhdlr == NULL )
    848 {
    849 SCIPerrorMessage("event handler for " HEUR_NAME " heuristic not found.\n");
    850 return SCIP_PLUGINNOTFOUND;
    851 }
    852
    853 /* determine node, memory, and time limits for the sub-SCIP. Both node and time limit change with every call to
    854 * the heuristic
    855 */
    856 SCIP_CALL( setSubscipLimits(scip, subscip, heur, heurdata, &success) );
    857
    858 /* if we did not succeed to set the limits of the subscip to let it run, we won't keep it any longer */
    859 if( !success )
    860 {
    861 *keepthisscip = FALSE;
    862
    863 return SCIP_OKAY;
    864 }
    865
    866 /* catch LP events of sub-SCIP */
    867 SCIP_CALL( SCIPtransformProb(subscip) );
    868 SCIP_CALL( SCIPcatchEvent(subscip, SCIP_EVENTTYPE_LPSOLVED, eventhdlr, (SCIP_EVENTDATA*) heurdata, NULL) );
    869
    870#ifdef WRITELPFACEPROB
    871 {
    872 char probfilename[] = "./lpface_prob.mps";
    873 char paramfilename[] = "./lpface_prob.set";
    874 SCIPinfoMessage(scip, NULL, "Writing problem and parameters to file: <%s> <%s>\n", probfilename, paramfilename);
    875 SCIP_CALL( SCIPwriteOrigProblem(subscip, probfilename, NULL, FALSE) );
    876 SCIP_CALL( SCIPwriteParams(subscip, paramfilename, TRUE, TRUE) );
    877 }
    878#endif
    879
    880 /* we must not be infeasible at this stage */
    881 assert(SCIPgetStatus(subscip) != SCIP_STATUS_INFEASIBLE);
    882
    883 /* solve the subproblem */
    884 SCIPdebugMsg(scip, "Solve Lpface subMIP\n");
    885 SCIPdebug(
    886 SCIP_CALL( subscipGetInfo(scip, subscip) );
    887 )
    888
    889 /* Errors in solving the subproblem should not kill the overall solving process.
    890 * Hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
    891 */
    892 SCIP_CALL_ABORT( SCIPsolve(subscip) );
    893
    894 /* print solving statistics of subproblem if we are in SCIP's debug mode */
    896
    897 /* save useful information regarding the subscip runs */
    898 heurdata->usednodes += SCIPgetNNodes(subscip);
    899 heurdata->submipnlpiters += SCIPgetNLPIterations(subscip);
    900 heurdata->submippresoltime += SCIPgetPresolvingTime(subscip);
    901 heurdata->submipstatus = SCIPgetStatus(subscip);
    902
    903 /* store the focus node lower bound as infeasible to avoid running on this face again */
    904 if( heurdata->submipstatus == SCIP_STATUS_INFEASIBLE )
    905 {
    906 heurdata->lastlpobjinfeas = focusnodelb;
    907 *keepthisscip = FALSE;
    908 }
    909 else if( SCIPgetNSols(subscip) > 0 )
    910 {
    911 int solindex;
    912
    913 /* check, whether a solution was found;
    914 * due to numerics, it might happen that not all solutions are feasible -> try all solutions until one is accepted
    915 */
    916 SCIP_CALL( SCIPtranslateSubSols(scip, subscip, heur, subvars, &success, &solindex) );
    917 SCIPdebugMsg(scip, "Transfer was %s successful\n", success ? "" : "not");
    918
    919 /* we found an optimal solution and are done. Thus, we free the subscip immediately */
    920 if( success )
    921 {
    922 *keepthisscip = FALSE;
    923 *result = SCIP_FOUNDSOL;
    924 }
    925
    926 /* if solution could not be added to problem => run is counted as a failure */
    927 if( ! success || solindex != SCIPsolGetIndex(SCIPgetBestSol(scip)) )
    928 updateFailureStatistic(scip, heurdata);
    929 }
    930 else
    931 {
    932 /* if no new solution was found, run was a failure */
    933 updateFailureStatistic(scip, heurdata);
    934 }
    935
    936 return SCIP_OKAY;
    937}
    938
    939/*
    940 * Callback methods of primal heuristic
    941 */
    942
    943/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
    944static
    945SCIP_DECL_HEURCOPY(heurCopyLpface)
    946{ /*lint --e{715}*/
    947 assert(scip != NULL);
    948 assert(heur != NULL);
    949 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
    950
    951 /* call inclusion method of primal heuristic */
    953
    954 return SCIP_OKAY;
    955}
    956
    957/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
    958static
    959SCIP_DECL_HEURFREE(heurFreeLpface)
    960{ /*lint --e{715}*/
    961 SCIP_HEURDATA* heurdata;
    962
    963 assert(heur != NULL);
    964 assert(scip != NULL);
    965
    966 /* get heuristic data */
    967 heurdata = SCIPheurGetData(heur);
    968 assert(heurdata != NULL);
    969
    970 /* free heuristic data */
    971 SCIPfreeBlockMemory(scip, &heurdata);
    972 SCIPheurSetData(heur, NULL);
    973
    974 return SCIP_OKAY;
    975}
    976
    977/** initialization method of primal heuristic (called after problem was transformed) */
    978static
    979SCIP_DECL_HEURINIT(heurInitLpface)
    980{ /*lint --e{715}*/
    981 SCIP_HEURDATA* heurdata;
    982
    983 assert(heur != NULL);
    984 assert(scip != NULL);
    985
    986 /* get heuristic's data */
    987 heurdata = SCIPheurGetData(heur);
    988 assert(heurdata != NULL);
    989
    990 /* initialize data */
    991 heurdata->usednodes = 0;
    992 heurdata->nfailures = 0;
    993 heurdata->nextnodenumber = 0;
    994
    995 heurdata->submipstatus = SCIP_STATUS_UNKNOWN;
    996 heurdata->submipnlpiters = -1;
    997 heurdata->submippresoltime = 0.0;
    998 heurdata->nvarsfixed = -1;
    999
    1000 return SCIP_OKAY;
    1001}
    1002
    1003/** solving process initialization method of primal heuristic (called when branch and bound process is about to begin) */
    1004static
    1005SCIP_DECL_HEURINITSOL(heurInitsolLpface)
    1006{ /*lint --e{715}*/
    1007 SCIP_HEURDATA* heurdata;
    1008
    1009 assert(heur != NULL);
    1010 assert(scip != NULL);
    1011
    1012 /* get heuristic's data */
    1013 heurdata = SCIPheurGetData(heur);
    1014 assert(heurdata != NULL);
    1015
    1016 /* reset the last infeasible objective because it lives in transformed space and must be invalidated at every restart */
    1017 heurdata->lastlpobjinfeas = -SCIPinfinity(scip);
    1018
    1019 assert(heurdata->subscipdata == NULL);
    1020
    1021 /* variable order might have changed since the last run, reinitialize sub-SCIP data */
    1022 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata->subscipdata) );
    1023 subscipdataReset(heurdata->subscipdata);
    1024
    1025 return SCIP_OKAY;
    1026}
    1027
    1028/** solving process deinitialization method of primal heuristic (called before branch and bound process is exiting) */
    1029static
    1030SCIP_DECL_HEUREXITSOL(heurExitsolLpface)
    1031{ /*lint --e{715}*/
    1032 SCIP_HEURDATA* heurdata;
    1033
    1034 assert(heur != NULL);
    1035 assert(scip != NULL);
    1036
    1037 /* get heuristic's data */
    1038 heurdata = SCIPheurGetData(heur);
    1039 assert(heurdata != NULL);
    1040
    1041 /* variable order might change after restart, free the heuristic subscipdata */
    1042 assert(heurdata->keepsubscip || heurdata->subscipdata->subscip == NULL);
    1043 if( heurdata->subscipdata->subscip != NULL )
    1044 {
    1045 /* free kept data structures first */
    1046 SCIP_CALL( subscipdataFreeSubscip(scip, heurdata->subscipdata) );
    1047 }
    1048
    1049 /* free the sub-SCIP data structure */
    1050 SCIPfreeBlockMemory(scip, &heurdata->subscipdata);
    1051
    1052 return SCIP_OKAY;
    1053}
    1054
    1055#ifdef SCIP_STATISTIC
    1056/** deinitialization method of primal heuristic (called before transformed problem is freed) */
    1057static
    1059{ /*lint --e{715}*/
    1060 SCIP_HEURDATA* heurdata;
    1061
    1062 assert(heur != NULL);
    1063 assert(scip != NULL);
    1064
    1065 /* get heuristic's data */
    1066 heurdata = SCIPheurGetData(heur);
    1067 assert(heurdata != NULL);
    1068
    1070 "LP Face heuristic stats: Status: %d Nodes: %d LP iters: %d Fixed: %d Presolving time: %.2f\n",
    1071 heurdata->submipstatus, heurdata->usednodes, heurdata->submipnlpiters, heurdata->nvarsfixed, heurdata->submippresoltime);
    1072
    1073 return SCIP_OKAY;
    1074}
    1075#else
    1076#define heurExitLpface NULL
    1077#endif
    1078
    1079/** execution method of primal heuristic */
    1080static
    1081SCIP_DECL_HEUREXEC(heurExecLpface)
    1082{ /*lint --e{715}*/
    1083 SCIP* subscip; /* the subproblem created by lpface */
    1084 SCIP_HEURDATA* heurdata; /* primal heuristic data */
    1085 SCIP_VAR** vars; /* original problem's variables */
    1086 SCIP_VAR** subvars; /* subproblem's variables */
    1087 SCIP_RETCODE retcode;
    1088 SCIP_Bool keepthisscip;
    1089 SCIP_Real focusnodelb;
    1090 SCIP_Real rootlb;
    1091 SCIP_Longint nodelimit; /* node limit for the subproblem */
    1092 int nvars; /* number of original problem's variables */
    1093 int nbinvars;
    1094 int nintvars;
    1095
    1096 assert(scip != NULL);
    1097 assert(heur != NULL);
    1098 assert(result != NULL);
    1099
    1100 *result = SCIP_DELAYED;
    1101
    1102 /* we skip infeasible nodes */
    1103 if( nodeinfeasible )
    1104 return SCIP_OKAY;
    1105
    1106 /* do not run heuristic on nodes that were not solved to optimality */
    1108 return SCIP_OKAY;
    1109
    1110 /* LP face requires that the LP defines a valid lower bound for the current node */
    1112 return SCIP_OKAY;
    1113
    1114 assert(SCIPgetCurrentNode(scip) != NULL);
    1116 assert(!SCIPisInfinity(scip, focusnodelb));
    1117
    1118 /* do not run if the current focus node already has a lower bound higher than the LP value at the node,
    1119 * for example, due to strong branching
    1120 */
    1121 if( SCIPisGT(scip, focusnodelb, SCIPgetLPObjval(scip)) )
    1122 return SCIP_OKAY;
    1123
    1124 /* from the checked conditions, the LP objective should be the lower bound for the current node */
    1125 assert(SCIPisEQ(scip, focusnodelb, SCIPgetLPObjval(scip)));
    1126
    1127 /* only run at lower bound defining nodes */
    1128 if( SCIPisGT(scip, focusnodelb, SCIPgetLowerbound(scip)) )
    1129 return SCIP_OKAY;
    1130
    1131 /* get heuristic's data */
    1132 heurdata = SCIPheurGetData(heur);
    1133 assert(heurdata != NULL);
    1134
    1135 /* delay heuristic if the active search tree path is not deep enough */
    1136 if( SCIPgetDepth(scip) < heurdata->minpathlen - 1 )
    1137 return SCIP_OKAY;
    1138
    1139 /* the node number to run the heuristic again was not yet reached */
    1140 if( SCIPgetNNodes(scip) < heurdata->nextnodenumber )
    1141 return SCIP_OKAY;
    1142
    1143 /* only run if lower bound has increased since last LP objective where the sub-MIP was solved to infeasibility */
    1144 if( SCIPisEQ(scip, heurdata->lastlpobjinfeas, focusnodelb) )
    1145 return SCIP_OKAY;
    1146
    1147 /* make the reasoning stronger if the objective value must be integral */
    1149 && (! SCIPisIntegral(scip, focusnodelb) || SCIPisLT(scip, focusnodelb, heurdata->lastlpobjinfeas + 1.0)) )
    1150 return SCIP_OKAY;
    1151
    1152 rootlb = SCIPgetLowerboundRoot(scip);
    1153 assert(SCIPisLE(scip, rootlb, focusnodelb));
    1154
    1155 /* if the lower bound hasn't changed since the root node, we want to run anyway, otherwise we base our decision on the
    1156 * total path length of the active search tree along which the lower bound did not change anymore.
    1157 */
    1158 if( SCIPisLT(scip, rootlb, focusnodelb) )
    1159 {
    1160 SCIP_NODE* parent;
    1161 int nonimprovingpathlen = 0; /* the length of the current path (in edges) along which the lower bound stayed the same */
    1162
    1164
    1165 /* count the path length along which the dual bound has not changed */
    1166 while( SCIPisEQ(scip, SCIPnodeGetLowerbound(parent), focusnodelb) && nonimprovingpathlen < heurdata->minpathlen )
    1167 {
    1168 ++nonimprovingpathlen;
    1169
    1170 /* we cannot hit the root node because the root lower bound is strictly smaller */
    1171 assert(SCIPnodeGetParent(parent) != NULL);
    1172 parent = SCIPnodeGetParent(parent);
    1173 }
    1174
    1175 /* we return if the nonimproving path is too short measured by the heuristic frequency */
    1176 if( nonimprovingpathlen < heurdata->minpathlen )
    1177 {
    1178 /* we do not delay the heuristic if the path has length zero, otherwise it may be called at children so that
    1179 * the path length is sufficient
    1180 */
    1181 if( nonimprovingpathlen == 0 )
    1182 *result = SCIP_DIDNOTRUN;
    1183
    1184 return SCIP_OKAY;
    1185 }
    1186 }
    1187
    1188 *result = SCIP_DIDNOTRUN;
    1189
    1190 /* calculate the maximal number of branching nodes until heuristic is aborted */
    1191 nodelimit = calcNodeLimit(scip, heur, heurdata);
    1192
    1193 /* check whether we have enough nodes left to call subproblem solving */
    1194 if( nodelimit < heurdata->minnodes )
    1195 return SCIP_OKAY;
    1196
    1197 if( SCIPisStopped(scip) )
    1198 return SCIP_OKAY;
    1199
    1200 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, &nbinvars, &nintvars, NULL, NULL) );
    1201 assert(nvars > 0);
    1202
    1203 /* check whether discrete variables are present */
    1204 if( nbinvars == 0 && nintvars == 0 )
    1205 return SCIP_OKAY;
    1206
    1207 *result = SCIP_DIDNOTFIND;
    1208
    1209 keepthisscip = heurdata->keepsubscip;
    1210
    1211 /* check if variable number increased since last call to the sub-SCIP */
    1212 if( heurdata->subscipdata->subscip != NULL && heurdata->subscipdata->nsubvars != nvars )
    1213 {
    1214 SCIPdebugMsg(scip, "Free subscip of LP face heuristic because variable number %d changed since last call (was %d)\n",
    1215 nvars, heurdata->subscipdata->nsubvars);
    1216
    1217 SCIP_CALL( subscipdataFreeSubscip(scip, heurdata->subscipdata) );
    1218 }
    1219 else if( heurdata->subscipdata->subscip != NULL && SCIPisGT(scip, focusnodelb, heurdata->subscipdata->objbound) )
    1220 {
    1221 SCIPdebugMsg(scip, "Free subscip of LP face heuristic because of different dual bound: %16.9g > %16.9g\n",
    1222 SCIPretransformObj(scip, focusnodelb), SCIPretransformObj(scip, heurdata->subscipdata->objbound));
    1223
    1224 SCIP_CALL( subscipdataFreeSubscip(scip, heurdata->subscipdata) );
    1225 }
    1226
    1227 /* retrieve the sub-SCIP from the heuristic data structure */
    1228 if( heurdata->subscipdata->subscip != NULL )
    1229 {
    1230 subscip = heurdata->subscipdata->subscip;
    1231 subvars = heurdata->subscipdata->subvars;
    1232 nvars = heurdata->subscipdata->nsubvars;
    1233
    1234 SCIPdebug(
    1235 SCIPdebugMsg(scip, "Loaded sub-SCIP from previous run:\n");
    1236 SCIP_CALL( subscipGetInfo(scip, subscip) );
    1237 )
    1238 }
    1239 else
    1240 {
    1241 SCIP_VAR** fixvars;
    1242 SCIP_Real* fixvals;
    1243 int nfixvars;
    1244 SCIP_Bool success;
    1245
    1246 assert(heurdata->subscipdata->subscip == NULL);
    1247
    1248 /* allocate memory to hold sub-SCIP variables */
    1249 SCIP_CALL( SCIPallocBufferArray(scip, &subvars, nvars) );
    1250
    1251 SCIP_CALL( SCIPallocBufferArray(scip, &fixvars, nvars) );
    1252 SCIP_CALL( SCIPallocBufferArray(scip, &fixvals, nvars) );
    1253
    1254 SCIP_CALL( determineVariableFixings(scip, heurdata, fixvars, fixvals, &nfixvars, &success) );
    1255
    1256 if( ! success )
    1257 {
    1258 SCIPfreeBufferArray(scip, &fixvals);
    1259 SCIPfreeBufferArray(scip, &fixvars);
    1260 SCIPfreeBufferArray(scip, &subvars);
    1261
    1262 *result = SCIP_DIDNOTRUN;
    1263 return SCIP_OKAY;
    1264 }
    1265
    1266 SCIPdebugMsg(scip, "Creating new sub-Problem for LP face heuristic\n");
    1267
    1268 /* initialize the subproblem */
    1269 SCIP_CALL( SCIPcreate(&subscip) );
    1270
    1271 SCIP_CALL( setupSubscipLpface(scip, subscip, heurdata, subvars, vars, fixvars, fixvals, nfixvars, nvars) );
    1272
    1273 SCIPfreeBufferArray(scip, &fixvals);
    1274 SCIPfreeBufferArray(scip, &fixvars);
    1275 }
    1276
    1277 retcode = solveSubscipLpface(scip, subscip, heur, heurdata, subvars, result, focusnodelb, &keepthisscip);
    1278
    1279 SCIP_CALL( retcode );
    1280
    1281 /* free subproblem or store it for the next run of the heuristic */
    1282 if( ! keepthisscip )
    1283 {
    1284 /* we only allocated buffer memory if no previous subscip was reinstalled */
    1285 if( heurdata->subscipdata->subscip == NULL )
    1286 {
    1287 SCIPfreeBufferArray(scip, &subvars);
    1288 SCIP_CALL( SCIPfree(&subscip) );
    1289 }
    1290 else
    1291 SCIP_CALL( subscipdataFreeSubscip(scip, heurdata->subscipdata) );
    1292
    1293 subscipdataReset(heurdata->subscipdata);
    1294 }
    1295 else
    1296 {
    1297 /* if the subscip has not yet been stored, we copy the subscip into the heuristic data to keep it for the next run */
    1298 if( heurdata->subscipdata->subscip == NULL )
    1299 {
    1300 SCIP_CALL( subscipdataCopySubscip(scip, heurdata->subscipdata, subscip, subvars, nvars) );
    1301 SCIPfreeBufferArray(scip, &subvars);
    1302 }
    1303 else
    1304 {
    1305 assert(heurdata->subscipdata->subscip == subscip);
    1306 assert(heurdata->subscipdata->subvars == subvars);
    1307 assert(heurdata->subscipdata->nsubvars == nvars);
    1308 }
    1309 }
    1310
    1311 return SCIP_OKAY;
    1312}
    1313
    1314/*
    1315 * primal heuristic specific interface methods
    1316 */
    1317
    1318/** creates the lpface primal heuristic and includes it in SCIP */
    1320 SCIP* scip /**< SCIP data structure */
    1321 )
    1322{
    1323 SCIP_HEURDATA* heurdata;
    1324 SCIP_HEUR* heur;
    1325
    1326 /* create Lpface primal heuristic data */
    1327 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
    1328
    1329 heurdata->subscipdata = NULL;
    1330
    1331 /* include primal heuristic */
    1334 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecLpface, heurdata) );
    1335
    1336 assert(heur != NULL);
    1337
    1338 /* primal heuristic is safe to use in exact solving mode */
    1339 SCIPheurMarkExact(heur);
    1340
    1341 /* set non-NULL pointers to callback methods */
    1342 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyLpface) );
    1343 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeLpface) );
    1344 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitLpface) );
    1345 SCIP_CALL( SCIPsetHeurInitsol(scip, heur, heurInitsolLpface) );
    1346 SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolLpface) );
    1348
    1349 /* add lpface primal heuristic parameters */
    1350 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/nodesofs",
    1351 "number of nodes added to the contingent of the total nodes",
    1352 &heurdata->nodesofs, FALSE, DEFAULT_NODESOFS, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    1353
    1354 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxnodes",
    1355 "maximum number of nodes to regard in the subproblem",
    1356 &heurdata->maxnodes, TRUE, DEFAULT_MAXNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    1357
    1358 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/minnodes",
    1359 "minimum number of nodes required to start the subproblem",
    1360 &heurdata->minnodes, TRUE, DEFAULT_MINNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    1361
    1362 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/nodesquot",
    1363 "contingent of sub problem nodes in relation to the number of nodes of the original problem",
    1364 &heurdata->nodesquot, FALSE, DEFAULT_NODESQUOT, 0.0, 1.0, NULL, NULL) );
    1365
    1366 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minfixingrate",
    1367 "required percentage of fixed integer variables in sub-MIP to run",
    1368 &heurdata->minfixingrate, FALSE, DEFAULT_MINFIXINGRATE, 0.0, 1.0, NULL, NULL) );
    1369
    1370 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/lplimfac",
    1371 "factor by which the limit on the number of LP depends on the node limit",
    1372 &heurdata->lplimfac, TRUE, DEFAULT_LPLIMFAC, 1.0, SCIP_REAL_MAX, NULL, NULL) );
    1373
    1374 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/uselprows",
    1375 "should subproblem be created out of the rows in the LP rows?",
    1376 &heurdata->uselprows, TRUE, DEFAULT_USELPROWS, NULL, NULL) );
    1377
    1378 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/dualbasisequations",
    1379 "should dually nonbasic rows be turned into equations?",
    1380 &heurdata->dualbasisequations, TRUE, DEFAULT_DUALBASISEQUATIONS, NULL, NULL) );
    1381
    1382 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/keepsubscip",
    1383 "should the heuristic continue solving the same sub-SCIP?",
    1384 &heurdata->keepsubscip, TRUE, DEFAULT_KEEPSUBSCIP, NULL, NULL) );
    1385
    1386 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/copycuts",
    1387 "if uselprows == FALSE, should all active cuts from cutpool be copied to constraints in subproblem?",
    1388 &heurdata->copycuts, TRUE, DEFAULT_COPYCUTS, NULL, NULL) );
    1389
    1390 SCIP_CALL( SCIPaddCharParam(scip, "heuristics/" HEUR_NAME "/subscipobjective",
    1391 "objective function in the sub-SCIP: (z)ero, (r)oot-LP-difference, (i)nference, LP (f)ractionality, (o)riginal",
    1392 &heurdata->subscipobjective, TRUE, 'z', "forzi", NULL, NULL) );
    1393
    1394 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/minpathlen",
    1395 "the minimum active search tree path length along which lower bound hasn't changed before heuristic becomes active",
    1396 &heurdata->minpathlen, TRUE, DEFAULT_MINPATHLEN, 0, 65531, NULL, NULL) );
    1397
    1398 return SCIP_OKAY;
    1399}
    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_REAL_MAX
    Definition: def.h:158
    #define SCIP_INVALID
    Definition: def.h:178
    #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_LONGINT_MAX
    Definition: def.h:142
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
    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 SCIPcopyPlugins(SCIP *sourcescip, SCIP *targetscip, SCIP_Bool copyreaders, SCIP_Bool copypricers, SCIP_Bool copyconshdlrs, SCIP_Bool copyconflicthdlrs, SCIP_Bool copypresolvers, SCIP_Bool copyrelaxators, SCIP_Bool copyseparators, SCIP_Bool copycutselectors, SCIP_Bool copypropagators, SCIP_Bool copyheuristics, SCIP_Bool copyeventhdlrs, SCIP_Bool copynodeselectors, SCIP_Bool copybranchrules, SCIP_Bool copyiisfinders, SCIP_Bool copydisplays, SCIP_Bool copydialogs, SCIP_Bool copytables, SCIP_Bool copyexprhdlrs, SCIP_Bool copynlpis, SCIP_Bool passmessagehdlr, SCIP_Bool *valid)
    Definition: scip_copy.c:276
    void SCIPsetSubscipDepth(SCIP *scip, int newdepth)
    Definition: scip_copy.c:2609
    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 SCIPcopyVars(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_VAR **fixedvars, SCIP_Real *fixedvals, int nfixedvars, SCIP_Bool global)
    Definition: scip_copy.c:1167
    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
    int SCIPgetSubscipDepth(SCIP *scip)
    Definition: scip_copy.c:2588
    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_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
    int SCIPgetNObjVars(SCIP *scip)
    Definition: scip_prob.c:2616
    const char * SCIPgetProbName(SCIP *scip)
    Definition: scip_prob.c:1242
    SCIP_RETCODE SCIPwriteOrigProblem(SCIP *scip, const char *filename, const char *extension, SCIP_Bool genericnames)
    Definition: scip_prob.c:742
    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_RETCODE SCIPcreateProbBasic(SCIP *scip, const char *name)
    Definition: scip_prob.c:182
    SCIP_Bool SCIPisObjIntegral(SCIP *scip)
    Definition: scip_prob.c:1801
    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
    SCIP_Real SCIPgetNodeLowerbound(SCIP *scip, SCIP_NODE *node)
    Definition: scip_prob.c:4215
    void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:208
    void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:225
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
    Definition: scip_param.c:250
    SCIP_RETCODE SCIPaddLongintParam(SCIP *scip, const char *name, const char *desc, SCIP_Longint *valueptr, SCIP_Bool isadvanced, SCIP_Longint defaultvalue, SCIP_Longint minvalue, SCIP_Longint maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:111
    SCIP_Bool SCIPisParamFixed(SCIP *scip, const char *name)
    Definition: scip_param.c:219
    SCIP_RETCODE SCIPaddCharParam(SCIP *scip, const char *name, const char *desc, char *valueptr, SCIP_Bool isadvanced, char defaultvalue, const char *allowedvalues, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:167
    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 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 SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
    Definition: scip_param.c:307
    SCIP_RETCODE SCIPwriteParams(SCIP *scip, const char *filename, SCIP_Bool comments, SCIP_Bool onlychanged)
    Definition: scip_param.c:813
    SCIP_RETCODE SCIPsetPresolving(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
    Definition: scip_param.c:956
    SCIP_RETCODE SCIPsetCharParam(SCIP *scip, const char *name, char value)
    Definition: scip_param.c:661
    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 SCIPgetLongintParam(SCIP *scip, const char *name, SCIP_Longint *value)
    Definition: scip_param.c:288
    SCIP_RETCODE SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
    Definition: scip_param.c:429
    SCIP_RETCODE SCIPsetRealParam(SCIP *scip, const char *name, SCIP_Real value)
    Definition: scip_param.c:603
    SCIP_RETCODE SCIPsetSeparating(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
    Definition: scip_param.c:985
    SCIP_RETCODE SCIPincludeHeurLpface(SCIP *scip)
    Definition: heur_lpface.c:1319
    SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
    Definition: scip_branch.c:304
    SCIP_Real SCIPgetColRedcost(SCIP *scip, SCIP_COL *col)
    Definition: scip_lp.c:1163
    SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
    Definition: lp.c:17425
    SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
    Definition: scip_cons.c:1173
    SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
    Definition: scip_event.c:111
    const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
    Definition: event.c:396
    SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
    Definition: event.c:1194
    SCIP_RETCODE SCIPcatchEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
    Definition: scip_event.c:293
    SCIP_Bool SCIPisExact(SCIP *scip)
    Definition: scip_exact.c:193
    SCIP_RETCODE SCIPenableExactSolving(SCIP *scip, SCIP_Bool enable)
    Definition: scip_exact.c:151
    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 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
    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_Bool SCIPisLPRelax(SCIP *scip)
    Definition: scip_lp.c:231
    SCIP_RETCODE SCIPgetLPRowsData(SCIP *scip, SCIP_ROW ***rows, int *nrows)
    Definition: scip_lp.c:576
    SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
    Definition: scip_lp.c:174
    SCIP_Bool SCIPallColsInLP(SCIP *scip)
    Definition: scip_lp.c:655
    SCIP_Real SCIPgetLPObjval(SCIP *scip)
    Definition: scip_lp.c:253
    SCIP_Longint SCIPgetMemExternEstim(SCIP *scip)
    Definition: scip_mem.c:126
    #define SCIPfreeBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:110
    SCIP_Longint SCIPgetMemUsed(SCIP *scip)
    Definition: scip_mem.c:100
    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 SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    #define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
    Definition: scip_mem.h:105
    SCIP_Real SCIPnodeGetLowerbound(SCIP_NODE *node)
    Definition: tree.c:8503
    SCIP_NODE * SCIPnodeGetParent(SCIP_NODE *node)
    Definition: tree.c:8782
    SCIP_NODESEL * SCIPfindNodesel(SCIP *scip, const char *name)
    Definition: scip_nodesel.c:242
    SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
    Definition: lp.c:17686
    int SCIProwGetNNonz(SCIP_ROW *row)
    Definition: lp.c:17607
    SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
    Definition: lp.c:17632
    SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
    Definition: lp.c:17696
    SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
    Definition: lp.c:17795
    const char * SCIProwGetName(SCIP_ROW *row)
    Definition: lp.c:17745
    SCIP_Real SCIPgetRowActivity(SCIP *scip, SCIP_ROW *row)
    Definition: scip_lp.c:2068
    SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
    Definition: lp.c:17652
    SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
    Definition: lp.c:17706
    SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
    Definition: lp.c:17642
    SCIP_SOL * SCIPgetBestSol(SCIP *scip)
    Definition: scip_sol.c:2981
    int SCIPgetNSols(SCIP *scip)
    Definition: scip_sol.c:2882
    int SCIPsolGetIndex(SCIP_SOL *sol)
    Definition: sol.c:4290
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1765
    SCIP_Real SCIPretransformObj(SCIP *scip, SCIP_Real obj)
    Definition: scip_sol.c:2132
    SCIP_RETCODE SCIPtransformProb(SCIP *scip)
    Definition: scip_solve.c:232
    SCIP_RETCODE SCIPinterruptSolve(SCIP *scip)
    Definition: scip_solve.c:3548
    SCIP_RETCODE SCIPsolve(SCIP *scip)
    Definition: scip_solve.c:2635
    SCIP_Real SCIPgetLowerboundRoot(SCIP *scip)
    SCIP_Longint SCIPgetNNodes(SCIP *scip)
    SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
    SCIP_Real SCIPgetLowerbound(SCIP *scip)
    SCIP_Longint SCIPgetNLPs(SCIP *scip)
    SCIP_Longint SCIPgetNLPIterations(SCIP *scip)
    SCIP_Real SCIPgetSolvingTime(SCIP *scip)
    Definition: scip_timing.c:378
    SCIP_Real SCIPgetPresolvingTime(SCIP *scip)
    Definition: scip_timing.c:442
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfrac(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisDualfeasZero(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    int SCIPgetDepth(SCIP *scip)
    Definition: scip_tree.c:672
    SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
    Definition: scip_tree.c:91
    SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
    Definition: var.c:23683
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23386
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23900
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24142
    int SCIPvarGetProbindex(SCIP_VAR *var)
    Definition: var.c:23662
    SCIP_Real SCIPvarGetRootSol(SCIP_VAR *var)
    Definition: var.c:19115
    SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
    Definition: var.c:23490
    SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
    Definition: var.c:24664
    SCIP_Bool SCIPvarIsRelaxationOnly(SCIP_VAR *var)
    Definition: var.c:23600
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24120
    SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
    Definition: scip_var.c:5372
    SCIP_Real SCIPgetVarAvgInferences(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
    Definition: scip_var.c:11891
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    static SCIP_RETCODE setSubscipLimits(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, SCIP_Bool *success)
    Definition: heur_lpface.c:427
    static SCIP_RETCODE createRows(SCIP *scip, SCIP *subscip, SCIP_VAR **subvars, SCIP_Bool dualbasisequations)
    Definition: heur_lpface.c:237
    #define DEFAULT_NODESQUOT
    Definition: heur_lpface.c:81
    static SCIP_RETCODE subscipdataCopySubscip(SCIP *scip, SUBSCIPDATA *subscipdata, SCIP *subscip, SCIP_VAR **subvars, int nvars)
    Definition: heur_lpface.c:586
    static SCIP_RETCODE setSubscipParameters(SCIP *subscip)
    Definition: heur_lpface.c:489
    static SCIP_DECL_HEUREXEC(heurExecLpface)
    Definition: heur_lpface.c:1081
    static SCIP_RETCODE setupSubscipLpface(SCIP *scip, SCIP *subscip, SCIP_HEURDATA *heurdata, SCIP_VAR **subvars, SCIP_VAR **vars, SCIP_VAR **fixvars, SCIP_Real *fixvals, int nfixvars, int nvars)
    Definition: heur_lpface.c:734
    static SCIP_RETCODE subscipdataFreeSubscip(SCIP *scip, SUBSCIPDATA *subscipdata)
    Definition: heur_lpface.c:557
    #define DEFAULT_NODESOFS
    Definition: heur_lpface.c:80
    static SCIP_RETCODE changeSubvariableObjective(SCIP *scip, SCIP *subscip, SCIP_VAR *var, SCIP_VAR *subvar, SCIP_HEURDATA *heurdata)
    Definition: heur_lpface.c:644
    #define DEFAULT_COPYCUTS
    Definition: heur_lpface.c:85
    #define DEFAULT_MAXNODES
    Definition: heur_lpface.c:77
    #define HEUR_TIMING
    Definition: heur_lpface.c:74
    #define DEFAULT_MINNODES
    Definition: heur_lpface.c:78
    #define HEUR_FREQOFS
    Definition: heur_lpface.c:72
    #define HEUR_DESC
    Definition: heur_lpface.c:68
    static SCIP_RETCODE solveSubscipLpface(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, SCIP_VAR **subvars, SCIP_RESULT *result, SCIP_Real focusnodelb, SCIP_Bool *keepthisscip)
    Definition: heur_lpface.c:825
    static SCIP_Longint calcNodeLimit(SCIP *scip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
    Definition: heur_lpface.c:395
    #define DEFAULT_KEEPSUBSCIP
    Definition: heur_lpface.c:88
    #define heurExitLpface
    Definition: heur_lpface.c:1076
    #define DEFAULT_LPLIMFAC
    Definition: heur_lpface.c:82
    static SCIP_DECL_HEURINITSOL(heurInitsolLpface)
    Definition: heur_lpface.c:1005
    #define DEFAULT_DUALBASISEQUATIONS
    Definition: heur_lpface.c:87
    #define DEFAULT_MINFIXINGRATE
    Definition: heur_lpface.c:79
    #define HEUR_DISPCHAR
    Definition: heur_lpface.c:69
    #define HEUR_MAXDEPTH
    Definition: heur_lpface.c:73
    #define HEUR_PRIORITY
    Definition: heur_lpface.c:70
    #define HEUR_NAME
    Definition: heur_lpface.c:67
    static SCIP_RETCODE determineVariableFixings(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_VAR **fixvars, SCIP_Real *fixvals, int *nfixvars, SCIP_Bool *success)
    Definition: heur_lpface.c:147
    #define DEFAULT_USELPROWS
    Definition: heur_lpface.c:83
    #define DEFAULT_MINPATHLEN
    Definition: heur_lpface.c:89
    static SCIP_DECL_HEURCOPY(heurCopyLpface)
    Definition: heur_lpface.c:945
    #define EVENTHDLR_DESC
    Definition: heur_lpface.c:93
    static void updateFailureStatistic(SCIP *scip, SCIP_HEURDATA *heurdata)
    Definition: heur_lpface.c:381
    #define HEUR_FREQ
    Definition: heur_lpface.c:71
    #define HEUR_USESSUBSCIP
    Definition: heur_lpface.c:75
    static SCIP_DECL_HEURFREE(heurFreeLpface)
    Definition: heur_lpface.c:959
    static SCIP_DECL_EVENTEXEC(eventExecLpface)
    Definition: heur_lpface.c:709
    #define EVENTHDLR_NAME
    Definition: heur_lpface.c:92
    static SCIP_DECL_HEURINIT(heurInitLpface)
    Definition: heur_lpface.c:979
    static void subscipdataReset(SUBSCIPDATA *subscipdata)
    Definition: heur_lpface.c:545
    static SCIP_RETCODE setupSubproblem(SCIP *scip, SCIP *subscip, SCIP_VAR **subvars, SCIP_HEURDATA *heurdata)
    Definition: heur_lpface.c:332
    static SCIP_DECL_HEUREXITSOL(heurExitsolLpface)
    Definition: heur_lpface.c:1030
    LNS heuristic that tries to compute integral solution on optimal LP face.
    memory allocation routines
    public methods for managing events
    public methods for primal heuristics
    public methods for LP management
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPdebug(x)
    Definition: pub_message.h:93
    public data structures and miscellaneous methods
    public methods for primal CIP solutions
    public methods for branch and bound tree
    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 event handler plugins and event handlers
    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 global and local (sub)problems
    public methods for solutions
    public solving methods
    public methods for querying solving statistics
    public methods for timing
    public methods for the branch-and-bound tree
    public methods for SCIP variables
    default SCIP plugins
    SCIP * subscip
    Definition: heur_lpface.c:102
    SCIP_VAR ** subvars
    Definition: heur_lpface.c:103
    SCIP_Real objbound
    Definition: heur_lpface.c:105
    struct SCIP_EventData SCIP_EVENTDATA
    Definition: type_event.h:179
    #define SCIP_EVENTTYPE_LPSOLVED
    Definition: type_event.h:102
    struct SCIP_HeurData SCIP_HEURDATA
    Definition: type_heur.h:77
    #define SCIP_DECL_HEUREXIT(x)
    Definition: type_heur.h:121
    @ SCIP_BRANCHDIR_DOWNWARDS
    Definition: type_history.h:43
    @ SCIP_BRANCHDIR_UPWARDS
    Definition: type_history.h:44
    @ SCIP_LPSOLSTAT_OPTIMAL
    Definition: type_lp.h:44
    @ SCIP_VERBLEVEL_HIGH
    Definition: type_message.h:61
    @ 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
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_PLUGINNOTFOUND
    Definition: type_retcode.h:54
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_STATUS_UNKNOWN
    Definition: type_stat.h:42
    @ SCIP_STATUS_INFEASIBLE
    Definition: type_stat.h:44
    enum SCIP_Status SCIP_STATUS
    Definition: type_stat.h:64
    @ SCIP_VARSTATUS_COLUMN
    Definition: type_var.h:53