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-2024 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(scip, cons);
161 id2 = SCIPgetItemid2Samediff(scip, cons);
162 type = SCIPgetTypeSamediff(scip, 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...
int SCIPgetItemid1Samediff(SCIP *scip, SCIP_CONS *cons)
CONSTYPE SCIPgetTypeSamediff(SCIP *scip, SCIP_CONS *cons)
int SCIPgetItemid2Samediff(SCIP *scip, 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:267
#define SCIP_MAXSTRLEN
Definition: def.h:288
#define SCIP_Longint
Definition: def.h:158
#define SCIP_Bool
Definition: def.h:91
#define SCIP_Real
Definition: def.h:173
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define SCIP_LONGINT_FORMAT
Definition: def.h:165
#define SCIP_CALL(x)
Definition: def.h:374
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:9690
SCIP_RETCODE SCIPaddCoefSetppc(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
Definition: cons_setppc.c:9522
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:9613
SCIP_Real SCIPgetDualfarkasSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9639
SCIP_RETCODE SCIPfree(SCIP **scip)
Definition: scip_general.c:339
SCIP_RETCODE SCIPcreate(SCIP **scip)
Definition: scip_general.c:307
SCIP_STATUS SCIPgetStatus(SCIP *scip)
Definition: scip_general.c:498
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:380
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1668
SCIP_RETCODE SCIPaddPricedVar(SCIP *scip, SCIP_VAR *var, SCIP_Real score)
Definition: scip_prob.c:1733
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:1992
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2770
SCIP_PROBDATA * SCIPgetProbData(SCIP *scip)
Definition: scip_prob.c:964
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:1947
SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
Definition: scip_prob.c:1242
SCIP_RETCODE SCIPcreateProbBasic(SCIP *scip, const char *name)
Definition: scip_prob.c:180
SCIP_RETCODE SCIPdelConsLocal(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:3474
#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:4636
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4197
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip_cons.c:941
SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4593
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8234
SCIP_RETCODE SCIPsetConsInitial(SCIP *scip, SCIP_CONS *cons, SCIP_Bool initial)
Definition: scip_cons.c:1272
SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
Definition: cons.c:8275
SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
Definition: cons.c:8311
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:8214
SCIP_RETCODE SCIPgetTransformedCons(SCIP *scip, SCIP_CONS *cons, SCIP_CONS **transcons)
Definition: scip_cons.c:1675
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1174
SCIP_RETCODE SCIPcaptureCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_cons.c:1139
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:513
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:3309
SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
Definition: scip_sol.c:1631
int SCIPgetNSols(SCIP *scip)
Definition: scip_sol.c:2070
SCIP_SOL ** SCIPgetSols(SCIP *scip)
Definition: scip_sol.c:2119
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip_sol.c:1300
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1217
SCIP_RETCODE SCIPsolve(SCIP *scip)
Definition: scip_solve.c:2498
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:18144
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17584
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:18088
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17419
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1248
SCIP_VARDATA * SCIPvarGetData(SCIP_VAR *var)
Definition: var.c:17439
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip_var.c:1527
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:18134
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:18078
SCIP_RETCODE SCIPprintVar(SCIP *scip, SCIP_VAR *var, FILE *file)
Definition: scip_var.c:9994
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:194
SCIP_RETCODE SCIPchgVarUbLazy(SCIP *scip, SCIP_VAR *var, SCIP_Real lazyub)
Definition: scip_var.c:5164
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10877
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:61
struct SCIP_VarData SCIP_VARDATA
Definition: type_var.h:120
@ SCIP_VARTYPE_BINARY
Definition: type_var.h:62
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.