PySCIPOpt  5.1.1
Python Interface for the SCIP Optimization Suite
weber_soco.py
Go to the documentation of this file.
1 
3 """
4 Copyright (c) by Joao Pedro PEDROSO, Masahiro MURAMATSU and Mikio KUBO, 2012
5 """
6 from pyscipopt import Model, quicksum
7 
8 
9 def weber(I, x, y, w):
10  """weber: model for solving the single source weber problem using soco.
11  Parameters:
12  - I: set of customers
13  - x[i]: x position of customer i
14  - y[i]: y position of customer i
15  - w[i]: weight of customer i
16  Returns a model, ready to be solved.
17  """
18 
19  model = Model("weber")
20 
21  X, Y, z, xaux, yaux = {}, {}, {}, {}, {}
22  X = model.addVar(lb=-model.infinity(), vtype="C", name="X")
23  Y = model.addVar(lb=-model.infinity(), vtype="C", name="Y")
24  for i in I:
25  z[i] = model.addVar(vtype="C", name="z(%s)" % (i))
26  xaux[i] = model.addVar(lb=-model.infinity(), vtype="C", name="xaux(%s)" % (i))
27  yaux[i] = model.addVar(lb=-model.infinity(), vtype="C", name="yaux(%s)" % (i))
28 
29  for i in I:
30  model.addCons(xaux[i] * xaux[i] + yaux[i] * yaux[i] <= z[i] * z[i], "MinDist(%s)" % (i))
31  model.addCons(xaux[i] == (x[i] - X), "xAux(%s)" % (i))
32  model.addCons(yaux[i] == (y[i] - Y), "yAux(%s)" % (i))
33 
34  model.setObjective(quicksum(w[i] * z[i] for i in I), "minimize")
35 
36  model.data = X, Y, z
37  return model
38 
39 
40 import random
41 
42 
43 def make_data(n, m):
44  """creates example data set"""
45  I = range(1, n + 1)
46  J = range(1, m + 1)
47  x, y, w = {}, {}, {}
48  for i in I:
49  x[i] = random.randint(0, 100)
50  y[i] = random.randint(0, 100)
51  w[i] = random.randint(1, 5)
52  return I, J, x, y, w
53 
54 
55 if __name__ == "__main__":
56 
57  random.seed(3)
58  n = 7
59  m = 1
60  I, J, x, y, w = make_data(n, m)
61  print("data:")
62  print("%s\t%8s\t%8s\t%8s" % ("i", "x[i]", "y[i]", "w[i]"))
63  for i in I:
64  print("%s\t%8g\t%8g\t%8g" % (i, x[i], y[i], w[i]))
65  print
66 
67  model = weber(I, x, y, w)
68  model.optimize()
69  X, Y, z = model.data
70  print("Optimal value=", model.getObjVal())
71  print("Selected position:", )
72  print("\t", (round(model.getVal(X)), round(model.getVal(Y))))
73  print
74  print("Solution:")
75  print("%s\t%8s" % ("i", "z[i]"))
76  for i in I:
77  print("%s\t%8g" % (i, model.getVal(z[i])))
78  print
79  try: # plot the result using networkx and matplotlib
80  import networkx as NX
81  import matplotlib.pyplot as P
82 
83  P.clf()
84  G = NX.Graph()
85 
86  G.add_nodes_from(I)
87  G.add_nodes_from(["D"])
88 
89  position = {}
90  for i in I:
91  position[i] = (x[i], y[i])
92  position["D"] = (round(model.getVal(X)), round(model.getVal(Y)))
93 
94  NX.draw(G, pos=position, node_size=200, node_color="g", nodelist=I)
95  NX.draw(G, pos=position, node_size=400, node_color="w", nodelist=["D"], alpha=0.5)
96  # P.savefig("weber.pdf",format="pdf",dpi=300)
97  P.show()
98 
99  except ImportError:
100  print("install 'networkx' and 'matplotlib' for plotting")
101 
102 
103 def weber_MS(I, J, x, y, w):
104  """weber -- model for solving the weber problem using soco (multiple source version).
105  Parameters:
106  - I: set of customers
107  - J: set of potential facilities
108  - x[i]: x position of customer i
109  - y[i]: y position of customer i
110  - w[i]: weight of customer i
111  Returns a model, ready to be solved.
112  """
113  M = max([((x[i] - x[j]) ** 2 + (y[i] - y[j]) ** 2) for i in I for j in I])
114  model = Model("weber - multiple source")
115  X, Y, v, u = {}, {}, {}, {}
116  xaux, yaux, uaux = {}, {}, {}
117  for j in J:
118  X[j] = model.addVar(lb=-model.infinity(), vtype="C", name="X(%s)" % j)
119  Y[j] = model.addVar(lb=-model.infinity(), vtype="C", name="Y(%s)" % j)
120  for i in I:
121  v[i, j] = model.addVar(vtype="C", name="v(%s,%s)" % (i, j))
122  u[i, j] = model.addVar(vtype="B", name="u(%s,%s)" % (i, j))
123  xaux[i, j] = model.addVar(lb=-model.infinity(), vtype="C", name="xaux(%s,%s)" % (i, j))
124  yaux[i, j] = model.addVar(lb=-model.infinity(), vtype="C", name="yaux(%s,%s)" % (i, j))
125  uaux[i, j] = model.addVar(vtype="C", name="uaux(%s,%s)" % (i, j))
126 
127  for i in I:
128  model.addCons(quicksum(u[i, j] for j in J) == 1, "Assign(%s)" % i)
129  for j in J:
130  model.addCons(xaux[i, j] * xaux[i, j] + yaux[i, j] * yaux[i, j] <= v[i, j] * v[i, j],
131  "MinDist(%s,%s)" % (i, j))
132  model.addCons(xaux[i, j] == (x[i] - X[j]), "xAux(%s,%s)" % (i, j))
133  model.addCons(yaux[i, j] == (y[i] - Y[j]), "yAux(%s,%s)" % (i, j))
134  model.addCons(uaux[i, j] >= v[i, j] - M * (1 - u[i, j]), "uAux(%s,%s)" % (i, j))
135 
136  model.setObjective(quicksum(w[i] * uaux[i, j] for i in I for j in J), "minimize")
137 
138  model.data = X, Y, v, u
139  return model
140 
141 
142 if __name__ == "__main__":
143  random.seed(3)
144  n = 7
145  m = 1
146  I, J, x, y, w = make_data(n, m)
147  model = weber_MS(I, J, x, y, w)
148  model.optimize()
149  X, Y, w, z = model.data
150  print("Optimal value:", model.getObjVal())
151  print("Selected positions:")
152  for j in J:
153  print("\t", (model.getVal(X[j]), model.getVal(Y[j])))
154  for (i, j) in sorted(w.keys()):
155  print("\t", (i, j), model.getVal(w[i, j]), model.getVal(z[i, j]))
156 
157  EPS = 1.e-4
158  edges = [(i, j) for (i, j) in z if model.getVal(z[i, j]) > EPS]
159 
160  try: # plot the result using networkx and matplotlib
161  import networkx as NX
162  import matplotlib.pyplot as P
163 
164  P.clf()
165  G = NX.Graph()
166 
167  G.add_nodes_from(I)
168  G.add_nodes_from("%s" % j for j in J) # for distinguishing J from I, make nodes as strings
169  for (i, j) in edges:
170  G.add_edge(i, "%s" % j)
171 
172  position = {}
173  for i in I:
174  position[i] = (x[i], y[i])
175  for j in J:
176  position["%s" % j] = (model.getVal(X[j]), model.getVal(Y[j]))
177  print(position)
178 
179  NX.draw(G, position, node_color="g", nodelist=I)
180  NX.draw(G, position, node_color="w", nodelist=["%s" % j for j in J])
181  P.show()
182  except ImportError:
183  print("install 'networkx' and 'matplotlib' for plotting")
pyscipopt.expr.quicksum
def quicksum(termlist)
Definition: expr.pxi:357
weber_soco.weber_MS
def weber_MS(I, J, x, y, w)
Definition: weber_soco.py:103
weber_soco.weber
def weber(I, x, y, w)
Definition: weber_soco.py:9
weber_soco.make_data
def make_data(n, m)
Definition: weber_soco.py:43