Iterative models/ Dynamic sets

Problems with modeling
Leon
User
User
Posts: 2
Joined: 5 years ago

Iterative models/ Dynamic sets

Post by Leon »

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
User avatar
Renger
Posts: 639
Joined: 7 years ago

Re: Iterative models/ Dynamic sets

Post by Renger »

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
User
Posts: 2
Joined: 5 years ago

Re: Iterative models/ Dynamic sets

Post by Leon »

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
User
Posts: 66
Joined: 7 years ago

Re: Iterative models/ Dynamic sets

Post by PeterBe »

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)
$LOAD  demand_electrical

volumeOfBufferTank (household)
$LOAD volumeOfBufferTank
...

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: 372
Joined: 7 years ago

Re: Iterative models/ Dynamic sets

Post by Fred »

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
User
Posts: 66
Joined: 7 years ago

Re: Iterative models/ Dynamic sets

Post by PeterBe »

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: 372
Joined: 7 years ago

Re: Iterative models/ Dynamic sets

Post by Fred »

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
User
Posts: 66
Joined: 7 years ago

Re: Iterative models/ Dynamic sets

Post by PeterBe »

Thanks Fred for your answer,

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;

$call gdxxrw data_5min_Jan_DayAhead_1HH.xlsx index=index!A1
$ife errorlevel<>0 $abort Problems running GDXXRW

$GDXIN 'data_5min_Jan_DayAhead_1HH.gdx';
$LOAD t
$LOAD household




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: 372
Joined: 7 years ago

Re: Iterative models/ Dynamic sets

Post by Fred »

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
User
Posts: 66
Joined: 7 years ago

Re: Iterative models/ Dynamic sets

Post by PeterBe »

Thanks Fred for your answer,

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;

$call gdxxrw data_5min_Jan_DayAhead_1HH.xlsx index=index!A1
$ife errorlevel<>0 $abort Problems running GDXXRW

$GDXIN 'data_5min_Jan_DayAhead_1HH.gdx';
$LOAD t_a
$LOAD household




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)
$LOAD  demand_heating

demand_electrical(t, household)
$LOAD  demand_electrical

...

temperature_level_DHWTank.lo(t, household) = minimalDHWTankTemperature;
temperature_level_DHWTank.up(t, household) = maximalDHWTankTemperature;
...
If I run the model I get many error messages stating "Values for domain 1 are unknown - no checking possible" and "Set has not been initialized".
My questin is whether I have to adjust the arguments for all those variables and parameters? For example shall I change "demand_electrical(t, household)" to "demand_electrical(tt, household)" or something like that?
Post Reply