warehouse.py
Go to the documentation of this file.
10 
11 from gams import *
12 import threading
13 import sys
14 import os
15 
17  return '''
18 $title Warehouse.gms
19 
20 $eolcom //
21 $SetDDList warehouse store fixed disaggregate // acceptable defines
22 $if not set warehouse $set warehouse 10
23 $if not set store $set store 50
24 $if not set fixed $set fixed 20
25 $if not set disaggregate $set disaggregate 1 // indicator for tighter bigM constraint
26 $ife %store%<=%warehouse% $abort Increase number of stores (>%warehouse)
27 
28 set res respond codes / 0 Normal
29  1 License Error
30  2 No solution
31  3 Other Error /
32  ares(res) / 3 /;
33 
34 Sets Warehouse /w1*w%warehouse% /
35  Store /s1*s%store% /
36 Alias (Warehouse,w), (Store,s);
37 Scalar
38  fixed fixed cost for opening a warehouse / %fixed% /
39 Parameter
40  capacity(WareHouse)
41  supplyCost(Store,Warehouse);
42 
43 $eval storeDIVwarehouse trunc(card(store)/card(warehouse))
44 capacity(w) = %storeDIVwarehouse% + mod(ord(w),%storeDIVwarehouse%);
45 supplyCost(s,w) = 1+mod(ord(s)+10*ord(w), 100);
46 
47 Variables
48  open(Warehouse)
49  supply(Store,Warehouse)
50  obj;
51 Binary variables open, supply;
52 
53 Equations
54  defobj
55  oneWarehouse(s)
56  defopen(w);
57 
58 defobj.. obj =e= sum(w, fixed*open(w)) + sum((w,s), supplyCost(s,w)*supply(s,w));
59 
60 oneWarehouse(s).. sum(w, supply(s,w)) =e= 1;
61 
62 defopen(w).. sum(s, supply(s,w)) =l= open(w)*capacity(w);
63 
64 $ifthen %disaggregate%==1
65 Equations
66  defopen2(s,w);
67 defopen2(s,w).. supply(s,w) =l= open(w);
68 $endif
69 
70 model distrib /all/;
71 solve distrib min obj using mip;
72 
73 $macro setResult(n) option clear=ares; ares(n) = yes;
74 if (distrib.modelstat=%ModelStat.LicensingProblem% or
75  distrib.solvestat=%Solvestat.LicensingProblems%,
76  setResult('1');
77  abort 'License Error';
78 );
79 if (distrib.solvestat<>%SolveStat.NormalCompletion% or
80  distrib.modelstat<>%ModelStat.Optimal% and
81  distrib.modelstat<>%ModelStat.IntegerSolution%,
82  setResult('2');
83  abort 'No solution';
84 );
85 setResult('0'); '''
86 
87 def solve_warehouse(workspace, number_of_warehouses, result, db_lock):
88  global status
89  global status_string
90  try:
91  # instantiate GAMSOptions and define some scalars
92  opt = workspace.add_options()
93  opt.all_model_types = "cplex"
94  opt.defines["Warehouse"] = str(number_of_warehouses)
95  opt.defines["Store"] = "65"
96  opt.defines["fixed"] = "22"
97  opt.defines["disaggregate"] = "0"
98  opt.optcr = 0.0 # Solve to optimality
99 
100  # create a GAMSJob from string and write results to the result database
101  job = workspace.add_job_from_string(get_model_text())
102  job.run(opt)
103 
104  # need to lock database write operations
105  db_lock.acquire()
106  result["objrep"].add_record(str(number_of_warehouses)).value = job.out_db["obj"][()].level
107  db_lock.release()
108  for supply_rec in job.out_db["supply"]:
109  if supply_rec.level > 0.5:
110  db_lock.acquire()
111  result["supplyMap"].add_record((str(number_of_warehouses), supply_rec.key(0), supply_rec.key(1)))
112  db_lock.release()
113  except GamsExceptionExecution as e:
114  # Check if we see a User triggered abort and look for the user defined result
115  if e.rc == GamsExitCode.ExecutionError:
116  db_lock.acquire()
117  status_string = job.out_db["res"]
118  status_string = status_string.find_record(job.out_db["ares"].first_record().key(0)).text
119  db_lock.release()
120  db_lock.acquire()
121  status = e.rc
122  db_lock.release()
123  except GamsException as e:
124  print(e)
125  db_lock.acquire()
126  status = -1
127  db_lock.release()
128  except Exception as e:
129  print(e)
130  db_lock.acquire()
131  status = -2
132  db_lock.release()
133 
134 if __name__ == "__main__":
135  if len(sys.argv) > 1:
136  ws = GamsWorkspace(system_directory = sys.argv[1])
137  else:
138  ws = GamsWorkspace()
139 
140  # create a GAMSDatabase for the results
141  result_db = ws.add_database()
142  result_db.add_parameter("objrep" ,1 ,"Objective value")
143  result_db.add_set("supplyMap" ,3 ,"Supply connection with level")
144 
145  status_string = ""
146  status = 0
147 
148  try:
149  # run multiple parallel jobs
150  db_lock = threading.Lock()
151  threads = {}
152  for i in range(10,22):
153  threads[i] = threading.Thread(target=solve_warehouse, args=(ws, i, result_db, db_lock))
154  threads[i].start()
155  for t in threads.values():
156  t.join()
157  if status > 0:
158  raise GamsExceptionExecution("Error when running GAMS: " + str(status) + " " + status_string, status);
159  elif status == -1:
160  raise GamsException("Error in GAMS API")
161  elif status == -2:
162  raise Exception()
163 
164  # export the result database to a GDX file
165  result_db.export("/tmp/result.gdx")
166 
167  except GamsException as e:
168  print("GamsException occured: " , e)
169  except Exception as e:
170  print(e)
171 
172 
173 
174 
def get_model_text()
Definition: warehouse.py:16