Scippy

    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-2025 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#include <string.h>
    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 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
    393
    394 /* call inclusion method of primal heuristic */
    396
    397 return SCIP_OKAY;
    398}
    399
    400/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
    401static
    402SCIP_DECL_HEURFREE(heurFreeOneopt)
    403{ /*lint --e{715}*/
    404 SCIP_HEURDATA* heurdata;
    405
    406 assert(heur != NULL);
    407 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
    408 assert(scip != NULL);
    409
    410 /* free heuristic data */
    411 heurdata = SCIPheurGetData(heur);
    412 assert(heurdata != NULL);
    413 SCIPfreeBlockMemory(scip, &heurdata);
    414 SCIPheurSetData(heur, NULL);
    415
    416 return SCIP_OKAY;
    417}
    418
    419
    420/** solving process initialization method of primal heuristic (called when branch and bound process is about to begin) */
    421static
    422SCIP_DECL_HEURINITSOL(heurInitsolOneopt)
    423{
    424 SCIP_HEURDATA* heurdata;
    425
    426 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
    427
    428 /* create heuristic data */
    429 heurdata = SCIPheurGetData(heur);
    430 assert(heurdata != NULL);
    431
    432 /* 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 */
    433 if( heurdata->duringroot && SCIPheurGetFreqofs(heur) == 0 )
    435
    436 return SCIP_OKAY;
    437}
    438
    439/** solving process deinitialization method of primal heuristic (called before branch and bound process data is freed) */
    440static
    441SCIP_DECL_HEUREXITSOL(heurExitsolOneopt)
    442{
    443 assert(heur != NULL);
    444 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
    445
    446 /* reset the timing mask to its default value */
    448
    449 return SCIP_OKAY;
    450}
    451
    452/** initialization method of primal heuristic (called after problem was transformed) */
    453static
    454SCIP_DECL_HEURINIT(heurInitOneopt)
    455{ /*lint --e{715}*/
    456 SCIP_HEURDATA* heurdata;
    457
    458 assert(heur != NULL);
    459 assert(scip != NULL);
    460
    461 /* get heuristic data */
    462 heurdata = SCIPheurGetData(heur);
    463 assert(heurdata != NULL);
    464
    465 /* initialize last solution index */
    466 heurdata->lastsolindex = -1;
    467
    468 return SCIP_OKAY;
    469}
    470
    471/** execution method of primal heuristic */
    472static
    473SCIP_DECL_HEUREXEC(heurExecOneopt)
    474{ /*lint --e{715}*/
    475 SCIP_HEURDATA* heurdata;
    476 SCIP_VAR** vars; /* SCIP variables */
    477 SCIP_VAR** shiftcands; /* shiftable variables */
    478 SCIP_ROW** lprows; /* SCIP LP rows */
    479 SCIP_SOL* bestsol; /* incumbent solution */
    480 SCIP_SOL* worksol; /* heuristic's working solution */
    481 SCIP_Real* activities; /* row activities for working solution */
    482 SCIP_Real* shiftvals;
    483 SCIP_Bool shifted;
    484 SCIP_RETCODE retcode;
    485 SCIP_Real lb;
    486 SCIP_Real ub;
    487 SCIP_Bool valid;
    488 int nchgbound;
    489 int nvars;
    490 int nenfovars;
    491 int nlprows;
    492 int nshiftcands;
    493 int shiftcandssize;
    494 int nsuccessfulshifts;
    495 int niterations;
    496
    497 assert(heur != NULL);
    498 assert(scip != NULL);
    499 assert(result != NULL);
    500
    501 /* get heuristic's data */
    502 heurdata = SCIPheurGetData(heur);
    503 assert(heurdata != NULL);
    504
    505 *result = SCIP_DELAYED;
    506
    507 /* we only want to process each solution once */
    508 bestsol = SCIPgetBestSol(scip);
    509 if( bestsol == NULL || heurdata->lastsolindex == SCIPsolGetIndex(bestsol) || SCIPsolIsExact(bestsol) )
    510 return SCIP_OKAY;
    511
    512 /* reset the timing mask to its default value (at the root node it could be different) */
    513 if( SCIPgetNNodes(scip) > 1 )
    515
    516 /* get problem variables */
    517 vars = SCIPgetVars(scip);
    518 nvars = SCIPgetNVars(scip);
    519 nenfovars = nvars - SCIPgetNContVars(scip) - SCIPgetNContImplVars(scip);
    520 assert(nenfovars >= 0);
    521
    522 /* do not run if there are no discrete variables */
    523 if( nenfovars == 0 )
    524 {
    525 *result = SCIP_DIDNOTRUN;
    526 return SCIP_OKAY;
    527 }
    528
    529 if( heurtiming == SCIP_HEURTIMING_BEFOREPRESOL )
    530 {
    531 SCIP* subscip; /* the subproblem created by oneopt */
    532 SCIP_VAR** subvars; /* subproblem's variables */
    533
    534 SCIP_Bool success;
    535
    536 if( !heurdata->beforepresol )
    537 return SCIP_OKAY;
    538
    539 /* check whether there is enough time and memory left */
    540 SCIP_CALL( SCIPcheckCopyLimits(scip, &success) );
    541
    542 if( !success )
    543 return SCIP_OKAY;
    544
    545 SCIP_CALL( SCIPallocBufferArray(scip, &subvars, nvars) );
    546
    547 /* initialize the subproblem */
    548 SCIP_CALL( SCIPcreate(&subscip) );
    549
    550 /* setup and solve the subproblem and catch the return code */
    551 retcode = setupAndSolveSubscipOneopt(scip, subscip, heur, vars, subvars, bestsol, result, &valid);
    552
    553 /* free the subscip in any case */
    554 SCIP_CALL( SCIPfree(&subscip) );
    555 SCIP_CALL( retcode );
    556
    557 SCIPfreeBufferArray(scip, &subvars);
    558
    559 return SCIP_OKAY;
    560 }
    561
    562 /* we can only work on solutions valid in the transformed space */
    563 if( SCIPsolIsOriginal(bestsol) )
    564 return SCIP_OKAY;
    565
    566 if( heurtiming == SCIP_HEURTIMING_BEFORENODE && (SCIPhasCurrentNodeLP(scip) || heurdata->forcelpconstruction) )
    567 {
    568 SCIP_Bool cutoff;
    569
    570 SCIP_CALL( SCIPconstructLP(scip, &cutoff) );
    571
    572 /* manually cut off the node if the LP construction detected infeasibility (heuristics cannot return such a
    573 * result); the cutoff result is safe to use in exact solving mode, but we don't have enough information to
    574 * give a certificate for the cutoff
    575 */
    576 if( cutoff && !SCIPisCertified(scip) )
    577 {
    579 return SCIP_OKAY;
    580 }
    581
    583
    584 /* get problem variables again, SCIPconstructLP() might have added new variables */
    585 vars = SCIPgetVars(scip);
    586 nvars = SCIPgetNVars(scip);
    587 nenfovars = nvars - SCIPgetNContVars(scip) - SCIPgetNContImplVars(scip);
    588 assert(nenfovars >= 0);
    589 }
    590
    591 /* we need an LP */
    592 if( SCIPgetNLPRows(scip) == 0 )
    593 return SCIP_OKAY;
    594
    595 *result = SCIP_DIDNOTFIND;
    596
    597 heurdata->lastsolindex = SCIPsolGetIndex(bestsol);
    598 SCIP_CALL( SCIPcreateSolCopy(scip, &worksol, bestsol) );
    599 SCIPsolSetHeur(worksol,heur);
    600
    601 SCIPdebugMsg(scip, "Starting bound adjustment in 1-opt heuristic\n");
    602
    603 nchgbound = 0;
    604 /* change solution values due to possible global bound changes first */
    605 for( int i = nvars - 1; i >= 0; --i )
    606 {
    607 SCIP_VAR* var;
    608 SCIP_Real solval;
    609
    610 var = vars[i];
    611 lb = SCIPvarGetLbGlobal(var);
    612 ub = SCIPvarGetUbGlobal(var);
    613
    614 solval = SCIPgetSolVal(scip, worksol, var);
    615 /* old solution value is smaller than the actual lower bound */
    616 if( SCIPisFeasLT(scip, solval, lb) )
    617 {
    618 /* set the solution value to the global lower bound */
    619 SCIP_CALL( SCIPsetSolVal(scip, worksol, var, lb) );
    620 ++nchgbound;
    621 SCIPdebugMsg(scip, "var <%s> type %d, old solval %g now fixed to lb %g\n", SCIPvarGetName(var), SCIPvarGetType(var), solval, lb);
    622 }
    623 /* old solution value is greater than the actual upper bound */
    624 else if( SCIPisFeasGT(scip, solval, SCIPvarGetUbGlobal(var)) )
    625 {
    626 /* set the solution value to the global upper bound */
    627 SCIP_CALL( SCIPsetSolVal(scip, worksol, var, ub) );
    628 ++nchgbound;
    629 SCIPdebugMsg(scip, "var <%s> type %d, old solval %g now fixed to ub %g\n", SCIPvarGetName(var), SCIPvarGetType(var), solval, ub);
    630 }
    631 }
    632
    633 SCIPdebugMsg(scip, "number of bound changes (due to global bounds) = %d\n", nchgbound);
    634
    635 SCIP_CALL( SCIPgetLPRowsData(scip, &lprows, &nlprows) );
    636 SCIP_CALL( SCIPallocBufferArray(scip, &activities, nlprows) );
    637
    638 valid = TRUE;
    639
    640 /* initialize LP row activities */
    641 for( int i = 0; i < nlprows; ++i )
    642 {
    643 SCIP_ROW* row;
    644
    645 row = lprows[i];
    646 assert(SCIProwGetLPPos(row) == i);
    647
    648 if( !SCIProwIsLocal(row) )
    649 {
    650 activities[i] = SCIPgetRowSolActivity(scip, row, worksol);
    651 SCIPdebugMsg(scip, "Row <%s> has activity %g\n", SCIProwGetName(row), activities[i]);
    652 if( SCIPisFeasLT(scip, activities[i], SCIProwGetLhs(row)) || SCIPisFeasGT(scip, activities[i], SCIProwGetRhs(row)) )
    653 {
    654 valid = FALSE;
    656 SCIPdebugMsg(scip, "row <%s> activity %g violates bounds, lhs = %g, rhs = %g\n", SCIProwGetName(row), activities[i], SCIProwGetLhs(row), SCIProwGetRhs(row));
    657 break;
    658 }
    659 }
    660 }
    661
    662 if( !valid )
    663 {
    664 /** @todo try to correct lp rows */
    665 SCIPdebugMsg(scip, "Some global bound changes were not valid in lp rows.\n");
    666
    667 SCIPfreeBufferArray(scip, &activities);
    668 SCIP_CALL( SCIPfreeSol(scip, &worksol) );
    669
    670 return SCIP_OKAY;
    671 }
    672
    673 /* allocate buffer storage for possible shift candidates */
    674 shiftcandssize = 8;
    675 SCIP_CALL( SCIPallocBufferArray(scip, &shiftcands, shiftcandssize) );
    676 SCIP_CALL( SCIPallocBufferArray(scip, &shiftvals, shiftcandssize) );
    677 nsuccessfulshifts = 0;
    678 niterations = 0;
    679 do
    680 {
    681 /* initialize data */
    682 shifted = FALSE;
    683 nshiftcands = 0;
    684 ++niterations;
    685 SCIPdebugMsg(scip, "Starting 1-opt heuristic iteration #%d\n", niterations);
    686
    687 /* enumerate all integer variables and find out which of them are shiftable */
    688 /* @todo if useloop=TRUE store for each variable which constraint blocked it and only iterate over those variables
    689 * in the following rounds for which the constraint slack was increased by previous shifts
    690 */
    691 for( int i = 0; i < nenfovars; ++i )
    692 {
    694 {
    695 SCIP_Real shiftval;
    696 SCIP_Real solval;
    697
    698 /* find out whether the variable can be shifted */
    699 solval = SCIPgetSolVal(scip, worksol, vars[i]);
    700 shiftval = calcShiftVal(scip, vars[i], solval, activities);
    701
    702 /* insert the variable into the list of shifting candidates */
    703 if( !SCIPisFeasZero(scip, shiftval) )
    704 {
    705 SCIPdebugMsg(scip, " -> Variable <%s> can be shifted by <%1.1f> \n", SCIPvarGetName(vars[i]), shiftval);
    706
    707 if( nshiftcands == shiftcandssize)
    708 {
    709 shiftcandssize *= 8;
    710 SCIP_CALL( SCIPreallocBufferArray(scip, &shiftcands, shiftcandssize) );
    711 SCIP_CALL( SCIPreallocBufferArray(scip, &shiftvals, shiftcandssize) );
    712 }
    713 shiftcands[nshiftcands] = vars[i];
    714 shiftvals[nshiftcands] = shiftval;
    715 nshiftcands++;
    716 }
    717 }
    718 }
    719
    720 /* if at least one variable can be shifted, shift variables sorted by their objective */
    721 if( nshiftcands > 0 )
    722 {
    723 SCIP_Real shiftval;
    724 SCIP_Real solval;
    725 SCIP_VAR* var;
    726
    727 /* the case that exactly one variable can be shifted is slightly easier */
    728 if( nshiftcands == 1 )
    729 {
    730 var = shiftcands[0];
    731 assert(var != NULL);
    732 solval = SCIPgetSolVal(scip, worksol, var);
    733 shiftval = shiftvals[0];
    734 assert(!SCIPisFeasZero(scip,shiftval));
    735 SCIPdebugMsg(scip, " Only one shiftcand found, var <%s>, which is now shifted by<%1.1f> \n",
    736 SCIPvarGetName(var), shiftval);
    737 SCIP_CALL( SCIPsetSolVal(scip, worksol, var, solval+shiftval) );
    738 SCIP_CALL( updateRowActivities(scip, activities, var, shiftval) );
    739 ++nsuccessfulshifts;
    740 }
    741 else
    742 {
    743 SCIP_Real* objcoeffs;
    744
    745 SCIP_CALL( SCIPallocBufferArray(scip, &objcoeffs, nshiftcands) );
    746
    747 SCIPdebugMsg(scip, " %d shiftcands found \n", nshiftcands);
    748
    749 /* sort the variables by their objective, optionally weighted with the shiftval */
    750 if( heurdata->weightedobj )
    751 {
    752 for( int i = 0; i < nshiftcands; ++i )
    753 objcoeffs[i] = SCIPvarGetObj(shiftcands[i])*shiftvals[i];
    754 }
    755 else
    756 {
    757 for( int i = 0; i < nshiftcands; ++i )
    758 objcoeffs[i] = SCIPvarGetObj(shiftcands[i]);
    759 }
    760
    761 /* sort arrays with respect to the first one */
    762 SCIPsortRealPtr(objcoeffs, (void**)shiftcands, nshiftcands);
    763
    764 /* try to shift each variable -> Activities have to be updated */
    765 for( int i = 0; i < nshiftcands; ++i )
    766 {
    767 var = shiftcands[i];
    768 assert(var != NULL);
    769 solval = SCIPgetSolVal(scip, worksol, var);
    770 shiftval = calcShiftVal(scip, var, solval, activities);
    771 assert(i > 0 || !SCIPisFeasZero(scip, shiftval));
    772 assert(SCIPisFeasGE(scip, solval+shiftval, SCIPvarGetLbGlobal(var)) && SCIPisFeasLE(scip, solval+shiftval, SCIPvarGetUbGlobal(var)));
    773
    774 /* update data structures for nonzero shift value */
    775 if( ! SCIPisFeasZero(scip, shiftval) )
    776 {
    777 SCIPdebugMsg(scip, " -> Variable <%s> is now shifted by <%1.1f> \n", SCIPvarGetName(vars[i]), shiftval);
    778 SCIP_CALL( SCIPsetSolVal(scip, worksol, var, solval+shiftval) );
    779 SCIP_CALL( updateRowActivities(scip, activities, var, shiftval) );
    780 ++nsuccessfulshifts;
    781 }
    782 }
    783
    784 SCIPfreeBufferArray(scip, &objcoeffs);
    785 }
    786 shifted = TRUE;
    787 }
    788 }
    789 while( heurdata->useloop && shifted );
    790
    791 if( nsuccessfulshifts > 0 )
    792 {
    793 /* if the problem is a pure IP, try to install the solution, if it is a MIP, solve LP again to set the continuous
    794 * variables to the best possible value
    795 */
    796 if( nvars == nenfovars || !SCIPhasCurrentNodeLP(scip) || SCIPgetLPSolstat(scip) != SCIP_LPSOLSTAT_OPTIMAL )
    797 {
    798 SCIP_Bool success;
    799
    800 /* since activities are maintained iteratively, we cannot guarantee the feasibility of the shiftings and have
    801 * to set the checklprows flag to TRUE
    802 */
    803 SCIP_CALL( SCIPtrySol(scip, worksol, FALSE, FALSE, FALSE, FALSE, TRUE, &success) );
    804
    805 if( success )
    806 {
    807 SCIPdebugMsg(scip, "found feasible shifted solution:\n");
    808 SCIPdebug( SCIP_CALL( SCIPprintSol(scip, worksol, NULL, FALSE) ) );
    809 *result = SCIP_FOUNDSOL;
    810 }
    811 }
    812 else
    813 {
    814 SCIP_Bool lperror;
    815#ifdef NDEBUG
    816 SCIP_RETCODE retstat;
    817#endif
    818
    819 SCIPdebugMsg(scip, "shifted solution should be feasible -> solve LP to fix continuous variables to best values\n");
    820
    821 /* start diving to calculate the LP relaxation */
    823
    824 /* set the bounds of the variables: fixed for integers, global bounds for continuous */
    825 for( int i = 0; i < nvars; ++i )
    826 {
    828 {
    829 SCIP_CALL( SCIPchgVarLbDive(scip, vars[i], SCIPvarGetLbGlobal(vars[i])) );
    830 SCIP_CALL( SCIPchgVarUbDive(scip, vars[i], SCIPvarGetUbGlobal(vars[i])) );
    831 }
    832 }
    833 /* apply this after global bounds to not cause an error with intermediate empty domains */
    834 for( int i = 0; i < nenfovars; ++i )
    835 {
    837 {
    838 SCIP_Real solval;
    839 solval = SCIPgetSolVal(scip, worksol, vars[i]);
    840 SCIP_CALL( SCIPchgVarLbDive(scip, vars[i], solval) );
    841 SCIP_CALL( SCIPchgVarUbDive(scip, vars[i], solval) );
    842 }
    843 }
    844
    845 /* solve LP */
    846 SCIPdebugMsg(scip, " -> old LP iterations: %" SCIP_LONGINT_FORMAT "\n", SCIPgetNLPIterations(scip));
    847
    848 /**@todo in case of an MINLP, if SCIPisNLPConstructed() is TRUE, say, rather solve the NLP instead of the LP */
    849 /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
    850 * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
    851 */
    852#ifdef NDEBUG
    853 retstat = SCIPsolveDiveLP(scip, -1, &lperror, NULL);
    854 if( retstat != SCIP_OKAY )
    855 {
    856 SCIPwarningMessage(scip, "Error while solving LP in 1-opt heuristic; LP solve terminated with code <%d>\n",retstat);
    857 }
    858#else
    859 SCIP_CALL( SCIPsolveDiveLP(scip, -1, &lperror, NULL) );
    860#endif
    861
    862 SCIPdebugMsg(scip, " -> new LP iterations: %" SCIP_LONGINT_FORMAT "\n", SCIPgetNLPIterations(scip));
    863 SCIPdebugMsg(scip, " -> error=%u, status=%d\n", lperror, SCIPgetLPSolstat(scip));
    864
    865 /* check if this is a feasible solution */
    866 if( !lperror && SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL )
    867 {
    868 SCIP_Bool success;
    869
    870 /* copy the current LP solution to the working solution */
    871 SCIP_CALL( SCIPlinkLPSol(scip, worksol) );
    872
    873 /* in exact mode we have to end diving prior to trying the solution */
    874 if( SCIPisExact(scip) )
    875 {
    876 SCIP_CALL( SCIPunlinkSol(scip, worksol) );
    878 }
    879
    880 SCIP_CALL( SCIPtrySol(scip, worksol, FALSE, FALSE, FALSE, FALSE, FALSE, &success) );
    881
    882 /* check solution for feasibility */
    883 if( success )
    884 {
    885 SCIPdebugMsg(scip, "found feasible shifted solution:\n");
    886 SCIPdebug( SCIP_CALL( SCIPprintSol(scip, worksol, NULL, FALSE) ) );
    887 *result = SCIP_FOUNDSOL;
    888 }
    889 }
    890
    891 /* terminate the diving */
    892 if( SCIPinDive(scip) )
    893 {
    895 }
    896 }
    897 }
    898
    899 /* heuristic should not rerun on this incumbent because the heuristic loop finishes only after no further
    900 * improvements of the incumbent solution are possible
    901 */
    902 if( heurdata->useloop )
    903 heurdata->lastsolindex = SCIPsolGetIndex(SCIPgetBestSol(scip));
    904
    905 SCIPfreeBufferArray(scip, &shiftvals);
    906 SCIPfreeBufferArray(scip, &shiftcands);
    907 SCIPfreeBufferArray(scip, &activities);
    908
    909 SCIP_CALL( SCIPfreeSol(scip, &worksol) );
    910
    911 SCIPdebugMsg(scip, "Finished 1-opt heuristic\n");
    912
    913 return SCIP_OKAY;
    914}
    915
    916/*
    917 * primal heuristic specific interface methods
    918 */
    919
    920/** creates the oneopt primal heuristic and includes it in SCIP */
    922 SCIP* scip /**< SCIP data structure */
    923 )
    924{
    925 SCIP_HEURDATA* heurdata;
    926 SCIP_HEUR* heur;
    927
    928 /* create Oneopt primal heuristic data */
    929 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
    930
    931 /* include primal heuristic */
    934 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecOneopt, heurdata) );
    935
    936 assert(heur != NULL);
    937
    938 /* primal heuristic is safe to use in exact solving mode */
    939 SCIPheurMarkExact(heur);
    940
    941 /* set non-NULL pointers to callback methods */
    942 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyOneopt) );
    943 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeOneopt) );
    944 SCIP_CALL( SCIPsetHeurInitsol(scip, heur, heurInitsolOneopt) );
    945 SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolOneopt) );
    946 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitOneopt) );
    947
    948 /* add oneopt primal heuristic parameters */
    949 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/oneopt/weightedobj",
    950 "should the objective be weighted with the potential shifting value when sorting the shifting candidates?",
    951 &heurdata->weightedobj, TRUE, DEFAULT_WEIGHTEDOBJ, NULL, NULL) );
    952
    953 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/oneopt/duringroot",
    954 "should the heuristic be called before and during the root node?",
    955 &heurdata->duringroot, TRUE, DEFAULT_DURINGROOT, NULL, NULL) );
    956
    957 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/oneopt/forcelpconstruction",
    958 "should the construction of the LP be forced even if LP solving is deactivated?",
    959 &heurdata->forcelpconstruction, TRUE, DEFAULT_FORCELPCONSTRUCTION, NULL, NULL) );
    960
    961 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/oneopt/beforepresol",
    962 "should the heuristic be called before presolving?",
    963 &heurdata->beforepresol, TRUE, DEFAULT_BEFOREPRESOL, NULL, NULL) );
    964
    965 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/oneopt/useloop",
    966 "should the heuristic continue to run as long as improvements are found?",
    967 &heurdata->useloop, TRUE, DEFAULT_USELOOP, NULL, NULL) );
    968
    969 return SCIP_OKAY;
    970}
    #define NULL
    Definition: def.h:248
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define SCIP_CALL_ABORT(x)
    Definition: def.h:334
    #define SCIP_LONGINT_FORMAT
    Definition: def.h:148
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_RETCODE SCIPtranslateSubSols(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_VAR **subvars, SCIP_Bool *success, int *solindex)
    Definition: scip_copy.c:1437
    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:2865
    SCIP_RETCODE SCIPcheckCopyLimits(SCIP *sourcescip, SCIP_Bool *success)
    Definition: scip_copy.c:3249
    SCIP_RETCODE SCIPcopyLimits(SCIP *sourcescip, SCIP *targetscip)
    Definition: scip_copy.c:3292
    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:921
    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:2981
    SCIP_RETCODE SCIPcreateSolCopy(SCIP *scip, SCIP_SOL **sol, SCIP_SOL *sourcesol)
    Definition: scip_sol.c:884
    SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
    Definition: scip_sol.c:1252
    SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
    Definition: scip_sol.c:2349
    SCIP_RETCODE SCIPcreateOrigSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
    Definition: scip_sol.c:831
    SCIP_RETCODE SCIPunlinkSol(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1506
    SCIP_Bool SCIPsolIsOriginal(SCIP_SOL *sol)
    Definition: sol.c:4140
    int SCIPsolGetIndex(SCIP_SOL *sol)
    Definition: sol.c:4290
    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:4012
    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:4109
    SCIP_RETCODE SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1295
    SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
    Definition: scip_sol.c:1571
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1765
    void SCIPsolSetHeur(SCIP_SOL *sol, SCIP_HEUR *heur)
    Definition: sol.c:4304
    SCIP_Bool SCIPsolIsExact(SCIP_SOL *sol)
    Definition: sol.c:4150
    SCIP_RETCODE SCIPtransformProb(SCIP *scip)
    Definition: scip_solve.c:232
    SCIP_RETCODE SCIPsolve(SCIP *scip)
    Definition: scip_solve.c:2635
    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:23683
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23386
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23900
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23453
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24142
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24120
    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:473
    #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:422
    #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:402
    #define DEFAULT_BEFOREPRESOL
    Definition: heur_oneopt.c:75
    static SCIP_DECL_HEUREXITSOL(heurExitsolOneopt)
    Definition: heur_oneopt.c:441
    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:454
    #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
    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