Skip to content

Instantly share code, notes, and snippets.

@c3c
Created March 22, 2013 10:57
Show Gist options
  • Save c3c/5220474 to your computer and use it in GitHub Desktop.
Save c3c/5220474 to your computer and use it in GitHub Desktop.
vrp with window as subtour elimination constraint
/*********************************************
* OPL 12.5 Model
* Author: crash
* Creation Date: Mar 6, 2013 at 3:33:35 PM
*********************************************/
using CP;
// Nodes
tuple node { string name; int x; int y; int tmin; int tmax; }
{node} AllNodes = ...;
int N = card(AllNodes);
range nodes = 0..N-1;
// Edges
tuple edge {int i; int j;}
setof(edge) AllEdges = { <i,j> | i,j in nodes : i != j }; // not filtered!
setof(edge) OrderedEdges = { <i,j> | ordered i,j in nodes};
int Dist[OrderedEdges] = ...;
// Deliveries
tuple delivery {int destination; int from; int numpalettes;}
{delivery} Deliveries = ...;
// Remove superfluous thingies
sorted {int} clients = { d.from | d in Deliveries : d.numpalettes > 0 } union { d.destination | d in Deliveries : d.numpalettes > 0 };
sorted {int} cities = {0} union clients;
int numCities = card(cities);
int demand[t in cities] = sum (d in Deliveries : d.destination == t) d.numpalettes;
int outgoing[t in cities] = sum (d in Deliveries : d.from == t) d.numpalettes;
//int tmin[t in cities] = item(AllNodes, t).tmin;
//int tmax[t in cities] = item(AllNodes, t).tmax;
setof(edge) Edges = { <i,j> | i,j in cities : i != j }; // filtered! :)
//
//execute {
// writeln(AllEdges);
// writeln(tmin);
// writeln(tmax);
//}
// Camions
tuple camion {key int id;int capacity; int maxweight; int maxtime;}
{camion} Camions = ...;
// Travel time
int vitesse = 65; // km/h
int tempstrajet[<i,j> in OrderedEdges] = ftoi(round(Dist[<i,j>]/vitesse*60));
int tempsservice = 30;
// Decision variables
dvar boolean x[Edges,Camions];
dvar boolean y[cities,Camions];
dvar int arrival[Camions][cities] in 0..numCities-2;
dvar int+ quantity[cities][Camions];
//dvar interval timeofdelivery[i in clients][m] in i.tmin..i.tmax size 30;
dvar int arrivee[Camions][cities];
execute {
// cp.param.NoOverlapInferenceLevel = "Medium";
// cp.param.ElementInferenceLevel = "Low";
//cp.param.TemporalRelaxation = "Off";
cp.param.TimeMode = "ElapsedTime";
cp.param.TimeLimit = 60;
};
//tuple Subtour {
// int ssize;
// camion truck;
// int subtour[cities];
//};
//{Subtour} subtours = ...;
minimize sum (<i,j> in Edges, m in Camions) Dist[<minl(i,j), maxl(i,j)>]*x[<i,j>,m];
subject to {
forall (k in Camions, j in cities)
(sum(i in cities : j!=i) x[<i,j>][k]) == 1;
forall (k in Camions, j in cities)
(sum(i in cities : j!=i) x[<j,i>][k]) == 1;
// continuité
forall (p in cities, k in Camions)
((sum(i in cities : i!=p) x[<i,p>][k]) - (sum(j in cities : j!=p) x[<p,j>][k])) == 0;
// chaque véhicule entre et sort qu'un seul fois du dépôt
// forall (k in Camions)
// (sum(j in clients) x[<0,j>][k]) == 1;
//
// forall (k in Camions)
// (sum(i in clients) x[<i,0>][k]) == 1;
forall (k in Camions, <i,j> in Edges : i!=0 && j != 0)
(x[<i,j>][k] == 1) => (arrival[k][i] + 1 == arrival[k][j]);
// // Quantity per camion for each client <= demand of node
// forall (k in Camions, i in cities)
// quantity[i][k] <= demand[i];//*y[i][k];
// For each client, the aggregated quantity of all trucks must match the demand
forall (i in cities)
sum(k in Camions) quantity[i][k] == demand[i];
// The amount of palettes the truck is going to deliver must be inferior|equal to his capacity
// (perhaps include dvar (c12)
forall (m in Camions)
sum(i in cities) quantity[i][m] <= m.capacity;
// // respect timewindows
// forall (<i,j> in Edges : i!=0, k in Camions)
// (x[<i,j>][k] == 1) => ((arrival[k][i] + tempstrajet[<minl(i,j), maxl(i,j)>]) <= arrival[k][j]);
//
// min max timeframe for entry at client
// forall(i in clients, k in Camions)
// (tmin[i] <= arrival[k][i]) && (arrival[k][i] <= tmax[i]);
// truck can't be longer than e.g. 12h on route
// forall (m in Camions)
// m.maxtime >= sum (<i,j> in Edges) x[<i,j>,m]*(tempstrajet[<minl(i,j),maxl(i,j)>]+tempsservice);
//
// // Delivery at node 2 must be later than delivery at node 1
// forall (<i,j> in Edges, d in Deliveries : d.destination == j && d.from == i, m in Camions)
// (x[<i,j>][m] == 1) => (arrival[i][m] <= arrival[j][m]);
//
// forall (j in clients, k in Camions)
// (x[<0,j>][k] == 1) => (arrival[k][0] == max(x in cities) arrival[k][x]);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment