alpar@1: /* BPP, Bin Packing Problem */ alpar@1: alpar@1: /* Written in GNU MathProg by Andrew Makhorin */ alpar@1: alpar@1: /* Given a set of items I = {1,...,m} with weight w[i] > 0, the Bin alpar@1: Packing Problem (BPP) is to pack the items into bins of capacity c alpar@1: in such a way that the number of bins used is minimal. */ alpar@1: alpar@1: param m, integer, > 0; alpar@1: /* number of items */ alpar@1: alpar@1: set I := 1..m; alpar@1: /* set of items */ alpar@1: alpar@1: param w{i in 1..m}, > 0; alpar@1: /* w[i] is weight of item i */ alpar@1: alpar@1: param c, > 0; alpar@1: /* bin capacity */ alpar@1: alpar@1: /* We need to estimate an upper bound of the number of bins sufficient alpar@1: to contain all items. The number of items m can be used, however, it alpar@1: is not a good idea. To obtain a more suitable estimation an easy alpar@1: heuristic is used: we put items into a bin while it is possible, and alpar@1: if the bin is full, we use another bin. The number of bins used in alpar@1: this way gives us a more appropriate estimation. */ alpar@1: alpar@1: param z{i in I, j in 1..m} := alpar@1: /* z[i,j] = 1 if item i is in bin j, otherwise z[i,j] = 0 */ alpar@1: alpar@1: if i = 1 and j = 1 then 1 alpar@1: /* put item 1 into bin 1 */ alpar@1: alpar@1: else if exists{jj in 1..j-1} z[i,jj] then 0 alpar@1: /* if item i is already in some bin, do not put it into bin j */ alpar@1: alpar@1: else if sum{ii in 1..i-1} w[ii] * z[ii,j] + w[i] > c then 0 alpar@1: /* if item i does not fit into bin j, do not put it into bin j */ alpar@1: alpar@1: else 1; alpar@1: /* otherwise put item i into bin j */ alpar@1: alpar@1: check{i in I}: sum{j in 1..m} z[i,j] = 1; alpar@1: /* each item must be exactly in one bin */ alpar@1: alpar@1: check{j in 1..m}: sum{i in I} w[i] * z[i,j] <= c; alpar@1: /* no bin must be overflowed */ alpar@1: alpar@1: param n := sum{j in 1..m} if exists{i in I} z[i,j] then 1; alpar@1: /* determine the number of bins used by the heuristic; obviously it is alpar@1: an upper bound of the optimal solution */ alpar@1: alpar@1: display n; alpar@1: alpar@1: set J := 1..n; alpar@1: /* set of bins */ alpar@1: alpar@1: var x{i in I, j in J}, binary; alpar@1: /* x[i,j] = 1 means item i is in bin j */ alpar@1: alpar@1: var used{j in J}, binary; alpar@1: /* used[j] = 1 means bin j contains at least one item */ alpar@1: alpar@1: s.t. one{i in I}: sum{j in J} x[i,j] = 1; alpar@1: /* each item must be exactly in one bin */ alpar@1: alpar@1: s.t. lim{j in J}: sum{i in I} w[i] * x[i,j] <= c * used[j]; alpar@1: /* if bin j is used, it must not be overflowed */ alpar@1: alpar@1: minimize obj: sum{j in J} used[j]; alpar@1: /* objective is to minimize the number of bins used */ alpar@1: alpar@1: data; alpar@1: alpar@1: /* The optimal solution is 3 bins */ alpar@1: alpar@1: param m := 6; alpar@1: alpar@1: param w := 1 50, 2 60, 3 30, 4 70, 5 50, 6 40; alpar@1: alpar@1: param c := 100; alpar@1: alpar@1: end;