1

I am coding the model using CP based on the paper "A Constraint Programming Approach to Electric Vehicle Routing with Time Windows" by Kyle.E.C.Booth

using CP;

int NoDepot = ...;
int NoCharge = ...;
int NoCustomer = ...;
int NoVehicle = ...;

range depot = 1 .. NoDepot;
range dummydepot = NoDepot+1 .. NoDepot*2;
range charge = NoDepot*2+1 .. NoDepot*2+NoCharge;
range customer = NoDepot*2+NoCharge+1 .. NoDepot*2+NoCharge+NoCustomer;
range allnode = 1..NoDepot*2+NoCharge+NoCustomer;
range vehicle = 1..NoVehicle;

int start[allnode] = ...;
int end[allnode] = ...;

int demand[customer] = ...;
int servicetime[customer] = ...;
int batterycapa[vehicle] = ...;
int loadcapa[vehicle] = ...;

int consumerate = 1;
int rechargerate = 1;

int alpha = 1;
int beta = 1;

int distancematrix[0..NoDepot*2+NoCharge+NoCustomer][0..NoDepot*2+NoCharge+NoCustomer] = ...; 
int timematrix[0..NoDepot*2+NoCharge+NoCustomer][0..NoDepot*2+NoCharge+NoCustomer] = ...;

tuple triplet { int id1; int id2; int value; };
{triplet} Mdist = {<id1,id2,distancematrix[id1][id2]> | id1,id2 in allnode};
{triplet} Mtime = {<id1,id2,timematrix[id1][id2]> | id1,id2 in allnode};

dvar interval visit[c in customer] in start[c]..end[c] size servicetime[c];
dvar interval vehvisit_dist[a in allnode][v in vehicle] optional size 0;
dvar interval vehvisit_time[a in allnode][v in vehicle] optional;

dvar sequence route_dist[v in vehicle] in all (a in allnode)vehvisit_dist[a][v] types all(a in allnode) a;
dvar sequence route_time[v in vehicle] in all (a in allnode)vehvisit_time[a][v] types all(a in allnode) a;

dvar interval vehicle_dist[v in vehicle] optional;


cumulFunction carry_load[v in vehicle] = stepAtStart(vehvisit_time[1][v],loadcapa[v]) 
                - sum(c in customer)stepAtStart(vehvisit_time[c][v],demand[c]);

cumulFunction battery_load[v in vehicle] = stepAtStart(vehvisit_time[1][v],batterycapa[v]) 
    - sum(b in allnode)stepAtEnd(vehvisit_time[b][v],distancematrix[typeOfPrev(route_time[v], vehvisit_time[b][v],0,0)][b]) + sum(f in charge)stepAtStart(vehvisit_time[f][v],0,batterycapa[v]);


subject to
{
    
    ct1:
    forall(c in customer)
        alternative(visit[c],all(v in vehicle)vehvisit_time[c][v]);
    
    ct2:
    forall(v in vehicle)
        noOverlap(route_dist[v],Mdist,true);
    
    ct3:
    forall(v in vehicle)
        noOverlap(route_time[v],Mtime,true);
    
    ct4:
    forall(v in vehicle)
        sameSequence(route_dist[v], route_time[v]);
    
    ct5:
    forall(v in vehicle)
        presenceOf(vehvisit_time[1][v]);
        
    ct6:
    forall(v in vehicle)
        presenceOf(vehvisit_time[2][v]);

    ct7:
    forall(v in vehicle)
    {
        first(route_time[v],vehvisit_time[1][v]);
        last(route_time[v],vehvisit_time[2][v]);        
    }   
    
    ct8:
    forall(v in vehicle)
        span(vehicle_dist[v], all(a in allnode)vehvisit_time[a][v]);

    ct9:
    forall(v in vehicle)
        alwaysIn(carry_load[v],start[1], end[1], 0, loadcapa[v]);
    
    ct10:
    forall(v in vehicle)
        alwaysIn(battery_load[v],start[1], end[1], 0, batterycapa[v]);
    
    ct11:
    forall(v in vehicle, f in charge)
        alwaysIn(battery_load[v],vehvisit_time[f][v],batterycapa[v],batterycapa[v]);
}


///////////// .dat file
SheetConnection file("final.xlsx");

NoDepot from SheetRead(file, "NoDepot");
NoCharge from SheetRead(file, "NoCharge");
NoCustomer from SheetRead(file, "NoCustomer");
NoVehicle from SheetRead(file, "NoVehicle");
start from SheetRead(file, "start");
end from SheetRead(file, "end");
demand from SheetRead(file, "demand");
servicetime from SheetRead(file, "servicetime");
batterycapa from SheetRead(file, "batterycapa");
loadcapa from SheetRead(file, "loadcapa");
distancematrix from SheetRead(file, "dist");
timematrix from SheetRead(file, "time");



Link data in format excel:: https://docs.google.com/spreadsheets/d/1ou-AO-CmWz80dynkEivm432rjBPfCSWY/edit?usp=sharing&ouid=110647671445738653790&rtpof=true&sd=true

I have an error: Unbound expression: distancematrix[typeOfPrev(route_time[v1],vehvisit_time[b][v1],0,0)][b] in side stepAtStart function.

I have try many times but it not work, please help me, thanks update 1: I have read document of ibm about function stepAtStart([interval variable], int hmin, int hmax)

  • hmax & hmin are pre-defined, like distance matrix. But I still get error

update 2: I found that function 'typeOfPrev' can not be inside function 'stepAtEnd'

2
  • why not sharing .dat so that other users can try ? Commented May 21, 2024 at 8:31
  • @AlexFleischer I have added data and dat file. Thanks Commented May 21, 2024 at 9:36

2 Answers 2

0

The height in StepAtEnd can be an integer or two integer bounds, but not an expression involving constrained variables.

Sign up to request clarification or add additional context in comments.

1 Comment

I understand that, but is there any way involving constrainted variable ? because my problem is the battery remain will reduce based on the distance between two point . So that I have to use typeOfPrev inside stepAtStart @Olivier Lhomme
0

What I would use is an alternative with all trips that go to C : A->C and B->C , you write a stepAtStart for all those interval. Only the interval that is present will contribute to the cumul and the value of the stepAtStart is the distance.

At https://github.com/AlexFleischerParis/howtowithopl/blob/master/tspcpo.mod I shared a small example of distance matrix and scheduling

using CP; 
int     n       = ...;
range   Cities  = 1..n;

int realCity[i in 1..n+1]=(i<=n)?i:1;



// Edges -- sparse set
tuple       edge        {int i; int j;}
setof(edge) Edges       = {<i,j> | ordered i,j in 1..n};
setof(edge) Edges2       = {<i,j> | i,j in 1..n+1};  // node n+1 is node 1

int         dist[Edges] = ...;
int         dist2[<i,j> in Edges2]=(realCity[i]==realCity[j])?0:
((realCity[i]<realCity[j])?dist[<realCity[i],realCity[j]>]:dist[<realCity[j],realCity[i]>]);


dvar interval itvs[1..n+1] size 1;


dvar sequence seq in all(i in 1..n+1) itvs[i]; 

execute
{

cp.param.TimeLimit=60;
var f = cp.factory;
  cp.setSearchPhases(f.searchPhase(seq));
}

tuple triplet { int c1; int c2; int d; };
{triplet} Dist = { 
    <i-1,j-1,dist2[<i ,j >]>
           |  i,j in 1..n+1};
           
           
minimize endOf(itvs[n+1]) - (n+1);           
subject to
{
    startOf(itvs[1])==0; // break sym
    noOverlap(seq,Dist,true);   // nooverlap with a distance matrix
    last(seq, itvs[n+1]); // last node
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.