A scalar drives the length of a set

Frequently asked questions about GAMS

Moderator: aileen

Forum rules
Please ask questions in the other sub-forums
Locked
aileen
User
User
Posts: 136
Joined: 4 years ago

A scalar drives the length of a set

Post by aileen »

I need my set to be able to change depending on the value of a scalar, e.g:

Code: Select all

scalar dim /10/; set myset /1*dim/;
aileen
User
User
Posts: 136
Joined: 4 years ago

Re: A scalar drives the length of a set

Post by aileen »

Before going into the details please note that set elements are not numbers - even if you choose labels that look like numbers. In fact, our recommendation is to avoid using set elements that look like numbers since it can cause confusion in different circumstances. If you write

Code: Select all

set t /t1 * t5/;
set i /i1 * i5/;
you won't get the two confused. If you write

Code: Select all

set i /5 * 9/;
set j /3 * 8/;
you'll be surprised to find that the order of elements in set j is 5, 6, 7, 8, 3, 4. That's because the ordering comes from the collection of all unique set elements in a GAMS program - and the order is defined by when they appear. The only advantage of labels that look like numbers is that you can use the .val suffix.

But now back to the original question. In general GAMS prefers to do this the other way around:

Code: Select all

set myset /i1*i10/;
scalar dim;
dim = card(myset);
In the GAMS philosophy sets drive the model. Creating sets based on data (e.g. scalars) requires the use of dynamic sets, which are a little bit more difficult to use than static sets. Moreover, you need to have an estimate of how big your scalar will maximal ever be. Here is a fragment that illustrates how you can use dynamic sets:

Code: Select all

set univ the universe /i1*i1000/;
scalar dim /6/;
set myset(univ);

myset(univ)$(ord(univ) <= dim) = yes;

display myset; 

* declare equations, variables and parameters over the universe set
* but use them over myset
parameter p(univ);
p(myset) = 1;
You can also pass compile time information through the command line: gams x.gms –dim=5 with x.gms.

Code: Select all

$if not set dim $set dim 5

set myset / i1*i%dim%/
In addition, if the value of the scalar is known at compile time (e.g. due to a data statement) you can use $eval to build a corresponding set:

Code: Select all

scalar dim /10/; 
$eval DIM dim
set myset /i1*i%DIM%/;
Locked