How to update/change end value of a set in a loop when solving a model?

Problems with modeling
Post Reply
maxisaacmagnus1
User
User
Posts: 1
Joined: 1 year ago

How to update/change end value of a set in a loop when solving a model?

Post by maxisaacmagnus1 »

I'm working with a model (mcp) that consists of a system of equations, whose values all depend on a set t (time) that is in the range /0*30/.

So, for now, I'm solving the model based on the end value of the set being 30. However, I'd like to also solve the model for different final values of the set t, so that I also solve it for the set t /0*29/, /0*28/, /0*27/, all the way to /0*2/.

QUESTION: Is it possible to change this final value of the set without having to do so manually (at the start of my code), but instead doing it so that the model solves it automatically for new end values of the set (for example in a loop or while)?

I'll share the main parts of my code below (I don't think it's necessary, but I could also provide the full code if it makes it clearer).

Code: Select all

Sets
    t time period /0*30/
  
    t0(t) Period t=0
    ts(t) Simulation periods
    ts2(t) Simulation periods except t=1
    tn(t) Last period
    ;

    t0(t) = yes$(ord(t) eq 1) ;
    ts(t) = yes$(ord(t) gt 1) ;
    ts2(t) = yes$(ord(t) gt 1 and ord(t) lt card(t)) ;
    tn(t) = yes$(ord(t) eq card(t)) ;

Scalars

Parameters
    
Positive Variables
    p(t) Price
    d(t) Demand 
    CumD Cumulative demand
    m_in(t) Inflow
    m_out(t) Outflow
    M(t) Size
    C(t) Cancellation
    ;
    
Equations
    EQ1(t) Inflow
    EQ2(t) Outflow
    EQ3(t) Cancellation 
    EQ4(t) Size
    EQ5(t) Market balance
    EQ6(t) Price over time
    EQ7(t) Demand 
    
    EQ7SUM Cumulative demand
    ;
    
    EQ1(t)$(ts(t))..  ;

    EQ2(t)$(ts(t))..   ;
   
    EQ3(t)$(ord(t) gt 2).. ;
    
    EQ4(t)$(ts(t))..  ;
    
    EQ5(t)$(ts(t))..  ;
    
    EQ6(t)$(ts2(t))..  ;

    EQ7(t)$(ts(t))..  ;

    EQ7SUM..  ;
    
Model MSR_YES /EQ1.m_in, EQ2.m_out, EQ3.C, EQ4.M, EQ5.p, EQ6.B, EQ7.d, EQ7SUM.CumD / ;

Solve MSR_YES using mcp;
So far, I've thought of doing a loop, or including a dynamic set for t, but I'm not sure how I would implement that. If I would try to implement a loop, I think it would look somehow like the following:

Code: Select all

SumD(t) store the value of CumD for each new loop/solution

loop(t$(ord(t) gt 1),
solve MSR_YES using mcp;
SumD(t) = CumD.l;
);
I am extremely unsure whether this would do what I'd like it to though. Could anyone provide insight in this?
User avatar
bussieck
Moderator
Moderator
Posts: 1037
Joined: 7 years ago

Re: How to update/change end value of a set in a loop when solving a model?

Post by bussieck »

You will need another dynamic set tt(t) and define (not declare) your equations over tt. Moreover, in your solve loop you need to assign tt and also reassign the sets ts, ts2, and tn. Here is the code:

Code: Select all

Sets
    t time period /0*30/
  
    t0(t) Period t=0
    ts(t) Simulation periods
    ts2(t) Simulation periods except t=1
    tn(t) Last period
    tt(t) Dynamic set of t
    ;

    t0(t) = yes$(ord(t) eq 1) ;

Scalars ... ;

Parameters ... ;
    
Positive Variables
    p(t) Price
    d(t) Demand 
    CumD Cumulative demand
    m_in(t) Inflow
    m_out(t) Outflow
    M(t) Size
    C(t) Cancellation
    ;
    
Equations
    EQ1(t) Inflow
    EQ2(t) Outflow
    EQ3(t) Cancellation 
    EQ4(t) Size
    EQ5(t) Market balance
    EQ6(t) Price over time
    EQ7(t) Demand 
    
    EQ7SUM Cumulative demand
    ;
    
    EQ1(tt(t))$(ts(t))..  1=e=1 ;

    EQ2(tt(t))$(ts(t))..  1=e=1 ;
   
    EQ3(tt(t))$(ord(t) gt 2).. 1=e=1;
    
    EQ4(tt(t))$(ts(t)).. 1=e=1 ;
    
    EQ5(tt(t))$(ts(t)).. 1=e=1 ;
    
    EQ6(tt(t))$(ts2(t)).. 1=e=1 ;

    EQ7(tt(t))$(ts(t)).. 1=e=1 ;

    EQ7SUM.. 1=e=1 ;
    
Model MSR_YES /EQ1.m_in, EQ2.m_out, EQ3.C, EQ4.M, EQ5.p, EQ6.d, EQ7.d, EQ7SUM.CumD / ;

alias (t,tx);
Parameter SumD(t) 'store the value of CumD for each new loop/solution';

loop(tx$(ord(tx) gt 1),
  tt(t) = ord(t)<=ord(tx);
  ts(tt(t)) = yes$(ord(t) gt 1) ;
  ts2(tt(t)) = yes$(ord(t) gt 1 and ord(t) lt card(tt)) ;
  tn(tt(t)) = yes$(ord(t) eq card(tt)) ;
  Solve MSR_YES using mcp;
  SumD(t) = CumD.l;
);  
-Michael
Post Reply