我正在解决相当大的问题,但我陷入了困境。我会在这里尝试简化它,希望有人能给我一个想法......
假设我们有 25 个航班 (FlightID) 在不同的时间 (TimeIndex) 起飞,必须分配给 10 个可用的行李处理工作站 (WS),如下所示:
每个航班需要 1、2 或 3 个行李处理工作站 (WS),从 StartTime 到 EndTime 将占用这些工作站。每个工作站在整个时间段(开始时间到结束时间)内只能服务一个航班。
我到目前为止看起来像这样:
首先,我从 .csv 文件中读取我的信息。
from pulp import *
import pandas
#Function to read from csv filename to dictionary dictname
def read_file(filename, dictname):
with open(filename, 'r') as f:
# Get the CSV reader and skip header
reader = csv.reader(f)
next(reader, None)
for row in reader:
#First column is the key, the rest is value
dictname[row[0]] = row[1:]
# Print result
# print(row[0], ':', dictname[row[0]])
# Read flight departures from csv file
flights = {}
flights_csv = '25_busySO.csv'
read_file(flights_csv, flights)
然后我创建了 10 个工作站。
chutes = []
for i in range(1,11):
chutes.append('ws' + str(i))
接下来,我声明我的决策变量“x” - 一个字典,其中飞行、时间、工作站作为键,0、1 作为值。
x = LpVariable.dicts('x', [(f, t, c) for f in flights.keys() for t in \
range(int(flights[f][1]),int(flights[f][2])+1) for c in chutes], 0, 1, LpBinary)
用虚拟目标函数声明问题。
simploc = LpProblem('simploc', LpMinimize)
simploc += 0
第一个约束强制将所有航班分配到一个工作站到所有需要的 24 次。
for f in flights.keys():
simploc += lpSum(x[f, t, c] for t in range(int(flights[f][1]),int(flights[f][2])+1) \
for c in chutes) == 24
这会创建一组独特的时间,以便仅在需要时创建约束,而不是遍历所有可能的时间范围。
times = []
for k in x.keys():
times.append(k[1])
times = sorted(set(times))
下一个约束强制一个工作站一次只分配给一个航班。
for t in times:
for f in flights.keys():
try:
simploc += lpSum(x[f, t, c] for c in chutes) <= 1
except KeyError:
pass
只需将模型写入 .txt 即可。
simploc.writeLP('simploc.txt')
simploc.solve()
# print problem status and objective value
print("problem status", LpStatus[simploc.status])
我也在使用 pandas 来获得“x”的可视化。
# transfer results from x lpvariable dictionary to dataframe for easy reading
result = {}
for k, v in x.items():
result[k] = value(v)
result = pandas.Series(result).unstack()
现在,我的问题是我不知道如何进行第三个约束,以便在该航班所需的所有时间将一个工作站 (WS) 分配给同一航班,如下所示:
更准确地说,例如,Flight01 应该一直分配给 WS1(从 116 到 140)。