本情境使用簡單的費用參數,針對指派給車輛的停靠站順序進行最佳化。這是最簡單的「路線最佳化」作業模式,可確保您在指定時間範圍內造訪所有停靠站。
下例說明包含一輛車和三件出貨的基本情境,且這些車輛都從單一地點 (稱為「平台」) 發出。
查看要求範例
{ "populatePolylines": true, "populateTransitionPolylines": true, "model": { "globalStartTime": "2023-01-13T16:00:00-08:00", "globalEndTime": "2023-01-14T16:00:00-08:00", "shipments": [ { "deliveries": [ { "arrivalLocation": { "latitude": 37.789456, "longitude": -122.390192 }, "duration": "250s" } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ] }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.789116, "longitude": -122.395080 }, "duration": "250s" } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ] }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.795242, "longitude": -122.399347 }, "duration": "250s" } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ] } ], "vehicles": [ { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerKilometer": 10.0, "costPerHour": 40.0 } ] } }
路線最佳化要求欄位
如總覽中所述,最重要的「路線最佳化」要求屬性為 vehicles
和 shipments
。
除了車輛和運送資訊外,要求還包含下列欄位:
折線
populatePolylines
和 populateTransitionPolylines
可指定路線最佳化是否應傳回折線。
這項服務會使用 Maps JS 折線轉碼器對折線編碼,後者會使用可列印的 ASCII 字元代表二進位折線資料。您可以使用互動式折線編碼器公用程式,以視覺化的方式呈現路線最佳化計算的路徑。本指南中的範例會將 populatePolylines
和 populateTransitionPolylines
設為 true,但其他指南則將其設為 false,以減少回應大小。
如需編碼格式的說明,請參閱編碼折線演算法格式。
全域時間限制
model.globalStartTime
和 model.globalEndTime
可設為任意 24 小時期間。這會讓輸出時間戳記更容易解讀。
造訪地點
要求範例只使用 model.shipments[].pickups[].arrivalLocation
和 model.shipments[].deliveries[].arrivalLocation
。此外,車輛從不同地點離開不同點的情況下,也有 departureLocation
屬性,例如建築物一側有入口的停車場,然後在另一側下車。在本章節和後續指南中,我們假設抵達和出發點都相同。
抵達和出發 waypoint
也可做為 latLng
的替代方案。Waypoint
欄位支援使用 Google 地點 ID 做為 LatLng
的替代方案,而且也能指定車輛標題。詳情請參閱參考說明文件 (REST、gRPC)。
範例中的限制
此情況會以下列方式限制最佳化工具:
- 所有活動都必須在全域的開始和結束時間之間完成。在這種情況下,由於運輸的距離和全球時間範圍非常接近,開始和結束時間就是非常寬鬆的限制。
- 所有出貨作業都必須完成。如未在
shipments
中指定罰款,則此為預設行為。 - 車輛已設定「
costPerKilometer
」和「costPerHour
」。
您可以在費用模式參數中解決費用。
路線最佳化回應屬性
查看要求範例的回應
{ "routes": [ { "vehicleStartTime": "2023-01-14T00:00:00Z", "vehicleEndTime": "2023-01-14T00:36:41Z", "visits": [ { "shipmentIndex": 2, "isPickup": true, "startTime": "2023-01-14T00:00:00Z", "detour": "0s" }, { "shipmentIndex": 1, "isPickup": true, "startTime": "2023-01-14T00:02:30Z", "detour": "150s" }, { "isPickup": true, "startTime": "2023-01-14T00:05:00Z", "detour": "300s" }, { "startTime": "2023-01-14T00:11:25Z", "detour": "0s" }, { "shipmentIndex": 1, "startTime": "2023-01-14T00:19:29Z", "detour": "503s" }, { "shipmentIndex": 2, "startTime": "2023-01-14T00:29:02Z", "detour": "1324s" } ], "transitions": [ { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-14T00:00:00Z", "routePolyline": {} }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-14T00:02:30Z", "routePolyline": {} }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-14T00:05:00Z", "routePolyline": {} }, { "travelDuration": "235s", "travelDistanceMeters": 795, "waitDuration": "0s", "totalDuration": "235s", "startTime": "2023-01-14T00:07:30Z", "routePolyline": { "points": "kvteFtfjVAA?C?C@C?A?C@AFMj@s@JKb@k@Zc@LSjA}ARWDGdAxAdAvAXa@@k@AsA\\c@FKp@_A\\c@Ze@fA{ALSFGd@o@rAgBB{BZc@" } }, { "travelDuration": "234s", "travelDistanceMeters": 793, "waitDuration": "0s", "totalDuration": "234s", "startTime": "2023-01-14T00:15:35Z", "routePolyline": { "points": "cwseFti_jVRWj@w@x@eAHLNRHJbApAHLX\\V^?@hA~AT\\PVFFDHDFJNp@~@NRLNNTFFUZIJY^Y^g@p@[`@KP{@fAEFSXe@l@c@h@WZY\\?BELk@v@MNa@l@" } }, { "travelDuration": "323s", "travelDistanceMeters": 1204, "waitDuration": "0s", "totalDuration": "323s", "startTime": "2023-01-14T00:23:39Z", "routePolyline": { "points": "cuseFhjVSTY`@Yb@GHEDIJEF]f@IJi@r@oAbBeCfDKLaApAKNQVIPKPCDQJIBIBM@iAJeALqBVC@C?A?QBYDI@C?_@Dc@FO@a@FDp@HfAHvABVDl@Dj@PpCQDiALsALAQASKwAOgBEe@COCYEa@Es@Eg@" } }, { "travelDuration": "209s", "travelDistanceMeters": 665, "waitDuration": "0s", "totalDuration": "209s", "startTime": "2023-01-14T00:33:12Z", "routePolyline": { "points": "{zteFxbajV?CAYEc@AMC_@AOAK?E?CCWAOAKCe@CY?WScDEm@d@EFA\\ENCB?XEVC^E`@EhBUVCNEB?@?\\Er@IMUe@k@k@w@AAMQa@i@SWQWMQi@u@AC?A" } } ], "routePolyline": { "points": "kvteFtfjVAA?C?C@C?A?C@AFMj@s@JKb@k@Zc@LSjA}ARWDGdAxAdAvAXa@@k@AsA\\c@FKp@_A\\c@Ze@fA{ALSFGd@o@rAgBB{BZc@RWj@w@x@eAHLNRHJbApAHLX\\V^?@hA~AT\\PVFFDHDFJNp@~@NRLNNTFFUZIJY^Y^g@p@[@KP{@fAEFSXe@l@c@h@WZY\\?BELk@v@MNa@l@STY@Yb@GHEDIJEF]f@IJi@r@oAbBeCfDKLaApAKNQVIPKPCDQJIBIBM@iAJeALqBVC@C?A?QBYDI@C?_@Dc@FO@a@FDp@HfAHvABVDl@Dj@PpCQDiALsALAQASKwAOgBEe@COCYEa@Es@Eg@?CAYEc@AMC_@AOAK?E?CCWAOAKCe@CY?WScDEm@d@EFA\\ENCB?XEVC^E`@EhBUVCNEB?@?\\Er@IMUe@k@k@w@AAMQa@i@SWQWMQi@u@AC?A" }, "metrics": { "performedShipmentCount": 3, "travelDuration": "1001s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "1200s", "totalDuration": "2201s", "travelDistanceMeters": 3457 }, "travelSteps": [ { "duration": "0s", "routePolyline": {} }, { "duration": "0s", "routePolyline": {} }, { "duration": "0s", "routePolyline": {} }, { "duration": "227s", "distanceMeters": 794, "routePolyline": { "points": "kvteFtfjVAA?C?C@C?A?C@AFMj@s@JKb@k@Zc@LSjA}ARWDGdAxAdAvAXa@@k@AsA\\c@FKp@_A\\c@Ze@fA{ALSFGd@o@rAgBB{BZc@" } }, { "duration": "233s", "distanceMeters": 791, "routePolyline": { "points": "cwseFti_jVRWj@w@x@eAHLNRHJbApAHLX\\V^?@hA~AT\\PVFFDHDFJNp@~@NRLNNTFFUZIJY^Y^g@p@[`@KP{@fAEFSXe@l@c@h@WZY\\?BELk@v@MNa@l@" } }, { "duration": "322s", "distanceMeters": 1205, "routePolyline": { "points": "cuseFhjVSTY`@Yb@GHEDIJEF]f@IJi@r@oAbBeCfDKLaApAKNQVIPKPCDQJIBIBM@iAJeALqBVC@C?A?QBYDI@C?_@Dc@FO@a@FDp@HfAHvABVDl@Dj@PpCQDiALsALAQASKwAOgBEe@COCYEa@Es@Eg@" } }, { "duration": "208s", "distanceMeters": 666, "routePolyline": { "points": "{zteFxbajV?CAYEc@AMC_@AOAK?E?CCWAOAKCe@CY?WScDEm@d@EFA\\ENCB?XEVC^E`@EhBUVCNEB?@?\\Er@IMUe@k@k@w@AAMQa@i@SWQWMQi@u@AC?A" } } ], "vehicleDetour": "2201s", "routeCosts": { "model.vehicles.cost_per_hour": 24.455555555555556, "model.vehicles.cost_per_kilometer": 34.57 }, "routeTotalCost": 59.025555555555556 } ], "totalCost": 59.025555555555556, "metrics": { "aggregatedRouteMetrics": { "performedShipmentCount": 3, "travelDuration": "1001s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "1200s", "totalDuration": "2201s", "travelDistanceMeters": 3457 }, "usedVehicleCount": 1, "earliestVehicleStartTime": "2023-01-14T00:00:00Z", "latestVehicleEndTime": "2023-01-14T00:36:41Z", "totalCost": 59.025555555555556, "costs": { "model.vehicles.cost_per_kilometer": 34.57, "model.vehicles.cost_per_hour": 24.455555555555556 } } }
路線最佳化回應包含代表提議路線的頂層 routes
欄位,每輛車會有一條路線。由於本指南的要求範例僅指定一輛車,因此 routes
包含一則 ShipmentRoute
訊息。
ShipmentRoute
項資源
ShipmentRoute
訊息類型的兩個最重要的屬性是 visits
和 transitions
。
每個 Visit
都代表從其中一個要求訊息的 VisitRequest
完成上車或外送。系統會將到訪作業有效指派給車輛,由車輛在某個地點和時間完成。
每個 Transition
都代表從一個地點前往下一個地點的車輛。系統可以在車輛起點、造訪地點和車輛端點之間完成轉換。
如要重建車輛的完整路線,必須合併 ShipmentRoute
的 visits
和 transitions
。將欄位組合成車輛活動進展的組合如下所示:
request.vehicles[0].startLocation -> transitions[0] -> visits[0] ->
transitions[1] -> visits[1] -> transitions[2] -> ... -> visits[3] ->
transitions[4] -> request.vehicles[0].endLocation
ShipmentRoute
的 transitions
一律比 visits
多一個,因為車輛必須在路線起點和路線起點的首次造訪時,從最後一次造訪到路線終點的最終位置行駛。如果車輛缺少開始或結束地點,仍會有 transitions
比 visits
更多,因為首次或上次造訪的地點會分別做為車輛的起點或終點位置。
在這個範例中,前三次上車造訪在兩者的距離為零和持續時間的轉場,因為這三個取貨服務在要求中都共用相同的位置。
詳情請參閱 ShipmentRoute
參考說明文件 (REST、gRPC)。
簡易路線控點順序最佳化
如這個範例所示,路線最佳化模型會模擬造訪屬性的屬性,但沒有路線控點的概念或停靠站做為獨立實體。不過,您可以將停靠站或路線控點視為貨物,只使用一個 VisitRequest
做為上車或到貨。車輛仍必須指派 costPerHour
或 costPerKilometer
,才能讓最佳化器尋找最佳路線 (而不是尋找任何可行的路線)。