Dear GAMS World Forum Users,
for my bachelor thesis I am currently creating a mathematical model.
The model itself is already finished, but uses a lot of binary variables and auxiliary variables. This results in a very large computing time.
To reduce the computing time a little it was an idea to replace some binary variables with SOS1 variables with an upper bound of 1.
However said variable has 3 indexes:
s(i,l,w)
As soon as this variable is converted into a SOS1 variable, according to the documentation (i,l) sets with (w) elements are created. But for my model (i) sets with (l,w) elements would have to be defined.
I have already tried to merge the sets l and w in a new set b with the help of:
Set
l Explanation Text /1*3/
w Explanation Text /1*3/
b(l,w) Explanation Text /#l.#w/;
SOS1 Variable
s(i,b) Explanation Text;
However this definition of the Variable “s” results in an Error Message telling me the Set b is not wanted in declaration.
*** Error 122
One dimensional Set expected
Is there a possibility to declare the variable “s(i,l,w)” as SOS1 Variable so that there are (i) Sets with (l,w) Elements?
Thank you very much.
Best Regards,
Pinguin_Fan
Hi,
you would need some dummy set that reperesents a pair (l,w), e.g.
*introduce new set lw with card(lw)=card(l)*card(w) and map set elements of lw with pairs of (l,w)
$eval cardLW card(l)*card(w)
set lw / lw_1*lw_%cardLW% /
lw_map(l,w,lw) / (#l.#w):#lw /;
*display lw and lw_map (in list format)
option lw_map:0:0:1; display lw, lw_map;
*declare sos1 variable (i special ordered sets with card(lw) elements
sos1 variable s(i,lw);
*[...]
*if you have some symbols that shold use (l,w) instead of lw, map back accordingly
someParameter(i,l,w) = sum(lw_map(l,w,lw), s.l(i,lw));
I hope this helps!
In general, I would not expect too much from that sort of reformulation (trading binary for sos1 variables), but maybe you have some specific insights why such a reformulation should be advantageous for you?
I hope this helps!
Fred
Hi Fred,
First of all, thanks for your quick respond.
The suggested code does exactly what I imagined it to do.
Now I only have to adjust the rest of my model.
To the background:
Generally speaking, it’s about a component allocation for an assembly.
The whole model uses binary variables, which are indexed with very large sets.
If you now imagine the variable with 3 indices as a cube whose edges span the individual indices, the model will later distribute entries with 1 only very sporadically in this huge cube of zeros due to its nature. If, for example, a 1 is set in a plane of the cube, all other entries in this plane must automatically become zero.
The whole thing has already been modeled with binary variables, but only works with certain auxiliary variables. The idea is to avoid some equations and auxiliary variables by using a SOS1 variable.
Hope this explanation gives a little more insight
Have a nice day and keep up the good work.
Best regards, Pinguin_Fan
PS: You got a little Typo in the explanation Text right before the SOS1 Variable, claiming you’re declaring a SOS2 Variable instead of SOS1