Description
GUSS is a procedure that facilitates optimization of a collection of related problems modifying data in those problems. Up to 24.3 GUSS could not be combined with the GAMS Grid Facility. The GAMS Grid Facility allows to easily split the scenarios set into multiple sets (e.g. number of CPUs/cores on the executing machine) to utilize the parallel machine power.
Small Model of Type : LP
Category : GAMS Model library
Main file : gussgrid.gms
$title Simple GUSS Grid Example (GUSSGRID,SEQ=400)
$onText
GUSS is a procedure that facilitates optimization of a collection of related
problems modifying data in those problems. Up to 24.3 GUSS could not be combined
with the GAMS Grid Facility. The GAMS Grid Facility allows to easily split the
scenarios set into multiple sets (e.g. number of CPUs/cores on the executing
machine) to utilize the parallel machine power.
Bussieck, M R, Ferris, M C, and Lohmann, T, GUSS: Solving Collections of Data
Related Models within GAMS. In Kallrath, J, Ed, Algebraic Modeling Systems:
Modeling and Solving Real World Optimization Problems. Springer, Berlin
Heidelberg, 2012, pp. 35-56.
Keywords: linear programming, transportation problem, scheduling, GUSS, scenario
analysis, grid facility
$offText
Set
i 'canning plants' / seattle, san-diego /
j 'markets' / new-york, chicago, topeka /;
Parameter
a(i) 'capacity of plant i in cases'
/ seattle 350
san-diego 600 /
b(j) 'demand at market j in cases'
/ new-york 325
chicago 300
topeka 275 /;
Table d(i,j) 'distance in thousands of miles'
new-york chicago topeka
seattle 2.5 1.7 1.8
san-diego 2.5 1.4;
Scalar f 'freight in dollars per case per thousand miles' / 90 /;
Parameter c(i,j) 'transport cost in thousands of dollars per case';
c(i,j) = f*d(i,j)/1000;
Variable
x(i,j) 'shipment quantities in cases'
z 'total transportation costs in thousands of dollars';
Positive Variable x;
Equation
cost 'define objective function'
supply(i) 'observe supply limit at plant i'
demand(j) 'satisfy demand at market j';
cost.. z =e= sum((i,j), c(i,j)*x(i,j));
supply(i).. sum(j, x(i,j)) =l= a(i);
demand(j).. sum(i, x(i,j)) =g= b(j);
Model transport / all /;
$if not set whatrun $set whatrun 4_100
$goTo %whatrun%
$label 4_10000
Set
ScenariosToRun 'scenarios' / s1*s10000 /
cpu 'grid jobs to run' / cpu1*cpu4 /
scpu(cpu,ScenariosToRun) / cpu1.( s1* s2500)
cpu2.(s2501* s5000)
cpu3.(s5001* s7500)
cpu4.(s7501*s10000) /;
$goTo cont
$label 4_100
Set
ScenariosToRun 'scenarios' / s1*s100 /
cpu 'grid jobs to run' / cpu1*cpu4 /
scpu(cpu,ScenariosToRun) / cpu1.( s1* s25)
cpu2.(s26* s50)
cpu3.(s51* s75)
cpu4.(s76*s100) /;
$goTo cont
$label 1_10000
Set
ScenariosToRun 'scenarios' / s1*s10000 /
cpu 'grid jobs to run' / cpu1 /
scpu(cpu,ScenariosToRun) / cpu1.(s1*s10000) /;
$goTo cont
$label cont
Alias (ScenariosToRun,s);
Parameter
newsupply(s,*) 'updater for a'
newdemand(s,*) 'updater for b'
resultantx(s,i,j) 'collector for level of x';
newdemand(s,j) = normal(b(j),0.1);
newsupply(s,i) = normal(a(i),0.1);
* Make sure we don't go infeasible
newdemand(s,'total') = sum(j,newdemand(s,j));
newsupply(s,'total') = sum(i,newsupply(s,i));
newsupply(s,i)$(newdemand(s,'total') > newsupply(s,'total')) =
newsupply(s,i)*(newdemand(s,'total') + 1)/newsupply(s,'total');
* Clear Total otherwise we get unmatched records in GUSS
newdemand(s,'total') = 0;
newsupply(s,'total') = 0;
Set
gs(s) 'scenarios per GUSS run'
dict / gs. scenario.''
a. param .newsupply
b. param .newdemand
x. level .resultantx /;
Parameter h(cpu) 'grid handles';
transport.solveLink = %solveLink.asyncGrid%;
option limRow = 0, limCol = 0;
$eolCom //
loop(cpu,
gs(s) = scpu(cpu,s);
solve transport using lp minimizing z scenario dict;
h(cpu) = transport.handle; // save instance handle
);
* we use the handle parameter to indicate that the solution and the scenario
* results have been collected. By default (change with option solveopt) we do
* a merge of the solution and scenario results
scalar timedOut / 0 /;
repeat
loop(cpu$handlecollect(h(cpu)),
display$handledelete(h(cpu)) 'trouble deleting handles';
h(cpu) = 0; // indicate that we have loaded the solution
);
display$sleep(card(h)*0.2) 'was sleeping for some time';
timedOut = (timeelapsed > 30);
until card(h) = 0 or timedOut; // wait until all models are loaded or time limit reached
abort.noError$[timedOut] 'Time limit hit in collection loop';
Set xcollected(s);
option xcollected < resultantx;
abort$(card(xcollected) <> card(ScenariosToRun)) 'not all scenarios collected',
xcollected, resultantx;