如果您没有绑定到约束库,我强烈建议您使用 SMT 求解器;对于此类问题,它可以相对轻松地扩展到许多飞机/航班/海湾。此外,它们可以使用许多高级语言编写脚本,包括 Python。我建议使用 Microsoft 的 Z3 来解决这个特殊问题;您可以从以下网址获得免费副本:https ://github.com/Z3Prover/z3
虽然您可以通过多种方式对问题进行建模,但我认为以下是使用 Z3 的 Python 绑定对其进行编码的惯用方式:
from z3 import *
# Flights
Flight, (MI428, UL867, QR664, TK730, UL303) = EnumSort('Flight', ('MI428', 'UL867', 'QR664', 'TK730', 'UL303'))
flights = [MI428, UL867, QR664, TK730, UL303]
# Planes
Plane, (B320, B777, B235) = EnumSort('Plane', ('B320', 'B777', 'B235'))
# Bays
Bay, (A1, A2, B1, B2, C1) = EnumSort('Bay', ('A1', 'A2', 'B1', 'B2', 'C1'))
bays = [A1, A2, B1, B2, C1]
# Get a solver
s = Solver()
# Mapping flights to planes
plane = Function('plane', Flight, Plane)
s.add(plane(MI428) == B320)
s.add(plane(UL867) == B320)
s.add(plane(QR664) == B777)
s.add(plane(TK730) == B235)
s.add(plane(UL303) == B235)
# Bay constraints. Here're we're assuming a B320 can only land in A1 or A2,
# A B777 can only land on C1, and a B235 can land anywhere.
compatible = Function('compatible', Plane, Bay, BoolSort())
def mkCompat(p, bs):
s.add(And([(compatible(p, b) if b in bs else Not(compatible(p, b))) for b in bays]))
mkCompat(B320, [A1, A2])
mkCompat(B777, [C1])
mkCompat(B235, bays)
# Allocation function
allocate = Function('allocate', Flight, Bay)
s.add(And([compatible(plane(f), allocate(f)) for f in flights]))
s.add(Distinct([allocate(f) for f in flights]))
# Get a model:
if s.check() == sat:
m = s.model()
print [(f, m.eval(allocate(f))) for f in flights]
else:
print "Cannot find a satisfying assignment"
当我在我的计算机上运行它时,我得到:
$ python a.py
[(MI428, A1), (UL867, A2), (QR664, C1), (TK730, B2), (UL303, B1)]
这几乎不需要时间来计算,我相信它可以毫无问题地扩展到数千个航班/飞机/海湾。Z3 作为 SMT 求解器,您甚至可以以编程和简单的方式编写算术约束,例如到达/离开时间等。