Loading...
Searching...
No Matches
transport12.m
1function transport12(varargin)
2
3 % check workspace info from arguments
4 if nargin > 0
5 wsInfo = gams.control.WorkspaceInfo();
6 wsInfo.systemDirectory = varargin{1};
7 ws = gams.control.Workspace(wsInfo);
8 else
9 ws = gams.control.Workspace();
10 end
11
12 model = {
13 'Sets '
14 ' i canning plants / seattle, san-diego / '
15 ' j markets / new-york, chicago, topeka / ; '
16 ' '
17 'Parameters '
18 ' '
19 ' a(i) capacity of plant i in cases '
20 ' / seattle 350 '
21 ' san-diego 600 / '
22 ' '
23 ' b(j) demand at market j in cases '
24 ' / new-york 325 '
25 ' chicago 300 '
26 ' topeka 275 / ; '
27 ' '
28 'Table d(i,j) distance in thousands of miles '
29 ' new-york chicago topeka '
30 ' seattle 2.5 1.7 1.8 '
31 ' san-diego 2.5 1.8 1.4 ; '
32 ' '
33 'Scalar f freight in dollars per case per thousand miles /90/ ;'
34 'Scalar bmult demand multiplier /1/; '
35 ' '
36 'Parameter c(i,j) transport cost in thousands of dollars per case ; '
37 ' '
38 ' c(i,j) = f * d(i,j) / 1000 ; '
39 ' '
40 'Variables '
41 ' x(i,j) shipment quantities in cases '
42 ' z total transportation costs in thousands of dollars ; '
43 ' '
44 'Positive Variable x ; '
45 ' '
46 'Equations '
47 ' cost define objective function '
48 ' supply(i) observe supply limit at plant i '
49 ' demand(j) satisfy demand at market j ; '
50 ' '
51 'cost .. z =e= sum((i,j), c(i,j)*x(i,j)) ; '
52 ' '
53 'supply(i) .. sum(j, x(i,j)) =l= a(i) ; '
54 ' '
55 'demand(j) .. sum(i, x(i,j)) =g= bmult*b(j) ; '
56 ' '
57 'Model transport /all/ ; '
58 ' '};
59 model = sprintf('%s\n', model{:});
60
61 % initialize a checkpont by running a job
62 cp = ws.addCheckpoint();
63 t12 = ws.addJobFromString(model);
64 t12.run(cp);
65
66 bmultlist = [0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3];
67
68 % create a ModelInstance and solve it multiple times with different scalar bmult
69 mi = cp.addModelInstance();
70 db1 = ws.addDatabase();
71 scen1 = db1.addSet('scen', 1, '');
72 bmult = db1.addParameter('bmultlist', '', scen1);
73 zscen1 = db1.addParameter('zscen', '', scen1);
74
75 for i = 1:numel(bmultlist)
76 rec = bmult.addRecord(sprintf('s%d', i));
77 rec.value = bmultlist(i);
78 scen1.addRecord(sprintf('s%d', i));
79 end
80
81 dict = db1.addSet('dict', 3, '');
82 dict.addRecord(scen1.name, 'scenario', '');
83 dict.addRecord('bmult', 'param', bmult.name);
84 dict.addRecord('z', 'level', zscen1.name);
85
86 GUSSCall(dict, mi, 'transport use lp min z', [], [], []);
87
88 for rec = db1.getParameter(zscen1.name).records;
89 fprintf('%s obj: %g\n', rec{1}.key(1), rec{1}.value);
90 end
91
92 mi2 = cp.addModelInstance();
93 db2 = ws.addDatabase();
94 scen2 = db2.addSet('scen', 1, '');
95 zscen2 = db2.addParameter('zscen', '', scen2);
96 xup = db2.addParameter('xup', 3, '');
97
98 for k = 1:4
99 for i = t12.outDB.getSet('i').records
100 for j = t12.outDB.getSet('j').records
101 rec = xup.addRecord(sprintf('s%d', k), i{1}.key(1), j{1}.key(1));
102 rec.value = k;
103 end
104 end
105 scen2.addRecord(sprintf('s%d', k));
106 end
107
108 dict2 = db2.addSet('dict', 3, '');
109 dict2.addRecord({scen2.name, 'scenario', ''});
110 dict2.addRecord({'x', 'lower', xup.name});
111 dict2.addRecord({'z', 'level', zscen2.name});
112
113 GUSSCall(dict2, mi2, 'transport use lp min z', [], [], gams.control.PrintStream());
114
115 for rec = db2.getParameter(zscen2.name).records;
116 fprintf('%s obj: %g\n', rec{1}.key(1), rec{1}.value);
117 end
118end
119
120function GUSSCall(dict, mi, solveStatement, opt, miOpt, output)
121
122 modifierList = {};
123 if (dict.dimension ~= 3)
124 error('Dict needs to be 3-dimensional');
125 end
126
127 scenName = dict.getFirstRecord(' ', 'scenario', ' ').key(1);
128 scenSymbol = dict.database.getSet(scenName);
129
130 for rec = dict.records
131 keys = rec{1}.keys;
132 key1 = lower(keys{2});
133 if strcmp(key1, 'scenario')
134 continue;
135 end
136
137 switch key1
138 case {'param', 'lower', 'upper', 'fixed'}
139 modifierDim = dict.database.getParameter(keys{3}).dimension - scenSymbol.dimension;
140 if modifierDim < 0
141 error('Dimension of %s too small', keys{3});
142 end
143 case {'level', 'marginal'}
144 otherwise
145 error('Cannot handle UpdateAction %s', keys{2});
146 end
147
148 switch key1
149 case {'lower', 'upper', 'fixed'}
150 try
151 modifierVar = dict.database.getVariable(keys{1});
152 catch
153 modifierVar = mi.syncDB.addVariable(keys{1}, modifierDim, gams.control.globals.VarType.FREE, '');
154 end
155 case {'level', 'marginal'}
156 % Check that parameter exists in Database, will throw an exception if not
157 dict.database.getParameter(keys{3});
158 end
159
160 switch key1
161 case 'param'
162 mod = gams.control.Modifier(mi.syncDB.addParameter(keys{1}, modifierDim, ''));
163 case 'lower'
164 mod = gams.control.Modifier(modifierVar, gams.control.globals.UpdateAction.LOWER, ...
165 mi.syncDB.addParameter(keys{3}, modifierDim, ''));
166 case 'upper'
167 mod = gams.control.Modifier(modifierVar, gams.control.globals.UpdateAction.UPPER, ...
168 mi.syncDB.addParameter(keys{3}, modifierDim, ''));
169 case 'fixed'
170 mod = gams.control.Modifier(modifierVar, gams.control.globals.UpdateAction.FIXED, ...
171 mi.syncDB.addParameter(keys{3}, modifierDim, ''));
172 end
173
174 switch key1
175 case {'param', 'lower', 'upper', 'fixed'}
176 param = dict.database.getParameter(keys{3});
177 modifierList{end+1} = {mod, param};
178 end
179 end
180
181 mods = {};
182 for i = 1:numel(modifierList)
183 if isa(modifierList{i}{1}, 'gams.control.Modifier')
184 mods{end+1} = modifierList{i}{1};
185 end
186 end
187
188 if isempty(opt)
189 mi.instantiate(solveStatement, mods);
190 else
191 mi.instantiate(solveStatement, opt, mods);
192 end
193
194 outList = {};
195
196 for s = scenSymbol.records
197 for i = 1:numel(modifierList)
198 m = modifierList{i}{1};
199 pscen = modifierList{i}{2};
200
201 p = m.dataSymbol;
202 if isempty(p)
203 p = m.gamsSymbol;
204 end
205 p.clear();
206
207 filter = cell(1, pscen.dimension);
208 for i = 1:scenSymbol.dimension
209 filter{i} = s{1}.key(i);
210 end
211 for i = scenSymbol.dimension+1:pscen.dimension
212 filter{i} = ' ';
213 end
214
215 try
216 rec = pscen.getFirstRecord(filter);
217 catch
218 continue;
219 end
220
221 while true
222 myKeys = cell(1, p.dimension);
223 for i = 1:p.dimension
224 myKeys{i} = rec.key(scenSymbol.dimension+i);
225 end
226 r = p.addRecord(myKeys);
227 r.value = rec.value;
228 if ~rec.moveNext()
229 break;
230 end
231 end
232 end
233
234 if isempty(output) && isempty(miOpt)
235 mi.solve(gams.control.globals.SymbolUpdateType.BASECASE);
236 elseif isempty(miOpt)
237 mi.solve(gams.control.globals.SymbolUpdateType.BASECASE, output);
238 else
239 mi.solve(gams.control.globals.SymbolUpdateType.BASECASE, output, miOpt);
240 end
241 if numel(outList) == 0
242 for rec = dict.records
243 key = lower(rec{1}.key(2));
244
245 switch key
246 case {'level', 'marginal'}
247 sym = mi.syncDB.getSymbol(rec{1}.key(1));
248 param = dict.database.getParameter(rec{1}.key(3));
249 str = lower(rec{1}.key(2));
250 outList{end+1} = {sym, param, str};
251 end
252 end
253 end
254
255 for i = 1:numel(outList)
256 symbol = outList{i}{1};
257 param = outList{i}{2};
258 str = outList{i}{3};
259 myKeys = cell(1, scenSymbol.dimension + numel(symbol.getFirstRecord().keys));
260 for j = 1:scenSymbol.dimension
261 myKeys{j} = s{1}.key(j);
262 end
263
264 if strcmp(str, 'level') && (isa(symbol, 'gams.control.Variable') || isa(symbol, 'gams.control.Equation'))
265 for rec = symbol.records
266 for j = 1:numel(rec{1}.keys)
267 myKeys(scenSymbol.dimension + j) = s{1}.key(j);
268 end
269 r = param.addRecord(myKeys);
270 r.value = rec{1}.level;
271 end
272 elseif strcmp(str, 'marginal') && (isa(symbol, 'gams.control.Variable') || isa(symbol, 'gams.control.Equation'))
273 for rec = symbol.records
274 for j = 1:numel(rec{1}.keys)
275 myKeys(scenSymbol.dimension + j) = s{1}.key(j);
276 end
277 r = param.addRecord(myKeys);
278 r.value = rec{1}.marginal;
279 end
280 end
281 end
282 end
283end