私は OptaPlanner を初めて使用し、CVRPTW の問題を解決するために自分のプロジェクトで OptaPlanner を構成しようとしています。私の現在の構成は、プロジェクトのソース コードにある例と非常に似ていますが、私の要件は異なります。私のアプリケーションは、次の場合に継続的な配信リクエストを受け取ります。
- 平均サービス時間は 5 分です
- DueTime - ReadyTime = 10 分
- ロケーション間の平均距離 (時間) は約 2.5 分です。
- デポは1つだけ
私の考えは、新しいリクエストが受信されるたびに解決アルゴリズムを再実行することです。これは、リクエストが実行可能かどうか、または時間を前後にシフトする必要があるかどうかを理解するために必要です。次の問題ステートメントを検討するとします (場所は省略されていますが、デポの場所からかなり等距離です)。
CUST_ID READY_TIME DUE_TIME SERV_DUR DEMAND
1 12:45:00 12:55:00 00:05:00 1
2 12:35:00 12:45:00 00:05:00 8
3 12:25:00 12:35:00 00:05:00 5
4 13:25:00 13:35:00 00:05:00 5
利用可能な車両が 2 台あり、どちらも定員 10 名であることを考慮すると、次の解が得られます (各車両の時刻表)。
**Vehicle 1 Capacity 10 - delivery sequence starting from Depot [1]**
Cust[3] D: 5 Ar.T: 12:25:00 Ap.T: 12:23:08 Prev.D: 00:01:52 Next.D: 00:03:46
Cust[4] D: 5 Ar.T: 12:33:56 Ap.T: 12:30:00 Prev.D: 00:03:56 Next.D: --:--:--
**Vehicle 2 Capacity 10 - delivery sequence starting from Depot [1]**
Cust[2] D: 8 Ar.T: 12:35:00 Ap.T: 12:33:03 Prev.D: 00:01:57 Next.D: 00:03:05
Cust[1] D: 1 Ar.T: 12:42:47 Ap.T: 12:40:00 Prev.D: 00:02:47 Next.D: --:--:--
ここで、D は需要、Ar.T は到着時間、Ap.T は接近時間 (選択した場所に時間通りに到着するために前の場所を離れる必要がある時間)、Prev.D は前の場所からの距離 (時間) です。 Next.D は、次の場所からの距離 (時間) です。
ご覧のとおり、顧客 4 はあまりにも早く配達を受け取ります (到着時間は 12:33:56 ですが、準備時間は 13:25:00 です)。私は、 arrivalBeforeReadyTimeというルールが非常に柔軟な制約であることを理解していますが、プランナーは、予約済みの配送を使用して顧客 4 に配送することを提案することを期待しています。ルールarrivalBeforeReadyTimeを追加の厳しい制約として設定すると、ほとんどの場合、次の例外が発生します。
org.drools.core.RuntimeDroolsException: java.lang.NullPointerException
at org.drools.core.base.accumulators.SumAccumulateFunction.reverse(SumAccumulateFunction.java:85)
2 つの質問があります。
- 上記の例外が発生した場合、「未解決の問題」としてキャッチする必要がありますか? または、構成を調整する必要がありますか? もらってはいけないものですか?
- 継続的デリバリーのシナリオはどのように管理すればよいですか? 個別に解決するには、異なる大きな時間枠を定義する必要がありますか? しかし、これらのウィンドウの境界を定義する方法は? また、国境を越えて計画された配送をどのように管理するのでしょうか? (この解決策は私には正しくないようです)
編集1:
OptaPlanner のバージョンを 6.0.0.CR3 から 6.0.0.CR4-Pre1 に更新すると、NullPointerException が解決されました。ドキュメントはリアルタイム計画について明確であり、プランナーをリアルタイム モードで実行することをすでに検討していました。しかし、上記の例では結果が良くなかったので、その状況を管理するために他に何ができるかを理解しようとしていました. ルールarrivalBeforeReadyTimeをソフト制約からハード制約に切り替えたところ、NullPointerExceptionが発生せず、タイムスケジュールが適切に管理されているようで、結果は次のようになりました(例):
問題文:
CUSTID RTIME DTIME SERVDUR DEMAND
1 12:45:00 12:55:00 00:05:00 5
2 12:35:00 12:45:00 00:05:00 3
3 12:25:00 12:35:00 00:05:00 10
4 14:25:00 14:35:00 00:05:00 2
解決
**Vehicle 1 Capacity 10 - delivery sequence starting from Depot [1]**
Cust[3] D: 10 Ar.T: 12:25:00 Ap.T: 12:23:08 Prev.D: 00:01:52 Next.D: 00:02:26
Cust[2] D: 3 Ar.T: 12:32:26 Ap.T: 12:30:00 Prev.D: 00:02:26 Next.D: 00:03:05
Cust[1] D: 5 Ar.T: 12:42:47 Ap.T: 12:40:00 Prev.D: 00:02:47 Next.D: --:--:--
**Vehicle 2 Capacity 10 - delivery sequence starting from Depot [1]**
Cust[4] D: 2 Ar.T: 14:25:00 Ap.T: 14:22:53 Prev.D: 00:02:07 Next.D: --:--:--
ご覧のとおり、需要の合計が車両の容量を超えているため、最初の配送は実行できません。それが正しいと考えるべきですか?つまり、その場合の良い解決策は、両方の車両を使用して顧客を管理することです 1、2、3。vehicleCapacity を厳しい制約として、例と同じ構成を使用しています。さらに、ハード制約を使用している場合も、顧客 2 と 1 は準備時間の前に提供されます。