alpar@1
|
1 |
/* BPP, Bin Packing Problem */
|
alpar@1
|
2 |
|
alpar@1
|
3 |
/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */
|
alpar@1
|
4 |
|
alpar@1
|
5 |
/* Given a set of items I = {1,...,m} with weight w[i] > 0, the Bin
|
alpar@1
|
6 |
Packing Problem (BPP) is to pack the items into bins of capacity c
|
alpar@1
|
7 |
in such a way that the number of bins used is minimal. */
|
alpar@1
|
8 |
|
alpar@1
|
9 |
param m, integer, > 0;
|
alpar@1
|
10 |
/* number of items */
|
alpar@1
|
11 |
|
alpar@1
|
12 |
set I := 1..m;
|
alpar@1
|
13 |
/* set of items */
|
alpar@1
|
14 |
|
alpar@1
|
15 |
param w{i in 1..m}, > 0;
|
alpar@1
|
16 |
/* w[i] is weight of item i */
|
alpar@1
|
17 |
|
alpar@1
|
18 |
param c, > 0;
|
alpar@1
|
19 |
/* bin capacity */
|
alpar@1
|
20 |
|
alpar@1
|
21 |
/* We need to estimate an upper bound of the number of bins sufficient
|
alpar@1
|
22 |
to contain all items. The number of items m can be used, however, it
|
alpar@1
|
23 |
is not a good idea. To obtain a more suitable estimation an easy
|
alpar@1
|
24 |
heuristic is used: we put items into a bin while it is possible, and
|
alpar@1
|
25 |
if the bin is full, we use another bin. The number of bins used in
|
alpar@1
|
26 |
this way gives us a more appropriate estimation. */
|
alpar@1
|
27 |
|
alpar@1
|
28 |
param z{i in I, j in 1..m} :=
|
alpar@1
|
29 |
/* z[i,j] = 1 if item i is in bin j, otherwise z[i,j] = 0 */
|
alpar@1
|
30 |
|
alpar@1
|
31 |
if i = 1 and j = 1 then 1
|
alpar@1
|
32 |
/* put item 1 into bin 1 */
|
alpar@1
|
33 |
|
alpar@1
|
34 |
else if exists{jj in 1..j-1} z[i,jj] then 0
|
alpar@1
|
35 |
/* if item i is already in some bin, do not put it into bin j */
|
alpar@1
|
36 |
|
alpar@1
|
37 |
else if sum{ii in 1..i-1} w[ii] * z[ii,j] + w[i] > c then 0
|
alpar@1
|
38 |
/* if item i does not fit into bin j, do not put it into bin j */
|
alpar@1
|
39 |
|
alpar@1
|
40 |
else 1;
|
alpar@1
|
41 |
/* otherwise put item i into bin j */
|
alpar@1
|
42 |
|
alpar@1
|
43 |
check{i in I}: sum{j in 1..m} z[i,j] = 1;
|
alpar@1
|
44 |
/* each item must be exactly in one bin */
|
alpar@1
|
45 |
|
alpar@1
|
46 |
check{j in 1..m}: sum{i in I} w[i] * z[i,j] <= c;
|
alpar@1
|
47 |
/* no bin must be overflowed */
|
alpar@1
|
48 |
|
alpar@1
|
49 |
param n := sum{j in 1..m} if exists{i in I} z[i,j] then 1;
|
alpar@1
|
50 |
/* determine the number of bins used by the heuristic; obviously it is
|
alpar@1
|
51 |
an upper bound of the optimal solution */
|
alpar@1
|
52 |
|
alpar@1
|
53 |
display n;
|
alpar@1
|
54 |
|
alpar@1
|
55 |
set J := 1..n;
|
alpar@1
|
56 |
/* set of bins */
|
alpar@1
|
57 |
|
alpar@1
|
58 |
var x{i in I, j in J}, binary;
|
alpar@1
|
59 |
/* x[i,j] = 1 means item i is in bin j */
|
alpar@1
|
60 |
|
alpar@1
|
61 |
var used{j in J}, binary;
|
alpar@1
|
62 |
/* used[j] = 1 means bin j contains at least one item */
|
alpar@1
|
63 |
|
alpar@1
|
64 |
s.t. one{i in I}: sum{j in J} x[i,j] = 1;
|
alpar@1
|
65 |
/* each item must be exactly in one bin */
|
alpar@1
|
66 |
|
alpar@1
|
67 |
s.t. lim{j in J}: sum{i in I} w[i] * x[i,j] <= c * used[j];
|
alpar@1
|
68 |
/* if bin j is used, it must not be overflowed */
|
alpar@1
|
69 |
|
alpar@1
|
70 |
minimize obj: sum{j in J} used[j];
|
alpar@1
|
71 |
/* objective is to minimize the number of bins used */
|
alpar@1
|
72 |
|
alpar@1
|
73 |
data;
|
alpar@1
|
74 |
|
alpar@1
|
75 |
/* The optimal solution is 3 bins */
|
alpar@1
|
76 |
|
alpar@1
|
77 |
param m := 6;
|
alpar@1
|
78 |
|
alpar@1
|
79 |
param w := 1 50, 2 60, 3 30, 4 70, 5 50, 6 40;
|
alpar@1
|
80 |
|
alpar@1
|
81 |
param c := 100;
|
alpar@1
|
82 |
|
alpar@1
|
83 |
end;
|