User Tools

Site Tools


gams:reverse_loops_in_gams

Reverse loops in GAMS

Q: Is it possible in a LOOP statement of GAMS to execute BACKWARD RECURSIVE statements, i.e. to traverse the members of the driving set of the loop in the reverse order?

There is no syntax designed especially for this, so you will want to avoid doing this if possible. If you must use a reverse loop, here is an example of how one can set this up.

set i / 1 * 10 /;
alias (i,ri);
set revi(i,ri);
* The idea is to populate the sw-ne diagonal of revi.
* Then looping through i in forward order gives us
* i in reverse order by taking the second index of revi.
* The follwing assignment would create revi, but it is very slow, o(n^2)!
* revi(i,ri)$(ord(i) + ord(ri) eq card(i)+1) = yes;
*
* This formulation is much faster, o(n).
revi(i,i+[card(i)-2*ord(i)+1]) = yes;

parameter c(i);
c(i) = uniform(0,1);
file fp / reverse.out /;
put fp;
loop (revi(i,ri),
      put ri.tl, c(ri)/;
     );
put /;

The put file shows:

10                  0.50
9                   0.07
8                   0.86
7                   0.35
6                   0.22
5                   0.29
4                   0.30
3                   0.55
2                   0.84
1                   0.17

Just a note on efficiency: The loop over revi goes very fast, since we are taking the first index, i, in order, and each row of revi has only one element. However, accessing c(ri) in reverse order is not so efficient, and may be a problem for very large i. To see this work, increase the dimension of set i, run the model using profiling and analyze what happens if you replace the “slow”

put ri.tl, c(ri)/;

by

put i.tl, c(i)/;

.

IMPRESSUM / LEGAL NOTICEPRIVACY POLICY gams/reverse_loops_in_gams.txt · Last modified: 2020/05/20 11:44 by Frederik Fiand