SCIP

    Solving Constraint Integer Programs

    heur_locks.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_locks.c
    26 * @ingroup DEFPLUGINS_HEUR
    27 * @brief rounding locks primal heuristic
    28 * @author Michael Winkler
    29 * @author Gerald Gamrath
    30 */
    31
    32/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    33
    35#include "scip/heur_locks.h"
    36#include "scip/pub_cons.h"
    37#include "scip/pub_heur.h"
    38#include "scip/pub_lp.h"
    39#include "scip/pub_message.h"
    40#include "scip/pub_misc.h"
    41#include "scip/pub_var.h"
    42#include "scip/scip_branch.h"
    44#include "scip/scip_cons.h"
    45#include "scip/scip_copy.h"
    46#include "scip/scip_exact.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"
    57#include "scip/scip_sol.h"
    58#include "scip/scip_solve.h"
    60#include "scip/scip_timing.h"
    61#include "scip/scip_tree.h"
    62
    63
    64#define HEUR_NAME "locks"
    65#define HEUR_DESC "heuristic that fixes variables based on their rounding locks"
    66#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_PROP
    67#define HEUR_PRIORITY 3000
    68#define HEUR_FREQ 0
    69#define HEUR_FREQOFS 0
    70#define HEUR_MAXDEPTH -1
    71#define HEUR_TIMING SCIP_HEURTIMING_BEFORENODE
    72#define HEUR_USESSUBSCIP TRUE /**< does the heuristic use a secondary SCIP instance? */
    73
    74#define DEFAULT_MAXNODES 5000LL /**< maximum number of nodes to regard in the subproblem */
    75#define DEFAULT_ROUNDUPPROBABILITY 0.67 /**< probability for rounding a variable up in case of ties */
    76#define DEFAULT_MINFIXINGRATE 0.65 /**< minimum percentage of variables that have to be fixed */
    77#define DEFAULT_MINIMPROVE 0.01 /**< factor by which locks heuristic should at least improve the
    78 * incumbent */
    79#define DEFAULT_MINNODES 500LL /**< minimum number of nodes to regard in the subproblem */
    80#define DEFAULT_NODESOFS 500LL /**< 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_MAXPROPROUNDS 2 /**< maximum number of propagation rounds during probing */
    83#define DEFAULT_UPDATELOCKS TRUE /**< should the locks be updated based on LP rows? */
    84#define DEFAULT_COPYCUTS TRUE /**< should all active cuts from the cutpool of the
    85 * original scip be copied to constraints of the subscip? */
    86#define DEFAULT_USEFINALSUBMIP TRUE /**< should a final sub-MIP be solved to construct a feasible
    87 * solution if the LP was not roundable? */
    88#define DEFAULT_RANDSEED 73 /**< initial random seed */
    89#define DEFAULT_MINFIXINGRATELP 0.0 /**< minimum fixing rate over all variables (including continuous)
    90 * to solve LP */
    91
    92/** primal heuristic data */
    93struct SCIP_HeurData
    94{
    95 SCIP_RANDNUMGEN* randnumgen; /**< random number generation */
    96 SCIP_Longint maxnodes; /**< maximum number of nodes to regard in the subproblem */
    97 SCIP_Longint minnodes; /**< minimum number of nodes to regard in the subproblem */
    98 SCIP_Longint nodesofs; /**< number of nodes added to the contingent of the total nodes */
    99 SCIP_Longint usednodes; /**< nodes already used by locks heuristic in earlier calls */
    100 SCIP_Real roundupprobability; /**< probability for rounding a variable up in case of ties */
    101 SCIP_Real minfixingrate; /**< minimum percentage of variables that have to be fixed */
    102 SCIP_Real minfixingratelp; /**< minimum fixing rate over all variables (including continuous) to solve LP */
    103 SCIP_Real minimprove; /**< factor by which locks heuristic should at least improve the incumbent */
    104 SCIP_Real nodesquot; /**< subproblem nodes in relation to nodes of the original problem */
    105 int maxproprounds; /**< maximum number of propagation rounds during probing */
    106 SCIP_Bool updatelocks; /**< should the locks be updated based on LP rows? */
    107 SCIP_Bool copycuts; /**< should all active cuts from cutpool be copied to constraints in
    108 * the subproblem? */
    109 SCIP_Bool usefinalsubmip; /**< should a final sub-MIP be solved to construct a feasible solution if
    110 * the LP was not roundable? */
    111};
    112
    113/*
    114 * Local methods
    115 */
    116
    117/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
    118static
    119SCIP_DECL_HEURCOPY(heurCopyLocks)
    120{ /*lint --e{715}*/
    121 assert(scip != NULL);
    122 assert(heur != NULL);
    123
    125
    126 /* call inclusion method of primal heuristic */
    128
    129 return SCIP_OKAY;
    130}
    131
    132/** free method for primal heuristic plugins (called when SCIP is exiting) */
    133static
    134SCIP_DECL_HEURFREE(heurFreeLocks)
    135{ /*lint --e{715}*/
    136 SCIP_HEURDATA* heurdata;
    137
    138 assert(scip != NULL);
    139 assert(heur != NULL);
    140
    142
    143 heurdata = SCIPheurGetData(heur);
    144
    145 /* free primal heuristic data */
    146 SCIPfreeBlockMemory(scip, &heurdata);
    147
    148 return SCIP_OKAY;
    149}
    150
    151/** initialization method of primal heuristic (called after problem was transformed) */
    152static
    153SCIP_DECL_HEURINIT(heurInitLocks) /*lint --e{715}*/
    154{ /*lint --e{715}*/
    155 SCIP_HEURDATA* heurdata;
    156
    158
    159 heurdata = SCIPheurGetData(heur);
    160 assert(heurdata != NULL);
    161
    162 /* initialize data */
    163 heurdata->usednodes = 0;
    164
    165 /* create random number generator */
    166 SCIP_CALL( SCIPcreateRandom(scip, &heurdata->randnumgen,
    168
    169 return SCIP_OKAY;
    170}
    171
    172/** deinitialization method of primal heuristic (called before transformed problem is freed) */
    173static
    174SCIP_DECL_HEUREXIT(heurExitLocks) /*lint --e{715}*/
    175{ /*lint --e{715}*/
    176 SCIP_HEURDATA* heurdata;
    177
    179
    180 /* free heuristic data */
    181 heurdata = SCIPheurGetData(heur);
    182 assert(heurdata != NULL);
    183
    184 /* free random number generator */
    185 SCIPfreeRandom(scip, &heurdata->randnumgen);
    186
    187 return SCIP_OKAY;
    188}
    189
    190/** apply fix-and-propagate scheme based on variable locks
    191 *
    192 * @note probing mode of SCIP needs to be enabled before
    193 */
    195 SCIP* scip, /**< SCIP data structure */
    196 SCIP_HEURDATA* heurdata, /**< primal heuristic data */
    197 SCIP_Bool* cutoff, /**< pointer to store if a cutoff was detected */
    198 SCIP_Bool* allrowsfulfilled /**< pointer to store if all rows became redundant */
    199 )
    200{
    201 SCIP_ROW** lprows;
    202 SCIP_VAR** vars;
    203 SCIP_VAR** sortvars;
    204 SCIP_Real* minact;
    205 SCIP_Real* maxact;
    206 SCIP_Bool* fulfilled;
    207 SCIP_VAR* var;
    208 SCIP_ROW* row;
    209 SCIP_COL* col;
    210 SCIP_ROW** colrows;
    211 SCIP_Real* colvals;
    212 int ncolrows;
    213 int* ndownlocks;
    214 int* nuplocks;
    215 int* varpos = NULL;
    216 SCIP_Real lastfixval;
    217 SCIP_Real randnumber;
    218 SCIP_Real roundupprobability;
    219 SCIP_Bool propagate;
    220 SCIP_Bool propagated;
    221 SCIP_Bool haslhs;
    222 SCIP_Bool hasrhs;
    223 SCIP_Bool updatelocks;
    224 int lastfixlocks;
    225 int maxproprounds;
    226 int nglbfulfilledrows;
    227 int rowpos;
    228 int nbinvars;
    229 int nvars;
    230 int nlprows;
    231 int nfulfilledrows;
    232 int bestpos;
    233 int lastbestscore;
    234 int bestscore;
    235 int score;
    236 int v;
    237 int r;
    238 int i;
    239
    240 assert(scip != NULL);
    241 assert(cutoff != NULL);
    242 assert(allrowsfulfilled != NULL);
    243 assert(SCIPinProbing(scip));
    244
    245 if( heurdata == NULL )
    246 {
    248 heurdata = SCIPheurGetData(heur);
    249 }
    250 assert(heurdata != NULL);
    251
    252 *cutoff = FALSE;
    253 *allrowsfulfilled = FALSE;
    254
    255 propagate = (heurdata->maxproprounds != 0);
    256
    257 if( heurdata->maxproprounds == -2 )
    258 maxproprounds = 0;
    259 else
    260 maxproprounds = heurdata->maxproprounds;
    261
    262 roundupprobability = heurdata->roundupprobability;
    263
    264 updatelocks = heurdata->updatelocks && (SCIPgetNCheckConss(scip) == SCIPgetNLPRows(scip));
    265
    266 SCIPdebugMsg(scip, "%d constraints: %d logicor, updatelocks=%u\n", SCIPgetNConss(scip), SCIPconshdlrGetNCheckConss(SCIPfindConshdlr(scip, "logicor")), updatelocks);
    267
    268 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, &nbinvars, NULL, NULL, NULL) );
    269 assert(vars != NULL);
    270
    271 /* allocate memory */
    272 SCIP_CALL( SCIPduplicateBufferArray(scip, &sortvars, vars, nbinvars) );
    273 SCIP_CALL( SCIPallocBufferArray(scip, &nuplocks, nbinvars) );
    274 SCIP_CALL( SCIPallocBufferArray(scip, &ndownlocks, nbinvars) );
    275
    276 /* get LP data */
    277 SCIP_CALL( SCIPgetLPRowsData(scip, &lprows, &nlprows) );
    278 SCIP_CALL( SCIPallocBufferArray(scip, &minact, nlprows) );
    279 SCIP_CALL( SCIPallocBufferArray(scip, &maxact, nlprows) );
    280 SCIP_CALL( SCIPallocClearBufferArray(scip, &fulfilled, nlprows) );
    281
    282 /* @todo add objective value as second sorting criteria */
    283
    284 nglbfulfilledrows = 0;
    285
    286 /* get locks of variables */
    287 for( v = 0; v < nbinvars; ++v )
    288 {
    289 var = sortvars[v];
    291 ndownlocks[v] = SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL);
    292 }
    293
    294 /* get activities of rows */
    295 for( r = 0; r < nlprows; ++r )
    296 {
    297 row = lprows[r];
    298 assert(SCIProwGetLPPos(row) == r);
    299
    300 /* no trivial rows */
    302
    303 minact[r] = SCIPgetRowMinActivity(scip, row);
    304 maxact[r] = SCIPgetRowMaxActivity(scip, row);
    305 }
    306
    307 propagated = TRUE;
    308 lastbestscore = INT_MAX;
    309
    310 /* fix variables */
    311 for( v = 0; v < nbinvars; v++ )
    312 {
    313 if( SCIPisStopped(scip) )
    314 break;
    315
    316 assert(!(*cutoff));
    317
    318 nfulfilledrows = 0;
    319
    320 while( v < nbinvars && (SCIPvarGetLbLocal(sortvars[v]) > 0.5 || SCIPvarGetUbLocal(sortvars[v]) < 0.5) )
    321 {
    322 ++v;
    323 }
    324 if( v == nbinvars )
    325 break;
    326
    327 bestpos = v;
    328 bestscore = nuplocks[v] + ndownlocks[v];
    329
    330 /* get best variable */
    331 if( bestscore < lastbestscore )
    332 {
    333 for( i = v + 1; i < nbinvars; ++i )
    334 {
    335 var = sortvars[i];
    336
    337 /* variable is already fixed; move it to the front and increment v to ignore it */
    338 if( SCIPvarGetLbLocal(var) > 0.5 || SCIPvarGetUbLocal(var) < 0.5 )
    339 {
    340 int locks;
    341
    342 sortvars[i] = sortvars[v];
    343 sortvars[v] = var;
    344
    345 locks = nuplocks[i];
    346 nuplocks[i] = nuplocks[v];
    347 nuplocks[v] = locks;
    348
    349 locks = ndownlocks[i];
    350 ndownlocks[i] = ndownlocks[v];
    351 ndownlocks[v] = locks;
    352
    353 if( varpos != NULL )
    354 {
    355 varpos[SCIPvarGetProbindex(sortvars[i])] = i;
    356 varpos[SCIPvarGetProbindex(sortvars[v])] = v;
    357 }
    358
    359 if( bestpos == v )
    360 bestpos = i;
    361
    362 ++v;
    363
    364 continue;
    365 }
    366
    367 score = nuplocks[i] + ndownlocks[i];
    368 assert(score <= lastbestscore);
    369
    370 if( score > bestscore )
    371 {
    372 bestscore = score;
    373 bestpos = i;
    374
    375 if( bestscore == lastbestscore )
    376 break;
    377 }
    378 }
    379 if( v == nbinvars )
    380 break;
    381 }
    382 lastbestscore = bestscore;
    383
    384 /* move best variable to the front (at position v) */
    385 if( bestpos != v )
    386 {
    387 int locks;
    388
    389 var = sortvars[bestpos];
    390 sortvars[bestpos] = sortvars[v];
    391 sortvars[v] = var;
    392
    393 locks = nuplocks[bestpos];
    394 nuplocks[bestpos] = nuplocks[v];
    395 nuplocks[v] = locks;
    396
    397 locks = ndownlocks[bestpos];
    398 ndownlocks[bestpos] = ndownlocks[v];
    399 ndownlocks[v] = locks;
    400
    401 if( varpos != NULL )
    402 {
    403 varpos[SCIPvarGetProbindex(sortvars[bestpos])] = bestpos;
    404 varpos[SCIPvarGetProbindex(sortvars[v])] = v;
    405 }
    406 }
    407
    408 var = sortvars[v];
    409
    410 /* all remaining variables are fixed, we can break the fix-and-propagate loop */
    411 if( SCIPvarGetLbLocal(var) > 0.5 || SCIPvarGetUbLocal(var) < 0.5 )
    412 {
    413 assert(v == nbinvars);
    414
    415 break;
    416 }
    417
    418 /* stop if we reached the depth limit */
    420 break;
    421
    422 if( propagated )
    423 {
    425 propagated = FALSE;
    426 }
    427
    428 /* set variables to the bound with fewer locks, if tie choose an average value */
    429 if( ndownlocks[v] > nuplocks[v] )
    430 lastfixval = 1.0;
    431 else if( ndownlocks[v] < nuplocks[v] )
    432 lastfixval = 0.0;
    433 else
    434 {
    435 /* prefer one-fixing if objective value is not positive */
    436 if( !SCIPisPositive(scip, SCIPvarGetObj(var)) )
    437 lastfixval = 1.0;
    438 else
    439 {
    440 randnumber = SCIPrandomGetReal(heurdata->randnumgen, 0.0, 1.0);
    441
    442 /* if a tie occurs, we randomly round the variable based on the parameter 'roundupprobability' */
    443 if( randnumber < roundupprobability )
    444 lastfixval = 1.0;
    445 else
    446 lastfixval = 0.0;
    447 }
    448 }
    449
    450 lastfixlocks = lastfixval > 0.5 ? nuplocks[v] : ndownlocks[v];
    451
    452 SCIP_CALL( SCIPfixVarProbing(scip, var, lastfixval) );
    453
    454 SCIPdebugMsg(scip, "iteration %d: fixing variable <%s> to %d with locks (%d, %d)\n", v, SCIPvarGetName(var), lastfixval > 0.5 ? 1 : 0, ndownlocks[v], nuplocks[v]);
    455
    456 if( propagate && lastfixlocks > 0 )
    457 {
    458 /* apply propagation */
    459 SCIP_CALL( SCIPpropagateProbing(scip, maxproprounds, cutoff, NULL) );
    460 propagated = TRUE;
    461
    462 if( *cutoff )
    463 {
    464 SCIPdebugMsg(scip, "last fixing led to infeasibility trying other bound\n");
    465
    466 /* fix cutoff variable in other direction */
    468 *cutoff = FALSE;
    469
    470 if( lastfixval < 0.5 )
    471 {
    472 lastfixval = 1.0;
    473
    474 if( SCIPvarGetUbLocal(var) > 0.5 )
    475 {
    476 SCIP_CALL( SCIPfixVarProbing(scip, var, 1.0) );
    477 }
    478 /* because of the limited number of propagation rounds, it may happen that conflict analysis finds a
    479 * valid global fixing for the last fixed variable that conflicts with applying the reverse fixing
    480 * after backtracking; in that case, we ran into a deadend and stop
    481 */
    482 else
    483 *cutoff = TRUE;
    484 }
    485 else
    486 {
    487 lastfixval = 0.0;
    488
    489 if( SCIPvarGetLbLocal(var) < 0.5 )
    490 {
    491 SCIP_CALL( SCIPfixVarProbing(scip, var, 0.0) );
    492 }
    493 /* because of the limited number of propagation rounds, it may happen that conflict analysis finds a
    494 * valid global fixing for the last fixed variable that conflicts with applying the reverse fixing
    495 * after backtracking; in that case, we ran into a deadend and stop
    496 */
    497 else
    498 *cutoff = TRUE;
    499 }
    500
    501 if( !(*cutoff) )
    502 {
    503 SCIP_CALL( SCIPpropagateProbing(scip, maxproprounds, cutoff, NULL) );
    504 }
    505 if( *cutoff )
    506 {
    507 SCIPdebugMsg(scip, "probing was infeasible\n");
    508
    509 break;
    510 }
    511 }
    512 /* @todo collect propagated bounds and use them to update row activities as well */
    513 }
    514
    515 if( updatelocks )
    516 {
    518 continue;
    519
    520 col = SCIPvarGetCol(var);
    521 assert(col != NULL);
    522
    523 colrows = SCIPcolGetRows(col);
    524 colvals = SCIPcolGetVals(col);
    525 ncolrows = SCIPcolGetNNonz(col);
    526
    527 /* update activities */
    528 for( r = 0; r < ncolrows; ++r )
    529 {
    530 row = colrows[r];
    531 rowpos = SCIProwGetLPPos(row);
    532
    533 /* the row is not in the LP */
    534 if( rowpos == -1 )
    535 continue;
    536
    537 assert(lprows[rowpos] == row);
    538
    539 /* we disregard cuts */
    540 if( SCIProwGetRank(row) > 0 )
    541 continue;
    542
    543 /* the row is already fulfilled */
    544 if( fulfilled[rowpos] )
    545 continue;
    546
    547 haslhs = !SCIPisInfinity(scip, -SCIProwGetLhs(row));
    548 hasrhs = !SCIPisInfinity(scip, SCIProwGetRhs(row));
    549
    550 /* no trivial rows */
    551 assert(hasrhs || haslhs);
    552
    553 if( ((colvals[r] > 0) == (lastfixval < 0.5)) )
    554 {
    555 maxact[rowpos] -= REALABS(colvals[r]);
    556 }
    557 if( ((colvals[r] > 0) == (lastfixval > 0.5)) )
    558 {
    559 minact[rowpos] += REALABS(colvals[r]);
    560 }
    561
    562 /* check if the row cannot be violated anymore */
    563 if( (!haslhs || SCIPisFeasGE(scip, minact[rowpos], SCIProwGetLhs(row)))
    564 && (!hasrhs || SCIPisFeasLE(scip, maxact[rowpos], SCIProwGetRhs(row))) )
    565 {
    566 SCIP_COL** cols;
    567 SCIP_VAR* colvar;
    568 SCIP_Real* vals;
    569 int ncols;
    570 int pos;
    571 int w;
    572
    573 SCIPdebugMsg(scip, "Row <%s> has activity [%g, %g], lhs=%g, rhs=%g\n", SCIProwGetName(row), minact[rowpos], maxact[rowpos], SCIProwGetLhs(row), SCIProwGetRhs(row));
    575
    576 if( varpos == NULL )
    577 {
    578 SCIP_CALL( SCIPallocBufferArray(scip, &varpos, nbinvars) );
    579
    580 for( pos = 0; pos < nbinvars; ++pos )
    581 varpos[SCIPvarGetProbindex(sortvars[pos])] = pos;
    582 }
    583
    584 ++nfulfilledrows;
    585 fulfilled[rowpos] = TRUE;
    586 cols = SCIProwGetCols(row);
    587 vals = SCIProwGetVals(row);
    588 ncols = SCIProwGetNNonz(row);
    589
    590 /* we assume that all rows are locking the variables */
    591 for( w = ncols - 1; w >= 0; --w )
    592 {
    593 colvar = SCIPcolGetVar(cols[w]);
    594 if( SCIPvarGetType(colvar) == SCIP_VARTYPE_BINARY && !SCIPvarIsImpliedIntegral(colvar) && colvar != var )
    595 {
    596 assert(sortvars[varpos[SCIPvarGetProbindex(colvar)]] == colvar);
    597 pos = varpos[SCIPvarGetProbindex(colvar)];
    598
    599 if( haslhs )
    600 {
    601 if( vals[w] > 0.0 )
    602 --(ndownlocks[pos]);
    603 else
    604 --(nuplocks[pos]);
    605 }
    606 if( hasrhs )
    607 {
    608 if( vals[w] > 0.0 )
    609 --(nuplocks[pos]);
    610 else
    611 --(ndownlocks[pos]);
    612 }
    613 }
    614 }
    615
    616 continue;
    617 }
    618 else if( SCIPisFeasLT(scip, maxact[rowpos], SCIProwGetLhs(row)) || SCIPisFeasGT(scip, minact[rowpos], SCIProwGetRhs(row)) )
    619 {
    620 *cutoff = TRUE;
    621 break;
    622 }
    623 }
    624
    625 if( *cutoff )
    626 {
    627 SCIPdebugMsg(scip, "found infeasible row, stopping heur\n");
    628 break;
    629 }
    630
    631 nglbfulfilledrows += nfulfilledrows;
    632 SCIPdebugMsg(scip, "last fixing led to %d fulfilled rows, now %d of %d rows are fulfilled\n", nfulfilledrows, nglbfulfilledrows, nlprows);
    633
    634 if( nglbfulfilledrows == nlprows )
    635 {
    636 *allrowsfulfilled = TRUE;
    637 break;
    638 }
    639 }
    640 } /*lint --e{850}*/
    641
    643 SCIPfreeBufferArray(scip, &fulfilled);
    644 SCIPfreeBufferArray(scip, &maxact);
    645 SCIPfreeBufferArray(scip, &minact);
    646 SCIPfreeBufferArray(scip, &ndownlocks);
    647 SCIPfreeBufferArray(scip, &nuplocks);
    648 SCIPfreeBufferArray(scip, &sortvars);
    649
    650 return SCIP_OKAY;
    651}
    652
    653
    654
    655
    656/** execution method of primal heuristic */
    657static
    658SCIP_DECL_HEUREXEC(heurExecLocks)
    659{ /*lint --e{715}*/
    660 SCIP_HEURDATA* heurdata;
    661 SCIP_VAR** vars;
    663 SCIP_Real lowerbound;
    664 SCIP_Bool cutoff;
    665 SCIP_Bool lperror;
    666 SCIP_Bool allrowsfulfilled = FALSE;
    667#ifdef NOCONFLICT
    668 SCIP_Bool enabledconflicts;
    669#endif
    670 int oldnpscands;
    671 int npscands;
    672
    673 int nvars;
    674 int i;
    675
    676 *result = SCIP_DIDNOTRUN;
    677
    678 /* only run once */
    679 if( SCIPgetNRuns(scip) > 1 )
    680 return SCIP_OKAY;
    681
    682 if( SCIPgetNBinVars(scip) == 0 )
    683 return SCIP_OKAY;
    684
    685 /* only run if we are allowed to solve an LP at the current node in the tree */
    687 return SCIP_OKAY;
    688
    690 {
    691 SCIP_CALL( SCIPconstructLP(scip, &cutoff) );
    692
    693 /* manually cut off the node if the LP construction detected infeasibility (heuristics cannot return such a
    694 * result); the cutoff result is safe to use in exact solving mode, but we don't have enough information to
    695 * give a certificate for the cutoff
    696 */
    697 if( cutoff && !SCIPisCertified(scip) )
    698 {
    700 return SCIP_OKAY;
    701 }
    702
    704
    705 /* we need an LP */
    706 if( SCIPgetNLPRows(scip) == 0 )
    707 return SCIP_OKAY;
    708 }
    709
    710 *result = SCIP_DIDNOTFIND;
    711
    712 heurdata = SCIPheurGetData(heur);
    713 assert(heurdata != NULL);
    714
    715#ifdef NOCONFLICT
    716 /* disable conflict analysis */
    717 SCIP_CALL( SCIPgetBoolParam(scip, "conflict/enable", &enabledconflicts) );
    718
    719 if( !SCIPisParamFixed(scip, "conflict/enable") )
    720 {
    721 SCIP_CALL( SCIPsetBoolParam(scip, "conflict/enable", FALSE) );
    722 }
    723#endif
    724
    725 lowerbound = SCIPgetLowerbound(scip);
    726 oldnpscands = SCIPgetNPseudoBranchCands(scip);
    727
    728 /* start probing mode */
    730
    731#ifdef COLLECTSTATISTICS
    733#endif
    734
    735 cutoff = FALSE;
    736 lperror = FALSE;
    737
    738 SCIP_CALL( SCIPapplyLockFixings(scip, heurdata, &cutoff, &allrowsfulfilled) );
    739
    740 if( cutoff || SCIPisStopped(scip) )
    741 goto TERMINATE;
    742
    743 /* check that we had enough fixings */
    745
    746 SCIPdebugMsg(scip, "npscands=%d, oldnpscands=%d, allrowsfulfilled=%u heurdata->minfixingrate=%g\n",
    747 npscands, oldnpscands, allrowsfulfilled, heurdata->minfixingrate);
    748
    749 if( !allrowsfulfilled && npscands > oldnpscands * (1 - heurdata->minfixingrate) )
    750 {
    751 SCIPdebugMsg(scip, "--> too few fixings\n");
    752
    753 goto TERMINATE;
    754 }
    755 else
    756 {
    757 char strbuf[SCIP_MAXSTRLEN];
    758 int ncols;
    759
    760 if( SCIPgetNContVars(scip) > 0 )
    761 {
    762 int nminfixings;
    763 int nfixedvars = 0;
    764
    765 nvars = SCIPgetNVars(scip);
    766 vars = SCIPgetVars(scip);
    767 nminfixings = (int)(SCIPceil(scip, heurdata->minfixingratelp * nvars));
    768
    769 /* count fixed variables */
    770 for( i = 0; i < nvars && nfixedvars < nminfixings; ++i )
    771 {
    772 if( SCIPisEQ(scip, SCIPvarGetLbLocal(vars[i]), SCIPvarGetUbLocal(vars[i])) )
    773 ++nfixedvars;
    774 }
    775
    776 SCIPdebugMsg(scip, "Fixed %d of %d (%.1f %%) variables after probing -> %s\n",
    777 nfixedvars, nvars, (100.0 * nfixedvars / (SCIP_Real)nvars),
    778 nfixedvars >= nminfixings ? "continue and solve LP for remaining variables" : "terminate without LP");
    779
    780 if( nfixedvars < nminfixings )
    781 goto TERMINATE;
    782 }
    783
    784 /* print message if relatively large LP is solved from scratch, since this could lead to a longer period during
    785 * which the user sees no output; more detailed probing stats only in debug mode */
    786 ncols = SCIPgetNLPCols(scip);
    787 if( !SCIPisLPSolBasic(scip) && ncols > 1000 )
    788 {
    789 int nunfixedcols = SCIPgetNUnfixedLPCols(scip);
    790
    791 if( nunfixedcols > 0.5 * ncols )
    792 {
    794 "Heuristic " HEUR_NAME " solving LP from scratch with %.1f %% unfixed columns (%d of %d) ...\n",
    795 100.0 * (nunfixedcols / (SCIP_Real)ncols), nunfixedcols, ncols);
    796 }
    797 }
    798 SCIPdebugMsg(scip, "Heuristic " HEUR_NAME " probing LP: %s\n",
    800
    801 /* solve LP;
    802 * errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
    803 * hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
    804 */
    805 SCIPdebugMsg(scip, "starting solving locks-lp at time %g\n", SCIPgetSolvingTime(scip));
    806#ifdef NDEBUG
    807 {
    808 SCIP_Bool retstat;
    809 retstat = SCIPsolveProbingLP(scip, -1, &lperror, &cutoff);
    810 if( retstat != SCIP_OKAY )
    811 {
    812 SCIPwarningMessage(scip, "Error while solving LP in LOCKS heuristic; LP solve terminated with code <%d>\n",
    813 retstat);
    814 }
    815 }
    816#else
    817 SCIP_CALL( SCIPsolveProbingLP(scip, -1, &lperror, &cutoff) );
    818#endif
    819 SCIPdebugMsg(scip, "ending solving locks-lp at time %g\n", SCIPgetSolvingTime(scip));
    820
    821 lpstatus = SCIPgetLPSolstat(scip);
    822
    823 SCIPdebugMsg(scip, " -> new LP iterations: %" SCIP_LONGINT_FORMAT "\n", SCIPgetNLPIterations(scip));
    824 SCIPdebugMsg(scip, " -> error=%u, status=%d\n", lperror, SCIPgetLPSolstat(scip));
    825
    826 /* check if this is a feasible solution */
    827 if( !lperror && lpstatus == SCIP_LPSOLSTAT_OPTIMAL )
    828 {
    829 SCIP_SOL* sol;
    830 SCIP_Bool success;
    831
    832 lowerbound = SCIPgetLPObjval(scip);
    833
    834 /* create a copy of the current LP solution */
    835 SCIP_CALL( SCIPcreateSol(scip, &sol, heur) );
    837
    838 SCIP_CALL( SCIProundSol(scip, sol, &success) );
    839
    840 if( success )
    841 {
    842 SCIP_Bool stored;
    843
    844 /* check solution for feasibility, and add it to solution store if possible.
    845 * Neither integrality nor feasibility of LP rows have to be checked, because they
    846 * are guaranteed by the heuristic at this stage.
    847 */
    848 SCIP_CALL( SCIPtrySol(scip, sol, FALSE, FALSE, FALSE, FALSE, FALSE, &stored) );
    849
    850 if( stored )
    851 {
    852#ifdef SCIP_MORE_DEBUG
    853 SCIP_Bool feasible;
    854 SCIP_CALL( SCIPcheckSol(scip, sol, TRUE, TRUE, TRUE, TRUE, TRUE, &feasible) );
    855 assert(feasible);
    856#endif
    857
    858 SCIPdebugMsg(scip, "found feasible solution:\n");
    860 *result = SCIP_FOUNDSOL;
    861 }
    862
    863 SCIP_CALL( SCIPfreeSol(scip, &sol) );
    864
    865 /* we found a solution, so we are done */
    866 goto TERMINATE;
    867 }
    868
    869 SCIP_CALL( SCIPfreeSol(scip, &sol) );
    870 }
    871 }
    872
    873 if( heurdata->usefinalsubmip && !cutoff && !lperror && lpstatus != SCIP_LPSOLSTAT_INFEASIBLE && lpstatus != SCIP_LPSOLSTAT_OBJLIMIT )
    874 {
    875 SCIP* subscip;
    876 SCIP_VAR** subvars;
    877 SCIP_HASHMAP* varmap;
    878 SCIP_Longint nstallnodes;
    879 SCIP_Bool valid;
    880
    881 /* calculate the maximal number of branching nodes until heuristic is aborted */
    882 nstallnodes = (SCIP_Longint)(heurdata->nodesquot * SCIPgetNNodes(scip));
    883
    884 /* reward locks heuristic if it succeeded often */
    885 nstallnodes = (SCIP_Longint)(nstallnodes * 3.0 * (SCIPheurGetNBestSolsFound(heur)+1.0)/(SCIPheurGetNCalls(heur) + 1.0));
    886 nstallnodes -= 100 * SCIPheurGetNCalls(heur); /* count the setup costs for the sub-MIP as 100 nodes */
    887 nstallnodes += heurdata->nodesofs;
    888
    889 /* determine the node limit for the current process */
    890 nstallnodes -= heurdata->usednodes;
    891 nstallnodes = MIN(nstallnodes, heurdata->maxnodes);
    892
    893 /* check whether we have enough nodes left to call subproblem solving */
    894 if( nstallnodes < heurdata->minnodes )
    895 {
    896 SCIPdebugMsg(scip, "skipping " HEUR_NAME ": nstallnodes=%" SCIP_LONGINT_FORMAT ", minnodes=%" SCIP_LONGINT_FORMAT "\n", nstallnodes, heurdata->minnodes);
    897 goto TERMINATE;
    898 }
    899
    900 /* check whether there is enough time and memory left */
    902
    903 if( !valid )
    904 goto TERMINATE;
    905
    906 /* get all variables */
    907 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
    908
    909 /* create subproblem */
    910 SCIP_CALL( SCIPcreate(&subscip) );
    911
    912 /* allocate temporary memory for subscip variables */
    913 SCIP_CALL( SCIPallocBufferArray(scip, &subvars, nvars) );
    914
    915 /* create the variable mapping hash map */
    916 SCIP_CALL( SCIPhashmapCreate(&varmap, SCIPblkmem(subscip), nvars) );
    917
    918 SCIP_CALL( SCIPcopy(scip, subscip, varmap, NULL, "_locks", FALSE, FALSE, FALSE, TRUE, &valid) );
    919
    920 if( heurdata->copycuts )
    921 {
    922 /* copies all active cuts from cutpool of sourcescip to linear constraints in targetscip */
    923 SCIP_CALL( SCIPcopyCuts(scip, subscip, varmap, NULL, FALSE, NULL) );
    924 }
    925
    926 for( i = 0; i < nvars; i++ )
    927 subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmap, vars[i]);
    928
    929 /* free hash map */
    930 SCIPhashmapFree(&varmap);
    931
    932 /* do not abort subproblem on CTRL-C */
    933 SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
    934
    935#ifdef SCIP_DEBUG
    936 /* for debugging, enable full output */
    937 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 5) );
    938 SCIP_CALL( SCIPsetIntParam(subscip, "display/freq", 100000000) );
    939#else
    940 /* disable statistic timing inside sub SCIP and output to console */
    941 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) );
    942 SCIP_CALL( SCIPsetBoolParam(subscip, "timing/statistictiming", FALSE) );
    943#endif
    944
    945 /* set limits for the subproblem */
    946 SCIP_CALL( SCIPcopyLimits(scip, subscip) );
    947 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/stallnodes", nstallnodes) );
    948 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", heurdata->maxnodes) );
    949
    950 /* forbid call of heuristics and separators solving sub-CIPs */
    951 SCIP_CALL( SCIPsetSubscipsOff(subscip, TRUE) );
    952
    953 /* disable cutting plane separation */
    955
    956 /* disable expensive presolving */
    958
    959 /* use inference branching */
    960 if( SCIPfindBranchrule(subscip, "inference") != NULL && !SCIPisParamFixed(subscip, "branching/inference/priority") )
    961 {
    962 SCIP_CALL( SCIPsetIntParam(subscip, "branching/inference/priority", INT_MAX/4) );
    963 }
    964
    965 /* speed up sub-SCIP by not checking dual LP feasibility */
    966 SCIP_CALL( SCIPsetBoolParam(subscip, "lp/checkdualfeas", FALSE) );
    967
    968 /* if there is already a solution, add an objective cutoff */
    969 if( SCIPgetNSols(scip) > 0 )
    970 {
    971 SCIP_Real upperbound;
    972 SCIP_Real minimprove;
    973 SCIP_Real cutoffbound;
    974
    975 minimprove = heurdata->minimprove;
    977
    978 upperbound = SCIPgetUpperbound(scip) - SCIPsumepsilon(scip);
    979
    980 if( !SCIPisInfinity(scip, -1.0 * lowerbound) )
    981 {
    982 cutoffbound = (1-minimprove) * SCIPgetUpperbound(scip) + minimprove * lowerbound;
    983 }
    984 else
    985 {
    986 if( SCIPgetUpperbound ( scip ) >= 0 )
    987 cutoffbound = (1 - minimprove) * SCIPgetUpperbound(scip);
    988 else
    989 cutoffbound = (1 + minimprove) * SCIPgetUpperbound(scip);
    990 }
    991 cutoffbound = MIN(upperbound, cutoffbound);
    992 SCIP_CALL( SCIPsetObjlimit(subscip, cutoffbound) );
    993 SCIPdebugMsg(scip, "setting objlimit for subscip to %g\n", cutoffbound);
    994 }
    995
    996 SCIPdebugMsg(scip, "starting solving locks-submip at time %g\n", SCIPgetSolvingTime(scip));
    997
    998 /* solve the subproblem */
    999 /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
    1000 * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
    1001 */
    1002#ifdef NDEBUG
    1003 {
    1004 SCIP_RETCODE retstat;
    1005 retstat = SCIPpresolve(subscip);
    1006 if( retstat != SCIP_OKAY )
    1007 {
    1008 SCIPwarningMessage(scip, "Error while presolving subMIP in locks heuristic; sub-SCIP terminated with code <%d>\n", retstat);
    1009
    1010 goto FREESCIPANDTERMINATE;
    1011 }
    1012 }
    1013#else
    1014 SCIP_CALL_ABORT( SCIPpresolve(subscip) );
    1015#endif
    1016
    1017 SCIPdebugMsg(scip, "locks heuristic presolved subproblem at time %g : %d vars, %d cons; fixing value = %g\n", SCIPgetSolvingTime(scip), SCIPgetNVars(subscip), SCIPgetNConss(subscip), ((nvars - SCIPgetNVars(subscip)) / (SCIP_Real)nvars));
    1018
    1019 /* after presolving, we should have at least reached a certain fixing rate over ALL variables (including continuous)
    1020 * to ensure that not only the MIP but also the LP relaxation is easy enough
    1021 */
    1022 if( ((nvars - SCIPgetNVars(subscip)) / (SCIP_Real)nvars) >= heurdata->minfixingrate )
    1023 {
    1024 SCIP_Bool success;
    1025
    1026 SCIPdebugMsg(scip, "solving subproblem: nstallnodes=%" SCIP_LONGINT_FORMAT ", maxnodes=%" SCIP_LONGINT_FORMAT "\n", nstallnodes, heurdata->maxnodes);
    1027
    1028#ifdef NDEBUG
    1029 {
    1030 SCIP_RETCODE retstat;
    1031 retstat = SCIPsolve(subscip);
    1032 if( retstat != SCIP_OKAY )
    1033 {
    1034 SCIPwarningMessage(scip, "Error while solving subMIP in locks heuristic; sub-SCIP terminated with code <%d>\n",retstat);
    1035
    1036 goto FREESCIPANDTERMINATE;
    1037 }
    1038 }
    1039#else
    1040 SCIP_CALL_ABORT( SCIPsolve(subscip) );
    1041#endif
    1042 SCIPdebugMsg(scip, "ending solving locks-submip at time %g, status = %d\n", SCIPgetSolvingTime(scip), SCIPgetStatus(subscip));
    1043
    1044 /* check, whether a solution was found; due to numerics, it might happen that not all solutions are feasible ->
    1045 * try all solutions until one was accepted
    1046 */
    1047 SCIP_CALL( SCIPtranslateSubSols(scip, subscip, heur, subvars, &success, NULL) );
    1048 if( success )
    1049 *result = SCIP_FOUNDSOL;
    1050 }
    1051
    1052#ifdef SCIP_DEBUG
    1053 SCIP_CALL( SCIPprintStatistics(subscip, NULL) );
    1054#endif
    1055
    1056 heurdata->usednodes += SCIPgetNNodes(subscip);
    1057#ifdef NDEBUG
    1058 FREESCIPANDTERMINATE:
    1059#endif
    1060 /* free subproblem */
    1061 SCIPfreeBufferArray(scip, &subvars);
    1062 SCIP_CALL( SCIPfree(&subscip) );
    1063 }
    1064
    1065 TERMINATE:
    1066 /* exit probing mode */
    1068
    1069#ifdef NOCONFLICT
    1070 /* reset the conflict analysis */
    1071 if( !SCIPisParamFixed(scip, "conflict/enable") )
    1072 {
    1073 SCIP_CALL( SCIPsetBoolParam(scip, "conflict/enable", enabledconflicts) );
    1074 }
    1075#endif
    1076
    1077 return SCIP_OKAY;
    1078}
    1079
    1080
    1081/*
    1082 * primal heuristic specific interface methods
    1083 */
    1084
    1085/** creates the locks primal heuristic and includes it in SCIP */
    1087 SCIP* scip /**< SCIP data structure */
    1088 )
    1089{
    1090 SCIP_HEURDATA* heurdata;
    1091 SCIP_HEUR* heur;
    1092
    1093 /* create primal heuristic data */
    1094 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
    1095
    1096 /* include primal heuristic */
    1099 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecLocks, heurdata) );
    1100
    1101 assert(heur != NULL);
    1102
    1103 /* primal heuristic is safe to use in exact solving mode */
    1104 SCIPheurMarkExact(heur);
    1105
    1106 /* set non-NULL pointers to callback methods */
    1107 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyLocks) );
    1108 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeLocks) );
    1109 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitLocks) );
    1110 SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitLocks) );
    1111
    1112 /* add locks primal heuristic parameters */
    1113 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxproprounds",
    1114 "maximum number of propagation rounds to be performed in each propagation call (-1: no limit, -2: parameter settings)",
    1115 &heurdata->maxproprounds, TRUE, DEFAULT_MAXPROPROUNDS, -2, INT_MAX, NULL, NULL) );
    1116
    1117 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minfixingrate",
    1118 "minimum percentage of integer variables that have to be fixable",
    1119 &heurdata->minfixingrate, FALSE, DEFAULT_MINFIXINGRATE, 0.0, 1.0, NULL, NULL) );
    1120
    1121 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/roundupprobability",
    1122 "probability for rounding a variable up in case of ties",
    1123 &heurdata->roundupprobability, FALSE, DEFAULT_ROUNDUPPROBABILITY, 0.0, 1.0, NULL, NULL) );
    1124
    1125 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/usefinalsubmip",
    1126 "should a final sub-MIP be solved to costruct a feasible solution if the LP was not roundable?",
    1127 &heurdata->usefinalsubmip, TRUE, DEFAULT_USEFINALSUBMIP, NULL, NULL) );
    1128
    1129 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxnodes",
    1130 "maximum number of nodes to regard in the subproblem",
    1131 &heurdata->maxnodes, TRUE, DEFAULT_MAXNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    1132
    1133 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/nodesofs",
    1134 "number of nodes added to the contingent of the total nodes",
    1135 &heurdata->nodesofs, FALSE, DEFAULT_NODESOFS, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    1136
    1137 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/minnodes",
    1138 "minimum number of nodes required to start the subproblem",
    1139 &heurdata->minnodes, TRUE, DEFAULT_MINNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    1140
    1141 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/nodesquot",
    1142 "contingent of sub problem nodes in relation to the number of nodes of the original problem",
    1143 &heurdata->nodesquot, FALSE, DEFAULT_NODESQUOT, 0.0, 1.0, NULL, NULL) );
    1144
    1145 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minimprove",
    1146 "factor by which " HEUR_NAME " heuristic should at least improve the incumbent",
    1147 &heurdata->minimprove, TRUE, DEFAULT_MINIMPROVE, 0.0, 1.0, NULL, NULL) );
    1148
    1149 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/copycuts",
    1150 "should all active cuts from cutpool be copied to constraints in subproblem?",
    1151 &heurdata->copycuts, TRUE, DEFAULT_COPYCUTS, NULL, NULL) );
    1152
    1153 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/updatelocks",
    1154 "should the locks be updated based on LP rows?",
    1155 &heurdata->updatelocks, TRUE, DEFAULT_UPDATELOCKS, NULL, NULL) );
    1156
    1157 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minfixingratelp",
    1158 "minimum fixing rate over all variables (including continuous) to solve LP",
    1159 &heurdata->minfixingratelp, TRUE, DEFAULT_MINFIXINGRATELP, 0.0, 1.0, NULL, NULL) );
    1160
    1161 return SCIP_OKAY;
    1162}
    SCIP_VAR * w
    Definition: circlepacking.c:67
    SCIP_Real * r
    Definition: circlepacking.c:59
    #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_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 SCIP_CALL_ABORT(x)
    Definition: def.h:343
    #define SCIP_LONGINT_FORMAT
    Definition: def.h:157
    #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 SCIPtranslateSubSols(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_VAR **subvars, SCIP_Bool *success, int *solindex)
    Definition: scip_copy.c:1438
    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 SCIPcopyCuts(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, int *ncutsadded)
    Definition: scip_copy.c:2114
    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
    int SCIPgetNContVars(SCIP *scip)
    Definition: scip_prob.c:2569
    int SCIPgetNCheckConss(SCIP *scip)
    Definition: scip_prob.c:3762
    SCIP_RETCODE SCIPsetObjlimit(SCIP *scip, SCIP_Real objlimit)
    Definition: scip_prob.c:1661
    SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
    Definition: scip_prob.c:2115
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    int SCIPgetNConss(SCIP *scip)
    Definition: scip_prob.c:3620
    SCIP_VAR ** SCIPgetVars(SCIP *scip)
    Definition: scip_prob.c:2201
    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 SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
    Definition: scip_param.c:250
    SCIP_RETCODE SCIPaddLongintParam(SCIP *scip, const char *name, const char *desc, SCIP_Longint *valueptr, SCIP_Bool isadvanced, SCIP_Longint defaultvalue, SCIP_Longint minvalue, SCIP_Longint maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:111
    SCIP_Bool SCIPisParamFixed(SCIP *scip, const char *name)
    Definition: scip_param.c:219
    SCIP_RETCODE 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 SCIPincludeHeurLocks(SCIP *scip)
    Definition: heur_locks.c:1086
    SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
    Definition: scip_branch.c:304
    int SCIPgetNPseudoBranchCands(SCIP *scip)
    Definition: scip_branch.c:766
    SCIP_Bool SCIPisCertified(SCIP *scip)
    SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
    Definition: lp.c:17425
    int SCIPcolGetNNonz(SCIP_COL *col)
    Definition: lp.c:17520
    SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
    Definition: lp.c:17555
    SCIP_ROW ** SCIPcolGetRows(SCIP_COL *col)
    Definition: lp.c:17545
    int SCIPconshdlrGetNCheckConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4802
    SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
    Definition: scip_cons.c:940
    SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
    Definition: scip_heur.c:167
    SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
    Definition: heur.c:1368
    SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
    Definition: scip_heur.c:122
    SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
    Definition: scip_heur.c:183
    SCIP_RETCODE SCIPsetHeurExit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXIT((*heurexit)))
    Definition: scip_heur.c:215
    SCIP_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
    Definition: heur.c:1613
    SCIP_Longint SCIPheurGetNCalls(SCIP_HEUR *heur)
    Definition: heur.c:1593
    SCIP_HEUR * SCIPfindHeur(SCIP *scip, const char *name)
    Definition: scip_heur.c:263
    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
    SCIP_RETCODE SCIPflushLP(SCIP *scip)
    Definition: scip_lp.c:154
    SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
    Definition: scip_lp.c:87
    SCIP_RETCODE SCIPconstructLP(SCIP *scip, SCIP_Bool *cutoff)
    Definition: scip_lp.c:130
    SCIP_Bool SCIPisLPConstructed(SCIP *scip)
    Definition: scip_lp.c:105
    SCIP_RETCODE SCIPgetLPRowsData(SCIP *scip, SCIP_ROW ***rows, int *nrows)
    Definition: scip_lp.c:576
    int SCIPgetNLPRows(SCIP *scip)
    Definition: scip_lp.c:632
    SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
    Definition: scip_lp.c:174
    SCIP_Real SCIPgetLPObjval(SCIP *scip)
    Definition: scip_lp.c:253
    int SCIPgetNUnfixedLPCols(SCIP *scip)
    Definition: scip_lp.c:554
    int SCIPgetNLPCols(SCIP *scip)
    Definition: scip_lp.c:533
    SCIP_Bool SCIPisLPSolBasic(SCIP *scip)
    Definition: scip_lp.c:673
    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 SCIPduplicateBufferArray(scip, ptr, source, num)
    Definition: scip_mem.h:132
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPfreeBufferArrayNull(scip, ptr)
    Definition: scip_mem.h:137
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    int SCIPgetProbingDepth(SCIP *scip)
    Definition: scip_probing.c:199
    char * SCIPsnprintfProbingStats(SCIP *scip, char *strbuf, int len)
    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_Bool SCIPinProbing(SCIP *scip)
    Definition: scip_probing.c:98
    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 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_Real SCIProwGetLhs(SCIP_ROW *row)
    Definition: lp.c:17686
    SCIP_Real SCIPgetRowMinActivity(SCIP *scip, SCIP_ROW *row)
    Definition: scip_lp.c:1903
    int SCIProwGetNNonz(SCIP_ROW *row)
    Definition: lp.c:17607
    SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
    Definition: lp.c:17632
    SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
    Definition: lp.c:17696
    SCIP_Real SCIPgetRowMaxActivity(SCIP *scip, SCIP_ROW *row)
    Definition: scip_lp.c:1920
    int SCIProwGetLPPos(SCIP_ROW *row)
    Definition: lp.c:17895
    SCIP_RETCODE SCIPprintRow(SCIP *scip, SCIP_ROW *row, FILE *file)
    Definition: scip_lp.c:2176
    const char * SCIProwGetName(SCIP_ROW *row)
    Definition: lp.c:17745
    int SCIProwGetRank(SCIP_ROW *row)
    Definition: lp.c:17775
    SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
    Definition: lp.c:17642
    SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
    Definition: scip_sol.c:514
    SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
    Definition: scip_sol.c:1250
    SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
    Definition: scip_sol.c:2351
    int SCIPgetNSols(SCIP *scip)
    Definition: scip_sol.c:2887
    SCIP_RETCODE SCIProundSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
    Definition: scip_sol.c:3128
    SCIP_RETCODE SCIPtrySol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
    Definition: scip_sol.c:4017
    SCIP_RETCODE SCIPcheckSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *feasible)
    Definition: scip_sol.c:4317
    SCIP_RETCODE SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1293
    SCIP_RETCODE SCIPpresolve(SCIP *scip)
    Definition: scip_solve.c:2425
    SCIP_RETCODE SCIPsolve(SCIP *scip)
    Definition: scip_solve.c:2611
    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 SCIPgetNLPIterations(SCIP *scip)
    SCIP_Real SCIPgetSolvingTime(SCIP *scip)
    Definition: scip_timing.c:378
    SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPsumepsilon(SCIP *scip)
    int SCIPgetDepth(SCIP *scip)
    Definition: scip_tree.c:672
    SCIP_RETCODE SCIPcutoffNode(SCIP *scip, SCIP_NODE *node)
    Definition: scip_tree.c:436
    SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
    Definition: scip_tree.c:91
    SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
    Definition: var.c:23715
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23418
    int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
    Definition: var.c:4380
    SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
    Definition: var.c:23530
    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
    int SCIPvarGetProbindex(SCIP_VAR *var)
    Definition: var.c:23694
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23299
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24266
    int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
    Definition: var.c:4322
    void SCIPenableVarHistory(SCIP *scip)
    Definition: scip_var.c:11083
    void SCIPfreeRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen)
    SCIP_Real SCIPrandomGetReal(SCIP_RANDNUMGEN *randnumgen, SCIP_Real minrandval, SCIP_Real maxrandval)
    Definition: misc.c:10245
    SCIP_RETCODE SCIPcreateRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen, unsigned int initialseed, SCIP_Bool useglobalseed)
    #define DEFAULT_NODESQUOT
    Definition: heur_locks.c:81
    static SCIP_DECL_HEUREXEC(heurExecLocks)
    Definition: heur_locks.c:658
    static SCIP_DECL_HEURFREE(heurFreeLocks)
    Definition: heur_locks.c:134
    static SCIP_DECL_HEUREXIT(heurExitLocks)
    Definition: heur_locks.c:174
    #define DEFAULT_NODESOFS
    Definition: heur_locks.c:80
    #define DEFAULT_MINFIXINGRATELP
    Definition: heur_locks.c:89
    #define DEFAULT_COPYCUTS
    Definition: heur_locks.c:84
    #define DEFAULT_MAXNODES
    Definition: heur_locks.c:74
    #define DEFAULT_ROUNDUPPROBABILITY
    Definition: heur_locks.c:75
    #define HEUR_TIMING
    Definition: heur_locks.c:71
    #define DEFAULT_MINNODES
    Definition: heur_locks.c:79
    static SCIP_DECL_HEURINIT(heurInitLocks)
    Definition: heur_locks.c:153
    static SCIP_DECL_HEURCOPY(heurCopyLocks)
    Definition: heur_locks.c:119
    #define HEUR_FREQOFS
    Definition: heur_locks.c:69
    #define HEUR_DESC
    Definition: heur_locks.c:65
    #define DEFAULT_MINFIXINGRATE
    Definition: heur_locks.c:76
    SCIP_RETCODE SCIPapplyLockFixings(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_Bool *cutoff, SCIP_Bool *allrowsfulfilled)
    Definition: heur_locks.c:194
    #define HEUR_DISPCHAR
    Definition: heur_locks.c:66
    #define HEUR_MAXDEPTH
    Definition: heur_locks.c:70
    #define HEUR_PRIORITY
    Definition: heur_locks.c:67
    #define DEFAULT_MINIMPROVE
    Definition: heur_locks.c:77
    #define HEUR_NAME
    Definition: heur_locks.c:64
    #define DEFAULT_UPDATELOCKS
    Definition: heur_locks.c:83
    #define DEFAULT_RANDSEED
    Definition: heur_locks.c:88
    #define DEFAULT_USEFINALSUBMIP
    Definition: heur_locks.c:86
    #define HEUR_FREQ
    Definition: heur_locks.c:68
    #define HEUR_USESSUBSCIP
    Definition: heur_locks.c:72
    #define DEFAULT_MAXPROPROUNDS
    Definition: heur_locks.c:82
    locks primal heuristic
    memory allocation routines
    public methods for managing constraints
    public methods for primal heuristics
    public methods for LP management
    public methods for message output
    #define SCIPdebug(x)
    Definition: pub_message.h:93
    public data structures and miscellaneous methods
    public methods for problem variables
    public methods for branching rule plugins and branching
    public methods for certified solving
    public methods for constraint handler plugins and constraints
    public methods for problem copies
    public methods for exact solving
    general public methods
    public methods for primal heuristic plugins and divesets
    public methods for the LP relaxation, rows and columns
    public methods for memory management
    public methods for message handling
    public methods for 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 random numbers
    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
    struct SCIP_HeurData SCIP_HEURDATA
    Definition: type_heur.h:77
    enum SCIP_LPSolStat SCIP_LPSOLSTAT
    Definition: type_lp.h:52
    @ SCIP_LPSOLSTAT_ERROR
    Definition: type_lp.h:50
    @ SCIP_LPSOLSTAT_OPTIMAL
    Definition: type_lp.h:44
    @ SCIP_LPSOLSTAT_INFEASIBLE
    Definition: type_lp.h:45
    @ SCIP_LPSOLSTAT_OBJLIMIT
    Definition: type_lp.h:47
    @ 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_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
    @ SCIP_VARTYPE_BINARY
    Definition: type_var.h:64
    @ SCIP_VARSTATUS_COLUMN
    Definition: type_var.h:53
    @ SCIP_LOCKTYPE_MODEL
    Definition: type_var.h:141