Scippy

    SCIP

    Solving Constraint Integer Programs

    pricer_binpacking.c
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-2025 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file pricer_binpacking.c
    26 * @brief Binpacking variable pricer
    27 * @author Timo Berthold
    28 * @author Stefan Heinz
    29 *
    30 * This file implements the variable pricer which check if variables exist with negative reduced cost. See
    31 * @ref BINPACKING_PRICER for more details.
    32 *
    33 * @page BINPACKING_PRICER Pricing new variables
    34 *
    35 * The task of the pricer is to search for new variables with negative reduced costs. For this, the following integer
    36 * program is solved:
    37 *
    38 * \f[
    39 * \begin{array}[t]{rll}
    40 * \max & \displaystyle \sum_{i=1}^n (\lambda_S)_i y^\star_i\\
    41 * & \\
    42 * subject \ to & \displaystyle \sum_{i=0}^n (\lambda_S)_i s_i \leq \kappa \\
    43 * & \\
    44 * & (\lambda_S)_i \in \{0,1\} & \quad \forall i \in \{ 1, \dots , n \} \\
    45 * \end{array}
    46 * \f]
    47 *
    48 * where \f$ (\lambda_S)_i \f$ for \f$i\in\{1,\dots,n\}\f$ are binary variables and \f$y^\star_i\f$ given by the dual
    49 * solution of the restricted master problem. See the \ref BINPACKING_PROBLEM "problem description" for more details.
    50 *
    51 * To solve the above integer program, we create a new SCIP instance within SCIP and use the usual functions to create
    52 * variables and constraints. Besides, we need the current dual solutions to all set covering constraints (each stands
    53 * for one item) which are the objective coefficients of the binary variables. Therefore, we use the functions
    54 * SCIPgetDualsolSetppc() and SCIPgetDualfarkasSetppc() which return the dual solution or ray for the given set
    55 * covering constraint for a feasible or infeasible restricted master LP.
    56 *
    57 * Since we also want to generate new variables during search, we have to care that we do not generate variables over
    58 * and over again. For example, if we branched or fixed a certain packing to zero, we have to make sure that we do not
    59 * generate the corresponding variables at that node again. For this, we have to add constraints forbidding to generate
    60 * variables which are locally fixed to zero. See the function addFixedVarsConss() for more details. While using the
    61 * \ref BINPACKING_BRANCHING "Ryan/Foster branching", we also have to ensure that these branching decisions are respected. This is
    62 * realized within the function addBranchingDecisionConss().
    63 */
    64
    65/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    66
    67#include <assert.h>
    68#include <string.h>
    69
    70#include "scip/cons_knapsack.h"
    71#include "scip/cons_logicor.h"
    72#include "scip/cons_setppc.h"
    73#include "scip/cons_varbound.h"
    74#include "scip/scipdefplugins.h"
    75
    76#include "cons_samediff.h"
    77#include "pricer_binpacking.h"
    78#include "probdata_binpacking.h"
    79#include "vardata_binpacking.h"
    80
    81/**@name Pricer properties
    82 *
    83 * @{
    84 */
    85
    86#define PRICER_NAME "binpacking"
    87#define PRICER_DESC "pricer for binpacking tours"
    88#define PRICER_PRIORITY 0
    89#define PRICER_DELAY TRUE /* only call pricer if all problem variables have non-negative reduced costs */
    90
    91/**@} */
    92
    93
    94/*
    95 * Data structures
    96 */
    97
    98/** @brief Variable pricer data used in the \ref pricer_binpacking.c "pricer" */
    99struct SCIP_PricerData
    100{
    101 SCIP_CONSHDLR* conshdlr; /**< comstraint handler for "same" and "diff" constraints */
    102 SCIP_CONS** conss; /**< set covering constraints for the items */
    103 SCIP_Longint* weights; /**< weight of the items */
    104 int* ids; /**< array of item ids */
    105 int nitems; /**< number of items to be packed */
    106 SCIP_Longint capacity; /**< capacity of the bins */
    107};
    108
    109
    110
    111/**@name Local methods
    112 *
    113 * @{
    114 */
    115
    116/** add branching decisions constraints to the sub SCIP */
    117static
    119 SCIP* scip, /**< SCIP data structure */
    120 SCIP* subscip, /**< pricing SCIP data structure */
    121 SCIP_VAR** vars, /**< variable array of the subscuip oder variables */
    122 SCIP_CONSHDLR* conshdlr /**< constraint handler for branching data */
    123 )
    124{
    125 SCIP_CONS** conss;
    126 SCIP_CONS* cons;
    127 int nconss;
    128 int id1;
    129 int id2;
    130 CONSTYPE type;
    131
    132 SCIP_Real vbdcoef;
    133 SCIP_Real lhs;
    134 SCIP_Real rhs;
    135
    136 int c;
    137
    138 assert( scip != NULL );
    139 assert( subscip != NULL );
    140 assert( conshdlr != NULL );
    141
    142 /* collect all branching decision constraints */
    143 conss = SCIPconshdlrGetConss(conshdlr);
    144 nconss = SCIPconshdlrGetNConss(conshdlr);
    145
    146 /* loop over all branching decision constraints and apply the branching decision if the corresponding constraint is
    147 * active
    148 */
    149 for( c = 0; c < nconss; ++c )
    150 {
    151 cons = conss[c];
    152
    153 /* ignore constraints which are not active since these are not laying on the current active path of the search
    154 * tree
    155 */
    156 if( !SCIPconsIsActive(cons) )
    157 continue;
    158
    159 /* collect the two item ids and the branching type (SAME or DIFFER) on which the constraint branched */
    160 id1 = SCIPgetItemid1Samediff(cons);
    161 id2 = SCIPgetItemid2Samediff(cons);
    162 type = SCIPgetTypeSamediff(cons);
    163
    164 SCIPdebugMsg(scip, "create varbound for %s(%d,%d)\n", type == SAME ? "same" : "diff",
    166
    167 /* depending on the branching type select the correct left and right hand side for the linear constraint which
    168 * enforces this branching decision in the pricing problem MIP
    169 */
    170 if( type == SAME )
    171 {
    172 lhs = 0.0;
    173 rhs = 0.0;
    174 vbdcoef = -1.0;
    175 }
    176 else if( type == DIFFER )
    177 {
    178 lhs = -SCIPinfinity(scip);
    179 rhs = 1.0;
    180 vbdcoef = 1.0;
    181 }
    182 else
    183 {
    184 SCIPerrorMessage("unknow constraint type <%d>\n", type);
    185 return SCIP_INVALIDDATA;
    186 }
    187
    188 /* add linear (in that case a variable bound) constraint to pricing MIP depending on the branching type:
    189 *
    190 * - branching type SAME: x1 = x2 <=> x1 - x2 = 0 <=> 0 <= x1 - x2 <= 0
    191 *
    192 * - branching type DIFFER: x1 + x2 <= 1 <=> -inf <= x1 + x2 <= 1
    193 *
    194 * note a setppc constraint would be sufficient and even better suitable for such kind of constraint
    195 */
    196 SCIP_CALL( SCIPcreateConsBasicVarbound(subscip, &cons, SCIPconsGetName(conss[c]),
    197 vars[id1], vars[id2], vbdcoef, lhs, rhs) );
    198
    199 SCIPdebugPrintCons(subscip, cons, NULL);
    200
    201 SCIP_CALL( SCIPaddCons(subscip, cons) );
    202 SCIP_CALL( SCIPreleaseCons(subscip, &cons) );
    203 }
    204
    205 return SCIP_OKAY;
    206}
    207
    208/** avoid to generate columns which are fixed to zero; therefore add for each variable which is fixed to zero a
    209 * corresponding logicor constraint to forbid this column
    210 *
    211 * @note variable which are fixed locally to zero should not be generated again by the pricing MIP
    212 */
    213static
    215 SCIP* scip, /**< SCIP data structure */
    216 SCIP* subscip, /**< pricing SCIP data structure */
    217 SCIP_VAR** vars, /**< variable array of the subscuip */
    218 SCIP_CONS** conss, /**< array of setppc constraint for each item one */
    219 int nitems /**< number of items */
    220 )
    221{
    222 SCIP_VAR** origvars;
    223 int norigvars;
    224
    225 SCIP_CONS* cons;
    226 int* consids;
    227 int nconsids;
    228 int consid;
    229 int nvars;
    230
    231 SCIP_VAR** logicorvars;
    232 SCIP_VAR* var;
    233 SCIP_VARDATA* vardata;
    234 SCIP_Bool needed;
    235 int nlogicorvars;
    236
    237 int v;
    238 int c;
    239 int o;
    240
    241 /* collect all variable which are currently existing */
    242 origvars = SCIPgetVars(scip);
    243 norigvars = SCIPgetNVars(scip);
    244
    245 /* loop over all these variables and check if they are fixed to zero */
    246 for( v = 0; v < norigvars; ++v )
    247 {
    248 assert(SCIPvarGetType(origvars[v]) == SCIP_VARTYPE_BINARY);
    249
    250 /* if the upper bound is smaller than 0.5 if follows due to the integrality that the binary variable is fixed to zero */
    251 if( SCIPvarGetUbLocal(origvars[v]) < 0.5 )
    252 {
    253 SCIPdebugMsg(scip, "variable <%s> glb=[%.15g,%.15g] loc=[%.15g,%.15g] is fixed to zero\n",
    254 SCIPvarGetName(origvars[v]), SCIPvarGetLbGlobal(origvars[v]), SCIPvarGetUbGlobal(origvars[v]),
    255 SCIPvarGetLbLocal(origvars[v]), SCIPvarGetUbLocal(origvars[v]) );
    256
    257 /* coolect the constraints/items the variable belongs to */
    258 vardata = SCIPvarGetData(origvars[v]);
    259 nconsids = SCIPvardataGetNConsids(vardata);
    260 consids = SCIPvardataGetConsids(vardata);
    261 needed = TRUE;
    262
    263 SCIP_CALL( SCIPallocBufferArray(subscip, &logicorvars, nitems) );
    264 nlogicorvars = 0;
    265 consid = consids[0];
    266 nvars = 0;
    267
    268 /* loop over these items and create a linear (logicor) constraint which forbids this item combination in the
    269 * pricing problem; thereby check if this item combination is already forbidden
    270 */
    271 for( c = 0, o = 0; o < nitems && needed; ++o )
    272 {
    273 assert(o <= consid);
    274 cons = conss[o];
    275
    276 if( SCIPconsIsEnabled(cons) )
    277 {
    278 assert( SCIPgetNFixedonesSetppc(scip, cons) == 0 );
    279
    280 var = vars[nvars];
    281 nvars++;
    282 assert(var != NULL);
    283
    284 if( o == consid )
    285 {
    286 SCIP_CALL( SCIPgetNegatedVar(subscip, var, &var) );
    287 }
    288
    289 logicorvars[nlogicorvars] = var;
    290 nlogicorvars++;
    291 }
    292 else if( o == consid )
    293 needed = FALSE;
    294
    295 if( o == consid )
    296 {
    297 c++;
    298 if ( c == nconsids )
    299 consid = nitems + 100;
    300 else
    301 {
    302 assert(consid < consids[c]);
    303 consid = consids[c];
    304 }
    305 }
    306 }
    307
    308 if( needed )
    309 {
    310 SCIP_CALL( SCIPcreateConsBasicLogicor(subscip, &cons, SCIPvarGetName(origvars[v]), nlogicorvars, logicorvars) );
    311 SCIP_CALL( SCIPsetConsInitial(subscip, cons, FALSE) );
    312
    313 SCIP_CALL( SCIPaddCons(subscip, cons) );
    314 SCIP_CALL( SCIPreleaseCons(subscip, &cons) );
    315 }
    316
    317 SCIPfreeBufferArray(subscip, &logicorvars);
    318 }
    319 }
    320
    321 return SCIP_OKAY;
    322}
    323
    324/** initializes the pricing problem for the given capacity */
    325static
    327 SCIP* scip, /**< SCIP data structure */
    328 SCIP_PRICERDATA* pricerdata, /**< pricer data */
    329 SCIP_Bool isfarkas, /**< whether we perform Farkas pricing */
    330 SCIP* subscip, /**< pricing SCIP data structure */
    331 SCIP_VAR** vars /**< variable array for the items */
    332 )
    333{
    334 SCIP_CONS** conss;
    335 SCIP_Longint* vals;
    336 SCIP_CONS* cons;
    337 SCIP_VAR* var;
    338 SCIP_Longint* weights;
    339 SCIP_Longint capacity;
    340 SCIP_Real dual;
    341
    342 int nitems;
    343 int nvars;
    344 int c;
    345
    346 assert( SCIPgetStage(subscip) == SCIP_STAGE_PROBLEM );
    347 assert(pricerdata != NULL);
    348
    349 nitems = pricerdata->nitems;
    350 conss = pricerdata->conss;
    351 weights = pricerdata->weights;
    352 capacity = pricerdata->capacity;
    353 nvars = 0;
    354
    355 SCIP_CALL( SCIPallocBufferArray(subscip, &vals, nitems) );
    356
    357 /* create for each order, which is not assigned yet, a variable with objective coefficient */
    358 for( c = 0; c < nitems; ++c )
    359 {
    360 cons = conss[c];
    361
    362 /* check if each constraint is setppc constraint */
    363 assert( !strncmp( SCIPconshdlrGetName( SCIPconsGetHdlr(cons) ), "setppc", 6) );
    364
    365 /* constraints which are (locally) disabled/redundant are not of
    366 * interest since the corresponding job is assigned to a packing
    367 */
    368 if( !SCIPconsIsEnabled(cons) )
    369 continue;
    370
    371 if( SCIPgetNFixedonesSetppc(scip, cons) == 1 )
    372 {
    373 /* disable constraint locally */
    375 continue;
    376 }
    377
    378 /* dual value in original SCIP */
    379 dual = isfarkas ? SCIPgetDualfarkasSetppc(scip, cons) : SCIPgetDualsolSetppc(scip, cons);
    380
    381 SCIP_CALL( SCIPcreateVarBasic(subscip, &var, SCIPconsGetName(cons), 0.0, 1.0, dual, SCIP_VARTYPE_BINARY) );
    382 SCIP_CALL( SCIPaddVar(subscip, var) );
    383
    384 vals[nvars] = weights[c];
    385 vars[nvars] = var;
    386 nvars++;
    387
    388 /* release variable */
    389 SCIP_CALL( SCIPreleaseVar(subscip, &var) );
    390 }
    391
    392 /* create capacity constraint */
    393 SCIP_CALL( SCIPcreateConsBasicKnapsack(subscip, &cons, "capacity", nvars, vars, vals, capacity) );
    394
    395 SCIP_CALL( SCIPaddCons(subscip, cons) );
    396 SCIP_CALL( SCIPreleaseCons(subscip, &cons) );
    397
    398 /* add constraint of the branching decisions */
    399 SCIP_CALL( addBranchingDecisionConss(scip, subscip, vars, pricerdata->conshdlr) );
    400
    401 /* avoid to generate columns which are fixed to zero */
    402 SCIP_CALL( addFixedVarsConss(scip, subscip, vars, conss, nitems) );
    403
    404 SCIPfreeBufferArray(subscip, &vals);
    405
    406 return SCIP_OKAY;
    407}
    408
    409/** perform packing pricing */
    410static
    412 SCIP* scip, /**< SCIP data structure */
    413 SCIP_PRICER* pricer, /**< variable pricer structure */
    414 SCIP_Bool isfarkas, /**< whether we perform Farkas pricing */
    415 SCIP_RESULT* result /**< pointer to store the result */
    416 )
    417{
    418 SCIP* subscip;
    419 SCIP_PRICERDATA* pricerdata;
    420 SCIP_CONS** conss;
    421 SCIP_VAR** vars;
    422 int* ids;
    423 SCIP_Bool addvar;
    424
    425 SCIP_SOL** sols;
    426 int nsols;
    427 int s;
    428
    429 int nitems;
    430 SCIP_Longint capacity;
    431
    432 SCIP_Real timelimit;
    433 SCIP_Real memorylimit;
    434
    435 assert(scip != NULL);
    436 assert(pricer != NULL);
    437 assert(result != NULL);
    438
    439 (*result) = SCIP_DIDNOTRUN;
    440
    441 /* get the pricer data */
    442 pricerdata = SCIPpricerGetData(pricer);
    443 assert(pricerdata != NULL);
    444
    445 capacity = pricerdata->capacity;
    446 conss = pricerdata->conss;
    447 ids = pricerdata->ids;
    448 nitems = pricerdata->nitems;
    449
    450 /* get the remaining time and memory limit */
    451 SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
    452 if( !SCIPisInfinity(scip, timelimit) )
    453 timelimit -= SCIPgetSolvingTime(scip);
    454 SCIP_CALL( SCIPgetRealParam(scip, "limits/memory", &memorylimit) );
    455 if( !SCIPisInfinity(scip, memorylimit) )
    456 memorylimit -= SCIPgetMemUsed(scip)/1048576.0;
    457
    458 /* initialize SCIP */
    459 SCIP_CALL( SCIPcreate(&subscip) );
    461
    462 /* create problem in sub SCIP */
    463 SCIP_CALL( SCIPcreateProbBasic(subscip, "pricing") );
    465
    466 /* do not abort subproblem on CTRL-C */
    467 SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
    468
    469 /* disable output to console */
    470 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) );
    471
    472 /* set time and memory limit */
    473 SCIP_CALL( SCIPsetRealParam(subscip, "limits/time", timelimit) );
    474 SCIP_CALL( SCIPsetRealParam(subscip, "limits/memory", memorylimit) );
    475
    476 /* allocate in orginal scip, since otherwise the buffer counts in subscip are not correct */
    477 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nitems) );
    478
    479 /* initialization local pricing problem */
    480 SCIP_CALL( initPricing(scip, pricerdata, isfarkas, subscip, vars) );
    481
    482 SCIPdebugMsg(scip, "solve pricer problem\n");
    483
    484 /* solve sub SCIP */
    485 SCIP_CALL( SCIPsolve(subscip) );
    486
    487 sols = SCIPgetSols(subscip);
    488 nsols = SCIPgetNSols(subscip);
    489 addvar = FALSE;
    490
    491 /* loop over all solutions and create the corresponding column to master if the reduced cost is negative for a
    492 * feasible dual solution of the restricted master LP, that is, the objective value is greater than 1.0 if the LP is
    493 * feasible or greater than 0.0 if the LP is infeasible
    494 */
    495 for( s = 0; s < nsols; ++s )
    496 {
    497 SCIP_Bool feasible;
    498 SCIP_SOL* sol;
    499
    500 /* the soultion should be sorted w.r.t. the objective function value */
    501 assert(s == 0 || SCIPisFeasGE(subscip, SCIPgetSolOrigObj(subscip, sols[s-1]), SCIPgetSolOrigObj(subscip, sols[s])));
    502
    503 sol = sols[s];
    504 assert(sol != NULL);
    505
    506 /* check if solution is feasible in original sub SCIP */
    507 SCIP_CALL( SCIPcheckSolOrig(subscip, sol, &feasible, FALSE, FALSE ) );
    508
    509 if( !feasible )
    510 {
    511 SCIPwarningMessage(scip, "solution in pricing problem (capacity <%" SCIP_LONGINT_FORMAT ">) is infeasible\n", capacity);
    512 continue;
    513 }
    514
    515 /* check if the solution has a value greater than 1.0 in redcost pricing or greater than 0.0 in Farkas pricing */
    516 if( SCIPisFeasGT(subscip, SCIPgetSolOrigObj(subscip, sol), isfarkas ? 0.0 : 1.0) )
    517 {
    518 SCIP_VAR* var;
    519 SCIP_VARDATA* vardata;
    520 int* consids;
    521 char strtmp[SCIP_MAXSTRLEN];
    522 char name[SCIP_MAXSTRLEN];
    523 int nconss;
    524 int o;
    525 int v;
    526
    527 SCIPdebug( SCIP_CALL( SCIPprintSol(subscip, sol, NULL, FALSE) ) );
    528
    529 nconss = 0;
    530 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "items");
    531
    532 SCIP_CALL( SCIPallocBufferArray(scip, &consids, nitems) );
    533
    534 /* check which variables are fixed -> which item belongs to this packing */
    535 for( o = 0, v = 0; o < nitems; ++o )
    536 {
    537 if( !SCIPconsIsEnabled(conss[o]) )
    538 continue;
    539
    540 assert(SCIPgetNFixedonesSetppc(scip, conss[o]) == 0);
    541
    542 if( SCIPgetSolVal(subscip, sol, vars[v]) > 0.5 )
    543 {
    544 (void) SCIPsnprintf(strtmp, SCIP_MAXSTRLEN, "_%d", ids[o]);
    545 strcat(name, strtmp);
    546
    547 consids[nconss] = o;
    548 nconss++;
    549 }
    550 else
    551 assert( SCIPisFeasEQ(subscip, SCIPgetSolVal(subscip, sol, vars[v]), 0.0) );
    552
    553 v++;
    554 }
    555
    556 SCIP_CALL( SCIPvardataCreateBinpacking(scip, &vardata, consids, nconss) );
    557
    558 /* create variable for a new column with objective function coefficient 1.0 */
    559 SCIP_CALL( SCIPcreateVarBinpacking(scip, &var, name, 1.0, FALSE, TRUE, vardata) );
    560
    561 /* add the new variable to the pricer store */
    562 SCIP_CALL( SCIPaddPricedVar(scip, var, 1.0) );
    563 addvar = TRUE;
    564
    565 /* change the upper bound of the binary variable to lazy since the upper bound is already enforced due to
    566 * the objective function the set covering constraint; The reason for doing is that, is to avoid the bound
    567 * of x <= 1 in the LP relaxation since this bound constraint would produce a dual variable which might have
    568 * a positive reduced cost
    569 */
    570 SCIP_CALL( SCIPchgVarUbLazy(scip, var, 1.0) );
    571
    572 /* check which variable are fixed -> which orders belong to this packing */
    573 for( v = 0; v < nconss; ++v )
    574 {
    575 assert(SCIPconsIsEnabled(conss[consids[v]]));
    576 SCIP_CALL( SCIPaddCoefSetppc(scip, conss[consids[v]], var) );
    577 }
    578
    580 SCIP_CALL( SCIPreleaseVar(scip, &var) );
    581
    582 SCIPfreeBufferArray(scip, &consids);
    583 }
    584 else
    585 break;
    586 }
    587
    588 /* free pricer MIP */
    590
    591 if( addvar || SCIPgetStatus(subscip) == SCIP_STATUS_OPTIMAL )
    592 (*result) = SCIP_SUCCESS;
    593
    594 /* free sub SCIP */
    595 SCIP_CALL( SCIPfree(&subscip) );
    596
    597 return SCIP_OKAY;
    598}
    599
    600/**@} */
    601
    602/**name Callback methods
    603 *
    604 * @{
    605 */
    606
    607/** destructor of variable pricer to free user data (called when SCIP is exiting) */
    608static
    609SCIP_DECL_PRICERFREE(pricerFreeBinpacking)
    610{
    611 SCIP_PRICERDATA* pricerdata;
    612
    613 assert(scip != NULL);
    614 assert(pricer != NULL);
    615
    616 pricerdata = SCIPpricerGetData(pricer);
    617
    618 if( pricerdata != NULL)
    619 {
    620 /* free memory */
    621 SCIPfreeBlockMemoryArrayNull(scip, &pricerdata->conss, pricerdata->nitems);
    622 SCIPfreeBlockMemoryArrayNull(scip, &pricerdata->weights, pricerdata->nitems);
    623 SCIPfreeBlockMemoryArrayNull(scip, &pricerdata->ids, pricerdata->nitems);
    624
    625 SCIPfreeBlockMemory(scip, &pricerdata);
    626 }
    627
    628 return SCIP_OKAY;
    629}
    630
    631
    632/** initialization method of variable pricer (called after problem was transformed) */
    633static
    634SCIP_DECL_PRICERINIT(pricerInitBinpacking)
    635{ /*lint --e{715}*/
    636 SCIP_PRICERDATA* pricerdata;
    637 SCIP_CONS* cons;
    638 int c;
    639
    640 assert(scip != NULL);
    641 assert(pricer != NULL);
    642
    643 pricerdata = SCIPpricerGetData(pricer);
    644 assert(pricerdata != NULL);
    645
    646 /* get transformed constraints */
    647 for( c = 0; c < pricerdata->nitems; ++c )
    648 {
    649 cons = pricerdata->conss[c];
    650
    651 /* release original constraint */
    652 SCIP_CALL( SCIPreleaseCons(scip, &pricerdata->conss[c]) );
    653
    654 /* get transformed constraint */
    655 SCIP_CALL( SCIPgetTransformedCons(scip, cons, &pricerdata->conss[c]) );
    656
    657 /* capture transformed constraint */
    658 SCIP_CALL( SCIPcaptureCons(scip, pricerdata->conss[c]) );
    659 }
    660
    661 return SCIP_OKAY;
    662}
    663
    664
    665/** solving process deinitialization method of variable pricer (called before branch and bound process data is freed) */
    666static
    667SCIP_DECL_PRICEREXITSOL(pricerExitsolBinpacking)
    668{
    669 SCIP_PRICERDATA* pricerdata;
    670 int c;
    671
    672 assert(scip != NULL);
    673 assert(pricer != NULL);
    674
    675 pricerdata = SCIPpricerGetData(pricer);
    676 assert(pricerdata != NULL);
    677
    678 /* get release constraints */
    679 for( c = 0; c < pricerdata->nitems; ++c )
    680 {
    681 /* release constraint */
    682 SCIP_CALL( SCIPreleaseCons(scip, &(pricerdata->conss[c])) );
    683 }
    684
    685 return SCIP_OKAY;
    686}
    687
    688/** reduced cost pricing method of variable pricer for feasible LPs */
    689static
    690SCIP_DECL_PRICERREDCOST(pricerRedcostBinpacking)
    691{ /*lint --e{715}*/
    692 SCIP_CALL( doPricing(scip, pricer, FALSE, result) );
    693
    694 return SCIP_OKAY;
    695}
    696
    697/** farkas pricing method of variable pricer for infeasible LPs */
    698static
    699SCIP_DECL_PRICERFARKAS(pricerFarkasBinpacking)
    700{ /*lint --e{715}*/
    701 SCIP_CALL( doPricing(scip, pricer, TRUE, result) );
    702
    703 return SCIP_OKAY;
    704}
    705
    706/**@} */
    707
    708
    709/**@name Interface methods
    710 *
    711 * @{
    712 */
    713
    714/** creates the binpacking variable pricer and includes it in SCIP */
    716 SCIP* scip /**< SCIP data structure */
    717 )
    718{
    719 SCIP_PRICERDATA* pricerdata;
    720 SCIP_PRICER* pricer;
    721
    722 /* create binpacking variable pricer data */
    723 SCIP_CALL( SCIPallocBlockMemory(scip, &pricerdata) );
    724
    725 pricerdata->conshdlr = SCIPfindConshdlr(scip, "samediff");
    726 assert(pricerdata->conshdlr != NULL);
    727
    728 pricerdata->conss = NULL;
    729 pricerdata->weights = NULL;
    730 pricerdata->ids = NULL;
    731 pricerdata->nitems = 0;
    732 pricerdata->capacity = 0;
    733
    734 /* include variable pricer */
    736 pricerRedcostBinpacking, pricerFarkasBinpacking, pricerdata) );
    737
    738 SCIP_CALL( SCIPsetPricerFree(scip, pricer, pricerFreeBinpacking) );
    739 SCIP_CALL( SCIPsetPricerInit(scip, pricer, pricerInitBinpacking) );
    740 SCIP_CALL( SCIPsetPricerExitsol(scip, pricer, pricerExitsolBinpacking) );
    741
    742 /* add binpacking variable pricer parameters */
    743 /* TODO: (optional) add variable pricer specific parameters with SCIPaddTypeParam() here */
    744
    745 return SCIP_OKAY;
    746}
    747
    748
    749/** added problem specific data to pricer and activates pricer */
    751 SCIP* scip, /**< SCIP data structure */
    752 SCIP_CONS** conss, /**< set covering constraints for the items */
    753 SCIP_Longint* weights, /**< weight of the items */
    754 int* ids, /**< array of item ids */
    755 int nitems, /**< number of items to be packed */
    756 SCIP_Longint capacity /**< capacity of the bins */
    757 )
    758{
    759 SCIP_PRICER* pricer;
    760 SCIP_PRICERDATA* pricerdata;
    761 int c;
    762
    763 assert(scip != NULL);
    764 assert(conss != NULL);
    765 assert(weights != NULL);
    766 assert(nitems > 0);
    767
    769 assert(pricer != NULL);
    770
    771 pricerdata = SCIPpricerGetData(pricer);
    772 assert(pricerdata != NULL);
    773
    774 /* copy arrays */
    775 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &pricerdata->conss, conss, nitems) );
    776 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &pricerdata->weights, weights, nitems) );
    777 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &pricerdata->ids, ids, nitems) );
    778
    779 pricerdata->nitems = nitems;
    780 pricerdata->capacity = capacity;
    781
    782 SCIPdebugMsg(scip, " nitems: %d capacity: %"SCIP_LONGINT_FORMAT" \n", nitems, capacity);
    783 SCIPdebugMsg(scip, " # profits weights x \n"); /* capture constraints */
    784
    785 /* capture all constraints */
    786 for( c = 0; c < nitems; ++c )
    787 {
    788 SCIP_CALL( SCIPcaptureCons(scip, conss[c]) );
    789 SCIPdebugMsgPrint(scip, "%4d %3"SCIP_LONGINT_FORMAT"\n", c, weights[c]);
    790 }
    791
    792 /* activate pricer */
    794
    795 return SCIP_OKAY;
    796}
    797
    798/**@} */
    Constraint handler for knapsack constraints of the form , x binary and .
    Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
    CONSTYPE SCIPgetTypeSamediff(SCIP_CONS *cons)
    int SCIPgetItemid2Samediff(SCIP_CONS *cons)
    int SCIPgetItemid1Samediff(SCIP_CONS *cons)
    Constraint handler stores the local branching decision data.
    enum ConsType CONSTYPE
    Definition: cons_samediff.h:49
    @ SAME
    Definition: cons_samediff.h:47
    @ DIFFER
    Definition: cons_samediff.h:46
    Constraint handler for the set partitioning / packing / covering constraints .
    Constraint handler for variable bound constraints .
    #define NULL
    Definition: def.h:248
    #define SCIP_MAXSTRLEN
    Definition: def.h:269
    #define SCIP_Longint
    Definition: def.h:141
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define SCIP_LONGINT_FORMAT
    Definition: def.h:148
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_RETCODE SCIPcreateConsBasicVarbound(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *var, SCIP_VAR *vbdvar, SCIP_Real vbdcoef, SCIP_Real lhs, SCIP_Real rhs)
    SCIP_RETCODE SCIPcreateConsBasicKnapsack(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Longint *weights, SCIP_Longint capacity)
    int SCIPgetNFixedonesSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9792
    SCIP_RETCODE SCIPaddCoefSetppc(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
    Definition: cons_setppc.c:9573
    SCIP_RETCODE SCIPcreateConsBasicLogicor(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars)
    SCIP_Real SCIPgetDualsolSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9664
    SCIP_Real SCIPgetDualfarkasSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9690
    SCIP_RETCODE SCIPfree(SCIP **scip)
    Definition: scip_general.c:402
    SCIP_RETCODE SCIPcreate(SCIP **scip)
    Definition: scip_general.c:370
    SCIP_STATUS SCIPgetStatus(SCIP *scip)
    Definition: scip_general.c:562
    SCIP_STAGE SCIPgetStage(SCIP *scip)
    Definition: scip_general.c:444
    SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_prob.c:1907
    SCIP_RETCODE SCIPaddPricedVar(SCIP *scip, SCIP_VAR *var, SCIP_Real score)
    Definition: scip_prob.c:1984
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3274
    SCIP_PROBDATA * SCIPgetProbData(SCIP *scip)
    Definition: scip_prob.c:1139
    SCIP_VAR ** SCIPgetVars(SCIP *scip)
    Definition: scip_prob.c:2201
    SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
    Definition: scip_prob.c:1417
    SCIP_RETCODE SCIPcreateProbBasic(SCIP *scip, const char *name)
    Definition: scip_prob.c:182
    SCIP_RETCODE SCIPdelConsLocal(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:4067
    #define SCIPdebugMsgPrint
    Definition: scip_message.h:79
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
    Definition: scip_message.c:120
    SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
    Definition: scip_param.c:487
    SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
    Definition: scip_param.c:307
    SCIP_RETCODE SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
    Definition: scip_param.c:429
    SCIP_RETCODE SCIPsetRealParam(SCIP *scip, const char *name, SCIP_Real value)
    Definition: scip_param.c:603
    int SCIPconshdlrGetNConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4778
    const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4316
    SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
    Definition: scip_cons.c:940
    SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4735
    SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
    Definition: cons.c:8409
    SCIP_RETCODE SCIPsetConsInitial(SCIP *scip, SCIP_CONS *cons, SCIP_Bool initial)
    Definition: scip_cons.c:1271
    SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
    Definition: cons.c:8450
    SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
    Definition: cons.c:8486
    const char * SCIPconsGetName(SCIP_CONS *cons)
    Definition: cons.c:8389
    SCIP_RETCODE SCIPgetTransformedCons(SCIP *scip, SCIP_CONS *cons, SCIP_CONS **transcons)
    Definition: scip_cons.c:1674
    SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
    Definition: scip_cons.c:1173
    SCIP_RETCODE SCIPcaptureCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:1138
    SCIP_Longint SCIPgetMemUsed(SCIP *scip)
    Definition: scip_mem.c:100
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    #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
    #define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
    Definition: scip_mem.h:105
    SCIP_RETCODE SCIPsetPricerExitsol(SCIP *scip, SCIP_PRICER *pricer, SCIP_DECL_PRICEREXITSOL((*pricerexitsol)))
    Definition: scip_pricer.c:295
    SCIP_PRICER * SCIPfindPricer(SCIP *scip, const char *name)
    Definition: scip_pricer.c:311
    SCIP_RETCODE SCIPsetPricerInit(SCIP *scip, SCIP_PRICER *pricer, SCIP_DECL_PRICERINIT((*pricerinit)))
    Definition: scip_pricer.c:223
    SCIP_PRICERDATA * SCIPpricerGetData(SCIP_PRICER *pricer)
    Definition: pricer.c:522
    SCIP_RETCODE SCIPactivatePricer(SCIP *scip, SCIP_PRICER *pricer)
    Definition: scip_pricer.c:384
    SCIP_RETCODE SCIPsetPricerFree(SCIP *scip, SCIP_PRICER *pricer, SCIP_DECL_PRICERFREE((*pricerfree)))
    Definition: scip_pricer.c:199
    SCIP_RETCODE SCIPincludePricerBasic(SCIP *scip, SCIP_PRICER **pricerptr, const char *name, const char *desc, int priority, SCIP_Bool delay, SCIP_DECL_PRICERREDCOST((*pricerredcost)), SCIP_DECL_PRICERFARKAS((*pricerfarkas)), SCIP_PRICERDATA *pricerdata)
    Definition: scip_pricer.c:127
    SCIP_RETCODE SCIPcheckSolOrig(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *feasible, SCIP_Bool printreason, SCIP_Bool completely)
    Definition: scip_sol.c:4380
    SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
    Definition: scip_sol.c:2349
    int SCIPgetNSols(SCIP *scip)
    Definition: scip_sol.c:2882
    SCIP_SOL ** SCIPgetSols(SCIP *scip)
    Definition: scip_sol.c:2931
    SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1892
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1765
    SCIP_RETCODE SCIPsolve(SCIP *scip)
    Definition: scip_solve.c:2635
    SCIP_Real SCIPgetSolvingTime(SCIP *scip)
    Definition: scip_timing.c:378
    SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24268
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23453
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24142
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
    Definition: scip_var.c:1887
    SCIP_VARDATA * SCIPvarGetData(SCIP_VAR *var)
    Definition: var.c:23287
    SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
    Definition: scip_var.c:2166
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24234
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24120
    SCIP_RETCODE SCIPprintVar(SCIP *scip, SCIP_VAR *var, FILE *file)
    Definition: scip_var.c:12465
    SCIP_RETCODE SCIPcreateVarBasic(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype)
    Definition: scip_var.c:184
    SCIP_RETCODE SCIPchgVarUbLazy(SCIP *scip, SCIP_VAR *var, SCIP_Real lazyub)
    Definition: scip_var.c:6362
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    static SCIP_DECL_PRICERREDCOST(pricerRedcostBinpacking)
    static SCIP_RETCODE addFixedVarsConss(SCIP *scip, SCIP *subscip, SCIP_VAR **vars, SCIP_CONS **conss, int nitems)
    static SCIP_RETCODE doPricing(SCIP *scip, SCIP_PRICER *pricer, SCIP_Bool isfarkas, SCIP_RESULT *result)
    SCIP_RETCODE SCIPincludePricerBinpacking(SCIP *scip)
    SCIP_RETCODE SCIPpricerBinpackingActivate(SCIP *scip, SCIP_CONS **conss, SCIP_Longint *weights, int *ids, int nitems, SCIP_Longint capacity)
    static SCIP_DECL_PRICEREXITSOL(pricerExitsolBinpacking)
    static SCIP_DECL_PRICERFARKAS(pricerFarkasBinpacking)
    #define PRICER_PRIORITY
    #define PRICER_NAME
    static SCIP_RETCODE initPricing(SCIP *scip, SCIP_PRICERDATA *pricerdata, SCIP_Bool isfarkas, SCIP *subscip, SCIP_VAR **vars)
    static SCIP_DECL_PRICERFREE(pricerFreeBinpacking)
    static SCIP_RETCODE addBranchingDecisionConss(SCIP *scip, SCIP *subscip, SCIP_VAR **vars, SCIP_CONSHDLR *conshdlr)
    static SCIP_DECL_PRICERINIT(pricerInitBinpacking)
    #define PRICER_DELAY
    #define PRICER_DESC
    Binpacking variable pricer.
    int * SCIPprobdataGetIds(SCIP_PROBDATA *probdata)
    Problem data for binpacking problem.
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPdebug(x)
    Definition: pub_message.h:93
    #define SCIPdebugPrintCons(x, y, z)
    Definition: pub_message.h:102
    SCIP_RETCODE SCIPincludeDefaultPlugins(SCIP *scip)
    default SCIP plugins
    struct SCIP_PricerData SCIP_PRICERDATA
    Definition: type_pricer.h:45
    @ SCIP_OBJSENSE_MAXIMIZE
    Definition: type_prob.h:47
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_SUCCESS
    Definition: type_result.h:58
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_STAGE_PROBLEM
    Definition: type_set.h:45
    @ SCIP_STATUS_OPTIMAL
    Definition: type_stat.h:43
    struct SCIP_VarData SCIP_VARDATA
    Definition: type_var.h:167
    @ SCIP_VARTYPE_BINARY
    Definition: type_var.h:64
    int * SCIPvardataGetConsids(SCIP_VARDATA *vardata)
    SCIP_RETCODE SCIPcreateVarBinpacking(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real obj, SCIP_Bool initial, SCIP_Bool removable, SCIP_VARDATA *vardata)
    SCIP_RETCODE SCIPvardataCreateBinpacking(SCIP *scip, SCIP_VARDATA **vardata, int *consids, int nconsids)
    int SCIPvardataGetNConsids(SCIP_VARDATA *vardata)
    Variable data containing the ids of constraints in which the variable appears.