確定タイプ (Finalization Type)
確定タイプ は、最適なルートがすでに決定された 後 に、停留所の正確な予定時間を微調整する後処理命令です。
これは、ルート内の停留所の順序を変更 しません が、車両が 利用可能な時間枠内でノードに到着するようにスケジュールされる いつ を調整します。これにより、プランナーは、車両の待機時間を最小限に抑えたり、早期到着を優先したりするなど、好みを制御できます。
この設定は、finalization_type プロパティを使用してノードごとに適用されます。
確定タイプの仕組み (How Finalization Type Works)
最適化エンジンが車両の最も効率的な停留所シーケンスを見つけると、確定ステップは、次の2つの設定のいずれかに基づいて到着時間を調整します。
max: できるだけ遅くスケジュールします。 オプティマイザーは、予定到着時間をノードの時間枠内の可能な限り遅い瞬間にプッシュします。min: できるだけ早くスケジュールします。 オプティマイザーは、予定到着時間を可能な限り早い瞬間に設定します。
プランナーにとっての価値とルートへの影響 (Value for Planners and Impact on Routes)
finalization_type は、ルート自体の基本的な効率を変更することなく、特定のビジネス目標に合わせてルート実行を調整するための強力なツールをプランナーに提供します。
-
プランナーにとって:
- スラックの最小化:
maxは、コストのかかる車両とドライバーのアイドル時間を削減するための鍵です。それはより「ジャストインタイム」のスケジュールを作成します。 - 顧客サービスの向上:
minは、できるだけ早いサービスを希望する顧客の期待に応えるために使用できます。 - 運用の柔軟性: 停留所ごとにスケジュールをきめ細かく制御できます。
- スラックの最小化:
-
ルートへの影響:
- 停留所順序の変更なし: 車両が通る実際のパスは同じままです。
- スラックと到着時間の調整: その主な影響は、ルート内のスラックの再配分です。待機時間をある停留所から別の停留所にシフトしたり、前の停留所を遅くスケジュールすることで完全に排除したりできます。
具体的な例 (A Concrete Example)
2つのドロップオフ停留所を持つ単一の車両ルートを考えてみましょう。
- 停留所 A: 午前9時から午前10時までの時間枠。
- 停留所 B: 午前11時から午後12時までの時間枠。
オプティマイザーは、最適なルートは デポ -> 停留所 A -> 停留所 B であると判断します。
- デポから停留所 A までの移動時間は30分です。車両は午前8時30分にデポを出発します。
- 停留所 A への最も早い到着は午前9時です。
- 停留所 A でのサービスには15分かかります。
- 停留所 A から停留所 B までの移動は45分です。
シナリオ 1: 確定なし (デフォルトの動作)
- 停留所 A に到着: 午前9時。
- 停留所 A を出発: 午前9時15分。
- 停留所 B に到着: 午前10時。
- 停留所 B で待機: 60分(午前11時のウィンドウが開くまで)。これは車両のスラックです。
シナリオ 2: 停留所 A で finalization_type: "max"
- オプティマイザーは、停留所 B での60分のスラックを確認します。
- このスラックを最小限に抑えるために、停留所 A のスケジュールを遅くプッシュします。
- 停留所 A への新しい到着: 午前10時(そのウィンドウの終わり)。
- 停留所 A を出発: 午前10時15分。
- 停留所 B への新しい到着: 午前11時。
- 停留所 B で待機: 0分。スラックは、前の停留所に遅く到着することで吸収されました。
シナリオ 3: 停留所 A で finalization_type: "min"
- スケジュールはデフォルトの動作と同じになります。車両はできるだけ早く到着します。
- これは、停留所 A の顧客ができるだけ早い配達を希望する場合に役立ちます。
構成例 (Example Configuration)
node_scheduler リクエストの JSON スニペットを以下に示します。この例では、最初のドロップオフノードは、2番目の停留所の前の潜在的な待機時間を最小限に抑えるために max に設定されています。
{
"nodes": [
{
"uid": "f0de0001-2024-0731-88ad-05ddd46ce72d",
"booking_uid": "b00c0000-2024-0421-0616-000000000001",
"node_type": "dropoff",
"lat": 1.280097,
"lon": 103.889129,
"open_time_ts": "2026-01-01T09:00:00+00:00",
"close_time_ts": "2026-01-01T10:00:00+00:00",
"service_time": 360,
"demand": { "units": 10 },
"finalization_type": "max"
},
{
"uid": "f0de0001-2024-0731-88ad-05ddd46ce74d",
"booking_uid": "b00c0000-2024-0421-0616-000000000002",
"node_type": "dropoff",
"lat": 1.290097,
"lon": 103.989129,
"open_time_ts": "2026-01-01T11:00:00+00:00",
"close_time_ts": "2026-01-01T12:00:00+00:00",
"service_time": 360,
"demand": { "units": 10 }
}
// ... other nodes and vehicle configuration
]
}
プレイグラウンド (Playground)
以下のプレイグラウンドを使用して、確定タイプ の概念を試すことができます。この例は、間に時間差がある2つのドロップオフノードで設定されています。
- 最初のドロップオフノードの
finalization_typeを"max"に設定して、2番目のノードでのスラック時間をどのように短縮するかを確認してください。 - 次に、それを
"min"に変更して、車両ができるだけ早く到着し、次の停留所でより長く待機することを確認してください。
スラックコストとの相互作用 (Interaction with Slack Cost)
スラック(待機時間)に関するソルバーの動作は、選択した最適化目標と finalization_type に大きく依存します。
- 目標:
total_time: ソルバーは自然に合計時間を最小限に抑えることを目指しており、これは暗黙的にスラックを最小限に抑えます。ただし、finalization_typeを"min"(可能な限り早く)または"max"(可能な限り遅く)に設定すると、出発時間と到着時間が制限され、ソルバーが「エッジ」制約を満たすために不要なスラックを受け入れることを余儀なくされる可能性があります。 - 目標:
total_distance: このモードでは、ソルバーはマイレージのみを最適化します。スラックと期間は主要な要因ではないため、スラック最適化が無効になっている場合、不要なスラックが少なくなる可能性があります。ここでfinalization_typeが使用される場合、蓄積された待機時間に関係なくスケジュールのタイミングが決定され、かなりのアイドル期間が発生する可能性があります。
スラックを最小限に抑えることが重要であるが、特定の確定動作が必要な場合は、次の戦略を検討してください。
slack_cost_factorを調整する: スラックのコストを増やすと、ソルバーは待機時間を短縮するように促されます。ただし、スラックを最小限に抑えることは、接続をシームレスにするためにタイミングを時間枠の「中間」に配置することを奨励することが多く、これは"min"または"max"確定タイプの「エッジにプッシュ」動作と直接矛盾することに注意してください。- トレードオフを受け入れる: 確定動作を厳密に必要とする場合(例:「常に ASAP で到着」)、最適化目標に関係なく、スラックはその制約の必要な副産物であることを受け入れる必要がある場合があります。
以下の例は、スラック最適化を有効にした場合としない場合で、さまざまな finalization_type 動作を試すことができる、微調整された時間枠を備えています。これは、"path_constraints_mode": "logistics" および "slack_cost_factor": 1 パラメータによって制御されます。ドロップオフの確定タイプを調整する(たとえば、あるドロップオフノードには min を設定し、別のドロップオフノードには max を設定する)と、スラック最適化をオフにして、ルートに単独でどのように影響するかを観察することを検討してください。例では PDP モードを使用していますが、同じ原則が CVRPTW モードにも適用できます。