When utilizing multiple solve statements (e.g. in a loop) the amount of memory used by GAMS may increase even though the indiviual model size (for the particular solve statement) remains the same. This is due to storage of parameters and variables grows, even though they are not necessarily used for each solve statement.
In some case there are ways to keep the amount of memory pretty constant. They include:
option solveopt=replace
which replaces rather than merges all solution values of each GAMS solve.option clear=param
to clean temporary data which is not used afterwards.file fput /rep.txt/; put fput (data);
The first two options are simple, the third one might be inconvenient (especially if you want to do post solution analysis) whereas the option to aggregate the LPs into fewer but bigger models can be quite difficult. This option generally is only useful if each sub-model to solve is not dependent on the solution of the previous model. Although there may be instances where the addition of a couple of more constraints can accomplish this, it is not always possible.
We shall give examples using the transportation model (trnsport.gms) where we have introduced a time series component.
Set t time / t1*t10 / tt(t) dynamic version of t; Parameter c(i,j) transport cost in thousands of dollars per case at(i,t), bt(j,t), ct(i,j,t) "supply, demand, cost by time"; c(i,j) = f * d(i,j) / 1000 ; Variables x(i,j,t) shipment quantities in cases Equations cost define objective function supply(i,t) observe supply limit at plant i demand(j,t) satisfy demand at market j ; cost .. z =e= sum((i,j,tt), ct(i,j,tt)*x(i,j,tt)) ; supply(i,tt) .. sum(j, x(i,j,tt)) =l= at(i,tt) ; demand(j,tt) .. sum(i, x(i,j,tt)) =g= bt(j,tt) ; loop(t, tt(t) = yes; ct(i,j,tt(t)) = c(i,j) * ( 1 + 0.25**ord(t)); at(i,tt(t)) = a(i) * (1 + 0.15**ord(t)); bt(j,tt(t)) = b(j) * (1 + 0.15**ord(t)); Solve transport using lp minimizing z ; tt(t) = no; );
option solveopt=replace;
before the loop(t,
statement.ct
, at
, and bt
, since they are only used for the local solve. After tt(t) = yes;
we specify option clear=ct, clear=at, clear=bt;
frep.put
before the loop by: file frep
. After the solve statement, we write to the put file by:put frep / t.tl 'modstat' transport.modelstat / t.tl 'slvstat' transport.solvestat / t.tl 'obj ' z.l;
Equations defobj cost(t) define objective function supply(i,t) observe supply limit at plant i demand(j,t) satisfy demand at market j ; defobj .. obj =e= sum(tt, z(tt)); cost(tt) .. z(tt) =e= sum((i,j), ct(i,j,tt)*x(i,j,tt)) ; scalar idx /0/, bsize /5/; repeat tt(t) = no; * Batch 5 single LPs into one larger model: loop(t$(ord(t)>(idx*bsize) and ((idx+1)*bsize)>=ord(t)), tt(t) = yes); ct(i,j,tt(t)) = c(i,j) * ( 1 + 0.25**ord(t)); at(i,tt(t)) = a(i) * (1 + 0.15**ord(t)); bt(j,tt(t)) = b(j) * (1 + 0.15**ord(t)); if (card(tt), Solve transport using lp minimizing obj); idx = idx + 1; until card(tt)=0;
The implementation of all four options using the same equations as above is:
File frep; Option solveopt=replace; repeat tt(t) = no; loop(t$(ord(t)>(idx*bsize) and ((idx+1)*bsize)>=ord(t)), tt(t) = yes); option clear=ct, clear=at, clear=bt; ct(i,j,tt(t)) = c(i,j) * ( 1 + 0.25**ord(t)); at(i,tt(t)) = a(i) * (1 + 0.15**ord(t)); bt(j,tt(t)) = b(j) * (1 + 0.15**ord(t)); if (card(tt), Solve transport using lp minimizing obj); loop(tt(t), put frep / t.tl 'modstat' transport.modelstat / t.tl 'slvstat' transport.solvestat / t.tl 'obj ' z.l(t); ); idx = idx + 1; until card(tt)=0;