SCIP

    Solving Constraint Integer Programs

    heur_zeroobj.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_zeroobj.c
    26 * @ingroup DEFPLUGINS_HEUR
    27 * @brief heuristic that tries to solve the problem without objective. In Gurobi, this heuristic is known as "Hail Mary"
    28 * @author Timo Berthold
    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/heur_zeroobj.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_var.h"
    41#include "scip/scip_branch.h"
    42#include "scip/scip_cons.h"
    43#include "scip/scip_copy.h"
    44#include "scip/scip_event.h"
    45#include "scip/scip_general.h"
    46#include "scip/scip_heur.h"
    47#include "scip/scip_lp.h"
    48#include "scip/scip_mem.h"
    49#include "scip/scip_message.h"
    50#include "scip/scip_nodesel.h"
    51#include "scip/scip_numerics.h"
    52#include "scip/scip_param.h"
    53#include "scip/scip_prob.h"
    54#include "scip/scip_sol.h"
    55#include "scip/scip_solve.h"
    57#include "scip/scip_tree.h"
    58#include "scip/scip_var.h"
    59
    60
    61#define HEUR_NAME "zeroobj"
    62#define HEUR_DESC "heuristic trying to solve the problem without objective"
    63#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_LNS
    64#define HEUR_PRIORITY 100
    65#define HEUR_FREQ -1
    66#define HEUR_FREQOFS 0
    67#define HEUR_MAXDEPTH 0
    68#define HEUR_TIMING SCIP_HEURTIMING_BEFORENODE | SCIP_HEURTIMING_BEFOREPRESOL
    69#define HEUR_USESSUBSCIP TRUE /**< does the heuristic use a secondary SCIP instance? */
    70
    71/* event handler properties */
    72#define EVENTHDLR_NAME "Zeroobj"
    73#define EVENTHDLR_DESC "LP event handler for " HEUR_NAME " heuristic"
    74
    75/* default values for zeroobj-specific plugins */
    76#define DEFAULT_MAXNODES 1000LL /* maximum number of nodes to regard in the subproblem */
    77#define DEFAULT_MINIMPROVE 0.01 /* factor by which zeroobj should at least improve the incumbent */
    78#define DEFAULT_MINNODES 100LL /* minimum number of nodes to regard in the subproblem */
    79#define DEFAULT_MAXLPITERS 5000LL /* maximum number of LP iterations to be performed in the subproblem */
    80#define DEFAULT_NODESOFS 100LL /* 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_ADDALLSOLS FALSE /* should all subproblem solutions be added to the original SCIP? */
    83#define DEFAULT_ONLYWITHOUTSOL TRUE /**< should heuristic only be executed if no primal solution was found, yet? */
    84#define DEFAULT_USEUCT FALSE /* should uct node selection be used at the beginning of the search? */
    85
    86/*
    87 * Data structures
    88 */
    89
    90/** primal heuristic data */
    91struct SCIP_HeurData
    92{
    93 SCIP_Longint maxnodes; /**< maximum number of nodes to regard in the subproblem */
    94 SCIP_Longint minnodes; /**< minimum number of nodes to regard in the subproblem */
    95 SCIP_Longint maxlpiters; /**< maximum number of LP iterations to be performed in the subproblem */
    96 SCIP_Longint nodesofs; /**< number of nodes added to the contingent of the total nodes */
    97 SCIP_Longint usednodes; /**< nodes already used by zeroobj in earlier calls */
    98 SCIP_Real minimprove; /**< factor by which zeroobj should at least improve the incumbent */
    99 SCIP_Real nodesquot; /**< subproblem nodes in relation to nodes of the original problem */
    100 SCIP_Bool addallsols; /**< should all subproblem solutions be added to the original SCIP? */
    101 SCIP_Bool onlywithoutsol; /**< should heuristic only be executed if no primal solution was found, yet? */
    102 SCIP_Bool useuct; /**< should uct node selection be used at the beginning of the search? */
    103};
    104
    105
    106/*
    107 * Local methods
    108 */
    109
    110/* ---------------- Callback methods of event handler ---------------- */
    111
    112/* exec the event handler
    113 *
    114 * we interrupt the solution process
    115 */
    116static
    117SCIP_DECL_EVENTEXEC(eventExecZeroobj)
    118{
    119 SCIP_HEURDATA* heurdata;
    120
    121 assert(eventhdlr != NULL);
    122 assert(eventdata != NULL);
    123 assert(event != NULL);
    125
    127
    128 heurdata = (SCIP_HEURDATA*)eventdata;
    129 assert(heurdata != NULL);
    130
    131 /* interrupt solution process of sub-SCIP */
    132 if( SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_ITERLIMIT || SCIPgetNLPIterations(scip) >= heurdata->maxlpiters )
    133 {
    135 }
    136
    137 return SCIP_OKAY;
    138}
    139/* ---------------- Callback methods of primal heuristic ---------------- */
    140
    141/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
    142static
    143SCIP_DECL_HEURCOPY(heurCopyZeroobj)
    144{ /*lint --e{715}*/
    145 assert(scip != NULL);
    146 assert(heur != NULL);
    147
    149
    150 /* call inclusion method of primal heuristic */
    152
    153 return SCIP_OKAY;
    154}
    155
    156/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
    157static
    158SCIP_DECL_HEURFREE(heurFreeZeroobj)
    159{ /*lint --e{715}*/
    160 SCIP_HEURDATA* heurdata;
    161
    162 assert( heur != NULL );
    163 assert( scip != NULL );
    164
    165 /* get heuristic data */
    166 heurdata = SCIPheurGetData(heur);
    167 assert( heurdata != NULL );
    168
    169 /* free heuristic data */
    170 SCIPfreeBlockMemory(scip, &heurdata);
    171 SCIPheurSetData(heur, NULL);
    172
    173 return SCIP_OKAY;
    174}
    175
    176
    177/** initialization method of primal heuristic (called after problem was transformed) */
    178static
    179SCIP_DECL_HEURINIT(heurInitZeroobj)
    180{ /*lint --e{715}*/
    181 SCIP_HEURDATA* heurdata;
    182
    183 assert( heur != NULL );
    184 assert( scip != NULL );
    185
    186 /* get heuristic data */
    187 heurdata = SCIPheurGetData(heur);
    188 assert( heurdata != NULL );
    189
    190 /* initialize data */
    191 heurdata->usednodes = 0;
    192
    193 return SCIP_OKAY;
    194}
    195
    196
    197/** execution method of primal heuristic */
    198static
    199SCIP_DECL_HEUREXEC(heurExecZeroobj)
    200{ /*lint --e{715}*/
    201 SCIP_HEURDATA* heurdata; /* heuristic's data */
    202 SCIP_Longint nnodes; /* number of stalling nodes for the subproblem */
    203
    204 assert( heur != NULL );
    205 assert( scip != NULL );
    206 assert( result != NULL );
    207
    208 /* get heuristic data */
    209 heurdata = SCIPheurGetData(heur);
    210 assert( heurdata != NULL );
    211
    212 /* calculate the maximal number of branching nodes until heuristic is aborted */
    213 nnodes = (SCIP_Longint)(heurdata->nodesquot * SCIPgetNNodes(scip));
    214
    215 /* reward zeroobj if it succeeded often */
    216 nnodes = (SCIP_Longint)(nnodes * 3.0 * (SCIPheurGetNBestSolsFound(heur)+1.0)/(SCIPheurGetNCalls(heur) + 1.0));
    217 nnodes -= 100 * SCIPheurGetNCalls(heur); /* count the setup costs for the sub-SCIP as 100 nodes */
    218 nnodes += heurdata->nodesofs;
    219
    220 /* determine the node limit for the current process */
    221 nnodes -= heurdata->usednodes;
    222 nnodes = MIN(nnodes, heurdata->maxnodes);
    223
    224 /* check whether we have enough nodes left to call subproblem solving */
    225 if( nnodes < heurdata->minnodes )
    226 {
    227 SCIPdebugMsg(scip, "skipping zeroobj: nnodes=%" SCIP_LONGINT_FORMAT ", minnodes=%" SCIP_LONGINT_FORMAT "\n", nnodes, heurdata->minnodes);
    228 return SCIP_OKAY;
    229 }
    230
    231 /* do not run zeroobj, if the problem does not have an objective function anyway */
    232 if( SCIPgetNObjVars(scip) == 0 )
    233 {
    234 SCIPdebugMsg(scip, "skipping zeroobj: pure feasibility problem anyway\n");
    235 return SCIP_OKAY;
    236 }
    237
    238 if( SCIPisStopped(scip) )
    239 return SCIP_OKAY;
    240
    241 SCIP_CALL( SCIPapplyZeroobj(scip, heur, result, heurdata->minimprove, nnodes) );
    242
    243 return SCIP_OKAY;
    244}
    245
    246/** setup and solve subscip */
    247static
    249 SCIP* scip, /**< SCIP data structure */
    250 SCIP* subscip, /**< SCIP data structure */
    251 SCIP_HEUR* heur, /**< heuristic data structure */
    252 SCIP_RESULT* result, /**< result data structure */
    253 SCIP_Real minimprove, /**< factor by which zeroobj should at least improve the incumbent */
    254 SCIP_Longint nnodes /**< node limit for the subproblem */
    255 )
    256{
    257 SCIP_Real cutoff; /* objective cutoff for the subproblem */
    258 SCIP_Real large;
    259 SCIP_HASHMAP* varmapfw; /* mapping of SCIP variables to sub-SCIP variables */
    260 SCIP_VAR** vars; /* original problem's variables */
    261 SCIP_VAR** subvars; /* subproblem's variables */
    262 SCIP_SOL** subsols;
    263 SCIP_HEURDATA* heurdata; /* heuristic's private data structure */
    264 SCIP_EVENTHDLR* eventhdlr; /* event handler for LP events */
    265
    266 int nsubsols;
    267 int nvars; /* number of original problem's variables */
    268 int i;
    269 SCIP_Bool success;
    270 SCIP_Bool valid;
    271
    272 assert(scip != NULL);
    273 assert(subscip != NULL);
    274 assert(heur != NULL);
    275 assert(result != NULL);
    276
    277 heurdata = SCIPheurGetData(heur);
    278 assert(heurdata != NULL);
    279
    280 /* get variable data */
    281 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
    282
    283 /* create the variable mapping hash map */
    284 SCIP_CALL( SCIPhashmapCreate(&varmapfw, SCIPblkmem(subscip), nvars) );
    285 SCIP_CALL( SCIPallocBufferArray(scip, &subvars, nvars) );
    286
    287 /* different methods to create sub-problem: either copy LP relaxation or the CIP with all constraints */
    288 valid = FALSE;
    289
    290 /* copy complete SCIP instance */
    291 SCIP_CALL( SCIPcopy(scip, subscip, varmapfw, NULL, "zeroobj", TRUE, FALSE, FALSE, TRUE, &valid) );
    292 SCIPdebugMsg(scip, "Copying the SCIP instance was %s complete.\n", valid ? "" : "not ");
    293
    294 /* create event handler for LP events */
    295 eventhdlr = NULL;
    296 SCIP_CALL( SCIPincludeEventhdlrBasic(subscip, &eventhdlr, EVENTHDLR_NAME, EVENTHDLR_DESC, eventExecZeroobj, NULL) );
    297 if( eventhdlr == NULL )
    298 {
    299 SCIPerrorMessage("event handler for " HEUR_NAME " heuristic not found.\n");
    300 return SCIP_PLUGINNOTFOUND;
    301 }
    302
    303 /* determine large value to set variables to */
    304 large = SCIPinfinity(scip);
    305 if( !SCIPisInfinity(scip, 0.1 / SCIPfeastol(scip)) )
    306 large = 0.1 / SCIPfeastol(scip);
    307
    308 /* get variable image and change to 0.0 in sub-SCIP */
    309 for( i = 0; i < nvars; i++ )
    310 {
    311 SCIP_Real adjustedbound;
    312 SCIP_Real lb;
    313 SCIP_Real ub;
    314 SCIP_Real inf;
    315
    316 subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, vars[i]);
    317 if( subvars[i] == NULL )
    318 continue;
    319
    320 SCIP_CALL( SCIPchgVarObj(subscip, subvars[i], 0.0) );
    321
    322 lb = SCIPvarGetLbGlobal(subvars[i]);
    323 ub = SCIPvarGetUbGlobal(subvars[i]);
    324 inf = SCIPinfinity(subscip);
    325
    326 /* adjust infinite bounds in order to avoid that variables with non-zero objective
    327 * get fixed to infinite value in zeroobj subproblem
    328 */
    329 if( SCIPisInfinity(subscip, ub ) )
    330 {
    331 adjustedbound = MAX(large, lb+large);
    332 adjustedbound = MIN(adjustedbound, inf);
    333 SCIP_CALL( SCIPchgVarUbGlobal(subscip, subvars[i], adjustedbound) );
    334 }
    335 if( SCIPisInfinity(subscip, -lb ) )
    336 {
    337 adjustedbound = MIN(-large, ub-large);
    338 adjustedbound = MAX(adjustedbound, -inf);
    339 SCIP_CALL( SCIPchgVarLbGlobal(subscip, subvars[i], adjustedbound) );
    340 }
    341 }
    342
    343 /* free hash map */
    344 SCIPhashmapFree(&varmapfw);
    345
    346 /* do not abort subproblem on CTRL-C */
    347 SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
    348
    349#ifdef SCIP_DEBUG
    350 /* for debugging, enable full output */
    351 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 5) );
    352 SCIP_CALL( SCIPsetIntParam(subscip, "display/freq", 100000000) );
    353#else
    354 /* disable statistic timing inside sub SCIP and output to console */
    355 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) );
    356 SCIP_CALL( SCIPsetBoolParam(subscip, "timing/statistictiming", FALSE) );
    357#endif
    358
    359 /* set limits for the subproblem */
    360 SCIP_CALL( SCIPcopyLimits(scip, subscip) );
    361 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", nnodes) );
    362 SCIP_CALL( SCIPsetIntParam(subscip, "limits/solutions", 1) );
    363
    364 /* forbid recursive call of heuristics and separators solving sub-SCIPs */
    365 SCIP_CALL( SCIPsetSubscipsOff(subscip, TRUE) );
    366
    367 /* disable expensive techniques that merely work on the dual bound */
    368
    369 /* disable cutting plane separation */
    371
    372 /* disable expensive presolving */
    374 if( !SCIPisParamFixed(subscip, "presolving/maxrounds") )
    375 {
    376 SCIP_CALL( SCIPsetIntParam(subscip, "presolving/maxrounds", 50) );
    377 }
    378
    379 /* use restart dfs node selection */
    380 if( SCIPfindNodesel(subscip, "restartdfs") != NULL && !SCIPisParamFixed(subscip, "nodeselection/restartdfs/stdpriority") )
    381 {
    382 SCIP_CALL( SCIPsetIntParam(subscip, "nodeselection/restartdfs/stdpriority", INT_MAX/4) );
    383 }
    384
    385 /* activate uct node selection at the top of the tree */
    386 if( heurdata->useuct && SCIPfindNodesel(subscip, "uct") != NULL && !SCIPisParamFixed(subscip, "nodeselection/uct/stdpriority") )
    387 {
    388 SCIP_CALL( SCIPsetIntParam(subscip, "nodeselection/uct/stdpriority", INT_MAX/2) );
    389 }
    390 /* use least infeasible branching */
    391 if( SCIPfindBranchrule(subscip, "leastinf") != NULL && !SCIPisParamFixed(subscip, "branching/leastinf/priority") )
    392 {
    393 SCIP_CALL( SCIPsetIntParam(subscip, "branching/leastinf/priority", INT_MAX/4) );
    394 }
    395
    396 /* disable feaspump and fracdiving */
    397 if( !SCIPisParamFixed(subscip, "heuristics/feaspump/freq") )
    398 {
    399 SCIP_CALL( SCIPsetIntParam(subscip, "heuristics/feaspump/freq", -1) );
    400 }
    401 if( !SCIPisParamFixed(subscip, "heuristics/fracdiving/freq") )
    402 {
    403 SCIP_CALL( SCIPsetIntParam(subscip, "heuristics/fracdiving/freq", -1) );
    404 }
    405
    406 /* speed up sub-SCIP by not checking dual LP feasibility */
    407 SCIP_CALL( SCIPsetBoolParam(subscip, "lp/checkdualfeas", FALSE) );
    408
    409 /* restrict LP iterations */
    410 SCIP_CALL( SCIPsetLongintParam(subscip, "lp/iterlim", 2*heurdata->maxlpiters / MAX(1,nnodes)) );
    411 SCIP_CALL( SCIPsetLongintParam(subscip, "lp/rootiterlim", heurdata->maxlpiters) );
    412
    413 /* if there is already a solution, add an objective cutoff */
    414 if( SCIPgetNSols(scip) > 0 )
    415 {
    416 SCIP_Real upperbound;
    417 SCIP_CONS* origobjcons;
    418#ifndef NDEBUG
    419 int nobjvars;
    420 nobjvars = 0;
    421#endif
    422
    424
    425 upperbound = SCIPgetUpperbound(scip) - SCIPsumepsilon(scip);
    426
    428 {
    429 cutoff = (1-minimprove)*SCIPgetUpperbound(scip) + minimprove*SCIPgetLowerbound(scip);
    430 }
    431 else
    432 {
    433 if( SCIPgetUpperbound(scip) >= 0 )
    434 cutoff = ( 1 - minimprove ) * SCIPgetUpperbound ( scip );
    435 else
    436 cutoff = ( 1 + minimprove ) * SCIPgetUpperbound ( scip );
    437 }
    438 cutoff = MIN(upperbound, cutoff);
    439
    440 SCIP_CALL( SCIPcreateConsLinear(subscip, &origobjcons, "objbound_of_origscip", 0, NULL, NULL, -SCIPinfinity(subscip), cutoff,
    442 for( i = 0; i < nvars; ++i)
    443 {
    444 if( !SCIPisFeasZero(subscip, SCIPvarGetObj(vars[i])) )
    445 {
    446 assert(subvars[i] != NULL); /* subvars[i] can be NULL for relax-only vars, but they cannot appear in the objective */
    447 SCIP_CALL( SCIPaddCoefLinear(subscip, origobjcons, subvars[i], SCIPvarGetObj(vars[i])) );
    448#ifndef NDEBUG
    449 nobjvars++;
    450#endif
    451 }
    452 }
    453 SCIP_CALL( SCIPaddCons(subscip, origobjcons) );
    454 SCIP_CALL( SCIPreleaseCons(subscip, &origobjcons) );
    455 assert(nobjvars == SCIPgetNObjVars(scip));
    456 }
    457
    458 /* catch LP events of sub-SCIP */
    459 SCIP_CALL( SCIPtransformProb(subscip) );
    460 SCIP_CALL( SCIPcatchEvent(subscip, SCIP_EVENTTYPE_NODESOLVED, eventhdlr, (SCIP_EVENTDATA*) heurdata, NULL) );
    461
    462 SCIPdebugMsg(scip, "solving subproblem: nnodes=%" SCIP_LONGINT_FORMAT "\n", nnodes);
    463
    464 /* errors in solving the subproblem should not kill the overall solving process;
    465 * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
    466 */
    467 SCIP_CALL_ABORT( SCIPsolve(subscip) );
    468
    469 /* drop LP events of sub-SCIP */
    470 SCIP_CALL( SCIPdropEvent(subscip, SCIP_EVENTTYPE_NODESOLVED, eventhdlr, (SCIP_EVENTDATA*) heurdata, -1) );
    471
    472 /* check, whether a solution was found;
    473 * due to numerics, it might happen that not all solutions are feasible -> try all solutions until one was accepted
    474 */
    475 nsubsols = SCIPgetNSols(subscip);
    476 subsols = SCIPgetSols(subscip);
    477 success = FALSE;
    478 for( i = 0; i < nsubsols && (!success || heurdata->addallsols); ++i )
    479 {
    480 SCIP_SOL* newsol;
    481
    482 SCIP_CALL( SCIPtranslateSubSol(scip, subscip, subsols[i], heur, subvars, &newsol) );
    483
    484 SCIP_CALL( SCIPtrySolFree(scip, &newsol, FALSE, FALSE, TRUE, TRUE, TRUE, &success) );
    485 if( success )
    486 *result = SCIP_FOUNDSOL;
    487 }
    488
    489#ifdef SCIP_DEBUG
    491#endif
    492
    493 /* free subproblem */
    494 SCIPfreeBufferArray(scip, &subvars);
    495
    496 return SCIP_OKAY;
    497}
    498
    499
    500/*
    501 * primal heuristic specific interface methods
    502 */
    503
    504
    505/** main procedure of the zeroobj heuristic, creates and solves a sub-SCIP */
    507 SCIP* scip, /**< original SCIP data structure */
    508 SCIP_HEUR* heur, /**< heuristic data structure */
    509 SCIP_RESULT* result, /**< result data structure */
    510 SCIP_Real minimprove, /**< factor by which zeroobj should at least improve the incumbent */
    511 SCIP_Longint nnodes /**< node limit for the subproblem */
    512 )
    513{
    514 SCIP* subscip; /* the subproblem created by zeroobj */
    515 SCIP_HEURDATA* heurdata; /* heuristic's private data structure */
    516 SCIP_Bool success;
    517 SCIP_RETCODE retcode;
    518
    519 assert(scip != NULL);
    520 assert(heur != NULL);
    521 assert(result != NULL);
    522
    523 assert(nnodes >= 0);
    524 assert(0.0 <= minimprove && minimprove <= 1.0);
    525
    526 *result = SCIP_DIDNOTRUN;
    527
    528 /* only call heuristic once at the root */
    529 if( SCIPgetDepth(scip) <= 0 && SCIPheurGetNCalls(heur) > 0 )
    530 return SCIP_OKAY;
    531
    532 /* get heuristic data */
    533 heurdata = SCIPheurGetData(heur);
    534 assert(heurdata != NULL);
    535
    536 /* only call the heuristic if we do not have an incumbent */
    537 if( SCIPgetNSolsFound(scip) > 0 && heurdata->onlywithoutsol )
    538 return SCIP_OKAY;
    539
    540 /* check whether there is enough time and memory left */
    541 SCIP_CALL( SCIPcheckCopyLimits(scip, &success) );
    542
    543 if( !success )
    544 return SCIP_OKAY;
    545
    546 *result = SCIP_DIDNOTFIND;
    547
    548 /* initialize the subproblem */
    549 SCIP_CALL( SCIPcreate(&subscip) );
    550
    551 retcode = setupAndSolveSubscip(scip, subscip, heur, result, minimprove, nnodes);
    552
    553 SCIP_CALL( SCIPfree(&subscip) );
    554
    555 return retcode;
    556}
    557
    558
    559/** creates the zeroobj primal heuristic and includes it in SCIP */
    561 SCIP* scip /**< SCIP data structure */
    562 )
    563{
    564 SCIP_HEURDATA* heurdata;
    565 SCIP_HEUR* heur;
    566
    567 /* create heuristic data */
    568 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
    569
    570 /* include primal heuristic */
    571 heur = NULL;
    574 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecZeroobj, heurdata) );
    575 assert(heur != NULL);
    576
    577 /* primal heuristic is safe to use in exact solving mode */
    578 SCIPheurMarkExact(heur);
    579
    580 /* set non-NULL pointers to callback methods */
    581 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyZeroobj) );
    582 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeZeroobj) );
    583 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitZeroobj) );
    584
    585 /* add zeroobj primal heuristic parameters */
    586 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxnodes",
    587 "maximum number of nodes to regard in the subproblem",
    588 &heurdata->maxnodes, TRUE,DEFAULT_MAXNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    589
    590 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/nodesofs",
    591 "number of nodes added to the contingent of the total nodes",
    592 &heurdata->nodesofs, FALSE, DEFAULT_NODESOFS, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    593
    594 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/minnodes",
    595 "minimum number of nodes required to start the subproblem",
    596 &heurdata->minnodes, TRUE, DEFAULT_MINNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    597
    598 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxlpiters",
    599 "maximum number of LP iterations to be performed in the subproblem",
    600 &heurdata->maxlpiters, TRUE, DEFAULT_MAXLPITERS, -1LL, SCIP_LONGINT_MAX, NULL, NULL) );
    601
    602 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/nodesquot",
    603 "contingent of sub problem nodes in relation to the number of nodes of the original problem",
    604 &heurdata->nodesquot, FALSE, DEFAULT_NODESQUOT, 0.0, 1.0, NULL, NULL) );
    605
    606 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minimprove",
    607 "factor by which zeroobj should at least improve the incumbent",
    608 &heurdata->minimprove, TRUE, DEFAULT_MINIMPROVE, 0.0, 1.0, NULL, NULL) );
    609
    610 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/addallsols",
    611 "should all subproblem solutions be added to the original SCIP?",
    612 &heurdata->addallsols, TRUE, DEFAULT_ADDALLSOLS, NULL, NULL) );
    613
    614 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/onlywithoutsol",
    615 "should heuristic only be executed if no primal solution was found, yet?",
    616 &heurdata->onlywithoutsol, TRUE, DEFAULT_ONLYWITHOUTSOL, NULL, NULL) );
    617 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/useuct",
    618 "should uct node selection be used at the beginning of the search?",
    619 &heurdata->useuct, TRUE, DEFAULT_USEUCT, NULL, NULL) );
    620
    621 return SCIP_OKAY;
    622}
    Constraint handler for linear constraints in their most general form, .
    #define NULL
    Definition: def.h:257
    #define SCIP_Longint
    Definition: def.h:150
    #define SCIP_Bool
    Definition: def.h:100
    #define MIN(x, y)
    Definition: def.h:233
    #define SCIP_STRINGEQ(name, reference, retcode)
    Definition: def.h:454
    #define SCIP_Real
    Definition: def.h:165
    #define TRUE
    Definition: def.h:102
    #define FALSE
    Definition: def.h:103
    #define MAX(x, y)
    Definition: def.h:229
    #define SCIP_CALL_ABORT(x)
    Definition: def.h:343
    #define SCIP_LONGINT_FORMAT
    Definition: def.h:157
    #define SCIP_LONGINT_MAX
    Definition: def.h:151
    #define SCIP_CALL(x)
    Definition: def.h:364
    #define nnodes
    Definition: gastrans.c:74
    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 SCIPcopy(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, const char *suffix, SCIP_Bool global, SCIP_Bool enablepricing, SCIP_Bool threadsafe, SCIP_Bool passmessagehdlr, SCIP_Bool *valid)
    Definition: scip_copy.c:2866
    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
    int SCIPgetNObjVars(SCIP *scip)
    Definition: scip_prob.c:2616
    SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
    Definition: scip_prob.c:2115
    SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3274
    void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
    Definition: misc.c:3095
    void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3284
    SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
    Definition: misc.c:3061
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    SCIP_RETCODE SCIPapplyZeroobj(SCIP *scip, SCIP_HEUR *heur, SCIP_RESULT *result, SCIP_Real minimprove, SCIP_Longint nnodes)
    Definition: heur_zeroobj.c:506
    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 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 SCIPincludeHeurZeroobj(SCIP *scip)
    Definition: heur_zeroobj.c:560
    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
    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_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
    Definition: scip_lp.c:174
    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
    SCIP_NODESEL * SCIPfindNodesel(SCIP *scip, const char *name)
    Definition: scip_nodesel.c:242
    int SCIPgetNSols(SCIP *scip)
    Definition: scip_sol.c:2887
    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 SCIPtransformProb(SCIP *scip)
    Definition: scip_solve.c:232
    SCIP_RETCODE SCIPinterruptSolve(SCIP *scip)
    Definition: scip_solve.c:3561
    SCIP_RETCODE SCIPsolve(SCIP *scip)
    Definition: scip_solve.c:2611
    SCIP_Longint SCIPgetNSolsFound(SCIP *scip)
    SCIP_Real SCIPgetUpperbound(SCIP *scip)
    SCIP_Longint SCIPgetNNodes(SCIP *scip)
    SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
    SCIP_Real SCIPgetLowerbound(SCIP *scip)
    SCIP_Longint SCIPgetNLPIterations(SCIP *scip)
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfeastol(SCIP *scip)
    SCIP_Real SCIPsumepsilon(SCIP *scip)
    int SCIPgetDepth(SCIP *scip)
    Definition: scip_tree.c:672
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23932
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24174
    SCIP_RETCODE SCIPchgVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_var.c:6141
    SCIP_RETCODE SCIPchgVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_var.c:6230
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24152
    SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
    Definition: scip_var.c:5372
    #define DEFAULT_ONLYWITHOUTSOL
    Definition: heur_zeroobj.c:83
    #define DEFAULT_NODESQUOT
    Definition: heur_zeroobj.c:81
    static SCIP_DECL_HEURFREE(heurFreeZeroobj)
    Definition: heur_zeroobj.c:158
    #define DEFAULT_NODESOFS
    Definition: heur_zeroobj.c:80
    #define DEFAULT_MAXNODES
    Definition: heur_zeroobj.c:76
    #define HEUR_TIMING
    Definition: heur_zeroobj.c:68
    #define DEFAULT_MINNODES
    Definition: heur_zeroobj.c:78
    #define HEUR_FREQOFS
    Definition: heur_zeroobj.c:66
    #define HEUR_DESC
    Definition: heur_zeroobj.c:62
    #define DEFAULT_ADDALLSOLS
    Definition: heur_zeroobj.c:82
    #define DEFAULT_USEUCT
    Definition: heur_zeroobj.c:84
    #define HEUR_DISPCHAR
    Definition: heur_zeroobj.c:63
    #define HEUR_MAXDEPTH
    Definition: heur_zeroobj.c:67
    #define HEUR_PRIORITY
    Definition: heur_zeroobj.c:64
    static SCIP_RETCODE setupAndSolveSubscip(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_RESULT *result, SCIP_Real minimprove, SCIP_Longint nnodes)
    Definition: heur_zeroobj.c:248
    static SCIP_DECL_HEURCOPY(heurCopyZeroobj)
    Definition: heur_zeroobj.c:143
    #define DEFAULT_MINIMPROVE
    Definition: heur_zeroobj.c:77
    #define HEUR_NAME
    Definition: heur_zeroobj.c:61
    static SCIP_DECL_HEURINIT(heurInitZeroobj)
    Definition: heur_zeroobj.c:179
    static SCIP_DECL_EVENTEXEC(eventExecZeroobj)
    Definition: heur_zeroobj.c:117
    #define EVENTHDLR_DESC
    Definition: heur_zeroobj.c:73
    #define HEUR_FREQ
    Definition: heur_zeroobj.c:65
    #define DEFAULT_MAXLPITERS
    Definition: heur_zeroobj.c:79
    #define HEUR_USESSUBSCIP
    Definition: heur_zeroobj.c:69
    #define EVENTHDLR_NAME
    Definition: heur_zeroobj.c:72
    static SCIP_DECL_HEUREXEC(heurExecZeroobj)
    Definition: heur_zeroobj.c:199
    heuristic that tries to solve the problem without objective. In Gurobi, this heuristic is known as "H...
    memory allocation routines
    public methods for managing events
    public methods for primal heuristics
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    public data structures and miscellaneous methods
    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 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 the branch-and-bound tree
    public methods for SCIP variables
    struct SCIP_EventData SCIP_EVENTDATA
    Definition: type_event.h:179
    #define SCIP_EVENTTYPE_NODESOLVED
    Definition: type_event.h:138
    struct SCIP_HeurData SCIP_HEURDATA
    Definition: type_heur.h:77
    @ SCIP_LPSOLSTAT_ITERLIMIT
    Definition: type_lp.h:48
    @ SCIP_PARAMSETTING_OFF
    Definition: type_paramset.h:63
    @ SCIP_PARAMSETTING_FAST
    Definition: type_paramset.h:62
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ 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
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63