I’m a beginner in the usage of GAMS and I fail to define a parameter based on the solution of my model, because I struggle with the indices. I have an assignment problem, where my decision variables x(t,w) assign to every task t exactly one worker w. Thus, my x variables are SOS1-variables. Now I like to define a parameter worker(t) that gives me to every task the assigned worker. Sadly, I have no idea how to retrieve this parameter with only one index from the variables with two indices. More mathematically spoken, I need: worker(t) = w : x.l(t,w) == 1.
Relevant declaration:
Set t ‘tasks’;
Set w ‘workers’;
Variable x(t,w) ‘Task t is a assigned to worker w’;
SOS1 variable x(t,w);
After the solve statement, I tried something like:
worker(t) $ x.l(t,w) = w,
or
loop(w,
loop(t,
if (x.l(t,w) = 1,
worker(t) = w)
));
Hi, workers is a set which could be something like /w1,w2,…wN/;
Parameter values have to be numbers which is why worker(t) =w is an incorrect way to think about the problem.
How about you define a parameter worker(t, w) which is 1 if task t is assigned to worker w?
You can certainly do that by
worker(t,w)$(x.l(t,w)) = 1;
As a sidenote, you can have variable x(t,w) to be a ‘binary variable’ instead of a variable. This way you won’t need any other parameter such as worker(t,w). You can simply read x to get this information.
Hope this helps.
thanks a lot for your answer! I have completely overlooked that parameters have to be numbers, that’s very good to know! Your suggestions with the redefined worker-parameter and/or the direct access to the binary x-variable work, thanks!
To satisfy my curiosity and perhaps for future use: In case the workers are simply numbers (Set w “workers” / 1 * 20 /;), is there a way to set my originally planned parameter worker(t) as I wanted?
If your set is a number and you want to access its value, then you can use set attribute ‘.val’. In your case, w.val will read set elements as numbers. In writing worker(t) $ x.l(t,w) = w, you will still face one issue which is that GAMS does not know which ‘w’ you are talking about when you check x.l(t,w) and you will get an error with something like ‘uncontrolled set…’.
The following statement should do the job instead
worker(t) = sum(w ($x.l(t,w)), w.val);
Great! Thank you very much!
Your explanation is super and the solution is brilliant! It does exactly what I searched for.
PS: Just in case anybody else wants to use your solution, there is an order-typo with the '', the correct syntax is: worker(t) = sum(w (x.l(t,w)), w.val);