Wednesday, May 6, 2009

loop madness

Hi Dear all,

I am new to GAMS and I am working on a MILP. I had been my code in AMPL.

Because of my solution capacity for the n > 8 had was too large, and I have a student version of AMPL then I want to change it in the GAMS representation.

I have two loop using FOR in my code, as:

for{i in 1..N} {
   for{j in 1..N} {
      for{p in 1..N} {
         let a[i,j,p,i,j,p] := f[j,j] * d [ i,i] * f[p,p] * d[i,i] ;
         for{k in 1..N} {
            if(k <> i) then
              for{n in 1..N} {
                 if(n <> j) then
                   for{q in 1..N} {
                      if(q <> p) then
                        let a[i,j,p,k,n,q]:= f[j,n] * d[i,k] * f[p,q] * d[i,k];
                      }
                 }
            }
         }
      }
   };

In the loop, f and d are two-dimensional matrix and i,j,p,k,n,q mention to elements of the matrices and N is a scalar as follow.

I have written the same loop in GAMS as:

* ----------------------------------------------

sets  i   /1*5/,
      j   /1*5/,
      p   /1*5/,
      k   /1*5/,
      n   /1*5/,
      q   /1*5/ ;

scalar M size of problem /5/;

parameter   c(i,j,p,k,n,q);

Scalar N /5/ ;

* ----------------------------------------------
Table  f(i,i)
         1    2    3    4    5
    1         1    1    2    3
    2    1         2    1    2
    3    1    2         1    2
    4    2    1    1         1
    5    3    2    2    1       ;

* ------------------------------------------------------
Table  d(k,k)
         1    2    3    4    5
    1         5    2    4    1
    2    5         3         2
    3    2    3
    4    4                   5
    5    1    2         5       ;

* ------------------------------------------------------

for(i=1 to M,
    for(j=1 to M,
       for(p=1 to M,
           a(i,j,p,i,j,p) = f(j,j) * d(i,i) * f(p,p) * d(i,i) ;
           for(k=1 to M,
              if(k ne i,
                for(n=1 to M,
                   if(n ne j,
                     for(q=1 to M,
                        if(q ne p,
                           a(i,j,p,k,n,q) = f(j,n) * d(i,k) * f(p,q) * d(i,k) ;
                          );
                        );
                     );
                   );
                );
              );
          );
       );
   );

* ----------------------------------------------

But there is an error regard to FOR. I know that it should be a scalar instead of i,j,p,k,n,q. but then who can I define the matrices?

Thanks in advance

This does not make much sense. Wow, this is very ugly and convoluted GAMS. At least from a syntactical point of view better would be:

* ----------------------------------------------
sets  i   /1*5/;
alias(i,j,p,k,n,q);

* ----------------------------------------------
Table  f(i,i)
         1    2    3    4    5
    1         1    1    2    3
    2    1         2    1    2
    3    1    2         1    2
    4    2    1    1         1
    5    3    2    2    1       ;
* ------------------------------------------------------
Table  d(k,k)
         1    2    3    4    5
    1         5    2    4    1
    2    5         3         2
    3    2    3
    4    4                   5
    5    1    2         5       ;
* ------------------------------------------------------

parameter a(i,j,p,k,n,q);
a(i,j,p,k,n,q) = f(j,n) * f(p,q) * sqr(d(i,k));

When you use GAMS in most cases you don’t need explicit loops: an assignment is an implicit loop. Also there is no advantage to split this into two assignments as suggested by the poster. Essentially he does:

a(i,j,p,i,j,p) = f(j,j) * f(p,p) * sqr(d(i,i));
a(i,j,p,k,n,q)$(ord(k)<>ord(i) and ord(n)<>ord(j) and ord(q)<>ord(p)) = f(j,n) * f(p,q) * sqr(d(i,k));

These two statements have the same effect as the single statement shown before.

There seems to be a big misunderstanding here how to write GAMS and actually how to write loops (the splitting of the assignment is an indication of that).