0

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

can_k
  • 31
  • 3

1 Answers1

1

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>;
Alex Fleischer
  • 9,276
  • 2
  • 12
  • 15
  • similar question in IBM Community https://community.ibm.com/community/user/datascience/discussion/python-docplex-obtaining-interval-var-start-and-end-value – Alex Fleischer Nov 19 '22 at 11:15
  • Thank you for your input! I checked the post you linked, it seems like you would need 2 different intervals in order to use overlap_length, in my case there is only a single interval. Even then, I am having a hard time understanding how overlap_length relates to the interval start and end, could you elaborate? – can_k Nov 21 '22 at 09:25
  • 1
    You would use overlap_length between your interval and the price windows – Alex Fleischer Nov 21 '22 at 09:42
  • 1
    Ok thanks alot for your help :) I was able to implement it this way! – can_k Dec 02 '22 at 10:11