我正在寻找在CPLEX OPL中解决的车辆路由问题的代码

发布于 2025-02-08 17:08:04 字数 1826 浏览 5 评论 0原文

我需要在CPLEX中创建一个简单的VRP模型,如果有人可以帮助我,我将非常感激。我想知道哪辆车正在为哪个客户服务?

这是细节: 仓库:1 车辆:15 车辆容量:17 客户:56 客户需求:2

这是我到目前为止尝试的:

.mod:

{string} k = ...;  // vehicles
{string} i = ...;  // nodes
{string} j = ...; // depot


int demand[i]= ...; // demand at node i
int cap[k]= ...; // capacity of the vehicle
int dist[i][j]=...; //distance from node i to j

dvar float x[i][j];


minimize 
    sum(nodes in i, depot in j)
      dist[i][j];
      
      
subject to {
  

forall (nodes in i)
      demand_must_be_met:
      sum(vehicle in k)
        x[k][i]==demand[i];
}  

.dat:

k = {k1,k2,k3,k4,k5,k6,k7,k8,k9,k10,k11,k12,k13,k14,k15};

i = {Taubenmarkt,Landstrasse,LLenaupark,LLandstrasse,Industriezeile,LentiaCity,LLeonding,LInterspar,KarlSteigerStrasse,Kornstrasse,Traunerkreuzung,PlusKaufStrasse,FMZ,Haid,Marchtrenk,EferdingPupping,Walding,Rohrbach,BadLeonfelden,LAltenbergerstrasse,Gallneukirchen,Unterweitersdorf,FMZNord,Mauthausen,Furnpark,FMZEnnspark,NaarerStrasse,Steyr,SteyrResthofstrasse,SteyrHaagerStrasse,Sierning,LHartheimeerstrasse,BadHall,Micheldorf,Vorchdorf,WelsBäckergasse,Dalistrasse,WelsOberfeldstrasse,MaxCenter,GrieskirchenSchlüsselberg,DruckereistrasseSEP,Laakirchen,Schwanenstadt,Ampflwang,RiedTumeltshamFMZ,Weberzeile,Schärding,BadIschlFMZ,BadIschlZentrum,VöcklabruchZentrum,Varena,FMZTimelkam,StGeorgen,Mondsee,CityCenter,Mattighofen
};

j = {Enns};

cap = [17,17,17,17,17,17,17,17,17,17,17,17,17,17,17];

demand = [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
];

dist = [23,22,22,24,12,24,19,18,22,23,23,16,20,33,41,35,68,52,28,37,42,63,10,4,3,17,22,21,21,28,11,36,63,52,43,37,38,43,55,75,64,64,90,82,81,106,111,108,77,76,80,87,110,123,117
];

非常感谢您提前提供帮助!

I need to create a simple VRP model in CPLEX, I would be so grateful if someone could help me out. I want to know which vehicle is serving which customer?

Here are the details:
depot: 1
vehicles: 15
vehicle capacity: 17
Customers: 56
Customers demand: 2

here is what I have tried so far:

.mod:

{string} k = ...;  // vehicles
{string} i = ...;  // nodes
{string} j = ...; // depot


int demand[i]= ...; // demand at node i
int cap[k]= ...; // capacity of the vehicle
int dist[i][j]=...; //distance from node i to j

dvar float x[i][j];


minimize 
    sum(nodes in i, depot in j)
      dist[i][j];
      
      
subject to {
  

forall (nodes in i)
      demand_must_be_met:
      sum(vehicle in k)
        x[k][i]==demand[i];
}  

.dat:

k = {k1,k2,k3,k4,k5,k6,k7,k8,k9,k10,k11,k12,k13,k14,k15};

i = {Taubenmarkt,Landstrasse,LLenaupark,LLandstrasse,Industriezeile,LentiaCity,LLeonding,LInterspar,KarlSteigerStrasse,Kornstrasse,Traunerkreuzung,PlusKaufStrasse,FMZ,Haid,Marchtrenk,EferdingPupping,Walding,Rohrbach,BadLeonfelden,LAltenbergerstrasse,Gallneukirchen,Unterweitersdorf,FMZNord,Mauthausen,Furnpark,FMZEnnspark,NaarerStrasse,Steyr,SteyrResthofstrasse,SteyrHaagerStrasse,Sierning,LHartheimeerstrasse,BadHall,Micheldorf,Vorchdorf,WelsBäckergasse,Dalistrasse,WelsOberfeldstrasse,MaxCenter,GrieskirchenSchlüsselberg,DruckereistrasseSEP,Laakirchen,Schwanenstadt,Ampflwang,RiedTumeltshamFMZ,Weberzeile,Schärding,BadIschlFMZ,BadIschlZentrum,VöcklabruchZentrum,Varena,FMZTimelkam,StGeorgen,Mondsee,CityCenter,Mattighofen
};

j = {Enns};

cap = [17,17,17,17,17,17,17,17,17,17,17,17,17,17,17];

demand = [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
];

dist = [23,22,22,24,12,24,19,18,22,23,23,16,20,33,41,35,68,52,28,37,42,63,10,4,3,17,22,21,21,28,11,36,63,52,43,37,38,43,55,75,64,64,90,82,81,106,111,108,77,76,80,87,110,123,117
];

thank you so much for your help in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

九歌凝 2025-02-15 17:08:04

您可以从如何使用opl

“

using CP;

tuple Node {
    key string nodeID;
    int x;
    int y;
}
{Node} nodes = ...; 

tuple Visit { 
            key int visitID;
            string nodeID; 
            int quantity; 
            int minTime; 
            int maxTime; 
            int dropTime; 
              };
{Visit} clientVisits = ...;   

tuple Vehicle {
                key string vehicleID;   
                string firstVisitID;
                string lastVisitID;
                int capacity;
                int start;
                int end;
            }   
{Vehicle} vehicles = ...;                               

int firstDepotVisitID = min(v in clientVisits) v.visitID - 1;
int lastDepotVisitID = max(v in clientVisits) v.visitID + 1;
Visit firstDepotVisit = <firstDepotVisitID,"depot",0,0,230,0>;
Visit lastDepotVisit = <lastDepotVisitID,"depot",0,0,230,0>;
{Visit} allVisits = clientVisits union
            // Needs to be generalized for multiple depots
            {firstDepotVisit, lastDepotVisit };
            
int xPerVisit[i in allVisits]=item(nodes,<i.nodeID>).x; 
int yPerVisit[i in allVisits]=item(nodes,<i.nodeID>).y; 

int horizon = max (v in allVisits) v.maxTime;

// Create transition distance
tuple triplet { int c1; int c2; int d; };
{triplet} Dist = { 
    
        <ord(allVisits,v1), ord(allVisits,v2), 
        ftoi(round(sqrt(pow(n2.x-n1.x,2)+pow(n2.y-n1.y,2))))> 
           | v1,v2 in allVisits, n1, n2 in nodes : v1.nodeID == n1.nodeID && v2.nodeID == n2.nodeID }; 
  
dvar interval visitInterval[v in clientVisits] in v.minTime..(v.maxTime+v.dropTime) size v.dropTime;
dvar interval wtvisitInterval [v in clientVisits] size v.dropTime..horizon;
dvar interval tvisitInterval  [v in allVisits][veh in vehicles] 
                  optional(v.visitID!=firstDepotVisitID && v.visitID!=lastDepotVisitID);
dvar sequence route[veh in vehicles] in all(v in allVisits) tvisitInterval[v][veh] 
                                  types all(v in allVisits) ord(allVisits,v); 
dvar interval truck [veh in vehicles] optional;
 
execute {
  cp.param.TimeLimit               = 10
}

dexpr int nonTravelTime = sum(v in clientVisits) sizeOf(wtvisitInterval[v]);
dexpr float travelTime = sum(veh in vehicles) endOf(tvisitInterval[lastDepotVisit][veh]) - nonTravelTime;
dexpr int nbUsed = sum(veh in vehicles) presenceOf(truck[veh]);
dexpr int load[veh in vehicles] = sum(v in clientVisits) presenceOf(tvisitInterval[v][veh])*v.quantity;

minimize staticLex(nbUsed,travelTime); 
subject to  {

  forall(v in clientVisits ) {
    endAtEnd(wtvisitInterval[v], visitInterval[v]);
    startBeforeStart(wtvisitInterval[v], visitInterval[v]);
  }
  forall(veh in vehicles) {
    span (truck[veh], all(v in clientVisits) tvisitInterval[v][veh]);
    noOverlap(route[veh], Dist);          // Travel time
    startOf(tvisitInterval[firstDepotVisit][veh])==0;     // Truck t starts at time 0 from depot
    last (route[veh],tvisitInterval[lastDepotVisit] [veh]); // Truck t returns at depot
    load[veh] <= veh.capacity;                       // Truck capacity
  }
  forall(v in clientVisits)
    alternative(wtvisitInterval[v], all(t in vehicles) tvisitInterval[v][t]); // Truck selection
}
 
execute {
  writeln(nbUsed + " vehicles are used");
  writeln("Total travelled distance is " + travelTime); 
}

you could start with the TSP example in How to with OPL

VRP

using CP;

tuple Node {
    key string nodeID;
    int x;
    int y;
}
{Node} nodes = ...; 

tuple Visit { 
            key int visitID;
            string nodeID; 
            int quantity; 
            int minTime; 
            int maxTime; 
            int dropTime; 
              };
{Visit} clientVisits = ...;   

tuple Vehicle {
                key string vehicleID;   
                string firstVisitID;
                string lastVisitID;
                int capacity;
                int start;
                int end;
            }   
{Vehicle} vehicles = ...;                               

int firstDepotVisitID = min(v in clientVisits) v.visitID - 1;
int lastDepotVisitID = max(v in clientVisits) v.visitID + 1;
Visit firstDepotVisit = <firstDepotVisitID,"depot",0,0,230,0>;
Visit lastDepotVisit = <lastDepotVisitID,"depot",0,0,230,0>;
{Visit} allVisits = clientVisits union
            // Needs to be generalized for multiple depots
            {firstDepotVisit, lastDepotVisit };
            
int xPerVisit[i in allVisits]=item(nodes,<i.nodeID>).x; 
int yPerVisit[i in allVisits]=item(nodes,<i.nodeID>).y; 

int horizon = max (v in allVisits) v.maxTime;

// Create transition distance
tuple triplet { int c1; int c2; int d; };
{triplet} Dist = { 
    
        <ord(allVisits,v1), ord(allVisits,v2), 
        ftoi(round(sqrt(pow(n2.x-n1.x,2)+pow(n2.y-n1.y,2))))> 
           | v1,v2 in allVisits, n1, n2 in nodes : v1.nodeID == n1.nodeID && v2.nodeID == n2.nodeID }; 
  
dvar interval visitInterval[v in clientVisits] in v.minTime..(v.maxTime+v.dropTime) size v.dropTime;
dvar interval wtvisitInterval [v in clientVisits] size v.dropTime..horizon;
dvar interval tvisitInterval  [v in allVisits][veh in vehicles] 
                  optional(v.visitID!=firstDepotVisitID && v.visitID!=lastDepotVisitID);
dvar sequence route[veh in vehicles] in all(v in allVisits) tvisitInterval[v][veh] 
                                  types all(v in allVisits) ord(allVisits,v); 
dvar interval truck [veh in vehicles] optional;
 
execute {
  cp.param.TimeLimit               = 10
}

dexpr int nonTravelTime = sum(v in clientVisits) sizeOf(wtvisitInterval[v]);
dexpr float travelTime = sum(veh in vehicles) endOf(tvisitInterval[lastDepotVisit][veh]) - nonTravelTime;
dexpr int nbUsed = sum(veh in vehicles) presenceOf(truck[veh]);
dexpr int load[veh in vehicles] = sum(v in clientVisits) presenceOf(tvisitInterval[v][veh])*v.quantity;

minimize staticLex(nbUsed,travelTime); 
subject to  {

  forall(v in clientVisits ) {
    endAtEnd(wtvisitInterval[v], visitInterval[v]);
    startBeforeStart(wtvisitInterval[v], visitInterval[v]);
  }
  forall(veh in vehicles) {
    span (truck[veh], all(v in clientVisits) tvisitInterval[v][veh]);
    noOverlap(route[veh], Dist);          // Travel time
    startOf(tvisitInterval[firstDepotVisit][veh])==0;     // Truck t starts at time 0 from depot
    last (route[veh],tvisitInterval[lastDepotVisit] [veh]); // Truck t returns at depot
    load[veh] <= veh.capacity;                       // Truck capacity
  }
  forall(v in clientVisits)
    alternative(wtvisitInterval[v], all(t in vehicles) tvisitInterval[v][t]); // Truck selection
}
 
execute {
  writeln(nbUsed + " vehicles are used");
  writeln("Total travelled distance is " + travelTime); 
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文