Questo scenario ottimizza l'ordine delle fermate assegnate a un veicolo con parametri di costo semplici. Questa è la modalità più semplice di operazione 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 denominata depot.
Visualizza una richiesta di esempio
{ "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 per la richiesta di ottimizzazione del percorso
Come indicato nella Panoramica, la più importante richiesta di ottimizzazione del percorso
sono vehicles
e shipments
.
Oltre a un veicolo e alle spedizioni, la richiesta include quanto segue campi:
Polilinee
populatePolylines
e populateTransitionPolylines
specificano se Route
L'ottimizzazione deve restituire le polilinee.
Il servizio codifica le polilinee utilizzando il codec polilinee Maps JS, che rappresenta
di dati di polilinee binarie utilizzando caratteri ASCII stampabili. Puoi utilizzare lo
Utility Polyline Encoder interattiva per visualizzare i percorsi calcolati
Ottimizzazione del percorso. L'esempio in questa guida imposta populatePolylines
e
populateTransitionPolylines
su true, ma altre guide li impostano su false per
ridurre le dimensioni della risposta.
Consulta Formato dell'algoritmo polilinea codificato per una descrizione della codifica formato.
Limiti di tempo globali
model.globalStartTime
e model.globalEndTime
sono impostati sul valore 24 arbitrario
ore. Ciò semplifica l'interpretazione dei timestamp di output.
Visita le sedi
La richiesta di esempio utilizza solo model.shipments[].pickups[].arrivalLocation
e
model.shipments[].deliveries[].arrivalLocation
. C'è anche un
Proprietà departureLocation
in situazioni in cui il veicolo parte da una
diverso da quello in cui arriva, come un parcheggio con un ingresso
da un lato dell'edificio e un'uscita su un altro. In questa e nei successivi
guide, si presume che i punti di arrivo e di partenza siano uguali.
Il giorno 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 specificare le intestazioni del veicolo. Consulta la documentazione di riferimento
(REST, gRPC) per ulteriori dettagli.
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, l'ora di inizio e l'ora di fine sono un vincolo molto permissivo data la vicinanza delle spedizioni e nell'ampia finestra temporale globale.
- Tutte le spedizioni devono essere completate. Questo è il comportamento predefinito quando
le penalità non sono specificate in data
shipments
. costPerKilometer
ecostPerHour
sono impostati sul veicolo.
I costi sono indicati 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 per l'ottimizzazione del 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
.
Ciascun Visit
rappresenta il completamento di un ritiro o di una consegna da uno degli
VisitRequest
dei messaggi di richiesta. Una visita è un lavoro assegnato efficacemente a
essere completato da un veicolo in un luogo e in un momento specifici.
Ciascun Transition
rappresenta il veicolo che si sposta da una località a
a questo punto. Le transizioni possono avvenire tra una coppia del punto di partenza del veicolo, una visita
posizione e punto di arrivo del veicolo.
Per ricostruire il percorso completo del veicolo, i visits
di ShipmentRoute
e
È necessario combinare transitions
. La combinazione di campi in una progressione
l'attività del veicolo è simile al 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 spostarsi dal luogo di partenza alla prima visita all'inizio
del percorso e dall'ultima visita alla sua posizione finale
percorso. Se il veicolo non ha una posizione di partenza o di arrivo, ne sarà comunque presente una.
più transitions
rispetto a visits
perché la località della prima o dell'ultima visita è
utilizzata rispettivamente come posizione di partenza o di arrivo del veicolo.
In questo esempio, le prime tre visite al ritiro presentano transizioni tra di loro con distanza e durata pari a zero, perché tutti e tre i pickup condividono la stessa posizione nella richiesta.
Per ulteriori dettagli, consulta la documentazione di riferimento di ShipmentRoute
(REST, gRPC).
Ottimizzazione dell'ordine dei waypoint semplice
Come illustrato in questo esempio, l'ottimizzazione del percorso modella le visite come proprietà
spedizioni e non ha una nozione di tappe o fermate come un
dell'oggetto. Tuttavia, è possibile rappresentare tappe o tappe come spedizioni.
con esattamente un VisitRequest
come ritiro o consegna. Il veicolo deve
ricevere un costPerHour
o costPerKilometer
affinché l'ottimizzatore trovi
percorso ottimale (invece di trovare qualsiasi percorso fattibile).