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