SCIP

    Solving Constraint Integer Programs

    concsolver_scip.c
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-2026 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file concsolver_scip.c
    26 * @ingroup PARALLEL
    27 * @brief implementation of concurrent solver interface for SCIP
    28 * @author Leona Gottwald
    29 * @author Marc Pfetsch
    30 */
    31
    32/* activate the define below for a feasibility check of the solutions transferred to the main SCIP. */
    33/* #define SCIP_CHECK_MAINSCIP_SOLUTION */
    34
    35/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    36
    38#include "scip/boundstore.h"
    39#include "scip/concsolver.h"
    41#include "scip/concurrent.h"
    42#include "scip/pub_disp.h"
    43#include "scip/pub_event.h"
    44#include "scip/pub_heur.h"
    45#include "scip/pub_message.h"
    46#include "scip/pub_misc.h"
    47#include "scip/pub_paramset.h"
    48#include "scip/pub_sol.h"
    49#include "scip/pub_var.h"
    51#include "scip/scip_copy.h"
    52#include "scip/scip_event.h"
    53#include "scip/scip_general.h"
    54#include "scip/scip_heur.h"
    55#include "scip/scip_mem.h"
    56#include "scip/scip_message.h"
    57#include "scip/scip_numerics.h"
    58#include "scip/scip_param.h"
    59#include "scip/scip_prob.h"
    60#include "scip/scip_sol.h"
    61#include "scip/scip_solve.h"
    63#include "scip/scip_timing.h"
    64#include "scip/syncstore.h"
    65#include "scip/prop_symmetry.h"
    66
    67/* event handler for synchronization */
    68#define EVENTHDLR_NAME "sync"
    69#define EVENTHDLR_DESC "event handler for synchronization of concurrent scip solvers"
    70
    71/*
    72 * Data structures
    73 */
    74
    75/** event handler data */
    76struct SCIP_EventhdlrData
    77{
    78 int filterpos;
    79};
    80
    81/*
    82 * Callback methods of event handler
    83 */
    84
    85/** destructor of event handler to free user data (called when SCIP is exiting) */
    86static
    87SCIP_DECL_EVENTFREE(eventFreeSync)
    88{ /*lint --e{715}*/
    89 SCIP_EVENTHDLRDATA* eventhdlrdata;
    90
    91 assert(scip != NULL);
    92 assert(eventhdlr != NULL);
    93
    95
    96 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
    97 assert(eventhdlrdata != NULL);
    98
    99 SCIPfreeBlockMemory(scip, &eventhdlrdata);
    100
    101 SCIPeventhdlrSetData(eventhdlr, NULL);
    102
    103 return SCIP_OKAY;
    104}
    105
    106/** initialization method of event handler (called after problem was transformed) */
    107static
    109{ /*lint --e{715}*/
    110 SCIP_EVENTHDLRDATA* eventhdlrdata;
    111 SCIP_SYNCSTORE* syncstore;
    112
    113 assert(scip != NULL);
    114 assert(eventhdlr != NULL);
    115
    117
    118 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
    119 assert(eventhdlrdata != NULL);
    120
    121 syncstore = SCIPgetSyncstore(scip);
    122 assert(syncstore != NULL);
    123
    124 if( eventhdlrdata->filterpos < 0 && SCIPsyncstoreIsInitialized(syncstore) )
    125 {
    126 /* notify SCIP that your event handler wants to react on synchronization events */
    127 SCIP_CALL( SCIPcatchEvent(scip, SCIP_EVENTTYPE_SYNC, eventhdlr, NULL, &eventhdlrdata->filterpos) );
    128 }
    129
    130 return SCIP_OKAY;
    131}
    132
    133/** deinitialization method of event handler (called before transformed problem is freed) */
    134static
    136{ /*lint --e{715}*/
    137 SCIP_EVENTHDLRDATA* eventhdlrdata;
    138
    139 assert(scip != NULL);
    140 assert(eventhdlr != NULL);
    141
    143
    144 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
    145 assert(eventhdlrdata != NULL);
    146
    147 /* notify SCIP that your event handler wants to drop the event type synchronization found */
    148 if( eventhdlrdata->filterpos >= 0 )
    149 {
    150 SCIP_CALL( SCIPdropEvent(scip, SCIP_EVENTTYPE_SYNC, eventhdlr, NULL, eventhdlrdata->filterpos) );
    151 eventhdlrdata->filterpos = -1;
    152 }
    153
    154 return SCIP_OKAY;
    155}
    156
    157/** execution method of event handler */
    158static
    160{ /*lint --e{715}*/
    161 assert(eventhdlr != NULL);
    162 assert(event != NULL);
    163 assert(scip != NULL);
    164
    166
    168
    169 return SCIP_OKAY;
    170}
    171
    172
    173/** includes event handler for synchronization found */
    174static
    176 SCIP* scip /**< SCIP data structure */
    177 )
    178{
    179 SCIP_EVENTHDLR* eventhdlr;
    180 SCIP_EVENTHDLRDATA* eventhdlrdata;
    181
    182 SCIP_CALL( SCIPallocBlockMemory(scip, &eventhdlrdata) );
    183 eventhdlrdata->filterpos = -1;
    184
    185 /* create event handler for events on watched variables */
    186 SCIP_CALL( SCIPincludeEventhdlrBasic(scip, &eventhdlr, EVENTHDLR_NAME, EVENTHDLR_DESC, eventExecSync, eventhdlrdata) );
    187 assert(eventhdlr != NULL);
    188
    189 SCIP_CALL( SCIPsetEventhdlrFree(scip, eventhdlr, eventFreeSync) );
    190 SCIP_CALL( SCIPsetEventhdlrInit(scip, eventhdlr, eventInitSync) );
    191 SCIP_CALL( SCIPsetEventhdlrExit(scip, eventhdlr, eventExitSync) );
    192
    193 return SCIP_OKAY;
    194}
    195
    196/** data for a concurrent solver type */
    197struct SCIP_ConcSolverTypeData
    198{
    199 SCIP_Bool loademphasis; /**< should emphasis settings be loaded when creating an instance of this concurrent solver */
    200 SCIP_PARAMEMPHASIS emphasis; /**< parameter emphasis that will be loaded if loademphasis is true */
    201};
    202
    203/** data for a concurrent solver */
    204struct SCIP_ConcSolverData
    205{
    206 SCIP* solverscip; /**< the concurrent solvers private SCIP data structure */
    207 SCIP_VAR** vars; /**< array of variables in the order of the main SCIP's variable array */
    208 int nvars; /**< number of variables in the above arrays */
    209};
    210
    211/** Disable dual reductions that might cut off optimal solutions. Although they keep at least
    212 * one optimal solution intact, communicating these bounds may cut off all optimal solutions,
    213 * if different optimal solutions were kept in different concurrent solvers. */
    214static
    216 SCIP* scip /**< SCIP data structure */
    217 )
    218{
    219 SCIP_Bool commvarbnds;
    220
    221 SCIP_CALL( SCIPgetBoolParam(scip, "concurrent/commvarbnds", &commvarbnds) );
    222
    223 if( !commvarbnds )
    224 return SCIP_OKAY;
    225
    226 SCIP_CALL( SCIPsetBoolParam(scip, "misc/allowstrongdualreds", FALSE) );
    227
    228 return SCIP_OKAY;
    229}
    230
    231/** sets the child selection rule based on the index of the concurrent solver */
    232static
    234 SCIP_CONCSOLVER* concsolver /**< the concurrent solver */
    235 )
    236{
    238 static const char childsel[] = { 'h', 'i', 'p', 'r', 'l', 'd', 'u' };
    239
    240 assert(concsolver != NULL);
    241
    242 data = SCIPconcsolverGetData(concsolver);
    243 assert(data != NULL);
    244
    245 SCIP_CALL( SCIPsetCharParam(data->solverscip, "nodeselection/childsel", childsel[SCIPconcsolverGetIdx(concsolver) % 7]) );
    246
    247 return SCIP_OKAY;
    248}
    249
    250/** initialize the concurrent SCIP solver, i.e., setup the copy of the problem and the
    251 * mapping of the variables */
    252static
    254 SCIP* scip, /**< the main SCIP instance */
    255 SCIP_CONCSOLVER* concsolver /**< the concurrent solver to set up */
    256 )
    257{
    258 SCIP_HASHMAP* varmapfw;
    260 SCIP_VAR** mainvars;
    261 SCIP_VAR** mainfixedvars;
    262 SCIP_VAR** mainallvars;
    263 SCIP_Bool symmetrybefore;
    264 SCIP_Bool valid;
    265 int nmainvars;
    266 int nmainfixedvars;
    267 int* varperm;
    268 int cnt;
    269 int v;
    270
    271 assert(scip != NULL);
    272 assert(concsolver != NULL);
    273
    274 data = SCIPconcsolverGetData(concsolver);
    275 assert(data != NULL);
    276
    277 /* we force the copying of symmetry constraints that may have been detected during a central presolving step;
    278 * otherwise, the copy may become invalid */
    279 SCIP_CALL( SCIPgetBoolParam(scip, "concurrent/symmetrybefore", &symmetrybefore) );
    280 if( symmetrybefore
    281 && ( SCIPsetBoolParam(scip, "constraints/orbitope_full/forceconscopy", TRUE) != SCIP_OKAY
    282 || SCIPsetBoolParam(scip, "constraints/orbitope_pp/forceconscopy", TRUE) != SCIP_OKAY
    283 || SCIPsetBoolParam(scip, "constraints/orbisack/forceconscopy", TRUE) != SCIP_OKAY
    284 || SCIPsetBoolParam(scip, "constraints/symresack/forceconscopy", TRUE) != SCIP_OKAY ) )
    285 {
    286 SCIPdebugMessage("Could not force copying of symmetry constraints\n");
    287 }
    288
    289 /* get number of active variables in main SCIP */
    290 nmainvars = SCIPgetNVars(scip);
    291 mainvars = SCIPgetVars(scip);
    292
    293 /* create the concurrent solver's SCIP instance and set up the problem */
    294 SCIP_CALL( SCIPcreate(&data->solverscip) );
    296 SCIP_CALL( SCIPhashmapCreate(&varmapfw, SCIPblkmem(data->solverscip), nmainvars + SCIPgetNFixedVars(scip)) );
    297 SCIP_CALL( SCIPcopyConsCompression(scip, data->solverscip, varmapfw, NULL, SCIPconcsolverGetName(concsolver),
    298 NULL, NULL, 0, TRUE, FALSE, FALSE, FALSE, &valid) );
    299 assert(valid);
    300
    301 /* include symmetry propagator if symmetry wasn't computed before and user wants symmetry */
    302 if( !symmetrybefore )
    303 {
    304 SCIP_CALL( SCIPincludePropSymmetry(data->solverscip) );
    305 }
    306
    307 /* Note that because some aggregations or fixed variables cannot be resolved by some constraint handlers (in
    308 * particular cons_sos1, cons_sos2, cons_and), the copied problem may contain more variables than the original
    309 * problem has active variables. */
    310 data->nvars = SCIPgetNOrigVars(data->solverscip);
    311 assert( nmainvars <= data->nvars );
    312 assert(data->nvars <= SCIPgetNVars(scip) + SCIPgetNFixedVars(scip));
    313
    314 /* allocate memory for the arrays to store the variable mapping */
    315 SCIP_CALL( SCIPallocBlockMemoryArray(data->solverscip, &data->vars, data->nvars) );
    316 SCIP_CALL( SCIPallocClearBufferArray(data->solverscip, &varperm, data->nvars) );
    317
    318 /* In the following, we create a variable mapping between the solver and main SCIP variables. The mapping is created
    319 * by first retrieving the active variables, then the variables that are "fixed" in the main SCIP. This order is
    320 * taken because when performing SCIPcopyConsCompression, the active variables are copied first. This is followed by
    321 * the variables, which might involve (multi-)aggregated/fixed variables and coupling linear constraints. The
    322 * latter variables appear in the main SCIP as "fixed" variables. */
    323
    324 /* set up the arrays for the variable mapping */
    325 SCIP_CALL( SCIPallocBufferArray(data->solverscip, &mainallvars, data->nvars) );
    326 for( v = 0; v < nmainvars; v++ )
    327 {
    328 SCIP_VAR* var;
    329 int idx;
    330
    331 var = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, mainvars[v]);
    332 assert(var != NULL);
    333 idx = SCIPvarGetProbindex(var);
    334 assert(0 <= idx && idx < data->nvars);
    335
    336 data->vars[v] = var;
    337 assert(varperm[idx] == 0);
    338 varperm[idx] = v;
    339
    340 /* for copying solutions below */
    341 mainallvars[v] = mainvars[v];
    342 }
    343
    344 nmainfixedvars = SCIPgetNFixedVars(scip);
    345 mainfixedvars = SCIPgetFixedVars(scip);
    346 cnt = nmainvars;
    347 for( v = 0; v < nmainfixedvars; v++ )
    348 {
    349 SCIP_VAR* var;
    350 int idx;
    351
    352 var = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, mainfixedvars[v]);
    353 if( var != NULL )
    354 {
    355 idx = SCIPvarGetProbindex(var);
    356 if( idx >= 0 )
    357 {
    358 assert(idx < data->nvars);
    359
    360 data->vars[cnt] = var;
    361 assert(varperm[idx] == 0);
    362 varperm[idx] = cnt;
    363
    364 /* for copying solutions below */
    365 mainallvars[cnt] = mainfixedvars[v];
    366 ++cnt;
    367 }
    368 }
    369 }
    370 assert( cnt == data->nvars );
    371
    372 /* transfer solutions from original problem to concurrent instances */
    373 if( SCIPgetNSols(scip) != 0 )
    374 {
    375 SCIP_Bool stored;
    376 SCIP_SOL* mainsol;
    377 SCIP_SOL* solversol;
    378
    379 mainsol = SCIPgetBestSol(scip);
    380 SCIP_CALL( SCIPcreateSol(data->solverscip, &solversol, NULL) );
    381 for( v = 0; v < data->nvars; ++v )
    382 {
    383 SCIP_Real val;
    384
    385 val = SCIPgetSolVal(scip, mainsol, mainallvars[v]);
    386 assert(data->vars[v] != NULL);
    387 SCIP_CALL( SCIPsetSolVal(data->solverscip, solversol, data->vars[v], val) );
    388 }
    389 SCIP_CALL( SCIPaddSolFree(data->solverscip, &solversol, &stored) );
    390 assert(stored);
    391 }
    392
    393 /* create the concurrent data structure for the concurrent solver's SCIP */
    394 SCIP_CALL( SCIPcreateConcurrent(data->solverscip, concsolver, varperm, data->nvars) );
    395 SCIPfreeBufferArray(data->solverscip, &mainallvars);
    396 SCIPfreeBufferArray(data->solverscip, &varperm);
    397
    398 /* free the hashmap */
    399 SCIPhashmapFree(&varmapfw);
    400
    401 return SCIP_OKAY;
    402}
    403
    404/** creates an instance of a concurrent SCIP solver */
    405static
    406SCIP_DECL_CONCSOLVERCREATEINST(concsolverScipCreateInstance)
    407{
    408 char filename[SCIP_MAXSTRLEN];
    410 SCIP_CONCSOLVERTYPEDATA* typedata;
    411 SCIP_Bool changechildsel;
    412 char* prefix;
    413
    414 assert(scip != NULL);
    415 assert(concsolvertype != NULL);
    416 assert(concsolver != NULL);
    417
    418 typedata = SCIPconcsolverTypeGetData(concsolvertype);
    419
    420 SCIP_ALLOC( BMSallocMemory(&data) );
    421 SCIPconcsolverSetData(concsolver, data);
    422
    423 SCIP_CALL( initConcsolver(scip, concsolver) );
    424
    425 /* check if emphasis setting should be loaded */
    426 if( typedata->loademphasis )
    427 {
    428 SCIP_PARAM** params;
    429 SCIP_PARAM** fixedparams;
    430 int nparams;
    431 int nfixedparams;
    432 int i;
    433
    434 params = SCIPgetParams(data->solverscip);
    435 nparams = SCIPgetNParams(data->solverscip);
    436 SCIP_CALL( SCIPallocBufferArray(data->solverscip, &fixedparams, nparams) );
    437 nfixedparams = 0;
    438
    439 /* fix certain parameters before loading emphasis to avoid setting them to default values */
    440 for( i = 0; i < nparams; ++i )
    441 {
    442 const char* paramname;
    443
    444 paramname = SCIPparamGetName(params[i]);
    445
    446 if( strncmp(paramname, "limits/", 7) == 0 ||
    447 strncmp(paramname, "numerics/", 9) == 0 ||
    448 strncmp(paramname, "memory/", 7) == 0 ||
    449 strncmp(paramname, "concurrent/sync/", 16) == 0 ||
    450 strncmp(paramname, "heuristics/sync/", 16) == 0 ||
    451 strncmp(paramname, "propagating/sync/", 17) == 0 )
    452 {
    453 fixedparams[nfixedparams++] = params[i];
    454 SCIP_CALL( SCIPfixParam(data->solverscip, paramname) );
    455 }
    456 }
    457
    458 SCIP_CALL( SCIPsetEmphasis(data->solverscip, typedata->emphasis, TRUE) );
    459
    460 for( i = 0; i < nfixedparams; ++i )
    461 SCIP_CALL( SCIPunfixParam(data->solverscip, SCIPparamGetName(fixedparams[i])) );
    462
    463 SCIPfreeBufferArray(data->solverscip, &fixedparams);
    464 }
    465
    466 /* load settings file if it exists */
    467 SCIP_CALL( SCIPgetStringParam(scip, "concurrent/paramsetprefix", &prefix) );
    468 (void) SCIPsnprintf(filename, SCIP_MAXSTRLEN, "%s%s.set", prefix, SCIPconcsolverGetName(concsolver));
    469
    470 if( SCIPfileExists(filename) )
    471 {
    472 /* load settings file and print info message */
    473 SCIPinfoMessage(scip, NULL, "reading parameter file <%s> for concurrent solver <%s>\n", filename, SCIPconcsolverGetName(concsolver));
    474 SCIP_CALL( SCIPreadParams(data->solverscip, filename) );
    475 }
    476 else
    477 {
    478 /* print message about missing setting files only in verblevel full */
    479 SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "skipping non existent parameter file <%s> for concurrent solver <%s>\n",
    480 filename, SCIPconcsolverGetName(concsolver));
    481 }
    482
    483 /* include eventhandler for synchronization */
    484 SCIP_CALL( includeEventHdlrSync(data->solverscip) );
    485
    486 /* disable output for subscip */
    487 SCIP_CALL( SCIPsetIntParam(data->solverscip, "display/verblevel", 0) );
    488
    489 /* use wall clock time in subscips */
    490 SCIP_CALL( SCIPsetIntParam(data->solverscip, "timing/clocktype", (int)SCIP_CLOCKTYPE_WALL) );
    491
    492 /* don't catch ctrlc since already caught in main SCIP */
    493 SCIP_CALL( SCIPsetBoolParam(data->solverscip, "misc/catchctrlc", FALSE) );
    494
    495 /* one solver can do all dual reductions and share them with the other solvers */
    496 if( SCIPconcsolverGetIdx(concsolver) != 0 )
    497 {
    498 SCIP_CALL( disableConflictingDualReductions(data->solverscip) );
    499 }
    500
    501 /* set different child selection rules if corresponding parameter is TRUE */
    502 SCIP_CALL( SCIPgetBoolParam(scip, "concurrent/changechildsel", &changechildsel) );
    503 if( changechildsel )
    504 {
    505 SCIP_CALL( setChildSelRule(concsolver) );
    506 }
    507
    508 return SCIP_OKAY;
    509}
    510
    511/** destroys an instance of a concurrent SCIP solver */
    512static
    513SCIP_DECL_CONCSOLVERDESTROYINST(concsolverScipDestroyInstance)
    514{
    516
    517 assert(concsolver != NULL);
    518
    519 data = SCIPconcsolverGetData(concsolver);
    520 assert(data != NULL);
    521 assert(data->solverscip != NULL);
    522
    523 /* free the array with the variable mapping */
    524 SCIPfreeBlockMemoryArray(data->solverscip, &data->vars, data->nvars);
    525
    526 /* free subscip */
    527 SCIP_CALL( SCIPfree(&data->solverscip) );
    528 BMSfreeMemory(&data);
    529 SCIPconcsolverSetData(concsolver, NULL);
    530
    531 return SCIP_OKAY;
    532}
    533
    534/** frees the data of a concurrent solver type */
    535static
    536SCIP_DECL_CONCSOLVERTYPEFREEDATA(concsolverTypeScipFreeData)
    537{
    538 assert(data != NULL);
    539 BMSfreeMemory(data);
    540}
    541
    542/** initializes the random and permutation seeds and enables permutation of constraints and variables */
    543static
    544SCIP_DECL_CONCSOLVERINITSEEDS(concsolverScipInitSeeds)
    545{
    547
    548 assert(concsolver != NULL);
    549
    550 data = SCIPconcsolverGetData(concsolver);
    551 assert(data != NULL);
    552
    553 SCIPinfoMessage(data->solverscip, NULL, "initializing seeds to %d in concurrent solver '%s'\n", (int) seed, SCIPconcsolverGetName(concsolver));
    554
    555 SCIP_CALL( SCIPsetIntParam(data->solverscip, "randomization/randomseedshift", (int) seed) );
    556 SCIP_CALL( SCIPsetIntParam(data->solverscip, "randomization/permutationseed", (int) seed) );
    557 SCIP_CALL( SCIPsetBoolParam(data->solverscip, "randomization/permutevars", TRUE) );
    558 SCIP_CALL( SCIPsetBoolParam(data->solverscip, "randomization/permuteconss", TRUE) );
    559
    560 return SCIP_OKAY;
    561}
    562
    563/** extracts solving status of this concurrent solver and the solving statistics
    564 * into the given SCIP instance
    565 */
    566static
    567SCIP_DECL_CONCSOLVERCOPYSOLVINGDATA(concsolverGetSolvingData)
    568{
    570 int nsols;
    571
    572 assert(scip != NULL);
    573 assert(concsolver != NULL);
    574
    575 data = SCIPconcsolverGetData(concsolver);
    576 assert(data != NULL);
    577 assert(data->solverscip != NULL);
    578
    579 nsols = SCIPgetNSols(data->solverscip);
    580 if( nsols > 0 )
    581 {
    582 SCIP_VAR** mainvars;
    583 SCIP_SOL** solversols;
    584 SCIP_Real* solvals;
    585 int nmainvars;
    586 int i;
    587
    588 mainvars = SCIPgetVars(scip);
    589 nmainvars = SCIPgetNVars(scip);
    590 assert(nmainvars <= data->nvars);
    591
    592 solversols = SCIPgetSols(data->solverscip);
    593
    594 /* allocate buffer array used for translating the solution to the given SCIP */
    595 SCIP_CALL( SCIPallocBufferArray(scip, &solvals, nmainvars) );
    596
    597 /* add the solutions to the given SCIP */
    598 for( i = 0; i < nsols; ++i )
    599 {
    600 SCIP_SOL* mainsol;
    601 SCIP_HEUR* heur;
    602 SCIP_Bool stored;
    603
    604 /* only get the first nmainvars, which correspond to the active variables */
    605 SCIP_CALL( SCIPgetSolVals(data->solverscip, solversols[i], nmainvars, data->vars, solvals) );
    606
    607 heur = SCIPsolGetHeur(solversols[i]);
    608 if( heur != NULL )
    609 heur = SCIPfindHeur(scip, SCIPheurGetName(heur));
    610
    611 SCIP_CALL( SCIPcreateSol(scip, &mainsol, heur) );
    612 SCIP_CALL( SCIPsetSolVals(scip, mainsol, nmainvars, mainvars, solvals) );
    613 SCIP_CALL( SCIPcopySolStats(solversols[i], mainsol) );
    614
    615#ifdef SCIP_CHECK_MAINSCIP_SOLUTION
    616 /* The following sometimes fails because we do not copy aggregations and cons_fixedvar can reject solutions in
    617 * mainscip, because of these. */
    618 {
    619 SCIP_Bool feasible;
    620 SCIP_CALL( SCIPcheckSol(scip, mainsol, TRUE, TRUE, TRUE, TRUE, FALSE, &feasible) );
    621 assert( feasible );
    622 }
    623#endif
    624
    625 SCIP_CALL( SCIPaddSolFree(scip, &mainsol, &stored) );
    626 }
    627
    628 /* free the buffer array */
    629 SCIPfreeBufferArray(scip, &solvals);
    630 }
    631
    632 /* copy solving statistics and status from the solver SCIP to the given SCIP */
    633 SCIP_CALL( SCIPcopyConcurrentSolvingStats(data->solverscip, scip) );
    634
    635 return SCIP_OKAY;
    636}
    637
    638/** execution method of SCIP concsolver solver
    639 *
    640 * Start solving the problem until the solving reaches a limit, gets interrupted, or just finished successfully.
    641 */
    642static
    643SCIP_DECL_CONCSOLVEREXEC(concsolverScipExec)
    644{
    646
    647 assert(concsolver != NULL);
    648 assert(solvingtime != NULL);
    649 assert(nlpiterations != NULL);
    650 assert(nnodes != NULL);
    651
    652 data = SCIPconcsolverGetData(concsolver);
    653 assert(data != NULL);
    654
    655 /* print info message that solving has started */
    656 SCIPinfoMessage(data->solverscip, NULL, "starting solve in concurrent solver '%s'\n", SCIPconcsolverGetName(concsolver));
    657
    658 /* solve */
    659 SCIP_CALL( SCIPsolve(data->solverscip) );
    660
    661 /* first output time */
    662 SCIPinfoMessage(data->solverscip, NULL, " ");
    663 SCIPdispTime(SCIPgetMessagehdlr(data->solverscip), NULL, SCIPgetSolvingTime(data->solverscip), 5);
    664 /* print info message with status */
    665 SCIPinfoMessage(data->solverscip, NULL, ": concurrent solver '%s' stopped with status ", SCIPconcsolverGetName(concsolver));
    666 SCIP_CALL( SCIPprintStatus(data->solverscip, NULL) );
    667 SCIPinfoMessage(data->solverscip, NULL, "\n");
    668
    669 /* set solving statistics */
    670 *solvingtime = SCIPgetSolvingTime(data->solverscip);
    671 *nlpiterations = SCIPgetNLPIterations(data->solverscip);
    672 *nnodes = SCIPgetNNodes(data->solverscip);
    673
    674 return SCIP_OKAY;
    675}
    676
    677/** stops the concurrent solver as soon as possible */
    678static
    679SCIP_DECL_CONCSOLVERSTOP(concsolverScipStop)
    680{
    682
    683 assert(concsolver != NULL);
    684
    685 data = SCIPconcsolverGetData(concsolver);
    686 assert(data != NULL);
    687
    688 SCIP_CALL( SCIPinterruptSolve(data->solverscip) );
    689
    690 return SCIP_OKAY;
    691}
    692
    693/** writes new solutions and global boundchanges to the given synchronization data */
    694static
    695SCIP_DECL_CONCSOLVERSYNCWRITE(concsolverScipSyncWrite)
    696{
    697 SCIP_SOL** sols;
    699 SCIP_BOUNDSTORE* boundstore;
    700 SCIP_STATUS solverstatus;
    701 int concsolverid;
    702 int nsols;
    703 int i;
    704
    705 assert(concsolver != NULL);
    706 assert(syncstore != NULL);
    707 assert(syncdata != NULL);
    708 assert(nsolsshared != NULL);
    709
    710 *nsolsshared = 0;
    711
    712 if ( maxcandsols <= 0 )
    713 return SCIP_OKAY;
    714
    716 return SCIP_OKAY;
    717
    718 data = SCIPconcsolverGetData(concsolver);
    719 assert(data != NULL);
    720 assert(data->solverscip != NULL);
    721 concsolverid = SCIPconcsolverGetIdx(concsolver);
    722 solverstatus = SCIPgetStatus(data->solverscip);
    723
    724 SCIPsyncdataSetStatus(syncdata, solverstatus, concsolverid);
    725 SCIPsyncdataSetLowerbound(syncdata, SCIPgetDualbound(data->solverscip));
    726 SCIPsyncdataSetUpperbound(syncdata, SCIPgetPrimalbound(data->solverscip));
    727
    728 SCIPdebugMessage("syncing in concurrent solver %s\n", SCIPconcsolverGetName(concsolver));
    729
    730 /* consider at most maxcandsols many solutions, and since the solution array is sorted, consider best solutions */
    731 nsols = SCIPgetNSols(data->solverscip);
    732 nsols = MIN(nsols, maxcandsols);
    733 sols = SCIPgetSols(data->solverscip);
    734
    735 for( i = 0; i < nsols; ++i )
    736 {
    737 if( SCIPIsConcurrentSolNew(data->solverscip, sols[i]) )
    738 {
    739 SCIP_Real solobj;
    740 SCIP_Real* solvals;
    741
    742 solobj = SCIPgetSolOrigObj(data->solverscip, sols[i]);
    743
    744 SCIPdebugMessage("adding sol in concurrent solver %s\n", SCIPconcsolverGetName(concsolver));
    745 SCIPsyncdataGetSolutionBuffer(syncstore, syncdata, solobj, concsolverid, &solvals);
    746
    747 /* if syncstore has no place for this solution, we can stop, since the next solution will have
    748 * a worse objective value and thus won't be accepted either
    749 */
    750 if( solvals == NULL )
    751 break;
    752
    753 ++(*nsolsshared);
    754 SCIP_CALL( SCIPgetSolVals(data->solverscip, sols[i], data->nvars, data->vars, solvals) );
    755
    756 /* if we have added the maximum number of solutions we can also stop */
    757 if( *nsolsshared == maxsharedsols )
    758 break;
    759 }
    760 }
    761
    762 boundstore = SCIPgetConcurrentGlobalBoundChanges(data->solverscip);
    763
    764 if( boundstore != NULL )
    765 {
    766 SCIP_CALL( SCIPsyncdataAddBoundChanges(syncstore, syncdata, boundstore) );
    767 }
    768
    769 SCIPsyncdataAddMemTotal(syncdata, SCIPgetMemTotal(data->solverscip));
    770
    771 return SCIP_OKAY;
    772}
    773
    774/** reads the solutions and bounds from the given synchronization data */
    775static
    776SCIP_DECL_CONCSOLVERSYNCREAD(concsolverScipSyncRead)
    777{ /*lint --e{715}*/
    778 SCIP_Real** solvals;
    780 SCIP_BOUNDSTORE* boundstore;
    781 int* concsolverids;
    782 int concsolverid;
    783 int nbndchgs;
    784 int nsols;
    785 int i;
    786
    787 assert(concsolver != NULL);
    788 assert(syncstore != NULL);
    789 assert(syncdata != NULL);
    790 assert(nsolsrecvd != NULL);
    791 assert(ntighterbnds != NULL);
    792 assert(ntighterintbnds != NULL);
    793
    794 *nsolsrecvd = 0;
    795
    796 data = SCIPconcsolverGetData(concsolver);
    797 assert(data != NULL);
    798
    799 concsolverid = SCIPconcsolverGetIdx(concsolver);
    800
    801 /* get solutions from synchronization data */
    802 SCIPsyncdataGetSolutions(syncdata, &solvals, &concsolverids, &nsols);
    803 for( i = 0; i < nsols; ++i )
    804 {
    805 SCIP_SOL* newsol;
    806 SCIP_Bool feasible;
    807
    808 /* do not add own solutions */
    809 if( concsolverids[i] == concsolverid )
    810 continue;
    811
    812 /* solution is from another solver, so translate to this solver's variable space and add it to SCIP */
    813 ++(*nsolsrecvd);
    814 SCIP_CALL( SCIPcreateOrigSol(data->solverscip, &newsol, NULL) );
    815 SCIP_CALL( SCIPsetSolVals(data->solverscip, newsol, data->nvars, data->vars, solvals[i]) );
    816
    817 /* check whether solution is feasible */
    818 SCIP_CALL( SCIPcheckSol(data->solverscip, newsol, FALSE, FALSE, TRUE, TRUE, FALSE, &feasible) );
    819
    820 if( feasible )
    821 {
    822 SCIPdebugMessage("adding solution in concurrent solver %s\n", SCIPconcsolverGetName(concsolver));
    823 SCIP_CALL( SCIPaddConcurrentSol(data->solverscip, newsol) );
    824 }
    825 }
    826
    827 /* get bound changes from the synchronization data and add it to this concurrent solvers SCIP */
    828 *ntighterbnds = 0;
    829 *ntighterintbnds = 0;
    830 boundstore = SCIPsyncdataGetBoundChgs(syncdata);
    831 nbndchgs = SCIPboundstoreGetNChgs(boundstore);
    832
    833 for( i = 0; i < nbndchgs; ++i )
    834 {
    835 SCIP_VAR* var;
    836 SCIP_BOUNDTYPE boundtype;
    837 SCIP_Real newbound;
    838 int idx;
    839
    840 idx = SCIPboundstoreGetChgVaridx(boundstore, i);
    841 assert(0 <= idx && idx < data->nvars);
    842 var = data->vars[idx];
    843 boundtype = SCIPboundstoreGetChgType(boundstore, i);
    844 newbound = SCIPboundstoreGetChgVal(boundstore, i);
    845
    846 SCIP_CALL( SCIPvarGetProbvarBound(&var, &newbound, &boundtype) );
    847
    848 /* cannot change bounds of multi-aggregated variables so do not pass this bound-change to the propagator */
    850 return SCIP_OKAY;
    851
    852 /* if bound is not better then do not pass this bound and do not waste memory for storing this boundchange */
    853 if( boundtype == SCIP_BOUNDTYPE_LOWER && SCIPisGE(data->solverscip, SCIPvarGetLbGlobal(var), newbound) )
    854 return SCIP_OKAY;
    855
    856 if( boundtype == SCIP_BOUNDTYPE_UPPER && SCIPisLE(data->solverscip, SCIPvarGetUbGlobal(var), newbound) )
    857 return SCIP_OKAY;
    858
    859 /* bound is better so incremented counters for statistics and pass it to the sync propagator */
    860 ++(*ntighterbnds);
    861
    863 ++(*ntighterintbnds);
    864
    865 SCIP_CALL( SCIPaddConcurrentBndchg(data->solverscip, var, newbound, boundtype) );
    866 }
    867
    868 return SCIP_OKAY;
    869}
    870
    871
    872/** creates the concurrent SCIP solver plugins and includes them in SCIP */
    874 SCIP* scip /**< SCIP data structure */
    875 )
    876{
    878
    879 assert(scip != NULL);
    880
    881 /* Include concurrent solvers for SCIP for all emphasis settings and without an emphasis setting.
    882 * For the SCIP without an emphasis setting we set the default preferred priority to 1 and for the other types to 0
    883 * so that the default concurrent solve will use multiple SCIP's using settings as specified by the user in the main SCIP.
    884 */
    885 SCIP_CALL( SCIPallocMemory(scip, &data) );
    886 data->loademphasis = FALSE;
    887 SCIP_CALL( SCIPincludeConcsolverType(scip, "scip", 1.0, concsolverScipCreateInstance, concsolverScipDestroyInstance, concsolverScipInitSeeds,
    888 concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
    889 concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
    890
    891 SCIP_CALL( SCIPallocMemory(scip, &data) );
    892 data->loademphasis = TRUE;
    893 data->emphasis = SCIP_PARAMEMPHASIS_DEFAULT;
    894 SCIP_CALL( SCIPincludeConcsolverType(scip, "scip-default", 0.0, concsolverScipCreateInstance, concsolverScipDestroyInstance, concsolverScipInitSeeds,
    895 concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
    896 concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
    897
    898 SCIP_CALL( SCIPallocMemory(scip, &data) );
    899 data->loademphasis = TRUE;
    900 data->emphasis = SCIP_PARAMEMPHASIS_CPSOLVER;
    901 SCIP_CALL( SCIPincludeConcsolverType(scip, "scip-cpsolver", 0.0, concsolverScipCreateInstance, concsolverScipDestroyInstance, concsolverScipInitSeeds,
    902 concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
    903 concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
    904
    905 SCIP_CALL( SCIPallocMemory(scip, &data) );
    906 data->loademphasis = TRUE;
    907 data->emphasis = SCIP_PARAMEMPHASIS_EASYCIP;
    908 SCIP_CALL( SCIPincludeConcsolverType(scip, "scip-easycip", 0.0, concsolverScipCreateInstance, concsolverScipDestroyInstance, concsolverScipInitSeeds,
    909 concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
    910 concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
    911
    912 SCIP_CALL( SCIPallocMemory(scip, &data) );
    913 data->loademphasis = TRUE;
    914 data->emphasis = SCIP_PARAMEMPHASIS_FEASIBILITY;
    915 SCIP_CALL( SCIPincludeConcsolverType(scip, "scip-feas", 0.0, concsolverScipCreateInstance, concsolverScipDestroyInstance, concsolverScipInitSeeds,
    916 concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
    917 concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
    918
    919 SCIP_CALL( SCIPallocMemory(scip, &data) );
    920 data->loademphasis = TRUE;
    921 data->emphasis = SCIP_PARAMEMPHASIS_HARDLP;
    922 SCIP_CALL( SCIPincludeConcsolverType(scip, "scip-hardlp", 0.0, concsolverScipCreateInstance, concsolverScipDestroyInstance, concsolverScipInitSeeds,
    923 concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
    924 concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
    925
    926 SCIP_CALL( SCIPallocMemory(scip, &data) );
    927 data->loademphasis = TRUE;
    928 data->emphasis = SCIP_PARAMEMPHASIS_OPTIMALITY;
    929 SCIP_CALL( SCIPincludeConcsolverType(scip, "scip-opti", 0.0, concsolverScipCreateInstance, concsolverScipDestroyInstance, concsolverScipInitSeeds,
    930 concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
    931 concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
    932
    933 SCIP_CALL( SCIPallocMemory(scip, &data) );
    934 data->loademphasis = TRUE;
    935 data->emphasis = SCIP_PARAMEMPHASIS_COUNTER;
    936 SCIP_CALL( SCIPincludeConcsolverType(scip, "scip-counter", 0.0, concsolverScipCreateInstance, concsolverScipDestroyInstance, concsolverScipInitSeeds,
    937 concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
    938 concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
    939
    940 return SCIP_OKAY;
    941}
    SCIP_Real SCIPboundstoreGetChgVal(SCIP_BOUNDSTORE *boundstore, int i)
    Definition: boundstore.c:191
    SCIP_BOUNDTYPE SCIPboundstoreGetChgType(SCIP_BOUNDSTORE *boundstore, int i)
    Definition: boundstore.c:179
    int SCIPboundstoreGetChgVaridx(SCIP_BOUNDSTORE *boundstore, int i)
    Definition: boundstore.c:167
    int SCIPboundstoreGetNChgs(SCIP_BOUNDSTORE *boundstore)
    Definition: boundstore.c:203
    the interface of the bound store data structure
    SCIP_CONCSOLVERDATA * SCIPconcsolverGetData(SCIP_CONCSOLVER *concsolver)
    Definition: concsolver.c:282
    void SCIPconcsolverSetData(SCIP_CONCSOLVER *concsolver, SCIP_CONCSOLVERDATA *data)
    Definition: concsolver.c:292
    int SCIPconcsolverGetIdx(SCIP_CONCSOLVER *concsolver)
    Definition: concsolver.c:626
    char * SCIPconcsolverGetName(SCIP_CONCSOLVER *concsolver)
    Definition: concsolver.c:303
    SCIP_CONCSOLVERTYPEDATA * SCIPconcsolverTypeGetData(SCIP_CONCSOLVERTYPE *concsolvertype)
    Definition: concsolver.c:170
    data structures for concurrent solvers
    static SCIP_DECL_CONCSOLVERDESTROYINST(concsolverScipDestroyInstance)
    static SCIP_DECL_CONCSOLVERINITSEEDS(concsolverScipInitSeeds)
    static SCIP_DECL_CONCSOLVERSYNCREAD(concsolverScipSyncRead)
    static SCIP_RETCODE initConcsolver(SCIP *scip, SCIP_CONCSOLVER *concsolver)
    static SCIP_DECL_EVENTEXIT(eventExitSync)
    static SCIP_DECL_CONCSOLVERTYPEFREEDATA(concsolverTypeScipFreeData)
    SCIP_RETCODE SCIPincludeConcurrentScipSolvers(SCIP *scip)
    static SCIP_RETCODE disableConflictingDualReductions(SCIP *scip)
    static SCIP_DECL_EVENTINIT(eventInitSync)
    static SCIP_DECL_EVENTFREE(eventFreeSync)
    static SCIP_RETCODE setChildSelRule(SCIP_CONCSOLVER *concsolver)
    static SCIP_DECL_CONCSOLVERSYNCWRITE(concsolverScipSyncWrite)
    static SCIP_DECL_EVENTEXEC(eventExecSync)
    static SCIP_RETCODE includeEventHdlrSync(SCIP *scip)
    static SCIP_DECL_CONCSOLVERSTOP(concsolverScipStop)
    #define EVENTHDLR_DESC
    #define EVENTHDLR_NAME
    static SCIP_DECL_CONCSOLVERCREATEINST(concsolverScipCreateInstance)
    static SCIP_DECL_CONCSOLVEREXEC(concsolverScipExec)
    static SCIP_DECL_CONCSOLVERCOPYSOLVINGDATA(concsolverGetSolvingData)
    implementation of concurrent solver interface for SCIP
    SCIP_RETCODE SCIPcreateConcurrent(SCIP *scip, SCIP_CONCSOLVER *concsolver, int *varperm, int nvars)
    Definition: concurrent.c:67
    SCIP_RETCODE SCIPsynchronize(SCIP *scip)
    Definition: concurrent.c:258
    SCIP_RETCODE SCIPaddConcurrentBndchg(SCIP *scip, SCIP_VAR *var, SCIP_Real val, SCIP_BOUNDTYPE bndtype)
    Definition: concurrent.c:398
    SCIP_RETCODE SCIPcopySolStats(SCIP_SOL *source, SCIP_SOL *target)
    Definition: concurrent.c:416
    SCIP_BOUNDSTORE * SCIPgetConcurrentGlobalBoundChanges(SCIP *scip)
    Definition: concurrent.c:472
    SCIP_Bool SCIPIsConcurrentSolNew(SCIP *scip, SCIP_SOL *sol)
    Definition: concurrent.c:459
    SCIP_RETCODE SCIPcopyConcurrentSolvingStats(SCIP *source, SCIP *target)
    Definition: concurrent.c:577
    SCIP_RETCODE SCIPaddConcurrentSol(SCIP *scip, SCIP_SOL *sol)
    Definition: concurrent.c:383
    helper functions for concurrent scip solvers
    #define NULL
    Definition: def.h:257
    #define SCIP_MAXSTRLEN
    Definition: def.h:278
    #define SCIP_Bool
    Definition: def.h:100
    #define MIN(x, y)
    Definition: def.h:233
    #define SCIP_ALLOC(x)
    Definition: def.h:375
    #define SCIP_STRINGEQ(name, reference, retcode)
    Definition: def.h:454
    #define SCIP_Real
    Definition: def.h:165
    #define TRUE
    Definition: def.h:102
    #define FALSE
    Definition: def.h:103
    #define SCIP_CALL(x)
    Definition: def.h:364
    #define nnodes
    Definition: gastrans.c:74
    SCIP_RETCODE SCIPcopyConsCompression(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, const char *suffix, SCIP_VAR **fixedvars, SCIP_Real *fixedvals, int nfixedvars, SCIP_Bool global, SCIP_Bool enablepricing, SCIP_Bool threadsafe, SCIP_Bool passmessagehdlr, SCIP_Bool *valid)
    Definition: scip_copy.c:2962
    SCIP_Bool SCIPfileExists(const char *filename)
    Definition: misc.c:11057
    SCIP_RETCODE SCIPprintStatus(SCIP *scip, FILE *file)
    Definition: scip_general.c:639
    SCIP_RETCODE SCIPfree(SCIP **scip)
    Definition: scip_general.c:402
    SCIP_RETCODE SCIPcreate(SCIP **scip)
    Definition: scip_general.c:370
    SCIP_STATUS SCIPgetStatus(SCIP *scip)
    Definition: scip_general.c:562
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    SCIP_VAR ** SCIPgetVars(SCIP *scip)
    Definition: scip_prob.c:2201
    int SCIPgetNOrigVars(SCIP *scip)
    Definition: scip_prob.c:2838
    int SCIPgetNFixedVars(SCIP *scip)
    Definition: scip_prob.c:2705
    SCIP_VAR ** SCIPgetFixedVars(SCIP *scip)
    Definition: scip_prob.c:2662
    void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
    Definition: misc.c:3095
    void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3284
    SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
    Definition: misc.c:3061
    void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:208
    void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:225
    SCIP_MESSAGEHDLR * SCIPgetMessagehdlr(SCIP *scip)
    Definition: scip_message.c:88
    void SCIPsetMessagehdlrQuiet(SCIP *scip, SCIP_Bool quiet)
    Definition: scip_message.c:108
    SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
    Definition: scip_param.c:250
    int SCIPgetNParams(SCIP *scip)
    Definition: scip_param.c:1019
    SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
    Definition: scip_param.c:487
    SCIP_RETCODE SCIPreadParams(SCIP *scip, const char *filename)
    Definition: scip_param.c:772
    SCIP_RETCODE SCIPunfixParam(SCIP *scip, const char *name)
    Definition: scip_param.c:385
    SCIP_RETCODE SCIPsetEmphasis(SCIP *scip, SCIP_PARAMEMPHASIS paramemphasis, SCIP_Bool quiet)
    Definition: scip_param.c:882
    SCIP_RETCODE SCIPsetCharParam(SCIP *scip, const char *name, char value)
    Definition: scip_param.c:661
    SCIP_RETCODE SCIPgetStringParam(SCIP *scip, const char *name, char **value)
    Definition: scip_param.c:345
    SCIP_PARAM ** SCIPgetParams(SCIP *scip)
    Definition: scip_param.c:1005
    SCIP_RETCODE SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
    Definition: scip_param.c:429
    SCIP_RETCODE SCIPfixParam(SCIP *scip, const char *name)
    Definition: scip_param.c:367
    SCIP_RETCODE SCIPincludeConcsolverType(SCIP *scip, const char *name, SCIP_Real prefpriodefault, SCIP_DECL_CONCSOLVERCREATEINST((*concsolvercreateinst)), SCIP_DECL_CONCSOLVERDESTROYINST((*concsolverdestroyinst)), SCIP_DECL_CONCSOLVERINITSEEDS((*concsolverinitseeds)), SCIP_DECL_CONCSOLVEREXEC((*concsolverexec)), SCIP_DECL_CONCSOLVERCOPYSOLVINGDATA((*concsolvercopysolvdata)), SCIP_DECL_CONCSOLVERSTOP((*concsolverstop)), SCIP_DECL_CONCSOLVERSYNCWRITE((*concsolversyncwrite)), SCIP_DECL_CONCSOLVERSYNCREAD((*concsolversyncread)), SCIP_DECL_CONCSOLVERTYPEFREEDATA((*concsolvertypefreedata)), SCIP_CONCSOLVERTYPEDATA *data)
    void SCIPdispTime(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, SCIP_Real val, int width)
    Definition: disp.c:643
    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
    const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
    Definition: event.c:396
    SCIP_EVENTHDLRDATA * SCIPeventhdlrGetData(SCIP_EVENTHDLR *eventhdlr)
    Definition: event.c:406
    void SCIPeventhdlrSetData(SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTHDLRDATA *eventhdlrdata)
    Definition: event.c:416
    SCIP_RETCODE SCIPsetEventhdlrFree(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTFREE((*eventfree)))
    Definition: scip_event.c:157
    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_HEUR * SCIPfindHeur(SCIP *scip, const char *name)
    Definition: scip_heur.c:263
    const char * SCIPheurGetName(SCIP_HEUR *heur)
    Definition: heur.c:1467
    #define SCIPfreeBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:110
    BMS_BLKMEM * SCIPblkmem(SCIP *scip)
    Definition: scip_mem.c:57
    #define SCIPallocClearBufferArray(scip, ptr, num)
    Definition: scip_mem.h:126
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPallocMemory(scip, ptr)
    Definition: scip_mem.h:60
    #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
    SCIP_Longint SCIPgetMemTotal(SCIP *scip)
    Definition: scip_mem.c:113
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    SCIP_SYNCSTORE * SCIPgetSyncstore(SCIP *scip)
    SCIP_SOL * SCIPgetBestSol(SCIP *scip)
    Definition: scip_sol.c:2986
    SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
    Definition: scip_sol.c:514
    SCIP_RETCODE SCIPaddSolFree(SCIP *scip, SCIP_SOL **sol, SCIP_Bool *stored)
    Definition: scip_sol.c:3914
    int SCIPgetNSols(SCIP *scip)
    Definition: scip_sol.c:2887
    SCIP_HEUR * SCIPsolGetHeur(SCIP_SOL *sol)
    Definition: sol.c:4274
    SCIP_RETCODE SCIPcreateOrigSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
    Definition: scip_sol.c:829
    SCIP_RETCODE SCIPgetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
    Definition: scip_sol.c:1844
    SCIP_RETCODE SCIPsetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
    Definition: scip_sol.c:1660
    SCIP_SOL ** SCIPgetSols(SCIP *scip)
    Definition: scip_sol.c:2936
    SCIP_RETCODE SCIPcheckSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *feasible)
    Definition: scip_sol.c:4317
    SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1890
    SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
    Definition: scip_sol.c:1569
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1763
    SCIP_RETCODE SCIPinterruptSolve(SCIP *scip)
    Definition: scip_solve.c:3561
    SCIP_RETCODE SCIPsolve(SCIP *scip)
    Definition: scip_solve.c:2611
    SCIP_Real SCIPgetPrimalbound(SCIP *scip)
    SCIP_Longint SCIPgetNNodes(SCIP *scip)
    SCIP_Real SCIPgetDualbound(SCIP *scip)
    SCIP_Longint SCIPgetNLPIterations(SCIP *scip)
    SCIP_Real SCIPgetSolvingTime(SCIP *scip)
    Definition: scip_timing.c:378
    SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_RETCODE SCIPvarGetProbvarBound(SCIP_VAR **var, SCIP_Real *bound, SCIP_BOUNDTYPE *boundtype)
    Definition: var.c:17846
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23418
    SCIP_Bool SCIPvarIsNonimpliedIntegral(SCIP_VAR *var)
    Definition: var.c:23538
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24174
    int SCIPvarGetProbindex(SCIP_VAR *var)
    Definition: var.c:23694
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24152
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    static const char * paramname[]
    Definition: lpi_msk.c:5172
    memory allocation routines
    #define BMSfreeMemory(ptr)
    Definition: memory.h:145
    #define BMSallocMemory(ptr)
    Definition: memory.h:118
    SCIP_Bool SCIPmessagehdlrIsQuiet(SCIP_MESSAGEHDLR *messagehdlr)
    Definition: message.c:910
    const char * SCIPparamGetName(SCIP_PARAM *param)
    Definition: paramset.c:656
    SCIP_RETCODE SCIPincludePropSymmetry(SCIP *scip)
    propagator for symmetry handling
    public methods for displaying runtime statistics
    public methods for managing events
    public methods for primal heuristics
    public methods for message output
    #define SCIPdebugMessage
    Definition: pub_message.h:96
    public data structures and miscellaneous methods
    public methods for handling parameter settings
    public methods for primal CIP solutions
    public methods for problem variables
    public methods for concurrent solving mode
    public methods for problem copies
    public methods for event handler plugins and event handlers
    general public methods
    public methods for primal heuristic plugins and divesets
    public methods for memory management
    public methods for message handling
    public methods for numerical tolerances
    public methods for SCIP parameter handling
    public methods for global and local (sub)problems
    public methods for solutions
    public solving methods
    public methods for querying solving statistics
    public methods for timing
    SCIP_BOUNDSTORE * SCIPsyncdataGetBoundChgs(SCIP_SYNCDATA *syncdata)
    Definition: syncstore.c:624
    void SCIPsyncdataSetUpperbound(SCIP_SYNCDATA *syncdata, SCIP_Real upperbound)
    Definition: syncstore.c:695
    SCIP_RETCODE SCIPsyncdataAddBoundChanges(SCIP_SYNCSTORE *syncstore, SCIP_SYNCDATA *syncdata, SCIP_BOUNDSTORE *boundstore)
    Definition: syncstore.c:778
    void SCIPsyncdataGetSolutions(SCIP_SYNCDATA *syncdata, SCIP_Real ***solvalues, int **solowner, int *nsols)
    Definition: syncstore.c:606
    void SCIPsyncdataSetStatus(SCIP_SYNCDATA *syncdata, SCIP_STATUS status, int solverid)
    Definition: syncstore.c:648
    void SCIPsyncdataSetLowerbound(SCIP_SYNCDATA *syncdata, SCIP_Real lowerbound)
    Definition: syncstore.c:706
    void SCIPsyncdataGetSolutionBuffer(SCIP_SYNCSTORE *syncstore, SCIP_SYNCDATA *syncdata, SCIP_Real solobj, int ownerid, SCIP_Real **buffer)
    Definition: syncstore.c:719
    SCIP_Bool SCIPsyncstoreIsInitialized(SCIP_SYNCSTORE *syncstore)
    Definition: syncstore.c:795
    void SCIPsyncdataAddMemTotal(SCIP_SYNCDATA *syncdata, SCIP_Longint memtotal)
    Definition: syncstore.c:684
    SCIP_STATUS SCIPsyncdataGetStatus(SCIP_SYNCDATA *syncdata)
    Definition: syncstore.c:521
    the function declarations for the synchronization store
    @ SCIP_CLOCKTYPE_WALL
    Definition: type_clock.h:45
    struct SCIP_ConcSolverTypeData SCIP_CONCSOLVERTYPEDATA
    struct SCIP_ConcSolverData SCIP_CONCSOLVERDATA
    #define SCIP_EVENTTYPE_SYNC
    Definition: type_event.h:118
    struct SCIP_EventhdlrData SCIP_EVENTHDLRDATA
    Definition: type_event.h:160
    @ SCIP_BOUNDTYPE_UPPER
    Definition: type_lp.h:58
    @ SCIP_BOUNDTYPE_LOWER
    Definition: type_lp.h:57
    enum SCIP_BoundType SCIP_BOUNDTYPE
    Definition: type_lp.h:60
    @ SCIP_VERBLEVEL_FULL
    Definition: type_message.h:62
    @ SCIP_PARAMEMPHASIS_DEFAULT
    Definition: type_paramset.h:70
    @ SCIP_PARAMEMPHASIS_CPSOLVER
    Definition: type_paramset.h:72
    @ SCIP_PARAMEMPHASIS_HARDLP
    Definition: type_paramset.h:75
    @ SCIP_PARAMEMPHASIS_FEASIBILITY
    Definition: type_paramset.h:74
    @ SCIP_PARAMEMPHASIS_EASYCIP
    Definition: type_paramset.h:73
    @ SCIP_PARAMEMPHASIS_COUNTER
    Definition: type_paramset.h:77
    @ SCIP_PARAMEMPHASIS_OPTIMALITY
    Definition: type_paramset.h:76
    enum SCIP_ParamEmphasis SCIP_PARAMEMPHASIS
    Definition: type_paramset.h:84
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_STATUS_UNKNOWN
    Definition: type_stat.h:42
    enum SCIP_Status SCIP_STATUS
    Definition: type_stat.h:64
    @ SCIP_VARSTATUS_MULTAGGR
    Definition: type_var.h:56