可用资源的分配(MILP?优化)

时间:2018-07-12 17:45:47

标签: python optimization linear-programming schedule linear

我要进行优化,考虑到我有一组可用的出发时间(例如5:20、6:25、6:30 ...)和一组所需的时间(5:25、7 :00,7:10 ...)的一组航班。

该想法是优化每次出发的可用时间,以最大程度地减少偏差:

一个错误的解决方案是将7:00的可用时间用于5:20。 7:00出发的最近可用时间是6:30 ... 我希望这是有道理的...

我相信这是熟女的一种,但我只是一个业余爱好者,不确定如何解决它。

非常感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

如果您真的坚持要使用python,则一个潜在的方向是使用scipy线性编程库,您可以在此处进行咨询:

https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.linprog.html

除此之外,我建议您咨询wikipedia list of linear program solvers。其中一些(例如Gurobi)具有免费的学术许可证。

答案 1 :(得分:0)

我主要将CPLEX用于此类优化问题,但是我可以想象您没有许可证可以使用。但是,我也对内置于Google OR Tools中的默认求解器有很好的经验,并将在下面的Python中显示一个解决方案。 Google的OR工具可以免费下载和使用,但并非可以与它集成的所有求解器都是

这是一个很好的小问题。我假设所有出发和飞行时间都在一天中,并且可以以一天中的分钟数表示(这不是限制性的:将所有时差转换为分钟数,并且可以很容易地扩展为多天等等)。我将飞行和离场之间的差异最小化为time of flight - time of departure。请注意,我安排了所有航班,但没有安排所有出发时间(其中之一必须具有约束力,否则可以通过不安排任何东西来获得最小限度)-相反,也可以通过翻转约束条件来实现。

from ortools.linear_solver import pywraplp
from itertools import product
import numpy as np

# In e.g. minutes of the day, 0 being midnight, 1339 being 23:59.
departures = [547, 902, 37, 1420, 1240, 1373, 1214, 334, 229, 683, 966, 165,
              105, 1394, 102, 999, 778, 610, 1033, 250, 981, 640, 1110, 1419,
              578]

flights = [288, 626, 435, 643, 490, 824, 248, 355, 801, 450]

# costs_{i, j} is the minutes difference between flight i and departure j
costs = np.subtract.outer(flights, departures)

solver = pywraplp.Solver("Solver",
                         pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)

# 1 if flight i is assigned departure j, 0 otherwise
assignments = {(i, j): solver.BoolVar("x[{0}, {1}]".format(i, j))
               for i in range(len(flights))
               for j in range(len(departures))}

# Minimize the difference between flight and departure, if assigned
solver.Minimize(solver.Sum(costs[i][j] * assignments[i, j]
                           for i in range(len(flights))
                           for j in range(len(departures))))

for i in range(len(flights)):  # all flights are assigned once
    solver.Add(solver.Sum(assignments[i, j]
                          for j in range(len(departures))) == 1)

for j in range(len(departures)):  # all departures are assigned at most once
    solver.Add(solver.Sum(assignments[i, j]
                          for i in range(len(flights))) <= 1)

# Flights are at the same time or later than departures
for i, j in product(range(len(flights)),
                    range(len(departures))):
    solver.Add(costs[i][j] * assignments[i, j] >= 0)

if solver.Solve() == solver.INFEASIBLE:
    raise ValueError("Infeasible problem")

print("flight\tdeparture")

for i, j in product(range(len(flights)),
                    range(len(departures))):
    if assignments[i, j].solution_value() > 0:
        print(flights[i], departures[j], sep="\t\t")

哪个产量

flight  departure
288     250
626     610
435     334
643     640
490     229
824     778
248     165
355     105
801     683
450     102

由我自己判断该规范是否可以得出可接受的解决方案。

供进一步阅读:这与assignment problem密切相关,combinatorial optimisation是经典的结果。诸如此类的优化问题在例如 operational research中是一角钱,我很高兴能积极工作,这是一个美丽的研究领域。