PySCIPOpt  5.1.1
Python Interface for the SCIP Optimization Suite
bpp.py
Go to the documentation of this file.
1 
3 """
4 The instance of the bin packing problem is represented by the two
5 lists of n items of sizes and quantity s=(s_i).
6 The bin size is B.
7 
8 We use Martello and Toth (1990) formulation, and suggest
9 extensions with tie-breaking and SOS constraints.
10 
11 Copyright (c) by Joao Pedro PEDROSO and Mikio KUBO, 2012
12 """
13 
14 from pyscipopt import Model, quicksum
15 
16 
17 def FFD(s, B):
18  """First Fit Decreasing heuristics for the Bin Packing Problem.
19  Parameters:
20  - s: list with item widths
21  - B: bin capacity
22  Returns a list of lists with bin compositions.
23  """
24  remain = [B] # keep list of empty space per bin
25  sol = [[]] # a list ot items (i.e., sizes) on each used bin
26  for item in sorted(s, reverse=True):
27  for (j, free) in enumerate(remain):
28  if free >= item:
29  remain[j] -= item
30  sol[j].append(item)
31  break
32  else: # does not fit in any bin
33  sol.append([item])
34  remain.append(B - item)
35  return sol
36 
37 
38 def bpp(s, B):
39  """bpp: Martello and Toth's model to solve the bin packing problem.
40  Parameters:
41  - s: list with item widths
42  - B: bin capacity
43  Returns a model, ready to be solved.
44  """
45  n = len(s)
46  U = len(FFD(s, B)) # upper bound of the number of bins
47  model = Model("bpp")
48  # setParam("MIPFocus",1)
49  x, y = {}, {}
50  for i in range(n):
51  for j in range(U):
52  x[i, j] = model.addVar(vtype="B", name="x(%s,%s)" % (i, j))
53  for j in range(U):
54  y[j] = model.addVar(vtype="B", name="y(%s)" % j)
55 
56  # assignment constraints
57  for i in range(n):
58  model.addCons(quicksum(x[i, j] for j in range(U)) == 1, "Assign(%s)" % i)
59 
60  # bin capacity constraints
61  for j in range(U):
62  model.addCons(quicksum(s[i] * x[i, j] for i in range(n)) <= B * y[j], "Capac(%s)" % j)
63 
64  # tighten assignment constraints
65  for j in range(U):
66  for i in range(n):
67  model.addCons(x[i, j] <= y[j], "Strong(%s,%s)" % (i, j))
68 
69  # tie breaking constraints
70  for j in range(U - 1):
71  model.addCons(y[j] >= y[j + 1], "TieBrk(%s)" % j)
72 
73  # SOS constraints
74  for i in range(n):
75  model.addConsSOS1([x[i, j] for j in range(U)])
76 
77  model.setObjective(quicksum(y[j] for j in range(U)), "minimize")
78  model.data = x, y
79 
80  return model
81 
82 
83 def solveBinPacking(s, B):
84  """solveBinPacking: use an IP model to solve the in Packing Problem.
85 
86  Parameters:
87  - s: list with item widths
88  - B: bin capacity
89 
90  Returns a solution: list of lists, each of which with the items in a roll.
91  """
92  n = len(s)
93  U = len(FFD(s, B)) # upper bound of the number of bins
94  model = bpp(s, B)
95  x, y = model.data
96 
97  model.optimize()
98 
99  bins = [[] for i in range(U)]
100  for (i, j) in x:
101  if model.getVal(x[i, j]) > .5:
102  bins[j].append(s[i])
103  for i in range(bins.count([])):
104  bins.remove([])
105  for b in bins:
106  b.sort()
107  bins.sort()
108  return bins
109 
110 
111 import random
112 
113 
114 def DiscreteUniform(n=10, LB=1, UB=99, B=100):
115  """DiscreteUniform: create random, uniform instance for the bin packing problem."""
116  B = 100
117  s = [0] * n
118  for i in range(n):
119  s[i] = random.randint(LB, UB)
120  return s, B
121 
122 
123 if __name__ == "__main__":
124  random.seed(256)
126  print("items:", s)
127  print("bin size:", B)
128 
129  ffd = FFD(s, B)
130  print("\n\n\n FFD heuristic:")
131  print("Solution:")
132  print(ffd)
133  print(len(ffd), "bins")
134 
135  print("\n\n\n IP formulation:")
136  bins = solveBinPacking(s, B)
137  print("Solution:")
138  print(bins)
139  print(len(bins), "bins")
pyscipopt.expr.quicksum
def quicksum(termlist)
Definition: expr.pxi:357
bpp.bpp
def bpp(s, B)
Definition: bpp.py:38
bpp.FFD
def FFD(s, B)
Definition: bpp.py:17
bpp
Definition: bpp.py:1
bpp.solveBinPacking
def solveBinPacking(s, B)
Definition: bpp.py:83
bpp.DiscreteUniform
def DiscreteUniform(n=10, LB=1, UB=99, B=100)
Definition: bpp.py:114