SCIP

    Solving Constraint Integer Programs

    branch_cloud.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 branch_cloud.c
    26 * @ingroup DEFPLUGINS_BRANCH
    27 * @brief cloud branching rule
    28 * @author Timo Berthold
    29 * @author Domenico Salvagnin
    30 *
    31 * Branching rule based on muliple optimal solutions to the current LP relaxation. See@n
    32 * Cloud Branching@n
    33 * Timo Berthold and Domenico Salvagnin@n
    34 * Integration of AI and OR Techniques in Constraint Programming for Combinatorial Optimization Problems, CPAIOR 2013, LNCS 7874@n
    35 * Preliminary version available as <a href="http://opus4.kobv.de/opus4-zib/frontdoor/index/index/docId/1730">ZIB-Report 13-01</a>.
    36 */
    37
    38/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    39
    42#include "scip/branch_cloud.h"
    44#include "scip/pub_branch.h"
    45#include "scip/pub_lp.h"
    46#include "scip/pub_message.h"
    47#include "scip/pub_tree.h"
    48#include "scip/pub_var.h"
    49#include "scip/scip_branch.h"
    50#include "scip/scip_exact.h"
    51#include "scip/scip_general.h"
    52#include "scip/scip_lp.h"
    53#include "scip/scip_mem.h"
    54#include "scip/scip_message.h"
    55#include "scip/scip_numerics.h"
    56#include "scip/scip_param.h"
    57#include "scip/scip_prob.h"
    58#include "scip/scip_sol.h"
    60#include "scip/scip_timing.h"
    61#include "scip/scip_tree.h"
    62#include "scip/scip_var.h"
    63
    64
    65#define BRANCHRULE_NAME "cloud"
    66#define BRANCHRULE_DESC "branching rule that considers several alternative LP optima"
    67#define BRANCHRULE_PRIORITY 0
    68#define BRANCHRULE_MAXDEPTH -1
    69#define BRANCHRULE_MAXBOUNDDIST 1.0
    70
    71#define DEFAULT_USECLOUD TRUE /**< should a cloud of points be used? */
    72#define DEFAULT_USEUNION FALSE /**< should the union of candidates be used? */
    73#define DEFAULT_MAXPOINTS -1 /**< maximum number of points for the cloud (-1 means no limit) */
    74#define DEFAULT_MINSUCCESSRATE 0.0 /**< minimum success rate for the cloud */
    75#define DEFAULT_MINSUCCESSUNION 0.0 /**< minimum success rate for the union */
    76#define DEFAULT_MAXDEPTHUNION 65000 /**< maximum depth for the union */
    77#define DEFAULT_ONLYF2 FALSE /**< should only F2 be used? */
    78
    79/*
    80 * Data structures
    81 */
    82
    83/** branching rule data */
    84struct SCIP_BranchruleData
    85{
    86 int lastcand; /**< last evaluated candidate of last branching rule execution */
    87 SCIP_Bool usecloud; /**< should a cloud of points be used? */
    88 SCIP_Bool useunion; /**< should the union of candidates be used? */
    89 SCIP_Bool onlyF2; /**< should only F2 be used? */
    90 int maxpoints; /**< maximum number of points for the cloud (-1 means no limit) */
    91 SCIP_Real minsuccessrate; /**< minimum success rate for the cloud */
    92 SCIP_Real minsuccessunion; /**< minimum success rate for the union */
    93 SCIP_CLOCK* cloudclock; /**< clock for cloud diving */
    94 SCIP_Bool* skipdown; /**< should down branch be skiped? */
    95 SCIP_Bool* skipup; /**< should up branch be skiped? */
    96 int ntried; /**< number of times the cloud was tried */
    97 int ntriedunions; /**< number of times the cloud was tried */
    98 int nuseful; /**< number of times the cloud was useful (at least one LP skipped) */
    99 int nusefulunions; /**< number of times the union was useful (took candidate from new list) */
    100 int ncloudpoints; /**< sum of cloud points taken over all nodes with at least two poitns in cloud */
    101 int nsavedlps; /**< sum of saved LPs taken over all nodes with at least two points in cloud */
    102 int maxdepthunion; /**< maximum depth for the union */
    103 int skipsize; /**< size of skipdown and skipup array */
    104};
    105
    106/*
    107 * Callback methods of branching rule
    108 */
    109
    110/** copy method for branchrule plugins (called when SCIP copies plugins) */
    111static
    112SCIP_DECL_BRANCHCOPY(branchCopyCloud)
    113{ /*lint --e{715}*/
    114 assert(scip != NULL);
    115 assert(branchrule != NULL);
    116
    118
    119 /* call inclusion method of branchrule */
    121
    122 return SCIP_OKAY;
    123}
    124
    125/** destructor of branching rule to free user data (called when SCIP is exiting) */
    126static
    127SCIP_DECL_BRANCHFREE(branchFreeCloud)
    128{ /*lint --e{715}*/
    129 SCIP_BRANCHRULEDATA* branchruledata;
    130
    131 /* free branching rule data */
    132 branchruledata = SCIPbranchruleGetData(branchrule);
    133
    134 if( branchruledata->cloudclock != NULL)
    135 {
    137 int ntried;
    138 int nuseful;
    139 int ncloudpoints;
    140 int nsavedlps;
    141
    142 ntried = branchruledata->ntried;
    143 nuseful = branchruledata->nuseful;
    144 ncloudpoints = branchruledata->ncloudpoints;
    145 nsavedlps = branchruledata->nsavedlps;
    146
    147 SCIPstatisticMessage("time spent diving in cloud branching: %g\n", SCIPgetClockTime(scip, branchruledata->cloudclock));
    148 SCIPstatisticMessage("cloud branching tried: %6d found cloud: %6d \n", ntried, nuseful);
    149 SCIPstatisticMessage("cloud used points: %6d saved LPs: %6d \n", ncloudpoints, nsavedlps);
    150 SCIPstatisticMessage("cloud success rates useful/tried: %8.6g points/useful: %8.6g saved/useful: %8.6g \n",
    151 ntried == 0 ? -1 : (SCIP_Real)nuseful / ntried, nuseful == 0 ? -1 : (SCIP_Real)ncloudpoints / nuseful, nuseful == 0 ? -1 : (SCIP_Real)nsavedlps / nuseful);
    152 )
    153
    154 SCIP_CALL( SCIPfreeClock(scip, &(branchruledata->cloudclock)) );
    155 }
    156
    157 SCIPfreeBlockMemoryArrayNull(scip, &branchruledata->skipdown, branchruledata->skipsize);
    158 SCIPfreeBlockMemoryArrayNull(scip, &branchruledata->skipup, branchruledata->skipsize);
    159
    160 SCIPfreeBlockMemory(scip, &branchruledata);
    161 SCIPbranchruleSetData(branchrule, NULL);
    162
    163 return SCIP_OKAY;
    164}
    165
    166
    167/** initialization method of branching rule (called after problem was transformed) */
    168static
    169SCIP_DECL_BRANCHINIT(branchInitCloud)
    170{ /*lint --e{715}*/
    171 SCIP_BRANCHRULEDATA* branchruledata;
    172
    173 /* initialize branching rule data */
    174 branchruledata = SCIPbranchruleGetData(branchrule);
    175 branchruledata->lastcand = 0;
    176 branchruledata->nuseful = 0;
    177 branchruledata->nusefulunions = 0;
    178 branchruledata->ntried = 0;
    179 branchruledata->ntriedunions = 0;
    180 branchruledata->ncloudpoints = 0;
    181 branchruledata->nsavedlps = 0;
    182
    183 if( branchruledata->cloudclock != NULL)
    184 {
    185 SCIP_CALL( SCIPresetClock(scip, branchruledata->cloudclock) );
    186 }
    187
    188 return SCIP_OKAY;
    189}
    190
    191/** branching execution method for fractional LP solutions */
    192static
    193SCIP_DECL_BRANCHEXECLP(branchExeclpCloud)
    194{ /*lint --e{715}*/
    195 SCIP_BRANCHRULEDATA* branchruledata;
    196
    197 SCIP_VAR** lpcands;
    198 SCIP_VAR** lpcandscopy;
    199
    200 SCIP_VAR** vars;
    201 SCIP_ROW** lprows;
    202 SCIP_Real* lpcandsfrac;
    203 SCIP_Real* lpcandssol;
    204 SCIP_Real* lpcandsfraccopy;
    205 SCIP_Real* lpcandssolcopy;
    206 SCIP_Real* lpcandsmin;
    207 SCIP_Real* lpcandsmax;
    208 SCIP_Real* newlpcandsmin;
    209 SCIP_Real* newlpcandsmax;
    210
    211 SCIP_Real bestdown;
    212 SCIP_Real bestup;
    213 SCIP_Real bestscore;
    214 SCIP_Real provedbound;
    215
    216 SCIP_Bool bestdownvalid;
    217 SCIP_Bool bestupvalid;
    218 SCIP_Bool newpoint;
    219 SCIP_Bool lperror;
    220
    221 int nlpcands;
    222 int npriolpcands;
    223 int nvars;
    224 int bestcand;
    225 int nlprows;
    226 int i;
    227 int counter;
    228 int ncomplete;
    229 int ndiscvars;
    230
    231 assert(branchrule != NULL);
    232 assert(scip != NULL);
    233 assert(result != NULL);
    234
    236
    237 if( !SCIPisLPSolBasic(scip) )
    238 return SCIP_OKAY;
    239
    240 SCIPdebugMsg(scip, "Execlp method of " BRANCHRULE_NAME " branching\n");
    241
    242 /* get problem variables and LP row data */
    243 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
    245 nlprows = SCIPgetNLPRows(scip);
    246 lprows = SCIPgetLPRows(scip);
    247
    248 /* get branching candidates */
    249 SCIP_CALL( SCIPgetLPBranchCands(scip, &lpcands, &lpcandssol, &lpcandsfrac, &nlpcands, &npriolpcands, NULL) );
    250 nlpcands = SCIPgetNLPBranchCands(scip);
    251 assert(nlpcands > 0);
    252
    253 /* get branching rule data */
    254 branchruledata = SCIPbranchruleGetData(branchrule);
    255 assert(branchruledata != NULL);
    256
    257 /* allocate skipping arrays on first call */
    258 if( branchruledata->skipdown == NULL )
    259 {
    260 assert(branchruledata->skipup == NULL);
    261
    262 branchruledata->skipsize = nvars;
    263 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &branchruledata->skipdown, branchruledata->skipsize) );
    264 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &branchruledata->skipup, branchruledata->skipsize) );
    265 }
    266
    267 /* reset skipping arrays to zero */
    268 BMSclearMemoryArray(branchruledata->skipdown, branchruledata->skipsize);
    269 BMSclearMemoryArray(branchruledata->skipup, branchruledata->skipsize);
    270
    271 /* allocate required data structures */
    272 SCIP_CALL( SCIPallocBufferArray(scip, &lpcandsmin, nlpcands) );
    273 SCIP_CALL( SCIPallocBufferArray(scip, &lpcandsmax, nlpcands) );
    274 SCIP_CALL( SCIPallocBufferArray(scip, &lpcandscopy, nlpcands) );
    275 SCIP_CALL( SCIPallocBufferArray(scip, &lpcandsfraccopy, nlpcands) );
    276 SCIP_CALL( SCIPallocBufferArray(scip, &lpcandssolcopy, nlpcands) );
    277 newlpcandsmin = NULL;
    278 newlpcandsmax = NULL;
    279 if( branchruledata->useunion && SCIPgetDepth(scip) < branchruledata->maxdepthunion && !branchruledata->onlyF2)
    280 {
    281 SCIP_CALL( SCIPallocBufferArray(scip, &newlpcandsmin, ndiscvars) );
    282 SCIP_CALL( SCIPallocBufferArray(scip, &newlpcandsmax, ndiscvars) );
    283 }
    284 BMScopyMemoryArray(lpcandsmin, lpcandssol, nlpcands);
    285 BMScopyMemoryArray(lpcandsmax, lpcandssol, nlpcands);
    286 BMScopyMemoryArray(lpcandssolcopy, lpcandssol, nlpcands);
    287 BMScopyMemoryArray(lpcandsfraccopy, lpcandsfrac, nlpcands);
    288 BMScopyMemoryArray(lpcandscopy, lpcands, nlpcands);
    289
    290 SCIP_CALL( SCIPstartClock(scip, branchruledata->cloudclock) );
    291 branchruledata->ntried++;
    292
    293 /* start diving to calculate the solution cloud */
    295
    296 /* fix variables with nonzero reduced costs to reduce LP to the optimal face */
    297 for( i = 0; i < nvars; ++i )
    298 {
    299 SCIP_Real solval;
    300 solval = SCIPgetSolVal(scip, NULL, vars[i]);
    301
    302 if( !SCIPisFeasZero(scip, SCIPgetVarRedcost(scip, vars[i])) )
    303 {
    304 SCIP_CALL( SCIPchgVarLbDive(scip, vars[i], solval) );
    305 SCIP_CALL( SCIPchgVarUbDive(scip, vars[i], solval) );
    306 }
    307 /* for non-implied integral variables with zero cost and fractional value we only allow the next integral values */
    308 else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_INTEGER && !SCIPvarIsImpliedIntegral(vars[i])
    309 && !SCIPisIntegral(scip, solval) )
    310 {
    311 SCIP_CALL( SCIPchgVarLbDive(scip, vars[i], SCIPfloor(scip, solval)) );
    312 SCIP_CALL( SCIPchgVarUbDive(scip, vars[i], SCIPceil(scip, solval)) );
    313 }
    314
    315 SCIP_CALL( SCIPchgVarObjDive(scip, vars[i], 0.0) );
    316 }
    317
    318 /* fix LP rows with nonzero dual solution to reduce LP to the optimal face */
    319 for( i = 0; i < nlprows; ++i )
    320 {
    321 SCIP_Real dualsol;
    322 dualsol = SCIProwGetDualsol(lprows[i]);
    323 if( !SCIPisZero(scip, dualsol) )
    324 {
    325 if( dualsol > 0 && SCIPisFeasEQ(scip, SCIProwGetLhs(lprows[i]), SCIPgetRowActivity(scip,lprows[i])) )
    326 {
    327 SCIP_CALL( SCIPchgRowRhsDive(scip, lprows[i], SCIProwGetLhs(lprows[i])) );
    328 }
    329 else if( dualsol < 0 && SCIPisFeasEQ(scip, SCIProwGetRhs(lprows[i]), SCIPgetRowActivity(scip,lprows[i])) )
    330 {
    331 SCIP_CALL( SCIPchgRowLhsDive(scip, lprows[i], SCIProwGetRhs(lprows[i])) );
    332 }
    333 }
    334 }
    335
    336 newpoint = TRUE;
    337 counter = 0;
    338
    339 if( branchruledata->useunion && !branchruledata->onlyF2 && SCIPgetDepth(scip) < branchruledata->maxdepthunion )
    340 {
    341 /* update cloud intervals for candidates that have been integral in original LP, but have been fractional in previous cloud points */
    342 for( i = 0; i < ndiscvars; ++i)
    343 {
    344 SCIP_Real solval;
    345 solval = SCIPgetSolVal(scip, NULL, vars[i]);
    346
    347 assert(newlpcandsmin != NULL);
    348 assert(newlpcandsmax != NULL);
    349
    350 newlpcandsmin[i] = solval;
    351 newlpcandsmax[i] = solval;
    352 }
    353 }
    354
    355 /* loop that generates new cloud point */
    356 while( newpoint && branchruledata->usecloud )
    357 {
    358#ifdef NDEBUG
    359 SCIP_RETCODE retcode;
    360#endif
    361
    362 /* apply feasibility pump objective function to fractional variables */
    363 for( i = 0; i < nlpcands; ++i )
    364 {
    365 SCIP_Real frac;
    366 frac = SCIPfrac(scip, SCIPgetSolVal(scip, NULL, lpcandscopy[i]));
    367
    368 if( !SCIPisZero(scip, frac) && !SCIPisIntegral(scip, lpcandsmin[i]) && !SCIPisIntegral(scip, lpcandsmax[i]) )
    369 {
    370 if( frac < 0.5 )
    371 {
    372 SCIP_CALL( SCIPchgVarObjDive(scip, vars[i], 1.0) );
    373 }
    374 else
    375 {
    376 SCIP_CALL( SCIPchgVarObjDive(scip, vars[i], -1.0) );
    377 }
    378 }
    379 }
    380
    381 /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
    382 * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
    383 */
    384#ifdef NDEBUG
    385 retcode = SCIPsolveDiveLP(scip, -1, &lperror, NULL);
    386 if( retcode != SCIP_OKAY )
    387 {
    388 SCIPwarningMessage(scip, "Error while solving LP in " BRANCHRULE_NAME "; LP solve terminated with code <%d>\n",retcode);
    389 }
    390#else
    391 SCIP_CALL( SCIPsolveDiveLP(scip, -1, &lperror, NULL) );
    392#endif
    393
    394 if( lperror || SCIPgetLPSolstat(scip) != SCIP_LPSOLSTAT_OPTIMAL )
    395 break;
    396
    397 /* check if a solution has been found */
    398 if( SCIPgetNLPBranchCands(scip) == 0 )
    399 {
    400 SCIP_Bool success;
    401 SCIP_SOL* sol;
    402
    403 /* create solution from diving LP */
    404 SCIP_CALL( SCIPcreateSol(scip, &sol, NULL) );
    406 SCIPdebugMsg(scip, "cloud branching found primal solution: obj=%g\n", SCIPgetSolOrigObj(scip, sol));
    407
    408 /* try to add solution to SCIP */
    409 SCIP_CALL( SCIPtrySolFree(scip, &sol, FALSE, FALSE, FALSE, FALSE, FALSE, &success) );
    410
    411 /* check, if solution was feasible and good enough */
    412 if( success )
    413 {
    414 SCIPdebugMsg(scip, " -> solution was feasible and good enough\n");
    416 *result = SCIP_CUTOFF;
    417 goto TERMINATE;
    418 }
    419 }
    420
    421 /* update cloud intervals for candidates that have been fractional in original LP */
    422 newpoint = FALSE;
    423 for( i = 0; i < nlpcands; ++i)
    424 {
    425 SCIP_Real solval;
    426 solval = SCIPgetSolVal(scip, NULL, lpcandscopy[i]);
    427
    428 if( SCIPisFeasIntegral(scip,solval) && !SCIPisFeasIntegral(scip, lpcandsmin[i]) && !SCIPisFeasIntegral(scip, lpcandsmax[i]) )
    429 newpoint = TRUE;
    430
    431 lpcandsmin[i] = MIN(lpcandsmin[i], solval);
    432 lpcandsmax[i] = MAX(lpcandsmax[i], solval);
    433 }
    434
    435 if( branchruledata->useunion && !branchruledata->onlyF2 && SCIPgetDepth(scip) < branchruledata->maxdepthunion )
    436 {
    437 /* update cloud intervals for candidates that have been integral in original LP, but have been fractional in previous cloud points */
    438 for( i = 0; i < ndiscvars; ++i)
    439 {
    440 SCIP_Real solval;
    441 solval = SCIPgetSolVal(scip, NULL, vars[i]);
    442
    443 assert(newlpcandsmin != NULL);
    444 assert(newlpcandsmax != NULL);
    445
    446 newlpcandsmin[i] = MIN(newlpcandsmin[i], solval);
    447 newlpcandsmax[i] = MAX(newlpcandsmax[i], solval);
    448 }
    449 }
    450
    451 if( newpoint )
    452 counter++;
    453
    454 if( branchruledata->maxpoints != -1 && counter >= branchruledata->maxpoints )
    455 break;
    456 }
    457
    458 SCIPdebugMsg(scip, "considered %d additional points in the cloud\n",counter);
    459
    460 /* terminate the diving */
    462
    463 SCIP_CALL( SCIPstopClock(scip, branchruledata->cloudclock) );
    464 ncomplete = nlpcands;
    465
    466 if( counter > 0 )
    467 {
    468 branchruledata->ncloudpoints += (counter+1);
    469 branchruledata->nuseful++;
    470
    471 counter = 0;
    472
    473 /* sort all variables for which both bounds are fractional to the front */
    474 for( i = 0; i < nlpcands; ++i)
    475 {
    476 if( !SCIPisFeasIntegral(scip, lpcandsmin[i]) && !SCIPisFeasIntegral(scip, lpcandsmax[i]) )
    477 {
    478 assert(counter <= i);
    479 lpcandscopy[counter] = lpcandscopy[i];
    480 lpcandssolcopy[counter] = lpcandssolcopy[i];
    481 lpcandsfraccopy[counter] = lpcandsfraccopy[i];
    482 counter++;
    483 }
    484 }
    485
    486 /* should only be in that if condition when at least one bound could be made integral */
    487 assert(nlpcands - counter > 0);
    488
    489 ncomplete = counter;
    490
    491 /* filter all variables for which exactly one interval bound is fractional */
    492 for( i = 0; i < nlpcands && !branchruledata->onlyF2; ++i)
    493 {
    494 if( SCIPisFeasIntegral(scip, lpcandsmin[i]) != SCIPisFeasIntegral(scip, lpcandsmax[i]) )
    495 {
    496 assert(counter < nlpcands);
    497 lpcandscopy[counter] = lpcandscopy[i];
    498 lpcandssolcopy[counter] = lpcandssolcopy[i];
    499 lpcandsfraccopy[counter] = lpcandsfraccopy[i];
    500
    501 if( SCIPisFeasIntegral(scip, lpcandsmin[i]) )
    502 branchruledata->skipdown[counter] = TRUE;
    503 if( SCIPisFeasIntegral(scip, lpcandsmax[i]) )
    504 branchruledata->skipup[counter] = TRUE;
    505 assert(branchruledata->skipdown[counter] != branchruledata->skipup[counter]);
    506
    507 counter++;
    508 }
    509 }
    510
    511 SCIPdebugMsg(scip, "can fully skip %d/%d strong branching candidates\n", nlpcands - counter, nlpcands);
    512 SCIPdebugMsg(scip, "can half skip %d/%d strong branching candidates\n", counter - ncomplete, nlpcands);
    513 }
    514 else
    515 counter = nlpcands;
    516
    517 /* if cloud sampling was not successful enough, disable it */
    518 if( branchruledata->usecloud &&
    519 branchruledata->ntried > 100 &&
    520 (SCIP_Real)branchruledata->nuseful / branchruledata->ntried < branchruledata->minsuccessrate )
    521 {
    522 SCIPdebugMsg(scip, "Disabling cloud branching (not effective)\n");
    523 branchruledata->usecloud = FALSE;
    524 }
    525
    526 if( branchruledata->onlyF2 )
    527 counter = MAX(counter,1);
    528
    529 /* the second counter should maybe be replaced at some point */
    530 SCIP_CALL( SCIPselectVarStrongBranching(scip, lpcandscopy, lpcandssolcopy, lpcandsfraccopy, branchruledata->skipdown,
    531 branchruledata->skipup, counter, counter, ncomplete, &branchruledata->lastcand, 0, FALSE, FALSE,
    532 &bestcand, &bestdown, &bestup, &bestscore, &bestdownvalid, &bestupvalid, &provedbound, result) );
    533
    534 if( branchruledata->lastcand <= ncomplete )
    535 {
    536 SCIPdebugMsg(scip, "saved %d of %d LPs\n", 2*(nlpcands - ncomplete), 2*nlpcands);
    537 branchruledata->nsavedlps += 2*(nlpcands - ncomplete);
    538 }
    539 else
    540 {
    541 SCIPdebugMsg(scip, "saved %d of %d LPs\n", 2*(nlpcands - counter)+counter - ncomplete, 2*nlpcands);
    542 branchruledata->nsavedlps += 2*(nlpcands - counter)+counter - ncomplete;
    543 }
    544
    545 /* perform the branching */
    546 if( *result != SCIP_CUTOFF && *result != SCIP_REDUCEDDOM && *result != SCIP_CONSADDED && counter > 0 )
    547 {
    548 SCIP_NODE* downchild;
    549 SCIP_NODE* upchild;
    550 SCIP_VAR* var;
    551 SCIP_Bool allcolsinlp;
    552 SCIP_Bool exactsolve;
    553 SCIP_Bool newselected;
    554
    555 assert(*result == SCIP_DIDNOTRUN);
    556 assert(0 <= bestcand && bestcand < nlpcands);
    557 assert(SCIPisLT(scip, provedbound, SCIPgetCutoffbound(scip)));
    558
    559 var = lpcandscopy[bestcand];
    560 newselected = FALSE;
    561
    562 /* if there are new candidates variables, also try them */
    563 if( branchruledata->useunion && !branchruledata->onlyF2 && SCIPgetDepth(scip) < branchruledata->maxdepthunion && branchruledata->lastcand > ncomplete )
    564 {
    565 SCIP_VAR** newlpcands;
    566
    567 counter = 0;
    568 /* reset skipping arrays to zero */
    569 BMSclearMemoryArray(branchruledata->skipdown, branchruledata->skipsize);
    570 BMSclearMemoryArray(branchruledata->skipup, branchruledata->skipsize);
    571
    572 SCIP_CALL( SCIPallocBufferArray(scip, &newlpcands, ndiscvars) );
    573
    574 /* get new LP candidates with one fractional bound */
    575 for( i = 0; i < ndiscvars; ++i)
    576 {
    577 if( !SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, NULL, vars[i])) )
    578 continue;
    579
    580 assert(newlpcandsmin != NULL);
    581 assert(newlpcandsmax != NULL);
    582
    583 if( SCIPisFeasIntegral(scip, newlpcandsmin[i]) != SCIPisFeasIntegral(scip, newlpcandsmax[i]) )
    584 {
    585 newlpcands[counter] = vars[i];
    586
    587 if( SCIPisFeasIntegral(scip, newlpcandsmin[i]) )
    588 branchruledata->skipdown[counter] = TRUE;
    589 if( SCIPisFeasIntegral(scip, newlpcandsmax[i]) )
    590 branchruledata->skipup[counter] = TRUE;
    591 assert(branchruledata->skipdown[counter] != branchruledata->skipup[counter]);
    592
    593 counter++;
    594 }
    595 }
    596
    597 /* when there are new candidates, also try these */
    598 if( counter > 0 )
    599 {
    600 SCIP_Real newdown;
    601 SCIP_Real newup;
    602 SCIP_Real newscore;
    603 int newcand;
    604 SCIP_Bool newdownvalid;
    605 SCIP_Bool newupvalid;
    606 SCIP_Real newbound;
    607
    608 branchruledata->ntriedunions++;
    609 newscore = -SCIPinfinity(scip);
    610 SCIP_CALL( SCIPselectVarPseudoStrongBranching(scip, newlpcands, branchruledata->skipdown, branchruledata->skipup, counter, counter,
    611 &newcand, &newdown, &newup, &newscore, &newdownvalid, &newupvalid, &newbound, result) );
    612
    613 if( *result == SCIP_CUTOFF || *result == SCIP_REDUCEDDOM || *result == SCIP_CONSADDED )
    614 {
    615 SCIPfreeBufferArray(scip, &newlpcands);
    616 goto TERMINATE;
    617 }
    618
    619 if( newscore > bestscore )
    620 {
    621 bestcand = newcand;
    622 var = newlpcands[newcand];
    623 bestdown = newdown;
    624 bestup = newup;
    625 bestdownvalid = newdownvalid;
    626 bestupvalid = newupvalid;
    627 bestscore = newscore;
    628 newselected = TRUE;
    629 branchruledata->nusefulunions++;
    630 }
    631 }
    632 /* free temporary array for new union candidates */
    633 SCIPfreeBufferArray(scip, &newlpcands);
    634 }
    635
    636 /* perform the branching */
    637 if( !newselected )
    638 {
    639 SCIPdebugMsg(scip, " -> %d candidates, selected candidate %d: variable <%s> (solval=%g, down=%g, up=%g, score=%g)\n",
    640 counter, bestcand, SCIPvarGetName(var), lpcandssolcopy[bestcand], bestdown, bestup, bestscore);
    641 }
    642 else
    643 {
    644 SCIPdebugMsg(scip, " -> selected from %d new candidates, candidate %d: variable <%s> (down=%g, up=%g, score=%g)\n",
    645 counter, bestcand, SCIPvarGetName(var), bestdown, bestup, bestscore);
    646 }
    647
    648 assert(!SCIPisFeasIntegral(scip, SCIPvarGetSol(lpcands[bestcand], TRUE)));
    649
    650 SCIP_CALL( SCIPbranchVar(scip, var, &downchild, NULL, &upchild) );
    651 assert(downchild != NULL);
    652 assert(upchild != NULL);
    653
    654 /* check, if we want to solve the problem exactly, meaning that strong branching information is not useful
    655 * for cutting off sub problems and improving lower bounds of children
    656 */
    657 exactsolve = SCIPisExact(scip);
    658
    659 /* check, if all existing columns are in LP, and thus the strong branching results give lower bounds */
    660 allcolsinlp = SCIPallColsInLP(scip);
    661
    662 /* update the lower bounds in the children */
    663 if( allcolsinlp && !exactsolve )
    664 {
    665 SCIP_CALL( SCIPupdateNodeLowerbound(scip, downchild, bestdownvalid ? MAX(bestdown, provedbound) : provedbound) );
    666 SCIP_CALL( SCIPupdateNodeLowerbound(scip, upchild, bestupvalid ? MAX(bestup, provedbound) : provedbound) );
    667 }
    668 SCIPdebugMsg(scip, " -> down child's lowerbound: %g\n", SCIPnodeGetLowerbound(downchild));
    669 SCIPdebugMsg(scip, " -> up child's lowerbound: %g\n", SCIPnodeGetLowerbound(upchild));
    670
    671 *result = SCIP_BRANCHED;
    672 }
    673
    674 TERMINATE:
    675 if( branchruledata->useunion && !branchruledata->onlyF2 && SCIPgetDepth(scip) < branchruledata->maxdepthunion )
    676 {
    677 SCIPfreeBufferArray(scip, &newlpcandsmax);
    678 SCIPfreeBufferArray(scip, &newlpcandsmin);
    679 }
    680 SCIPfreeBufferArray(scip, &lpcandscopy);
    681 SCIPfreeBufferArray(scip, &lpcandssolcopy);
    682 SCIPfreeBufferArray(scip, &lpcandsfraccopy);
    683 SCIPfreeBufferArray(scip, &lpcandsmax);
    684 SCIPfreeBufferArray(scip, &lpcandsmin);
    685
    686 /* if union usage was not successful enough, disable it */
    687 if( branchruledata->useunion &&
    688 branchruledata->ntriedunions > 10 &&
    689 (SCIP_Real)branchruledata->nusefulunions / branchruledata->ntriedunions < branchruledata->minsuccessunion )
    690 {
    691 SCIPdebugMsg(scip, "Disabling union usage (not effective)\n");
    692 branchruledata->useunion = FALSE;
    693 }
    694
    695 return SCIP_OKAY; /*lint !e438*/
    696}
    697
    698/*
    699 * branching rule specific interface methods
    700 */
    701
    702/** creates the cloud branching rule and includes it in SCIP */
    704 SCIP* scip /**< SCIP data structure */
    705 )
    706{
    707 SCIP_BRANCHRULEDATA* branchruledata;
    708 SCIP_BRANCHRULE* branchrule;
    709
    710 /* create cloud branching rule data */
    711 SCIP_CALL( SCIPallocBlockMemory(scip, &branchruledata) );
    712 branchruledata->lastcand = 0;
    713 branchruledata->skipsize = 0;
    714 branchruledata->skipup = NULL;
    715 branchruledata->skipdown = NULL;
    716 SCIP_CALL( SCIPcreateClock(scip, &(branchruledata->cloudclock)) );
    717
    718 /* include branching rule */
    719 branchrule = NULL;
    722 assert(branchrule != NULL);
    723
    724 /* set non-fundamental callbacks via setter functions */
    725 SCIP_CALL( SCIPsetBranchruleCopy(scip, branchrule, branchCopyCloud) );
    726 SCIP_CALL( SCIPsetBranchruleFree(scip, branchrule, branchFreeCloud) );
    727 SCIP_CALL( SCIPsetBranchruleInit(scip, branchrule, branchInitCloud) );
    728 SCIP_CALL( SCIPsetBranchruleExecLp(scip, branchrule, branchExeclpCloud) );
    729
    730 /* add cloud branching rule parameters */
    732 "branching/" BRANCHRULE_NAME "/usecloud",
    733 "should a cloud of points be used?",
    734 &branchruledata->usecloud, FALSE, DEFAULT_USECLOUD, NULL, NULL) );
    736 "branching/" BRANCHRULE_NAME "/onlyF2",
    737 "should only F2 be used?",
    738 &branchruledata->onlyF2, FALSE, DEFAULT_ONLYF2, NULL, NULL) );
    740 "branching/" BRANCHRULE_NAME "/useunion",
    741 "should the union of candidates be used?",
    742 &branchruledata->useunion, FALSE, DEFAULT_USEUNION, NULL, NULL) );
    744 "branching/" BRANCHRULE_NAME "/maxpoints",
    745 "maximum number of points for the cloud (-1 means no limit)",
    746 &branchruledata->maxpoints, FALSE, DEFAULT_MAXPOINTS, -1, INT_MAX, NULL, NULL) );
    748 "branching/" BRANCHRULE_NAME "/minsuccessrate",
    749 "minimum success rate for the cloud",
    750 &branchruledata->minsuccessrate, FALSE, DEFAULT_MINSUCCESSRATE, 0.0, 1.0, NULL, NULL) );
    752 "branching/" BRANCHRULE_NAME "/minsuccessunion",
    753 "minimum success rate for the union",
    754 &branchruledata->minsuccessunion, FALSE, DEFAULT_MINSUCCESSUNION, 0.0, 1.0, NULL, NULL) );
    756 "branching/" BRANCHRULE_NAME "/maxdepthunion",
    757 "maximum depth for the union",
    758 &branchruledata->maxdepthunion, FALSE, DEFAULT_MAXDEPTHUNION, 0, 65000, NULL, NULL) );
    759
    760 return SCIP_OKAY;
    761}
    SCIP_RETCODE SCIPselectVarPseudoStrongBranching(SCIP *scip, SCIP_VAR **pseudocands, SCIP_Bool *skipdown, SCIP_Bool *skipup, int npseudocands, int npriopseudocands, int *bestpseudocand, SCIP_Real *bestdown, SCIP_Real *bestup, SCIP_Real *bestscore, SCIP_Bool *bestdownvalid, SCIP_Bool *bestupvalid, SCIP_Real *provedbound, SCIP_RESULT *result)
    all variables full strong LP branching rule
    #define BRANCHRULE_DESC
    Definition: branch_cloud.c:66
    static SCIP_DECL_BRANCHINIT(branchInitCloud)
    Definition: branch_cloud.c:169
    #define BRANCHRULE_PRIORITY
    Definition: branch_cloud.c:67
    #define DEFAULT_MAXPOINTS
    Definition: branch_cloud.c:73
    #define DEFAULT_MINSUCCESSUNION
    Definition: branch_cloud.c:75
    #define DEFAULT_USEUNION
    Definition: branch_cloud.c:72
    #define BRANCHRULE_NAME
    Definition: branch_cloud.c:65
    static SCIP_DECL_BRANCHCOPY(branchCopyCloud)
    Definition: branch_cloud.c:112
    #define DEFAULT_MAXDEPTHUNION
    Definition: branch_cloud.c:76
    static SCIP_DECL_BRANCHEXECLP(branchExeclpCloud)
    Definition: branch_cloud.c:193
    #define DEFAULT_ONLYF2
    Definition: branch_cloud.c:77
    #define DEFAULT_MINSUCCESSRATE
    Definition: branch_cloud.c:74
    static SCIP_DECL_BRANCHFREE(branchFreeCloud)
    Definition: branch_cloud.c:127
    #define DEFAULT_USECLOUD
    Definition: branch_cloud.c:71
    #define BRANCHRULE_MAXDEPTH
    Definition: branch_cloud.c:68
    #define BRANCHRULE_MAXBOUNDDIST
    Definition: branch_cloud.c:69
    cloud branching rule
    full strong LP branching rule
    #define NULL
    Definition: def.h:257
    #define SCIP_Bool
    Definition: def.h:100
    #define MIN(x, y)
    Definition: def.h:233
    #define SCIP_STRINGEQ(name, reference, retcode)
    Definition: def.h:454
    #define SCIP_Real
    Definition: def.h:165
    #define TRUE
    Definition: def.h:102
    #define FALSE
    Definition: def.h:103
    #define MAX(x, y)
    Definition: def.h:229
    #define SCIP_CALL(x)
    Definition: def.h:364
    SCIP_RETCODE SCIPselectVarStrongBranching(SCIP *scip, SCIP_VAR **lpcands, SCIP_Real *lpcandssol, SCIP_Real *lpcandsfrac, SCIP_Bool *skipdown, SCIP_Bool *skipup, int nlpcands, int npriolpcands, int ncomplete, int *start, int maxproprounds, SCIP_Bool probingbounds, SCIP_Bool forcestrongbranch, int *bestcand, SCIP_Real *bestdown, SCIP_Real *bestup, SCIP_Real *bestscore, SCIP_Bool *bestdownvalid, SCIP_Bool *bestupvalid, SCIP_Real *provedbound, SCIP_RESULT *result)
    SCIP_RETCODE SCIPincludeBranchruleCloud(SCIP *scip)
    Definition: branch_cloud.c:703
    int SCIPgetNIntVars(SCIP *scip)
    Definition: scip_prob.c:2340
    SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
    Definition: scip_prob.c:2115
    int SCIPgetNBinVars(SCIP *scip)
    Definition: scip_prob.c:2293
    SCIP_RETCODE SCIPupdateNodeLowerbound(SCIP *scip, SCIP_NODE *node, SCIP_Real newbound)
    Definition: scip_prob.c:4354
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
    Definition: scip_message.c:120
    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 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 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 SCIPsetBranchruleExecLp(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHEXECLP((*branchexeclp)))
    Definition: scip_branch.c:256
    SCIP_RETCODE SCIPsetBranchruleCopy(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHCOPY((*branchcopy)))
    Definition: scip_branch.c:160
    SCIP_RETCODE SCIPincludeBranchruleBasic(SCIP *scip, SCIP_BRANCHRULE **branchruleptr, const char *name, const char *desc, int priority, int maxdepth, SCIP_Real maxbounddist, SCIP_BRANCHRULEDATA *branchruledata)
    Definition: scip_branch.c:123
    const char * SCIPbranchruleGetName(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:2018
    SCIP_BRANCHRULEDATA * SCIPbranchruleGetData(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:1886
    SCIP_RETCODE SCIPsetBranchruleFree(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHFREE((*branchfree)))
    Definition: scip_branch.c:176
    SCIP_RETCODE SCIPsetBranchruleInit(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHINIT((*branchinit)))
    Definition: scip_branch.c:192
    void SCIPbranchruleSetData(SCIP_BRANCHRULE *branchrule, SCIP_BRANCHRULEDATA *branchruledata)
    Definition: branch.c:1896
    SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
    Definition: scip_branch.c:402
    SCIP_RETCODE SCIPbranchVar(SCIP *scip, SCIP_VAR *var, SCIP_NODE **downchild, SCIP_NODE **eqchild, SCIP_NODE **upchild)
    Definition: scip_branch.c:1058
    int SCIPgetNLPBranchCands(SCIP *scip)
    Definition: scip_branch.c:436
    SCIP_Bool SCIPisExact(SCIP *scip)
    Definition: scip_exact.c:193
    SCIP_RETCODE SCIPchgVarLbDive(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_lp.c:2384
    SCIP_RETCODE SCIPchgVarUbDive(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_lp.c:2416
    SCIP_RETCODE SCIPchgRowLhsDive(SCIP *scip, SCIP_ROW *row, SCIP_Real newlhs)
    Definition: scip_lp.c:2487
    SCIP_RETCODE SCIPchgRowRhsDive(SCIP *scip, SCIP_ROW *row, SCIP_Real newrhs)
    Definition: scip_lp.c:2520
    SCIP_RETCODE SCIPstartDive(SCIP *scip)
    Definition: scip_lp.c:2206
    SCIP_RETCODE SCIPchgVarObjDive(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
    Definition: scip_lp.c:2343
    SCIP_RETCODE SCIPsolveDiveLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
    Definition: scip_lp.c:2643
    SCIP_RETCODE SCIPendDive(SCIP *scip)
    Definition: scip_lp.c:2255
    SCIP_ROW ** SCIPgetLPRows(SCIP *scip)
    Definition: scip_lp.c:611
    int SCIPgetNLPRows(SCIP *scip)
    Definition: scip_lp.c:632
    SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
    Definition: scip_lp.c:174
    SCIP_Bool SCIPallColsInLP(SCIP *scip)
    Definition: scip_lp.c:655
    SCIP_Bool SCIPisLPSolBasic(SCIP *scip)
    Definition: scip_lp.c:673
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #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 SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    SCIP_Real SCIPnodeGetLowerbound(SCIP_NODE *node)
    Definition: tree.c:8533
    SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
    Definition: lp.c:17686
    SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
    Definition: lp.c:17696
    SCIP_Real SCIPgetRowActivity(SCIP *scip, SCIP_ROW *row)
    Definition: scip_lp.c:2068
    SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
    Definition: lp.c:17706
    SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
    Definition: scip_sol.c:514
    SCIP_RETCODE SCIPtrySolFree(SCIP *scip, SCIP_SOL **sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
    Definition: scip_sol.c:4114
    SCIP_RETCODE SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1293
    SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1890
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1763
    SCIP_Real SCIPgetCutoffbound(SCIP *scip)
    SCIP_RETCODE SCIPcreateClock(SCIP *scip, SCIP_CLOCK **clck)
    Definition: scip_timing.c:76
    SCIP_RETCODE SCIPresetClock(SCIP *scip, SCIP_CLOCK *clck)
    Definition: scip_timing.c:144
    SCIP_RETCODE SCIPstopClock(SCIP *scip, SCIP_CLOCK *clck)
    Definition: scip_timing.c:178
    SCIP_RETCODE SCIPfreeClock(SCIP *scip, SCIP_CLOCK **clck)
    Definition: scip_timing.c:127
    SCIP_Real SCIPgetClockTime(SCIP *scip, SCIP_CLOCK *clck)
    Definition: scip_timing.c:319
    SCIP_RETCODE SCIPstartClock(SCIP *scip, SCIP_CLOCK *clck)
    Definition: scip_timing.c:161
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfrac(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    int SCIPgetDepth(SCIP *scip)
    Definition: scip_tree.c:672
    SCIP_Real SCIPvarGetSol(SCIP_VAR *var, SCIP_Bool getlpval)
    Definition: var.c:19036
    SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
    Definition: var.c:23530
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23485
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23299
    SCIP_Real SCIPgetVarRedcost(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:2608
    memory allocation routines
    #define BMScopyMemoryArray(ptr, source, num)
    Definition: memory.h:134
    #define BMSclearMemoryArray(ptr, num)
    Definition: memory.h:130
    public methods for branching rules
    public methods for LP management
    public methods for message output
    #define SCIPstatisticMessage
    Definition: pub_message.h:123
    #define SCIPstatistic(x)
    Definition: pub_message.h:120
    public methods for branch and bound tree
    public methods for problem variables
    public methods for branching rule plugins and branching
    public methods for exact solving
    general public methods
    public methods for the LP relaxation, rows and columns
    public methods for memory management
    public methods for message handling
    public methods for numerical tolerances
    public methods for SCIP parameter handling
    public methods for global and local (sub)problems
    public methods for solutions
    public methods for querying solving statistics
    public methods for timing
    public methods for the branch-and-bound tree
    public methods for SCIP variables
    struct SCIP_BranchruleData SCIP_BRANCHRULEDATA
    Definition: type_branch.h:57
    @ SCIP_LPSOLSTAT_OPTIMAL
    Definition: type_lp.h:44
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_CUTOFF
    Definition: type_result.h:48
    @ SCIP_REDUCEDDOM
    Definition: type_result.h:51
    @ SCIP_CONSADDED
    Definition: type_result.h:52
    @ SCIP_BRANCHED
    Definition: type_result.h:54
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_VARTYPE_INTEGER
    Definition: type_var.h:65