Este cenário otimiza a ordem das paradas atribuídas a um veículo com simples parâmetros de custo. Este é o modo mais simples de operação de otimização de trajetos e assegura que todas as paradas sejam visitadas dentro do período especificado.
O exemplo a seguir ilustra um cenário básico com um veículo e três envios, todos originados de um único local chamado depósito.
Ver um exemplo de solicitação
{ "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 } ] } }
Campos de solicitação da otimização de rotas
Como mencionado na Visão geral, as propriedades de solicitação mais importantes da otimização de rotas são vehicles
e shipments
.
Além de um veículo e remessas, a solicitação inclui o seguinte: :
Polilinhas
populatePolylines
e populateTransitionPolylines
especificam se o Routes
A otimização vai retornar polilinhas.
O serviço codifica as polilinhas usando o codec de polilinhas Maps JS, que representa
dados de polilinha binária usando caracteres ASCII para impressão. Você pode usar o Utilitário interativo de codificação de polilinhas para visualizar os caminhos calculados pela otimização de rotas. O exemplo neste guia define populatePolylines
e
populateTransitionPolylines
como "true", mas outros guias definem como "false" para
reduzir o tamanho da resposta.
Consulte Formato do algoritmo de polilinhas codificadas para ver uma descrição do .
Restrições de tempo globais
model.globalStartTime
e model.globalEndTime
são definidos como 24 arbitrários
período de horas. Isso facilita a interpretação dos carimbos de data/hora de saída.
Visitar locais
A solicitação de exemplo usa apenas model.shipments[].pickups[].arrivalLocation
e
model.shipments[].deliveries[].arrivalLocation
. Também há um
Propriedade departureLocation
para situações em que o veículo sai de um
um ponto diferente daquele em que ele chega, como um complexo de estacionamento com uma entrada
de um lado do prédio e uma saída em outro. Nesta e nas próximas
guias, presume-se que os pontos de chegada e partida sejam os mesmos.
As opções de chegada e partida (waypoint
) também são uma alternativa ao latLng
.
Os campos Waypoint
oferecem suporte ao uso de IDs de lugar do Google como uma alternativa a LatLng
e também podem especificar direções do veículo. Consulte a documentação de referência
(REST, gRPC) para mais detalhes.
Restrições no exemplo
Este cenário restringe o otimizador de várias maneiras:
- Todas as atividades precisam ser concluídas entre os horários globais de início e término. Nesse cenário, os horários de início e término são uma restrição muito flexível, considerando o perto das remessas e da ampla janela de tempo global.
- Todos os envios precisam ser concluídos. Esse é o comportamento padrão quando
custos de penalidade não são especificados em
shipments
. costPerKilometer
ecostPerHour
estão definidos no veículo.
Os custos são abordados em Parâmetros do modelo de custo.
Propriedades de resposta da Otimização de trajetos
Veja uma resposta ao exemplo de solicitação
{ "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 } } }
A resposta da otimização de rotas inclui um campo routes
de nível superior que
representa os trajetos propostos, com um trajeto por veículo. Como o exemplo
solicitação neste guia especifica apenas um veículo, routes
inclui um
ShipmentRoute
mensagem.
ShipmentRoute
propriedades
As duas propriedades mais importantes para o tipo de mensagem ShipmentRoute
são
visits
e transitions
.
Cada Visit
representa a conclusão de uma coleta ou entrega de um dos
VisitRequest
s da mensagem de solicitação. Uma visita recebe um trabalho
ser concluída por um veículo em algum lugar e horário.
Cada Transition
representa o veículo viajando de um local para o
a seguir. Podem ocorrer transições entre o ponto de partida do veículo, uma visita
a localização e o endpoint do veículo.
Para reconstruir o trajeto completo do veículo, o visits
e a ShipmentRoute
do veículo
transitions
precisa ser combinado. A combinação de campos em uma progressão de
a atividade do veículo é semelhante a esta:
request.vehicles[0].startLocation -> transitions[0] -> visits[0] ->
transitions[1] -> visits[1] -> transitions[2] -> ... -> visits[3] ->
transitions[4] -> request.vehicles[0].endLocation
Uma ShipmentRoute
sempre tem uma transitions
a mais do que visits
, já que a
veículo deve viajar do local de início até a primeira visita no início
do trajeto e da última visita até o local de término, no final do
trajeto. Se o veículo não tiver um local de partida ou de chegada, ainda haverá um
mais transitions
do que visits
porque o local da primeira ou da última visita é
usado como o local de partida ou chegada do veículo, respectivamente.
Neste exemplo, as três primeiras visitas de retirada têm transições entre elas com distância e duração zero, porque os três embarques compartilham o mesmo local na solicitação.
Consulte a documentação de referência de ShipmentRoute
(REST, gRPC) para saber mais
detalhes.
Otimização simples da ordem dos waypoints
Como este exemplo demonstra, a Otimização de trajetos modela as visitas como propriedades
fretes e não tem uma noção de waypoints ou paradas como um parâmetro
com uma entidade conhecida. No entanto, é possível representar paradas ou waypoints como remessas
com exatamente um VisitRequest
para retirada ou entrega. O veículo ainda precisa
receber um costPerHour
ou costPerKilometer
para que o otimizador encontre um
rota ideal (em vez de encontrar qualquer rota viável).