Search code examples
pythoncplexdocplex

Python DOcplex how to get end and start value for interval_var


I am trying to model a scheduling task using IBMs DOcplex Python API. The goal is to optimize EV charging schedules and minimize charging costs. However, I am having problems working with the CPO interval variable.

Charging costs are defined by different price windows, e.g., charging between 00:00 - 06:00 costs 0.10$ per kW while charging between 06:00 - 18:00 costs 0.15$ per kW.

My initial idea was this:

schedule_start = start_of(all_trips[trip_id].interval)
schedule_end   = end_of(all_trips[trip_id].interval)

cost_windows = {
                "morning":{ "time":range(0,44),
                            "cost":10},
                "noon":{    "time":range(44,64),
                            "cost":15},
                "afternoon":{ "time":range(64,84),
                              "cost":15},
                "night":{ "time":range(84,97),
                           "cost":10}
               }

time_low = 0
time_high = 0
for i in range(schedule_start,schedule_end):
    for key in cost_windows.keys():
        if i in cost_windows.get(key).get("time"):
             if cost_windows.get(key).get("cost") == 10:
                 time_low += 1
             else:
                 time_high += 1

cost_total = ((time_low * 10 * power) + (time_high * 15 * power)) / 400

As seen above, the idea was to loop through the interval start to end (interval size can be a maximum of 96, each unit representing a 15 minute time block) and check in what price window the block is. We later calculate the total cost by multiplying the number of blocks in each window with the power (integer variable) and price.

However, this approach does not work as we cannot use the start_of(interval) like a regular integer. Is there a way to get the start and end values for an interval and use them like regular integers? Or is there another approach that I am missing?

Regards


Solution

  • Have you tried to use overlap_length as can be seen in

    How to initiate the interval variable bounds in docplex (python)?

    ?

    start_of and end_of do not return values but something that is not set until the model is run.

    What you were trying to do is a bit like

    using CP;
    
    dvar int l;
    
    dvar interval a in 0..10 size 3;
    
    subject to
    {
      l==sum(i in 0..10) ((startOf(a)<=i) && (endOf(a)>i));
      
      
    }
    
    execute
    {
      writeln("l=",l);
    }
    

    in OPL but you enumerate time and that's not the good way

    Small example with overlapLength and 3 time windows with 3 prices

    using CP;
    
    dvar int l;
    
    tuple pricewindow
    {
      int s;
      int e;
      float price;
    }
    
    {pricewindow} windows={<0,5,1>,<5,6,0>,<6,10,0.5>};
    
    dvar interval pwit[w in windows] in w.s..w.e size (w.e-w.s);
    
    dvar interval a in 0..10 size 6;
    
    dexpr float cost=sum(w in windows) overlapLength(a,pwit[w])*w.price;
    minimize cost;
    subject to
    {
      
      
    }
    

    which gives

    // solution with objective 3
    a = <1 4 10 6>;