Questo scenario ottimizza l'ordine delle fermate assegnate a un veicolo con parametri di costo semplici. Questa è la modalità più semplice di ottimizzazione del percorso e garantisce che tutte le fermate vengano visitate entro il periodo di tempo specificato.
L'esempio seguente illustra uno scenario di base con un veicolo e tre spedizioni, tutte provenienti da un'unica sede chiamata depot.
Visualizza un esempio di richiesta
{ "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 } ] } }
Campi di richiesta di ottimizzazione del percorso
Come menzionato nella Panoramica, le proprietà più importanti delle richieste di ottimizzazione del percorso sono vehicles
e shipments
.
Oltre al veicolo e alle spedizioni, la richiesta include i seguenti campi:
Polilinee
populatePolylines
e populateTransitionPolylines
specificano se l'ottimizzazione
di percorso deve restituire polilinee.
Il servizio codifica le polilinee utilizzando il codec polilinea JS di Maps, che rappresenta i dati binari delle polilinee utilizzando caratteri ASCII stampabili. Puoi utilizzare l'utilità di codifica interattiva Polyline per visualizzare i percorsi calcolati dall'ottimizzazione delle route. L'esempio in questa guida imposta populatePolylines
e populateTransitionPolylines
su true, ma le altre guide li impostano su false per ridurre le dimensioni della risposta.
Per una descrizione del formato di codifica, consulta Formato algoritmo polilinea codificato.
Vincoli di tempo globali
model.globalStartTime
e model.globalEndTime
sono impostati su un periodo arbitrario di 24 ore. Ciò semplifica l'interpretazione dei timestamp di output.
Visita sedi
La richiesta di esempio utilizza solo model.shipments[].pickups[].arrivalLocation
e
model.shipments[].deliveries[].arrivalLocation
. Esiste anche una proprietà departureLocation
per le situazioni in cui il veicolo parte da un punto diverso da quello di arrivo, ad esempio un parcheggio con un ingresso su un lato dell'edificio e un'uscita su un altro. In questa guida e in quelle successive, si presume che i punti di arrivo e di partenza siano gli stessi.
Gli orari di arrivo e di partenza waypoint
sono disponibili anche in alternativa a latLng
.
I campi Waypoint
supportano l'utilizzo di ID luogo di Google in alternativa a LatLng
e possono anche specificare le intestazioni dei veicoli. Per ulteriori dettagli, consulta la documentazione di riferimento (REST, gRPC).
Vincoli nell'esempio
Questo scenario vincola l'ottimizzatore in diversi modi:
- Tutte le attività devono essere completate tra l'ora di inizio e l'ora di fine globali. In questo scenario, le ore di inizio e di fine sono un vincolo molto flessibili, data la vicinanza delle spedizioni e l'ampia finestra temporale globale.
- Tutte le spedizioni devono essere completate. Questo è il comportamento predefinito quando
i costi delle penali non vengono specificati su
shipments
. - Sul veicolo sono impostate
costPerKilometer
ecostPerHour
.
I costi vengono gestiti in Parametri del modello di costo.
Proprietà della risposta di ottimizzazione del percorso
Visualizza una risposta alla richiesta di esempio
{ "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 } } }
La risposta Ottimizzazione percorso include un campo routes
di primo livello che rappresenta i percorsi proposti, con un percorso per veicolo. Poiché la richiesta di esempio in questa guida specifica un solo veicolo, routes
include un messaggio ShipmentRoute
.
ShipmentRoute
strutture
Le due proprietà più importanti per il tipo di messaggio ShipmentRoute
sono
visits
e transitions
.
Ogni Visit
rappresenta il completamento di un ritiro o di una consegna da uno
dei VisitRequest
del messaggio di richiesta. Una visita è un lavoro che deve essere
completato da un veicolo in un determinato luogo e momento.
Ogni Transition
rappresenta il veicolo che viaggia da una località all'altra. Possono verificarsi transizioni tra una coppia di punto di partenza del veicolo, un luogo di visita e l'endpoint del veicolo.
Per ricostruire il percorso completo del veicolo, i visits
e
transitions
di ShipmentRoute
devono essere combinati. La combinazione di campi in una progressione
dell'attività del veicolo è simile alla seguente:
request.vehicles[0].startLocation -> transitions[0] -> visits[0] ->
transitions[1] -> visits[1] -> transitions[2] -> ... -> visits[3] ->
transitions[4] -> request.vehicles[0].endLocation
Un ShipmentRoute
ha sempre un transitions
in più rispetto a visits
, poiché
il veicolo deve viaggiare dalla posizione di partenza alla prima visita all'inizio
del percorso e dall'ultima visita a quella di arrivo alla fine
del percorso. Se il veicolo non ha una posizione di partenza o di arrivo, il numero sarà comunque pari a uno
in più di transitions
rispetto a visits
perché la località della prima o dell'ultima visita viene
utilizzata rispettivamente come posizione di partenza o di arrivo del veicolo.
In questo esempio, le prime tre visite di prelievo presentano transizioni tra loro senza distanza e durata perché tutti e tre i prelievi condividono la stessa località nella richiesta.
Per ulteriori dettagli, consulta la documentazione di riferimento di ShipmentRoute
(REST, gRPC).
Ottimizzazione semplice dell'ordine dei waypoint
Come dimostra questo esempio, Route Optimization modella le visite come proprietà delle spedizioni e non ha una nozione di waypoint o fermate come entità indipendente. Tuttavia, è possibile rappresentare fermate o waypoint come spedizioni
con esattamente un VisitRequest
come ritiro o consegna. Al veicolo deve comunque essere assegnato un costPerHour
o un costPerKilometer
affinché l'ottimizzatore possa trovare un percorso ottimale (anziché trovare un percorso fattibile).