## Iterative models/ Dynamic sets

Problems with modeling
Leon
User Posts: 2
Joined: 1 year ago

### Iterative models/ Dynamic sets

Dear All,

I am working on a power model that the output of the day 1 will be used as an input for the second day and it will continue for a month.
I tried to do this procedure for this goal. I defined a set: tt /1*744/ and then defined adynamic set day1(tt) /1*24/. Day2(tt) /25*48/....Day31(tt)/720*744/
Alias (t,Day1(tt));
I have lots of parameters and variables depended on time (like: Loading for different days(t,x)) with many constraints.
After the model declaration and minimizing the objective for the first iteration(day). I would like to update some of my parameters and then use the "day2" for all the parameters. Something like this

solve model using MIP minimizing obj1; //for the first day//

then: Alias (t, Day2(tt)); // I already know I cant redefine a set but I do not have any clue how I should solve this issue//
Update some of the parameters

solve model using MIP minimizing obj1; //for the second day//

* and same steps till the 31 days.

Best,
Leon

Renger
Posts: 406
Joined: 3 years ago

### Re: Iterative models/ Dynamic sets

Hi Leon

Instead of having everything based on the hours, you make them depending on hours (1*24) and days (1*31).
You then loop over the days:

Code: Select all

``````loop(day,
assing parameter values from tables
solve mymodel
assign solution to other parameters
)
``````

e.g.
A parameter is also defined over days and hours

Code: Select all

``````  table capacity(day,hours)
1 2 3 4 5 ... 24
1
...
31
``````
Hope this helps
Renger
____________________________________
Enjoy modeling even more: Read my blog on modeling at The lazy economist

Leon
User Posts: 2
Joined: 1 year ago

### Re: Iterative models/ Dynamic sets

Thank you Renger. It solved my problem.
Before I post my question, I checked the GAMS world for any similar question and I saw your response to other people as well.
That is really kind of you.
Thank you again.

PeterBe
User Posts: 66
Joined: 2 years ago

### Re: Iterative models/ Dynamic sets

Hi all,

I have a similar problem. I want to solve a model interatively. In my model I have two sets: t (for time) and households. Most of my parameters depend on both sets(t,households) and some only on (households) like:

Code: Select all

``````...
demand_electrical(t, household)

volumeOfBufferTank (household)
...
``````

I have several equations and variables that depend on both sets (t,households) but there are also some equations that only depend on (t).

My aim is to solve the model for each member of the set household with a loop statement. I have 2 questions regarding this:
1) Do I have to change the index of the parameters, variables and equations? And if so how shall I do this considering that not all parameters depend on the same sets.
2) Ho can I update the data in the loop statement? At the official GAMS docu the following example is used (https://www.gams.com/latest/docs/UG_FlowControl.html):

Code: Select all

``````loop (i,
problemdata = g(i);
solve mymodel using lp maximizing profit;
d(i) = profit.l;
);

``````
What I do not understand is how to do the data update: problemdata = g(i).?

Fred
Posts: 166
Joined: 3 years ago

### Re: Iterative models/ Dynamic sets

Peter,

You could introduce a dynamic subset of household and use that in the definition (not declaration!) of equations.

Code: Select all

``````set h(household) 'dynamic subset of household';
[...]
variable x(t,household);
[...]
equation e(household);
[...]
e(h).. sum(t,x(t,h)) + ... =g= ...;
``````
Now if you set h(household) = yes; the entire set household will be contained in subset h and you solve the entire model as you probably did before. To solve slices of the model for every household independently in a loop you could do:

Code: Select all

``````h(household) = no;
loop(household,
h(household) = yes;
solve mymodel ...
h(household) = no;
);
``````
I hope this helps!

Fred

PeterBe
User Posts: 66
Joined: 2 years ago

### Re: Iterative models/ Dynamic sets

Thanks a lot Fred for your answer and help. I really appreciate the tremendous help in this forum it help me solve the problem. Now I want to not only run the model for every household for the entire optimization horizon (all t) but I want for every 288 timeslots to run run the optimization for every household for a horizon of 288 timeslots.

My questions are:
1) In conventional programming you would use a nested loop for that. Is that also possible in GAMS?
2) How can I tell GAMS to repeatedly optimize for 288 timeslots for every household? If I just use the conventional loop with a t index, then I will solve the model for every timeslot.

Fred
Posts: 166
Joined: 3 years ago

### Re: Iterative models/ Dynamic sets

Peter,

Yes, you can use nested loops to implement that.
The following example creates a set of time slices and maps the slices to the original timeslots (not sure how many you have in total). Then you can basically use the same logic with dynamic subsets for the timeslots in your equations as illustrated before with the set households.

Code: Select all

``````set tt 'super set of time steps' /t1*t8760/;
\$eval tSlices ceil(card(tt)/288)
set tSlice          / ts1*ts%tSlices% /
t(tt)           'dynamic subset of tt'
map(tSlice,tt)  'mapping of time slice to time steps'
;
map(tSlice,tt) = (ord(tSlice)-1)*288 < ord(tt) and (ord(tSlice))*288 >= ord(tt);
option map:0:0:1; display map;

loop(tSlice,
t(tt) = map(tSlice,tt); display t;
loop(household,
h(household) = yes;
solve mymodel ...
h(household) = no;
);
);
``````
I hope this helps!

Fred

PeterBe
User Posts: 66
Joined: 2 years ago

### Re: Iterative models/ Dynamic sets

I first of all wanted to try the mapping of the timeslots (without having the nested loop). However I have to admit that I don't the code you posted so I just copied and pasted it in my model (I merely adjusted the number of time slots). The beginning of my model looks like this:

Code: Select all

``````Set
t timeslices
household households;

\$ife errorlevel<>0 \$abort Problems running GDXXRW

set tt 'super set of time steps' /t1*t8928/;
\$eval tSlices ceil(card(tt)/288)
set tSlice          / ts1*ts%tSlices% /
t(tt)           'dynamic subset of tt'
map(tSlice,tt)  'mapping of time slice to time steps'
;
map(tSlice,tt) = (ord(tSlice)-1)*288 < ord(tt) and (ord(tSlice))*288 >= ord(tt);
option map:0:0:1; display map;
``````
Unfortunately it does not work and I get the following error message: " Domain list redefined - no previous domain list - * assumed when data was associated with this symbol" and the line "t(tt) 'dynamic subset of tt' " is marked. Then I tried to comment out the lines " t timeslices" and "\$LOAD t" at the beginning (which were part of my inicial code and not part of the code you posted). After that I received many error messages stating that a set could not be found.

Fred
Posts: 166
Joined: 3 years ago

### Re: Iterative models/ Dynamic sets

Peter,

Just pasting code that you don't understand is probably not a good idea. In order to provide target-oriented help, it would be good to know what part of the code you do not understand.

I assumed that you have set of all timeslots. In my example this was tt. I dont know how many timeslots you actually have in total, so I just made up some number for my example (8760=hours per year).
My understanding was that you want to slice your entire time horizon into smaller parts of 288 timeslots each. With the 8928 time slots you have this would result in 31 such smaller parts or slices.

The following line computes this number 31 and stores it in a compile time variable:

Code: Select all

``\$eval tSlices ceil(card(tt)/288)``
You might want to consult the documentation if you are struggling with this part of the code:
https://www.gams.com/latest/docs/UG_Gam ... leTimeVars
https://www.gams.com/latest/docs/UG_Dol ... DOLLAReval

Then a corresponding set for the time slices is declared:

Code: Select all

``set tSlice          / ts1*ts%tSlices% /``
;

Apparently, you need to know which time slots are contained in which time slice. Therefore, a corresponding mapping is introduced and calculated.

Code: Select all

``````set t(tt)           'dynamic subset of tt'
map(tSlice,tt)  'mapping of time slice to time steps'
;
map(tSlice,tt) = (ord(tSlice)-1)*288 < ord(tt) and (ord(tSlice))*288 >= ord(tt);
``````
That's basically it.

You get an error because you already have a set t which you also load from data_5min_Jan_DayAhead_1HH.gdx. Not sure what is in this set. If this is your superset with all the time slots, you should adjust the set names accordingly. I guess you can figure that out yourself.

Best,
Fred

PeterBe
User Posts: 66
Joined: 2 years ago

### Re: Iterative models/ Dynamic sets

there are still a few things that I do not understand.

Code: Select all

``````\$eval tSlices ceil(card(tt)/288)
``````
why do we need a Compile-Time Variable here? You anyways specify the number of total timeslots. So the number of time slices can be computed based on this.

Code: Select all

``````map(tSlice,tt) = (ord(tSlice)-1)*288 < ord(tt) and (ord(tSlice))*288 >= ord(tt);
``````
I could not find a good description of the mapping operator. What is done in the statement "(ord(tSlice)-1)*288 < ord(tt) and (ord(tSlice))*288 >= ord(tt)"?

Code: Select all

``````option map:0:0:1; display map;
``````
The same question here. What does 0:0:1 mean?

Regarding my code I changed the name of the variable that I used before from t to t_a. This set (and all other parameters) are loaded from the file "data_5min_Jan_DayAhead_1HH.gdx."

Code: Select all

``````Set
t_a timeslices
household households;

\$ife errorlevel<>0 \$abort Problems running GDXXRW

set tt 'super set of time steps' /t1*t8928/;
\$eval tSlices ceil(card(tt)/288)
set tSlice          / ts1*ts%tSlices% /
t(tt)           'dynamic subset of tt'
map(tSlice,tt)  'mapping of time slice to time steps'
;
map(tSlice,tt) = (ord(tSlice)-1)*288 < ord(tt) and (ord(tSlice))*288 >= ord(tt);
option map:0:0:1; display map;
....
``````
I also load other parameters from that file and define variables.

Code: Select all

``````...
Parameter

demand_heating(t, household)