Routing 在CPLEX定位路径问题中,如何确定车辆是否从车辆段m出发,必须返回同一车辆段

Routing 在CPLEX定位路径问题中,如何确定车辆是否从车辆段m出发,必须返回同一车辆段,routing,location,cplex,opl,depot,Routing,Location,Cplex,Opl,Depot,这是在我的OPL代码中的位置路由问题,有3个候选站点,8个客户和4辆车。优化结果为:300174667,开放的车辆段为第二和第三车辆段。路线是这样的: from depot 2-4-8- depot 3 (vehicle 2) from depot 2-7-5- depot 2 (vehicle 1) from depot 2-10-9- depot 3 (vehicle 4) from depot 3-6-11- depot 3 (vehicle 3) forall(k in K) fora

这是在我的OPL代码中的位置路由问题,有3个候选站点,8个客户和4辆车。优化结果为:300174667,开放的车辆段为第二和第三车辆段。路线是这样的:

from depot 2-4-8- depot 3 (vehicle 2)
from depot 2-7-5- depot 2 (vehicle 1)
from depot 2-10-9- depot 3 (vehicle 4)
from depot 3-6-11- depot 3 (vehicle 3)
forall(k in K) forall (m in M) sum(i in C) X[<m,i,k>] == sum(c in C) X[<i,m,k>];
可以看出,有两条路线从车辆段2开始,在车辆段3结束。我希望的结果是,如果车辆在车辆段2启动,它们也将在车辆段2结束

我曾试图改变需求或容量,但结果仍然是这样。你能告诉我哪里出错了吗?非常感谢你

这是我的模型:

int m=...; //depot
int c=...; //customer
int k=...; //vehicle
range M=1..m;
range C=m+1..m+c;
range V=1..m+c;
range K=1..k;

tuple jalur {int i;int j;}
tuple jalur_truk {int i;int j;int k;}

setof (jalur) ij={<i,j> | i,j in V:i!=j};
setof (jalur_truk) ijk={<i,j,k> | i,j in V:i!=j, k in K};

int ct[ij]=...;
int f[M]=...;
int o[K]=...;
int Q[M]=...;
int d[C]=...;
int q[K]=...;

//decision variable
dvar boolean X[ijk]; 
dvar boolean Y[M];

//(1): objective functions:
minimize sum(m in M) f[m]*Y[m] + sum(i,j in V:i!=j, k in K) ct[<i,j>]*X[<i,j,k>]+
    sum(m in M, i in C, k in K) o[k]*X[<m,i,k>]; 

 subject to{
//(2): each customer must be visited exactly once
forall (j in C) 
  sum (k in K, i in V:j!=i) X[<i,j,k>] == 1;

forall (i in C) 
  sum (k in K, j in V:j!=i) X[<i,j,k>] == 1;

//(3)-(5): vehicle flow conservation 
forall (k in K)
  sum (m in M, i in C) X[<m,i,k>] == 1;  

forall (k in K)
  sum (i in C, m in M) X[<i,m,k>] == 1; 

forall (h in C, k in K)
  sum(i in V:i!=h) X[<i,h,k>] - sum (j in V:j!=h) X[<h,j,k>] == 0 ;

//(6)-(7): vehicle and depot capacity constraints
forall (k in K)
  sum(i in C,j in V: j!=i) d[i]*X[<i,j,k>] <= q[k];

forall (m in M)
  sum(j in C, k in K) d[j]*X[<m,j,k>] <= Q[m]*Y[m];

//(8): computes and limits the number of vehicle U used
  sum (i in M, j in C, k in K) X[<i,j,k>] - k == 0;  

}

如果您希望某条路线在其起点所在的同一停车场结束,则必须将其明确声明为约束。您的约束仅说明,对于每辆车,车辆必须离开任何车辆段,并且必须进入任何车辆段。您可能还想要这样的东西:

from depot 2-4-8- depot 3 (vehicle 2)
from depot 2-7-5- depot 2 (vehicle 1)
from depot 2-10-9- depot 3 (vehicle 4)
from depot 3-6-11- depot 3 (vehicle 3)
forall(k in K) forall (m in M) sum(i in C) X[<m,i,k>] == sum(c in C) X[<i,m,k>];
forall(k in k)forall(m in m)sum(i in C)X[]==sum(C in C)X[];
也就是说,对于每个仓库,使用的出站弧数必须与使用的入站弧数相同。 或者,可以声明此流守恒约束

forall (h in C, k in K)
  sum(i in V:i!=h) X[<i,h,k>] - sum (j in V:j!=h) X[<h,j,k>] == 0 ;
forall(C中的h,k中的k)
sum(V:i!=h中的i)X[]-sum(V:j!=h中的j)X[]=0;

也适用于站点(目前仅针对客户进行说明)。

如果您希望路线在其开始的同一站点结束,则必须明确说明这是一个约束条件。您的约束仅说明,对于每辆车,车辆必须离开任何车辆段,并且必须进入任何车辆段。您可能还想要这样的东西:

from depot 2-4-8- depot 3 (vehicle 2)
from depot 2-7-5- depot 2 (vehicle 1)
from depot 2-10-9- depot 3 (vehicle 4)
from depot 3-6-11- depot 3 (vehicle 3)
forall(k in K) forall (m in M) sum(i in C) X[<m,i,k>] == sum(c in C) X[<i,m,k>];
forall(k in k)forall(m in m)sum(i in C)X[]==sum(C in C)X[];
也就是说,对于每个仓库,使用的出站弧数必须与使用的入站弧数相同。 或者,可以声明此流守恒约束

forall (h in C, k in K)
  sum(i in V:i!=h) X[<i,h,k>] - sum (j in V:j!=h) X[<h,j,k>] == 0 ;
forall(C中的h,k中的k)
sum(V:i!=h中的i)X[]-sum(V:j!=h中的j)X[]=0;
也适用于仓库(目前仅针对客户)