具有docplex和python错误的三指标车辆流量公式CVRP

问题描述

我正在尝试使用CPLEX和python编写三索引cvrp。我发现了许多实现two-index formulation代码,但找不到扩展版本。按照github代码,我使用了广义的miller-tucker-zemlin子约束(请参见图片1.37-1.38),但是无论选择多少车辆,我都得到了不可行的解决方案。

enter image description here

下面是我的代码

import numpy as np
import matplotlib.pyplot as plt
from docplex.mp.model import Model

rnd = np.random
rnd.seed(0)

n = 10
Q = 20
N = [i for i in range(1,n+1)]
V = [0] + N
q = {i: rnd.randint(1,10) for i in N}
K = range(1,4)
loc_x = rnd.rand(len(V))*200
loc_y = rnd.rand(len(V))*100

A = [(i,j,k) for i in V for j in V if i != j for k in K]
Y = [(i,k) for i in V for k in K]
U = [(i,k) for i in N for k in K]
# c = {(i,j): np.hypot(loc_x[i]-loc_x[j],loc_y[i]-loc_y[j]) for i,k in A}
c = {(i,k in A}

mdl = Model('CVRP')

x = mdl.binary_var_dict(A,name='x')
y = mdl.binary_var_dict(Y,name='y')
u = mdl.continuous_var_dict(U,ub=Q,name='u')

mdl.minimize(mdl.sum(c[i,j]*x[i,k] for i,k in A))

# constraint 1
#for i in N:
mdl.add_constraints(mdl.sum(y[i,k] for k in K) == 1 for i in N)

# constraint 2
mdl.add_constraint(mdl.sum(y[0,k] for k in K) == len(K))

# constraint 3
mdl.add_constraints(mdl.sum(x[i,k] for j in V if i != j) - mdl.sum(x[j,i,k] for j in V if i != j) - y[i,k] == 0 for i in V for k in K)

# constraints 4 and 5 subtour elimination and capacity
mdl.add_indicator_constraints(mdl.indicator_constraint(x[i,k],u[i,k]+q[j] == u[j,k]) for i,k in A if i != 0 and j != 0)
mdl.add_constraints(u[i,k] >= q[i] for i in N for k in K)

mdl.parameters.timelimit = 30
solution = mdl.solve(log_output=True)

还有其他方法可以在CPLEX中编码此公式吗?我确实需要三项指标来增加车辆的成本。

解决方法

看看Model.binary_var_cube(以及其他类型的变体)

,

如果所有车辆的固定成本相同,那么您只需将固定成本添加到离开仓库的每个弧线的可变成本中,仍然可以使用2指标公式。

for i in clients:
    c[0,i] += fixed_cost

如果车辆的成本不同,则需要采用3指数公式。