私は、ドライバー、潜在的な乗客、およびその場所に関するデータを取り込むシステムを作成し、いくつかの制約が与えられたドライバーで持ち上げることができる乗客の数を最適化しようとしています。私は 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 に対してどのように定義する必要があるかわかりません。各ドライバーには最短距離の値が 1 つしかありません。これにはラムダ関数を使用する必要がありますか?
編集
これのラムダバージョンを実装しようとしましたが、ラムダ構文がダウンしていないようです。私はいたるところを見てきましたが、これの何が問題なのかを見つけることができないようです。基本的に、コードの最後のスニペットを置き換え (getRouteDistance(driver) の値を制限するための制約を追加)、代わりに次のようにします。
for driver in driver_set:
self.problem.addConstraint(lambda d: self.getRouteDistance(d) <= float(MAX_DISTANCE), driver)
しかし、その後、このエラーが発生しました (編集した行から呼び出されたのではなく、後に続く problem.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)
他の誰かがこのようなことをしようとしましたか? 制約ライブラリがこれを許可しない理由がわかりません。