SCIP

    Solving Constraint Integer Programs

    heur_completesol.c
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-2026 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file heur_completesol.c
    26 * @ingroup DEFPLUGINS_HEUR
    27 * @brief COMPLETESOL - primal heuristic trying to complete given partial solutions
    28 * @author Jakob Witzig
    29 */
    30
    31/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    32
    34#include "scip/cons_linear.h"
    36#include "scip/pub_event.h"
    37#include "scip/pub_heur.h"
    38#include "scip/pub_message.h"
    39#include "scip/pub_misc.h"
    40#include "scip/pub_sol.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_event.h"
    46#include "scip/scip_general.h"
    47#include "scip/scip_heur.h"
    48#include "scip/scip_mem.h"
    49#include "scip/scip_message.h"
    50#include "scip/scip_nlp.h"
    51#include "scip/scip_nodesel.h"
    52#include "scip/scip_numerics.h"
    53#include "scip/scip_param.h"
    54#include "scip/scip_prob.h"
    55#include "scip/scip_probing.h"
    56#include "scip/scip_sol.h"
    57#include "scip/scip_solve.h"
    59#include "scip/scip_timing.h"
    60#include "scip/scip_tree.h"
    61#include "scip/scip_var.h"
    62
    63
    64#define HEUR_NAME "completesol"
    65#define HEUR_DESC "primal heuristic trying to complete given partial solutions"
    66#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_LNS
    67#define HEUR_PRIORITY 0
    68#define HEUR_FREQ 0
    69#define HEUR_FREQOFS 0
    70#define HEUR_MAXDEPTH 0
    71#define HEUR_TIMING SCIP_HEURTIMING_BEFOREPRESOL | SCIP_HEURTIMING_BEFORENODE
    72#define HEUR_USESSUBSCIP TRUE /**< does the heuristic use a secondary SCIP instance? */
    73
    74/* default values for heuristic plugins */
    75#define DEFAULT_MAXNODES 5000LL /**< maximum number of nodes to regard in the subproblem */
    76#define DEFAULT_MAXUNKRATE 0.85 /**< maximum percentage of unknown solution values */
    77#define DEFAULT_ADDALLSOLS FALSE /**< should all subproblem solutions be added to the original SCIP? */
    78#define DEFAULT_MINNODES 50LL /**< minimum number of nodes to regard in the subproblem */
    79#define DEFAULT_NODESOFS 500LL /**< number of nodes added to the contingent of the total nodes */
    80#define DEFAULT_NODESQUOT 0.1 /**< subproblem nodes in relation to nodes of the original problem */
    81#define DEFAULT_LPLIMFAC 2.0 /**< factor by which the limit on the number of LP depends on the node limit */
    82#define DEFAULT_OBJWEIGHT 1.0 /**< weight of the original objective function (1: only original objective) */
    83#define DEFAULT_BOUNDWIDENING 0.1 /**< bound widening factor applied to continuous variables
    84 * (0: round bounds to next integer, 1: relax to global bounds)
    85 */
    86#define DEFAULT_MINIMPROVE 0.01 /**< factor by which the incumbent should be improved at least */
    87#define DEFAULT_MINOBJWEIGHT 1e-3 /**< minimal weight for original objective function (zero could lead to infinite solutions) */
    88#define DEFAULT_IGNORECONT FALSE /**< should solution values for continuous variables be ignored? */
    89#define DEFAULT_BESTSOLS 5 /**< heuristic stops, if the given number of improving solutions were found (-1: no limit) */
    90#define DEFAULT_MAXPROPROUNDS 10 /**< maximal number of iterations in propagation (-1: no limit) */
    91#define DEFAULT_MAXLPITER -1LL /**< maximal number of LP iterations (-1: no limit) */
    92#define DEFAULT_MAXCONTVARS -1 /**< maximal number of continuous variables after presolving (-1: no limit) */
    93#define DEFAULT_BEFOREPRESOL TRUE /**< should the heuristic run before presolving? */
    94
    95/* event handler properties */
    96#define EVENTHDLR_NAME "Completesol"
    97#define EVENTHDLR_DESC "LP event handler for " HEUR_NAME " heuristic"
    98
    99
    100/** primal heuristic data */
    101struct SCIP_HeurData
    102{
    103 SCIP_Longint maxnodes; /**< maximum number of nodes to regard in the subproblem */
    104 SCIP_Longint minnodes; /**< minimum number of nodes to regard in the subproblem */
    105 SCIP_Longint nodesofs; /**< number of nodes added to the contingent of the total nodes */
    106 SCIP_Longint maxlpiter; /**< maximal number of LP iterations (-1: no limit) */
    107 SCIP_Real maxunknownrate; /**< maximal rate of changed coefficients in the objective function */
    108 SCIP_Real nodesquot; /**< subproblem nodes in relation to nodes of the original problem */
    109 SCIP_Real nodelimit; /**< the nodelimit employed in the current sub-SCIP, for the event handler*/
    110 SCIP_Real lplimfac; /**< factor by which the limit on the number of LP depends on the node limit */
    111 SCIP_Real objweight; /**< weight of the original objective function (1: only original obj, 0: try to keep to given solution) */
    112 SCIP_Real boundwidening; /**< bound widening factor applied to continuous variables
    113 * (0: fix variables to given solution values, 1: relax to global bounds)
    114 */
    115 SCIP_Real minimprove; /**< factor by which the incumbent should be improved at least */
    116 SCIP_Bool addallsols; /**< should all subproblem solutions be added to the original SCIP? */
    117 SCIP_Bool ignorecont; /**< should solution values for continuous variables be ignored? */
    118 SCIP_Bool beforepresol; /**< should the heuristic run before presolving? */
    119 int bestsols; /**< heuristic stops, if the given number of improving solutions were found (-1: no limit) */
    120 int maxcontvars; /**< maximal number of continuous variables after presolving (-1: no limit) */
    121 int maxproprounds; /**< maximal number of iterations in propagation (-1: no limit) */
    122};
    123
    124/* ---------------- Callback methods of event handler ---------------- */
    125
    126/* exec the event handler
    127 *
    128 * we interrupt the solution process
    129 */
    130static
    131SCIP_DECL_EVENTEXEC(eventExecCompletesol)
    132{
    133 SCIP_HEURDATA* heurdata;
    134
    135 assert(eventhdlr != NULL);
    136 assert(eventdata != NULL);
    137 assert(event != NULL);
    139
    141
    142 heurdata = (SCIP_HEURDATA*)eventdata;
    143 assert(heurdata != NULL);
    144
    145 /* interrupt solution process of sub-SCIP */
    146 if( SCIPgetNLPs(scip) > heurdata->lplimfac * heurdata->nodelimit )
    147 {
    148 SCIPdebugMsg(scip, "interrupt after %" SCIP_LONGINT_FORMAT " LPs\n",SCIPgetNLPs(scip));
    150 }
    151
    152 return SCIP_OKAY;
    153}
    154
    155/** creates a subproblem by fixing a number of variables */
    156static
    158 SCIP* scip, /**< original SCIP data structure */
    159 SCIP* subscip, /**< SCIP data structure for the subproblem */
    160 SCIP_HEURDATA* heurdata, /**< heuristic's private data structure */
    161 SCIP_VAR** subvars, /**< the variables of the subproblem */
    162 SCIP_SOL* partialsol, /**< partial solution */
    163 SCIP_Bool* tightened /**< array to store for which variables we have found bound tightenings */
    164 )
    165{
    166 SCIP_VAR** vars;
    167 SCIP_CONS* objcons;
    168 SCIP_Real epsobj;
    169 SCIP_Real cutoff;
    170 SCIP_Real upperbound;
    171 char consobjname[SCIP_MAXSTRLEN];
    172 int nvars;
    173 int i;
    174
    175 assert(scip != NULL);
    176 assert(subscip != NULL);
    177 assert(subvars != NULL);
    178 assert(heurdata != NULL);
    179
    180 /* if there is already a solution, add an objective cutoff */
    181 if( SCIPgetNSols(scip) > 0 )
    182 {
    184
    185 upperbound = SCIPgetUpperbound(scip) - SCIPsumepsilon(scip);
    186
    188 cutoff = (1 - heurdata->minimprove) * SCIPgetUpperbound(scip) + heurdata->minimprove * SCIPgetLowerbound(scip);
    189 else
    190 {
    191 if( SCIPgetUpperbound(scip) >= 0 )
    192 cutoff = (1 - heurdata->minimprove) * SCIPgetUpperbound(scip);
    193 else
    194 cutoff = (1 + heurdata->minimprove) * SCIPgetUpperbound(scip);
    195 }
    196 cutoff = MIN(upperbound, cutoff);
    197 SCIPdebugMsg(scip, "set cutoff=%g for sub-SCIP\n", cutoff);
    198 }
    199 else
    200 cutoff = SCIPinfinity(scip);
    201
    202 /* calculate objective coefficients for all potential epsilons */
    203 if( SCIPisEQ(scip, heurdata->objweight, 1.0) )
    204 return SCIP_OKAY;
    205 else if( !SCIPisInfinity(scip, cutoff) )
    206 epsobj = 1.0;
    207 else
    208 {
    209 /* divide by objweight to avoid changing objective coefficient of original problem variables */
    210 epsobj = (1.0 - heurdata->objweight)/heurdata->objweight;
    211
    212 /* scale with -1 if we have a maximization problem */
    214 epsobj *= -1.0;
    215 }
    216
    217 /* get active variables */
    218 vars = SCIPgetVars(scip);
    219 nvars = SCIPgetNVars(scip);
    220
    221 objcons = NULL;
    222
    223 /* add constraints to measure the distance to the given partial solution */
    224 for( i = 0; i < nvars; i++ )
    225 {
    226 SCIP_Real solval;
    227 int idx;
    228
    229 assert(SCIPvarIsActive(vars[i]));
    230
    231 if( subvars[i] == NULL )
    232 continue;
    233
    234 /* add objective function as a constraint, if a primal bound exists */
    235 if( SCIPisInfinity(scip, cutoff) )
    236 {
    237 /* create the constraints */
    238 if( objcons == NULL )
    239 {
    240 SCIP_Real lhs;
    241 SCIP_Real rhs;
    242
    244 {
    245 lhs = -SCIPinfinity(subscip);
    246 rhs = cutoff;
    247 }
    248 else
    249 {
    250 lhs = cutoff;
    251 rhs = SCIPinfinity(subscip);
    252 }
    253
    254 (void)SCIPsnprintf(consobjname, SCIP_MAXSTRLEN, "obj");
    255 SCIP_CALL( SCIPcreateConsBasicLinear(subscip, &objcons, consobjname, 0, NULL, NULL, lhs, rhs) );
    256 }
    257
    258 /* add the variable to the constraints */
    259 SCIP_CALL( SCIPaddCoefLinear(subscip, objcons, subvars[i], SCIPvarGetObj(subvars[i])) );
    260
    261 /* set objective coefficient to 0.0 */
    262 SCIP_CALL( SCIPchgVarObj(subscip, subvars[i], 0.0) );
    263 }
    264
    265 solval = SCIPgetSolVal(scip, partialsol, vars[i]);
    266
    267 /* skip variables with unknown solution value */
    268 if( solval == SCIP_UNKNOWN ) /*lint !e777*/
    269 continue;
    270
    271 idx = SCIPvarGetProbindex(vars[i]);
    272 assert(idx >= 0);
    273
    274 /* skip variables where we already found some bound tightenings */
    275 if( tightened[idx] == FALSE )
    276 {
    277 /* special case: vars[i] is binary; we do not add an extra variable, but we mimic the behavior we would get with it.
    278 * E.g., if the solval is 0.3, setting the variable to 0 would give a cost of 0.3 * epsobj, setting it to 1 gives
    279 * 0.7 * epsobj. Thus, 0.3 * epsobj can be treated as a constant in the objective function and the variable gets
    280 * an objective coefficient of 0.4 * epsobj.
    281 */
    282 if( SCIPvarIsBinary(vars[i]) )
    283 {
    284 SCIP_Real frac = SCIPfeasFrac(scip, solval);
    285 SCIP_Real objcoef;
    286
    287 frac = MIN(frac, 1-frac);
    288 objcoef = (1 - 2*frac) * epsobj * (int)SCIPgetObjsense(scip);
    289
    290 if( solval > 0.5 )
    291 {
    292 SCIP_CALL( SCIPchgVarObj(scip, vars[i], -objcoef) );
    293 }
    294 else
    295 {
    296 SCIP_CALL( SCIPchgVarObj(scip, vars[i], objcoef) );
    297 }
    298 }
    299 else
    300 {
    301 SCIP_CONS* conspos;
    302 SCIP_CONS* consneg;
    303 SCIP_VAR* eps;
    304 char consnamepos[SCIP_MAXSTRLEN];
    305 char consnameneg[SCIP_MAXSTRLEN];
    306 char epsname[SCIP_MAXSTRLEN];
    307
    308 /* create two new variables */
    309 (void)SCIPsnprintf(epsname, SCIP_MAXSTRLEN, "eps_%s", SCIPvarGetName(subvars[i]));
    310
    311 SCIP_CALL( SCIPcreateVarBasic(subscip, &eps, epsname, 0.0, SCIPinfinity(scip), epsobj, SCIP_VARTYPE_CONTINUOUS) );
    312 SCIP_CALL( SCIPaddVar(subscip, eps) );
    313
    314 /* create two constraints */
    315 (void)SCIPsnprintf(consnamepos, SCIP_MAXSTRLEN, "cons_%s_pos", SCIPvarGetName(subvars[i]));
    316 (void)SCIPsnprintf(consnameneg, SCIP_MAXSTRLEN, "cons_%s_neq", SCIPvarGetName(subvars[i]));
    317
    318 /* x_{i} - s_{i} <= e_{i} <==> x_{i} - e_{i} <= s_{i} */
    319 SCIP_CALL( SCIPcreateConsBasicLinear(subscip, &conspos, consnamepos, 0, NULL, NULL, -SCIPinfinity(scip), solval) );
    320 SCIP_CALL( SCIPaddCoefLinear(subscip, conspos, subvars[i], 1.0) );
    321 SCIP_CALL( SCIPaddCoefLinear(subscip, conspos, eps, -1.0) );
    322 SCIP_CALL( SCIPaddCons(subscip, conspos) );
    323 SCIP_CALL( SCIPreleaseCons(subscip, &conspos) );
    324
    325 /* s_{i} - x_{i} <= e_{i} <==> e_{i} - x_{i} >= s_{i} */
    326 SCIP_CALL( SCIPcreateConsBasicLinear(subscip, &consneg, consnameneg, 0, NULL, NULL, solval, SCIPinfinity(scip)) );
    327 SCIP_CALL( SCIPaddCoefLinear(subscip, consneg, subvars[i], -1.0) );
    328 SCIP_CALL( SCIPaddCoefLinear(subscip, consneg, eps, 1.0) );
    329 SCIP_CALL( SCIPaddCons(subscip, consneg) );
    330 SCIP_CALL( SCIPreleaseCons(subscip, &consneg) );
    331
    332 /* release the variables */
    333 SCIP_CALL( SCIPreleaseVar(subscip, &eps) );
    334 }
    335 }
    336 }
    337
    338 /* add and release the constraint representing the original objective function */
    339 if( objcons != NULL )
    340 {
    341 SCIP_CALL( SCIPaddCons(subscip, objcons) );
    342 SCIP_CALL( SCIPreleaseCons(subscip, &objcons) );
    343 }
    344
    345 return SCIP_OKAY;
    346}
    347
    348/** perform a probing bound change or fixes the variable */
    349static
    351 SCIP* scip, /**< original SCIP data structure */
    352 SCIP_VAR* var, /**< problem variable */
    353 SCIP_Real newval, /**< new bound */
    354 SCIP_BRANCHDIR branchdir, /**< bound change direction */
    355 SCIP_Bool* success /**< pointer to store whether the bound could be tightened */
    356 )
    357{
    358 SCIP_Real ub;
    359 SCIP_Real lb;
    360
    361 assert(scip != NULL);
    362 assert(var != NULL);
    363
    364 (*success) = FALSE;
    365
    366 ub = SCIPvarGetUbLocal(var);
    367 lb = SCIPvarGetLbLocal(var);
    368
    369 switch (branchdir) {
    371 if( SCIPisLT(scip, newval, ub) && SCIPisGE(scip, newval, lb) )
    372 {
    373 SCIP_CALL( SCIPchgVarUbProbing(scip, var, newval) );
    374 (*success) = TRUE;
    375 }
    376 break;
    378 if( SCIPisLE(scip, newval, ub) && SCIPisGT(scip, newval, lb) )
    379 {
    380 SCIP_CALL( SCIPchgVarLbProbing(scip, var, newval) );
    381 (*success) = TRUE;
    382 }
    383 break;
    385 if( SCIPisLE(scip, newval, ub) && SCIPisGE(scip, newval, lb) )
    386 {
    387 SCIP_CALL( SCIPfixVarProbing(scip, var, newval) );
    388 (*success) = TRUE;
    389 }
    390 break;
    391 default:
    392 return SCIP_INVALIDDATA;
    393 }/*lint !e788*/
    394
    395 return SCIP_OKAY;
    396}
    397
    398/** tries variables bound changes guided by the given solution */
    399static
    401 SCIP* scip, /**< original SCIP data structure */
    402 SCIP_HEURDATA* heurdata, /**< heuristic's private data structure */
    403 SCIP_VAR** vars, /**< problem variables */
    404 int nvars, /**< number of problem variables */
    405 SCIP_SOL* sol, /**< solution to guide the bound changes */
    406 SCIP_Bool* tightened, /**< array to store if variable bound could be tightened */
    407 SCIP_Bool* infeasible /**< pointer to store whether subproblem is infeasible */
    408 )
    409{
    410#ifndef NDEBUG
    411 SCIP_Bool incontsection;
    412#endif
    413 SCIP_Bool abortearly;
    414 SCIP_Bool cutoff;
    415 SCIP_Bool probingsuccess;
    416 SCIP_Longint ndomreds;
    417 SCIP_Longint ndomredssum;
    418 int nbndtightenings;
    419 int v;
    420
    421 assert(scip != NULL);
    422 assert(heurdata != NULL);
    423 assert(vars != NULL);
    424 assert(nvars >= 0);
    425 assert(sol != NULL);
    426 assert(tightened != NULL);
    427
    429
    430 SCIPdebugMsg(scip, "> start probing along the solution values\n");
    431
    432 *infeasible = FALSE;
    433 abortearly = FALSE;
    434 nbndtightenings = 0;
    435 ndomredssum = 0;
    436#ifndef NDEBUG
    437 incontsection = FALSE;
    438#endif
    439
    440 /* there is at least one integral variable; open one probing node for all non-continuous variables */
    441 if( nvars - SCIPgetNContVars(scip) > 0 )
    442 {
    444 }
    445
    446 for( v = 0; v < nvars && !abortearly; v++ )
    447 {
    448 SCIP_Real solval;
    449
    450 assert(SCIPvarIsActive(vars[v]));
    451
    452 cutoff = FALSE;
    453 ndomreds = 0;
    454
    455#ifndef NDEBUG
    456 incontsection |= (!SCIPvarIsIntegral(vars[v])); /*lint !e514*/
    457 assert(!incontsection || !SCIPvarIsIntegral(vars[v]));
    458#endif
    459
    460 /* return if we have found enough domain reductions tightenings */
    461 if( ndomredssum > 0.3*nvars )
    462 break;
    463
    464 solval = SCIPgetSolVal(scip, sol, vars[v]);
    465
    466 /* skip unknown variables */
    467 if( solval == SCIP_UNKNOWN ) /*lint !e777*/
    468 continue;
    469 assert(!SCIPisInfinity(scip, solval) && !SCIPisInfinity(scip, -solval));
    470
    471 /* variable is binary or integer */
    472 if( SCIPvarIsIntegral(vars[v]) )
    473 {
    474 /* the solution value is integral, try to fix them */
    475 if( SCIPisIntegral(scip, solval) )
    476 {
    477 SCIP_CALL( chgProbingBound(scip, vars[v], solval, SCIP_BRANCHDIR_FIXED, &probingsuccess) );
    478 tightened[SCIPvarGetProbindex(vars[v])] = TRUE;
    479 ++nbndtightenings;
    480
    481#ifdef SCIP_MORE_DEBUG
    482 SCIPdebugMsg(scip, "> fix variable <%s> = [%g,%g] to %g \n", SCIPvarGetName(vars[v]),
    483 SCIPvarGetLbGlobal(vars[v]), SCIPvarGetUbGlobal(vars[v]), solval);
    484#endif
    485 }
    486 else
    487 {
    488 SCIP_Real ub = SCIPceil(scip, solval) + 1.0;
    489 SCIP_Real lb = SCIPfloor(scip, solval) - 1.0;
    490
    491 /* try tightening of upper bound */
    492 if( SCIPisLT(scip, ub, SCIPvarGetUbLocal(vars[v])) )
    493 {
    494 SCIP_CALL( chgProbingBound(scip, vars[v], solval, SCIP_BRANCHDIR_DOWNWARDS, &probingsuccess) );
    495 tightened[SCIPvarGetProbindex(vars[v])] = TRUE;
    496 ++nbndtightenings;
    497
    498#ifdef SCIP_MORE_DEBUG
    499 SCIPdebugMsg(scip, "> tighten upper bound of variable <%s>: %g to %g\n", SCIPvarGetName(vars[v]),
    500 SCIPvarGetUbGlobal(vars[v]), ub);
    501#endif
    502 }
    503
    504 /* try tightening of lower bound */
    505 if( SCIPisGT(scip, lb, SCIPvarGetLbLocal(vars[v])) )
    506 {
    507 SCIP_CALL( chgProbingBound(scip, vars[v], solval, SCIP_BRANCHDIR_UPWARDS, &probingsuccess) );
    508 tightened[SCIPvarGetProbindex(vars[v])] = TRUE;
    509 ++nbndtightenings;
    510
    511#ifdef SCIP_MORE_DEBUG
    512 SCIPdebugMsg(scip, "> tighten lower bound of variable <%s>: %g to %g\n", SCIPvarGetName(vars[v]),
    513 SCIPvarGetLbGlobal(vars[v]), ub);
    514#endif
    515 }
    516 }
    517 }
    518 /* variable is continuous */
    519 else
    520 {
    521 /* fix to lb or ub */
    522 if( SCIPisEQ(scip, solval, SCIPvarGetLbLocal(vars[v])) || SCIPisEQ(scip, solval, SCIPvarGetUbLocal(vars[v])) )
    523 {
    524 /* open a new probing node */
    526 {
    528
    529 SCIP_CALL( chgProbingBound(scip, vars[v], solval, SCIP_BRANCHDIR_FIXED, &probingsuccess) );
    530
    531 /* skip propagation if the bound could not be changed, e.g., already tightened due to previous
    532 * domain propagation
    533 */
    534 if( probingsuccess )
    535 {
    536 SCIP_CALL( SCIPpropagateProbing(scip, heurdata->maxproprounds, &cutoff, &ndomreds) );
    537 }
    538
    539 if( cutoff )
    540 {
    541 ndomreds = 0;
    543 }
    544 else
    545 {
    546 assert(SCIPvarGetProbindex(vars[v]) >= 0);
    547 tightened[SCIPvarGetProbindex(vars[v])] = TRUE;
    548 ++nbndtightenings;
    549#ifdef SCIP_MORE_DEBUG
    550 SCIPdebugMsg(scip, "> fix variable <%s> = [%g,%g] to %g (ndomreds=%lld)\n", SCIPvarGetName(vars[v]),
    551 SCIPvarGetLbGlobal(vars[v]), SCIPvarGetUbGlobal(vars[v]), solval, ndomreds);
    552#endif
    553 }
    554 }
    555 else
    556 /* abort probing */
    557 abortearly = TRUE;
    558 }
    559 else
    560 {
    561 SCIP_Real offset;
    562 SCIP_Real newub = SCIPvarGetUbGlobal(vars[v]);
    563 SCIP_Real newlb = SCIPvarGetLbGlobal(vars[v]);
    564
    565 /* both bound are finite */
    566 if( !SCIPisInfinity(scip, -newlb) && !SCIPisInfinity(scip, newub) )
    567 offset = REALABS(heurdata->boundwidening * (newub-newlb));
    568 else
    569 {
    570 offset = 0.0;
    571
    572 /* if exactly one bound is finite, widen bound w.r.t. solution value and finite bound */
    573 if( !SCIPisInfinity(scip, -newlb) )
    574 offset = REALABS(heurdata->boundwidening * (solval-newlb));
    575 else if( !SCIPisInfinity(scip, newub) )
    576 offset = REALABS(heurdata->boundwidening * (newub-solval));
    577 }
    578
    579 /* update bounds */
    580 newub = SCIPceil(scip, solval) + offset;
    581 newlb = SCIPfloor(scip, solval) - offset;
    582
    583 /* try tightening of upper bound */
    584 if( SCIPisLT(scip, newub, SCIPvarGetUbLocal(vars[v])) )
    585 {
    586 /* open a new probing node */
    588 {
    590 SCIP_CALL( chgProbingBound(scip, vars[v], newub, SCIP_BRANCHDIR_DOWNWARDS, &probingsuccess) );
    591
    592 /* skip propagation if the bound could not be changed, e.g., already tightened due to previous
    593 * domain propagation
    594 */
    595 if( probingsuccess )
    596 {
    597 SCIP_CALL( SCIPpropagateProbing(scip, heurdata->maxproprounds, &cutoff, &ndomreds) );
    598 }
    599
    600 if( cutoff )
    601 {
    602 ndomreds = 0;
    603
    604 /* backtrack to last feasible probing node */
    606
    607 /* we can tighten the lower bound by newub */
    608 SCIP_CALL( chgProbingBound(scip, vars[v], newub, SCIP_BRANCHDIR_UPWARDS, &probingsuccess) );
    609
    610 /* propagate the new bound */
    611 SCIP_CALL( SCIPpropagateProbing(scip, heurdata->maxproprounds, &cutoff, &ndomreds) );
    612
    613 /* there is no feasible solution w.r.t. the current bounds */
    614 if( cutoff )
    615 {
    616 SCIPdebugMsg(scip, "> subproblem is infeasible within the local bounds\n");
    617 *infeasible = TRUE;
    618 return SCIP_OKAY;
    619 }
    620#ifdef SCIP_MORE_DEBUG
    621 SCIPdebugMsg(scip, "> tighten lower bound of variable <%s>: %g to %g\n",
    622 SCIPvarGetName(vars[v]), SCIPvarGetLbGlobal(vars[v]), newub);
    623#endif
    624 }
    625 else
    626 {
    627 assert(SCIPvarGetProbindex(vars[v]) >= 0);
    628 tightened[SCIPvarGetProbindex(vars[v])] = TRUE;
    629 ++nbndtightenings;
    630#ifdef SCIP_MORE_DEBUG
    631 SCIPdebugMsg(scip, "> tighten upper bound of variable <%s>: %g to %g (ndomreds=%lld)\n",
    632 SCIPvarGetName(vars[v]), SCIPvarGetUbGlobal(vars[v]), newub, ndomreds);
    633#endif
    634 }
    635 }
    636 else
    637 /* abort probing */
    638 abortearly = TRUE;
    639 }
    640
    641 /* try tightening of lower bound */
    642 if( SCIPisGT(scip, newlb, SCIPvarGetLbLocal(vars[v])) )
    643 {
    644 /* open a new probing node */
    646 {
    648 SCIP_CALL( chgProbingBound(scip, vars[v], newlb, SCIP_BRANCHDIR_UPWARDS, &probingsuccess) );
    649
    650 /* skip propagation if the bound could not be changed, e.g., already tightened due to previous
    651 * domain propagation
    652 */
    653 if( probingsuccess )
    654 {
    655 SCIP_CALL( SCIPpropagateProbing(scip, -1, &cutoff, &ndomreds) );
    656 }
    657
    658 if( cutoff )
    659 {
    660 ndomreds = 0;
    661
    662 /* backtrack to last feasible probing node */
    664
    665 /* we can tighten the upper bound by newlb */
    666 SCIP_CALL( chgProbingBound(scip, vars[v], newlb, SCIP_BRANCHDIR_DOWNWARDS, &probingsuccess) );
    667
    668 /* propagate the new bound */
    669 SCIP_CALL( SCIPpropagateProbing(scip, heurdata->maxproprounds, &cutoff, &ndomreds) );
    670
    671 /* there is no feasible solution w.r.t. the current bounds */
    672 if( cutoff )
    673 {
    674 SCIPdebugMsg(scip, "> subproblem is infeasible within the local bounds\n");
    675 *infeasible = TRUE;
    676 return SCIP_OKAY;
    677 }
    678#ifdef SCIP_MORE_DEBUG
    679 SCIPdebugMsg(scip, "> tighten upper bound of variable <%s>: %g to %g\n",
    680 SCIPvarGetName(vars[v]), SCIPvarGetUbGlobal(vars[v]), newlb);
    681#endif
    682 }
    683 else
    684 {
    685 assert(SCIPvarGetProbindex(vars[v]) >= 0);
    686 tightened[SCIPvarGetProbindex(vars[v])] = TRUE;
    687 ++nbndtightenings;
    688#ifdef SCIP_MORE_DEBUG
    689 SCIPdebugMsg(scip, "> tighten lower bound of variable <%s>: %g to %g (ndomreds=%lld)\n",
    690 SCIPvarGetName(vars[v]), SCIPvarGetLbGlobal(vars[v]), newlb, ndomreds);
    691#endif
    692 }
    693 }
    694 else
    695 /* abort probing */
    696 abortearly = TRUE;
    697 }
    698 }
    699 }
    700
    701 ndomredssum += ndomreds;
    702 }
    703
    704 SCIPdebugMsg(scip, "> found %d bound tightenings and %lld induced domain reductions (abort=%u).\n", nbndtightenings,
    705 ndomredssum, abortearly);
    706
    707 return SCIP_OKAY;
    708}
    709
    710/* setup and solve the sub-SCIP */
    711static
    713 SCIP* scip, /**< original SCIP data structure */
    714 SCIP* subscip, /**< sub-SCIP data structure */
    715 SCIP_HEUR* heur, /**< heuristic data structure */
    716 SCIP_HEURDATA* heurdata, /**< heuristic's private data structure */
    717 SCIP_RESULT* result, /**< result data structure */
    718 SCIP_Longint nstallnodes, /**< number of stalling nodes for the subproblem */
    719 SCIP_SOL* partialsol, /**< partial solution */
    720 SCIP_Bool* tightened /**< array to store whether a variable was already tightened */
    721 )
    722{
    723 SCIP_HASHMAP* varmapf;
    724 SCIP_VAR** vars;
    725 SCIP_VAR** subvars = NULL;
    726 SCIP_EVENTHDLR* eventhdlr;
    727 int nvars;
    728 int i;
    729
    730 SCIP_SOL** subsols;
    731 int nsubsols;
    732
    733 SCIP_Bool valid;
    734 SCIP_Bool success;
    735 SCIP_RETCODE retcode;
    736
    737 assert(scip != NULL);
    738 assert(subscip != NULL);
    739 assert(heur != NULL);
    740 assert(heurdata != NULL);
    741 assert(result != NULL);
    742 assert(partialsol != NULL);
    743
    744 vars = SCIPgetVars(scip);
    745 nvars = SCIPgetNVars(scip);
    746
    747 /* create the variable mapping hash map */
    748 SCIP_CALL( SCIPhashmapCreate(&varmapf, SCIPblkmem(subscip), nvars) );
    749
    750 eventhdlr = NULL;
    751 valid = FALSE;
    752
    753 /* copy complete SCIP instance */
    754 SCIP_CALL( SCIPcopyConsCompression(scip, subscip, varmapf, NULL, "completesol", NULL, NULL, 0, FALSE, FALSE, FALSE,
    755 TRUE, &valid) );
    756 SCIPdebugMsg(scip, "Copying the SCIP instance returned with valid=%u.\n", valid);
    757
    758 /* create event handler for LP events */
    759 SCIP_CALL( SCIPincludeEventhdlrBasic(subscip, &eventhdlr, EVENTHDLR_NAME, EVENTHDLR_DESC, eventExecCompletesol, NULL) );
    760 if( eventhdlr == NULL )
    761 {
    762 SCIPerrorMessage("event handler for " HEUR_NAME " heuristic not found.\n");
    763 return SCIP_PLUGINNOTFOUND;
    764 }
    765
    766 /* allocate memory to align the SCIP and the sub-SCIP variables */
    767 SCIP_CALL( SCIPallocBufferArray(scip, &subvars, nvars) );
    768
    769 /* map all variables */
    770 for( i = 0; i < nvars; i++ )
    771 subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmapf, vars[i]);
    772
    773 /* free hash map */
    774 SCIPhashmapFree(&varmapf);
    775
    776 /* create a new problem, which fixes variables with same value in bestsol and LP relaxation */
    777 SCIP_CALL( createSubproblem(scip, subscip, heurdata, subvars, partialsol, tightened) );
    778 SCIPdebugMsg(scip, "Completesol subproblem: %d vars, %d cons\n", SCIPgetNVars(subscip), SCIPgetNConss(subscip));
    779
    780 /* do not abort subproblem on CTRL-C */
    781 SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
    782
    783#ifdef SCIP_DEBUG
    784 /* for debugging, enable full output */
    785 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", SCIP_VERBLEVEL_FULL) );
    786 SCIP_CALL( SCIPsetIntParam(subscip, "display/freq", -1) );
    787#else
    788 /* disable statistic timing inside sub SCIP and output to console */
    789 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", (int) SCIP_VERBLEVEL_NONE) );
    790 SCIP_CALL( SCIPsetBoolParam(subscip, "timing/statistictiming", FALSE) );
    791#endif
    792
    793 /* set limits for the subproblem */
    794 SCIP_CALL( SCIPcopyLimits(scip, subscip) );
    795 heurdata->nodelimit = heurdata->maxnodes;
    796 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/stallnodes", nstallnodes) );
    797 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", heurdata->maxnodes) );
    798 SCIP_CALL( SCIPsetIntParam(subscip, "limits/bestsol", heurdata->bestsols) );
    799
    800 /* limit the number of LP iterations */
    801 SCIP_CALL( SCIPsetLongintParam(subscip, "lp/iterlim", heurdata->maxlpiter) );
    802 SCIP_CALL( SCIPsetLongintParam(subscip, "lp/rootiterlim", heurdata->maxlpiter) );
    803
    804 /* forbid recursive call of heuristics and separators solving sub-SCIPs */
    805 SCIP_CALL( SCIPsetSubscipsOff(subscip, TRUE) );
    806
    807 /* disable cutting plane separation */
    809
    810 /* disable expensive presolving */
    812
    813 /* use best estimate node selection */
    814 if( SCIPfindNodesel(subscip, "estimate") != NULL && !SCIPisParamFixed(subscip, "nodeselection/estimate/stdpriority") )
    815 {
    816 SCIP_CALL( SCIPsetIntParam(subscip, "nodeselection/estimate/stdpriority", INT_MAX/4) );
    817 }
    818
    819 /* use inference branching */
    820 if( SCIPfindBranchrule(subscip, "inference") != NULL && !SCIPisParamFixed(subscip, "branching/inference/priority") )
    821 {
    822 SCIP_CALL( SCIPsetIntParam(subscip, "branching/inference/priority", INT_MAX/4) );
    823 }
    824
    825 /* disable conflict analysis */
    826 if( !SCIPisParamFixed(subscip, "conflict/enable") )
    827 {
    828 SCIP_CALL( SCIPsetBoolParam(subscip, "conflict/enable", FALSE) );
    829 }
    830
    831 /* speed up sub-SCIP by not checking dual LP feasibility */
    832 SCIP_CALL( SCIPsetBoolParam(subscip, "lp/checkdualfeas", FALSE) );
    833
    834 SCIP_CALL( SCIPtransformProb(subscip) );
    835 SCIP_CALL( SCIPcatchEvent(subscip, SCIP_EVENTTYPE_LPSOLVED, eventhdlr, (SCIP_EVENTDATA*) heurdata, NULL) );
    836
    837 /* solve the subproblem */
    838 SCIPdebugMsg(scip, "solving subproblem: nstallnodes=%" SCIP_LONGINT_FORMAT ", maxnodes=%" SCIP_LONGINT_FORMAT "\n", nstallnodes, heurdata->maxnodes);
    839
    840 /* errors in solving the subproblem should not kill the overall solving process;
    841 * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
    842 */
    843
    844 retcode = SCIPpresolve(subscip);
    845
    846 /* errors in presolving the subproblem should not kill the overall solving process;
    847 * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
    848 */
    849 if( retcode != SCIP_OKAY )
    850 {
    851 SCIPwarningMessage(scip, "Error while presolving subproblem in %s heuristic; sub-SCIP terminated with code <%d>\n", HEUR_NAME, retcode);
    852
    853 SCIPABORT(); /*lint --e{527}*/
    854
    855 goto TERMINATE;
    856 }
    857
    858 if( SCIPgetStage(subscip) == SCIP_STAGE_PRESOLVED )
    859 {
    860 SCIPdebugMsg(scip, "presolved instance has bin=%d, int=%d, cont=%d variables\n",
    861 SCIPgetNBinVars(subscip) + SCIPgetNBinImplVars(subscip),
    862 SCIPgetNIntVars(subscip) + SCIPgetNIntImplVars(subscip),
    863 SCIPgetNContVars(subscip) + SCIPgetNContImplVars(subscip));
    864
    865 /* check whether the presolved instance is small enough */
    866 if( heurdata->maxcontvars >= 0 && SCIPgetNContVars(subscip) > heurdata->maxcontvars )
    867 {
    868 SCIPdebugMsg(scip, "presolved instance has too many continuous variables (maxcontvars: %d)\n", heurdata->maxcontvars);
    869 goto TERMINATE;
    870 }
    871
    872 /* set node limit of 1 if the presolved problem is an LP, otherwise we would start branching if an LP iteration
    873 * limit was set by the user.
    874 */
    875 if( !SCIPisNLPEnabled(subscip) && SCIPgetNContVars(subscip) == SCIPgetNVars(subscip) )
    876 {
    877 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", 1LL) );
    878 }
    879
    880 retcode = SCIPsolve(subscip);
    881
    882 /* errors in solving the subproblem should not kill the overall solving process;
    883 * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
    884 */
    885 if( retcode != SCIP_OKAY )
    886 {
    887 SCIPwarningMessage(scip, "Error while solving subproblem in %s heuristic; sub-SCIP terminated with code <%d>\n", HEUR_NAME, retcode);
    888
    889 SCIPABORT(); /*lint --e{527}*/
    890
    891 goto TERMINATE;
    892 }
    893 }
    894
    895 SCIP_CALL( SCIPdropEvent(subscip, SCIP_EVENTTYPE_LPSOLVED, eventhdlr, (SCIP_EVENTDATA*) heurdata, -1) );
    896
    897 /* print solving statistics of subproblem if we are in SCIP's debug mode */
    899
    900 /* check, whether a solution was found;
    901 * due to numerics, it might happen that not all solutions are feasible -> try all solutions until one was accepted
    902 */
    903 nsubsols = SCIPgetNSols(subscip);
    904 subsols = SCIPgetSols(subscip);
    905 success = FALSE;
    906 for( i = 0; i < nsubsols && (!success || heurdata->addallsols); i++ )
    907 {
    908 SCIP_SOL* newsol;
    909
    910 /* create new solution, try to add to SCIP, and free it immediately */
    911 SCIP_CALL( SCIPtranslateSubSol(scip, subscip, subsols[i], heur, subvars, &newsol) );
    912 SCIP_CALL( SCIPtrySolFree(scip, &newsol, FALSE, FALSE, TRUE, TRUE, TRUE, &success) );
    913
    914 if( success )
    915 *result = SCIP_FOUNDSOL;
    916 }
    917
    918 SCIPstatisticPrintf("%s statistic: fixed %6.3f integer variables, needed %6.1f seconds, %" SCIP_LONGINT_FORMAT " nodes, solution %10.4f found at node %" SCIP_LONGINT_FORMAT "\n",
    919 HEUR_NAME, 0.0, SCIPgetSolvingTime(subscip), SCIPgetNNodes(subscip), success ? SCIPgetPrimalbound(scip) : SCIPinfinity(scip),
    920 nsubsols > 0 ? SCIPsolGetNodenum(SCIPgetBestSol(subscip)) : -1 );
    921
    922 /* print message if the completion of a partial solution failed */
    923 if( *result != SCIP_FOUNDSOL )
    924 {
    925 switch( SCIPgetStatus(subscip) )
    926 {
    928 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "completion of a partial solution failed (subproblem is infeasible)\n");
    929 break;
    931 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "completion of a partial solution failed (node limit exceeded)\n");
    932 break;
    934 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "completion of a partial solution failed (time limit exceeded)\n");
    935 break;
    937 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "completion of a partial solution failed (memory limit exceeded)\n");
    938 break;
    939 default:
    940 break;
    941 } /*lint !e788*/
    942 }
    943
    944TERMINATE:
    945 SCIPfreeBufferArray(scip, &subvars);
    946
    947 return SCIP_OKAY;
    948}
    949
    950/** main procedure of the completesol heuristic, creates and solves a sub-SCIP */
    951static
    953 SCIP* scip, /**< original SCIP data structure */
    954 SCIP_HEUR* heur, /**< heuristic data structure */
    955 SCIP_HEURDATA* heurdata, /**< heuristic's private data structure */
    956 SCIP_RESULT* result, /**< result data structure */
    957 SCIP_Longint nstallnodes, /**< number of stalling nodes for the subproblem */
    958 SCIP_SOL* partialsol /**< partial solution */
    959 )
    960{
    961 SCIP* subscip;
    962 SCIP_VAR** vars;
    963 SCIP_Bool* tightened;
    964 SCIP_Bool infeasible;
    965 SCIP_Bool success;
    966 SCIP_RETCODE retcode;
    967 int nvars;
    968
    969 assert(scip != NULL);
    970 assert(heur != NULL);
    971 assert(heurdata != NULL);
    972 assert(result != NULL);
    973 assert(partialsol != NULL);
    974
    975 *result = SCIP_DIDNOTRUN;
    976
    977 SCIPdebugMsg(scip, "+---+ Start Completesol heuristic +---+\n");
    978
    979 /* check whether there is enough time and memory left */
    980 SCIP_CALL( SCIPcheckCopyLimits(scip, &success) );
    981
    982 if( !success )
    983 return SCIP_OKAY;
    984
    985 *result = SCIP_DIDNOTFIND;
    986
    987 /* get variable data */
    988 vars = SCIPgetVars(scip);
    989 nvars = SCIPgetNVars(scip);
    990
    991 /* get buffer memory and initialize it to FALSE */
    992 SCIP_CALL( SCIPallocClearBufferArray(scip, &tightened, nvars) );
    993
    995
    996 SCIP_CALL( tightenVariables(scip, heurdata, vars, nvars, partialsol, tightened, &infeasible) );
    997
    998 if( infeasible )
    999 {
    1000 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "completion of a partial solution failed (subproblem is infeasible)\n");
    1001 goto ENDPROBING;
    1002 }
    1003
    1004 /* initialize the subproblem */
    1005 SCIP_CALL( SCIPcreate(&subscip) );
    1006
    1007 retcode = setupAndSolve(scip, subscip, heur, heurdata, result, nstallnodes, partialsol, tightened);
    1008
    1009 /* free subproblem */
    1010 SCIP_CALL( SCIPfree(&subscip) );
    1011
    1012 SCIP_CALL( retcode );
    1013
    1014 ENDPROBING:
    1015 SCIPfreeBufferArray(scip, &tightened);
    1017
    1018 return SCIP_OKAY;
    1019}
    1020
    1021
    1022/*
    1023 * Callback methods of primal heuristic
    1024 */
    1025
    1026/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
    1027static
    1028SCIP_DECL_HEURCOPY(heurCopyCompletesol)
    1029{ /*lint --e{715}*/
    1030 assert(scip != NULL);
    1031 assert(heur != NULL);
    1032
    1034
    1035 /* call inclusion method of primal heuristic */
    1037
    1038 return SCIP_OKAY;
    1039}
    1040
    1041/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
    1042static
    1043SCIP_DECL_HEURFREE(heurFreeCompletesol)
    1044{ /*lint --e{715}*/
    1045 SCIP_HEURDATA* heurdata;
    1046
    1047 assert(heur != NULL);
    1048 assert(scip != NULL);
    1049
    1050 /* get heuristic data */
    1051 heurdata = SCIPheurGetData(heur);
    1052 assert(heurdata != NULL);
    1053
    1054 /* free heuristic data */
    1055 SCIPfreeBlockMemory(scip, &heurdata);
    1056 SCIPheurSetData(heur, NULL);
    1057
    1058 return SCIP_OKAY;
    1059}
    1060
    1061/** execution method of primal heuristic */
    1062static
    1063SCIP_DECL_HEUREXEC(heurExecCompletesol)
    1064{/*lint --e{715}*/
    1065 SCIP_HEURDATA* heurdata;
    1066 SCIP_VAR** vars;
    1067 SCIP_SOL** partialsols;
    1068 SCIP_Longint nstallnodes;
    1069 int npartialsols;
    1070 int nunknown;
    1071 int nfracints;
    1072 int nvars;
    1073 int s;
    1074 int v;
    1075
    1076 assert( heur != NULL );
    1077 assert( scip != NULL );
    1078 assert( result != NULL );
    1079
    1080 *result = SCIP_DELAYED;
    1081
    1082 /* do not call heuristic if node was already detected to be infeasible */
    1083 if( nodeinfeasible )
    1084 return SCIP_OKAY;
    1085
    1086 /* get heuristic data */
    1087 heurdata = SCIPheurGetData(heur);
    1088 assert( heurdata != NULL );
    1089
    1090 *result = SCIP_DIDNOTRUN;
    1091
    1092 if( SCIPisStopped(scip) )
    1093 return SCIP_OKAY;
    1094
    1095 /* do not run after restart */
    1096 if( SCIPgetNRuns(scip) > 1 )
    1097 return SCIP_OKAY;
    1098
    1099 /* check whether we want to run before presolving */
    1100 if( (heurtiming & SCIP_HEURTIMING_BEFOREPRESOL) && !heurdata->beforepresol )
    1101 return SCIP_OKAY;
    1102
    1103 /* only run before root node */
    1104 if( (heurtiming & SCIP_HEURTIMING_BEFORENODE)
    1105 && (heurdata->beforepresol || SCIPgetCurrentNode(scip) != SCIPgetRootNode(scip)) )
    1106 return SCIP_OKAY;
    1107
    1108 /* get variable data and return if no variables are left in the problem */
    1109 vars = SCIPgetVars(scip);
    1110 nvars = SCIPgetNVars(scip);
    1111 if( heurdata->ignorecont )
    1113 assert(nvars >= 0);
    1114
    1115 if( nvars == 0 )
    1116 return SCIP_OKAY;
    1117
    1118 /* calculate the maximal number of branching nodes until heuristic is aborted */
    1119 nstallnodes = (SCIP_Longint)(heurdata->nodesquot * SCIPgetNNodes(scip));
    1120
    1121 /* reward Completesol if it succeeded often */
    1122 nstallnodes = (SCIP_Longint)(nstallnodes * 3.0 * (SCIPheurGetNBestSolsFound(heur)+1.0)/(SCIPheurGetNCalls(heur) + 1.0));
    1123 nstallnodes -= 100 * SCIPheurGetNCalls(heur); /* count the setup costs for the sub-SCIP as 100 nodes */
    1124 nstallnodes += heurdata->nodesofs;
    1125
    1126 /* determine the node limit for the current process */
    1127 nstallnodes = MIN(nstallnodes, heurdata->maxnodes);
    1128
    1129 /* check whether we have enough nodes left to call subproblem solving */
    1130 if( nstallnodes < heurdata->minnodes )
    1131 {
    1132 SCIPdebugMsg(scip, "skipping Complete: nstallnodes=%" SCIP_LONGINT_FORMAT ", minnodes=%" SCIP_LONGINT_FORMAT "\n",
    1133 nstallnodes, heurdata->minnodes);
    1134 return SCIP_OKAY;
    1135 }
    1136
    1137 /* check the number of variables with unknown value and continuous variables with fractional value */
    1138 nfracints = 0;
    1139
    1140 /* get all partial sols */
    1141 npartialsols = SCIPgetNPartialSols(scip);
    1142 partialsols = SCIPgetPartialSols(scip);
    1143
    1144 /* loop over all partial solutions */
    1145 for( s = 0; s < npartialsols; s++ )
    1146 {
    1147 SCIP_SOL* sol;
    1148 SCIP_Real solval;
    1149 SCIP_Real unknownrate;
    1150
    1151 sol = partialsols[s];
    1152 assert(sol != NULL);
    1153 assert(SCIPsolIsPartial(sol));
    1154
    1155 nunknown = 0;
    1156 /* loop over all variables */
    1157 for( v = 0; v < nvars; v++ )
    1158 {
    1159 assert(SCIPvarIsActive(vars[v]));
    1160
    1161 solval = SCIPgetSolVal(scip, sol, vars[v]);
    1162
    1163 /* we only want to count variables that are unfixed after the presolving */
    1164 if( solval == SCIP_UNKNOWN ) /*lint !e777*/
    1165 ++nunknown;
    1166 else if( SCIPvarGetType(vars[v]) != SCIP_VARTYPE_CONTINUOUS && !SCIPisIntegral(scip, solval) )
    1167 ++nfracints;
    1168 }
    1169
    1170 unknownrate = nunknown / ((SCIP_Real)nvars);
    1171
    1172 SCIPdebugMsg(scip, "%d (rate %.4f) unknown solution values\n", nunknown, unknownrate);
    1173
    1174 /* run the heuristic, if not too many unknown variables exist */
    1175 if( unknownrate > heurdata->maxunknownrate )
    1176 {
    1177 SCIPwarningMessage(scip, "ignore partial solution (%d) because unknown rate is too large (%g > %g)\n", s,
    1178 unknownrate, heurdata->maxunknownrate);
    1179 continue;
    1180 }
    1181
    1182 /* all variables have a finite/known solution value all integer variables have an integral solution value,
    1183 * and there are no continuous variables
    1184 * in the sub-SCIP, all variables would be fixed, so create a new solution without solving a sub-SCIP
    1185 */
    1186 if( nunknown == 0 && nfracints == 0 && nvars == SCIPgetNVars(scip) )
    1187 {
    1188 SCIP_SOL* newsol;
    1189 SCIP_Bool stored;
    1190
    1191 assert(vars != NULL);
    1192 assert(nvars >= 0);
    1193
    1194 SCIP_CALL( SCIPcreateSol(scip, &newsol, heur) );
    1195
    1196 for( v = 0; v < nvars; v++ )
    1197 {
    1198 solval = SCIPgetSolVal(scip, sol, vars[v]);
    1199 assert(solval != SCIP_UNKNOWN); /*lint !e777*/
    1200
    1201 SCIP_CALL( SCIPsetSolVal(scip, newsol, vars[v], solval) );
    1202 }
    1203
    1204 SCIP_CALL( SCIPtrySolFree(scip, &newsol, FALSE, FALSE, TRUE, TRUE, TRUE, &stored) );
    1205 if( stored )
    1206 *result = SCIP_FOUNDSOL;
    1207 }
    1208 else
    1209 {
    1210 /* run the heuristic */
    1211 SCIP_CALL( applyCompletesol(scip, heur, heurdata, result, nstallnodes, sol) );
    1212 }
    1213 }
    1214
    1215 return SCIP_OKAY;
    1216}
    1217
    1218
    1219/*
    1220 * primal heuristic specific interface methods
    1221 */
    1222
    1223/** creates the completesol primal heuristic and includes it in SCIP */
    1225 SCIP* scip /**< SCIP data structure */
    1226 )
    1227{
    1228 SCIP_HEURDATA* heurdata;
    1229 SCIP_HEUR* heur;
    1230
    1231 /* create completesol primal heuristic data */
    1232 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
    1233 assert(heurdata != NULL);
    1234
    1235 /* include primal heuristic */
    1238 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecCompletesol, heurdata) );
    1239
    1240 assert(heur != NULL);
    1241
    1242 /* primal heuristic is safe to use in exact solving mode */
    1243 SCIPheurMarkExact(heur);
    1244
    1245 /* set non fundamental callbacks via setter functions */
    1246 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyCompletesol) );
    1247 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeCompletesol) );
    1248
    1249 /* add completesol primal heuristic parameters */
    1250
    1251 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxnodes",
    1252 "maximum number of nodes to regard in the subproblem",
    1253 &heurdata->maxnodes, TRUE, DEFAULT_MAXNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    1254
    1255 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/minnodes",
    1256 "minimum number of nodes required to start the subproblem",
    1257 &heurdata->minnodes, TRUE, DEFAULT_MINNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    1258
    1259 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/maxunknownrate",
    1260 "maximal rate of unknown solution values",
    1261 &heurdata->maxunknownrate, FALSE, DEFAULT_MAXUNKRATE, 0.0, 1.0, NULL, NULL) );
    1262
    1263 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/addallsols",
    1264 "should all subproblem solutions be added to the original SCIP?",
    1265 &heurdata->addallsols, TRUE, DEFAULT_ADDALLSOLS, NULL, NULL) );
    1266
    1267 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/nodesofs",
    1268 "number of nodes added to the contingent of the total nodes",
    1269 &heurdata->nodesofs, FALSE, DEFAULT_NODESOFS, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    1270
    1271 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/nodesquot",
    1272 "contingent of sub problem nodes in relation to the number of nodes of the original problem",
    1273 &heurdata->nodesquot, FALSE, DEFAULT_NODESQUOT, 0.0, 1.0, NULL, NULL) );
    1274
    1275 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/lplimfac",
    1276 "factor by which the limit on the number of LP depends on the node limit",
    1277 &heurdata->lplimfac, TRUE, DEFAULT_LPLIMFAC, 1.0, SCIP_REAL_MAX, NULL, NULL) );
    1278
    1279 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/objweight",
    1280 "weight of the original objective function (1: only original objective)",
    1281 &heurdata->objweight, TRUE, DEFAULT_OBJWEIGHT, DEFAULT_MINOBJWEIGHT, 1.0, NULL, NULL) );
    1282
    1283 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/boundwidening",
    1284 "bound widening factor applied to continuous variables (0: fix variables to given solution values, 1: relax to global bounds)",
    1285 &heurdata->boundwidening, TRUE, DEFAULT_BOUNDWIDENING, 0.0, 1.0, NULL, NULL) );
    1286
    1287 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minimprove",
    1288 "factor by which the incumbent should be improved at least",
    1289 &heurdata->minimprove, TRUE, DEFAULT_MINIMPROVE, 0.0, 1.0, NULL, NULL) );
    1290
    1291 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/ignorecont",
    1292 "should number of continuous variables be ignored?",
    1293 &heurdata->ignorecont, FALSE, DEFAULT_IGNORECONT, NULL, NULL) );
    1294
    1295 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/solutions",
    1296 "heuristic stops, if the given number of improving solutions were found (-1: no limit)",
    1297 &heurdata->bestsols, FALSE, DEFAULT_BESTSOLS, -1, INT_MAX, NULL, NULL) );
    1298
    1299 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxproprounds",
    1300 "maximal number of iterations in propagation (-1: no limit)",
    1301 &heurdata->maxproprounds, FALSE, DEFAULT_MAXPROPROUNDS, -1, INT_MAX, NULL, NULL) );
    1302
    1303 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/beforepresol",
    1304 "should the heuristic run before presolving?",
    1305 &heurdata->beforepresol, FALSE, DEFAULT_BEFOREPRESOL, NULL, NULL) );
    1306
    1307 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxlpiter",
    1308 "maximal number of LP iterations (-1: no limit)",
    1309 &heurdata->maxlpiter, FALSE, DEFAULT_MAXLPITER, -1LL, SCIP_LONGINT_MAX, NULL, NULL) );
    1310
    1311 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxcontvars",
    1312 "maximal number of continuous variables after presolving",
    1313 &heurdata->maxcontvars, FALSE, DEFAULT_MAXCONTVARS, -1, INT_MAX, NULL, NULL) );
    1314
    1315 return SCIP_OKAY;
    1316}
    Constraint handler for linear constraints in their most general form, .
    #define NULL
    Definition: def.h:257
    #define SCIP_MAXSTRLEN
    Definition: def.h:278
    #define SCIP_Longint
    Definition: def.h:150
    #define SCIP_MAXTREEDEPTH
    Definition: def.h:306
    #define SCIP_REAL_MAX
    Definition: def.h:167
    #define SCIP_Bool
    Definition: def.h:100
    #define MIN(x, y)
    Definition: def.h:233
    #define SCIP_STRINGEQ(name, reference, retcode)
    Definition: def.h:454
    #define SCIP_Real
    Definition: def.h:165
    #define SCIP_UNKNOWN
    Definition: def.h:188
    #define TRUE
    Definition: def.h:102
    #define FALSE
    Definition: def.h:103
    #define SCIP_LONGINT_FORMAT
    Definition: def.h:157
    #define SCIPABORT()
    Definition: def.h:336
    #define REALABS(x)
    Definition: def.h:191
    #define SCIP_LONGINT_MAX
    Definition: def.h:151
    #define SCIP_CALL(x)
    Definition: def.h:364
    SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
    SCIP_RETCODE SCIPcreateConsBasicLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs)
    SCIP_RETCODE SCIPcopyConsCompression(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, const char *suffix, SCIP_VAR **fixedvars, SCIP_Real *fixedvals, int nfixedvars, SCIP_Bool global, SCIP_Bool enablepricing, SCIP_Bool threadsafe, SCIP_Bool passmessagehdlr, SCIP_Bool *valid)
    Definition: scip_copy.c:2962
    SCIP_RETCODE SCIPcheckCopyLimits(SCIP *sourcescip, SCIP_Bool *success)
    Definition: scip_copy.c:3250
    SCIP_RETCODE SCIPtranslateSubSol(SCIP *scip, SCIP *subscip, SCIP_SOL *subsol, SCIP_HEUR *heur, SCIP_VAR **subvars, SCIP_SOL **newsol)
    Definition: scip_copy.c:1398
    SCIP_RETCODE SCIPcopyLimits(SCIP *sourcescip, SCIP *targetscip)
    Definition: scip_copy.c:3293
    SCIP_Bool SCIPisStopped(SCIP *scip)
    Definition: scip_general.c:767
    SCIP_RETCODE SCIPfree(SCIP **scip)
    Definition: scip_general.c:402
    SCIP_RETCODE SCIPcreate(SCIP **scip)
    Definition: scip_general.c:370
    SCIP_STATUS SCIPgetStatus(SCIP *scip)
    Definition: scip_general.c:562
    SCIP_STAGE SCIPgetStage(SCIP *scip)
    Definition: scip_general.c:444
    SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_prob.c:1907
    int SCIPgetNIntVars(SCIP *scip)
    Definition: scip_prob.c:2340
    int SCIPgetNContVars(SCIP *scip)
    Definition: scip_prob.c:2569
    int SCIPgetNBinImplVars(SCIP *scip)
    Definition: scip_prob.c:2432
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3274
    int SCIPgetNConss(SCIP *scip)
    Definition: scip_prob.c:3620
    SCIP_VAR ** SCIPgetVars(SCIP *scip)
    Definition: scip_prob.c:2201
    int SCIPgetNIntImplVars(SCIP *scip)
    Definition: scip_prob.c:2477
    int SCIPgetNContImplVars(SCIP *scip)
    Definition: scip_prob.c:2522
    SCIP_OBJSENSE SCIPgetObjsense(SCIP *scip)
    Definition: scip_prob.c:1400
    int SCIPgetNBinVars(SCIP *scip)
    Definition: scip_prob.c:2293
    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
    void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:225
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
    Definition: scip_message.c:120
    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 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 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 SCIPincludeHeurCompletesol(SCIP *scip)
    SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
    Definition: scip_branch.c:304
    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_RETCODE SCIPdropEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
    Definition: scip_event.c:333
    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_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
    Definition: heur.c:1613
    SCIP_Longint SCIPheurGetNCalls(SCIP_HEUR *heur)
    Definition: heur.c:1593
    void SCIPheurMarkExact(SCIP_HEUR *heur)
    Definition: heur.c:1457
    const char * SCIPheurGetName(SCIP_HEUR *heur)
    Definition: heur.c:1467
    void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
    Definition: heur.c:1378
    BMS_BLKMEM * SCIPblkmem(SCIP *scip)
    Definition: scip_mem.c:57
    #define SCIPallocClearBufferArray(scip, ptr, num)
    Definition: scip_mem.h:126
    #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
    SCIP_Bool SCIPisNLPEnabled(SCIP *scip)
    Definition: scip_nlp.c:74
    SCIP_NODESEL * SCIPfindNodesel(SCIP *scip, const char *name)
    Definition: scip_nodesel.c:242
    int SCIPgetProbingDepth(SCIP *scip)
    Definition: scip_probing.c:199
    SCIP_RETCODE SCIPchgVarUbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_probing.c:346
    SCIP_RETCODE SCIPchgVarLbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_probing.c:302
    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_SOL * SCIPgetBestSol(SCIP *scip)
    Definition: scip_sol.c:2986
    SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
    Definition: scip_sol.c:514
    SCIP_SOLORIGIN SCIPsolGetOrigin(SCIP_SOL *sol)
    Definition: sol.c:4145
    SCIP_SOL ** SCIPgetPartialSols(SCIP *scip)
    Definition: scip_sol.c:4268
    SCIP_Longint SCIPsolGetNodenum(SCIP_SOL *sol)
    Definition: sol.c:4254
    int SCIPgetNPartialSols(SCIP *scip)
    Definition: scip_sol.c:4290
    int SCIPgetNSols(SCIP *scip)
    Definition: scip_sol.c:2887
    SCIP_Bool SCIPsolIsPartial(SCIP_SOL *sol)
    Definition: sol.c:4175
    SCIP_SOL ** SCIPgetSols(SCIP *scip)
    Definition: scip_sol.c:2936
    SCIP_RETCODE SCIPtrySolFree(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:4114
    SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
    Definition: scip_sol.c:1569
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1763
    SCIP_RETCODE SCIPtransformProb(SCIP *scip)
    Definition: scip_solve.c:232
    SCIP_RETCODE SCIPpresolve(SCIP *scip)
    Definition: scip_solve.c:2425
    SCIP_RETCODE SCIPinterruptSolve(SCIP *scip)
    Definition: scip_solve.c:3561
    SCIP_RETCODE SCIPsolve(SCIP *scip)
    Definition: scip_solve.c:2611
    SCIP_Real SCIPgetPrimalbound(SCIP *scip)
    SCIP_Real SCIPgetUpperbound(SCIP *scip)
    SCIP_Longint SCIPgetNNodes(SCIP *scip)
    SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
    SCIP_Real SCIPgetLowerbound(SCIP *scip)
    int SCIPgetNRuns(SCIP *scip)
    SCIP_Longint SCIPgetNLPs(SCIP *scip)
    SCIP_Real SCIPgetSolvingTime(SCIP *scip)
    Definition: scip_timing.c:378
    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 SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPsumepsilon(SCIP *scip)
    SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
    Definition: scip_tree.c:91
    SCIP_NODE * SCIPgetRootNode(SCIP *scip)
    Definition: scip_tree.c:110
    SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
    Definition: var.c:23674
    SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
    Definition: var.c:23510
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24300
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23932
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23485
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24174
    int SCIPvarGetProbindex(SCIP_VAR *var)
    Definition: var.c:23694
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23299
    SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
    Definition: scip_var.c:1887
    SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
    Definition: var.c:23522
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24266
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24152
    SCIP_RETCODE SCIPcreateVarBasic(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype)
    Definition: scip_var.c:184
    SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
    Definition: scip_var.c:5372
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    static SCIP_RETCODE createSubproblem(SCIP *scip, SCIP *subscip, SCIP_HEURDATA *heurdata, SCIP_VAR **subvars, SCIP_SOL *partialsol, SCIP_Bool *tightened)
    #define DEFAULT_BESTSOLS
    #define DEFAULT_NODESQUOT
    static SCIP_DECL_HEURCOPY(heurCopyCompletesol)
    static SCIP_DECL_HEURFREE(heurFreeCompletesol)
    #define DEFAULT_MAXCONTVARS
    static SCIP_RETCODE chgProbingBound(SCIP *scip, SCIP_VAR *var, SCIP_Real newval, SCIP_BRANCHDIR branchdir, SCIP_Bool *success)
    #define DEFAULT_OBJWEIGHT
    #define DEFAULT_NODESOFS
    static SCIP_RETCODE tightenVariables(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_VAR **vars, int nvars, SCIP_SOL *sol, SCIP_Bool *tightened, SCIP_Bool *infeasible)
    #define DEFAULT_MAXNODES
    static SCIP_DECL_EVENTEXEC(eventExecCompletesol)
    #define HEUR_TIMING
    #define DEFAULT_MINNODES
    #define DEFAULT_MAXUNKRATE
    #define DEFAULT_IGNORECONT
    #define HEUR_FREQOFS
    #define HEUR_DESC
    #define DEFAULT_LPLIMFAC
    #define DEFAULT_ADDALLSOLS
    static SCIP_RETCODE setupAndSolve(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, SCIP_RESULT *result, SCIP_Longint nstallnodes, SCIP_SOL *partialsol, SCIP_Bool *tightened)
    static SCIP_RETCODE applyCompletesol(SCIP *scip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, SCIP_RESULT *result, SCIP_Longint nstallnodes, SCIP_SOL *partialsol)
    #define HEUR_DISPCHAR
    #define HEUR_MAXDEPTH
    #define HEUR_PRIORITY
    #define DEFAULT_MINOBJWEIGHT
    #define DEFAULT_MINIMPROVE
    #define HEUR_NAME
    #define DEFAULT_MAXLPITER
    static SCIP_DECL_HEUREXEC(heurExecCompletesol)
    #define DEFAULT_BEFOREPRESOL
    #define EVENTHDLR_DESC
    #define HEUR_FREQ
    #define HEUR_USESSUBSCIP
    #define DEFAULT_MAXPROPROUNDS
    #define EVENTHDLR_NAME
    #define DEFAULT_BOUNDWIDENING
    primal heuristic trying to complete given partial solutions
    memory allocation routines
    real eps
    public methods for managing events
    public methods for primal heuristics
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPdebug(x)
    Definition: pub_message.h:93
    #define SCIPstatisticPrintf
    Definition: pub_message.h:126
    public data structures and miscellaneous methods
    public methods for primal CIP solutions
    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
    general public methods
    public methods for primal heuristic plugins and divesets
    public methods for memory management
    public methods for message handling
    public methods for nonlinear relaxation
    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 the probing mode
    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
    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
    @ SCIP_BRANCHDIR_DOWNWARDS
    Definition: type_history.h:43
    @ SCIP_BRANCHDIR_FIXED
    Definition: type_history.h:45
    @ SCIP_BRANCHDIR_UPWARDS
    Definition: type_history.h:44
    enum SCIP_BranchDir SCIP_BRANCHDIR
    Definition: type_history.h:48
    @ SCIP_VERBLEVEL_NONE
    Definition: type_message.h:57
    @ SCIP_VERBLEVEL_HIGH
    Definition: type_message.h:61
    @ SCIP_VERBLEVEL_FULL
    Definition: type_message.h:62
    @ SCIP_PARAMSETTING_OFF
    Definition: type_paramset.h:63
    @ SCIP_PARAMSETTING_FAST
    Definition: type_paramset.h:62
    @ SCIP_OBJSENSE_MAXIMIZE
    Definition: type_prob.h:47
    @ SCIP_OBJSENSE_MINIMIZE
    Definition: type_prob.h:48
    @ 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_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_PLUGINNOTFOUND
    Definition: type_retcode.h:54
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_STAGE_PRESOLVED
    Definition: type_set.h:51
    @ SCIP_SOLORIGIN_PARTIAL
    Definition: type_sol.h:48
    @ SCIP_STATUS_TIMELIMIT
    Definition: type_stat.h:54
    @ SCIP_STATUS_INFEASIBLE
    Definition: type_stat.h:44
    @ SCIP_STATUS_NODELIMIT
    Definition: type_stat.h:49
    @ SCIP_STATUS_MEMLIMIT
    Definition: type_stat.h:55
    #define SCIP_HEURTIMING_BEFOREPRESOL
    Definition: type_timing.h:92
    #define SCIP_HEURTIMING_BEFORENODE
    Definition: type_timing.h:80
    @ SCIP_VARTYPE_CONTINUOUS
    Definition: type_var.h:71