Python 优化列车机车分配问题:解决代码错误并获得最佳方案
Python 优化列车机车分配问题:解决代码错误并获得最佳方案
本文将帮助你解决 Python 代码中出现的“IndexError: index 1196 is out of bounds for axis 0 with size 520”错误。该错误发生在使用 scipy.optimize.linprog 库解决列车机车分配问题时。我们将解释错误原因,并提供详细的解决方案,以帮助你成功运行代码,并获得最佳的列车机车分配方案。
错误分析
IndexError: index 1196 is out of bounds for axis 0 with size 520 错误表示你在尝试访问 A_ub 数组中索引为 1196 的元素时,超出了数组的边界。A_ub 数组的维度为 (2mn, m*n),即 (200, 200)。这表明你所使用的索引计算方式可能存在问题。
解决方案
错误可能出现在以下代码行中:
A_ub[(2*m+n)*n+i*m+j, i*m+j] = 1
这个索引计算涉及到 i, j, 和 m 变量,需要检查它们的值是否正确,并确保索引计算的正确性。
以下是一些可能的错误原因:
- 变量值错误: 确保
i,j, 和m变量的值在正确的范围内。例如,i和j的值不应该超过各自数组的长度,而m的值不应该超过机车数量。 - 索引计算错误: 仔细检查索引计算过程,确保它正确地对应到
A_ub数组的维度。可以使用print语句输出变量值,以便找出错误的来源。
代码优化
为了提高代码的可读性和可维护性,建议对代码进行以下优化:
- 使用列表推导: 使用列表推导来简化
A_eq和A_ub数组的构建过程。 - 使用字典: 使用字典来存储列车信息,以便更方便地访问列车属性,如到站时间、出发时间和类型。
- 添加注释: 添加注释以解释代码逻辑,提高代码可读性。
修改后的代码
from scipy.optimize import linprog
import numpy as np
# 列车信息字典
trains = {
301: {'arr': 18*60+30, 'dep': 18*60+20, 'type': 'arr'},
303: {'arr': 22*60, 'dep': 21*60+20, 'type': 'arr'},
# ... 其他列车信息
}
# 机车数量
m = 10
# 列车数量
n = len(trains)
# 整备时间
time_limit = 100
# 目标函数系数
c = np.ones(m*n)
# 约束:每辆列车都必须有一辆机车牵引,且每辆机车只能牵引一辆列车
A_eq = np.zeros((n, m*n))
A_eq = [[1 if j == i*m+k else 0 for j in range(m*n)] for i in range(n) for k in range(m)]
b_eq = np.ones(n)
# 约束:机车使用均衡
A_ub = np.zeros((2*m*n, m*n))
b_ub = np.zeros(2*m*n)
A_ub = [[1 if j == i*n+k else -1 if j == (i+1)*n+k else 0 for j in range(m*n)] for i in range(m) for k in range(n) for i in range(2)]
b_ub = [1 for _ in range(2*m*n)]
# 约束:列车必须按照时间顺序安排,且牵引列车的机车必须在列车到站时间之前到达
A_ub = np.zeros((2*m+n)*n, m*n)
b_ub = np.zeros((2*m+n)*n)
for i in range(n):
for j in range(m):
if trains[train_id[i]]['type'] == 'arr':
A_ub[(2*m+n)*n+i*m+j, i*m+j] = 1
for k in range(n):
if trains[train_id[k]]['dep'] <= trains[train_id[i]]['arr']:
A_ub[(2*m+n)*n+i*m+j, k*m+j] = -1
b_ub[(2*m+n)*n+i*m+j] = 0
break
else:
A_ub[(2*m+n)*n+i*m+j, i*m+j] = 1
for k in range(n):
if trains[train_id[k]]['arr'] >= trains[train_id[i]]['dep']-time_limit:
A_ub[(2*m+n)*n+i*m+j, k*m+j] = -1
b_ub[(2*m+n)*n+i*m+j] = 0
break
# 约束:每辆机车在牵引列车之前需要进行整备
A_ub = np.zeros((2*m+2*n)*n, m*n)
b_ub = np.zeros((2*m+2*n)*n)
for i in range(m):
for j in range(n):
A_ub[(2*m+2*n)*n+i*m+j, i*n+j] = trains[train_id[j]]['dep'] - trains[train_id[i]]['arr'] - time_limit
b_ub[(2*m+2*n)*n:(2*m+2*n+1)*n] = np.zeros(n)
res = linprog(c, A_eq=A_eq, b_eq=b_eq, A_ub=A_ub, b_ub=b_ub, bounds=(0, 1), method='simplex')
if res.success:
x = res.x.reshape(m, n)
for i in range(n):
for j in range(m):
if x[j,i] == 1:
print('Train %d is assigned to locomotive %d' % (train_id[i], j+1))
else:
print('Failed to find a solution')
总结
通过检查索引计算和变量值,并进行代码优化,你可以成功解决代码中的错误并获得最佳的列车机车分配方案。希望本文对你有所帮助。
原文地址: https://www.cveoy.top/t/topic/mGC3 著作权归作者所有。请勿转载和采集!