$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 ); $ifThen not set ETIME_LIMIT * jobTrace is used as an indicator that slvtest called this model $ if not "%gams.jobTrace%" $set ETIME_LIMIT 30 $ if "%gams.jobTrace%" $set ETIME_LIMIT INF $endIf scalar etimeLim 'time limit for collection loop' / %ETIME_LIMIT% /; * 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 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'; until card(h) = 0 or timeelapsed > etimeLim; // wait until all models are loaded or time limit reached abort.noError$[card(h)>0] 'Time limit hit in collection loop', etimeLim, h; Set xcollected(s); option xcollected < resultantx; abort$(card(xcollected) <> card(ScenariosToRun)) 'not all scenarios collected', xcollected, resultantx;