Loading...
Searching...
No Matches
transport12.py
Go to the documentation of this file.
6
7import sys
8from gams import (
9 GamsWorkspace,
10 GamsModifier,
11 GamsEquation,
12 GamsVariable,
13 GamsException,
14 UpdateAction,
15 VarType,
16 SymbolUpdateType,
17)
18
19GAMS_MODEL = """
20Set
21 i 'canning plants' / seattle, san-diego /
22 j 'markets' / new-york, chicago, topeka /;
23
24Parameter
25 a(i) 'capacity of plant i in cases'
26 / seattle 350
27 san-diego 600 /
28
29 b(j) 'demand at market j in cases'
30 / new-york 325
31 chicago 300
32 topeka 275 /;
33
34Table d(i,j) 'distance in thousands of miles'
35 new-york chicago topeka
36 seattle 2.5 1.7 1.8
37 san-diego 2.5 1.8 1.4;
38
39Scalar
40 f 'freight in dollars per case per thousand miles' / 90 /
41 bmult 'demand multiplier' / 1 /;
42
43Parameter c(i,j) 'transport cost in thousands of dollars per case';
44c(i,j) = f*d(i,j)/1000;
45
46Variable
47 x(i,j) 'shipment quantities in cases'
48 z 'total transportation costs in thousands of dollars';
49
50Positive Variable x;
51
52Equations
53 cost 'define objective function'
54 supply(i) 'observe supply limit at plant i'
55 demand(j) 'satisfy demand at market j';
56
57cost.. z =e= sum((i,j), c(i,j)*x(i,j));
58
59supply(i).. sum(j, x(i,j)) =l= a(i);
60
61demand(j).. sum(i, x(i,j)) =g= bmult*b(j);
62
63Model transport /all/;
64"""
65
66
67# needs to be called with an uninstantiated GamsModelInstance
68def guss_call(scenario_dict, mi, solve_statement, opt=None, mi_opt=None, output=None):
69 if scenario_dict.dimension != 3:
70 raise GamsException("Scenario dictionary needs to be 3-dimensional")
71
72 scen_name = scenario_dict.first_record((" ", "scenario", " ")).key(0)
73 scen_symbol = scenario_dict.database[scen_name]
74 modifier_list = []
75 for rec in scenario_dict:
76 if rec.key(1).lower() == "scenario":
77 continue
78 if rec.key(1).lower() == "param":
79 modifier_dim = (
80 scenario_dict.database[rec.key(2)].dimension - scen_symbol.dimension
81 )
82 if modifier_dim < 0:
83 raise GamsException("Dimension of " + rec.key(2) + " too small")
84 modifier_list.append(
85 (
86 GamsModifier(
87 mi.sync_db.add_parameter(rec.key(0), modifier_dim, "")
88 ),
89 scenario_dict.database[rec.key(2)],
90 )
91 )
92 elif rec.key(1).lower() in ["lower", "upper", "fixed"]:
93 modifier_dim = (
94 scenario_dict.database[rec.key(2)].dimension - scen_symbol.dimension
95 )
96 if modifier_dim < 0:
97 raise GamsException("Dimension of " + rec.key(2) + " too small")
98 modifier_var = None
99 try:
100 modifier_var = scenario_dict.database[rec.key(0)]
101 except:
102 modifier_var = mi.sync_db.add_variable(
103 rec.key(0), modifier_dim, VarType.Free, ""
104 )
105 if rec.key(1).lower() == "lower":
106 update_action = UpdateAction.Lower
107 elif rec.key(1).lower() == "upper":
108 update_action = UpdateAction.Upper
109 else: # fixed
110 update_action = UpdateAction.Fixed
111 modifier_list.append(
112 (
113 GamsModifier(
114 modifier_var,
115 update_action,
116 mi.sync_db.add_parameter(rec.key(2), modifier_dim, ""),
117 ),
118 scenario_dict.database[rec.key(2)],
119 )
120 )
121 elif rec.key(1).lower() in ["level", "marginal"]:
122 # check that parameter exists in GamsDatabase, will throw an exception if not
123 scenario_dict.database[rec.key(2)]
124 else:
125 raise GamsException("Cannot handle UpdateAction " + rec.key(1))
126
127 ml = [m[0] for m in modifier_list]
128 mi.instantiate(solve_statement, ml, opt)
129 out_list = []
130 for s in scen_symbol:
131 for m, p_scen in modifier_list:
132 p = m.gams_symbol if m.data_symbol is None else m.data_symbol
133 p.clear() # implemented SymbolUpdateType=BaseCase
134
135 rec = None
136 filter = [""] * p_scen.dimension
137 for i in range(scen_symbol.dimension):
138 filter[i] = s.key(i)
139 for i in range(scen_symbol.dimension, p_scen.dimension):
140 filter[i] = " "
141 try:
142 rec = p_scen.first_record(filter)
143 except:
144 continue
145
146 while True:
147 my_keys = [
148 rec.key(scen_symbol.dimension + i) for i in range(p.dimension)
149 ]
150 p.add_record(my_keys).value = rec.value
151 if not rec.move_next():
152 break
153
154 mi.solve(SymbolUpdateType.BaseCase, output, mi_opt)
155 if not out_list:
156 for rec in scenario_dict:
157 if rec.key(1).lower() in ["level", "marginal"]:
158 out_list.append(
159 (
160 mi.sync_db[rec.key(0)],
161 scenario_dict.database[rec.key(2)],
162 rec.key(1).lower(),
163 )
164 )
165
166 for tup in out_list:
167 my_keys = [""] * (scen_symbol.dimension + len(tup[0].first_record().keys))
168 for i in range(scen_symbol.dimension):
169 my_keys[i] = s.key(i)
170
171 if isinstance(tup[0], (GamsVariable, GamsEquation)):
172 if tup[2] in ["level", "marginal"]:
173 for rec in tup[0]:
174 for i in range(len(rec.keys)):
175 my_keys[scen_symbol.dimension + i] = s.key(i)
176 tup[1].add_record(my_keys).value = (
177 rec.level if tup[2] == "level" else rec.marginal
178 )
179
180
181if __name__ == "__main__":
182 sys_dir = sys.argv[1] if len(sys.argv) > 1 else None
183 ws = GamsWorkspace(system_directory=sys_dir)
184
185 cp = ws.add_checkpoint()
186
187 # initialize a GamsCheckpoint by running a GamsJob
188 job = ws.add_job_from_string(GAMS_MODEL)
189 job.run(checkpoint=cp)
190
191 # create a GamsModelInstance and solve it multiple times with different scalar bmult
192 mi = cp.add_modelinstance()
193 bmult_list = [0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3]
194 db = ws.add_database()
195 scen = db.add_set("scen", 1, "")
196 bmult = db.add_parameter_dc("bmultlist", [scen])
197 zscen = db.add_parameter_dc("zscen", [scen])
198
199 for i, b in enumerate(bmult_list):
200 bmult.add_record(f"s{i}").value = b
201 scen.add_record(f"s{i}")
202
203 scenario_dict = db.add_set("scenario_dict", 3, "")
204 scenario_dict.add_record((scen.name, "scenario", ""))
205 scenario_dict.add_record(("bmult", "param", bmult.name))
206 scenario_dict.add_record(("z", "level", zscen.name))
207
208 guss_call(scenario_dict, mi, "transport use lp min z")
209
210 for rec in db[zscen.name]:
211 print(f"{rec.key(0)} obj: {rec.value}")
212
213 mi2 = cp.add_modelinstance()
214 db2 = ws.add_database()
215
216 scen2 = db2.add_set("scen", 1, "")
217 zscen2 = db2.add_parameter_dc("zscen", [scen2])
218 xup = db2.add_parameter("xup", 3, "")
219
220 for j in range(4):
221 for rec_i in job.out_db["i"]:
222 for rec_j in job.out_db["j"]:
223 xup.add_record((f"s{j}", rec_i.key(0), rec_j.key(0))).value = j + 1
224 scen2.add_record(f"s{j}")
225
226 scenario_dict2 = db2.add_set("scenario_dict", 3, "")
227 scenario_dict2.add_record((scen2.name, "scenario", ""))
228 scenario_dict2.add_record(("x", "lower", xup.name))
229 scenario_dict2.add_record(("z", "level", zscen2.name))
230
231 guss_call(scenario_dict2, mi2, "transport use lp min z", output=sys.stdout)
232
233 for rec in db2[zscen2.name]:
234 print(f"{rec.key(0)} obj: {rec.value}")
def guss_call(scenario_dict, mi, solve_statement, opt=None, mi_opt=None, output=None)
Definition: transport12.py:68