Scippy

    SCIP

    Solving Constraint Integer Programs

    heur_dualval.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_dualval.c
    26 * @ingroup DEFPLUGINS_HEUR
    27 * @brief dualval primal heuristic
    28 * @author Tobias Buchwald
    29 *
    30 * This heuristic tries to find solutions by taking the LP or NLP, rounding solution values, fixing the variables to the
    31 * rounded values and then changing some of the values. To determine which variable is changed we give each variable a
    32 * ranking dependent on its dualvalue. We work with a transformed problem that is always feasible and has objective = 0
    33 * iff the original problem is also feasible. Thus we cannot expect to find really good solutions.
    34 */
    35
    36/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    37
    39#include "scip/type_expr.h"
    40#include "scip/cons_indicator.h"
    41#include "scip/cons_knapsack.h"
    42#include "scip/cons_linear.h"
    43#include "scip/cons_logicor.h"
    44#include "scip/cons_setppc.h"
    45#include "scip/cons_varbound.h"
    46#include "scip/heur_dualval.h"
    47#include "scip/pub_cons.h"
    48#include "scip/pub_event.h"
    49#include "scip/pub_heur.h"
    50#include "scip/pub_message.h"
    51#include "scip/pub_misc.h"
    52#include "scip/pub_misc_sort.h"
    53#include "scip/pub_nlp.h"
    54#include "scip/pub_sol.h"
    55#include "scip/pub_var.h"
    56#include "scip/scip_branch.h"
    57#include "scip/scip_cons.h"
    58#include "scip/scip_copy.h"
    59#include "scip/scip_event.h"
    60#include "scip/scip_exact.h"
    61#include "scip/scip_general.h"
    62#include "scip/scip_heur.h"
    63#include "scip/scip_lp.h"
    64#include "scip/scip_mem.h"
    65#include "scip/scip_message.h"
    66#include "scip/scip_nlp.h"
    67#include "scip/scip_nlpi.h"
    68#include "scip/scip_numerics.h"
    69#include "scip/scip_param.h"
    70#include "scip/scip_prob.h"
    71#include "scip/scip_sol.h"
    72#include "scip/scip_solve.h"
    74#include "scip/scip_var.h"
    75#include <string.h>
    76
    77#define HEUR_NAME "dualval"
    78#define HEUR_DESC "primal heuristic using dual values"
    79#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_LNS
    80#define HEUR_PRIORITY -10
    81#define HEUR_FREQ -1
    82#define HEUR_FREQOFS 0
    83#define HEUR_MAXDEPTH -1
    84#define HEUR_TIMING SCIP_HEURTIMING_AFTERNODE
    85#define HEUR_USESSUBSCIP TRUE /**< does the heuristic use a secondary SCIP instance? */
    86
    87#define EVENTHDLR_NAME "lpsol_dualval"
    88#define EVENTHDLR_DESC "event handler for lp solution found"
    89
    90/* default values for user parameters */
    91/* boolean parameters */
    92#define DEFAULT_FORCEIMPROVEMENTS FALSE /**< exit if objective doesn't improve */
    93#define DEFAULT_ONLYCHEAPER TRUE /**< add constraint to ensure that discrete vars are improving */
    94#define DEFAULT_ONLYLEAVES FALSE /**< disable the heuristic if it was not called at a leaf of the B&B tree */
    95#define DEFAULT_RELAXINDICATORS FALSE /**< relax the indicator variables by introducing continuous copies */
    96#define DEFAULT_RELAXCONTVARS FALSE /**< enable relaxation of continous variables */
    97
    98/* integer parameters */
    99#define DEFAULT_HEURVERBLEVEL 0 /**< verblevel of the heuristic, default is 0 to display nothing */
    100#define DEFAULT_NLPVERBLEVEL 0 /**< verblevel of the nlp solver, can be 0 or 1 */
    101#define DEFAULT_RANKVALUE 10 /**< number of ranks that should be displayed when the heuristic is called */
    102#define DEFAULT_MAXCALLS 25 /**< maximal number of recursive calls of the heuristic (if dynamicdepth is off) */
    103#define DEFAULT_DYNAMICDEPTH 0 /**< says if and how the recursion depth is computed at runtime */
    104#define DEFAULT_MAXEQUALRANKS 50 /**< maximal number of variables that may have maximal rank, quit if there are more, turn off by setting -1 */
    105
    106/* real value parameters */
    107#define DEFAULT_MINGAP 5.0 /**< minimal gap for which we still run the heuristic, if gap is less we return without doing anything */
    108#define DEFAULT_LAMBDASLACK 1.0 /**< value added to objective of slack variables, must not be zero */
    109#define DEFAULT_LAMBDAOBJ 0.0 /**< scaling factor for the objective function */
    110
    111
    112/**primal heuristic data */
    113struct SCIP_HeurData
    114{
    115 SCIP* subscip; /**< copy of CIP */
    116 SCIP_VAR** integervars; /**< array of all binary and integer variables of the original scip */
    117 SCIP_HASHMAP* varsciptosubscip; /**< mapping variables in SCIP to sub-SCIP variables */
    118 SCIP_HASHMAP* varsubsciptoscip; /**< mapping variables in sub-SCIP to SCIP variables */
    119 SCIP_HASHMAP* origsubscipConsMap; /**< maps constraints from the transformed problem to corresponding constraints in subproblem */
    120 SCIP_HASHMAP* switchedvars; /**< stores the last value of switched var to avoid cycling */
    121 SCIP_HASHMAP* switchedvars2; /**< stores the second last value of switched vars to avoid cycling */
    122 SCIP_HASHMAP* relaxcons; /**< maps subscip variables to their relaxation constraints */
    123 SCIP_HASHMAP* relaxconsindi; /**< maps indicator variables and their copies to relaxation constraint */
    124 SCIP_HASHMAP* slacktoindivarsmap; /**< maps slack variables of indicator constraint to indicator variable */
    125 SCIP_HASHMAP* indicators; /**< maps indicator variables to their indicator constraint */
    126 SCIP_HASHMAP* conss2nlrow; /**< maps constraint to the corresponding nlrow */
    127 SCIP_HASHMAP* dualvalues; /**< maps constraints of the subscip to their dual values */
    128 SCIP_HASHMAP* slack2var; /**< maps slack variables to the variable they actually relax */
    129 SCIP_HASHMAP* indicopymap; /**< maps indicator variables to their copy variables */
    130 SCIP_HASHMAP* indicopymapback; /**< maps copy variables to their indicator variables */
    131 SCIP_HASHMAP* slackvarlbMap; /**< mapping used indicators to slack variables lower bound*/
    132 SCIP_HASHMAP* slackvarubMap; /**< mapping used indicators to slack variables upper bound*/
    133 SCIP_CONS* objbound; /**< contraint for upper bound of the objective function */
    134 SCIP_Real prevobjective; /**< stores objective value (of the original) so we know if it improved */
    135 SCIP_Real mingap; /**< don't run the heuristic if the gap is less than mingap */
    136 SCIP_Real lambdaslack; /**< the value added to the objective function */
    137 SCIP_Real lambdaobj; /**< the value the original objective function is scaled with */
    138 int integervarssize; /**< size of integervars array */
    139 int nintegervars; /**< number of integer variables in the original problem */
    140 int heurverblevel; /**< verblevel, range is 0 to 4 */
    141 int nlpverblevel; /**< sets verblevel of the included nlp */
    142 int rankvalue; /**< print out the 'rankvalue' highest ranks during iterations */
    143 int maxcalls; /**< maximum number of allowed iterations */
    144 int nonimprovingRounds; /**< nr of rounds, where the algorithm has not improved */
    145 int dynamicdepth; /**< how should the number of calls be computed? */
    146 int maxequalranks; /**< maximum number of variables that may have maximal (absolute) rank */
    147 int nvars; /**< number of active transformed variables in SCIP */
    148 int nsubvars; /**< number of original variables in sub-SCIP */
    149 int usedcalls; /**< number of currently used iterations */
    150 SCIP_Bool isnlp; /**< tells us, whether we have nonlinearities in our program or not */
    151 SCIP_Bool forceimprovements; /**< whether we exit on nonimproving objective in the relaxation or not */
    152 SCIP_Bool prevInfeasible; /**< will tell us if the previous call led to an infeasible fixing */
    153 SCIP_Bool solfound; /**< parameter says, if we already found a solution and have to go back */
    154 SCIP_Bool subscipisvalid; /**< whether all constraints have been copied */
    155 SCIP_Bool switchdifferent; /**< tells us that we want to go up one level and switch another variable */
    156 SCIP_Bool triedsetupsubscip; /**< whether we have tried to setup a sub-SCIP */
    157 SCIP_Bool onlycheaper; /**< add constraint to ensure that discrete vars are improving */
    158 SCIP_Bool onlyleaves; /**< don't use heuristic if we are not in a leaf of the B&B tree */
    159 SCIP_Bool relaxindicators; /**< additionally relax indicator variables */
    160 SCIP_Bool relaxcontvars; /**< additionally relax continous variables */
    161};
    162
    163/*
    164 * event handler method
    165 */
    166
    167/** initialization method of event handler (called after problem was transformed) */
    168static
    169SCIP_DECL_EVENTINIT(eventInitLPsol)
    170{ /*lint --e{715}*/
    171 assert(scip != NULL);
    172 assert(eventhdlr != NULL);
    173
    174 /* notify SCIP that your event handler wants to react on the event type best solution found */
    176
    177 return SCIP_OKAY;
    178}
    179
    180/** deinitialization method of event handler (called before transformed problem is freed) */
    181static
    182SCIP_DECL_EVENTEXIT(eventExitLPsol)
    183{ /*lint --e{715}*/
    184 assert(scip != NULL);
    185 assert(eventhdlr != NULL);
    186
    187 /* notify SCIP that your event handler wants to drop the event type best solution found */
    189
    190 return SCIP_OKAY;
    191}
    192
    193/** execution method of event handler */
    194static
    195SCIP_DECL_EVENTEXEC(eventExecLPsol)
    196{ /*lint --e{715}*/
    197 int i;
    198 int nsubconss;
    199 SCIP_HEURDATA* heurdata;
    200 SCIP_CONS** subconss;
    201 SCIP_Real* dualval;
    202
    203 assert(eventhdlr != NULL);
    204 assert(event != NULL);
    205 assert(scip != NULL);
    207
    208 heurdata = (SCIP_HEURDATA* )SCIPeventhdlrGetData(eventhdlr);
    209 nsubconss = SCIPgetNOrigConss(heurdata->subscip);
    210 subconss = SCIPgetOrigConss(heurdata->subscip);
    211
    212 /* free memory of all entries and clear the hashmap before filling it */
    213 for( i = 0; i < nsubconss; i++ )
    214 {
    215 dualval = (SCIP_Real*)SCIPhashmapGetImage(heurdata->dualvalues, subconss[i]);
    216 if( dualval != NULL )
    217 SCIPfreeBlockMemoryArray(heurdata->subscip, &dualval, 1);
    218 }
    219 SCIP_CALL( SCIPhashmapRemoveAll(heurdata->dualvalues) );
    220
    221 /* insert dualvalues from LP into a hashmap */
    222 for( i = 0; i < nsubconss; i++ )
    223 {
    224 SCIP_CONS* transcons = NULL;
    225 SCIP_CALL( SCIPgetTransformedCons(heurdata->subscip, subconss[i], &transcons) );
    226
    227 if( transcons == NULL )
    228 continue;
    229
    230 if( SCIPconsGetHdlr(transcons) != SCIPfindConshdlr(heurdata->subscip, "linear") )
    231 continue;
    232
    233 SCIP_CALL( SCIPallocBlockMemoryArray(heurdata->subscip, &dualval, 1) ); /*lint !e506*/
    234 *dualval = -SCIPgetDualsolLinear(heurdata->subscip, transcons );
    235 SCIP_CALL( SCIPhashmapInsert(heurdata->dualvalues, subconss[i], dualval) );
    236 }
    237 if( heurdata->heurverblevel > 2 )
    238 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "LP solved event!\n");
    239
    240 return SCIP_OKAY;
    241}
    242
    243/** includes event handler for best solution found */
    244static
    246 SCIP* scip, /**< SCIP data structure */
    247 SCIP_HEURDATA* heurdata /**< heuristic data */
    248 )
    249{
    250 SCIP_EVENTHDLRDATA* eventhdlrdata;
    251 SCIP_EVENTHDLR* eventhdlr = NULL;
    252
    253 eventhdlrdata = (SCIP_EVENTHDLRDATA*)heurdata;
    254
    255 /* create event handler */
    256 SCIP_CALL( SCIPincludeEventhdlrBasic(scip, &eventhdlr, EVENTHDLR_NAME, EVENTHDLR_DESC, eventExecLPsol, eventhdlrdata) );
    257 assert(eventhdlr != NULL);
    258
    259 SCIP_CALL( SCIPsetEventhdlrInit(scip, eventhdlr, eventInitLPsol) );
    260 SCIP_CALL( SCIPsetEventhdlrExit(scip, eventhdlr, eventExitLPsol) );
    261
    262 return SCIP_OKAY;
    263}
    264
    265/*
    266 * Local methods
    267 */
    268
    269/** releases all variables or constraints from given hash map */
    270static
    272 SCIP* scip, /**< SCIP data structure */
    273 SCIP_HASHMAP* hashmap, /**< hashmap */
    274 SCIP_Bool isvarmap /**< are the entries variables or constraints? */
    275 )
    276{
    277 int nentries;
    278 int i;
    279
    280 assert(scip != NULL);
    281 assert(hashmap != NULL);
    282
    283 nentries = SCIPhashmapGetNEntries(hashmap);
    284
    285 for( i = 0; i < nentries; ++i )
    286 {
    287 SCIP_HASHMAPENTRY* entry;
    288 entry = SCIPhashmapGetEntry(hashmap, i);
    289
    290 if( entry != NULL )
    291 {
    292 if( isvarmap )
    293 {
    294 SCIP_VAR* var;
    295 var = (SCIP_VAR*) SCIPhashmapEntryGetImage(entry);
    296
    297 SCIP_CALL( SCIPreleaseVar(scip, &var) );
    298 }
    299 else
    300 {
    301 SCIP_CONS* cons;
    302 cons = (SCIP_CONS*) SCIPhashmapEntryGetImage(entry);
    303
    304 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
    305 }
    306 }
    307 }
    308
    309 return SCIP_OKAY;
    310}
    311
    312/** releases all NLP rows from given hash map */
    313static
    315 SCIP* scip, /**< SCIP data structure */
    316 SCIP_HASHMAP* hashmap /**< hashmap */
    317 )
    318{
    319 int nentries;
    320 int i;
    321
    322 assert(scip != NULL);
    323 assert(hashmap != NULL);
    324
    325 nentries = SCIPhashmapGetNEntries(hashmap);
    326
    327 for( i = 0; i < nentries; ++i )
    328 {
    329 SCIP_HASHMAPENTRY* entry;
    330 entry = SCIPhashmapGetEntry(hashmap, i);
    331 if( entry != NULL )
    332 {
    333 SCIP_NLROW* nlrow;
    334 nlrow = (SCIP_NLROW*) SCIPhashmapEntryGetImage(entry);
    335
    336 SCIP_CALL( SCIPreleaseNlRow(scip, &nlrow) );
    337 }
    338 }
    339
    340 return SCIP_OKAY;
    341}
    342
    343
    344/** adds linear constraints from a SCIP instance to its NLP */
    345static
    347 SCIP* scip, /**< SCIP data structure */
    348 SCIP_CONSHDLR* conshdlr, /**< constraint handler for linear constraints */
    349 SCIP_Bool addcombconss, /**< whether to add combinatorial linear constraints to NLP */
    350 SCIP_Bool addcontconss, /**< whether to add continuous linear constraints to NLP */
    351 SCIP_HEURDATA* heurdata /**< heuristic data structure */
    352 )
    353{
    354 SCIP_CONS** conss;
    355 SCIP_VAR** vars;
    356 SCIP_NLROW* nlrow;
    357 int nconss;
    358 int i;
    359 int j;
    360 int nvars;
    361 SCIP_Bool iscombinatorial;
    362
    363 assert(scip != NULL);
    364 assert(conshdlr != NULL);
    365
    366 nconss = SCIPconshdlrGetNActiveConss(conshdlr);
    367 conss = SCIPconshdlrGetConss(conshdlr);
    368
    369 if( nconss == 0 )
    370 return SCIP_OKAY;
    371
    372 for( i = 0; i < nconss; ++i )
    373 {
    374 /* skip local and redundant constraints */
    375 if( !SCIPconsIsEnabled(conss[i]) || !SCIPconsIsChecked(conss[i]) )
    376 continue;
    377
    378 /* under some circumstances, this method may be called even though the problem has been shown to be
    379 * infeasible in presolve already.
    380 * this infeasibility may come from a linear constraint with lhs > rhs
    381 * the NLP does not allow such constraints, so we skip them here
    382 */
    383 if( !SCIPisRelLE(scip, SCIPgetLhsLinear(scip, conss[i]), SCIPgetRhsLinear(scip, conss[i])) )
    384 continue;
    385
    386 nvars = SCIPgetNVarsLinear(scip, conss[i]);
    387 vars = SCIPgetVarsLinear(scip, conss[i]);
    388
    389 /* check if constraint should be added, only need this check if we do not wanna any constraint anyway */
    390 if( !addcombconss || !addcontconss )
    391 {
    392 iscombinatorial = TRUE;
    393
    394 for( j = 0; j < nvars; ++j )
    395 {
    396 if( !SCIPvarIsIntegral(vars[j]) )
    397 {
    398 iscombinatorial = FALSE;
    399 break;
    400 }
    401 }
    402
    403 /* skip constraint, if not of interest */
    404 if( (iscombinatorial && !addcombconss) || (!iscombinatorial && !addcontconss) )
    405 continue;
    406 }
    407
    408 SCIP_CALL( SCIPcreateNlRow(scip, &nlrow, SCIPconsGetName(conss[i]), 0.0,
    409 SCIPgetNVarsLinear(scip, conss[i]), SCIPgetVarsLinear(scip, conss[i]), SCIPgetValsLinear(scip, conss[i]), NULL,
    410 SCIPgetLhsLinear(scip, conss[i]), SCIPgetRhsLinear(scip, conss[i]),
    412
    413 SCIP_CALL( SCIPaddNlRow(scip, nlrow) );
    414 SCIP_CALL( SCIPhashmapInsert(heurdata->conss2nlrow, conss[i], nlrow) );
    415 SCIP_CALL( SCIPreleaseNlRow(scip, &nlrow) );
    416 }
    417
    418 return SCIP_OKAY;
    419}
    420
    421/** adds variable bound constraints from a SCIP instance to its NLP */
    422static
    424 SCIP* scip, /**< SCIP data structure */
    425 SCIP_CONSHDLR* conshdlr, /**< constraint handler for linear constraints */
    426 SCIP_Bool addcombconss, /**< whether to add combinatorial linear constraints to NLP */
    427 SCIP_Bool addcontconss, /**< whether to add continuous linear constraints to NLP */
    428 SCIP_HEURDATA* heurdata /**< heuristic data structure */
    429 )
    430{
    431 SCIP_CONS** conss;
    432 int nconss;
    433 SCIP_NLROW* nlrow;
    434 int i;
    435 SCIP_VAR* vars[2];
    436 SCIP_Real coefs[2];
    437 SCIP_Bool iscombinatorial;
    438
    439 assert(scip != NULL);
    440 assert(conshdlr != NULL);
    441
    442 nconss = SCIPconshdlrGetNActiveConss(conshdlr);
    443 conss = SCIPconshdlrGetConss(conshdlr);
    444
    445 if( nconss == 0 )
    446 return SCIP_OKAY;
    447
    448 for( i = 0; i < nconss; ++i )
    449 {
    450 /* skip local and redundant constraints */
    451 if( !SCIPconsIsEnabled(conss[i]) || !SCIPconsIsChecked(conss[i]) )
    452 continue;
    453
    454 vars[0] = SCIPgetVarVarbound(scip, conss[i]);
    455 vars[1] = SCIPgetVbdvarVarbound(scip, conss[i]);
    456
    457 iscombinatorial = SCIPvarIsIntegral(vars[0]) && SCIPvarIsIntegral(vars[1]);
    458
    459 /* skip constraint, if not of interest */
    460 if( (iscombinatorial && !addcombconss) || (!iscombinatorial && !addcontconss) )
    461 continue;
    462
    463 coefs[0] = 1.0;
    464 coefs[1] = SCIPgetVbdcoefVarbound(scip, conss[i]);
    465
    466 SCIP_CALL( SCIPcreateNlRow(scip, &nlrow, SCIPconsGetName(conss[i]), 0.0,
    467 2, vars, coefs, NULL,
    468 SCIPgetLhsVarbound(scip, conss[i]), SCIPgetRhsVarbound(scip, conss[i]),
    470
    471 SCIP_CALL( SCIPaddNlRow(scip, nlrow) );
    472 SCIP_CALL( SCIPhashmapInsert(heurdata->conss2nlrow, conss[i], nlrow) );
    473 }
    474
    475 return SCIP_OKAY;
    476}
    477
    478
    479/** adds logic-or constraints to NLP */
    480static
    482 SCIP* scip, /**< SCIP data structure */
    483 SCIP_CONSHDLR* conshdlr, /**< constraint handler for linear constraints */
    484 SCIP_HEURDATA* heurdata /**< heuristic data structure */
    485 )
    486{
    487 SCIP_CONS** conss;
    488 int nconss;
    489 SCIP_NLROW* nlrow;
    490 int i;
    491 int j;
    492 SCIP_Real* coefs;
    493 int coefssize;
    494 int nvars;
    495
    496 assert(scip != NULL);
    497 assert(conshdlr != NULL);
    498
    499 nconss = SCIPconshdlrGetNActiveConss(conshdlr);
    500 if( !nconss )
    501 return SCIP_OKAY;
    502
    503 conss = SCIPconshdlrGetConss(conshdlr);
    504
    505 coefs = NULL;
    506 coefssize = 0;
    507
    508 for( i = 0; i < nconss; ++i )
    509 {
    510 /* skip local and redundant constraints */
    511 if( !SCIPconsIsEnabled(conss[i]) || !SCIPconsIsChecked(conss[i]) )
    512 continue;
    513
    514 nvars = SCIPgetNVarsLogicor(scip, conss[i]);
    515
    516 if( coefssize < nvars )
    517 {
    518 if( coefs == NULL )
    519 {
    520 SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nvars) );
    521 }
    522 else
    523 {
    524 SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, nvars) );
    525 }
    526 for( j = coefssize; j < nvars; ++j )
    527 coefs[j] = 1.0;
    528 coefssize = nvars;
    529 }
    530
    531 /* logic or constraints: 1 == sum_j x_j */
    532 SCIP_CALL( SCIPcreateNlRow(scip, &nlrow, SCIPconsGetName(conss[i]), 0.0,
    533 nvars, SCIPgetVarsLogicor(scip, conss[i]), coefs, NULL,
    534 1.0, SCIPinfinity(scip),
    536
    537 SCIP_CALL( SCIPaddNlRow(scip, nlrow) );
    538 SCIP_CALL( SCIPhashmapInsert(heurdata->conss2nlrow, conss[i], nlrow) );
    539 }
    540
    542
    543 return SCIP_OKAY;
    544}
    545
    546/** adds setppc constraints to NLP */
    547static
    549 SCIP* scip, /**< SCIP data structure */
    550 SCIP_CONSHDLR* conshdlr, /**< constraint handler for linear constraints */
    551 SCIP_HEURDATA* heurdata /**< heuristic data structure */
    552 )
    553{
    554 SCIP_CONS** conss;
    555 int nconss;
    556 SCIP_NLROW* nlrow;
    557 int i;
    558 int j;
    559 SCIP_Real* coefs;
    560 int coefssize;
    561 int nvars;
    562 SCIP_Real lhs;
    563 SCIP_Real rhs;
    564
    565 assert(scip != NULL);
    566 assert(conshdlr != NULL);
    567
    568 nconss = SCIPconshdlrGetNActiveConss(conshdlr);
    569 if( nconss == 0 )
    570 return SCIP_OKAY;
    571
    572 conss = SCIPconshdlrGetConss(conshdlr);
    573
    574 coefs = NULL;
    575 coefssize = 0;
    576
    577 for( i = 0; i < nconss; ++i )
    578 {
    579 /* skip local and redundant constraints */
    580 if( !SCIPconsIsEnabled(conss[i]) || !SCIPconsIsChecked(conss[i]) )
    581 continue;
    582
    583 nvars = SCIPgetNVarsSetppc(scip, conss[i]);
    584
    585 if( coefssize < nvars )
    586 {
    587 if( coefs == NULL )
    588 {
    589 SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nvars) );
    590 }
    591 else
    592 {
    593 SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, nvars) );
    594 }
    595 for( j = coefssize; j < nvars; ++j )
    596 coefs[j] = 1.0;
    597 coefssize = nvars;
    598 }
    599
    600 /* setppc constraint: 1 ~ sum_j x_j */
    601
    602 switch( SCIPgetTypeSetppc(scip, conss[i]) )
    603 {
    605 lhs = 1.0;
    606 rhs = 1.0;
    607 break;
    608
    610 lhs = -SCIPinfinity(scip);
    611 rhs = 1.0;
    612 break;
    613
    615 lhs = 1.0;
    616 rhs = SCIPinfinity(scip);
    617 break;
    618
    619 default:
    620 SCIPerrorMessage("unexpected setppc type\n");
    621 return SCIP_ERROR;
    622 }
    623
    624 SCIP_CALL( SCIPcreateNlRow(scip, &nlrow, SCIPconsGetName(conss[i]), 0.0,
    625 nvars, SCIPgetVarsSetppc(scip, conss[i]), coefs, NULL,
    626 lhs, rhs,
    628
    629 SCIP_CALL( SCIPaddNlRow(scip, nlrow) );
    630 SCIP_CALL( SCIPhashmapInsert(heurdata->conss2nlrow, conss[i], nlrow) );
    631 }
    632
    634
    635 return SCIP_OKAY;
    636}
    637
    638/** adds knapsack constraints to NLP */
    639static
    641 SCIP* scip, /**< SCIP data structure */
    642 SCIP_CONSHDLR* conshdlr, /**< constraint handler for linear constraints */
    643 SCIP_HEURDATA* heurdata /**< heuristic data structure */
    644 )
    645{
    646 SCIP_CONS** conss;
    647 int nconss;
    648 SCIP_NLROW* nlrow;
    649 int i;
    650 int j;
    651 SCIP_Real* coefs;
    652 int coefssize;
    653 int nvars;
    654
    655 assert(scip != NULL);
    656 assert(conshdlr != NULL);
    657
    658 nconss = SCIPconshdlrGetNActiveConss(conshdlr);
    659 if( nconss == 0 )
    660 return SCIP_OKAY;
    661
    662 conss = SCIPconshdlrGetConss(conshdlr);
    663 assert(conss != NULL);
    664
    665 coefs = NULL;
    666 coefssize = 0;
    667
    668 for( i = 0; i < nconss; ++i )
    669 {
    670 SCIP_Longint* weights;
    671
    672 /* skip local and redundant constraints */
    673 if( !SCIPconsIsEnabled(conss[i]) || !SCIPconsIsChecked(conss[i]) )
    674 continue;
    675
    676 nvars = SCIPgetNVarsKnapsack(scip, conss[i]);
    677
    678 if( coefssize < nvars )
    679 {
    680 if( coefs == NULL )
    681 {
    682 SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nvars) );
    683 }
    684 else
    685 {
    686 SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, nvars) );
    687 }
    688 coefssize = nvars;
    689 }
    690
    691 weights = SCIPgetWeightsKnapsack(scip, conss[i]);
    692 for( j = 0; j < nvars; ++j )
    693 coefs[j] = (SCIP_Real)weights[j]; /*lint !e613*/
    694
    695 SCIP_CALL( SCIPcreateNlRow(scip, &nlrow, SCIPconsGetName(conss[i]), 0.0,
    696 nvars, SCIPgetVarsKnapsack(scip, conss[i]), coefs, NULL,
    699
    700 SCIP_CALL( SCIPaddNlRow(scip, nlrow) );
    701 SCIP_CALL( SCIPhashmapInsert(heurdata->conss2nlrow, conss[i], nlrow) );
    702 }
    703
    705
    706 return SCIP_OKAY;
    707}
    708
    709
    710/** adds combinatorial and/or continuous variants of linear constraints from a SCIP instance to its NLP */
    711static
    713 SCIP* scip, /**< SCIP data structure */
    714 SCIP_Bool addcombconss, /**< whether to add combinatorial linear constraints to NLP */
    715 SCIP_Bool addcontconss, /**< whether to add continuous linear constraints to NLP */
    716 SCIP_HEURDATA* heurdata /**< heuristic data structure */
    717 )
    718{
    719 SCIP_CONSHDLR* conshdlr;
    720
    721 /* add linear constraints */
    722 conshdlr = SCIPfindConshdlr(scip, "linear");
    723 if( conshdlr != NULL )
    724 {
    725 SCIP_CALL( addLinearConstraints(scip, conshdlr, addcombconss, addcontconss, heurdata) );
    726 }
    727
    728 /* add varbound constraints */
    729 conshdlr = SCIPfindConshdlr(scip, "varbound");
    730 if( conshdlr != NULL )
    731 {
    732 SCIP_CALL( addVarboundConstraints(scip, conshdlr, addcombconss, addcontconss, heurdata) );
    733 }
    734
    735 if( addcombconss )
    736 {
    737 /* add logic-or constraints */
    738 conshdlr = SCIPfindConshdlr(scip, "logicor");
    739 if( conshdlr != NULL )
    740 {
    741 SCIP_CALL( addLogicOrConstraints(scip, conshdlr, heurdata) );
    742 }
    743
    744 /* add setppc constraints */
    745 conshdlr = SCIPfindConshdlr(scip, "setppc");
    746 if( conshdlr != NULL )
    747 {
    748 SCIP_CALL( addSetppcConstraints(scip, conshdlr, heurdata) );
    749 }
    750
    751 /* add knapsack constraints */
    752 conshdlr = SCIPfindConshdlr(scip, "knapsack");
    753 if( conshdlr != NULL )
    754 {
    755 SCIP_CALL( addKnapsackConstraints(scip, conshdlr, heurdata) );
    756 }
    757 }
    758
    759 return SCIP_OKAY;
    760}
    761
    762
    763
    764/** creates a SCIP_SOL in our SCIP space out of the SCIP_SOL from a sub-SCIP */
    765static
    767 SCIP* scip, /**< SCIP data structure */
    768 SCIP_HEUR* heur, /**< heuristic data structure */
    769 SCIP_SOL** sol, /**< buffer to store solution value; if pointing to NULL, a new solution
    770 * is created, otherwise values in the given one are overwritten */
    771 SCIP_SOL* subsol /**< solution of sub-SCIP */
    772 )
    773{
    774 SCIP_HEURDATA* heurdata;
    775 SCIP_VAR** vars;
    776 SCIP_VAR** subvars;
    777 SCIP_VAR* var;
    778 SCIP_VAR* subvar;
    779 SCIP_Real scalar;
    780 SCIP_Real constant;
    781 SCIP_Real val;
    782 int i;
    783 int nvars;
    784
    785 heurdata = SCIPheurGetData(heur);
    786 assert( heurdata != NULL );
    787 SCIP_CALL( SCIPgetOrigVarsData(heurdata->subscip, &subvars, &nvars, NULL, NULL, NULL, NULL) );
    788
    789 if( *sol == NULL )
    790 {
    791 SCIP_CALL( SCIPcreateOrigSol(scip, sol, heur) );
    792 }
    793
    794 vars = SCIPgetOrigVars(scip);
    795 nvars = SCIPgetNOrigVars(scip);
    796
    797 for( i = 0; i < nvars; ++i )
    798 {
    799 var = vars[i];
    800
    801 constant = 0;
    802 scalar = 1.0;
    803 var = SCIPvarGetTransVar(var);
    804 val = 0;
    805
    806 if( REALABS(scalar) > 0 )
    807 {
    808 SCIP_Real transval = 0.0;
    809
    810 subvar = (SCIP_VAR*) SCIPhashmapGetImage(heurdata->varsciptosubscip, (void*)var);
    811 if( subvar == NULL )
    812 {
    813 SCIPdebugMsg(scip, "return14 : abort building solution since a variable was not in our list\n");
    814
    815 SCIP_CALL( SCIPfreeSol(scip, sol) );
    816 return SCIP_OKAY;
    817 }
    818
    819 if( SCIPvarIsBinary(subvar) )
    820 transval = SCIPvarGetLbGlobal(subvar);
    821 else
    822 {
    823 SCIP_Real tconstant = 0.0;
    824 SCIP_Real tscalar = 1.0;
    825 SCIP_CALL( SCIPgetProbvarSum(heurdata->subscip, &subvar, &tscalar, &tconstant) );
    826
    827 transval = 0.0;
    828
    829 if( REALABS(tscalar) > 0.0 )
    830 {
    831 assert(subvar != NULL);
    832 transval = SCIPgetSolVal(heurdata->subscip, subsol, subvar);
    833 }
    834
    835 /* recompute aggregations */
    836 transval = tscalar * transval + tconstant;
    837 }
    838 val = scalar * transval + constant;
    839 }
    840 else
    841 {
    842 /* recompute aggregations */
    843 val = scalar * val + constant;
    844 }
    845
    846 assert( val != SCIP_INVALID ); /*lint !e777*/
    847 SCIP_CALL( SCIPsetSolVal(scip, *sol, vars[i], val) );
    848 }
    849
    850 return SCIP_OKAY;
    851}
    852
    853
    854
    855/** creates copy of CIP from problem in SCIP */
    856static
    858 SCIP* scip, /**< SCIP data structure */
    859 SCIP_HEURDATA* heurdata /**< heuristic data structure */
    860 )
    861{
    862 SCIP_HASHMAP* varsmap;
    863 SCIP_HASHMAP* conssmap;
    864 SCIP_CONSHDLR* conshdlrindicator;
    865 SCIP_CONSHDLR* conshdlrindi;
    866 SCIP_CONSHDLR* conshdlrlin;
    867 SCIP_CONSHDLR* conshdlrnonlin;
    868 SCIP_CONSHDLR* conshdlrvarbound;
    869 SCIP_CONSHDLR* conshdlrknapsack;
    870 SCIP_CONSHDLR* conshdlrlogicor;
    871 SCIP_CONSHDLR* conshdlrsetppc;
    872 SCIP_CONSHDLR* currentconshdlr;
    873 SCIP_CONS** conss;
    874 SCIP_CONS* subcons;
    875 SCIP_CONS* transcons;
    876 SCIP_CONS* linindicons;
    877 SCIP_CONS* indicons;
    878 SCIP_CONS* cons = NULL;
    879 SCIP_VAR** vars;
    880 SCIP_VAR** subvars;
    881 SCIP_VAR* var;
    882 SCIP_VAR* tmpvar;
    883 SCIP_VAR* subvar;
    884 SCIP_VAR* slackvarpos;
    885 SCIP_VAR* slackvarneg;
    886 SCIP_VAR* indislackvarpos;
    887 SCIP_VAR* indislackvarneg;
    888 SCIP_VAR* indicatorcopy;
    889 char probname[SCIP_MAXSTRLEN];
    890 char varname[SCIP_MAXSTRLEN];
    891 char consname[SCIP_MAXSTRLEN];
    892 SCIP_Real varobjective;
    893 int nconss;
    894 int nconsindicator;
    895 int i;
    896 int j;
    897 int k;
    898 int nvars;
    899 int ncontvars;
    900 SCIP_Bool feasible;
    901 SCIP_Bool success;
    902
    903 assert( heurdata != NULL );
    904 assert( heurdata->subscip == NULL );
    905
    906 heurdata->usedcalls = 0;
    907 heurdata->solfound = FALSE;
    908 heurdata->nonimprovingRounds = 0;
    909
    910 /* we can't change the vartype in some constraints, so we have to check that only the right constraints are present */
    911 conshdlrindi = SCIPfindConshdlr(scip, "indicator");
    912 conshdlrlin = SCIPfindConshdlr(scip, "linear");
    913 conshdlrnonlin = SCIPfindConshdlr(scip, "nonlinear");
    914 conshdlrvarbound = SCIPfindConshdlr(scip, "varbound");
    915 conshdlrknapsack = SCIPfindConshdlr(scip, "knapsack");
    916 conshdlrlogicor = SCIPfindConshdlr(scip, "logicor");
    917 conshdlrsetppc = SCIPfindConshdlr(scip, "setppc");
    918
    919 nconss = SCIPgetNOrigConss(scip);
    920 conss = SCIPgetOrigConss(scip);
    921
    922 /* for each constraint ask if it has an allowed type */
    923 for( i = 0; i < nconss; i++ )
    924 {
    925 cons = conss[i];
    926 currentconshdlr = SCIPconsGetHdlr(cons);
    927
    928 if( currentconshdlr == conshdlrindi ||
    929 currentconshdlr == conshdlrnonlin ||
    930 currentconshdlr == conshdlrvarbound ||
    931 currentconshdlr == conshdlrknapsack ||
    932 currentconshdlr == conshdlrlogicor ||
    933 currentconshdlr == conshdlrsetppc ||
    934 currentconshdlr == conshdlrlin )
    935 {
    936 continue;
    937 }
    938 else
    939 {
    940 return SCIP_OKAY;
    941 }
    942 }
    943
    944 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, &ncontvars) );
    945
    946 if( heurdata->dynamicdepth == 1 )
    947 {
    948 heurdata->maxcalls = (int)SCIPfloor(scip, sqrt((double)(nvars - ncontvars)));
    949 }
    950
    951 heurdata->triedsetupsubscip = TRUE;
    952
    953 /* initializing the subproblem */
    954 SCIP_CALL( SCIPcreate(&heurdata->subscip) );
    955
    956 /* create variable hash mapping scip -> subscip */
    957 SCIP_CALL( SCIPhashmapCreate(&varsmap, SCIPblkmem(scip), nvars) );
    958
    959 SCIP_CALL( SCIPhashmapCreate(&heurdata->switchedvars, SCIPblkmem(scip), heurdata->maxcalls) );
    960 SCIP_CALL( SCIPhashmapCreate(&heurdata->switchedvars2, SCIPblkmem(scip), heurdata->maxcalls) );
    961
    962 /* create sub-SCIP copy of CIP, copy interesting plugins */
    963 success = TRUE;
    964 SCIP_CALL( SCIPcopyPlugins(scip, heurdata->subscip, TRUE, FALSE, TRUE, FALSE, TRUE,
    965 FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, &success) );
    966
    967 if( success == FALSE )
    968 {
    969 SCIPdebugMsg(scip, "In heur_dualval: failed to copy some plugins to sub-SCIP, continue anyway\n");
    970 }
    971
    972 /* copy parameter settings */
    973 SCIP_CALL( SCIPcopyParamSettings(scip, heurdata->subscip) );
    974
    975 /* even when solving exactly, sub-SCIP heuristics should be run in floating-point mode, since the exactsol constraint
    976 * handler is in place to perform a final repair step
    977 */
    978 SCIP_CALL( SCIPenableExactSolving(heurdata->subscip, FALSE) );
    979
    980 /* disable bound limits */
    981 SCIP_CALL( SCIPsetRealParam(heurdata->subscip, "limits/primal", SCIP_INVALID) );
    982 SCIP_CALL( SCIPsetRealParam(heurdata->subscip, "limits/dual", SCIP_INVALID) );
    983
    984 /* create problem in sub-SCIP */
    985
    986 /* get name of the original problem and add "dualval" */
    987 (void) SCIPsnprintf(probname, SCIP_MAXSTRLEN, "%s_dualval", SCIPgetProbName(scip));
    988 SCIP_CALL( SCIPcreateProb(heurdata->subscip, probname, NULL, NULL, NULL, NULL, NULL, NULL, NULL) );
    989
    990 SCIP_CALL( SCIPincludeEventHdlrLPsol(heurdata->subscip, heurdata) );
    991
    992 /* copy all variables */
    993 SCIP_CALL( SCIPcopyVars(scip, heurdata->subscip, varsmap, NULL, NULL, NULL, 0, TRUE) );
    994
    995 /* copy as many constraints as possible */
    997 SCIP_CALL( SCIPcopyConss(scip, heurdata->subscip, varsmap, conssmap, TRUE, FALSE, &heurdata->subscipisvalid) );
    998
    999 SCIP_CALL( SCIPhashmapCreate(&heurdata->origsubscipConsMap, SCIPblkmem(scip), SCIPgetNConss(scip)) );
    1000
    1001 nconss = SCIPgetNOrigConss(scip);
    1002 conss = SCIPgetOrigConss(scip);
    1003
    1004 /* fill constraint mapping from original scip to the subscip */
    1005 for( i = 0; i < nconss; ++i )
    1006 {
    1007 transcons = NULL;
    1008 SCIP_CALL( SCIPgetTransformedCons(scip, conss[i], &transcons) );
    1009
    1010 subcons = (SCIP_CONS*)SCIPhashmapGetImage(conssmap, transcons);
    1011 assert( subcons != NULL );
    1012
    1013 SCIP_CALL( SCIPcaptureCons(heurdata->subscip, subcons) );
    1014 SCIP_CALL( SCIPhashmapInsert(heurdata->origsubscipConsMap, transcons, subcons) );
    1015 }
    1016
    1017 SCIP_CALL( SCIPhashmapCreate(&heurdata->conss2nlrow, SCIPblkmem(scip), SCIPgetNConss(scip)) );
    1018
    1019 if( !heurdata->subscipisvalid )
    1020 {
    1021 SCIPdebugMsg(scip, "In heur_dualval: failed to copy some constraints to sub-SCIP, continue anyway\n");
    1022 }
    1023
    1024 SCIP_CALL( SCIPgetVarsData(heurdata->subscip, &subvars, &heurdata->nsubvars, NULL, NULL, NULL, NULL) );
    1025 heurdata->nvars = nvars;
    1026
    1027 /* create hashmaps from scip transformed vars to subscip original vars, and vice versa
    1028 * capture variables in SCIP and sub-SCIP
    1029 * catch global bound change events */
    1030 SCIP_CALL( SCIPhashmapCreate(&heurdata->varsubsciptoscip, SCIPblkmem(scip), SCIPgetNOrigVars(scip)) );
    1031 SCIP_CALL( SCIPhashmapCreate(&heurdata->varsciptosubscip, SCIPblkmem(scip), SCIPgetNOrigVars(scip)) );
    1032
    1033 /* we need to get all subscip variables, also those which are copies of fixed variables from the main scip,
    1034 * therefore we iterate over the hashmap */
    1035 for( i = 0; i < SCIPhashmapGetNEntries(varsmap); ++i )
    1036 {
    1037 SCIP_HASHMAPENTRY* entry;
    1038 entry = SCIPhashmapGetEntry(varsmap, i);
    1039 if( entry != NULL )
    1040 {
    1041 var = (SCIP_VAR*) SCIPhashmapEntryGetOrigin(entry);
    1042 subvar = (SCIP_VAR*) SCIPhashmapEntryGetImage(entry);
    1043
    1044 assert( SCIPvarGetProbindex(subvar) >= 0 );
    1045 assert( SCIPvarGetProbindex(subvar) <= heurdata->nsubvars );
    1046
    1047 if( SCIPvarIsActive(var) )
    1048 {
    1049 assert( SCIPvarGetProbindex(var) <= heurdata->nvars );
    1050 /* assert that we have no mapping for this var yet */
    1051 assert( SCIPhashmapGetImage(heurdata->varsciptosubscip,var) == NULL );
    1052 SCIP_CALL( SCIPhashmapInsert(heurdata->varsciptosubscip, var, subvar) );
    1053 }
    1054
    1055 assert( SCIPhashmapGetImage(heurdata->varsubsciptoscip, subvar) == NULL );
    1056 SCIP_CALL( SCIPhashmapInsert(heurdata->varsubsciptoscip, subvar, var) );
    1057
    1058 SCIP_CALL( SCIPcaptureVar(scip, var) );
    1059 SCIP_CALL( SCIPcaptureVar(heurdata->subscip, subvar) );
    1060
    1061 assert( SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(var), SCIPvarGetLbGlobal(subvar)) );
    1062 assert( SCIPisFeasEQ(scip, SCIPvarGetUbGlobal(var), SCIPvarGetUbGlobal(subvar)) );
    1063 }
    1064 }
    1065
    1066 /* we map all slack variables of indicator constraints to their indicator variables */
    1067 conshdlrindicator = SCIPfindConshdlr(scip, "indicator");
    1068 nconsindicator = SCIPconshdlrGetNConss(conshdlrindicator);
    1069
    1070 SCIP_CALL( SCIPhashmapCreate(&heurdata->slacktoindivarsmap, SCIPblkmem(scip), nconsindicator) );
    1071 SCIP_CALL( SCIPhashmapCreate(&heurdata->indicators, SCIPblkmem(scip), nconsindicator) );
    1072 SCIP_CALL( SCIPhashmapCreate(&heurdata->indicopymap, SCIPblkmem(scip), nconsindicator) );
    1073 SCIP_CALL( SCIPhashmapCreate(&heurdata->indicopymapback, SCIPblkmem(scip), nconsindicator) );
    1074 SCIP_CALL( SCIPhashmapCreate(&heurdata->slackvarlbMap, SCIPblkmem(scip), SCIPgetNOrigVars(scip)) );
    1075 SCIP_CALL( SCIPhashmapCreate(&heurdata->slackvarubMap, SCIPblkmem(scip), SCIPgetNOrigVars(scip)) );
    1076
    1077 for( i = 0; i < nconsindicator; i++ )
    1078 {
    1079 SCIP_CONS** indicatorconss = SCIPconshdlrGetConss(conshdlrindicator);
    1080 SCIP_CONS* currcons;
    1081
    1082 currcons = indicatorconss[i];
    1083 assert(currcons != NULL);
    1084
    1085 SCIP_CALL( SCIPhashmapInsert(heurdata->slacktoindivarsmap, SCIPgetSlackVarIndicator(currcons),
    1086 SCIPgetBinaryVarIndicator(currcons)) );
    1087 SCIP_CALL( SCIPhashmapInsert(heurdata->indicators, SCIPgetBinaryVarIndicator(currcons), currcons) );
    1088 SCIP_CALL( SCIPcaptureCons(scip, currcons) );
    1090 }
    1091
    1092 /* we introduce slackvariables s+ and s- for each constraint to ensure that the problem is feasible
    1093 * we want to minimize over the sum of these variables, so set the objective to 1 */
    1094 SCIP_CALL( SCIPhashmapCreate(&heurdata->relaxcons, SCIPblkmem(scip), nvars) );
    1095 SCIP_CALL( SCIPhashmapCreate(&heurdata->relaxconsindi, SCIPblkmem(scip), nvars) );
    1096 SCIP_CALL( SCIPhashmapCreate(&heurdata->slack2var, SCIPblkmem(scip), nvars) );
    1097
    1098 vars = SCIPgetOrigVars(scip);
    1099 nvars = SCIPgetNOrigVars(scip);
    1100
    1101 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(heurdata->integervars), nvars) );
    1102 BMSclearMemoryArray(heurdata->integervars, nvars);
    1103 heurdata->integervarssize = nvars;
    1104 j = 0;
    1105
    1106 /* here we relax the variables (or indicator constraints, since indicator variables cannot be relaxed) */
    1107 for( i = 0; i < nvars; ++i )
    1108 {
    1109 var = SCIPvarGetTransVar(vars[i]);
    1110 assert( var != NULL );
    1111
    1112 if( ! SCIPvarIsActive(var) )
    1113 continue;
    1114
    1115 if( ! SCIPvarIsIntegral(var) )
    1116 continue;
    1117
    1118 heurdata->integervars[j++] = vars[i];
    1119
    1120 var = (SCIP_VAR*)SCIPhashmapGetImage(heurdata->varsciptosubscip, var);
    1121 if( var == NULL )
    1122 continue;
    1123
    1124 /* in this case our variable is an indicator variable */
    1125 if( SCIPhashmapGetImage(heurdata->indicators, SCIPhashmapGetImage(heurdata->varsubsciptoscip, var)) != NULL )
    1126 {
    1127 /* we have to find all the indicator constraints of this variable */
    1128 for( k = 0; k < nconsindicator; k++ )
    1129 {
    1130 SCIP_CONS** indicatorconss = SCIPconshdlrGetConss(conshdlrindicator);
    1131 SCIP_CONS* currcons;
    1132 SCIP_VAR* negatedvar;
    1133 SCIP_VAR* indicatorbinvar;
    1134
    1135 currcons = indicatorconss[k];
    1136 assert(currcons != NULL);
    1137
    1138 indicatorbinvar = SCIPgetBinaryVarIndicator(currcons);
    1139 assert(indicatorbinvar != NULL);
    1140
    1141 SCIP_CALL( SCIPgetNegatedVar(scip, (SCIP_VAR*)SCIPhashmapGetImage(heurdata->varsubsciptoscip, var), &negatedvar) );
    1142
    1143 if( indicatorbinvar == SCIPhashmapGetImage(heurdata->varsubsciptoscip, var) || indicatorbinvar == negatedvar )
    1144 {
    1145 /* case that we have a negated variable */
    1146 if( SCIPvarIsNegated(indicatorbinvar) )
    1147 {
    1148 assert(indicatorbinvar == negatedvar);
    1149 varobjective = SCIPvarGetObj(negatedvar);
    1150 }
    1151 else
    1152 {
    1153 assert(indicatorbinvar != negatedvar);
    1154 varobjective = SCIPvarGetObj(indicatorbinvar);
    1155 }
    1156
    1157 varobjective = heurdata->lambdaobj * REALABS(varobjective);
    1158
    1159 indicons = currcons;
    1160 assert( indicons != NULL );
    1161
    1162 indicons = (SCIP_CONS*)SCIPhashmapGetImage(conssmap, indicons);
    1163
    1164 assert( indicons != NULL );
    1165 linindicons = SCIPgetLinearConsIndicator(indicons);
    1166
    1167 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "relax_%s_pos3", SCIPconsGetName(linindicons));
    1168 SCIP_CALL( SCIPcreateVar(heurdata->subscip, &slackvarpos, varname, 0.0, SCIPinfinity(heurdata->subscip),
    1169 heurdata->lambdaslack *100 + varobjective, SCIP_VARTYPE_CONTINUOUS, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
    1170 SCIP_CALL( SCIPaddVar(heurdata->subscip, slackvarpos) );
    1171
    1172 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "relax_%s_neg3", SCIPconsGetName(linindicons));
    1173 SCIP_CALL( SCIPcreateVar(heurdata->subscip, &slackvarneg, varname, 0.0, SCIPinfinity(heurdata->subscip),
    1174 heurdata->lambdaslack * 100 + varobjective, SCIP_VARTYPE_CONTINUOUS, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
    1175 SCIP_CALL( SCIPaddVar(heurdata->subscip, slackvarneg) );
    1176
    1177 /* make a copy of the indicator to relax it if this parameter is set true */
    1178 if( heurdata->relaxindicators )
    1179 {
    1180 SCIP_CONS* imagecons;
    1181
    1182 indicatorbinvar = SCIPgetBinaryVarIndicator(indicons);
    1183
    1184 SCIP_CALL( SCIPgetNegatedVar(heurdata->subscip, indicatorbinvar, &negatedvar) );
    1185
    1186 if( SCIPhashmapGetImage(heurdata->indicopymap, indicatorbinvar) == NULL &&
    1187 SCIPhashmapGetImage(heurdata->indicopymap, negatedvar) == NULL)
    1188 {
    1189 SCIP_Bool negated = FALSE;
    1190
    1191 if (SCIPvarIsNegated(indicatorbinvar))
    1192 {
    1193 indicatorbinvar = negatedvar;
    1194 negated = TRUE;
    1195 }
    1196
    1197 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "indicopy_%s", SCIPvarGetName(indicatorbinvar));
    1198 SCIP_CALL( SCIPcreateVar(heurdata->subscip, &indicatorcopy, varname, SCIPvarGetLbGlobal(indicatorbinvar), SCIPvarGetUbGlobal(indicatorbinvar),
    1199 SCIPvarGetObj(indicatorbinvar), SCIP_VARTYPE_BINARY, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
    1200
    1201 SCIP_CALL( SCIPaddVar(heurdata->subscip, indicatorcopy) );
    1202
    1203 SCIP_CALL( SCIPhashmapInsert(heurdata->indicopymap, indicatorbinvar, indicatorcopy) );
    1204 SCIP_CALL( SCIPhashmapInsert(heurdata->indicopymapback, indicatorcopy, indicatorbinvar) );
    1205 SCIP_CALL( SCIPcaptureVar(heurdata->subscip, indicatorbinvar) );
    1206
    1207 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "relax_%s_pos1", SCIPvarGetName(indicatorbinvar));
    1208 SCIP_CALL( SCIPcreateVar(heurdata->subscip, &indislackvarpos, varname, 0.0, SCIPinfinity(heurdata->subscip),
    1209 heurdata->lambdaslack * 100 + varobjective, SCIP_VARTYPE_CONTINUOUS, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
    1210 SCIP_CALL( SCIPaddVar(heurdata->subscip, indislackvarpos) );
    1211
    1212 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "relax_%s_neg1", SCIPvarGetName(indicatorbinvar));
    1213 SCIP_CALL( SCIPcreateVar(heurdata->subscip, &indislackvarneg, varname, 0.0, SCIPinfinity(heurdata->subscip),
    1214 heurdata->lambdaslack * 100 + varobjective, SCIP_VARTYPE_CONTINUOUS, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
    1215 SCIP_CALL( SCIPaddVar(heurdata->subscip, indislackvarneg) );
    1216
    1217 /* create linking constraint */
    1218 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "linking_%s", SCIPvarGetName(indicatorbinvar));
    1219 cons = NULL;
    1220 SCIP_CALL( SCIPcreateConsLinear( heurdata->subscip, &cons, consname, 0, NULL, NULL, 0.0, 0.0,
    1222 SCIP_CALL( SCIPaddCoefLinear(heurdata->subscip, cons, indicatorbinvar, 1.0) );
    1223 SCIP_CALL( SCIPaddCoefLinear(heurdata->subscip, cons, indicatorcopy, -1.0) );
    1224 SCIP_CALL( SCIPaddCoefLinear(heurdata->subscip, cons, indislackvarpos, 1.0) );
    1225 SCIP_CALL( SCIPaddCoefLinear(heurdata->subscip, cons, indislackvarneg, -1.0) );
    1226
    1227 SCIP_CALL( SCIPhashmapInsert(heurdata->relaxconsindi, indicatorbinvar, cons) );
    1228 SCIP_CALL( SCIPhashmapInsert(heurdata->relaxconsindi, indicatorcopy, cons) );
    1229
    1230 SCIP_CALL( SCIPaddCons(heurdata->subscip, cons) );
    1231 SCIP_CALL( SCIPcaptureCons(heurdata->subscip, cons) );
    1232
    1233 assert( SCIPhashmapGetImage(heurdata->indicopymap, indicatorbinvar) != NULL );
    1234
    1235 if ( negated )
    1236 {
    1237 SCIP_CALL( SCIPgetNegatedVar(heurdata->subscip, indicatorcopy, &indicatorcopy) );
    1238 }
    1239
    1240 SCIP_CALL( SCIPchgVarType(heurdata->subscip, indicatorbinvar, SCIP_VARTYPE_CONTINUOUS, &feasible) );
    1241
    1242 SCIP_CALL( SCIPhashmapInsert(heurdata->slack2var, indislackvarpos, var) );
    1243 SCIP_CALL( SCIPhashmapInsert(heurdata->slack2var, indislackvarneg, var) );
    1244 SCIP_CALL( SCIPcaptureVar(heurdata->subscip, var) );
    1245 SCIP_CALL( SCIPcaptureVar(heurdata->subscip, var) );
    1246 SCIP_CALL( SCIPreleaseVar(heurdata->subscip, &indislackvarpos) );
    1247 SCIP_CALL( SCIPreleaseVar(heurdata->subscip, &indislackvarneg) );
    1248 }
    1249 else
    1250 {
    1251 if (!SCIPvarIsNegated(indicatorbinvar))
    1252 indicatorcopy = (SCIP_VAR*)SCIPhashmapGetImage(heurdata->indicopymap, indicatorbinvar);
    1253 else
    1254 {
    1255 indicatorcopy = (SCIP_VAR*)SCIPhashmapGetImage(heurdata->indicopymap, negatedvar);
    1256 SCIP_CALL( SCIPgetNegatedVar(heurdata->subscip, indicatorcopy, &indicatorcopy) );
    1257 }
    1258 }
    1259
    1260 cons = NULL;
    1261 SCIP_CALL( SCIPcreateConsIndicatorLinCons(heurdata->subscip, &cons, SCIPconsGetName(indicons), indicatorcopy,
    1263 SCIPconsIsSeparated(indicons), SCIPconsIsEnforced(indicons), SCIPconsIsChecked(indicons),
    1264 SCIPconsIsPropagated(indicons), SCIPconsIsLocal(indicons), SCIPconsIsDynamic(indicons),
    1265 SCIPconsIsRemovable(indicons), SCIPconsIsStickingAtNode(indicons)) );
    1266 SCIP_CALL( SCIPaddCons(heurdata->subscip, cons) );
    1267
    1268 /* delete old indicator constraints so we can relax the indicator variables */
    1269 imagecons = (SCIP_CONS*) SCIPhashmapGetImage(heurdata->origsubscipConsMap, (void*)(currcons));
    1270 assert(imagecons != NULL);
    1271 SCIP_CALL( SCIPreleaseCons(heurdata->subscip, &imagecons) );
    1272 SCIP_CALL( SCIPhashmapRemove(heurdata->origsubscipConsMap, currcons) );
    1273 SCIP_CALL( SCIPhashmapInsert(heurdata->origsubscipConsMap, currcons, cons) );
    1275 SCIP_CALL( SCIPdelCons(heurdata->subscip, indicons) );
    1276 }
    1277
    1278 SCIP_CALL( SCIPhashmapInsert(heurdata->slack2var, slackvarpos, var) );
    1279 SCIP_CALL( SCIPhashmapInsert(heurdata->slack2var, slackvarneg, var) );
    1280 SCIP_CALL( SCIPcaptureVar(heurdata->subscip, var) );
    1281 SCIP_CALL( SCIPcaptureVar(heurdata->subscip, var) );
    1282
    1283 SCIP_CALL( SCIPaddCoefLinear(heurdata->subscip, linindicons, slackvarpos, 1.0) );
    1284 SCIP_CALL( SCIPaddCoefLinear(heurdata->subscip, linindicons, slackvarneg, -1.0) );
    1285 SCIP_CALL( SCIPreleaseVar(heurdata->subscip, &slackvarpos) );
    1286 SCIP_CALL( SCIPreleaseVar(heurdata->subscip, &slackvarneg) );
    1287 }
    1288 }
    1289 continue;
    1290 }
    1291
    1292 if( heurdata->relaxindicators )
    1293 {
    1294 /* relax the old indicator variables*/
    1295 for( k = 0; k < nvars; k++ )
    1296 {
    1297 if( SCIPhashmapGetImage(heurdata->indicators, vars[k]) == NULL )
    1298 continue;
    1299
    1300 tmpvar = (SCIP_VAR*)SCIPhashmapGetImage(heurdata->varsciptosubscip, vars[k]);
    1301 SCIP_CALL( SCIPchgVarType(heurdata->subscip, tmpvar, SCIP_VARTYPE_CONTINUOUS, &feasible) );
    1302 SCIP_CALL( SCIPchgVarLbGlobal(heurdata->subscip, tmpvar, -SCIPinfinity(heurdata->subscip)) );
    1303 SCIP_CALL( SCIPchgVarUbGlobal(heurdata->subscip, tmpvar, SCIPinfinity(heurdata->subscip)) );
    1304 }
    1305
    1306 /* we map all slack variables of indicator constraints to their indicator variables */
    1307 conshdlrindicator = SCIPfindConshdlr(scip, "indicator");
    1308 nconsindicator = SCIPconshdlrGetNConss(conshdlrindicator);
    1309
    1310 /* delete old hashmaps and fill with the new indicators*/
    1311 SCIP_CALL( releaseHashmapEntries(scip, heurdata->slacktoindivarsmap, TRUE) );
    1312 SCIP_CALL( releaseHashmapEntries(scip, heurdata->indicators, FALSE) );
    1313 SCIP_CALL( SCIPhashmapRemoveAll(heurdata->slacktoindivarsmap) );
    1314 SCIP_CALL( SCIPhashmapRemoveAll(heurdata->indicators) );
    1315
    1316 /* fill hashmaps with new values */
    1317 for( k = 0; k < nconsindicator; k++ )
    1318 {
    1319 SCIP_CONS** indicatorconss = SCIPconshdlrGetConss(conshdlrindicator);
    1320 SCIP_CONS* currcons;
    1321
    1322 currcons = indicatorconss[k];
    1323 assert(currcons != NULL);
    1324
    1326 SCIP_CALL( SCIPcaptureCons(scip, currcons) );
    1327
    1328 SCIP_CALL( SCIPhashmapInsert(heurdata->slacktoindivarsmap, SCIPgetSlackVarIndicator(currcons),
    1329 SCIPgetBinaryVarIndicator(currcons)) );
    1330 SCIP_CALL( SCIPhashmapInsert(heurdata->indicators, SCIPgetBinaryVarIndicator(currcons), currcons) );
    1331 }
    1332 }
    1333
    1334 /* in this case, we have a normal variable */
    1335 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "relax_%s", SCIPvarGetName(var));
    1336 cons = NULL;
    1337 SCIP_CALL( SCIPcreateConsLinear( heurdata->subscip, &cons, consname, 0, NULL, NULL, 0.0, 0.0,
    1339
    1340 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "relax_%s_pos0", SCIPvarGetName(var));
    1341 SCIP_CALL( SCIPcreateVar( heurdata->subscip, &slackvarpos, varname, 0.0, SCIPinfinity(heurdata->subscip),
    1342 heurdata->lambdaslack * 100, SCIP_VARTYPE_CONTINUOUS, TRUE, FALSE, NULL, NULL, NULL, NULL,NULL) );
    1343 SCIP_CALL( SCIPaddVar(heurdata->subscip, slackvarpos) );
    1344
    1345 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "relax_%s_neg0", SCIPvarGetName(var));
    1346 SCIP_CALL( SCIPcreateVar(heurdata->subscip, &slackvarneg, varname, 0.0, SCIPinfinity(heurdata->subscip),
    1347 heurdata->lambdaslack * 100, SCIP_VARTYPE_CONTINUOUS, TRUE, FALSE, NULL, NULL, NULL, NULL,NULL) );
    1348 SCIP_CALL( SCIPaddVar(heurdata->subscip, slackvarneg) );
    1349
    1350 SCIP_CALL( SCIPaddCoefLinear(heurdata->subscip, cons, var, 1.0) );
    1351 SCIP_CALL( SCIPaddCoefLinear(heurdata->subscip, cons, slackvarpos, 1.0) );
    1352 SCIP_CALL( SCIPaddCoefLinear(heurdata->subscip, cons, slackvarneg, -1.0) );
    1353
    1354 SCIP_CALL( SCIPaddCons(heurdata->subscip, cons) );
    1355
    1356 SCIP_CALL( SCIPhashmapInsert(heurdata->slack2var, slackvarpos, var) );
    1357 SCIP_CALL( SCIPhashmapInsert(heurdata->slack2var, slackvarneg, var) );
    1358 SCIP_CALL( SCIPcaptureVar(heurdata->subscip, var) );
    1359 SCIP_CALL( SCIPcaptureVar(heurdata->subscip, var) );
    1360 SCIP_CALL( SCIPhashmapInsert(heurdata->relaxcons, var, cons) );
    1361 SCIP_CALL( SCIPreleaseVar(heurdata->subscip, &slackvarpos) );
    1362 SCIP_CALL( SCIPreleaseVar(heurdata->subscip, &slackvarneg) );
    1363
    1364 /* if the var is no indicator, relax it to a continuous variable */
    1365 if( SCIPhashmapGetImage(heurdata->indicators, SCIPhashmapGetImage(heurdata->varsubsciptoscip, var)) == NULL )
    1366 {
    1367 SCIP_CALL( SCIPchgVarType(heurdata->subscip, var, SCIP_VARTYPE_CONTINUOUS, &feasible) );
    1368 SCIP_CALL( SCIPchgVarLbGlobal(heurdata->subscip, var, -SCIPinfinity(heurdata->subscip)) );
    1369 SCIP_CALL( SCIPchgVarUbGlobal(heurdata->subscip, var, SCIPinfinity(heurdata->subscip)) );
    1370 }
    1371 }
    1372
    1373 /* set up relaxation constraints for continuous variables */
    1374 if( heurdata->relaxcontvars )
    1375 {
    1376 for( i = 0; i < nvars; ++i )
    1377 {
    1378 var = SCIPvarGetTransVar(vars[i]);
    1379 assert( var != NULL );
    1380
    1381 if( ! SCIPvarIsActive(var) )
    1382 continue;
    1383
    1384 if( SCIPvarIsIntegral(var) )
    1385 continue;
    1386
    1388 continue;
    1389
    1391 continue;
    1392
    1393 var = (SCIP_VAR*)SCIPhashmapGetImage(heurdata->varsciptosubscip, var);
    1394 if( var == NULL )
    1395 continue;
    1396
    1397 /* in this case, we have a normal variable */
    1398 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "relax_ub_%s", SCIPvarGetName(var));
    1399 cons = NULL;
    1400 SCIP_CALL( SCIPcreateConsLinear( heurdata->subscip, &cons, consname, 0, NULL, NULL, -SCIPinfinity(heurdata->subscip), SCIPvarGetUbGlobal(var),
    1402
    1403 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "relax_%s_pos2", SCIPvarGetName(var));
    1404 SCIP_CALL( SCIPcreateVar( heurdata->subscip, &slackvarpos, varname, 0.0, SCIPinfinity(heurdata->subscip),
    1405 heurdata->lambdaslack, SCIP_VARTYPE_CONTINUOUS, TRUE, FALSE, NULL, NULL, NULL, NULL,NULL) );
    1406 SCIP_CALL( SCIPaddVar(heurdata->subscip, slackvarpos) );
    1407
    1408 SCIP_CALL( SCIPaddCoefLinear(heurdata->subscip, cons, var, 1.0) );
    1409 SCIP_CALL( SCIPaddCoefLinear(heurdata->subscip, cons, slackvarpos, -1.0) );
    1410
    1411 SCIP_CALL( SCIPaddCons(heurdata->subscip, cons) );
    1412 SCIP_CALL( SCIPreleaseCons(heurdata->subscip, &cons) );
    1413 SCIP_CALL( SCIPhashmapInsert(heurdata->slackvarubMap, var, slackvarpos) );
    1414 SCIP_CALL( SCIPhashmapInsert(heurdata->slack2var, slackvarpos, var) );
    1415 SCIP_CALL( SCIPcaptureVar(heurdata->subscip, var) );
    1416
    1417 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "relax_lb_%s", SCIPvarGetName(var));
    1418 cons = NULL;
    1419 SCIP_CALL( SCIPcreateConsLinear( heurdata->subscip, &cons, consname, 0, NULL, NULL, SCIPvarGetLbGlobal(var), SCIPinfinity(heurdata->subscip),
    1421
    1422 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "relax_%s_neg2", SCIPvarGetName(var));
    1423 SCIP_CALL( SCIPcreateVar( heurdata->subscip, &slackvarneg, varname, 0.0, SCIPinfinity(heurdata->subscip),
    1424 heurdata->lambdaslack, SCIP_VARTYPE_CONTINUOUS, TRUE, FALSE, NULL, NULL, NULL, NULL,NULL) );
    1425 SCIP_CALL( SCIPaddVar(heurdata->subscip, slackvarneg) );
    1426
    1427 SCIP_CALL( SCIPaddCoefLinear(heurdata->subscip, cons, var, 1.0) );
    1428 SCIP_CALL( SCIPaddCoefLinear(heurdata->subscip, cons, slackvarneg, 1.0) );
    1429
    1430 SCIP_CALL( SCIPaddCons(heurdata->subscip, cons) );
    1431 SCIP_CALL( SCIPreleaseCons(heurdata->subscip, &cons) );
    1432 SCIP_CALL( SCIPhashmapInsert(heurdata->slackvarlbMap, var, slackvarneg) );
    1433 SCIP_CALL( SCIPhashmapInsert(heurdata->slack2var, slackvarneg, var) );
    1434 SCIP_CALL( SCIPcaptureVar(heurdata->subscip, var) );
    1435
    1436 SCIP_CALL( SCIPchgVarLbGlobal(heurdata->subscip, var, -SCIPinfinity(heurdata->subscip)) );
    1437 SCIP_CALL( SCIPchgVarUbGlobal(heurdata->subscip, var, SCIPinfinity(heurdata->subscip)) );
    1438 }
    1439 }
    1440
    1441 /* if we have a solution add constraint that the next solution must not be worse than the current one */
    1442 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "objbound");
    1443 SCIP_CALL( SCIPcreateConsLinear( heurdata->subscip, &cons, consname, 0, NULL, NULL, -SCIPinfinity(scip),
    1445 heurdata->objbound = cons;
    1446
    1447 for( i = 0; i < nvars; ++i )
    1448 {
    1449 var = SCIPvarGetTransVar(vars[i]);
    1450 assert( var != NULL );
    1451
    1452 if( !SCIPvarIsActive(var) )
    1453 continue;
    1454
    1455 subvar = (SCIP_VAR*)SCIPhashmapGetImage(heurdata->varsciptosubscip, var);
    1456 if( subvar == NULL )
    1457 continue;
    1458
    1459 SCIP_CALL( SCIPaddCoefLinear(heurdata->subscip, cons, subvar, SCIPvarGetObj(var)) );
    1460
    1461 SCIP_CALL( SCIPchgVarObj(heurdata->subscip, subvar, heurdata->lambdaobj * SCIPvarGetObj(subvar) ) );
    1462 }
    1463
    1464 SCIP_CALL( SCIPaddCons(heurdata->subscip, cons) );
    1465 SCIP_CALL( SCIPreleaseCons(heurdata->subscip, &cons) );
    1466
    1467 /* do not need varsmap and conssmap anymore */
    1468 SCIPhashmapFree(&conssmap);
    1469 SCIPhashmapFree(&varsmap);
    1470
    1471 /* enable SCIP output if needed */
    1472 if( heurdata->heurverblevel > 3 )
    1473 {
    1474 SCIP_CALL( SCIPsetIntParam(heurdata->subscip, "display/verblevel", 4) );
    1475 }
    1476 else
    1477 {
    1478 SCIP_CALL( SCIPsetIntParam(heurdata->subscip, "display/verblevel", 0) );
    1479 }
    1480
    1481 heurdata->nintegervars = j;
    1482
    1483 return SCIP_OKAY;
    1484}
    1485
    1486
    1487/** free sub-SCIP data structure */
    1488static
    1490 SCIP* scip, /**< SCIP data structure */
    1491 SCIP_HEURDATA* heurdata /**< heuristic data structure */
    1492 )
    1493{
    1494 assert(scip != NULL);
    1495 assert(heurdata != NULL);
    1496 assert(heurdata->subscip != NULL);
    1497
    1498 heurdata->nsubvars = 0;
    1499 heurdata->nvars = 0;
    1500
    1501 /* free sub-SCIP */
    1502 SCIP_CALL( SCIPfree(&heurdata->subscip) );
    1503
    1504 return SCIP_OKAY;
    1505}
    1506
    1507
    1508/** create a solution from the values of current nonlinear program */
    1509static
    1511 SCIP* scip, /**< SCIP data structure */
    1512 SCIP_HEUR* heur, /**< heuristic data structure */
    1513 SCIP_SOL** sol /**< buffer to store solution value; if pointing to NULL a new solution is
    1514 * created, otherwise values in the given one are overwritten */
    1515 )
    1516{
    1517 SCIP_HEURDATA* heurdata;
    1518 SCIP_VAR** subvars;
    1519 SCIP_VAR* subvar;
    1520 int i;
    1521 int nsubvars;
    1522
    1523 assert(scip != NULL);
    1524 assert(heur != NULL);
    1525 assert(sol != NULL);
    1526
    1527 heurdata = SCIPheurGetData(heur);
    1528 assert(heurdata != NULL);
    1529
    1530 if( *sol == NULL )
    1531 {
    1532 SCIP_CALL( SCIPcreateSol(scip, sol, heur) );
    1533 }
    1534
    1535 /* sub-SCIP may have more variables than the number of active (transformed) variables in the main SCIP
    1536 * since constraint copying may have required the copy of variables that are fixed in the main SCIP */
    1537 assert(heurdata->nsubvars <= SCIPgetNOrigVars(heurdata->subscip));
    1538
    1539 SCIP_CALL( SCIPgetOrigVarsData(heurdata->subscip, &subvars, &nsubvars, NULL, NULL, NULL, NULL) );
    1540
    1541 /* set solution values */
    1542 for( i = 0; i < nsubvars; ++i )
    1543 {
    1544 subvar = subvars[i];
    1545 assert(subvar != NULL);
    1546
    1547 subvar = SCIPvarGetTransVar(subvar);
    1548
    1549 if( !SCIPvarIsActive(subvar) )
    1550 continue;
    1551
    1552 assert(SCIPvarGetNLPSol(subvar) != SCIP_INVALID);/*lint !e777*/
    1553 SCIP_CALL( SCIPsetSolVal(scip, *sol, subvar, SCIPvarGetNLPSol(subvar)) );
    1554 }
    1555
    1556 return SCIP_OKAY;
    1557}
    1558
    1559#define BIG_VALUE 1E+10
    1560
    1561/** method to fix the (relaxed) discrete variables */
    1562static
    1564 SCIP* scip, /**< SCIP data structure */
    1565 SCIP_HEURDATA* heurdata, /**< heuristic data structure */
    1566 SCIP_SOL* refpoint, /**< point to take fixation of discrete variables from;
    1567 * if NULL, then LP solution is used */
    1568 SCIP_SOL** transsol /**< pointer to new created solution with fixed values as solution value */
    1569 )
    1570{
    1571 SCIP_Real fixval;
    1572 SCIP_VAR* var;
    1573 SCIP_VAR* subvar;
    1574 SCIP_CONS* rcons;
    1575 int i;
    1576
    1577 SCIP_CALL( SCIPcreateOrigSol(scip, transsol, NULL) );
    1578
    1579 /* fix discrete variables */
    1580 for( i = 0; i < heurdata->nintegervars; i++ )
    1581 {
    1582 var = heurdata->integervars[i];
    1583 assert(var != NULL);
    1584
    1585 var = SCIPvarGetTransVar(var);
    1586 assert(var != NULL);
    1587 subvar = (SCIP_VAR*)SCIPhashmapGetImage(heurdata->varsciptosubscip, var);
    1588
    1589 if( subvar == NULL )
    1590 continue;
    1591
    1592 if ( SCIPhashmapGetImage(heurdata->indicopymap, subvar) != NULL )
    1593 subvar = (SCIP_VAR*)SCIPhashmapGetImage(heurdata->indicopymap, subvar);
    1594
    1595 /* if we do not really have a startpoint, we set to 0.0 here and project on bounds below */
    1596 if( refpoint == NULL && SCIPgetLPSolstat(scip) != SCIP_LPSOLSTAT_OPTIMAL )
    1597 fixval = 0.0;
    1598 else
    1599 {
    1600 /* get value of the variables (NULL as refpoint gives the current LP solution, otherwise the start point) */
    1601 fixval = SCIPgetSolVal(scip, refpoint, heurdata->integervars[i]);
    1602
    1603 /* take care that we do not fix variables to very large values (project on bounds below) */
    1604 if( REALABS(fixval) > BIG_VALUE )
    1605 fixval = 0.0;
    1606 else
    1607 {
    1608 /* round fractional variables to the nearest integer, use exact integral value, if the variable is only
    1609 * integral within numerical tolerances */
    1610 fixval = SCIPfloor(scip, fixval + 0.5);
    1611 }
    1612 }
    1613
    1614 /* adjust value to the global bounds of the corresponding SCIP variable */
    1615 fixval = MAX(fixval, SCIPvarGetLbGlobal(heurdata->integervars[i])); /*lint !e666*/
    1616 fixval = MIN(fixval, SCIPvarGetUbGlobal(heurdata->integervars[i])); /*lint !e666*/
    1617
    1618 SCIP_CALL( SCIPsetSolVal(scip, *transsol, heurdata->integervars[i], fixval) );
    1619
    1620 /* adjust the relaxation constraints to the new fixval */
    1621 rcons = (SCIP_CONS*) SCIPhashmapGetImage(heurdata->relaxcons, subvar);
    1622
    1623 fixval = MAX(fixval, SCIPvarGetLbGlobal(subvar));/*lint !e666*/
    1624 fixval = MIN(fixval, SCIPvarGetUbGlobal(subvar));/*lint !e666*/
    1625 if( rcons == NULL )
    1626 {
    1627 SCIP_CALL( SCIPchgVarLbGlobal(heurdata->subscip, subvar, fixval) );
    1628 SCIP_CALL( SCIPchgVarUbGlobal(heurdata->subscip, subvar, fixval) );
    1629 continue;
    1630 }
    1631
    1632 SCIP_CALL( SCIPchgLhsLinear(heurdata->subscip, rcons, fixval) );
    1633 SCIP_CALL( SCIPchgRhsLinear(heurdata->subscip, rcons, fixval) );
    1634 }
    1635
    1636 return SCIP_OKAY;
    1637}
    1638
    1639/** method to free memory before leaving the heuristic or jumping up in the recursion */
    1640static
    1642 SCIP* scip, /**< scip data structure */
    1643 SCIP_HEURDATA* heurdata, /**< heuristic data structure */
    1644 SCIP_SOL* transsol, /**< sol that has to be freed */
    1645 SCIP_Real* absranks, /**< array of absolute rank values */
    1646 SCIP_Real* ranks, /**< array of rank values */
    1647 SCIP_VAR** sortedvars, /**< array of corresponding variables */
    1648 SCIP_Bool beforeswitching, /**< did we call this method before or after switching variables? */
    1649 SCIP_Bool clearswitchedvars /**< says if we should clear switchedvars or not */
    1650 )
    1651{
    1652 SCIP_VAR** subvars;
    1653 SCIP_VAR* subvar;
    1654 SCIP_VAR* var;
    1655 SCIP_Real* val;
    1656 int nsubvars;
    1657 int nsubbinvars;
    1658 int nsubintvars;
    1659 int i;
    1660
    1661 if( clearswitchedvars )
    1662 {
    1663 /* free memory of the solution values in the hashmaps */
    1664 for( i = 0; i < heurdata->nintegervars; i++ )
    1665 {
    1666 var = heurdata->integervars[i];
    1667
    1668 if( SCIPhashmapGetImage(heurdata->slacktoindivarsmap, var) != NULL )
    1669 var = (SCIP_VAR*)SCIPhashmapGetImage(heurdata->slacktoindivarsmap, var);
    1670
    1671 val = (SCIP_Real*)SCIPhashmapGetImage(heurdata->switchedvars, var);
    1672 if( val != NULL )
    1673 {
    1674 SCIPfreeBlockMemoryArray(heurdata->subscip, &val, 1);
    1675 }
    1676
    1677 val = (SCIP_Real*)SCIPhashmapGetImage(heurdata->switchedvars2, var);
    1678 if( val != NULL )
    1679 {
    1680 SCIPfreeBlockMemoryArray(heurdata->subscip, &val, 1);
    1681 }
    1682 }
    1683
    1684 SCIP_CALL( SCIPhashmapRemoveAll(heurdata->switchedvars) );
    1685 SCIP_CALL( SCIPhashmapRemoveAll(heurdata->switchedvars2) );
    1686 }
    1687
    1688 SCIPfreeBufferArrayNull( scip, &ranks );
    1689 SCIPfreeBufferArrayNull( scip, &absranks );
    1690 SCIPfreeBufferArrayNull( scip, &sortedvars );
    1691
    1692 if( transsol != NULL )
    1693 {
    1694 SCIP_CALL( SCIPfreeSol(scip, &transsol) );
    1695 }
    1696
    1697 if( beforeswitching )
    1698 {
    1699 SCIP_CALL( SCIPfreeTransform(heurdata->subscip) );
    1700 }
    1701
    1702 /* undo fixing of discrete variables in sub-SCIP */
    1703 SCIP_CALL( SCIPgetOrigVarsData(heurdata->subscip, &subvars, &nsubvars, &nsubbinvars, &nsubintvars, NULL, NULL) );
    1704
    1705 /* set bounds of discrete variables to original values */
    1706 for( i = nsubbinvars + nsubintvars - 1; i >= 0; --i )
    1707 {
    1708 subvar = subvars[i];
    1709 assert(SCIPvarGetProbindex(subvar) == i);
    1710
    1711 var = (SCIP_VAR*)SCIPhashmapGetImage(heurdata->varsubsciptoscip, subvar);
    1712
    1713 if (SCIPhashmapGetImage(heurdata->indicopymapback, subvar) != NULL)
    1714 var = (SCIP_VAR*)SCIPhashmapGetImage(heurdata->varsubsciptoscip, SCIPhashmapGetImage(heurdata->indicopymapback, subvar));
    1715
    1716 assert(var != NULL);
    1717
    1718 SCIP_CALL( SCIPchgVarLbGlobal(heurdata->subscip, subvar, SCIPvarGetLbGlobal(var)) );
    1719 SCIP_CALL( SCIPchgVarUbGlobal(heurdata->subscip, subvar, SCIPvarGetUbGlobal(var)) );
    1720 }
    1721
    1722 return SCIP_OKAY;
    1723}
    1724
    1725/** computes the ranks, saves them into an array and sorts the variables according to absolute ranks */
    1726static
    1728 SCIP* scip, /**< scip data structure */
    1729 SCIP_HEURDATA* heurdata, /**< heuristic data structure */
    1730 SCIP_Real* absranks, /**< array of absolute rank values */
    1731 SCIP_Real* ranks, /**< array of rank values */
    1732 SCIP_VAR** sortedvars /**< array of corresponding variables */
    1733 )
    1734{
    1735 SCIP_CONSHDLR* conshdlrindicator;
    1736 SCIP_CONS* relaxcons;
    1737 SCIP_CONS* indicons;
    1738 SCIP_CONS* subcons;
    1739 SCIP_CONS* transcons;
    1740 SCIP_VAR* var;
    1741 SCIP_Real* dualvalue;
    1742 int nconsindicator;
    1743 int j;
    1744 int k;
    1745
    1746 conshdlrindicator = SCIPfindConshdlr(scip, "indicator");
    1747 nconsindicator = SCIPconshdlrGetNConss(conshdlrindicator);
    1748
    1749 /* Now we compute the rank of each variable */
    1750 for( j = 0; j < heurdata->nintegervars; j++ )
    1751 {
    1752 sortedvars[j] = heurdata->integervars[j];
    1753 ranks[j] = 0;
    1754 absranks[j] = 0;
    1755
    1756 if( sortedvars[j] == NULL )
    1757 break;
    1758
    1759 var = SCIPvarGetTransVar(sortedvars[j]);
    1760 assert(var != NULL);
    1761
    1762 /* globally fixed variables get rank 0 */
    1764 {
    1765 ranks[j] = 0;
    1766 continue;
    1767 }
    1768 else
    1769 {
    1770 var = (SCIP_VAR*)SCIPhashmapGetImage(heurdata->varsciptosubscip, var);
    1771 assert(var != NULL);
    1772 relaxcons = (SCIP_CONS*)SCIPhashmapGetImage(heurdata->relaxcons, (void*)(var));
    1773
    1774 /* get ranks */
    1775 if( relaxcons != NULL )
    1776 {
    1777 SCIP_CALL( SCIPgetTransformedCons(heurdata->subscip, relaxcons, &transcons) );
    1778 dualvalue = (SCIP_Real*)SCIPhashmapGetImage(heurdata->dualvalues, (void*)transcons);
    1779
    1780 if( dualvalue == NULL )
    1781 dualvalue = (SCIP_Real*)SCIPhashmapGetImage(heurdata->dualvalues, (void*)(relaxcons));
    1782
    1783 if( dualvalue == NULL )
    1784 continue;
    1785
    1786 assert(dualvalue != NULL);
    1787 ranks[j] = (*dualvalue);
    1788 }
    1789 else /* if we have an indicator variable */
    1790 {
    1791 assert(ranks[j] == 0.0);
    1792
    1793 if (SCIPhashmapGetImage(heurdata->relaxconsindi, (void*)(var)) != NULL)
    1794 {
    1795 subcons = (SCIP_CONS*)SCIPhashmapGetImage(heurdata->relaxconsindi, (void*)(var));
    1796
    1797 dualvalue = (SCIP_Real*)SCIPhashmapGetImage(heurdata->dualvalues, (void*)(subcons));
    1798
    1799 if( dualvalue == NULL )
    1800 continue;
    1801
    1802 assert(dualvalue != NULL);
    1803
    1804 ranks[j] = (*dualvalue);
    1805 }
    1806
    1807 /* compute the rank of the indicators, we take the highest dualvalue of an indicator constraint */
    1808 for( k = 0; k < nconsindicator; k++ )
    1809 {
    1810 SCIP_CONS** indicatorconss = SCIPconshdlrGetConss(conshdlrindicator);
    1811 SCIP_CONS* currcons;
    1812 SCIP_VAR* indicatorbinvar;
    1813
    1814 currcons = indicatorconss[k];
    1815 assert(currcons != NULL);
    1816
    1817 indicatorbinvar = SCIPgetBinaryVarIndicator(currcons);
    1818 assert(indicatorbinvar != NULL);
    1819
    1820 if( indicatorbinvar == (SCIP_VAR*)SCIPhashmapGetImage(heurdata->varsubsciptoscip, var)
    1821 || (SCIPvarIsNegated(indicatorbinvar) && indicatorbinvar == SCIPvarGetNegatedVar(var)) )
    1822 {
    1823 indicons = currcons;
    1824 assert(indicons != NULL);
    1825
    1826 subcons = (SCIP_CONS*)SCIPhashmapGetImage(heurdata->origsubscipConsMap, (void*)(indicons));
    1827 assert(subcons != NULL);
    1828
    1829 subcons = SCIPgetLinearConsIndicator(subcons);
    1830 assert(subcons != NULL);
    1831
    1832 dualvalue = (SCIP_Real*)SCIPhashmapGetImage(heurdata->dualvalues, (void*)(subcons));
    1833
    1834 if( dualvalue == NULL )
    1835 continue;
    1836
    1837 assert(dualvalue != NULL);
    1838
    1839 if( REALABS(ranks[j]) < REALABS(*dualvalue) )
    1840 ranks[j] = (*dualvalue);
    1841 }
    1842 }
    1843 }
    1844 }
    1845
    1846 /* take the absolute value of each rank */
    1847 absranks[j] = REALABS(ranks[j]);
    1848 }
    1849
    1850 SCIPsortDownRealRealPtr(absranks, ranks, (void**)sortedvars, heurdata->nintegervars);
    1851
    1852 return SCIP_OKAY;
    1853}
    1854
    1855/** compute maximal slack of a variable */
    1856static
    1858 SCIP* scip, /**< scip data structure */
    1859 SCIP_HEURDATA* heurdata /**< heuristic data structure */
    1860 )
    1861{
    1862 SCIP_VAR* maxvar;
    1863 SCIP_VAR* subvar;
    1864 SCIP_SOL* bestsol;
    1865 SCIP_Real maxslack;
    1866 int i;
    1867 int nsubvars;
    1868 SCIP_Bool maxslackset;
    1869
    1870 /* compute maximal slack */
    1871 nsubvars = SCIPgetNOrigVars(heurdata->subscip);
    1872
    1873 /* save information about maximal violation */
    1874 maxvar = NULL;
    1875 maxslack = -SCIPinfinity(heurdata->subscip);
    1876 maxslackset = FALSE;
    1877
    1878 bestsol = SCIPgetBestSol(heurdata->subscip);
    1879
    1880 /* search for variable with maximal slack */
    1881 for( i = 0; i < nsubvars; i++ )
    1882 {
    1883 subvar = SCIPgetOrigVars(heurdata->subscip)[i];
    1884 if( subvar == NULL)
    1885 continue;
    1886
    1887 /* if variable is slack */
    1888 if( SCIPhashmapGetImage(heurdata->slack2var, subvar) != NULL )
    1889 {
    1890 if( heurdata->isnlp )
    1891 {
    1892 if( maxslack < SCIPvarGetNLPSol(subvar) )
    1893 {
    1894 maxslack = SCIPvarGetNLPSol(subvar);
    1895 maxvar = subvar;
    1896 maxslackset = TRUE;
    1897 }
    1898 }
    1899 else
    1900 {
    1901 assert(bestsol != NULL);
    1902 if( maxslack < SCIPgetSolVal(heurdata->subscip, bestsol, subvar) )
    1903 {
    1904 maxslack = SCIPgetSolVal(heurdata->subscip, bestsol, subvar);
    1905 maxvar = subvar;
    1906 maxslackset = TRUE;
    1907 }
    1908 }
    1909 }
    1910 }
    1911
    1912 if( ! maxslackset )
    1913 {
    1914 maxslack = 0;
    1915 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "could not find a variable with maximal slack!\n");
    1916 }
    1917
    1918 assert(maxslack >= 0);
    1919
    1920 if( heurdata->heurverblevel > 0 && maxslackset )
    1921 {
    1922 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "maximum slack: %f %s\n", maxslack, SCIPvarGetName(maxvar));
    1923 }
    1924
    1925 return maxslack;
    1926}
    1927
    1928/** method called after a solution is found which is feasible in the original problem, stores it and cleans up */
    1929static
    1931 SCIP* scip, /**< SCIP data structure */
    1932 SCIP_HEUR* heur, /**< heuristic data */
    1933 SCIP_RESULT* result, /**< pointer to store result of: did not run, solution found,
    1934 * no solution found, or fixing is infeasible (cutoff) */
    1935 SCIP_SOL* transsol, /**< solution to fix variables */
    1936 SCIP_SOL* bestsol /**< solution we create a original scip solution from */
    1937 )
    1938{
    1939 SCIP_HEURDATA* heurdata;
    1940 SCIP_SOL* sol = NULL;
    1941 SCIP_Bool stored;
    1942 SCIP_Real primalobj;
    1943
    1944 /* get heuristic's data */
    1945 heurdata = SCIPheurGetData(heur);
    1946 assert(heurdata != NULL);
    1947 SCIP_CALL( createSolFromSubScipSol(scip, heur, &sol, bestsol) );
    1948
    1949 /* if this happens, there was an ipopt error - stop the heuristic for there is no good starting point */
    1950 if( heurdata->isnlp && SCIPgetNLPSolstat(heurdata->subscip) > SCIP_NLPSOLSTAT_FEASIBLE )
    1951 {
    1952 *result = SCIP_DIDNOTFIND;
    1953 heurdata->solfound = TRUE;
    1954
    1955 /* here we can be sure that we are in the nlp case */
    1956 assert( heurdata->isnlp );
    1957 SCIP_CALL( SCIPfreeSol(heurdata->subscip, &bestsol) );
    1958
    1959 SCIP_CALL( freeMemory(scip, heurdata, transsol, NULL, NULL, NULL, TRUE, TRUE) );
    1960
    1961 /* don't use the heuristic anymore if IPOPT doesn't give proper solution
    1962 * (normally then this happens in most ipopt runs that may follow) */
    1963 SCIPheurSetFreq(heur, -1);
    1964
    1965 SCIPdebugMsg(scip, "return10 : turn off heuristic, ipopt error\n");
    1966
    1967 if( heurdata->heurverblevel > 1 )
    1968 {
    1969 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "turn off heuristic due to ipopt error");
    1970 }
    1971
    1972 return SCIP_OKAY;
    1973 }
    1974
    1975 primalobj = SCIPinfinity(scip);
    1976
    1977 /* if there is a solution, try to add solution to storage and free it */
    1978 if( sol != NULL )
    1979 {
    1980 primalobj = SCIPsolGetOrigObj(sol);
    1981
    1982 if( heurdata->heurverblevel > 0 )
    1983 {
    1984 SCIP_CALL( SCIPtrySolFree(scip, &sol, TRUE, TRUE, TRUE, FALSE, TRUE, &stored) );
    1985 }
    1986 else
    1987 {
    1988 SCIP_CALL( SCIPtrySolFree(scip, &sol, FALSE, FALSE, TRUE, FALSE, TRUE, &stored) );
    1989 }
    1990 }
    1991 else
    1992 stored = FALSE;
    1993
    1994 if( stored && heurdata->heurverblevel > 1 )
    1995 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "accepted solution\n");
    1996
    1997 if( heurdata->isnlp )
    1998 SCIP_CALL( SCIPfreeSol(heurdata->subscip, &bestsol) );
    1999
    2000 SCIP_CALL( freeMemory(scip, heurdata, transsol, NULL, NULL, NULL, TRUE, TRUE) );
    2001
    2002 if( !stored )
    2003 {
    2004 *result = SCIP_DIDNOTFIND;
    2005 heurdata->solfound = TRUE;
    2006
    2007 if( heurdata->heurverblevel >= 1 )
    2008 {
    2009 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "return9 : found solution that was not stored, objective %f\n", primalobj);/*lint !e644*/
    2010 }
    2011
    2012 return SCIP_OKAY;
    2013 }
    2014
    2015 heurdata->prevInfeasible = FALSE;
    2016 heurdata->solfound = TRUE;
    2017 *result = SCIP_FOUNDSOL;
    2018
    2019 if( heurdata->heurverblevel >= 1 )
    2020 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "return 9 : found and stored new solution, objective %lf\n", primalobj);
    2021
    2022 return SCIP_OKAY;
    2023}
    2024
    2025/** main procedure of the dualval heuristic */
    2027 SCIP* scip, /**< original SCIP data structure */
    2028 SCIP_HEUR* heur, /**< heuristic data structure */
    2029 SCIP_RESULT* result, /**< pointer to store result of: did not run, solution found, no solution
    2030 * found, or fixing is infeasible (cutoff) */
    2031 SCIP_SOL* refpoint /**< point to take fixation of discrete variables from; if NULL, then LP
    2032 * solution is used */
    2033 )
    2034{
    2035 SCIP_HEURDATA* heurdata;
    2036 SCIP_NLROW* nlrow;
    2037 SCIP_SOL* transsol;
    2038 SCIP_SOL* bestsol;
    2039 SCIP_CONS** subconss;
    2040 SCIP_CONS* rcons;
    2041 SCIP_VAR** subvars;
    2042 SCIP_VAR** sortedvars;
    2043 SCIP_VAR* var;
    2044 SCIP_VAR* subvar;
    2045 SCIP_VAR* v;
    2046 SCIP_RETCODE retcode;
    2047 SCIP_Real* absranks;
    2048 SCIP_Real* ranks;
    2049 SCIP_Real* startpoint;
    2050 SCIP_Real* dualval;
    2051 SCIP_Real* lastval;
    2052 SCIP_Real* seclastval;
    2053 SCIP_Real* newval;
    2055 SCIP_Real maxslack;
    2056 SCIP_Real objvalue;
    2057 int i;
    2058 int k;
    2059 int nsubvars;
    2060 int nsubbinvars;
    2061 int nsubintvars;
    2062 int nsubconss;
    2063 int maxequalranks;
    2064
    2065 assert(scip != NULL);
    2066 assert(heur != NULL);
    2067
    2068 /* dio not run without nlp solver */
    2069 if( SCIPgetNNlpis(scip) <= 0 )
    2070 return SCIP_OKAY;
    2071
    2072 /* get heuristic's data */
    2073 heurdata = SCIPheurGetData(heur);
    2074 assert(heurdata != NULL);
    2075
    2076 /* don't use the heuristic, if the gap is small so we don't expect to get better solutions than already found */
    2077 if( SCIPgetGap(scip) * 100 < heurdata->mingap )
    2078 {
    2079 SCIPdebugMsg(scip, "return13 : gap is less than mingap\n");
    2080 return SCIP_OKAY;
    2081 }
    2082
    2083 /* in the mode 'onlyleaves' don't run the heuristic if we are not in a leaf of the B&B tree */
    2084 if( heurdata->onlyleaves && (SCIPgetNLPBranchCands(scip) != 0 || SCIPgetNPseudoBranchCands(scip) != 0) )
    2085 return SCIP_OKAY;
    2086
    2087 /* try to setup subscip if not tried before */
    2088 if( heurdata->subscip == NULL && !heurdata->triedsetupsubscip )
    2089 {
    2090 SCIP_CALL( createSubSCIP(scip, heurdata) );
    2091 }
    2092
    2093 /* quit the recursion if we have found a solution */
    2094 if( heurdata->solfound )
    2095 {
    2096 SCIPdebugMsg(scip, "return1 : already found solution \n");
    2097 return SCIP_OKAY;
    2098 }
    2099
    2100 *result = SCIP_DIDNOTRUN;
    2101
    2102 /* not initialized */
    2103 if( heurdata->subscip == NULL )
    2104 {
    2105 SCIPdebugMsg(scip, "return2 : subscip is NULL\n");
    2106 return SCIP_OKAY;
    2107 }
    2108
    2109 assert(heurdata->nsubvars > 0);
    2110 assert(heurdata->varsubsciptoscip != NULL);
    2111
    2112 /* fix discrete variables in sub-SCIP */
    2113 SCIP_CALL( fixDiscreteVars(scip, heurdata, refpoint, &transsol) );
    2115
    2116 if( heurdata->onlycheaper && !SCIPisInfinity(scip, bound) )
    2117 {
    2118 SCIP_CALL( SCIPchgRhsLinear( heurdata->subscip, heurdata->objbound, bound) );
    2119 }
    2120
    2121 SCIP_CALL( SCIPsetIntParam(heurdata->subscip, "presolving/maxrounds", 1) );
    2122 SCIP_CALL( SCIPsetIntParam(heurdata->subscip, "propagating/maxroundsroot", 0) );
    2123
    2124 SCIP_CALL( SCIPsetLongintParam(heurdata->subscip, "limits/nodes", 1LL) );
    2125 SCIP_CALL( SCIPpresolve(heurdata->subscip) );
    2126
    2127 if( SCIPgetStatus(heurdata->subscip) == SCIP_STATUS_INFEASIBLE )
    2128 {
    2129 SCIPdebugMsg(scip, "return 4 : subscip is infeasible\n");
    2130
    2131 *result = SCIP_DIDNOTFIND;
    2132 heurdata->prevInfeasible = TRUE;
    2133 SCIP_CALL( freeMemory(scip, heurdata, transsol, NULL, NULL, NULL, TRUE, TRUE) );
    2134
    2135 return SCIP_OKAY;
    2136 }
    2137
    2138 SCIP_CALL( SCIPsetLongintParam(heurdata->subscip, "limits/nodes", 0LL) );
    2139 retcode = SCIPsolve(heurdata->subscip);
    2140 heurdata->isnlp = TRUE;
    2141
    2142 bestsol = NULL;
    2143
    2144 /* we have no dualvalues, so give up */
    2145 if( SCIPgetStatus(heurdata->subscip) == SCIP_STATUS_OPTIMAL)
    2146 {
    2147 *result = SCIP_DIDNOTFIND;
    2148 SCIP_CALL( freeMemory(scip, heurdata, transsol, NULL, NULL, NULL, TRUE, TRUE) );
    2149
    2150 return SCIP_OKAY;
    2151 }
    2152
    2153 /* If no NLP was constructed, then there were no nonlinearities after presolve.
    2154 * So we increase the nodelimit to 1 and hope that SCIP will find some solution to this probably linear subproblem.
    2155 */
    2156 if( ! SCIPisNLPConstructed(heurdata->subscip) && retcode == SCIP_OKAY )
    2157 {
    2158 SCIP_CALL( SCIPsetLongintParam(heurdata->subscip, "limits/nodes", 1LL) );
    2159 SCIP_CALL( SCIPsolve(heurdata->subscip) );
    2160 heurdata->isnlp = FALSE;
    2161 bestsol = SCIPgetBestSol(heurdata->subscip);
    2162 }
    2163
    2164 if( heurdata->isnlp )
    2165 {
    2166 /* add non-combinatorial linear constraints from subscip into subNLP */
    2167 SCIP_CALL( addLinearConstraintsToNlp(heurdata->subscip, FALSE, TRUE, heurdata) );
    2168
    2169 SCIP_CALL( SCIPallocBufferArray(scip, &startpoint, SCIPgetNNLPVars(heurdata->subscip)) );
    2170
    2171 /* set starting values (=refpoint, if not NULL; otherwise LP solution (or pseudo solution)) */
    2172 for( i = 0; i < SCIPgetNNLPVars(heurdata->subscip); ++i )
    2173 {
    2174 SCIP_Real scalar = 1.0;
    2175 SCIP_Real constant = 0.0;
    2176
    2177 subvar = SCIPgetNLPVars(heurdata->subscip)[i];
    2178
    2179 /* gets corresponding original variable */
    2180 SCIP_CALL( SCIPvarGetOrigvarSum(&subvar, &scalar, &constant) );
    2181 if( subvar == NULL )
    2182 {
    2183 startpoint[i] = constant;
    2184 continue;
    2185 }
    2186
    2187 var = (SCIP_VAR*)SCIPhashmapGetImage(heurdata->varsubsciptoscip, subvar);
    2188 if( var == NULL || REALABS( SCIPgetSolVal(scip, refpoint, var) ) > 1.0e+12 )
    2189 {
    2190 SCIP_Real tmpmax;
    2191 tmpmax = MAX( 0.0, SCIPvarGetLbGlobal(subvar) );/*lint !e666*/
    2192 startpoint[i] = MIN( tmpmax, SCIPvarGetUbGlobal(subvar) );/*lint !e666*/
    2193 }
    2194 else
    2195 /* scalar*subvar+constant corresponds to nlpvar[i], so nlpvar[i] gets value scalar*varval+constant */
    2196 startpoint[i] = scalar * SCIPgetSolVal(scip, refpoint, var) + constant;
    2197 }
    2198
    2199 SCIP_CALL( SCIPsetNLPInitialGuess(heurdata->subscip, startpoint) );
    2200
    2201 /* don't need startpoint array anymore */
    2202 SCIPfreeBufferArray( scip, &startpoint );
    2203
    2204 SCIP_CALL( SCIPsolveNLP(heurdata->subscip, .verblevel = (unsigned short)heurdata->nlpverblevel) ); /*lint !e666*/
    2205 assert(SCIPisNLPConstructed(heurdata->subscip));
    2206
    2207 /* in this case there was an error in ipopt, we try to give another startpoint */
    2208 if( SCIPgetNLPSolstat(heurdata->subscip) > SCIP_NLPSOLSTAT_FEASIBLE )
    2209 {
    2210 SCIP_CALL( SCIPsetNLPInitialGuess(heurdata->subscip, NULL) );
    2211 SCIP_CALL( SCIPsolveNLP(heurdata->subscip, .verblevel = (unsigned short)heurdata->nlpverblevel) ); /*lint !e666*/
    2212 assert(SCIPisNLPConstructed(heurdata->subscip));
    2213 }
    2214
    2215 nsubconss = SCIPgetNOrigConss(heurdata->subscip);
    2216 subconss = SCIPgetOrigConss(heurdata->subscip);
    2217
    2218 /* free memory of all entries and clear the hashmap before filling it */
    2219 for( i = 0; i < nsubconss; i++ )
    2220 {
    2221 dualval = (SCIP_Real*)SCIPhashmapGetImage(heurdata->dualvalues, subconss[i]);
    2222 SCIPfreeBlockMemoryArray(heurdata->subscip, &dualval, 1);
    2223 }
    2224 SCIP_CALL( SCIPhashmapRemoveAll(heurdata->dualvalues) );
    2225
    2226 /* save the dualvalues from our nlp solution */
    2227 for( i = 0; i < nsubconss; i++ )
    2228 {
    2229 SCIP_CONS* transcons;
    2230
    2231 SCIP_CALL( SCIPgetTransformedCons(heurdata->subscip, subconss[i], &transcons) );
    2232
    2233 if( transcons == NULL )
    2234 continue;
    2235
    2236 if( SCIPconsGetHdlr(transcons) != SCIPfindConshdlr(heurdata->subscip, "linear") )
    2237 continue;
    2238
    2239 nlrow = (SCIP_NLROW*)SCIPhashmapGetImage(heurdata->conss2nlrow, transcons);
    2240
    2241 if (nlrow != NULL)
    2242 {
    2243 SCIP_CALL( SCIPallocBlockMemoryArray(heurdata->subscip, &dualval, 1) ); /*lint !e506*/
    2244 *dualval = SCIPnlrowGetDualsol(nlrow);
    2245 }
    2246 else
    2247 {
    2248 SCIP_CALL( SCIPallocBlockMemoryArray(heurdata->subscip, &dualval, 1) ); /*lint !e506*/
    2249 *dualval = 0;
    2250 }
    2251
    2252 SCIP_CALL( SCIPhashmapInsert(heurdata->dualvalues, subconss[i], dualval) );
    2253 }
    2254
    2255 bestsol = NULL;
    2256 SCIP_CALL( createSolFromNLP(heurdata->subscip, heur, &bestsol) );
    2257 }
    2258
    2259 /* if we are infeasible, we can't do anything*/
    2260 if( SCIPgetStatus(heurdata->subscip) == SCIP_STATUS_INFEASIBLE )
    2261 {
    2262 SCIPdebugMsg(scip, "return4 : the subscip is infeasible\n");
    2263
    2264 SCIP_CALL( freeMemory(scip, heurdata, transsol, NULL, NULL, NULL, TRUE, TRUE) );
    2265
    2266 return SCIP_OKAY;
    2267 }
    2268
    2269 maxslack = maximalslack(scip, heurdata);
    2270 SCIPdebugMsg(scip, "origObj: %f\n", SCIPgetSolOrigObj(heurdata->subscip, bestsol));
    2271 SCIP_CALL( SCIPgetOrigVarsData(heurdata->subscip, &subvars, &nsubvars, &nsubbinvars, &nsubintvars, NULL, NULL) );
    2272 objvalue = 0.0;
    2273 assert(bestsol != NULL);
    2274
    2275 /* save information about maximal violation */
    2276 for( i = 0; i < nsubvars; i++ )
    2277 {
    2278 subvar = SCIPgetOrigVars(heurdata->subscip)[i];
    2279
    2280 if( SCIPhashmapGetImage(heurdata->slack2var, subvar) == NULL )
    2281 objvalue += SCIPvarGetObj(subvar) * SCIPgetSolVal(heurdata->subscip, bestsol, subvar);
    2282 }
    2283
    2284 /* we stop the heuristic if it does not come "closer" to a feasible solution*/
    2285 if( heurdata->forceimprovements )
    2286 {
    2287 if( SCIPisGE(scip, SCIPgetSolOrigObj(heurdata->subscip, bestsol) - objvalue, heurdata->prevobjective) && maxslack > 0 )
    2288 {
    2289 heurdata->nonimprovingRounds++;
    2290 SCIPdebugMsg(scip, "nonimpr rounds %d prevobj %f \n", heurdata->nonimprovingRounds, heurdata->prevobjective);
    2291
    2292 /* leave, if we have not improved some iterations*/
    2293 if( heurdata->nonimprovingRounds > heurdata->maxcalls/8 )
    2294 {
    2295 *result = SCIP_DIDNOTFIND;
    2296
    2297 if( heurdata->isnlp )
    2298 {
    2299 SCIP_CALL( SCIPfreeSol(heurdata->subscip, &bestsol) );
    2300 }
    2301
    2302 SCIP_CALL( freeMemory(scip, heurdata, transsol, NULL, NULL, NULL, TRUE, TRUE) );
    2303
    2304 heurdata->solfound = TRUE;
    2305 heurdata->switchdifferent = TRUE;
    2306
    2307 SCIPdebugMsg(scip, "return11 : solution did not improve\n");
    2308
    2309 return SCIP_OKAY;
    2310 }
    2311 }
    2312 }
    2313
    2314 heurdata->prevobjective = SCIPgetSolOrigObj(heurdata->subscip, bestsol) - objvalue;
    2315
    2316 /* in this case we found a feasible solution, store it, clean up and stop the heuristic*/
    2317 if( SCIPisFeasLE(heurdata->subscip, maxslack, 0.0) )
    2318 return storeSolution(scip, heur, result, transsol, bestsol);
    2319
    2320 SCIP_CALL( SCIPallocBufferArray(scip, &ranks, heurdata->nintegervars) );
    2321 SCIP_CALL( SCIPallocBufferArray(scip, &sortedvars, heurdata->nintegervars) );
    2322 SCIP_CALL( SCIPallocBufferArray(scip, &absranks, heurdata->nintegervars) );
    2323
    2324 /* compute ranks and sort them in non-increasing order */
    2325 SCIP_CALL( computeRanks(scip, heurdata, absranks, ranks, sortedvars) );
    2326
    2327 /* print out the highest ranks */
    2328 if( heurdata->heurverblevel > 1 )
    2329 {
    2330 k = heurdata->rankvalue;
    2331
    2332 if( heurdata->nintegervars < heurdata->rankvalue )
    2333 k = heurdata->nintegervars;
    2334
    2335 for( i = 0; i < k; i++ )
    2336 {
    2337 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "%i. rank: %f name: %s\n", i, ranks[i], SCIPvarGetName(sortedvars[i]));
    2338 }
    2339 }
    2340
    2341 /* free solution */
    2342 if( heurdata->isnlp )
    2343 SCIP_CALL( SCIPfreeSol(heurdata->subscip, &bestsol) );
    2344
    2345 /* we don't allow more than a third of the variables to have the same rank */
    2346 maxequalranks = MIN(heurdata->maxequalranks, heurdata->nintegervars/3);
    2347
    2348 if( heurdata->maxequalranks >= 0 && SCIPisFeasEQ(heurdata->subscip, REALABS(ranks[0]), REALABS(ranks[maxequalranks])) )
    2349 {
    2350 *result = SCIP_DIDNOTFIND;
    2351
    2352 SCIPdebugMsg(scip, "return12 : equal maxranks\n");
    2353
    2354 SCIP_CALL( freeMemory(scip, heurdata, transsol, absranks, ranks, sortedvars, TRUE, TRUE ) );
    2355 return SCIP_OKAY;
    2356 }
    2357
    2358 /* now we can start switching the variable values */
    2359 SCIP_CALL( SCIPfreeTransform(heurdata->subscip) );
    2360
    2361 /* set bounds of fixed discrete variables to original values so we can switch */
    2362 for( k = 0; k < heurdata->nintegervars; ++k )
    2363 {
    2364 var = heurdata->integervars[k];
    2365 if( var == NULL )
    2366 break;
    2367
    2368 var = SCIPvarGetTransVar(var);
    2369 subvar = (SCIP_VAR*)SCIPhashmapGetImage(heurdata->varsciptosubscip, var);
    2370
    2371 rcons = (SCIP_CONS*) SCIPhashmapGetImage(heurdata->relaxcons, subvar);
    2372 if( rcons != NULL )
    2373 continue;
    2374
    2375 assert(var != NULL);
    2376 assert(subvar != NULL);
    2377
    2378 if ( SCIPhashmapGetImage(heurdata->indicopymap, subvar) != NULL )
    2379 subvar = (SCIP_VAR*)SCIPhashmapGetImage(heurdata->indicopymap, subvar);
    2380
    2381 SCIP_CALL( SCIPchgVarLbGlobal(heurdata->subscip, subvar, SCIPvarGetLbGlobal(heurdata->integervars[k])) );
    2382 SCIP_CALL( SCIPchgVarUbGlobal(heurdata->subscip, subvar, SCIPvarGetUbGlobal(heurdata->integervars[k])) );
    2383 }
    2384
    2385 /* switch variable with maximum ranking if possible */
    2386 for( i = 0; i < heurdata->nintegervars; i++ )
    2387 {
    2388 v = sortedvars[i];
    2389 SCIP_CALL( SCIPallocBlockMemoryArray(heurdata->subscip, &newval, 1) ); /*lint !e506*/
    2390
    2391 /* compute the new value of the variable */
    2392
    2393 /* if we have an indicator constraint, we turn it off */
    2394 if( SCIPhashmapGetImage(heurdata->slacktoindivarsmap, v) != NULL )
    2395 {
    2396 /* get the indicator var of this constraint */
    2397 v = (SCIP_VAR*)SCIPhashmapGetImage(heurdata->slacktoindivarsmap, v);
    2398
    2399 /* set the value to 0 */
    2400 SCIP_CALL( SCIPsetSolVal(scip, transsol, v, 0.0) );
    2401 if( heurdata->heurverblevel > 1 )
    2402 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "Setting value of %s%s to 0\n", SCIPvarIsNegated(v) ? "(negated) " : " ", SCIPvarGetName(v));
    2403
    2404 *newval = 0.0;
    2405 SCIP_CALL( SCIPhashmapInsert(heurdata->switchedvars, v, newval) );
    2406 }
    2407 else
    2408 {
    2409 /* ignore fixed vars in input */
    2411 {
    2412 SCIPfreeBlockMemoryArray(heurdata->subscip, &newval, 1);
    2413 continue;
    2414 }
    2415
    2416 if( ranks[i] > 0 )
    2417 {
    2418 if( SCIPvarIsBinary(v) && SCIPisEQ(scip, 1.0, SCIPgetSolVal(scip, transsol, v)) )
    2419 {
    2420 SCIPfreeBlockMemoryArray(heurdata->subscip, &newval, 1);
    2421 continue;
    2422 }
    2423
    2424 *newval = SCIPgetSolVal(scip, transsol, v) + 1;
    2425 }
    2426 else
    2427 {
    2428 if( SCIPvarIsBinary(v) && SCIPisEQ(scip, 0.0, SCIPgetSolVal(scip, transsol, v)) )
    2429 {
    2430 SCIPfreeBlockMemoryArray(heurdata->subscip, &newval, 1);
    2431 continue;
    2432 }
    2433
    2434 *newval = SCIPgetSolVal(scip, transsol, v) - 1;
    2435 }
    2436 }
    2437 lastval = (SCIP_Real*)SCIPhashmapGetImage(heurdata->switchedvars, v);
    2438 seclastval = (SCIP_Real*)SCIPhashmapGetImage(heurdata->switchedvars2, v);
    2439
    2440 /* we don't want to set a variable to a value it already had,or set a binary variable more than once */
    2441 if( (lastval != NULL && (SCIPvarIsBinary(v) || SCIPisFeasEQ(scip, *lastval, *newval))) || (seclastval != NULL && SCIPisFeasEQ(scip, *seclastval, *newval)) )
    2442 {
    2443 SCIPfreeBlockMemoryArray(heurdata->subscip, &newval, 1);
    2444 continue;
    2445 }
    2446 else /* update the switchedvars values, switchedvars2 is the second last and switchedvars the last value */
    2447 {
    2448 if( seclastval != NULL )
    2449 SCIPfreeBlockMemoryArray(heurdata->subscip, &seclastval, 1);
    2450
    2451 SCIP_CALL( SCIPhashmapRemove(heurdata->switchedvars2, v) );
    2452 SCIP_CALL( SCIPhashmapInsert(heurdata->switchedvars2, v, lastval) );
    2453 SCIP_CALL( SCIPhashmapRemove(heurdata->switchedvars, v) );
    2454 SCIP_CALL( SCIPhashmapInsert(heurdata->switchedvars, v, newval) );
    2455
    2456 if( heurdata->heurverblevel > 1 )
    2457 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "Setting value of %s from %f to %f\n", SCIPvarGetName(v), SCIPgetSolVal(scip, transsol, v), *newval);
    2458
    2459 SCIP_CALL( SCIPsetSolVal(scip, transsol, v, *newval) );
    2460 }
    2461
    2462 /* if we have exceeded our iterations limit give up without any solution */
    2463 if( heurdata->usedcalls >= heurdata->maxcalls )
    2464 {
    2465 SCIPdebugMsg(scip, "return5 : reached iteration limit\n");
    2466
    2467 SCIP_CALL( freeMemory(scip, heurdata, transsol, absranks, ranks, sortedvars, FALSE, TRUE) );
    2468 *result = SCIP_DIDNOTFIND;
    2469 return SCIP_OKAY;
    2470 }
    2471
    2472 heurdata->usedcalls++;
    2473
    2474 if( heurdata->heurverblevel > 1 )
    2475 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "----- Total Calls: %d\n", heurdata->usedcalls);
    2476
    2477 /* recursive call of the heuristic */
    2478 SCIP_CALL( SCIPapplyHeurDualval(scip, heur, result, transsol) );
    2479
    2480 /* just to go up in the recursion */
    2481 if( *result == SCIP_DIDNOTFIND || heurdata->solfound || heurdata->prevInfeasible )
    2482 {
    2483 SCIPdebugMsg(scip, "return6 : go up\n");
    2484
    2485 /* here we only go up one step and try another switch (switch the same variables again is forbidden
    2486 * since they are contained in switchedvars) */
    2487 if( heurdata->switchdifferent )
    2488 {
    2489 heurdata->switchdifferent = FALSE;
    2490 heurdata->solfound = FALSE;
    2491 *result = SCIP_DIDNOTRUN;
    2492 heurdata->nonimprovingRounds -= 2;
    2493 }
    2494
    2495 if( heurdata->prevInfeasible )
    2496 {
    2497 heurdata->prevInfeasible = FALSE;
    2498 heurdata->solfound = FALSE;
    2499 *result = SCIP_DIDNOTRUN;
    2500 heurdata->nonimprovingRounds++;
    2501 }
    2502
    2503 SCIP_CALL( freeMemory(scip, heurdata, transsol, absranks, ranks, sortedvars, FALSE, FALSE) );
    2504 return SCIP_OKAY;
    2505 }
    2506 }
    2507
    2508 if( heurdata->subscip == NULL )
    2509 {
    2510 /* something horrible must have happened that we decided to give up completely on this heuristic */
    2511 *result = SCIP_DIDNOTFIND;
    2512 SCIPdebugMsg(scip, "return7 : subscip was set NULL\n");
    2513
    2514 SCIP_CALL( freeMemory(scip, heurdata, transsol, absranks, ranks, sortedvars, FALSE, TRUE) );
    2515 return SCIP_OKAY;
    2516 }
    2517 assert(!SCIPisTransformed(heurdata->subscip));
    2518
    2519 SCIPdebugMsg(scip, "return8 : cannot switch any variable\n");
    2520
    2521 SCIP_CALL( freeMemory(scip, heurdata, transsol, absranks, ranks, sortedvars, FALSE, TRUE) );
    2522
    2523 *result = SCIP_DIDNOTFIND;
    2524 return SCIP_OKAY;
    2525}
    2526
    2527/*
    2528 * Callback methods of primal heuristic
    2529 */
    2530
    2531/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
    2532static
    2533SCIP_DECL_HEURCOPY(heurCopyDualval)
    2534{ /*lint --e{715}*/
    2535 assert(scip != NULL);
    2536 assert(heur != NULL);
    2537 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
    2538
    2539 /* call inclusion method of primal heuristic */
    2541
    2542 return SCIP_OKAY;
    2543}
    2544
    2545/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
    2546static
    2547SCIP_DECL_HEURFREE(heurFreeDualval)
    2548{
    2549 SCIP_HEURDATA* heurdata;
    2550
    2551 assert(scip != NULL);
    2552 assert(heur != NULL);
    2553
    2554 heurdata = SCIPheurGetData(heur);
    2555
    2556 SCIPfreeBlockMemory(scip, &heurdata);
    2557
    2558 return SCIP_OKAY;
    2559}
    2560
    2561
    2562/** initialization method of primal heuristic (called after problem was transformed) */
    2563static
    2564SCIP_DECL_HEURINIT(heurInitDualval)
    2565{ /*lint --e{715}*/
    2566 SCIP_HEURDATA* heurdata;
    2567
    2568 assert(scip != NULL);
    2569 assert(heur != NULL);
    2570
    2571 /* skip setting up sub-SCIP if heuristic is disabled or we do not want to run the heuristic */
    2572 if( SCIPheurGetFreq(heur) < 0 )
    2573 return SCIP_OKAY;
    2574
    2575 SCIP_CALL( SCIPsetIntParam(scip, "presolving/maxrestarts", 0) );
    2576
    2577 heurdata = SCIPheurGetData(heur);
    2578 assert(heurdata != NULL);
    2579 assert(heurdata->subscip == NULL);
    2580 assert(!heurdata->triedsetupsubscip);
    2581
    2582 /* create sub-SCIP for later use */
    2583 SCIP_CALL( createSubSCIP(scip, heurdata) );
    2584
    2585 /* creating sub-SCIP may fail if the solver interfaces did not copy into subscip */
    2586 if( heurdata->subscip == NULL )
    2587 return SCIP_OKAY;
    2588
    2589 /* if the heuristic is called at the root node, we want to be called directly after the initial root LP solve */
    2590 if( SCIPheurGetFreqofs(heur) == 0 )
    2592
    2593 SCIP_CALL( SCIPhashmapCreate(&heurdata->dualvalues, SCIPblkmem(scip), 512) );
    2594
    2595 return SCIP_OKAY;
    2596}
    2597
    2598/** deinitialization method of primal heuristic (called before transformed problem is freed) */
    2599static
    2600SCIP_DECL_HEUREXIT(heurExitDualval)
    2601{ /*lint --e{715}*/
    2602 SCIP_HEURDATA* heurdata;
    2603 SCIP_CONS** subconss;
    2604 SCIP_Real* dualval;
    2605 int i;
    2606 int nsubconss;
    2607
    2608 assert(scip != NULL);
    2609 assert(heur != NULL);
    2610
    2611 heurdata = SCIPheurGetData(heur);
    2612 assert(heurdata != NULL);
    2613
    2614 SCIPfreeBlockMemoryArrayNull(scip, &heurdata->integervars, heurdata->integervarssize);
    2615
    2616 if( heurdata->subscip != NULL)
    2617 {
    2618 nsubconss = SCIPgetNOrigConss(heurdata->subscip);
    2619 subconss = SCIPgetOrigConss(heurdata->subscip);
    2620
    2621 /* free memory of all entries and clear the hashmap before filling it */
    2622 for( i = 0; i < nsubconss; i++ )
    2623 {
    2624 dualval = (SCIP_Real*)SCIPhashmapGetImage(heurdata->dualvalues, subconss[i]);
    2625 SCIPfreeBlockMemoryArrayNull(heurdata->subscip, &dualval, 1);
    2626 }
    2627 SCIP_CALL( SCIPhashmapRemoveAll(heurdata->dualvalues) );
    2628 SCIPhashmapFree(&heurdata->dualvalues);
    2629
    2630 if( heurdata->varsciptosubscip != NULL )
    2631 {
    2632 SCIP_CALL( releaseHashmapEntries(heurdata->subscip, heurdata->varsciptosubscip, TRUE) );
    2633
    2634 SCIPhashmapFree(&heurdata->varsciptosubscip);
    2635 }
    2636 if( heurdata->origsubscipConsMap != NULL )
    2637 {
    2638 SCIP_CALL( releaseHashmapEntries(heurdata->subscip, heurdata->origsubscipConsMap, FALSE) );
    2639
    2640 SCIPhashmapFree(&heurdata->origsubscipConsMap);
    2641 }
    2642 if( heurdata->relaxcons != NULL )
    2643 {
    2644 SCIP_CALL( releaseHashmapEntries(heurdata->subscip, heurdata->relaxcons, FALSE) );
    2645
    2646 SCIPhashmapFree(&heurdata->relaxcons);
    2647 }
    2648 if( heurdata->conss2nlrow != NULL )
    2649 {
    2650 SCIP_CALL( releaseHashmapNLPRows(heurdata->subscip, heurdata->conss2nlrow) );
    2651
    2652 SCIPhashmapFree(&heurdata->conss2nlrow);
    2653 }
    2654 if( heurdata->slack2var != NULL )
    2655 {
    2656 SCIP_CALL( releaseHashmapEntries(heurdata->subscip, heurdata->slack2var, TRUE) );
    2657
    2658 SCIPhashmapFree(&heurdata->slack2var);
    2659 }
    2660 if( heurdata->indicopymap != NULL )
    2661 {
    2662 SCIP_CALL( releaseHashmapEntries(heurdata->subscip, heurdata->indicopymap, TRUE) );
    2663
    2664 SCIPhashmapFree(&heurdata->indicopymap);
    2665 }
    2666 if( heurdata->indicopymapback != NULL )
    2667 {
    2668 SCIP_CALL( releaseHashmapEntries(heurdata->subscip, heurdata->indicopymapback, TRUE) );
    2669
    2670 SCIPhashmapFree(&heurdata->indicopymapback);
    2671 }
    2672 if( heurdata->relaxconsindi != NULL )
    2673 {
    2674 SCIP_CALL( releaseHashmapEntries(heurdata->subscip, heurdata->relaxconsindi, FALSE) );
    2675
    2676 SCIPhashmapFree(&heurdata->relaxconsindi);
    2677 }
    2678 if( heurdata->slackvarlbMap != NULL )
    2679 {
    2680 SCIP_CALL( releaseHashmapEntries(heurdata->subscip, heurdata->slackvarlbMap, TRUE) );
    2681
    2682 SCIPhashmapFree(&heurdata->slackvarlbMap);
    2683 }
    2684 if( heurdata->slackvarubMap != NULL )
    2685 {
    2686 SCIP_CALL( releaseHashmapEntries(heurdata->subscip, heurdata->slackvarubMap, TRUE) );
    2687
    2688 SCIPhashmapFree(&heurdata->slackvarubMap);
    2689 }
    2690
    2691 if( heurdata->subscip != NULL )
    2692 {
    2693 SCIP_CALL( freeSubSCIP(scip, heurdata) );
    2694 }
    2695 }
    2696
    2697 if( heurdata->varsubsciptoscip != NULL )
    2698 {
    2699 SCIP_CALL( releaseHashmapEntries(scip, heurdata->varsubsciptoscip, TRUE) );
    2700
    2701 SCIPhashmapFree(&heurdata->varsubsciptoscip);
    2702 }
    2703 if( heurdata->slacktoindivarsmap != NULL )
    2704 {
    2705 SCIP_CALL( releaseHashmapEntries(scip, heurdata->slacktoindivarsmap, TRUE) );
    2706
    2707 SCIPhashmapFree(&heurdata->slacktoindivarsmap);
    2708 }
    2709 if( heurdata->indicators != NULL )
    2710 {
    2711 SCIP_CALL( releaseHashmapEntries(scip, heurdata->indicators, FALSE) );
    2712
    2713 SCIPhashmapFree(&heurdata->indicators);
    2714 }
    2715 if( heurdata->switchedvars != NULL )
    2716 {
    2717 SCIPhashmapFree(&heurdata->switchedvars);
    2718 }
    2719 if( heurdata->switchedvars2 != NULL )
    2720 {
    2721 SCIPhashmapFree(&heurdata->switchedvars2);
    2722 }
    2723
    2724 /* reset some flags and counters */
    2725 heurdata->triedsetupsubscip = FALSE;
    2726 heurdata->usedcalls = 0;
    2727 heurdata->solfound = FALSE;
    2728 heurdata->prevInfeasible = FALSE;
    2729
    2730 assert(heurdata->subscip == NULL);
    2731 assert(heurdata->varsubsciptoscip == NULL);
    2732 assert(heurdata->varsciptosubscip == NULL);
    2733
    2734 return SCIP_OKAY;
    2735}
    2736
    2737/** solving process initialization method of primal heuristic (called when branch and bound process is about to begin) */
    2738static
    2739SCIP_DECL_HEURINITSOL(heurInitsolDualval)
    2740{
    2741 SCIP_HEURDATA* heurdata;
    2742
    2743 assert(scip != NULL);
    2744 assert(heur != NULL);
    2745
    2746 /* skip setting up sub-SCIP if heuristic is disabled or we do not want to run the heuristic */
    2747 if( SCIPheurGetFreq(heur) < 0 )
    2748 return SCIP_OKAY;
    2749
    2750 heurdata = SCIPheurGetData(heur);
    2751 assert(heurdata != NULL);
    2752
    2753 /* creating sub-SCIP may fail if the solver interfaces did not copy into subscip */
    2754 if( heurdata->subscip == NULL )
    2755 return SCIP_OKAY;
    2756
    2757 /* if the heuristic is called at the root node, we want to be called directly after the initial root LP solve */
    2758 if( SCIPheurGetFreqofs(heur) == 0 )
    2760
    2761 return SCIP_OKAY;
    2762}
    2763
    2764
    2765/** solving process deinitialization method of primal heuristic (called before branch and bound process data is freed) */
    2766static
    2767SCIP_DECL_HEUREXITSOL(heurExitsolDualval)
    2768{
    2769 assert(scip != NULL);
    2770 assert(heur != NULL);
    2771
    2773
    2774 return SCIP_OKAY;
    2775}
    2776
    2777
    2778/** execution method of primal heuristic */
    2779static
    2780SCIP_DECL_HEUREXEC(heurExecDualval)
    2781{ /*lint --e{715}*/
    2782 SCIP_HEURDATA* heurdata;
    2783
    2784 assert(scip != NULL);
    2785 assert(heur != NULL);
    2786 assert(result != NULL);
    2787
    2788 /* get heuristic's data */
    2789 heurdata = SCIPheurGetData(heur);
    2790 assert(heurdata != NULL);
    2791
    2792 /* obviously, we did not do anything yet */
    2793 *result = SCIP_DIDNOTRUN;
    2794
    2795 /* init data */
    2796 heurdata->usedcalls = 0;
    2797 heurdata->prevInfeasible = FALSE;
    2798 heurdata->solfound = FALSE;
    2799 heurdata->nonimprovingRounds = 0;
    2800 heurdata->prevobjective = INT_MAX;
    2801
    2802 SCIP_CALL( SCIPapplyHeurDualval(scip, heur, result, NULL) );
    2803
    2804 /* SCIP does not like cutoff as return, so we say didnotfind, since we did not find a solution */
    2805 if( *result == SCIP_CUTOFF )
    2806 *result = SCIP_DIDNOTFIND;
    2807
    2808 /* reset timing, if it was changed temporary (at the root node) */
    2809 if( heurtiming != HEUR_TIMING )
    2811
    2812 return SCIP_OKAY;
    2813}
    2814
    2815
    2816/* primal heuristic specific interface methods */
    2817
    2818/** creates the dualval primal heuristic and includes it in SCIP */
    2820 SCIP* scip /**< SCIP data structure */
    2821 )
    2822{
    2823 SCIP_HEURDATA* heurdata = NULL;
    2824 SCIP_HEUR* heur = NULL;
    2825
    2826 /* create dualval primal heuristic data */
    2827 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
    2828 BMSclearMemory(heurdata);
    2829
    2830 /* include primal heuristic */
    2833 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecDualval, heurdata) );
    2834
    2835 assert(heur != NULL);
    2836
    2837 /* primal heuristic is safe to use in exact solving mode */
    2838 SCIPheurMarkExact(heur);
    2839
    2840 /* set non fundamental callbacks via setter functions */
    2841 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyDualval) );
    2842 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeDualval) );
    2843 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitDualval) );
    2844 SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitDualval) );
    2845 SCIP_CALL( SCIPsetHeurInitsol(scip, heur, heurInitsolDualval) );
    2846 SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolDualval) );
    2847
    2848 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/forceimprovements",
    2849 "exit if objective doesn't improve",
    2850 &heurdata->forceimprovements, TRUE, DEFAULT_FORCEIMPROVEMENTS, NULL, NULL) );
    2851
    2852 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/onlycheaper",
    2853 "add constraint to ensure that discrete vars are improving",
    2854 &heurdata->onlycheaper, TRUE, DEFAULT_ONLYCHEAPER, NULL, NULL) );
    2855
    2856 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/onlyleaves",
    2857 "disable the heuristic if it was not called at a leaf of the B&B tree",
    2858 &heurdata->onlyleaves, FALSE, DEFAULT_ONLYLEAVES, NULL, NULL) );
    2859
    2860 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/relaxindicators",
    2861 "relax the indicator variables by introducing continuous copies",
    2862 &heurdata->relaxindicators, FALSE, DEFAULT_RELAXINDICATORS, NULL, NULL) );
    2863
    2864 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/relaxcontvars",
    2865 "relax the continous variables",
    2866 &heurdata->relaxcontvars, FALSE, DEFAULT_RELAXCONTVARS, NULL, NULL) );
    2867
    2868 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/heurverblevel",
    2869 "verblevel of the heuristic, default is 0 to display nothing",
    2870 &heurdata->heurverblevel, FALSE, DEFAULT_HEURVERBLEVEL, 0, 4, NULL, NULL) );
    2871
    2872 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/nlpverblevel",
    2873 "verblevel of the nlp solver, can be 0 or 1",
    2874 &heurdata->nlpverblevel, FALSE, DEFAULT_NLPVERBLEVEL, 0, 1, NULL, NULL) );
    2875
    2876 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/rankvalue",
    2877 "number of ranks that should be displayed when the heuristic is called",
    2878 &heurdata->rankvalue, FALSE, DEFAULT_RANKVALUE, 0, INT_MAX, NULL, NULL) );
    2879
    2880 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxcalls",
    2881 "maximal number of recursive calls of the heuristic (if dynamicdepth is off)",
    2882 &heurdata->maxcalls, FALSE, DEFAULT_MAXCALLS, 0, INT_MAX, NULL, NULL) );
    2883
    2884 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/dynamicdepth",
    2885 "says if and how the recursion depth is computed at runtime",
    2886 &heurdata->dynamicdepth, FALSE, DEFAULT_DYNAMICDEPTH, 0, 1, NULL, NULL) );
    2887
    2888 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxequalranks",
    2889 "maximal number of variables that may have maximal rank, quit if there are more, turn off by setting -1",
    2890 &heurdata->maxequalranks, FALSE, DEFAULT_MAXEQUALRANKS, -1, INT_MAX, NULL, NULL) );
    2891
    2892 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/mingap",
    2893 "minimal gap for which we still run the heuristic, if gap is less we return without doing anything",
    2894 &heurdata->mingap, FALSE, DEFAULT_MINGAP, 0.0, 100.0, NULL, NULL) );
    2895
    2896 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/lambdaslack",
    2897 "value added to objective of slack variables, must not be zero",
    2898 &heurdata->lambdaslack, FALSE, DEFAULT_LAMBDASLACK, 0.1, SCIPinfinity(scip), NULL, NULL) );
    2899
    2900 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/lambdaobj",
    2901 "scaling factor for the objective function",
    2902 &heurdata->lambdaobj, FALSE, DEFAULT_LAMBDAOBJ, 0.0, 1.0, NULL, NULL) );
    2903
    2904 return SCIP_OKAY;
    2905}
    static long bound
    constraint handler for indicator constraints
    Constraint handler for knapsack constraints of the form , x binary and .
    Constraint handler for linear constraints in their most general form, .
    Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
    Constraint handler for the set partitioning / packing / covering constraints .
    Constraint handler for variable bound constraints .
    #define NULL
    Definition: def.h:248
    #define SCIP_MAXSTRLEN
    Definition: def.h:269
    #define SCIP_Longint
    Definition: def.h:141
    #define SCIP_INVALID
    Definition: def.h:178
    #define SCIP_Bool
    Definition: def.h:91
    #define MIN(x, y)
    Definition: def.h:224
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define MAX(x, y)
    Definition: def.h:220
    #define REALABS(x)
    Definition: def.h:182
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_RETCODE SCIPcreateConsIndicatorLinCons(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *binvar, SCIP_CONS *lincons, SCIP_VAR *slackvar, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    SCIP_Real SCIPgetDualsolLinear(SCIP *scip, SCIP_CONS *cons)
    int SCIPgetNVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real SCIPgetVbdcoefVarbound(SCIP *scip, SCIP_CONS *cons)
    int SCIPgetNVarsLogicor(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPchgRhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
    SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
    SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
    int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR * SCIPgetVbdvarVarbound(SCIP *scip, SCIP_CONS *cons)
    int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9596
    SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9619
    SCIP_VAR * SCIPgetBinaryVarIndicator(SCIP_CONS *cons)
    SCIP_VAR * SCIPgetVarVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_Longint * SCIPgetWeightsKnapsack(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR * SCIPgetSlackVarIndicator(SCIP_CONS *cons)
    SCIP_Longint SCIPgetCapacityKnapsack(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real SCIPgetLhsVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_SETPPCTYPE SCIPgetTypeSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9642
    SCIP_CONS * SCIPgetLinearConsIndicator(SCIP_CONS *cons)
    SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    SCIP_VAR ** SCIPgetVarsLogicor(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real SCIPgetRhsVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR ** SCIPgetVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPchgLhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
    @ SCIP_SETPPCTYPE_PARTITIONING
    Definition: cons_setppc.h:87
    @ SCIP_SETPPCTYPE_COVERING
    Definition: cons_setppc.h:89
    @ SCIP_SETPPCTYPE_PACKING
    Definition: cons_setppc.h:88
    SCIP_RETCODE SCIPcopyPlugins(SCIP *sourcescip, SCIP *targetscip, SCIP_Bool copyreaders, SCIP_Bool copypricers, SCIP_Bool copyconshdlrs, SCIP_Bool copyconflicthdlrs, SCIP_Bool copypresolvers, SCIP_Bool copyrelaxators, SCIP_Bool copyseparators, SCIP_Bool copycutselectors, SCIP_Bool copypropagators, SCIP_Bool copyheuristics, SCIP_Bool copyeventhdlrs, SCIP_Bool copynodeselectors, SCIP_Bool copybranchrules, SCIP_Bool copyiisfinders, SCIP_Bool copydisplays, SCIP_Bool copydialogs, SCIP_Bool copytables, SCIP_Bool copyexprhdlrs, SCIP_Bool copynlpis, SCIP_Bool passmessagehdlr, SCIP_Bool *valid)
    Definition: scip_copy.c:276
    SCIP_RETCODE SCIPcopyVars(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_VAR **fixedvars, SCIP_Real *fixedvals, int nfixedvars, SCIP_Bool global)
    Definition: scip_copy.c:1167
    SCIP_RETCODE SCIPcopyConss(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, SCIP_Bool enablepricing, SCIP_Bool *valid)
    Definition: scip_copy.c:1716
    SCIP_RETCODE SCIPcopyParamSettings(SCIP *sourcescip, SCIP *targetscip)
    Definition: scip_copy.c:2547
    SCIP_Bool SCIPisTransformed(SCIP *scip)
    Definition: scip_general.c:647
    SCIP_RETCODE SCIPfree(SCIP **scip)
    Definition: scip_general.c:402
    SCIP_RETCODE SCIPcreate(SCIP **scip)
    Definition: scip_general.c:370
    SCIP_STATUS SCIPgetStatus(SCIP *scip)
    Definition: scip_general.c:562
    SCIP_STAGE SCIPgetStage(SCIP *scip)
    Definition: scip_general.c:444
    SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_prob.c:1907
    SCIP_RETCODE SCIPgetOrigVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
    Definition: scip_prob.c:2753
    const char * SCIPgetProbName(SCIP *scip)
    Definition: scip_prob.c:1242
    SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
    Definition: scip_prob.c:2115
    int SCIPgetNOrigConss(SCIP *scip)
    Definition: scip_prob.c:3712
    SCIP_VAR ** SCIPgetOrigVars(SCIP *scip)
    Definition: scip_prob.c:2811
    SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3274
    SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3420
    int SCIPgetNConss(SCIP *scip)
    Definition: scip_prob.c:3620
    int SCIPgetNOrigVars(SCIP *scip)
    Definition: scip_prob.c:2838
    SCIP_CONS ** SCIPgetOrigConss(SCIP *scip)
    Definition: scip_prob.c:3739
    SCIP_RETCODE SCIPcreateProb(SCIP *scip, const char *name, SCIP_DECL_PROBDELORIG((*probdelorig)), SCIP_DECL_PROBTRANS((*probtrans)), SCIP_DECL_PROBDELTRANS((*probdeltrans)), SCIP_DECL_PROBINITSOL((*probinitsol)), SCIP_DECL_PROBEXITSOL((*probexitsol)), SCIP_DECL_PROBCOPY((*probcopy)), SCIP_PROBDATA *probdata)
    Definition: scip_prob.c:119
    void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
    Definition: misc.c:3095
    void * SCIPhashmapEntryGetImage(SCIP_HASHMAPENTRY *entry)
    Definition: misc.c:3613
    void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3284
    SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
    Definition: misc.c:3143
    int SCIPhashmapGetNEntries(SCIP_HASHMAP *hashmap)
    Definition: misc.c:3584
    SCIP_HASHMAPENTRY * SCIPhashmapGetEntry(SCIP_HASHMAP *hashmap, int entryidx)
    Definition: misc.c:3592
    SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
    Definition: misc.c:3061
    void * SCIPhashmapEntryGetOrigin(SCIP_HASHMAPENTRY *entry)
    Definition: misc.c:3603
    SCIP_RETCODE SCIPhashmapRemoveAll(SCIP_HASHMAP *hashmap)
    Definition: misc.c:3676
    SCIP_RETCODE SCIPhashmapRemove(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3482
    void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:225
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    SCIP_RETCODE SCIPapplyHeurDualval(SCIP *scip, SCIP_HEUR *heur, SCIP_RESULT *result, SCIP_SOL *refpoint)
    SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:83
    SCIP_RETCODE SCIPsetLongintParam(SCIP *scip, const char *name, SCIP_Longint value)
    Definition: scip_param.c:545
    SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:139
    SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
    Definition: scip_param.c:487
    SCIP_RETCODE 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 SCIPsetRealParam(SCIP *scip, const char *name, SCIP_Real value)
    Definition: scip_param.c:603
    SCIP_RETCODE SCIPincludeHeurDualval(SCIP *scip)
    int SCIPgetNLPBranchCands(SCIP *scip)
    Definition: scip_branch.c:436
    int SCIPgetNPseudoBranchCands(SCIP *scip)
    Definition: scip_branch.c:766
    int SCIPconshdlrGetNConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4778
    SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
    Definition: scip_cons.c:940
    int SCIPconshdlrGetNActiveConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4812
    SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4735
    void SCIPconsAddUpgradeLocks(SCIP_CONS *cons, int nlocks)
    Definition: cons.c:8828
    SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
    Definition: cons.c:8648
    SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
    Definition: cons.c:8409
    SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
    Definition: cons.c:8558
    SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
    Definition: cons.c:8588
    SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
    Definition: cons.c:8578
    SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
    Definition: cons.c:8608
    SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
    Definition: cons.c:8628
    SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
    Definition: cons.c:8486
    const char * SCIPconsGetName(SCIP_CONS *cons)
    Definition: cons.c:8389
    SCIP_RETCODE SCIPgetTransformedCons(SCIP *scip, SCIP_CONS *cons, SCIP_CONS **transcons)
    Definition: scip_cons.c:1674
    SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
    Definition: cons.c:8668
    SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
    Definition: scip_cons.c:1173
    SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
    Definition: cons.c:8568
    SCIP_RETCODE SCIPcaptureCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:1138
    SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
    Definition: cons.c:8658
    SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
    Definition: scip_event.c:111
    SCIP_EVENTHDLRDATA * SCIPeventhdlrGetData(SCIP_EVENTHDLR *eventhdlr)
    Definition: event.c:406
    SCIP_RETCODE SCIPsetEventhdlrExit(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTEXIT((*eventexit)))
    Definition: scip_event.c:185
    SCIP_RETCODE SCIPsetEventhdlrInit(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTINIT((*eventinit)))
    Definition: scip_event.c:171
    SCIP_RETCODE SCIPcatchEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
    Definition: scip_event.c:293
    SCIP_RETCODE SCIPdropEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
    Definition: scip_event.c:333
    SCIP_RETCODE SCIPenableExactSolving(SCIP *scip, SCIP_Bool enable)
    Definition: scip_exact.c:151
    SCIP_RETCODE SCIPsetHeurExitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXITSOL((*heurexitsol)))
    Definition: scip_heur.c:247
    SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
    Definition: scip_heur.c:167
    SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
    Definition: heur.c:1368
    SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
    Definition: scip_heur.c:122
    SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
    Definition: scip_heur.c:183
    SCIP_RETCODE SCIPsetHeurExit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXIT((*heurexit)))
    Definition: scip_heur.c:215
    void SCIPheurSetFreq(SCIP_HEUR *heur, int freq)
    Definition: heur.c:1562
    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
    int SCIPheurGetFreq(SCIP_HEUR *heur)
    Definition: heur.c:1552
    const char * SCIPheurGetName(SCIP_HEUR *heur)
    Definition: heur.c:1467
    SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
    Definition: scip_lp.c:174
    #define SCIPfreeBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:110
    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 SCIPallocBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:93
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
    Definition: scip_mem.h:111
    #define SCIPfreeBufferArrayNull(scip, ptr)
    Definition: scip_mem.h:137
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    int SCIPgetNNlpis(SCIP *scip)
    Definition: scip_nlpi.c:205
    SCIP_RETCODE SCIPaddNlRow(SCIP *scip, SCIP_NLROW *nlrow)
    Definition: scip_nlp.c:396
    SCIP_Bool SCIPisNLPConstructed(SCIP *scip)
    Definition: scip_nlp.c:110
    SCIP_NLPSOLSTAT SCIPgetNLPSolstat(SCIP *scip)
    Definition: scip_nlp.c:574
    #define SCIPsolveNLP(...)
    Definition: scip_nlp.h:361
    SCIP_RETCODE SCIPsetNLPInitialGuess(SCIP *scip, SCIP_Real *initialguess)
    Definition: scip_nlp.c:474
    int SCIPgetNNLPVars(SCIP *scip)
    Definition: scip_nlp.c:201
    SCIP_VAR ** SCIPgetNLPVars(SCIP *scip)
    Definition: scip_nlp.c:179
    SCIP_RETCODE SCIPreleaseNlRow(SCIP *scip, SCIP_NLROW **nlrow)
    Definition: scip_nlp.c:1058
    SCIP_Real SCIPnlrowGetDualsol(SCIP_NLROW *nlrow)
    Definition: nlp.c:1966
    SCIP_RETCODE SCIPcreateNlRow(SCIP *scip, SCIP_NLROW **nlrow, const char *name, SCIP_Real constant, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, SCIP_EXPR *expr, SCIP_Real lhs, SCIP_Real rhs, SCIP_EXPRCURV curvature)
    Definition: scip_nlp.c:954
    SCIP_SOL * SCIPgetBestSol(SCIP *scip)
    Definition: scip_sol.c:2981
    SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
    Definition: scip_sol.c:516
    SCIP_Real SCIPsolGetOrigObj(SCIP_SOL *sol)
    Definition: sol.c:4170
    SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
    Definition: scip_sol.c:1252
    SCIP_RETCODE SCIPcreateOrigSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
    Definition: scip_sol.c:831
    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_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1892
    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
    SCIP_RETCODE SCIPpresolve(SCIP *scip)
    Definition: scip_solve.c:2449
    SCIP_RETCODE SCIPfreeTransform(SCIP *scip)
    Definition: scip_solve.c:3462
    SCIP_RETCODE SCIPsolve(SCIP *scip)
    Definition: scip_solve.c:2635
    SCIP_Real SCIPgetUpperbound(SCIP *scip)
    SCIP_Real SCIPgetGap(SCIP *scip)
    SCIP_Bool SCIPisRelLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
    Definition: var.c:18320
    SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
    Definition: var.c:23868
    SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
    Definition: var.c:23642
    SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
    Definition: var.c:23478
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23900
    SCIP_RETCODE SCIPgetProbvarSum(SCIP *scip, SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
    Definition: scip_var.c:2499
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24142
    int SCIPvarGetProbindex(SCIP_VAR *var)
    Definition: var.c:23662
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
    Definition: scip_var.c:1887
    SCIP_RETCODE SCIPchgVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_var.c:6141
    SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
    Definition: var.c:23490
    SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
    Definition: scip_var.c:10113
    SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
    Definition: scip_var.c:2166
    SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
    Definition: var.c:23443
    SCIP_RETCODE SCIPchgVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_var.c:6230
    SCIP_RETCODE SCIPcreateVar(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
    Definition: scip_var.c:120
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24120
    SCIP_VAR * SCIPvarGetTransVar(SCIP_VAR *var)
    Definition: var.c:23672
    SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
    Definition: scip_var.c:5372
    SCIP_Real SCIPvarGetNLPSol(SCIP_VAR *var)
    Definition: var.c:24691
    SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:1853
    void SCIPsortDownRealRealPtr(SCIP_Real *realarray1, SCIP_Real *realarray2, void **ptrarray, int len)
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    static SCIP_DECL_EVENTEXEC(eventExecLPsol)
    Definition: heur_dualval.c:195
    #define DEFAULT_RANKVALUE
    Definition: heur_dualval.c:101
    #define DEFAULT_ONLYCHEAPER
    Definition: heur_dualval.c:93
    static SCIP_RETCODE createSolFromSubScipSol(SCIP *scip, SCIP_HEUR *heur, SCIP_SOL **sol, SCIP_SOL *subsol)
    Definition: heur_dualval.c:766
    static SCIP_RETCODE addSetppcConstraints(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_HEURDATA *heurdata)
    Definition: heur_dualval.c:548
    static SCIP_DECL_HEUREXIT(heurExitDualval)
    #define DEFAULT_LAMBDAOBJ
    Definition: heur_dualval.c:109
    #define DEFAULT_MINGAP
    Definition: heur_dualval.c:107
    #define DEFAULT_HEURVERBLEVEL
    Definition: heur_dualval.c:99
    static SCIP_RETCODE addLogicOrConstraints(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_HEURDATA *heurdata)
    Definition: heur_dualval.c:481
    #define HEUR_TIMING
    Definition: heur_dualval.c:84
    static SCIP_RETCODE createSolFromNLP(SCIP *scip, SCIP_HEUR *heur, SCIP_SOL **sol)
    #define HEUR_FREQOFS
    Definition: heur_dualval.c:82
    static SCIP_RETCODE computeRanks(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_Real *absranks, SCIP_Real *ranks, SCIP_VAR **sortedvars)
    #define HEUR_DESC
    Definition: heur_dualval.c:78
    static SCIP_RETCODE freeMemory(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_SOL *transsol, SCIP_Real *absranks, SCIP_Real *ranks, SCIP_VAR **sortedvars, SCIP_Bool beforeswitching, SCIP_Bool clearswitchedvars)
    #define DEFAULT_RELAXINDICATORS
    Definition: heur_dualval.c:95
    static SCIP_DECL_HEUREXEC(heurExecDualval)
    static SCIP_RETCODE releaseHashmapNLPRows(SCIP *scip, SCIP_HASHMAP *hashmap)
    Definition: heur_dualval.c:314
    static SCIP_RETCODE addLinearConstraints(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_Bool addcombconss, SCIP_Bool addcontconss, SCIP_HEURDATA *heurdata)
    Definition: heur_dualval.c:346
    #define DEFAULT_FORCEIMPROVEMENTS
    Definition: heur_dualval.c:92
    #define HEUR_DISPCHAR
    Definition: heur_dualval.c:79
    #define HEUR_MAXDEPTH
    Definition: heur_dualval.c:83
    #define HEUR_PRIORITY
    Definition: heur_dualval.c:80
    static SCIP_RETCODE storeSolution(SCIP *scip, SCIP_HEUR *heur, SCIP_RESULT *result, SCIP_SOL *transsol, SCIP_SOL *bestsol)
    #define DEFAULT_LAMBDASLACK
    Definition: heur_dualval.c:108
    static SCIP_DECL_EVENTEXIT(eventExitLPsol)
    Definition: heur_dualval.c:182
    #define HEUR_NAME
    Definition: heur_dualval.c:77
    static SCIP_DECL_HEURINIT(heurInitDualval)
    #define DEFAULT_RELAXCONTVARS
    Definition: heur_dualval.c:96
    static SCIP_DECL_HEURCOPY(heurCopyDualval)
    #define DEFAULT_MAXCALLS
    Definition: heur_dualval.c:102
    static SCIP_Real maximalslack(SCIP *scip, SCIP_HEURDATA *heurdata)
    static SCIP_RETCODE SCIPincludeEventHdlrLPsol(SCIP *scip, SCIP_HEURDATA *heurdata)
    Definition: heur_dualval.c:245
    static SCIP_RETCODE createSubSCIP(SCIP *scip, SCIP_HEURDATA *heurdata)
    Definition: heur_dualval.c:857
    static SCIP_DECL_HEUREXITSOL(heurExitsolDualval)
    #define BIG_VALUE
    static SCIP_DECL_HEURFREE(heurFreeDualval)
    static SCIP_RETCODE fixDiscreteVars(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_SOL *refpoint, SCIP_SOL **transsol)
    static SCIP_RETCODE addKnapsackConstraints(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_HEURDATA *heurdata)
    Definition: heur_dualval.c:640
    #define DEFAULT_DYNAMICDEPTH
    Definition: heur_dualval.c:103
    static SCIP_DECL_HEURINITSOL(heurInitsolDualval)
    #define DEFAULT_ONLYLEAVES
    Definition: heur_dualval.c:94
    static SCIP_RETCODE freeSubSCIP(SCIP *scip, SCIP_HEURDATA *heurdata)
    #define DEFAULT_NLPVERBLEVEL
    Definition: heur_dualval.c:100
    static SCIP_RETCODE releaseHashmapEntries(SCIP *scip, SCIP_HASHMAP *hashmap, SCIP_Bool isvarmap)
    Definition: heur_dualval.c:271
    #define EVENTHDLR_DESC
    Definition: heur_dualval.c:88
    #define DEFAULT_MAXEQUALRANKS
    Definition: heur_dualval.c:104
    #define HEUR_FREQ
    Definition: heur_dualval.c:81
    static SCIP_RETCODE addVarboundConstraints(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_Bool addcombconss, SCIP_Bool addcontconss, SCIP_HEURDATA *heurdata)
    Definition: heur_dualval.c:423
    #define HEUR_USESSUBSCIP
    Definition: heur_dualval.c:85
    static SCIP_RETCODE addLinearConstraintsToNlp(SCIP *scip, SCIP_Bool addcombconss, SCIP_Bool addcontconss, SCIP_HEURDATA *heurdata)
    Definition: heur_dualval.c:712
    static SCIP_DECL_EVENTINIT(eventInitLPsol)
    Definition: heur_dualval.c:169
    #define EVENTHDLR_NAME
    Definition: heur_dualval.c:87
    primal heuristic that uses dualvalues for successive switching variable values
    memory allocation routines
    #define BMSclearMemory(ptr)
    Definition: memory.h:129
    #define BMSclearMemoryArray(ptr, num)
    Definition: memory.h:130
    public methods for managing constraints
    public methods for managing events
    public methods for primal heuristics
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    public data structures and miscellaneous methods
    methods for sorting joint arrays of various types
    public methods for NLP management
    public methods for primal CIP solutions
    public methods for problem variables
    public methods for branching rule plugins and branching
    public methods for constraint handler plugins and constraints
    public methods for problem copies
    public methods for event handler plugins and event handlers
    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 nonlinear relaxation
    public methods for NLPI solver interfaces
    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 SCIP variables
    #define SCIP_EVENTTYPE_FIRSTLPSOLVED
    Definition: type_event.h:101
    struct SCIP_EventhdlrData SCIP_EVENTHDLRDATA
    Definition: type_event.h:160
    #define SCIP_EVENTTYPE_LPSOLVED
    Definition: type_event.h:102
    type and macro definitions related to algebraic expressions
    @ SCIP_EXPRCURV_LINEAR
    Definition: type_expr.h:65
    struct SCIP_HeurData SCIP_HEURDATA
    Definition: type_heur.h:77
    @ SCIP_LPSOLSTAT_OPTIMAL
    Definition: type_lp.h:44
    @ SCIP_VERBLEVEL_HIGH
    Definition: type_message.h:61
    @ SCIP_NLPSOLSTAT_FEASIBLE
    Definition: type_nlpi.h:162
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_CUTOFF
    Definition: type_result.h:48
    @ 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_ERROR
    Definition: type_retcode.h:43
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_STAGE_SOLVING
    Definition: type_set.h:53
    @ SCIP_STATUS_OPTIMAL
    Definition: type_stat.h:43
    @ SCIP_STATUS_INFEASIBLE
    Definition: type_stat.h:44
    #define SCIP_HEURTIMING_DURINGLPLOOP
    Definition: type_timing.h:81
    @ SCIP_VARTYPE_CONTINUOUS
    Definition: type_var.h:71
    @ SCIP_VARTYPE_BINARY
    Definition: type_var.h:64