SCIP

    Solving Constraint Integer Programs

    heur_indicator.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_indicator.c
    26 * @ingroup DEFPLUGINS_HEUR
    27 * @brief handle partial solutions for linear problems with indicators and otherwise continuous variables
    28 * @author Marc Pfetsch
    29 *
    30 * For linear problems with indicators and otherwise continuous variables, the indicator constraint handler can produce
    31 * partial solutions, i.e., values for the indicator variables. This partial solution can be passed to this heuristic,
    32 * which then fixes these values and solves an LP. Additionally a local search for a better solution is added.
    33 */
    34
    35/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    36
    38#include "scip/cons_indicator.h"
    39#include "scip/heur_indicator.h"
    40#include "scip/pub_cons.h"
    41#include "scip/pub_heur.h"
    42#include "scip/pub_message.h"
    43#include "scip/pub_sol.h"
    44#include "scip/pub_var.h"
    45#include "scip/scip_cons.h"
    46#include "scip/scip_copy.h"
    47#include "scip/scip_general.h"
    48#include "scip/scip_heur.h"
    49#include "scip/scip_lp.h"
    50#include "scip/scip_mem.h"
    51#include "scip/scip_message.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_tree.h"
    58
    59
    60#define HEUR_NAME "indicator"
    61#define HEUR_DESC "indicator heuristic to create feasible solutions from values for indicator variables"
    62#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_LNS
    63#define HEUR_PRIORITY -20200
    64#define HEUR_FREQ 1
    65#define HEUR_FREQOFS 0
    66#define HEUR_MAXDEPTH -1
    67#define HEUR_TIMING SCIP_HEURTIMING_DURINGLPLOOP
    68#define HEUR_USESSUBSCIP FALSE /**< does the heuristic use a secondary SCIP instance? */
    69
    70#define DEFAULT_ONEOPT FALSE /**< whether the one-opt heuristic should be started */
    71#define DEFAULT_IMPROVESOLS FALSE /**< Try to improve other solutions by one-opt? */
    72
    73
    74/** primal heuristic data */
    75struct SCIP_HeurData
    76{
    77 int nindconss; /**< number of indicator constraints */
    78 SCIP_CONS** indconss; /**< indicator constraints */
    79 SCIP_Bool* solcand; /**< bitset of indicator variables in solution candidate */
    80 SCIP_Real obj; /**< objective of previously stored solution */
    81 SCIP_Bool oneopt; /**< whether the one-opt heuristic should be started */
    82 SCIP_CONSHDLR* indicatorconshdlr; /**< indicator constraint handler */
    83 SCIP_SOL* lastsol; /**< last solution considered for improvement */
    84 SCIP_Bool improvesols; /**< Try to improve other solutions by one-opt? */
    85 SCIP_HEURTIMING inittiming; /**< initial heuristic timing */
    86};
    87
    88/*
    89 * Local methods
    90 */
    91
    92/** try one-opt on given solution */
    93static
    95 SCIP* scip, /**< SCIP data structure */
    96 SCIP_HEUR* heur, /**< indicator heuristic */
    97 SCIP_HEURDATA* heurdata, /**< heuristic data */
    98 int nindconss, /**< number of indicator constraints */
    99 SCIP_CONS** indconss, /**< indicator constraints */
    100 SCIP_Bool* solcand, /**< values for indicator variables in partial solution */
    101 int* nfoundsols /**< number of solutions found */
    102 )
    103{
    104 SCIP_Bool cutoff;
    105 SCIP_Bool lperror;
    106 SCIP_Bool stored;
    107 SCIP_SOL* sol;
    108 int cnt = 0;
    109 int i;
    110 int c;
    111
    112 assert( scip != NULL );
    113 assert( heur != NULL );
    114 assert( heurdata != NULL );
    115 assert( nindconss == 0 || indconss != NULL );
    116 assert( solcand != NULL );
    117 assert( nfoundsols != NULL );
    118
    119 SCIPdebugMsg(scip, "Performing one-opt ...\n");
    120 *nfoundsols = 0;
    121
    123
    124 for (i = 0; i < nindconss && ! SCIPisStopped(scip); ++i)
    125 {
    126 SCIP_VAR* binvar;
    127
    128 /* skip nonactive constraints */
    129 if ( ! SCIPconsIsActive(indconss[i]) )
    130 continue;
    131
    132 binvar = SCIPgetBinaryVarIndicator(indconss[i]);
    133 assert( binvar != NULL );
    134
    135 /* skip constraints with fixed variables */
    136 if ( SCIPvarGetUbLocal(binvar) < 0.5 || SCIPvarGetLbLocal(binvar) > 0.5 )
    137 continue;
    138
    139 /* return if the we would exceed the depth limit of the tree */
    141 break;
    142
    143 if ( solcand[i] )
    144 continue;
    145
    146 /* get rid of all bound changes */
    148 ++cnt;
    149
    150 /* fix variables */
    151 for (c = 0; c < nindconss; ++c)
    152 {
    153 SCIP_Bool s;
    154
    155 /* skip nonactive constraints */
    156 if ( ! SCIPconsIsActive(indconss[c]) )
    157 continue;
    158
    159 binvar = SCIPgetBinaryVarIndicator(indconss[c]);
    160 assert( binvar != NULL );
    161
    162 /* fix variables according to solution candidate, except constraint i */
    163 if ( c == i )
    164 s = ! solcand[c];
    165 else
    166 s = solcand[c];
    167
    168 if ( ! s )
    169 {
    170 if ( SCIPvarGetLbLocal(binvar) < 0.5 && SCIPvarGetUbLocal(binvar) > 0.5 )
    171 {
    172 SCIP_CALL( SCIPchgVarLbProbing(scip, binvar, 1.0) );
    173 }
    174 }
    175 else
    176 {
    177 if ( SCIPvarGetUbLocal(binvar) > 0.5 && SCIPvarGetLbLocal(binvar) < 0.5 )
    178 {
    179 SCIP_CALL( SCIPchgVarUbProbing(scip, binvar, 0.0) );
    180 }
    181 }
    182 }
    183
    184 /* propagate variables */
    185 SCIP_CALL( SCIPpropagateProbing(scip, -1, &cutoff, NULL) );
    186 if ( cutoff )
    187 {
    189 continue;
    190 }
    191
    192 /* solve LP to move continuous variables */
    193 SCIP_CALL( SCIPsolveProbingLP(scip, -1, &lperror, &cutoff) );
    194
    195 /* the LP often reaches the objective limit - we currently do not use such solutions */
    196 if ( lperror || cutoff || SCIPgetLPSolstat(scip) != SCIP_LPSOLSTAT_OPTIMAL )
    197 {
    198#ifdef SCIP_DEBUG
    199 if ( lperror )
    200 SCIPdebugMsg(scip, "An LP error occurred.\n");
    201#endif
    203 continue;
    204 }
    205
    206 /* create solution */
    207 SCIP_CALL( SCIPcreateSol(scip, &sol, heur) );
    208
    209 /* copy the current LP solution to the working solution */
    211
    212 /* check solution for feasibility */
    213 SCIPdebugMsg(scip, "One-opt found solution candidate with value %g.\n", SCIPgetSolTransObj(scip, sol));
    214
    215 /* only check integrality, because we solved an LP */
    216 SCIP_CALL( SCIPtrySolFree(scip, &sol, FALSE, FALSE, FALSE, TRUE, FALSE, &stored) );
    217 if ( stored )
    218 ++(*nfoundsols);
    220 }
    222
    223 SCIPdebugMsg(scip, "Finished one-opt (tried variables: %d, found sols: %d).\n", cnt, *nfoundsols);
    224
    225 return SCIP_OKAY;
    226}
    227
    228
    229/** try given solution */
    230static
    232 SCIP* scip, /**< SCIP data structure */
    233 SCIP_HEUR* heur, /**< indicator heuristic */
    234 SCIP_HEURDATA* heurdata, /**< heuristic data */
    235 int nindconss, /**< number of indicator constraints */
    236 SCIP_CONS** indconss, /**< indicator constraints */
    237 SCIP_Bool* solcand, /**< values for indicator variables in partial solution */
    238 int* nfoundsols /**< number of solutions found */
    239 )
    240{
    241 SCIP_Bool cutoff;
    242 SCIP_Bool lperror;
    243 SCIP_Bool stored;
    244 SCIP_SOL* sol;
    245 int c;
    246
    247 assert( scip != NULL );
    248 assert( heur != NULL );
    249 assert( heurdata != NULL );
    250 assert( nindconss == 0 || indconss != NULL );
    251 assert( solcand != NULL );
    252 assert( nfoundsols != NULL );
    253
    254 SCIPdebugMsg(scip, "Trying to generate feasible solution with indicators from solution candidate (obj: %f) ...\n", heurdata->obj);
    255 *nfoundsols = 0;
    256
    258
    259 /* we can stop here if we have already reached the maximal depth */
    261 {
    263 return SCIP_OKAY;
    264 }
    265
    267
    268 /* fix variables */
    269 for (c = 0; c < nindconss; ++c)
    270 {
    271 SCIP_VAR* binvar;
    272
    273 /* skip nonactive constraints */
    274 if ( ! SCIPconsIsActive(indconss[c]) )
    275 continue;
    276
    277 binvar = SCIPgetBinaryVarIndicator(indconss[c]);
    278 assert( binvar != NULL );
    279
    280 /* Fix binary variables not in cover to 1 and corresponding slack variables to 0. The other binary variables are fixed to 0. */
    281 if ( ! solcand[c] )
    282 {
    283 /* to be sure, check for non-fixed variables */
    284 if ( SCIPvarGetLbLocal(binvar) < 0.5 && SCIPvarGetUbLocal(binvar) > 0.5 )
    285 {
    286 SCIP_CALL( SCIPchgVarLbProbing(scip, binvar, 1.0) );
    287 }
    288 }
    289 else
    290 {
    291 if ( SCIPvarGetUbLocal(binvar) > 0.5 && SCIPvarGetLbLocal(binvar) < 0.5 )
    292 {
    293 SCIP_CALL( SCIPchgVarUbProbing(scip, binvar, 0.0) );
    294 }
    295 }
    296 }
    297
    298 /* propagate variables */
    299 SCIP_CALL( SCIPpropagateProbing(scip, -1, &cutoff, NULL) );
    300 if ( cutoff )
    301 {
    302 SCIPdebugMsg(scip, "Solution candidate reaches cutoff (in propagation).\n");
    304 return SCIP_OKAY;
    305 }
    306
    307 /* solve LP to move continuous variables */
    308 SCIP_CALL( SCIPsolveProbingLP(scip, -1, &lperror, &cutoff) );
    309
    310 /* the LP often reaches the objective limit - we currently do not use such solutions */
    311 if ( lperror || cutoff || SCIPgetLPSolstat(scip) != SCIP_LPSOLSTAT_OPTIMAL )
    312 {
    313#ifdef SCIP_DEBUG
    314 if ( lperror )
    315 {
    316 SCIPdebugMsg(scip, "An LP error occurred.\n");
    317 }
    318 else
    319 {
    320 SCIPdebugMsg(scip, "Solution candidate reaches cutoff (in LP solving).\n");
    321 }
    322#endif
    324 return SCIP_OKAY;
    325 }
    326
    327 /* create solution */
    328 SCIP_CALL( SCIPcreateSol(scip, &sol, heur) );
    329
    330 /* copy the current LP solution to the working solution */
    332
    333 /* check solution for feasibility */
    334#ifdef SCIP_DEBUG
    335 SCIPdebugMsg(scip, "Found solution candidate with value %g.\n", SCIPgetSolTransObj(scip, sol));
    336#ifdef SCIP_MORE_DEBUG
    338#endif
    339 SCIP_CALL( SCIPtrySolFree(scip, &sol, TRUE, TRUE, TRUE, TRUE, TRUE, &stored) );
    340 if ( stored )
    341 {
    342 ++(*nfoundsols);
    343 SCIPdebugMsg(scip, "Solution is feasible and stored.\n");
    344 }
    345 else
    346 SCIPdebugMsg(scip, "Solution was not stored.\n");
    347#else
    348 /* only check integrality, because we solved an LP */
    349 SCIP_CALL( SCIPtrySolFree(scip, &sol, FALSE, FALSE, FALSE, TRUE, FALSE, &stored) );
    350 if ( stored )
    351 ++(*nfoundsols);
    352#endif
    354
    355 /* possibly perform one-opt */
    356 if ( stored && heurdata->oneopt )
    357 {
    358 int nfound = 0;
    359 assert( *nfoundsols > 0 );
    360 SCIP_CALL( tryOneOpt(scip, heur, heurdata, nindconss, indconss, solcand, &nfound) );
    361 }
    362
    363 return SCIP_OKAY;
    364}
    365
    366
    367/*
    368 * Callback methods of primal heuristic
    369 */
    370
    371/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
    372static
    373SCIP_DECL_HEURCOPY(heurCopyIndicator)
    374{ /*lint --e{715}*/
    375 assert( scip != NULL );
    376 assert( heur != NULL );
    377
    379
    380 /* call inclusion method of primal heuristic */
    382
    383 return SCIP_OKAY;
    384}
    385
    386/** solving process initialization method of primal heuristic (called when branch and bound process is about to begin) */
    387static
    388SCIP_DECL_HEURINITSOL(heurInitsolIndicator)
    389{ /*lint --e{715}*/
    390 SCIP_HEURDATA* heurdata;
    391
    392 assert( scip != NULL );
    393
    395
    396 /* get heuristic data */
    397 heurdata = SCIPheurGetData(heur);
    398 assert( heurdata != NULL );
    399
    400 /* find indicator handler */
    401 heurdata->indicatorconshdlr = SCIPfindConshdlr(scip, "indicator");
    402
    403 /* store indicator timing */
    404 heurdata->inittiming = SCIPheurGetTimingmask(heur);
    405
    406 /* disable indicator heuristic, enabled when indicators are passed */
    407 if ( heurdata->indicatorconshdlr == NULL || SCIPconshdlrGetNConss(heurdata->indicatorconshdlr) == 0 || SCIPgetSubscipDepth(scip) > 0 )
    409
    410 return SCIP_OKAY;
    411}
    412
    413/** solving process deinitialization method of primal heuristic (called before branch and bound process data is freed) */
    414static
    415SCIP_DECL_HEUREXITSOL(heurExitsolIndicator)
    416{ /*lint --e{715}*/
    417 SCIP_HEURDATA* heurdata;
    418
    419 assert( scip != NULL );
    420
    422
    423 /* get heuristic data */
    424 heurdata = SCIPheurGetData(heur);
    425 assert( heurdata != NULL );
    426
    427 /* reset indicator timing */
    428 SCIPheurSetTimingmask(heur, heurdata->inittiming);
    429
    430 return SCIP_OKAY;
    431}
    432
    433/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
    434static
    435SCIP_DECL_HEURFREE(heurFreeIndicator)
    436{ /*lint --e{715}*/
    437 SCIP_HEURDATA* heurdata;
    438
    439 assert( heur != NULL );
    440 assert( scip != NULL );
    441
    442 /* get heuristic data */
    443 heurdata = SCIPheurGetData(heur);
    444 assert( heurdata != NULL );
    445
    446 SCIPfreeBlockMemoryArrayNull(scip, &(heurdata->indconss), heurdata->nindconss);
    447 SCIPfreeBlockMemoryArrayNull(scip, &(heurdata->solcand), heurdata->nindconss);
    448
    449 /* free heuristic data */
    450 SCIPfreeBlockMemory(scip, &heurdata);
    451 SCIPheurSetData(heur, NULL);
    452
    453 return SCIP_OKAY;
    454}
    455
    456
    457/** execution method of primal heuristic */
    458static
    459SCIP_DECL_HEUREXEC(heurExecIndicator)
    460{ /*lint --e{715}*/
    461 SCIP_HEURDATA* heurdata;
    462 int nindconss;
    463 int nfoundsols;
    464
    465 assert( scip != NULL );
    466 assert( heur != NULL );
    467 assert( result != NULL );
    468
    469 *result = SCIP_DIDNOTRUN;
    470
    471 /* get heuristic's data */
    472 heurdata = SCIPheurGetData(heur);
    473 assert( heurdata != NULL );
    474 assert( heurdata->indicatorconshdlr != NULL );
    475 nindconss = heurdata->solcand == NULL ? SCIPconshdlrGetNConss(heurdata->indicatorconshdlr) : heurdata->nindconss;
    476
    477 /* the heuristic will only be successful if there are indicator constraints, no binary variables except for the
    478 * indicator variables, and no integral variables */
    479 if ( nindconss == 0
    482 return SCIP_OKAY;
    483
    484 /* call heuristic if solution candidate is available */
    485 if ( heurdata->solcand != NULL )
    486 {
    487 assert( heurdata->indconss != NULL );
    488
    489 SCIP_CALL( trySolCandidate(scip, heur, heurdata, nindconss, heurdata->indconss, heurdata->solcand, &nfoundsols) );
    490
    491 if ( nfoundsols > 0 )
    492 *result = SCIP_FOUNDSOL;
    493 else
    494 *result = SCIP_DIDNOTFIND;
    495
    496 /* free memory */
    497 SCIPfreeBlockMemoryArray(scip, &(heurdata->solcand), nindconss);
    498 SCIPfreeBlockMemoryArray(scip, &(heurdata->indconss), nindconss);
    499 }
    500
    501 /* try to improve solutions generated by other heuristics */
    502 if ( heurdata->improvesols )
    503 {
    504 SCIP_CONS** indconss;
    505 SCIP_Bool* solcand;
    506 SCIP_SOL* bestsol;
    507 int i;
    508
    509 /* check whether a new best solution has been found */
    510 bestsol = SCIPgetBestSol(scip);
    511 if ( bestsol == heurdata->lastsol )
    512 return SCIP_OKAY;
    513 heurdata->lastsol = bestsol;
    514
    515 /* avoid solutions produced by this heuristic */
    516 if ( SCIPsolGetHeur(bestsol) == heur )
    517 return SCIP_OKAY;
    518
    519 indconss = SCIPconshdlrGetConss(heurdata->indicatorconshdlr);
    520 assert( indconss != NULL );
    521
    522 /* fill solution candidate */
    523 SCIP_CALL( SCIPallocBufferArray(scip, &solcand, nindconss) );
    524 for (i = 0; i < nindconss; ++i)
    525 {
    526 SCIP_VAR* binvar;
    527 SCIP_Real val;
    528
    529 solcand[i] = FALSE;
    530 if ( SCIPconsIsActive(indconss[i]) )
    531 {
    532 binvar = SCIPgetBinaryVarIndicator(indconss[i]);
    533 assert( binvar != NULL );
    534
    535 val = SCIPgetSolVal(scip, bestsol, binvar);
    536 assert( SCIPisFeasIntegral(scip, val) );
    537 if ( val > 0.5 )
    538 solcand[i] = TRUE;
    539 }
    540 }
    541
    542 SCIPdebugMsg(scip, "Trying to improve best solution of value %f.\n", SCIPgetSolOrigObj(scip, bestsol) );
    543
    544 /* try one-opt heuristic */
    545 SCIP_CALL( tryOneOpt(scip, heur, heurdata, nindconss, indconss, solcand, &nfoundsols) );
    546
    547 if ( nfoundsols > 0 )
    548 *result = SCIP_FOUNDSOL;
    549 else
    550 *result = SCIP_DIDNOTFIND;
    551
    552 SCIPfreeBufferArray(scip, &solcand);
    553 }
    554
    555 return SCIP_OKAY;
    556}
    557
    558
    559/*
    560 * primal heuristic specific interface methods
    561 */
    562
    563/** creates the indicator primal heuristic and includes it in SCIP */
    565 SCIP* scip /**< SCIP data structure */
    566 )
    567{
    568 SCIP_HEURDATA* heurdata;
    569 SCIP_HEUR* heur;
    570
    571 /* create Indicator primal heuristic data */
    572 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
    573 heurdata->nindconss = 0;
    574 heurdata->indconss = NULL;
    575 heurdata->solcand = NULL;
    576 heurdata->lastsol = NULL;
    577 heurdata->indicatorconshdlr = NULL;
    578 heurdata->obj = SCIPinfinity(scip);
    579 heurdata->inittiming = HEUR_TIMING;
    580
    581 /* include primal heuristic */
    584 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecIndicator, heurdata) );
    585
    586 assert( heur != NULL );
    587
    588 /* primal heuristic is safe to use in exact solving mode */
    589 SCIPheurMarkExact(heur);
    590
    591 /* set non-NULL pointers to callback methods */
    592 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyIndicator) );
    593 SCIP_CALL( SCIPsetHeurInitsol(scip, heur, heurInitsolIndicator) );
    594 SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolIndicator) );
    595 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeIndicator) );
    596
    597 /* add parameters */
    599 "heuristics/" HEUR_NAME "/oneopt",
    600 "whether the one-opt heuristic should be started",
    601 &heurdata->oneopt, TRUE, DEFAULT_ONEOPT, NULL, NULL) );
    602
    604 "heuristics/" HEUR_NAME "/improvesols",
    605 "Try to improve other solutions by one-opt?",
    606 &heurdata->improvesols, TRUE, DEFAULT_IMPROVESOLS, NULL, NULL) );
    607
    608 return SCIP_OKAY;
    609}
    610
    611
    612/** pass partial solution for indicator variables to heuristic */
    614 SCIP* scip, /**< SCIP data structure */
    615 SCIP_HEUR* heur, /**< indicator heuristic */
    616 int nindconss, /**< number of indicator constraints */
    617 SCIP_CONS** indconss, /**< indicator constraints */
    618 SCIP_Bool* solcand, /**< values for indicator variables in partial solution */
    619 SCIP_Real obj /**< objective of solution */
    620 )
    621{
    622 SCIP_HEURDATA* heurdata;
    623
    624 assert( scip != NULL );
    625 assert( heur != NULL );
    626 assert( nindconss > 0 );
    627 assert( indconss != NULL );
    628 assert( solcand != NULL );
    629
    631
    632 /* get heuristic's data */
    633 heurdata = SCIPheurGetData(heur);
    634 assert( heurdata != NULL );
    635
    636 if ( obj >= heurdata->obj )
    637 return SCIP_OKAY;
    638
    639 /* copy indicator information */
    640 if ( heurdata->indconss != NULL )
    641 SCIPfreeBlockMemoryArray(scip, &(heurdata->indconss), heurdata->nindconss);
    642
    643 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(heurdata->indconss), indconss, nindconss) );
    644 heurdata->nindconss = nindconss;
    645
    646 /* copy partial solution */
    647 if ( heurdata->solcand != NULL )
    648 BMScopyMemoryArray(heurdata->solcand, solcand, nindconss);
    649 else
    650 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(heurdata->solcand), solcand, nindconss) );
    651 heurdata->obj = obj;
    652
    653 /* enable indicator heuristic */
    654 SCIPheurSetTimingmask(heur, heurdata->inittiming);
    655
    656 return SCIP_OKAY;
    657}
    constraint handler for indicator constraints
    #define NULL
    Definition: def.h:257
    #define SCIP_MAXTREEDEPTH
    Definition: def.h:306
    #define SCIP_Bool
    Definition: def.h:100
    #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 SCIP_CALL(x)
    Definition: def.h:364
    SCIP_VAR * SCIPgetBinaryVarIndicator(SCIP_CONS *cons)
    int SCIPgetSubscipDepth(SCIP *scip)
    Definition: scip_copy.c:2589
    SCIP_Bool SCIPisStopped(SCIP *scip)
    Definition: scip_general.c:767
    int SCIPgetNIntVars(SCIP *scip)
    Definition: scip_prob.c:2340
    int SCIPgetNBinImplVars(SCIP *scip)
    Definition: scip_prob.c:2432
    int SCIPgetNIntImplVars(SCIP *scip)
    Definition: scip_prob.c:2477
    int SCIPgetNBinVars(SCIP *scip)
    Definition: scip_prob.c:2293
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    SCIP_RETCODE SCIPheurPassIndicator(SCIP *scip, SCIP_HEUR *heur, int nindconss, SCIP_CONS **indconss, SCIP_Bool *solcand, SCIP_Real obj)
    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 SCIPincludeHeurIndicator(SCIP *scip)
    int SCIPconshdlrGetNConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4782
    SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
    Definition: scip_cons.c:940
    SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4739
    SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
    Definition: cons.c:8454
    SCIP_RETCODE SCIPsetHeurExitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXITSOL((*heurexitsol)))
    Definition: scip_heur.c:247
    SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
    Definition: scip_heur.c:167
    SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
    Definition: heur.c:1368
    SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
    Definition: scip_heur.c:122
    SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
    Definition: scip_heur.c:183
    SCIP_HEURTIMING SCIPheurGetTimingmask(SCIP_HEUR *heur)
    Definition: heur.c:1497
    void SCIPheurSetTimingmask(SCIP_HEUR *heur, SCIP_HEURTIMING timingmask)
    Definition: heur.c:1507
    SCIP_RETCODE SCIPsetHeurInitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINITSOL((*heurinitsol)))
    Definition: scip_heur.c:231
    void SCIPheurMarkExact(SCIP_HEUR *heur)
    Definition: heur.c:1457
    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
    #define SCIPfreeBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:110
    #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 SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
    Definition: scip_mem.h:111
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    #define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
    Definition: scip_mem.h:105
    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 SCIPsolveProbingLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
    Definition: scip_probing.c:825
    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_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
    Definition: scip_sol.c:2351
    SCIP_HEUR * SCIPsolGetHeur(SCIP_SOL *sol)
    Definition: sol.c:4274
    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 SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1293
    SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1890
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1763
    SCIP_Real SCIPgetSolTransObj(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:2003
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
    int SCIPgetDepth(SCIP *scip)
    Definition: scip_tree.c:672
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24300
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24266
    static SCIP_RETCODE tryOneOpt(SCIP *scip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, int nindconss, SCIP_CONS **indconss, SCIP_Bool *solcand, int *nfoundsols)
    static SCIP_DECL_HEURINITSOL(heurInitsolIndicator)
    #define DEFAULT_ONEOPT
    #define HEUR_TIMING
    static SCIP_DECL_HEURFREE(heurFreeIndicator)
    #define HEUR_FREQOFS
    #define HEUR_DESC
    static SCIP_DECL_HEUREXITSOL(heurExitsolIndicator)
    static SCIP_RETCODE trySolCandidate(SCIP *scip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, int nindconss, SCIP_CONS **indconss, SCIP_Bool *solcand, int *nfoundsols)
    static SCIP_DECL_HEUREXEC(heurExecIndicator)
    #define HEUR_DISPCHAR
    #define HEUR_MAXDEPTH
    #define HEUR_PRIORITY
    #define HEUR_NAME
    #define HEUR_FREQ
    #define HEUR_USESSUBSCIP
    static SCIP_DECL_HEURCOPY(heurCopyIndicator)
    #define DEFAULT_IMPROVESOLS
    handle partial solutions for linear problems with indicators and otherwise continuous variables
    memory allocation routines
    #define BMScopyMemoryArray(ptr, source, num)
    Definition: memory.h:134
    public methods for managing constraints
    public methods for primal heuristics
    public methods for message output
    public methods for primal CIP solutions
    public methods for problem variables
    public methods for constraint handler plugins and constraints
    public methods for problem copies
    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 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 methods for the branch-and-bound tree
    struct SCIP_HeurData SCIP_HEURDATA
    Definition: type_heur.h:77
    @ SCIP_LPSOLSTAT_OPTIMAL
    Definition: type_lp.h:44
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_FOUNDSOL
    Definition: type_result.h:56
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    unsigned int SCIP_HEURTIMING
    Definition: type_timing.h:103
    #define SCIP_HEURTIMING_NONE
    Definition: type_timing.h:79