SCIP

    Solving Constraint Integer Programs

    heur_oneopt.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_oneopt.c
    26 * @ingroup DEFPLUGINS_HEUR
    27 * @brief improvement heuristic that alters single variable values
    28 * @author Timo Berthold
    29 */
    30
    31/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    32
    34#include "scip/heur_oneopt.h"
    35#include "scip/pub_heur.h"
    36#include "scip/pub_lp.h"
    37#include "scip/pub_message.h"
    38#include "scip/pub_misc.h"
    39#include "scip/pub_misc_sort.h"
    40#include "scip/pub_sol.h"
    41#include "scip/pub_var.h"
    43#include "scip/scip_copy.h"
    44#include "scip/scip_exact.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_numerics.h"
    51#include "scip/scip_param.h"
    52#include "scip/scip_prob.h"
    53#include "scip/scip_sol.h"
    54#include "scip/scip_solve.h"
    56#include "scip/scip_tree.h"
    57
    58
    59/* @note If the heuristic runs in the root node, the timing is changed to (SCIP_HEURTIMING_DURINGLPLOOP |
    60 * SCIP_HEURTIMING_BEFORENODE), see SCIP_DECL_HEURINITSOL callback.
    61 */
    62
    63#define HEUR_NAME "oneopt"
    64#define HEUR_DESC "1-opt heuristic which tries to improve setting of single integer variables"
    65#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_ITERATIVE
    66#define HEUR_PRIORITY -20000
    67#define HEUR_FREQ 1
    68#define HEUR_FREQOFS 0
    69#define HEUR_MAXDEPTH -1
    70#define HEUR_TIMING SCIP_HEURTIMING_BEFOREPRESOL | SCIP_HEURTIMING_AFTERNODE
    71#define HEUR_USESSUBSCIP FALSE /**< does the heuristic use a secondary SCIP instance? */
    72
    73#define DEFAULT_WEIGHTEDOBJ TRUE /**< should the objective be weighted with the potential shifting value when sorting the shifting candidates? */
    74#define DEFAULT_DURINGROOT TRUE /**< should the heuristic be called before and during the root node? */
    75#define DEFAULT_BEFOREPRESOL FALSE /**< should the heuristic be called before presolving */
    76#define DEFAULT_FORCELPCONSTRUCTION FALSE /**< should the construction of the LP be forced even if LP solving is deactivated? */
    77#define DEFAULT_USELOOP TRUE /**< should the heuristic continue to run as long as improvements are found? */
    78/*
    79 * Data structures
    80 */
    81
    82/** primal heuristic data */
    83struct SCIP_HeurData
    84{
    85 int lastsolindex; /**< index of the last solution for which oneopt was performed */
    86 SCIP_Bool weightedobj; /**< should the objective be weighted with the potential shifting value when sorting the shifting candidates? */
    87 SCIP_Bool duringroot; /**< should the heuristic be called before and during the root node? */
    88 SCIP_Bool forcelpconstruction;/**< should the construction of the LP be forced even if LP solving is deactivated? */
    89 SCIP_Bool beforepresol; /**< should the heuristic be called before presolving */
    90 SCIP_Bool useloop; /**< should the heuristic continue to run as long as improvements are found? */
    91};
    92
    93
    94/*
    95 * Local methods
    96 */
    97
    98/** compute value by which the solution of variable @p var can be shifted */
    99static
    101 SCIP* scip, /**< SCIP data structure */
    102 SCIP_VAR* var, /**< variable that should be shifted */
    103 SCIP_Real solval, /**< current solution value */
    104 SCIP_Real* activities /**< LP row activities */
    105 )
    106{
    107 SCIP_Real lb;
    108 SCIP_Real ub;
    109 SCIP_Real obj;
    110 SCIP_Real newsolval;
    111
    112 SCIP_COL* col;
    113 SCIP_ROW** colrows;
    114 SCIP_Real* colvals;
    115 SCIP_Bool shiftdown;
    116
    117 int ncolrows;
    118
    119 /* get variable's solution value, global bounds and objective coefficient */
    120 lb = SCIPvarGetLbGlobal(var);
    121 ub = SCIPvarGetUbGlobal(var);
    122 obj = SCIPvarGetObj(var);
    123 shiftdown = TRUE;
    124
    125 /* determine shifting direction and maximal possible shifting w.r.t. corresponding bound */
    126 if( obj > 0.0 )
    127 newsolval = SCIPfeasCeil(scip, lb);
    128 else if( obj < 0.0 )
    129 {
    130 newsolval = SCIPfeasFloor(scip, ub);
    131 shiftdown = FALSE;
    132 }
    133 else
    134 newsolval = solval;
    135
    136 /* newsolval might be bounding solval -> avoid numerical shifting */
    137 if( ( shiftdown && SCIPisFeasGE(scip, newsolval, solval) )
    138 || ( !shiftdown && SCIPisFeasLE(scip, newsolval, solval) ) )
    139 return 0.0;
    140
    141 SCIPdebugMsg(scip, "Try to shift %s variable <%s> with\n", shiftdown ? "down" : "up", SCIPvarGetName(var) );
    142 SCIPdebugMsg(scip, " lb:<%g> <= val:<%g> <= ub:<%g> and obj:<%g> by at most: <%g>\n", lb, solval, ub, obj, newsolval - solval );
    143
    144 /* get data of LP column */
    145 col = SCIPvarGetCol(var);
    146 colrows = SCIPcolGetRows(col);
    147 colvals = SCIPcolGetVals(col);
    148 ncolrows = SCIPcolGetNLPNonz(col);
    149
    150 assert(ncolrows == 0 || (colrows != NULL && colvals != NULL));
    151
    152 /* find maximal shift value, st. all rows stay valid */
    153 for( int i = 0; i < ncolrows; ++i )
    154 {
    155 SCIP_ROW* row;
    156 int rowpos;
    157
    158 row = colrows[i];
    159 rowpos = SCIProwGetLPPos(row);
    160 assert( -1 <= rowpos && rowpos < SCIPgetNLPRows(scip) );
    161
    162 /* only global rows need to be valid */
    163 if( rowpos >= 0 && !SCIProwIsLocal(row) )
    164 {
    165 SCIP_Real side;
    166 SCIP_Bool left;
    167
    168 left = shiftdown == ( colvals[i] > 0 );
    169 side = left ? SCIProwGetLhs(row) : SCIProwGetRhs(row);
    170
    171 /* only finite bounds need to be considered */
    172 if( !SCIPisInfinity(scip, left ? -side : side) )
    173 {
    174 SCIP_Real newsolvalrow;
    175
    176 assert( SCIProwIsInLP(row) );
    177 newsolvalrow = solval + (side - activities[rowpos]) / colvals[i];
    178
    179 /* update shifting value */
    180 if( ( shiftdown && newsolvalrow > newsolval ) || ( !shiftdown && newsolvalrow < newsolval ) )
    181 {
    182 SCIP_Real activity;
    183
    184 activity = activities[rowpos] + colvals[i] * ((shiftdown ? floor(newsolvalrow) : ceil(newsolvalrow)) - solval);
    185
    186 /* ensure that shifting preserves feasibility */
    187 if( shiftdown == ( ( left && SCIPisFeasGE(scip, activity, side) )
    188 || ( !left && SCIPisFeasLE(scip, activity, side) ) ) )
    189 newsolval = floor(newsolvalrow);
    190 else
    191 newsolval = ceil(newsolvalrow);
    192
    193 SCIPdebugMsg(scip, " -> The shift value has to be set to <%g>, because of row <%s>.\n",
    194 newsolval - solval, SCIProwGetName(row));
    195 SCIPdebugMsg(scip, " lhs:<%g> <= act:<%g> <= rhs:<%g>, colval:<%g>\n",
    196 SCIProwGetLhs(row), activities[rowpos], SCIProwGetRhs(row), colvals[i]);
    197
    198 /* newsolval might have reached solval -> avoid numerical shifting */
    199 if( ( shiftdown && SCIPisFeasGE(scip, newsolval, solval) )
    200 || ( !shiftdown && SCIPisFeasLE(scip, newsolval, solval) ) )
    201 return 0.0;
    202 }
    203 }
    204 }
    205 }
    206
    207 /* we must not shift variables to infinity */
    208 return SCIPisInfinity(scip, shiftdown ? -newsolval : newsolval) ? 0.0 : newsolval - solval;
    209}
    210
    211
    212/** update row activities after a variable's solution value changed */
    213static
    215 SCIP* scip, /**< SCIP data structure */
    216 SCIP_Real* activities, /**< LP row activities */
    217 SCIP_VAR* var, /**< variable that has been changed */
    218 SCIP_Real shiftval /**< value that is added to variable */
    219 )
    220{
    221 SCIP_Real* colvals;
    222 SCIP_ROW** colrows;
    223 SCIP_COL* col;
    224
    225 int ncolrows;
    226
    227 assert(activities != NULL);
    228
    229 /* get data of column associated to variable */
    230 col = SCIPvarGetCol(var);
    231 colrows = SCIPcolGetRows(col);
    232 colvals = SCIPcolGetVals(col);
    233 ncolrows = SCIPcolGetNLPNonz(col);
    234 assert(ncolrows == 0 || (colrows != NULL && colvals != NULL));
    235
    236 /* enumerate all rows with nonzero entry in this column */
    237 for( int i = 0; i < ncolrows; ++i )
    238 {
    239 SCIP_ROW* row;
    240 int rowpos;
    241
    242 row = colrows[i];
    243 rowpos = SCIProwGetLPPos(row);
    244 assert(-1 <= rowpos && rowpos < SCIPgetNLPRows(scip) );
    245
    246 /* update row activity, only regard global rows in the LP */
    247 if( rowpos >= 0 && !SCIProwIsLocal(row) )
    248 {
    249 activities[rowpos] += shiftval * colvals[i];
    250
    251 if( SCIPisInfinity(scip, activities[rowpos]) )
    252 activities[rowpos] = SCIPinfinity(scip);
    253 else if( SCIPisInfinity(scip, -activities[rowpos]) )
    254 activities[rowpos] = -SCIPinfinity(scip);
    255 }
    256 }
    257
    258 return SCIP_OKAY;
    259}
    260
    261/** setup and solve oneopt sub-SCIP */
    262static
    264 SCIP* scip, /**< SCIP data structure */
    265 SCIP* subscip, /**< sub-SCIP data structure */
    266 SCIP_HEUR* heur, /**< oneopt heuristic */
    267 SCIP_VAR** vars, /**< SCIP variables */
    268 SCIP_VAR** subvars, /**< subproblem's variables */
    269 SCIP_SOL* bestsol, /**< incumbent solution */
    270 SCIP_RESULT* result, /**< pointer to store the result */
    271 SCIP_Bool* valid /**< pointer to store the valid value */
    272 )
    273{
    274 SCIP_HASHMAP* varmapfw; /* mapping of SCIP variables to sub-SCIP variables */
    275 SCIP_SOL* startsol;
    276 int nvars; /* number of original problem's variables */
    277
    278 assert(scip != NULL);
    279 assert(subscip != NULL);
    280 assert(heur != NULL);
    281
    282 nvars = SCIPgetNVars(scip);
    283
    284 /* create the variable mapping hash map */
    285 SCIP_CALL( SCIPhashmapCreate(&varmapfw, SCIPblkmem(subscip), nvars) );
    286
    287 /* copy complete SCIP instance */
    288 *valid = FALSE;
    289 SCIP_CALL( SCIPcopy(scip, subscip, varmapfw, NULL, "oneopt", TRUE, FALSE, FALSE, TRUE, valid) );
    290 SCIP_CALL( SCIPtransformProb(subscip) );
    291
    292 /* get variable image and create start solution for the subproblem */
    293 SCIP_CALL( SCIPcreateOrigSol(subscip, &startsol, NULL) );
    294 for( int i = 0; i < nvars; ++i )
    295 {
    296 subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, vars[i]);
    297 if( subvars[i] != NULL )
    298 SCIP_CALL( SCIPsetSolVal(subscip, startsol, subvars[i], SCIPgetSolVal(scip, bestsol, vars[i])) );
    299 }
    300
    301 /* try to add new solution to sub-SCIP and free it immediately */
    302 *valid = FALSE;
    303 SCIP_CALL( SCIPtrySolFree(subscip, &startsol, FALSE, FALSE, FALSE, FALSE, FALSE, valid) );
    304 SCIPhashmapFree(&varmapfw);
    305
    306 /* deactivate basically everything except oneopt in the sub-SCIP */
    310
    311 /* set limits for the subproblem */
    312 SCIP_CALL( SCIPcopyLimits(scip, subscip) );
    313 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", 1LL) );
    314
    315 SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
    316
    317#ifdef SCIP_DEBUG
    318 /* for debugging, enable full output */
    319 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 5) );
    320 SCIP_CALL( SCIPsetIntParam(subscip, "display/freq", 100000000) );
    321#else
    322 /* disable statistic timing inside sub SCIP and output to console */
    323 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) );
    324 SCIP_CALL( SCIPsetBoolParam(subscip, "timing/statistictiming", FALSE) );
    325#endif
    326
    327 /* if necessary, some of the parameters have to be unfixed first */
    328 if( SCIPisParamFixed(subscip, "lp/solvefreq") )
    329 {
    330 SCIPwarningMessage(scip, "unfixing parameter lp/solvefreq in subscip of oneopt heuristic\n");
    331 SCIP_CALL( SCIPunfixParam(subscip, "lp/solvefreq") );
    332 }
    333 SCIP_CALL( SCIPsetIntParam(subscip, "lp/solvefreq", -1) );
    334
    335 if( SCIPisParamFixed(subscip, "heuristics/oneopt/freq") )
    336 {
    337 SCIPwarningMessage(scip, "unfixing parameter heuristics/oneopt/freq in subscip of oneopt heuristic\n");
    338 SCIP_CALL( SCIPunfixParam(subscip, "heuristics/oneopt/freq") );
    339 }
    340 SCIP_CALL( SCIPsetIntParam(subscip, "heuristics/oneopt/freq", 1) );
    341
    342 if( SCIPisParamFixed(subscip, "heuristics/oneopt/forcelpconstruction") )
    343 {
    344 SCIPwarningMessage(scip, "unfixing parameter heuristics/oneopt/forcelpconstruction in subscip of oneopt heuristic\n");
    345 SCIP_CALL( SCIPunfixParam(subscip, "heuristics/oneopt/forcelpconstruction") );
    346 }
    347 SCIP_CALL( SCIPsetBoolParam(subscip, "heuristics/oneopt/forcelpconstruction", TRUE) );
    348
    349 /* avoid recursive call, which would lead to an endless loop */
    350 if( SCIPisParamFixed(subscip, "heuristics/oneopt/beforepresol") )
    351 {
    352 SCIPwarningMessage(scip, "unfixing parameter heuristics/oneopt/beforepresol in subscip of oneopt heuristic\n");
    353 SCIP_CALL( SCIPunfixParam(subscip, "heuristics/oneopt/beforepresol") );
    354 }
    355 SCIP_CALL( SCIPsetBoolParam(subscip, "heuristics/oneopt/beforepresol", FALSE) );
    356
    357 /* speed up sub-SCIP by not checking dual LP feasibility */
    358 SCIP_CALL( SCIPsetBoolParam(subscip, "lp/checkdualfeas", FALSE) );
    359
    360 if( *valid )
    361 {
    362 /* errors in solving the subproblem should not kill the overall solving process;
    363 * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
    364 */
    365 SCIP_CALL_ABORT( SCIPsolve(subscip) );
    366
    367#ifdef SCIP_DEBUG
    369#endif
    370
    371 /* check, whether a solution was found;
    372 * due to numerics, it might happen that not all solutions are feasible -> try all solutions until one was accepted
    373 */
    374 SCIP_CALL( SCIPtranslateSubSols(scip, subscip, heur, subvars, valid, NULL) );
    375 if( *valid )
    376 *result = SCIP_FOUNDSOL;
    377 }
    378
    379 return SCIP_OKAY;
    380}
    381
    382/*
    383 * Callback methods of primal heuristic
    384 */
    385
    386/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
    387static
    388SCIP_DECL_HEURCOPY(heurCopyOneopt)
    389{ /*lint --e{715}*/
    390 assert(scip != NULL);
    391 assert(heur != NULL);
    392
    394
    395 /* call inclusion method of primal heuristic */
    397
    398 return SCIP_OKAY;
    399}
    400
    401/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
    402static
    403SCIP_DECL_HEURFREE(heurFreeOneopt)
    404{ /*lint --e{715}*/
    405 SCIP_HEURDATA* heurdata;
    406
    407 assert(heur != NULL);
    408 assert(scip != NULL);
    409
    411
    412 /* free heuristic data */
    413 heurdata = SCIPheurGetData(heur);
    414 assert(heurdata != NULL);
    415 SCIPfreeBlockMemory(scip, &heurdata);
    416 SCIPheurSetData(heur, NULL);
    417
    418 return SCIP_OKAY;
    419}
    420
    421
    422/** solving process initialization method of primal heuristic (called when branch and bound process is about to begin) */
    423static
    424SCIP_DECL_HEURINITSOL(heurInitsolOneopt)
    425{
    426 SCIP_HEURDATA* heurdata;
    427
    429
    430 /* create heuristic data */
    431 heurdata = SCIPheurGetData(heur);
    432 assert(heurdata != NULL);
    433
    434 /* if the heuristic is called at the root node, we may want to be called during the cut-and-price loop and even before the first LP solve */
    435 if( heurdata->duringroot && SCIPheurGetFreqofs(heur) == 0 )
    437
    438 return SCIP_OKAY;
    439}
    440
    441/** solving process deinitialization method of primal heuristic (called before branch and bound process data is freed) */
    442static
    443SCIP_DECL_HEUREXITSOL(heurExitsolOneopt)
    444{
    445 assert(heur != NULL);
    446
    448
    449 /* reset the timing mask to its default value */
    451
    452 return SCIP_OKAY;
    453}
    454
    455/** initialization method of primal heuristic (called after problem was transformed) */
    456static
    457SCIP_DECL_HEURINIT(heurInitOneopt)
    458{ /*lint --e{715}*/
    459 SCIP_HEURDATA* heurdata;
    460
    461 assert(heur != NULL);
    462 assert(scip != NULL);
    463
    464 /* get heuristic data */
    465 heurdata = SCIPheurGetData(heur);
    466 assert(heurdata != NULL);
    467
    468 /* initialize last solution index */
    469 heurdata->lastsolindex = -1;
    470
    471 return SCIP_OKAY;
    472}
    473
    474/** execution method of primal heuristic */
    475static
    476SCIP_DECL_HEUREXEC(heurExecOneopt)
    477{ /*lint --e{715}*/
    478 SCIP_HEURDATA* heurdata;
    479 SCIP_VAR** vars; /* SCIP variables */
    480 SCIP_VAR** shiftcands; /* shiftable variables */
    481 SCIP_ROW** lprows; /* SCIP LP rows */
    482 SCIP_SOL* bestsol; /* incumbent solution */
    483 SCIP_SOL* worksol; /* heuristic's working solution */
    484 SCIP_Real* activities; /* row activities for working solution */
    485 SCIP_Real* shiftvals;
    486 SCIP_Bool shifted;
    487 SCIP_RETCODE retcode;
    488 SCIP_Real lb;
    489 SCIP_Real ub;
    490 SCIP_Bool valid;
    491 int nchgbound;
    492 int nvars;
    493 int nenfovars;
    494 int nlprows;
    495 int nshiftcands;
    496 int shiftcandssize;
    497 int nsuccessfulshifts;
    498 int niterations;
    499
    500 assert(heur != NULL);
    501 assert(scip != NULL);
    502 assert(result != NULL);
    503
    504 /* get heuristic's data */
    505 heurdata = SCIPheurGetData(heur);
    506 assert(heurdata != NULL);
    507
    508 *result = SCIP_DELAYED;
    509
    510 /* we only want to process each solution once */
    511 bestsol = SCIPgetBestSol(scip);
    512 if( bestsol == NULL || heurdata->lastsolindex == SCIPsolGetIndex(bestsol) || SCIPsolIsExact(bestsol) )
    513 return SCIP_OKAY;
    514
    515 /* reset the timing mask to its default value (at the root node it could be different) */
    516 if( SCIPgetNNodes(scip) > 1 )
    518
    519 /* get problem variables */
    520 vars = SCIPgetVars(scip);
    521 nvars = SCIPgetNVars(scip);
    522 nenfovars = nvars - SCIPgetNContVars(scip) - SCIPgetNContImplVars(scip);
    523 assert(nenfovars >= 0);
    524
    525 /* do not run if there are no discrete variables */
    526 if( nenfovars == 0 )
    527 {
    528 *result = SCIP_DIDNOTRUN;
    529 return SCIP_OKAY;
    530 }
    531
    532 if( heurtiming == SCIP_HEURTIMING_BEFOREPRESOL )
    533 {
    534 SCIP* subscip; /* the subproblem created by oneopt */
    535 SCIP_VAR** subvars; /* subproblem's variables */
    536
    537 SCIP_Bool success;
    538
    539 if( !heurdata->beforepresol )
    540 return SCIP_OKAY;
    541
    542 /* check whether there is enough time and memory left */
    543 SCIP_CALL( SCIPcheckCopyLimits(scip, &success) );
    544
    545 if( !success )
    546 return SCIP_OKAY;
    547
    548 SCIP_CALL( SCIPallocBufferArray(scip, &subvars, nvars) );
    549
    550 /* initialize the subproblem */
    551 SCIP_CALL( SCIPcreate(&subscip) );
    552
    553 /* setup and solve the subproblem and catch the return code */
    554 retcode = setupAndSolveSubscipOneopt(scip, subscip, heur, vars, subvars, bestsol, result, &valid);
    555
    556 /* free the subscip in any case */
    557 SCIP_CALL( SCIPfree(&subscip) );
    558 SCIP_CALL( retcode );
    559
    560 SCIPfreeBufferArray(scip, &subvars);
    561
    562 return SCIP_OKAY;
    563 }
    564
    565 /* we can only work on solutions valid in the transformed space */
    566 if( SCIPsolIsOriginal(bestsol) )
    567 return SCIP_OKAY;
    568
    569 if( heurtiming == SCIP_HEURTIMING_BEFORENODE && (SCIPhasCurrentNodeLP(scip) || heurdata->forcelpconstruction) )
    570 {
    571 SCIP_Bool cutoff;
    572
    573 SCIP_CALL( SCIPconstructLP(scip, &cutoff) );
    574
    575 /* manually cut off the node if the LP construction detected infeasibility (heuristics cannot return such a
    576 * result); the cutoff result is safe to use in exact solving mode, but we don't have enough information to
    577 * give a certificate for the cutoff
    578 */
    579 if( cutoff && !SCIPisCertified(scip) )
    580 {
    582 return SCIP_OKAY;
    583 }
    584
    586
    587 /* get problem variables again, SCIPconstructLP() might have added new variables */
    588 vars = SCIPgetVars(scip);
    589 nvars = SCIPgetNVars(scip);
    590 nenfovars = nvars - SCIPgetNContVars(scip) - SCIPgetNContImplVars(scip);
    591 assert(nenfovars >= 0);
    592 }
    593
    594 /* we need an LP */
    595 if( SCIPgetNLPRows(scip) == 0 )
    596 return SCIP_OKAY;
    597
    598 *result = SCIP_DIDNOTFIND;
    599
    600 heurdata->lastsolindex = SCIPsolGetIndex(bestsol);
    601 SCIP_CALL( SCIPcreateSolCopy(scip, &worksol, bestsol) );
    602 SCIPsolSetHeur(worksol,heur);
    603
    604 SCIPdebugMsg(scip, "Starting bound adjustment in 1-opt heuristic\n");
    605
    606 nchgbound = 0;
    607 /* change solution values due to possible global bound changes first */
    608 for( int i = nvars - 1; i >= 0; --i )
    609 {
    610 SCIP_VAR* var;
    611 SCIP_Real solval;
    612
    613 var = vars[i];
    614 lb = SCIPvarGetLbGlobal(var);
    615 ub = SCIPvarGetUbGlobal(var);
    616
    617 solval = SCIPgetSolVal(scip, worksol, var);
    618 /* old solution value is smaller than the actual lower bound */
    619 if( SCIPisFeasLT(scip, solval, lb) )
    620 {
    621 /* set the solution value to the global lower bound */
    622 SCIP_CALL( SCIPsetSolVal(scip, worksol, var, lb) );
    623 ++nchgbound;
    624 SCIPdebugMsg(scip, "var <%s> type %d, old solval %g now fixed to lb %g\n", SCIPvarGetName(var), SCIPvarGetType(var), solval, lb);
    625 }
    626 /* old solution value is greater than the actual upper bound */
    627 else if( SCIPisFeasGT(scip, solval, SCIPvarGetUbGlobal(var)) )
    628 {
    629 /* set the solution value to the global upper bound */
    630 SCIP_CALL( SCIPsetSolVal(scip, worksol, var, ub) );
    631 ++nchgbound;
    632 SCIPdebugMsg(scip, "var <%s> type %d, old solval %g now fixed to ub %g\n", SCIPvarGetName(var), SCIPvarGetType(var), solval, ub);
    633 }
    634 }
    635
    636 SCIPdebugMsg(scip, "number of bound changes (due to global bounds) = %d\n", nchgbound);
    637
    638 SCIP_CALL( SCIPgetLPRowsData(scip, &lprows, &nlprows) );
    639 SCIP_CALL( SCIPallocBufferArray(scip, &activities, nlprows) );
    640
    641 valid = TRUE;
    642
    643 /* initialize LP row activities */
    644 for( int i = 0; i < nlprows; ++i )
    645 {
    646 SCIP_ROW* row;
    647
    648 row = lprows[i];
    649 assert(SCIProwGetLPPos(row) == i);
    650
    651 if( !SCIProwIsLocal(row) )
    652 {
    653 activities[i] = SCIPgetRowSolActivity(scip, row, worksol);
    654 SCIPdebugMsg(scip, "Row <%s> has activity %g\n", SCIProwGetName(row), activities[i]);
    655 if( SCIPisFeasLT(scip, activities[i], SCIProwGetLhs(row)) || SCIPisFeasGT(scip, activities[i], SCIProwGetRhs(row)) )
    656 {
    657 valid = FALSE;
    659 SCIPdebugMsg(scip, "row <%s> activity %g violates bounds, lhs = %g, rhs = %g\n", SCIProwGetName(row), activities[i], SCIProwGetLhs(row), SCIProwGetRhs(row));
    660 break;
    661 }
    662 }
    663 }
    664
    665 if( !valid )
    666 {
    667 /** @todo try to correct lp rows */
    668 SCIPdebugMsg(scip, "Some global bound changes were not valid in lp rows.\n");
    669
    670 SCIPfreeBufferArray(scip, &activities);
    671 SCIP_CALL( SCIPfreeSol(scip, &worksol) );
    672
    673 return SCIP_OKAY;
    674 }
    675
    676 /* allocate buffer storage for possible shift candidates */
    677 shiftcandssize = 8;
    678 SCIP_CALL( SCIPallocBufferArray(scip, &shiftcands, shiftcandssize) );
    679 SCIP_CALL( SCIPallocBufferArray(scip, &shiftvals, shiftcandssize) );
    680 nsuccessfulshifts = 0;
    681 niterations = 0;
    682 do
    683 {
    684 /* initialize data */
    685 shifted = FALSE;
    686 nshiftcands = 0;
    687 ++niterations;
    688 SCIPdebugMsg(scip, "Starting 1-opt heuristic iteration #%d\n", niterations);
    689
    690 /* enumerate all integer variables and find out which of them are shiftable */
    691 /* @todo if useloop=TRUE store for each variable which constraint blocked it and only iterate over those variables
    692 * in the following rounds for which the constraint slack was increased by previous shifts
    693 */
    694 for( int i = 0; i < nenfovars; ++i )
    695 {
    697 {
    698 SCIP_Real shiftval;
    699 SCIP_Real solval;
    700
    701 /* find out whether the variable can be shifted */
    702 solval = SCIPgetSolVal(scip, worksol, vars[i]);
    703 shiftval = calcShiftVal(scip, vars[i], solval, activities);
    704
    705 /* insert the variable into the list of shifting candidates */
    706 if( !SCIPisFeasZero(scip, shiftval) )
    707 {
    708 SCIPdebugMsg(scip, " -> Variable <%s> can be shifted by <%1.1f> \n", SCIPvarGetName(vars[i]), shiftval);
    709
    710 if( nshiftcands == shiftcandssize)
    711 {
    712 shiftcandssize *= 8;
    713 SCIP_CALL( SCIPreallocBufferArray(scip, &shiftcands, shiftcandssize) );
    714 SCIP_CALL( SCIPreallocBufferArray(scip, &shiftvals, shiftcandssize) );
    715 }
    716 shiftcands[nshiftcands] = vars[i];
    717 shiftvals[nshiftcands] = shiftval;
    718 nshiftcands++;
    719 }
    720 }
    721 }
    722
    723 /* if at least one variable can be shifted, shift variables sorted by their objective */
    724 if( nshiftcands > 0 )
    725 {
    726 SCIP_Real shiftval;
    727 SCIP_Real solval;
    728 SCIP_VAR* var;
    729
    730 /* the case that exactly one variable can be shifted is slightly easier */
    731 if( nshiftcands == 1 )
    732 {
    733 var = shiftcands[0];
    734 assert(var != NULL);
    735 solval = SCIPgetSolVal(scip, worksol, var);
    736 shiftval = shiftvals[0];
    737 assert(!SCIPisFeasZero(scip,shiftval));
    738 SCIPdebugMsg(scip, " Only one shiftcand found, var <%s>, which is now shifted by<%1.1f> \n",
    739 SCIPvarGetName(var), shiftval);
    740 SCIP_CALL( SCIPsetSolVal(scip, worksol, var, solval+shiftval) );
    741 SCIP_CALL( updateRowActivities(scip, activities, var, shiftval) );
    742 ++nsuccessfulshifts;
    743 }
    744 else
    745 {
    746 SCIP_Real* objcoeffs;
    747
    748 SCIP_CALL( SCIPallocBufferArray(scip, &objcoeffs, nshiftcands) );
    749
    750 SCIPdebugMsg(scip, " %d shiftcands found \n", nshiftcands);
    751
    752 /* sort the variables by their objective, optionally weighted with the shiftval */
    753 if( heurdata->weightedobj )
    754 {
    755 for( int i = 0; i < nshiftcands; ++i )
    756 objcoeffs[i] = SCIPvarGetObj(shiftcands[i])*shiftvals[i];
    757 }
    758 else
    759 {
    760 for( int i = 0; i < nshiftcands; ++i )
    761 objcoeffs[i] = SCIPvarGetObj(shiftcands[i]);
    762 }
    763
    764 /* sort arrays with respect to the first one */
    765 SCIPsortRealPtr(objcoeffs, (void**)shiftcands, nshiftcands);
    766
    767 /* try to shift each variable -> Activities have to be updated */
    768 for( int i = 0; i < nshiftcands; ++i )
    769 {
    770 var = shiftcands[i];
    771 assert(var != NULL);
    772 solval = SCIPgetSolVal(scip, worksol, var);
    773 shiftval = calcShiftVal(scip, var, solval, activities);
    774 assert(i > 0 || !SCIPisFeasZero(scip, shiftval));
    775 assert(SCIPisFeasGE(scip, solval+shiftval, SCIPvarGetLbGlobal(var)) && SCIPisFeasLE(scip, solval+shiftval, SCIPvarGetUbGlobal(var)));
    776
    777 /* update data structures for nonzero shift value */
    778 if( ! SCIPisFeasZero(scip, shiftval) )
    779 {
    780 SCIPdebugMsg(scip, " -> Variable <%s> is now shifted by <%1.1f> \n", SCIPvarGetName(vars[i]), shiftval);
    781 SCIP_CALL( SCIPsetSolVal(scip, worksol, var, solval+shiftval) );
    782 SCIP_CALL( updateRowActivities(scip, activities, var, shiftval) );
    783 ++nsuccessfulshifts;
    784 }
    785 }
    786
    787 SCIPfreeBufferArray(scip, &objcoeffs);
    788 }
    789 shifted = TRUE;
    790 }
    791 }
    792 while( heurdata->useloop && shifted );
    793
    794 if( nsuccessfulshifts > 0 )
    795 {
    796 /* if the problem is a pure IP, try to install the solution, if it is a MIP, solve LP again to set the continuous
    797 * variables to the best possible value
    798 */
    799 if( nvars == nenfovars || !SCIPhasCurrentNodeLP(scip) || SCIPgetLPSolstat(scip) != SCIP_LPSOLSTAT_OPTIMAL )
    800 {
    801 SCIP_Bool success;
    802
    803 /* since activities are maintained iteratively, we cannot guarantee the feasibility of the shiftings and have
    804 * to set the checklprows flag to TRUE
    805 */
    806 SCIP_CALL( SCIPtrySol(scip, worksol, FALSE, FALSE, FALSE, FALSE, TRUE, &success) );
    807
    808 if( success )
    809 {
    810 SCIPdebugMsg(scip, "found feasible shifted solution:\n");
    811 SCIPdebug( SCIP_CALL( SCIPprintSol(scip, worksol, NULL, FALSE) ) );
    812 *result = SCIP_FOUNDSOL;
    813 }
    814 }
    815 else
    816 {
    817 SCIP_Bool lperror;
    818#ifdef NDEBUG
    819 SCIP_RETCODE retstat;
    820#endif
    821
    822 SCIPdebugMsg(scip, "shifted solution should be feasible -> solve LP to fix continuous variables to best values\n");
    823
    824 /* start diving to calculate the LP relaxation */
    826
    827 /* set the bounds of the variables: fixed for integers, global bounds for continuous */
    828 for( int i = 0; i < nvars; ++i )
    829 {
    831 {
    832 SCIP_CALL( SCIPchgVarLbDive(scip, vars[i], SCIPvarGetLbGlobal(vars[i])) );
    833 SCIP_CALL( SCIPchgVarUbDive(scip, vars[i], SCIPvarGetUbGlobal(vars[i])) );
    834 }
    835 }
    836 /* apply this after global bounds to not cause an error with intermediate empty domains */
    837 for( int i = 0; i < nenfovars; ++i )
    838 {
    840 {
    841 SCIP_Real solval;
    842 solval = SCIPgetSolVal(scip, worksol, vars[i]);
    843 SCIP_CALL( SCIPchgVarLbDive(scip, vars[i], solval) );
    844 SCIP_CALL( SCIPchgVarUbDive(scip, vars[i], solval) );
    845 }
    846 }
    847
    848 /* solve LP */
    849 SCIPdebugMsg(scip, " -> old LP iterations: %" SCIP_LONGINT_FORMAT "\n", SCIPgetNLPIterations(scip));
    850
    851 /**@todo in case of an MINLP, if SCIPisNLPConstructed() is TRUE, say, rather solve the NLP instead of the LP */
    852 /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
    853 * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
    854 */
    855#ifdef NDEBUG
    856 retstat = SCIPsolveDiveLP(scip, -1, &lperror, NULL);
    857 if( retstat != SCIP_OKAY )
    858 {
    859 SCIPwarningMessage(scip, "Error while solving LP in 1-opt heuristic; LP solve terminated with code <%d>\n",retstat);
    860 }
    861#else
    862 SCIP_CALL( SCIPsolveDiveLP(scip, -1, &lperror, NULL) );
    863#endif
    864
    865 SCIPdebugMsg(scip, " -> new LP iterations: %" SCIP_LONGINT_FORMAT "\n", SCIPgetNLPIterations(scip));
    866 SCIPdebugMsg(scip, " -> error=%u, status=%d\n", lperror, SCIPgetLPSolstat(scip));
    867
    868 /* check if this is a feasible solution */
    869 if( !lperror && SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL )
    870 {
    871 SCIP_Bool success;
    872
    873 /* copy the current LP solution to the working solution */
    874 SCIP_CALL( SCIPlinkLPSol(scip, worksol) );
    875
    876 /* in exact mode we have to end diving prior to trying the solution */
    877 if( SCIPisExact(scip) )
    878 {
    879 SCIP_CALL( SCIPunlinkSol(scip, worksol) );
    881 }
    882
    883 SCIP_CALL( SCIPtrySol(scip, worksol, FALSE, FALSE, FALSE, FALSE, FALSE, &success) );
    884
    885 /* check solution for feasibility */
    886 if( success )
    887 {
    888 SCIPdebugMsg(scip, "found feasible shifted solution:\n");
    889 SCIPdebug( SCIP_CALL( SCIPprintSol(scip, worksol, NULL, FALSE) ) );
    890 *result = SCIP_FOUNDSOL;
    891 }
    892 }
    893
    894 /* terminate the diving */
    895 if( SCIPinDive(scip) )
    896 {
    898 }
    899 }
    900 }
    901
    902 /* heuristic should not rerun on this incumbent because the heuristic loop finishes only after no further
    903 * improvements of the incumbent solution are possible
    904 */
    905 if( heurdata->useloop )
    906 heurdata->lastsolindex = SCIPsolGetIndex(SCIPgetBestSol(scip));
    907
    908 SCIPfreeBufferArray(scip, &shiftvals);
    909 SCIPfreeBufferArray(scip, &shiftcands);
    910 SCIPfreeBufferArray(scip, &activities);
    911
    912 SCIP_CALL( SCIPfreeSol(scip, &worksol) );
    913
    914 SCIPdebugMsg(scip, "Finished 1-opt heuristic\n");
    915
    916 return SCIP_OKAY;
    917}
    918
    919/*
    920 * primal heuristic specific interface methods
    921 */
    922
    923/** creates the oneopt primal heuristic and includes it in SCIP */
    925 SCIP* scip /**< SCIP data structure */
    926 )
    927{
    928 SCIP_HEURDATA* heurdata;
    929 SCIP_HEUR* heur;
    930
    931 /* create Oneopt primal heuristic data */
    932 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
    933
    934 /* include primal heuristic */
    937 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecOneopt, heurdata) );
    938
    939 assert(heur != NULL);
    940
    941 /* primal heuristic is safe to use in exact solving mode */
    942 SCIPheurMarkExact(heur);
    943
    944 /* set non-NULL pointers to callback methods */
    945 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyOneopt) );
    946 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeOneopt) );
    947 SCIP_CALL( SCIPsetHeurInitsol(scip, heur, heurInitsolOneopt) );
    948 SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolOneopt) );
    949 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitOneopt) );
    950
    951 /* add oneopt primal heuristic parameters */
    952 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/oneopt/weightedobj",
    953 "should the objective be weighted with the potential shifting value when sorting the shifting candidates?",
    954 &heurdata->weightedobj, TRUE, DEFAULT_WEIGHTEDOBJ, NULL, NULL) );
    955
    956 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/oneopt/duringroot",
    957 "should the heuristic be called before and during the root node?",
    958 &heurdata->duringroot, TRUE, DEFAULT_DURINGROOT, NULL, NULL) );
    959
    960 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/oneopt/forcelpconstruction",
    961 "should the construction of the LP be forced even if LP solving is deactivated?",
    962 &heurdata->forcelpconstruction, TRUE, DEFAULT_FORCELPCONSTRUCTION, NULL, NULL) );
    963
    964 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/oneopt/beforepresol",
    965 "should the heuristic be called before presolving?",
    966 &heurdata->beforepresol, TRUE, DEFAULT_BEFOREPRESOL, NULL, NULL) );
    967
    968 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/oneopt/useloop",
    969 "should the heuristic continue to run as long as improvements are found?",
    970 &heurdata->useloop, TRUE, DEFAULT_USELOOP, NULL, NULL) );
    971
    972 return SCIP_OKAY;
    973}
    #define NULL
    Definition: def.h:257
    #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_ABORT(x)
    Definition: def.h:343
    #define SCIP_LONGINT_FORMAT
    Definition: def.h:157
    #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 SCIPcopyLimits(SCIP *sourcescip, SCIP *targetscip)
    Definition: scip_copy.c:3293
    SCIP_RETCODE SCIPfree(SCIP **scip)
    Definition: scip_general.c:402
    SCIP_RETCODE SCIPcreate(SCIP **scip)
    Definition: scip_general.c:370
    int SCIPgetNContVars(SCIP *scip)
    Definition: scip_prob.c:2569
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    SCIP_VAR ** SCIPgetVars(SCIP *scip)
    Definition: scip_prob.c:2201
    int SCIPgetNContImplVars(SCIP *scip)
    Definition: scip_prob.c:2522
    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
    void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
    Definition: scip_message.c:120
    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 SCIPsetHeuristics(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
    Definition: scip_param.c:930
    SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
    Definition: scip_param.c:487
    SCIP_RETCODE SCIPunfixParam(SCIP *scip, const char *name)
    Definition: scip_param.c:385
    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 SCIPincludeHeurOneopt(SCIP *scip)
    Definition: heur_oneopt.c:924
    SCIP_Bool SCIPisCertified(SCIP *scip)
    SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
    Definition: lp.c:17555
    SCIP_ROW ** SCIPcolGetRows(SCIP_COL *col)
    Definition: lp.c:17545
    int SCIPcolGetNLPNonz(SCIP_COL *col)
    Definition: lp.c:17534
    SCIP_Bool SCIPisExact(SCIP *scip)
    Definition: scip_exact.c:193
    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
    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
    int SCIPheurGetFreqofs(SCIP_HEUR *heur)
    Definition: heur.c:1573
    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_RETCODE SCIPchgVarLbDive(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_lp.c:2384
    SCIP_RETCODE SCIPchgVarUbDive(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_lp.c:2416
    SCIP_RETCODE SCIPstartDive(SCIP *scip)
    Definition: scip_lp.c:2206
    SCIP_RETCODE SCIPsolveDiveLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
    Definition: scip_lp.c:2643
    SCIP_RETCODE SCIPendDive(SCIP *scip)
    Definition: scip_lp.c:2255
    SCIP_Bool SCIPinDive(SCIP *scip)
    Definition: scip_lp.c:2740
    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_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
    BMS_BLKMEM * SCIPblkmem(SCIP *scip)
    Definition: scip_mem.c:57
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPreallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:128
    #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_Real SCIProwGetLhs(SCIP_ROW *row)
    Definition: lp.c:17686
    SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
    Definition: lp.c:17696
    int SCIProwGetLPPos(SCIP_ROW *row)
    Definition: lp.c:17895
    SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
    Definition: lp.c:17795
    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
    SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
    Definition: lp.c:17917
    SCIP_Real SCIPgetRowSolActivity(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
    Definition: scip_lp.c:2108
    SCIP_SOL * SCIPgetBestSol(SCIP *scip)
    Definition: scip_sol.c:2986
    SCIP_RETCODE SCIPcreateSolCopy(SCIP *scip, SCIP_SOL **sol, SCIP_SOL *sourcesol)
    Definition: scip_sol.c:882
    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
    SCIP_RETCODE SCIPcreateOrigSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
    Definition: scip_sol.c:829
    SCIP_RETCODE SCIPunlinkSol(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1504
    SCIP_Bool SCIPsolIsOriginal(SCIP_SOL *sol)
    Definition: sol.c:4155
    int SCIPsolGetIndex(SCIP_SOL *sol)
    Definition: sol.c:4305
    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 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_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
    Definition: scip_sol.c:1569
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1763
    void SCIPsolSetHeur(SCIP_SOL *sol, SCIP_HEUR *heur)
    Definition: sol.c:4319
    SCIP_Bool SCIPsolIsExact(SCIP_SOL *sol)
    Definition: sol.c:4165
    SCIP_RETCODE SCIPtransformProb(SCIP *scip)
    Definition: scip_solve.c:232
    SCIP_RETCODE SCIPsolve(SCIP *scip)
    Definition: scip_solve.c:2611
    SCIP_Longint SCIPgetNNodes(SCIP *scip)
    SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
    SCIP_Longint SCIPgetNLPIterations(SCIP *scip)
    SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfeasFloor(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_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    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
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23932
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23485
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24174
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23299
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24152
    void SCIPsortRealPtr(SCIP_Real *realarray, void **ptrarray, int len)
    static SCIP_RETCODE setupAndSolveSubscipOneopt(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_VAR **vars, SCIP_VAR **subvars, SCIP_SOL *bestsol, SCIP_RESULT *result, SCIP_Bool *valid)
    Definition: heur_oneopt.c:263
    #define DEFAULT_FORCELPCONSTRUCTION
    Definition: heur_oneopt.c:76
    static SCIP_DECL_HEUREXEC(heurExecOneopt)
    Definition: heur_oneopt.c:476
    #define HEUR_TIMING
    Definition: heur_oneopt.c:70
    #define HEUR_FREQOFS
    Definition: heur_oneopt.c:68
    #define HEUR_DESC
    Definition: heur_oneopt.c:64
    static SCIP_RETCODE updateRowActivities(SCIP *scip, SCIP_Real *activities, SCIP_VAR *var, SCIP_Real shiftval)
    Definition: heur_oneopt.c:214
    static SCIP_DECL_HEURINITSOL(heurInitsolOneopt)
    Definition: heur_oneopt.c:424
    #define DEFAULT_WEIGHTEDOBJ
    Definition: heur_oneopt.c:73
    #define HEUR_DISPCHAR
    Definition: heur_oneopt.c:65
    #define HEUR_MAXDEPTH
    Definition: heur_oneopt.c:69
    #define HEUR_PRIORITY
    Definition: heur_oneopt.c:66
    #define DEFAULT_DURINGROOT
    Definition: heur_oneopt.c:74
    #define HEUR_NAME
    Definition: heur_oneopt.c:63
    static SCIP_Real calcShiftVal(SCIP *scip, SCIP_VAR *var, SCIP_Real solval, SCIP_Real *activities)
    Definition: heur_oneopt.c:100
    static SCIP_DECL_HEURFREE(heurFreeOneopt)
    Definition: heur_oneopt.c:403
    #define DEFAULT_BEFOREPRESOL
    Definition: heur_oneopt.c:75
    static SCIP_DECL_HEUREXITSOL(heurExitsolOneopt)
    Definition: heur_oneopt.c:443
    static SCIP_DECL_HEURCOPY(heurCopyOneopt)
    Definition: heur_oneopt.c:388
    #define HEUR_FREQ
    Definition: heur_oneopt.c:67
    static SCIP_DECL_HEURINIT(heurInitOneopt)
    Definition: heur_oneopt.c:457
    #define HEUR_USESSUBSCIP
    Definition: heur_oneopt.c:71
    #define DEFAULT_USELOOP
    Definition: heur_oneopt.c:77
    Improvement heuristic that alters single variable values.
    memory allocation routines
    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
    methods for sorting joint arrays of various types
    public methods for primal CIP solutions
    public methods for problem variables
    public methods for certified solving
    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 solutions
    public solving methods
    public methods for querying solving statistics
    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_PARAMSETTING_OFF
    Definition: type_paramset.h:63
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_DELAYED
    Definition: type_result.h:43
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_FOUNDSOL
    Definition: type_result.h:56
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    #define SCIP_HEURTIMING_BEFOREPRESOL
    Definition: type_timing.h:92
    #define SCIP_HEURTIMING_DURINGLPLOOP
    Definition: type_timing.h:81
    #define SCIP_HEURTIMING_BEFORENODE
    Definition: type_timing.h:80
    @ SCIP_VARSTATUS_COLUMN
    Definition: type_var.h:53