我一直在制作一个系统,该系统可以接收有关驾驶员、潜在乘客及其位置的数据,并尝试在某些限制条件下优化可以与驾驶员一起乘坐电梯的乘客数量。我正在使用 python-constraint 模块,决策变量是这样表示的:
p = [(passenger, driver) for driver in drivers for passenger in passengers]
driver_set = [zip(passengers, [e1]*len(drivers)) for e1 in drivers]
passenger_set = [zip([e1]*len(passengers), drivers) for e1 in passengers]
self.problem.addVariables(p, [0,1])
因此,当我打印 p 的值以及 driver_set 和passenger_set 时,我得到以下输出(给定我提供的测试数据):
[(0, 0), (1, 0), (2, 0), (0, 1), (1, 1), (2, 1)] # p
[[(0, 0), (0, 1)], [(1, 0), (1, 1)], [(2, 0), (2, 1)]] # passenger_set
[[(0, 0), (1, 0)], [(0, 1), (1, 1)]] # driver_set
因此,有 3 名乘客和 2 名司机:变量 (2,0) 表示乘客 2 在 0 号车内,依此类推。我添加了以下约束,以确保没有乘客乘坐超过一辆车,并且驾驶员的人数不能超过座位:
for passenger in passenger_set:
self.problem.addConstraint(MaxSumConstraint(1), passenger)
for driver in driver_set:
realdriver = self.getDriverByOpId(driver[0][1])
self.problem.addConstraint(MaxSumConstraint(realdriver.numSeats), driver)
这行得通 - 生成的所有解决方案都满足这些约束。但是,我现在想添加一些限制条件,即任何解决方案都不应该让车手行驶超过一定距离。我有一个函数,它接收一个司机(与 driver_set 中的实体格式相同)并计算司机接所有乘客的最短距离。我试图添加这样的约束:
for driver in driver_set:
self.problem.addConstraint(MaxSumConstraint(MAX_DISTANCE), [self.getRouteDistance(self.getShortestRoute(driver))])
这给出了以下错误:
KeyError: 1.8725031790578293
我不确定应该如何为 python-constraint 定义这个约束:每个驱动程序只有一个最短距离值。我应该为此使用 lambda 函数吗?
编辑
我尝试实现它的 lambda 版本,但是我似乎没有降低 lambda 语法。我到处寻找,但似乎找不到这有什么问题。基本上我替换了最后一段代码(添加约束以限制 getRouteDistance(driver) 的值),而是把它:
for driver in driver_set:
self.problem.addConstraint(lambda d: self.getRouteDistance(d) <= float(MAX_DISTANCE), driver)
但后来我得到了这个错误(注意它不是从我编辑的行中调用的,它来自之后的问题.getSolutions()):
File "allocation.py", line 130, in buildProblem
for solution in self.problem.getSolutions():
File "/Users/wadben/Documents/Dev/Python/sp-allocation/constraint.py", line 236, in getSolutions
return self._solver.getSolutions(domains, constraints, vconstraints)
File "/Users/wadben/Documents/Dev/Python/sp-allocation/constraint.py", line 529, in getSolutions
return list(self.getSolutionIter(domains, constraints, vconstraints))
File "/Users/wadben/Documents/Dev/Python/sp-allocation/constraint.py", line 506, in getSolutionIter
pushdomains):
File "/Users/wadben/Documents/Dev/Python/sp-allocation/constraint.py", line 939, in __call__
self.forwardCheck(variables, domains, assignments)))
File "/Users/wadben/Documents/Dev/Python/sp-allocation/constraint.py", line 891, in forwardCheck
if not self(variables, domains, assignments):
File "/Users/wadben/Documents/Dev/Python/sp-allocation/constraint.py", line 940, in __call__
return self._func(*parms)
TypeError: <lambda>() takes exactly 1 argument (3 given)
有没有其他人试图做这样的事情?我不明白为什么约束库不允许这样做。