I need my set to be able to change depending on the value of a scalar, e.g:
scalar dim /10/; set myset /1*dim/;
I need my set to be able to change depending on the value of a scalar, e.g:
scalar dim /10/; set myset /1*dim/;
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
set t /t1 * t5/;
set i /i1 * i5/;
you won’t get the two confused. If you write
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:
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:
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.
$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:
scalar dim /10/;
$eval DIM dim
set myset /i1*i%DIM%/;