User Tools

Site Tools


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
* this will work, but it is very slow, o(n^2)!
* revi(i,ri)$(ord(i) + ord(ri) eq n+1) = yes;
* this 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, 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 or 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 and run the model using profiling.

gams/reverse_loops_in_gams.txt · Last modified: 2007/03/20 08:21 (external edit)