set starting in 0

Hello!

I found this week an error which I had never found before …

When running these lines


set i machine /12/;
set j jobs /0
4/;
parameter oo(j);
oo(j) = ord(j);
display oo;


I get an error. However, if I swap the first two, there is no error:


set j jobs /04/;
set i machine /1
2/;
parameter oo(j);
oo(j) = ord(j);
display oo;


Any idea why this might be happening?

Thanks !

Fede

GAMS works with an internal unique element list, see https://www.gams.com/30/docs/UG_OrderedSets.html#UG_OrderedSets_OrderedAndUnorderedSets. So in the first example, this ordered list is 1,2,0,3,4 while in the second exampl it is 0,1,2,3,4. Because the set element order of j is not compatible with the order of unique element list, the set is not sorted and hence you cannot use operators like ord or lag (-) and leads (+). The best way to avoid this (also for other purposes) is using good labels:

set i machine /m1*m2/;
set j jobs /j0*j4/;
parameter oo(j);
oo(j) = ord(j);
display oo;

if you have to work with integers, make a dummy set at the beginning of your program (don’t make it too big since GAMS needs to store all the labels) that gets you your desired order:

set dummy 'good sort order for non-negative integers' /'-1000'*'-1',0*1000/;
set i machine /1*2/;
set j jobs /0*4/;
parameter oo(j);
oo(j) = ord(j);
display oo;

If the job position parameter oo does not need to to be in the natural order, but some order, you can use the pos suffix:

set i machine /1*2/;
set j jobs /0*4/;
parameter oo(j);
oo(j) = j.pos;
display oo;

You can also use the predefined set sorteduels that establishes a smart alphabetical order (non-negative integers are sorted according to their numeric value) of the uels and lets one iterate through elements in an alphabetic order, so you can assign a proper position:

set i machine /1*2/;
set j jobs /0*4/;
parameter oo(j);
alias (u,*); scalar cnt /1/;
loop(sorteduels(j,u), oo(j) = cnt; cnt=cnt+1);
display oo;

As in the previous “solution” this still does not give you access to lag and leads with the set j.

-Michael

Thanks! I guess then that the second code I put

set j jobs /04/;
set i machine /1
2/;

is correct because the unique element list is 0,1,2,3,4.

I really appreciate the explanation :slight_smile: