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 definethe 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);* ----------------------------------------------

parameter a(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 ;

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

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).

I totally with u Erwin, could you give us some hints and tricks about efficient GAMS coding practice ? thanks

ReplyDeleteThere are a number of posts in this blog that discuss performance related modeling tricks w.r.t. GAMS. Some of them are more or less obvious (like this one), others require some more knowledge about how GAMS organizes and process sparse data. Sorry: I don't have a summary write-up available right now.

ReplyDelete