模型代码如下
```python
from pulp import *
# 配送点数量和车辆数量
num_points = 10
num_vehicles = 5
# 距离矩阵
distances = [
[0, 0.56, 1.30, 0.50, 0.94, 0.03, 0.77, 0.55, 0.95, 0.46, 0.38],
[0.56, 0, 1.50, 0.84, 1.40, 1.10, 0.16, 0.90, 1.40, 0.94, 0.86],
[1.30, 1.50, 0, 0.41, 0.57, 0.71, 1.40, 0.45, 0.81, 1.10, 1.00],
[0.50, 0.84, 0.41, 0, 1.20, 0.31, 0.98, 0.05, 1.20, 0.73, 0.65],
[0.94, 1.40, 0.57, 1.20, 0, 1.20, 1.20, 0.96, 0.004, 1.40, 1.50],
[0.03, 1.10, 0.71, 0.31, 1.20, 0, 0.67, 0.51, 0.92, 0.42, 0.34],
[0.77, 0.16, 1.40, 0.98, 1.20, 0.67, 0, 0.80, 1.30, 1.10, 1.00],
[0.55, 0.90, 0.45, 0.05, 0.96, 0.51, 0.80, 0, 1.20, 0.71, 0.62],
[0.95, 1.40, 0.81, 1.20, 0.004, 0.92, 1.30, 1.20, 0, 1.30, 1.30],
[0.46, 0.94, 1.10, 0.73, 1.40, 0.42, 1.10, 0.71, 1.30, 0, 0.71],
[0.38, 0.86, 1.00, 0.65, 1.50, 0.34, 1.00, 0.62, 1.30, 0.71, 0]
]
# 需求量
demands = {
1: 118, 2: 125, 3: 126, 4: 115, 5: 120,
6: 130, 7: 110, 8: 116, 9: 129, 10: 124
}
# 每辆车的最大运载量
Q = 260
#单位距离运输成本
C=10
# 创建问题
problem = LpProblem("Vehicle Routing Problem", LpMinimize)
# 创建变量
x = LpVariable.dicts("route", [(i, j, k) for i in range(num_points+1)
for j in range(num_points+1)
for k in range(num_vehicles)],
lowBound=0, upBound=1, cat=LpInteger)
d = LpVariable.dicts("demand", [i for i in range(num_points+1)],
lowBound=0, upBound=None, cat=LpInteger)
#目标函数
problem += lpSum([C * distances[i][j] * x[(i, j, k)] for i in range(num_points+1)
for j in range(num_points+1)
for k in range(num_vehicles)])
# 约束条件 - 每个配送点只被一个车辆访问
for i in range(1, num_points+1):
problem += lpSum([x[(i, j, k)] for j in range(num_points+1) for k in range(num_vehicles)]) == 1
# 约束条件 - 每辆车的容量约束
for k in range(num_vehicles):
problem += lpSum([demands[i] * x[(i, j, k)] for i in range(1,num_points+1) for j in range(num_points+1)]) <= Q
# 约束条件 - 避免子循环路径
for i in range(1, num_points+1):
for k in range(num_vehicles):
problem += lpSum([x[(i, j, k)] for j in range(num_points+1)]) <= 1
# 约束条件 - 出发点和回到出发点
for k in range(num_vehicles):
problem += lpSum([x[(0, j, k)] for j in range(1, num_points+1)]) == 2
# 求解问题
problem.solve()
# 输出结果
print("最小运输成本:", value(problem.objective))
print("车辆配送方案:")
for k in range(num_vehicles):
print("车辆", k+1, ":", end=" ")
route = [0]
for i in range(1, num_points+1):
for j in range(num_points+1):
if value(x[(i, j, k)]) == 1:
route.append(i)
break
route.append(0)
print(route)
输出结果
最小运输成本: 20.5
车辆配送方案:
车辆 1 : [0, 4, 7, 0]
车辆 2 : [0, 8, 10, 0]
车辆 3 : [0, 3, 5, 0]
车辆 4 : [0, 1, 9, 0]
车辆 5 : [0, 2, 6, 0]
目标函数的结果是错误的,因为根据车辆配送的方案可以计算出运输成本应该为103.5
车辆 1 : = 10 * (0.94 + 0.96 + 0.55) = 24.5
车辆 2 : = 10 * (0.95 + 1.30 + 0.38) = 26.3
车辆 3 : = 10 * (0.50 + 0.31 + 0.03) = 8.4
车辆 4 : = 10 * (0.56 + 0.94 + 0.46) = 9.6
车辆 5 : = 10 * (1.30 + 1.40 + 0.77) = 34.7
总运输成本 = 24.5 + 26.3 + 8.4 + 9.6 + 34.7 = 103.5,请问目标函数应该如何修改?
这咋看着像tsp问题,但又不完全一样。你可以试试分支限界法或者遗传算法求解这类题
Python+Gurobi求解非线性规划模型
可以参考下这个例子
查一下官方文档吧,可能版本问题或者参数改掉了
检查一下版本,可能是版本问题
该回答引用ChatGPT-3.5,仅供参考,不保证完全正确
要修改目标函数以正确计算运输成本,您需要更改以下代码行:
problem += lpSum([C * distances[i][j] * x[(i, j, k)] for i in range(num_points+1)
for j in range(num_points+1)
for k in range(num_vehicles)])
您需要修改乘法项的顺序,将运输成本乘以距离和车辆路线变量,而不是距离乘以运输成本和车辆路线变量。修改后的代码如下:
problem += lpSum([C * x[(i, j, k)] * distances[i][j] for i in range(num_points+1)
for j in range(num_points+1)
for k in range(num_vehicles)])
通过更改乘法项的顺序,您将正确计算每个车辆的运输成本,并得到正确的目标函数结果。
该回答引用NewBing,仅供参考,不保证完全正确
根据我从网络上搜索到的信息,您的目标函数可能有一些错误。您的目标函数是最小化所有车辆的总运输成本,但是您的代码中只考虑了每辆车的第一段和最后一段路程的成本,而没有考虑中间的路程。例如,如果车辆1从0出发,访问4和7,然后回到0,那么您的代码只计算了0到4和7到0的距离,而没有计算4到7的距离。这样会导致目标函数的值偏小。
为了修正这个问题,您可以修改您的目标函数如下:
problem += lpSum([C * distances[i][j] * x[(i, j, k)] for i in range(num_points+1)
for j in range(num_points+1)
for k in range(num_vehicles) if i != 0 and j != 0])
这样就可以考虑所有车辆访问的所有客户之间的距离,而不是只考虑出发点和终点。
源: 与必应的对话, 2023/7/18
(1) problem about vehicle routing problem by Gurobi Python. https://stackoverflow.com/questions/68329896/problem-about-vehicle-routing-problem-by-gurobi-python.
(2) CVRPTW stands for Capacitated Vehicle Routing Problem with Time Windows. https://github.com/sudhan-bhattarai/CVRPTW_MILP.
(3) vehicle-routing-problem · GitHub Topics · GitHub. https://github.com/topics/vehicle-routing-problem?l=python.
(4) undefined. https://github.com/KaiyuWei/VRP-problem-by-Gurobi--Python.
problem += lpSum([C * distances[i][j] * x[(i, j, k)] for i in range(num_points+1)
for j in range(num_points+1)
for k in range(num_vehicles)])
应该修改为:
problem += lpSum([C * distances[i][j] * x[(i, j, k)] for i in range(num_points+1)
for j in range(num_points+1)
for k in range(num_vehicles)]) / num_vehicles
这样修改之后的代码如下:
# 求解问题
problem.solve()
# 计算每个车辆的运输成本
total_cost = 0
for k in range(num_vehicles):
vehicle_cost = 0
for i in range(num_points+1):
for j in range(num_points+1):
if value(x[(i, j, k)]) == 1:
vehicle_cost += distances[i][j]
vehicle_cost *= C
total_cost += vehicle_cost
# 输出结果
print("最小运输成本:", total_cost)
print("车辆配送方案:")
for k in range(num_vehicles):
print("车辆", k+1, ":", end=" ")
route = [0]
for i in range(1, num_points+1):
for j in range(num_points+1):
if value(x[(i, j, k)]) == 1:
route.append(i)
break
route.append(0)
print(route)
这样修改之后,你应该可以得到正确的运输成本。
在目标函数的计算中,您需要将运输成本乘以对应的配送路径的需求量。当前的目标函数没有考虑需求量,因此结果不正确。您可以按以下方式修改目标函数:
# 目标函数
problem += lpSum([C * distances[i][j] * demands[i] * x[(i, j, k)] for i in range(num_points+1)
for j in range(num_points+1)
for k in range(num_vehicles)])
这样,目标函数会将每个配送路径的距离乘以对应的需求量,并计算总运输成本。
修改后的目标函数将考虑需求量,然后重新求解问题并输出结果。希望这可以解决您的问题!如果您有任何其他疑问,请随时问。
你的目标函数计算的是每辆车的运输成本,但你的车辆分配方案中,每辆车都只负责一部分商品的,而不是全部。
为了解决这个问题,你需要修改你的目标函数,使其考虑到每辆车只负责一部分商品的情况。具体来说,你可以将每个商品的的成本分配给负责该商品的的车,然后将每辆车的成本相加,这样你就可以得到正确的总运输成本。
或者参考资料:
带时间窗约束的车辆路径规划问题(VRPTW)详解 + Python 调用 Gurobi 建模求解:http://imyhq.com/ai/4078.html