倉庫の容量制限 (Limiting capacity of the warehouse)
倉庫には容量に制限があることが多く、同時にサービスを提供するトラックの数に制限が必要です。このモデルは SWAT API によってサポートされており、cumulative limitation パラメータを使用してこの制約を強制できます。
ルート計画への影響:
車両ルーティング問題 (VRP) における累積制限は、特定の場所または特定の時間枠内で使用できるリソースの総数、または消費できるリソースの総量に対する制約を表します。これらの制限は、多くの場合、デポまたはその他のサービス場所に適用され、ルート計画とリソース割り当てに大きな影響を与える可能性があります。
累積制限 (Cumulative Limitations):
累積制限は、長期にわたるリソースの最大容量または使用量を定義します。VRP のコンテキストでは、これは多くの場合、倉庫で同時にサービスを提供できる車両の数を指します。たとえば、倉庫には積み込みドックの数が限られており、同時に積み込みまたは積み降ろしできる車両の数が制限される場合があります。その他の例は次のとおりです。
- 倉庫の容量: 倉庫には駐車スペースまたは積み込みベイの数が限られており、いつでも倉庫に存在できる車両の数が制限される場合があります。
- サービス容量: サービス場所には、サービス担当者または機器の数が限られており、同時にサービス を提供できる車両の数が制限される場合があります。
- リソースの可用性: 特定の種類の燃料や特殊なツールなどのリソースは数量が限られており、特定の時間枠内で使用できる車両の数が制限される場合があります。
例:
配送会社は、2つの積み込みドックしかない中央倉庫から運営されています。つまり、同時に2台のトラックしか積み込むことができません。同社は5台のトラックのフリートを持っており、次の注文を受け取ります。
- 注文 1: 倉庫での積み込みが必要です。
- 注文 2: 倉庫での積み込みが必要です。
- 注文 3: 倉庫での積み込みが必要です。
この例では、cumulative limitation を使用して、一定のサービス時間が設定された倉庫で同時にサービスを受ける車両の数を制限できます。Cumulative limitation は、リクエストの model_parameters に設定されます。
実装 (Implementation)
ノード、グループ、および対応するサービス時間は、model_parameters.cumulative_limitations 構成で設定する必要があります。
group と node_uids は、制限のあるグループ全体を構成するために使用される groups、または一部のノードのみの node_uids と同じ構成で一緒に使用できます。
このオプションが正しく機能するには、すべての車両に、部分ルートとして バインドされたタイプ vehicle_position のノードが1つ以下である必要があります。このノードは、ピックアップイベントのプレースホルダーです。partial_route に他のノードが含まれている場合、vehicle_position ノードはリストの最後にある必要があります。
ピックアップが発生する可能性のある時間間隔は、累積制限ノードの時間枠の交差(つまり、最大の共通間隔)によって識別されます。各サービス間隔の期間は depot_service_time です。nodes_uids オブジェクトのリストは、vehicle_position ノードの uid を保持する必要があります。スケジューラは、ピックアップ時間間隔をサービス間隔に分割し、各サービス間隔に対して max_cumulative_vehicles 個のピックアップノードを作成します。作成されたノードの uid は cumulative_ で始まります。これらすべてのノードはオプションですが、影響を受ける各車両にそのようなノードを1つだけ追加する必要があります。その後、スケジューラは partial_route から vehicle_position ノードを削除し、代わりに、サービス間隔ごとに車両ごとに1つずつ partial_route の直後にピックアップノードを挿入します。
各累積制限について、vehicle_position ノードは、グループで設定されている以外のいくつかのグループに属する場合があります。この場合、node[”groups”] 内の他のグループは、すべてのノードで等しくなければなりません。作成された pickup ノードは、cumulative_limitation.group を除く vehicle_position ノードからグループリストを継承します。
例えば:
cumulative_limitations = [{
"group": "CL1",
"node_uids": ["n3"],
"depot_service_time": 300,
"max_cumulative_vehicles": 3
}],
nodes: [
{"uid": "n1", groups = ["CL1", "group_a", "group_b"], <...>}, - valid
{"uid": "n2", groups = ["CL1", "group_b", "group_a"], <...>}, - valid
{"uid": "n3", groups = ["group_b", "group_a"], <...>}, - valid
{"uid": "n4", groups = ["CL1", "group_a", "group_Z"], <...>}, - NOT valid
{"uid": "n5", groups = ["group_a", "group_b", "group_Z"], <...>} - NOT valid
]
vehicle_position ノードの uid に関係なく、最終的な json で作成されたすべてのピックアップノードは cumulative_ で始まり、booking_uid も同様です。
ステートレス API からのレスポンスには、拒否された予約にすべての一時的な cumulative_ 予約が含まれます。
ピックアップノードは partial_route からルートの主要部分に移動されるため、フラグ zero_cost_if_only_partial_routes はそれらに適用されなくなります。
特別なケース (Special cases)
groups_order を使用した特別なケース cumulative_limitations。どちらの機能も groups を使用し、partial_route を変更します。競合を回避する方法は2つあります。
-
各車両で別々のピックアップノードと vehicle_position ノードを使用する:
- グループ名とその優先順位を使用して
groups_orderを作成します。 - 最も優先順位の高い
groups_orderのpickupノードを作成し、この最も優先順位の高いグループをこのノードのgroupsに追加します。 vehicle_positionノードを作成します。- ピックアップノードと
vehicle_positionをpartial_routeに追加します。vehicle_positionノードがリストの最後にあることを確認してください。
- グループ名とその優先順位を使用して
-
各車両でピックアップと
vehicle_positionに同じノードを使用する:- グループ名と優先順位を使用して
groups_orderを作成します。 vehicle_positionノードを作成し、最も優先順位の高いグループを割り当てます。vehicle_positionノード uid をcumulative_limitationsに追加します。vehicle_positionノード uid をpartial_routeに追加します。- 注: シミュレーション後のこのノードの
uid、booking_uid、およびnode_typeは上書きされます。
- グループ名と優先順位を使用して
例 (Example)
{
"model_parameters": {
"cumulative_limitations": [
{
"node_uids": ["10W_0_start"],
"depot_service_time": 100,
"max_cumulative_vehicles": 10
}
]
},
...
"vehicles": [
{
"agent_id": "10W_0",
"capacity": {
"CBCM": 21500000,
"WEIGHT": 11710,
},
"lat": 0,
"lon": 0,
"assigned_nodes": [
{
"uid": "10W_0_start",
"node_type": "vehicle_position",
"open_time_ts": "2022-02-18T16:00:00+00:00",
"close_time_ts": "2025-02-18T20:42:00+00:00",
"close_time_ts_dynamic": "2026-02-19T16:42:00+00:00",
"service_time": 0,
"lat": 11.975487,
"lon": 101.399407,
"stop_id": "depot",
"max_slack": null,
"demand": {
"CBCM": 0,
"WEIGHT": 0
},
"groups": [],
"trip_cost": 0
}
],
"partial_route": [
"10W_0_start",
],
"partial_route_end": [
"10W_0_end"
],
...
}
]
}
シミュレーション全体の上限 (Simulation-wide limit): max_departures_per_hour
ここまでの説明では、制約をノード単位で直接設定してきました。運用全体で「1 時間に出発できるトラックは N 台まで」という 1 つのルールを共有している場合は、Integration API のより簡単な方法を使えます。シミュレーションに logistics_api_settings.max_departures_per_hour を設定すれば、低レベルの制約へ自動的に変換されます。
値 N は、その実行に含まれるすべてのピックアップノードと vehicle_position ノードを対象とする 1 件の累積制限になります。
| 変換後のパラメータ | 値 |
|---|---|
max_cumulative_vehicles | 1 |
depot_service_time | 3600 / N |
同時に扱えるのは 1 台のみで、各サービス間隔は 3600 / N 秒です。したがって 1 時間にちょうど N 台が出発します。未設定のままにするか 0 を指定した場合、制限は一切適用されません。
{
"max_departures_per_hour": 12
}
上の例では depot_service_time が 300 秒、つまり 5 分ごとに 1 台の出発となります。
max_departures_per_hour と、運行拠点 の calculation_params に設定する拠点ごとの cumulative_limitation は併用できません。max_departures_per_hour が設定された実行に、独自の cumulative_limitation を持つ拠点(または拠点グループ)が含まれている場合、どちらかが優先されるのではなく最適化が失敗します。ルールが全体で共通ならシミュレーション全体の設定を、拠点ごとに条件が異なるなら拠点ごとの累積制限を使ってくださ い。
適用範囲について、さらに 2 点あります。
- この設定が適用されるのは最適化の実行のみです。手動編集の再計算に累積制限が渡されることはないため、編集によって最適化なら空けておいたはずのスロットに車両が入ることがあります。
- これは Stateful (Integration) API の設定です。最適化 (Stateless) API を直接呼び出す場合は、このページの前半で説明したとおり
model_parameters.cumulative_limitationsを自分で組み立ててください。
拠点スロットの割り当てタイミングの制御 (Controlling when depot slots are assigned)
cumulative_limitations を使うと、どの車両がどの荷役スロットを使うかを決める必要があります。既定では、この割り当ては経路計画と同時に行われます。つまり各車両のスロット割り当てが同じ最適化の一部になります。ほとんどのケースではこれで問題ありません。
車両数が非常に多い場合や拠点の待ち行列が長い場合、スロット割り当てのロジックが最適化全体を遅くしたり、経路計画全体の品質を下げたりすることがあります。cumulative_limitations_mode パラメータを使うと、スロット割り当てと経路計画を分離し、それぞれをより効果的に解けるようになります。
| モード | 動作 |
|---|---|
local_search | スロット割り当てを最初から経路最適化に含めます。 |
postprocessing | まずスロット制約なしで経路を計画し、その後の 2 段目で各車両を空いている最適なスロットに割り当てます。拠点が混み合う大規模なフリートに向いています。 |
既定でどちらになるかは、呼び出す API によって異なります。
- 最適化 (Stateless) API — フィールドを省略する(または
nullを指定する)とlocal_searchになります。 - Integration (Stateful) API — シミュレーションはデプロイごとの既定値で実行され、現在は
postprocessingです。特定のモードに依存する運用ではlogistics_api_settings.cumulative_limitations_modeを明示的に指定してください。
この設定が効くのは、累積制限が実際に適用されているときだけです(Stateless リクエストの model_parameters.cumulative_limitations、あるいは累積制限に変換される max_departures_per_hour や拠点ごとの制限)。制限がまったくない場合、この設定には効果がありません。