以前に解決した問題を再解決するシナリオでは (もちろん、いくつかの新しいデータを使用して)、一度与えられた車両の最初の割り当てを再割り当てすることは通常不可能です。ドライバーはすでに進行中であり、新しいソリューションでは次のことを考慮する必要があります。
- 仕事は彼のままでなければなりません(別の車両に割り当てることはできません)
- 彼に最初に割り当てられたアクティビティは、今後のソリューションでもそのままにしておく必要があります
簡単にするために、ここでは 1 台の車両のシナリオを使用し、2 番目の箇条書きのみを課そうとします (つまり、特定のアクティビティがソリューションの最初になるようにします)。
これは私が制約を定義した方法です:
new HardActivityConstraint()
{
@Override
public ConstraintsStatus fulfilled(JobInsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct,
double prevActDepTime)
{
String locationId = newAct.getLocation().getId();
// we want to make sure that any solution will have "C1" as its first activity
boolean activityShouldBeFirst = locationId.equals("C1");
boolean attemptingToInsertFirst = (prevAct instanceof Start);
if (activityShouldBeFirst && !attemptingToInsertFirst)
return ConstraintsStatus.NOT_FULFILLED_BREAK;
if (!activityShouldBeFirst && attemptingToInsertFirst)
return ConstraintsStatus.NOT_FULFILLED;
return ConstraintsStatus.FULFILLED;
}
}
これは私がアルゴリズムを構築する方法です:
VehicleRoutingAlgorithmBuilder vraBuilder;
vraBuilder = new VehicleRoutingAlgorithmBuilder(vrpProblem, "schrimpf.xml");
vraBuilder.addCoreConstraints();
vraBuilder.addDefaultCostCalculators();
StateManager stateManager = new StateManager(vrpProblem);
ConstraintManager constraintManager = new ConstraintManager(vrpProblem, stateManager);
constraintManager.addConstraint(new HardActivityConstraint() { ... }, Priority.HIGH);
vraBuilder.setStateAndConstraintManager(stateManager, constraintManager);
VehicleRoutingAlgorithm algorithm = vraBuilder.build();
結果は良くありません。割り当てられた 1 つのジョブ (必要なアクティビティを含むもの) のソリューションしか得られません。デバッグでは、ジョブ挿入の反復で、問題を完全に解決するように見える多くの実行可能なオプションが考慮されることは明らかですが、最終的には、アルゴリズムによって返される最適なソリューションには他のジョブが含まれていません。
更新:さらに驚くべきことは、5 台以上の車両を使用するシナリオで制約を使用すると、正常に機能することです (最悪の結果は 1 台の車両の場合です)。
必要に応じて、より多くの情報を喜んで添付します。
ありがとうザック