車両ごとの複数のピックアップを伴うミルクランの実装 (Implementation of milkruns with multiple pickups per vehicle)
ロジスティクスでは、ミルクラン
は、単一の車両が事前定義されたルートに沿って複数の停車地を作り、さまざまな場所で商品をピックアップまたはドロップオフする配達方法です。このアプローチは、出荷を統合し、輸送コストを削減し、複数の個別の配達の必要性を回避することで効率を向上させることを目的としています。Integration API は、さまざまな状況でミルクランをサポートするための複数の便利な機能を提供します。役立つ可能性のある特定の機能は次のとおりです。
- 日ごとに変動する可能性があるが、静的なルートセットまたは定期的なベースに役立つシミュレーションテンプレート内の周期的な予約、ルート、車両割り当てである運用に役立つ、スケジュールに基づいてシミュレーションの シミュレーション テンプレートを自動選択する機能
- 運用上の理由(ドライバーの病気、車両が利用できないなど)により、毎日のスケジュールを調整する機能
- その予約を実行するための最適な車両とシーケンスを特定するための即時最適化を伴うアドホック 予約 をシミュレーションに挿入する機能
- 車両と予約に運用ゾーンを割り当てる機能。これにより、特定の運用ゾーンに割り当てられた車両は、このゾーンの予約に割り当てられます。ゾーンは「タグ」として定義されます
- 計画の変更について利害関係者に通知する機能(テキストメッセージやその他の IM の送信など)
- 予約を他の時間枠または翌日に自動的に調整およびシフトする機能
- 既存の OMS、CRM、または ERP とフローを統合する機能
これらの機能のほとんどは完全に自動化できるため、必要な人的労力を最小限に抑えることができます。
ユースケース (Use case)
物流会社は、複数の運用ゾーンで運行する車両フリートを持っています。これらの車両は、事前に割り当てられた目的地全体で事前定義されたルートのセットを実行しており、これは日ごとに異なる場合がありますが、毎週繰り返されます。これらの目的地では、車両は商品をピックアップしてデポに配達します。 車両は、午前と午後の2つのシフトで運行しています。また、シフト時間とフリート構成は曜日によって異なり、ピックアップポイントの営業時間も毎日同じではありませんが、毎週繰り返されます。時折、このスケジュールが変更される場合があります(新しいピックアップ場所が追加されたり、古い場所が削除されたり、車両の稼働時間も長期的に変更される可能性があります)。 予約はクライアントによってピックアップ場所で作成され、SLA を満たしながら収集され、デポに配達されることが期待されています。
フリート内の各車両は、運行が許可されている特定のゾーンに割り当てられているため、ゾーンに割り当てられたピックアップ場所に対して作成された予約は、そのゾーンにサービスを提供する車両に割り当てられる必要があります。各ピックアップ場所は1つのゾーンにのみ属するこ とができ、同様に各車両は1つの運用ゾーンのみにサービスを提供できます。
シフト中、アドホックなピックアップ注文が表示される場合があり、車両はそれらを実行することが期待されているため、システムはそれを達成するための最も適切で効率的な方法を選択する必要があります。特定のシフトで予約に利用できる車両がない場合、予約は次のシフト(つまり、午前のシフトから午後のシフトへ)に移動する必要があります。午後のシフト中に配達できない場合は、予約をキャンセルする必要があります。システムがいずれかの段階で予約に対応できない場合は、利害関係者に通知を送信する必要があります。
予約、フリート構成、および営業時間を伴うピックアップ場所は、API を介してこのデータを SWAT システムと同期しているクライアントの ERP で管理され、配達証明、ETA、および予約のステータスを取得することも期待されています。
ユースケースの目標は、移動距離と必要な車両数を最小限に抑えながら、アドホック予約を動的に管理することで、ミルクランを最適化することです。
プロジェクトの設定 (Setting the project up)
シナリオを実現するには、いくつかの API を使用および構成する必要があります。次のガイドには、一度(プロジェクトのセットアップ中に)、まれに(フリート構成と ピックアップ場所の変更)、および毎日(通知、アドホック予約、配達証明、ETA の管理)実行する必要がある手順が含まれています。ワークフローの目標は、毎日必要なリクエストの数を最小限に抑え、構成のできるだけ多くをプロジェクトのセットアップにオフロードすることです。
プロジェクトによっては、SWAT チームがプロジェクトと初期テンプレートをセットアップしている場合がありますが、このガイドでは、すべての構成と実行の手順が API を介して行われることを前提としています。
JSON はデータのみの形式であり、コメントをサポートしていないため、以下の例のすべてのコメントは、ペイロードとして試すときに削除する必要があります。
ミルクランのシミュレーションを構成するための一般的なフローには、次の手順が含まれます。
- 頻繁に変更されない(例:月に1回)静的ピックアップ場所(荷受人マスター)を構成(またはインポート)する
- 静的ルート、車両フリート、および事前定義されたルート(ミルクラン)を含む複数のシミュレーションテンプレートを設定する
- 曜日に基づいて適用されるシミュレーションテンプレート を構成する(例:月曜日のシミュレーションテンプレートと、残りの週の別のテンプレート)。
- 車両制約(車両がサービスを提供できる場所のグループ)を構成する
- シミュレーションの初期最適化を実行して、ミルクランの最適なルートを確立する
- アドホック注文の予約のオンデマンド(リアルタイム)挿入を構成し、未配達の予約を後続のシフトに転送するように構成する
- フローをテストし、通知を設定する
ミルクランとテンプレートに関連付けられた静的データを表すデータモデル (Data model representing milk runs and static data associated with templates)
営業時間、場所、運用エリア間の関係を確立するために、いくつかの追加のデータモデルを一度使用して構成する必要があります。このデータは通常、顧客の ERP からインポートして維持する必要があります。
プロジェクトとシミュレーションの初期セットアップ (Initial Setup for Projects and Simulations)
プロジェクトのセットアップは、次の2つのステップで構成されます。
- プロジェクト自体の設定(ジオフェンス、場所を含む)
- ミルクランの運用場所(荷受人)の構成
- シミュレーションテンプレートの設定(定期的な期間ごとのテンプレート、たとえば月曜日、火曜日など)
- 車両と車両の制限ゾーンの設定
- ミルクランに追加される予約テンプレートの追加
- ミルクランの事前定義されたルートを確立するための初期最適化の実行
- アドホック注文と未割り当て予約のシフトをサポートするためのプロセッサの構成
ジオフェンスは、車両の運用エリアを定 義します。このシナリオでは、運用ゾーン全体を網羅する1つのジオフェンスを作成します。車両(この例ではジオフェンスではありません)間で運用ゾーンを分割するには、運用ゾーングループを使用します。
ミルクランの静的場所の作成(荷受人リスト) (Creating static locations for a milkrun (consignee list))
運用ゾーンは、広い意味での荷受人マスターを表します。これにより、プロジェクトレベルで事前定義された場所とその可用性時間枠(複数の時間枠がサポートされています)を追加のパラメータとともに指定できます。API 場所は場所グループにグループ化でき、これを使用して特定の車両のみへのアクセスを制限できます API。この制約を適用するには、車両特性を使用します。さらに、ジオフェンス制約を場所グループに追加できます。
場所運用グループを作成するには、次のリクエストを使用できます。
JSON ペイロードを見 る
POST /api/v2/operationslocationgroup
{
"code": "E99",
"geofence": null,
"project": "/api/v2/project/{{project_id}}"
}
このシナリオでは、会社は1つの中央デポと、定期的に訪問される複数のピックアップポイントでミルクランを運営しています。ピックアップ場所はめったに変更されないため、API のコンシューマーが毎日またはその他の運用ウィンドウでそれらを再作成する手間を省くために、テンプレートに追加されます。ミルクランを表すデータモデルは、これを容易にすることができます。プロジェクトモデルは、関連する時間枠と運用エリアを持つ場所のリスト(ピックアップまたはドロップオフポイントとして機能できます)を参照できます。
Project には、祝日のリストを持つことができる public_holidays プロパティもあります。時間枠ベースのテンプレートはこの祝日のリストを尊重しますが、これは運用時間枠オブジェクト内のフラグを使用して上書きできます。
プロジェクト内のすべての利用可能な場所をリクエストして表示するには。
GET <project_id>/api/v2/operationslocation/<project_id>
場所は API を介して作成でき、以下のリクエストを使用して場所に複数の時間枠を設定できます。
JSON ペイロードを見る
POST /api/v2/operationslocation
{
"address": "Some address",
"code": "12345",
"created_at": "2024-09-05T18:44:32.593694+00:00",
"data": {},
"external_id": "12345",
"group": "/api/v2/operationslocationgroup/5", //group this location belongs to
"h3": "0040062446533530004660",
"id": 11,
"modified_at": "2024-09-05T18:44:32.593717+00:00",
"name": "Test name",
"project":"/api/v2/project/<project_id>",
"point": {
"coordinates": [
100.0000,
10.000
],
"type": "Point"
},
"time_windows": [
{
"time_window": {
"resource_uri": "/api/v2/operationstimewindow/<time_window_id>"
}
}
]
}
複数の営業時間枠を持つ場所を作成するには、次のリクエストを使用できます。
JSON ペイロードを見る
POST /api/v2/operationslocationgroup
{
"address": " TAMPINES ST 111 #11-111",
"code": "A11",
"created_at": "2024-09-05T18:44:32.593694+00:00",
"data": {},
"external_id": "A111",
"group": "/api/v2/operationslocationgroup/26",
"modified_at": "2024-09-05T18:44:32.593717+00:00",
"name": "Main Location",
"project":"/api/v2/project/{{project_id}}",
"point": {
"coordinates": [
103.917644661626,
1.32892431398393
],
"type": "Point"
},
"time_windows": [
{
"time_window": {
"resource_uri": "/api/v2/operationstimewindow/1348"
}
}
]
}
このシナリオでは、会社にはデポに1つのドロップオフポイントがあり、定期的に訪問されるいくつかのピックアップポイント(つまり、ミルクラン運用)があります。ピックアップ場所はめったに変更されないため、これらの場所はテンプレートに追加され、API コンシューマーが毎日または他の運用ウィンドウ中にそれらを再作成する必要をなくします。ミルクランを表すデータモデルは、この目的に使用できます。
プロジェクトモデルは、関連する時間枠と運用エリアを持つ場所のリスト(ピックアップまたはドロップオフ場所として機能できます)を参 照できます。
Project には、祝日のリストを持つことができる public_holidays プロパティもあります。時間枠ベースのテンプレートはこの祝日のリストを尊重しますが、これは運用時間枠オブジェクト内のフラグを使用して上書きできます。時間枠の繰り返しは、iCal 形式で運用時間枠オブジェクトに設定できます。また、プロジェクトレベルで構成された祝日ルールを尊重または上書きすることも可能です。
JSON ペイロードを見る
POST /api/v2/operationstimewindow
{
"close_time_ts": "1900-01-01T13:00:00+00:00",
"name": "SOME DROP OFF - thursday Day Shift 1",
"open_time_ts": "1900-01-01T09:00:00+00:00",
"project": "/api/v2/project/{{project_id}}",
"public_holiday": false,
"recurrences": "DTSTART:20240905T184433Z\nRRULE:FREQ=DAILY;BYDAY=TH",
"strict": true
}
シミュレーションテンプレートの作成 (Creating simulation templates)
シミュレーションテンプレートには、次のようなミルクランを実行するために必要なすべてのデータが含まれています。
- 車両と車両の制約。
- 事前定義された 予約(および ノード)の形式の事前定義されたルートが、最適なシーケンスで車両に割り当てられます。予約とノードは、運用場所(荷受人リスト)から推測されます。
- 初期最適化中に適用される運用上の制約
シミュレーションテンプレートのこの状態を実現するには、次の手順に従う必要があります。
- 運用場所グループから予約(したがって、ノード)を作成する
- シミュレーションの車両とその制約を作成する
- 最適化を実行し、割り当てを事前定義されたミルクランとして保存する
選択した日時(つまり、曜日ごとに異なるテンプレートが自動的に作成される)の適切なテンプレートに基づく自動シミュレーション作成を反映するには、期間ごとに個別のテンプレート(つまり、月曜日、火曜日、水曜日など)を作成し、必要な設定と recurrence パラメータを構成する必要があります。
より簡単なシミュレーション設定のために、車両などのオブジェクトを複製するための追加の API を活用 できます。API
次の例では、単一のテンプレートを作成します。これは、各日(または、より詳細なテンプレートが必要な場合は他の期間)に適切な設定で繰り返す必要があります。recurrence フィールドに注意してください。これは、2024-09-29 まで毎週水曜日と木曜日に繰り返されるテンプレートを設定します。recurrence_priority フィールドは、シミュレーションのインスタンス化中に複数のテンプレートが使用可能な場合に、テンプレートの優先度を設定するために使用されます。また、simulation_mode が template として設定されていることにも注意してください。これは、このシミュレーションがテンプレートとして扱われることを意味します。API
JSON ペイロードを見る
POST /api/v2/simulation
{
"absolute_max_trip_duration": null,
"acceptable_waiting_time": 900,
"adjust_driver_breaks_enabled": true,
"algo_optimize_quantity": "total_time",
"algo_type": "dynamic",
"allow_jump": false,
"analytics_export_completed": false,
"avg_journey_time_difference": null,
"avg_planned_actual_journey_time_difference": null,
"avg_waiting_time": null,
"avg_waiting_time_difference": null,
"bacchus_id": "2b3dfa37-594b-4a56-bffa-446c68e21a7d",
"booking_end_time": null,
"booking_start_time": null,
"bookings_count": 0,
"completed_at": null,
"completed_bookings_count": 0,
"completed_fixed_route_trips_count": null,
"completed_odbs_trips_count": null,
"conversion_rate": 100.0,
"created_at": "2024-08-02T05:05:34.027934+00:00",
"data": {
"logistics_api_settings": {
"algo_optimize_quantity": "total_time",
"algorithm": "static",
"allow_upload_after_simulation_start_time": false,
"allow_vehicle_late": false,
"average_travel_duration_to_node": 1200,
"booking_penalty": 1000,
"cvb_fleetmin_iterations_limit": 3000000,
"cvb_fleetmin_solutions_limit": 30000,
"cvb_fleetmin_time_limit": 600,
"cvb_local_search_iterations_limit": 100000,
"first_solution_strategies": [
0
],
"geofence_definition_strategy": "by_dropoff",
"geofence_vehicle_allocation_strategy": "strict",
"group_crossing_penalty": 10000.0,
"guided_local_search_lambda_coefficient": 0.1,
"lifo_order_check_on_all_vehicles": true,
"lns_time_limit_ms": 1000,
"log_search": false,
"max_dropoff_slack": null,
"max_pickup_slack": null,
"max_possible_lateness": null,
"mutually_exclusive_groups": [],
"only_pdp": false,
"optimization_step": 1,
"path_equalizer_weight": 100,
"pipeline_type": "simple_one_stage",
"savings_neighbors_ratio": 1.0,
"should_set_max_slack_start_location_zero": true,
"solution_limit": 100000000,
"stateless_api_login": null,
"stateless_api_password": null,
"stateless_api_server": null,
"strictly_exclusive_groups": [],
"time_limit_ms": 30000,
"trip_cost": 0.0,
"use_all_local_search_operators": false,
"use_cvb_local_search_operator": false,
"use_depth_first_search": false,
"use_lifo_order_check": false,
"use_local_search_metaheuristic": false,
"use_local_search_operators": [],
"use_mixed_time_matrix": false,
"use_node_weights_cost": true,
"use_path_equalizer": false,
"use_tsp_opt": false,
"use_walking_time_to_reduce_time_windows": false,
"vehicle_amortized_linear_cost_factor": null,
"vehicle_amortized_quadratic_cost_factor": null,
"vehicle_cost": 1000.0,
"vehicle_late_penalty_coefficient": 10,
"waypoints_optimization_second_phase": false,
"waypoints_solution_limit": 1000
}
},
"dataset": "/api/v2/dataset/111",
"dataset_csv_filename": null,
"dataset_name": "Default dataset for project 111",
"dead_mileage": null,
"deleted": false,
"deployment_label": null,
"description": "",
"driver_prep_time": 300,
"dropoff_transit_stops": "/api/v2/transitstopset/111",
"enable_offer_messages_generation": true,
"enable_waypoints_cache": true,
"end_time": "2021-01-01T23:59:59+00:00",
"explicit_stops": null,
"fixed_route_filter_model": null,
"fixed_route_schedule": null,
"geofence_id": "17103da2-4f92-4a82-8a93-b9b85f1af652",
"geofence_name": "Default geofence for project testing",
"geofences_zones": [],
"high_priority_stops": null,
"in_service_mileage": null,
"is_processor_based": true,
"journey_duration_source": "constant",
"max_additional_journey_time": 900,
"max_additional_journey_time_percent": 0.0,
"max_advance_booking_window": 0,
"max_journey_time_difference": null,
"max_planned_actual_journey_time_difference": null,
"max_waiting_time": null,
"max_waiting_time_difference": null,
"max_walking_distance": 0.0,
"min_advance_booking_window": 0,
"min_driver_rest_time": 360,
"min_journey_time_difference": null,
"min_planned_actual_journey_time_difference": null,
"min_waiting_time": null,
"min_waiting_time_difference": null,
"mixed_fleet": true,
"modified_at": "2024-09-12T08:29:12.287791+00:00",
"name": "Default Monday Tuesday template simulation for project",
"no_offer_count": null,
"number_of_vehicles": 0,
"odbs_trip_duration": 5400,
"odbs_trips_per_vehicle_per_hour": null,
"offer_generation_enabled": false,
"order_tracking_enabled": true,
"percentage_driver_rest_time": 8.0,
"performance_tracker_enabled": true,
"pickup_transit_stops": "/api/v2/transitstopset/673",
"pricing": null,
"processors": [],
"project": "/api/v2/project/111",
"project_name": "Testing",
"recurrence": "RRULE:FREQ=WEEKLY;UNTIL=20240929T110000Z;BYDAY=WE,TH",
"recurrence_priority": 0,
"result": {
"empty": true
},
"revenue": null,
"road_network": "van",
"routing_profile": null,
"routing_settings": {},
"simulation_mode": "template",
"start_time": "2021-01-01T00:00:00+00:00",
"state": "created",
"template": null,
"total_cost": null,
"transfer_rate": null,
"used_vehicles_count": null,
"utilization_rate": null,
"vehicle_capacity": 40,
"vehicle_ordering_in_one_by_one_stage": 1,
"walking_profile": null,
"walking_settings": {},
"write_events_log": true
}
応答には、作成されたシミュレーションオブジェクトが含まれます。
車両の追加 (Adding vehicles)
デフォルトのシミュレーションテンプレートは、運用の各日のシミュレーションを作成するために使用されるため、各シミュレーション用に複製される車両のリストを含めることもできます。次の例では、最小限の構成の車両が作成されます。このユースケースでは、車両に operations_locations_group を割り当てる必要があります。API
容量と車両特性がペイロードに含まれていることに注意してください。たとえば、車両モデル 4W の場合、その容量は 2000 任意の重量単位と 7000000 立方cm として定義されています。
車両の時間制約(その車両の稼働時間)を有効にするには、ペイロードに start_time と end_time を設定してください。車両がシミュレーションテンプレートからコピーされると、労働時間(日付ではない)のみがコピーされ、時間の日付部分は無視されます。
消費アプリケーションは、任意の <string><number> ペアの形式で容量のニーズを定義できます。予約が作成されると、オプティマイザーが容量ルーティング問題を解決するために、これと同じ容量名を使用する必要があります。
JSON ペイロードを見る
POST /api/v2/vehicle
{
"agent_id": "a69cf9fc-62a9-4585-8f5a-c82372438160",
"capacity": {
"bts": 1,
"cbcm": 10000000,
"weight": 3000
},
"characteristics": {
"ALL": true,
"Fridge": false,
"Helper": false,
"weight": 5
},
"color": "#FFFC66",
"end_time": "2024-01-15T13:55:00+00:00",
"geofence_ids": [
2035
],
"in_use": "enabled",
"labels": [
"10"
],
"project": "/api/v2/project/<project_id>",
"routing_engine_settings": {
"batch_matrix_size": 50,
"continue_straight": true,
"curb": false,
"key": "<your key>",
"make_depot_zero": true,
"osrme_timestamp_mode": "start_time",
"road_network": "driving_thailand",
"routing_engine_name": "osrme",
"speed": null,
"time_factor": 1,
"URL": "<routing engine URL>",
"use_speed_in_routing": false,
"vehicle_model": "4W Jumbo"
},
"service_number": "4w jumbo-1",
"simulation": "/api/v2/simulation/<simulation_id>",
"start_time": "2024-01-14T22:00:00+00:00",
"vehicle_cost": 25000,
"operations_location_groups": ["/api/v2/operationslocationgroup/<operations_group_id>"]
}
この記事のユースケースでは、異なる運用日に複数のシミュレーションテンプレートを使用するため、各 simulation_template を適切な車両で更新する必要があります。フリートが運用日ごとに変更されない場合、各 simulation_template には同じ車両セットが作成されている必要があります。
デフォルトのシミュレーションテンプレートまたはそのシミュレーションテンプレートに関連付けられた車両を更新しても、この変更の前に作成されたシミュレーションは遡及的に変更されないことに注意してください。
予約テンプレートの追加 (Adding booking templates)
シミュレーションテンプレートは、予約、ノード、および車両割り当てをキャプチャして、指定されたルートを効果的に表 すことができます。シミュレーションテンプレートと通常のシミュレーションの違いは、テンプレートから通常のシミュレーションが作成されると、テンプレートからすべての予約、ノード、および車両が継承されることです。これにより、テンプレートはミルクランの静的ルートを保持できます。 予約をアップロードするには、通常の予約手順を適用できます。この場合、予約は、ある運用場所でのピックアップとデポでのドロップオフを表します。作成時に、運用場所の時間枠が予約の関連ノードに適用されます。API
ペイロードで提供される容量と車両特性に注意してください。たとえば、車両モデル 4W の容量は、2,000の任意の重量単位と7,000,000立方センチメートルとして定義されています。消費アプリケーションは、任意の <string><number> ペアの形式で必要な容量を指定できます。予約が作成されると、オプティマイザーはこれらの容量名を使用して、容量ルーティング問題を解決します 。
このユースケースでは、以下を使用してアップロードを行う必要があります。
POST /api/v2/microservices/logisticsapi
JSON ペイロードを見る
POST /api/v2/microservices/logisticsapi
{
"calculation_uid": "e33e7240-96ba-4c4a-b958-f903eca9b422",
"simulation_id": 1,
"bookings": [
{
"uid": "a87fdfe8-29c6-4483-8fcd-49448362473d",
"dropoff_postal_code": "2",
"dropoff_location_name": "Dropoff name",
"dropoff_location_lat": 13.8353723,
"dropoff_location_lon": 100.5732801,
"pickup_operations_location":"/api/v2/operationslocation/25",
"min_pickup_time": "2021-08-17T08:59:10.073329+00:00",
"max_pickup_time": "2021-08-17T09:14:10.073329+00:00",
"min_dropoff_time": "2021-08-17T08:59:10.073329+00:00",
"max_dropoff_time": "2021-08-17T09:59:10.073329+00:00",
"demand": {
"volume": 1
},
"data": {
"some": "thing",
"number": 1
},
"pickup_service_time": 0,
"dropoff_service_time": 0,
"groups": []
}
],
"upload_strategy": "clear_all"
}
リクエストは、システムに追加された注文(予約)IDのリストを返します。
車両への初期ルートの事前割り当て (Preassigning initial routes to vehicles)
前の手順が完了すると、シミュレーション(以降、シミュレーションテンプレートとして機能します)には、ミルクランの最適化されたルートを作成するために必要なすべてのデータが含まれます。繰り返しルールを適用して複数のシミュレーションを作成する場合は、個々のシミュレーションごとに最適化を実行する必要があります。API
最適化は optimize API を介して実行する必要があります。これにより、最適化を実行するタスクを含む必要なすべての処理ロジックが生成されます。タスクの一意の識別子は、このリクエストの応答本文で返されます。
最適化プロセスは、設定、予約数、車両数によっては時間がかかる場合があります。したがって、最適化リクエストは非同期であり、コンシューマーはポーリング API を行い、最適化実行が完了するまで待つ必要があります。
POST /api/v2/microservices/logisticsapi_optimize
JSON ペイロードを見る
POST /api/v2/microservices/logisticsapi
{
"calculation_uid": <arbitrary unique identifier for the calculation>,
"simulation_id": <simulation id created previously>,
"bookings": [],
"booking_uids": <bookings identifiers to be used for optimization from upload bookings request>
}
最適化の実行後、シミュレーションは、現場で実行できるすべての必要なデータ要素とともに、車両へのノードの割り当て(つまり、ルート)を生成します。ただし、ミルクランの状況では、これらの事前に生成されたルートが毎日(または他の繰り返しで)実行され、各操作スロットに最適化が必要ないという考え方があります。これを実現するために、ルートが含まれるシミュレーションを変換して、適用可能な繰り返しルールを持つテンプレートにすることができ、各操作をテンプレートからインスタンス化できるようになります。
PATCH /api/v2/simulation/<simulation_id>
JSON ペイロードを見る
PATCH /api/v2/simulation/<simulation_id>
{
"simulation_mode":"template",
"recurrence":"RRULE:FREQ=WEEKLY;UNTIL=20240929T110000Z;BYDAY=WE,TH"
}
プロジェクトには複数のシミュレーションテンプレートを含めること ができ、それぞれに繰り返しルールがあり、そのルールに基づいて特定の時間または日のシミュレーションを自動的に生成する柔軟性があります。選択した時間または日付に複数のテンプレートが利用可能な場合、recurrence_priority フィールドを使用して、優先度が最も高いシミュレーションを選択します。
アドホック注文のサポート (Supporting ad-hoc orders)
デフォルトでは、ロジスティクスアプリケーションは注文のアドホックなリアルタイム追加をサポートしておらず、ルートの自動再最適化もサポートしていません。ただし、処理エンジンの特定の構成を使用すると、注文の自動再最適化を実現できます。上記 で説明したように、processor と呼ばれるエンティティを使用して、シミュレーションの最適化を実行します。各シミュレーションには、データを分割したり、異なるパラメータセットで最適化を実行したり、特定のフリートのみを最適化したりするために使用できる複数のプロセッサを関連付けることができます。API
プロセッサがテンプレートであるシミュレーションに添付されている場合、プロセッサはそのテンプレ ートから作成されたシミュレーションのインスタンスにもコピーされ、処理ワークフローの設定の複雑さが軽減されます。
ユースケース によると、注文を自動的に処理する必要があるケースは2つあります。
- 運用中にアドホック注文が到着し、可能であれば車両に割り当てる必要がある
- 未割り当ての注文、またはピックアップに失敗した注文は、ドライバーの次のシフトに自動的に割り当てる必要がある
注文の自動挿入 (Automatic insertion of orders)
注文の自動挿入は、continuous タイプのプロセッサを作成することで実現されます。これは、継続的に実行され、設定されたルールに基づいて新しいオブジェクトが変更または表示されるのを待つことを意味します。また、指定された時間の境界内でも実行されます。シミュレーション用にこのようなプロセッサを作成するには(これはシミュレーションテンプレートまたは実際のシミュレーションで行うことができます。この場合、テンプレート用に作成することを検討します)、次のリクエストを実行します。
POST /api/v2/simulationprocessor
JSON ペイロードを見る
POST /api/v2/simulationprocessor
// clean up existing processors first, and remove the from the template
{
"bookings_filter_expression": {
"state__in": [
// Prepared bookings are bookings that have just been uploaded, have their nodes created, and are ready for optimization
"prepared"
]
},
"calculation_parameters_logistics": "/api/v2/logisticscalculationparameters/43859",
"calculation_parameters_regenerator": {},
"fault_tolerant": false,
"geofences_zones": [],
"processor_lifecycle_type": "continuous",
"processor_type": "logistics",
// Simulation this processor should belong to
"simulation": "/api/v2/simulation/124868",
"vehicle_selectiSon_by_emptiness": false,
"vehicle_selection_in_service": false,
"vehicle_selection_in_use": true,
// Optionally, only specific vehicles can be chosen to allow for ad-hoc insertion, for example, vehicles with a specific label
"vehicles_filter_expression": {
"label__in": [
"adhoc"
]
},
//Timestamps should represent operations time bounds, for example for the first shift from 8 am to 11 am
"schedule_after": "2024-10-20T09:00:00+00:00",
"start_time": "2024-10-20T09:00:00+00:00",
"end_time": "2024-10-21T11:00:00+00:00",
"state":"new"
}
テンプレートに使用されていない、または不要なプロセッサがないことを確認し、それらを削除してください。プロセッサはシミュレーションがインスタンス化されると実行を開始し、予期しない結果を生み出す可能性があります。
この例では、プロセッサは、シミュレーションに prepared 状態の新しい予約が表示された場合にのみ、シミュレーションを実行します。プロセッサのアクティビティ時間は、start_time および end_time フィールドで設定されます。予約と同様に車両にフィルターを適用する必要がある場合は、ルール に従って vehicle_filter_expression を使用できます。このプロセッサはシミュレーションテンプレート用に作成されているため、開始されません。このテンプレートからシミュレーションのインスタンスが作成されたときにのみ開始されます。 すべての時間は、そのシミュレーションインスタンスの時間境界に合わせて調整されます。
シミュレーションには、シフトごとに1つずつ、複数のプロセッサを生成できます。最適化中、プロセッサは現在の車両位置と、シミュレーションですでに満たされている注文を考慮します。ただし、注文を割り当てる実際の能力は、プロセッサがすべての制約を満たすかどうかによって異なります。フリートに空き容量がない場合、新しい注文は未割り当てになる可能性があります。各シフトに1つの continuous プロセッサをスケジュールすることをお勧めします。
未割り当て注文の後続シフトへの再割り当ての自動化 (Automating reassignment of unassigned orders to the subsequent shift)
配達に失敗した注文、または未割り当ての注文を再割り当てするロジックを有効にするには、regenerator タイプのプロセッサを使用する必要があります。API 実行されると、フィルタリング基準を満たすすべての予約とノードが調整されます(したがって、このプロセッサは、目的の時間に正確に1回実行されるように single shot として構成する必要があります)。
Regenerator パイプラインは、booking_filter_expression 設定を満たすすべての bookings に対して次のルールを実行します。
Booking.stateをPREPAREDにリセットしますNode.stateをNEWにリセットしますNode.assigned_vehicleをNoneにリセットしますNode.scheduled_tsをNoneにリセットします- (オプション)
Booking.min_pickup_timeをprocessor.calculation_parameters_regenerator['min_pickup_time']にリセットします - (オプション)
Booking.max_pickup_timeをprocessor.calculation_parameters_regenerator['max_pickup_time']にリセットします - (オプション)
Booking.min_dropoff_timeをprocessor.calculation_parameters_regenerator['min_dropoff_time']にリセットします - (オプション)
Booking.max_dropoff_timeをprocessor.calculation_parameters_regenerator['max_dropoff_time']にリセットします - (オプション) (pickup)
Node.open_time_tsをprocessor.calculation_parameters_regenerator['min_pickup_time']にリセットします - (オプション) (pickup)
Node.close_time_tsをprocessor.calculation_parameters_regenerator['max_pickup_time']にリセットします - (オプション) (dropoff)
Node.open_time_tsをprocessor.calculation_parameters_regenerator['min_dropoff_time']にリセットします - (オプション) (dropoff)
Node.close_time_tsをprocessor.calculation_parameters_regenerator['max_dropoff_time']にリセットします
POST /api/v2/simulationprocessor
JSON ペイロードを見る
POST /api/v2/simulationprocessor
// clean up existing processors first, and remove the from the template
{
"bookings_filter_expression": {
"state__in": [
// Driver failed to pickup and order
"fail_to_board",
// There was not enough capacity to deliver the order
"rejected_by_system"
]
},
"calculation_parameters_logistics": "/api/v2/logisticscalculationparameters/43859",
"calculation_parameters_regenerator": {
// The nodes should be scheduled with this time slot within the next shift
// This is optional, if not set, original time windows of the node will be applied
"min_pickup_time": "2024-10-20T11:00:00+00:00",
"max_pickup_time": "2024-10-20T15:00:00+00:00",
"min_dropoff_time": "2024-10-20T16:00:00+00:00",
"max_dropoff_time": "2024-10-20T16:00:00+00:00",
},
"fault_tolerant": false,
"geofences_zones": [],
// Execute the processor just once
"processor_lifecycle_type": "one_shot",
"processor_type": "regenerator",
// Simulation this processor should belong to
"simulation": "/api/v2/simulation/124868",
"vehicle_selectiSon_by_emptiness": false,
"vehicle_selection_in_service": false,
"vehicle_selection_in_use": true,
"vehicles_filter_expression": {},
// Schedule right before next shift starts
"schedule_after": "2024-10-20T10:45:00+00:00",
"state":"new"
}
この例では、ノードの時間枠が変更され、初期の配達スケジュールから逸脱する可能性があります。ノードの時間枠が後続の配達シフトと重複している場合、またはノードに複数の時間枠がある場合、calculation_parameters_regenerator は必要ありません。このシナリオでは、元のノードの時間枠が保持されます。
シミュレーションには、シフトごとに regenerator タイプの複数のプロセッサを含めることができます。
毎日の運用 (Daily operations)
すべての構成が完了し、必要なシミュレーションテンプレートが作成されると、運用を計画するためのワークフローは、FMCG などの他のユースケースと同様になります。ただし、重要な違いがあります。テンプレートからシミュレーションが確立されると、車両にはすでにルートが事前に割り当てられており、シミュレーションにアップロードされた予約は追加(アドホック)のものとして扱われます。したがって、upload_strategy フラグが keep_assigned API に設定されていれば、既存の事前定義されたルートとともに自動的に最適化されます。予約はいつでもアップロードでき、利用可能なフリート容量に応じて、現在のシフトに追加するか、次のシフトにプッシュすることができます。一連の手順には次のものが含まれます。
1日の締めくくり (Wrapping up a day)
すべてのシフトがスケジュールされ、実行される regenerator タイプのプロセッサが残っていない場合、1日は終了します。シミュレーションの終了時間に、すべてのアクティブな continuous プロセッサが終了し、1日の完了を示します。