Optimisation de base des commandes stop pour les retraits et les livraisons

Ce scénario optimise l'ordre des arrêts attribués à un véhicule avec des paramètres de coût simples. Il s'agit du mode d'opération d'optimisation des routes le plus simple. garantit que tous les arrêts sont desservis dans les délais impartis.

L'exemple suivant illustre un scénario de base avec un véhicule et trois de livraison, qui proviennent toutes d'un même site appelé dépôt.

Voir un exemple de requête

      {
        "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
            }
          ]
        }
      }
    

Champs d'une requête d'optimisation des itinéraires

Comme indiqué dans la présentation, la requête d'optimisation d'itinéraire la plus importante sont vehicles et shipments.

Outre le véhicule et les livraisons, la demande inclut les éléments suivants : :

Polylignes

populatePolylines et populateTransitionPolylines spécifient si la route L'optimisation doit renvoyer des polylignes.

Le service encode les polylignes à l'aide du codec de polyligne Maps JS, qui représente des données de polylignes binaires à l’aide de caractères ASCII imprimables. Vous pouvez utiliser Interactive Polyline Encoder Usage (Utilitaire d'encodage interactif des polylignes) pour visualiser les chemins calculés par Optimisation des routes. L'exemple de ce guide définit populatePolylines et populateTransitionPolylines sur "true", mais d'autres guides les définissent sur "false" ; réduire la taille des réponses.

Pour obtenir une description de l'encodage, consultez l'article Format d'algorithme des polylignes encodées. .

Contraintes de temps globales

model.globalStartTime et model.globalEndTime sont définis sur une valeur arbitraire 24 d'une heure. Cela facilite l'interprétation des horodatages de sortie.

Visiter des lieux

L'exemple de requête n'utilise que model.shipments[].pickups[].arrivalLocation et model.shipments[].deliveries[].arrivalLocation Un Propriété departureLocation si le véhicule part d'une point d'arrivée différent de celui d'arrivée, par exemple un parking doté d'une entrée d'un côté du bâtiment et une sortie sur un autre. Dans cette section et les suivantes, les points d'arrivée et de départ sont supposés identiques.

Les waypoint d'arrivée et de départ existent également en remplacement de latLng. Les champs Waypoint acceptent l'utilisation des ID de lieu Google au lieu de LatLng, et des caps de véhicule. Consulter la documentation de référence (REST, gRPC) pour en savoir plus.

Contraintes de l'exemple

Ce scénario contraint l'optimiseur de plusieurs manières :

  1. Toute activité doit être effectuée entre les heures de début et de fin globales. Dans ce scénario, les heures de début et de fin sont une contrainte très souple compte tenu de la proximité des envois et de la large fenêtre temporelle globale.
  2. Tous les envois doivent être finalisés. Il s'agit du comportement par défaut les pénalités ne sont pas spécifiées dans shipments.
  3. costPerKilometer et costPerHour sont définis sur le véhicule.

Les coûts sont abordés dans la section Paramètres du modèle de coûts.

Propriétés de la réponse d'optimisation des routes

Afficher une réponse à l'exemple de requête

    {
      "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 réponse d'optimisation des routes inclut un champ routes de premier niveau qui représente les itinéraires proposés (un itinéraire par véhicule). Étant donné que l'exemple de requête de ce guide ne spécifie qu'un seul véhicule, routes inclut un message ShipmentRoute.

ShipmentRoute établissements

Les deux propriétés les plus importantes pour le type de message ShipmentRoute sont les suivantes : visits et transitions.

Chaque Visit représente la fin d'un retrait ou d'une livraison auprès de l'un des les VisitRequest du message de requête. Une visite se voit attribuer du travail à être effectuées par un véhicule à un endroit et à un moment précis.

Chaque Transition représente le véhicule circulant d'un endroit à un autre suivant. Des transitions peuvent se produire entre deux points de départ du véhicule, une visite l'emplacement et l'arrivée du véhicule.

Pour reconstituer l'itinéraire complet du ShipmentRoute visits et transitions doit être combiné. La combinaison de champs dans une progression de l'activité du véhicule se présente comme suit:

request.vehicles[0].startLocation -> transitions[0] -> visits[0] ->
transitions[1] -> visits[1] -> transitions[2] -> ... -> visits[3] ->
transitions[4] -> request.vehicles[0].endLocation

Un ShipmentRoute a toujours un transitions de plus que visits, car le le véhicule doit voyager de son point de départ à sa première visite au départ de l'itinéraire et de sa dernière visite à son point d'arrivée à la fin de la via un routage réseau. Si le véhicule n'a pas de lieu de départ ou d'arrivée, il y en aura tout de même plus de transitions que visits, car la localisation de la première ou de la dernière visite est sert respectivement de point de départ ou d'arrivée du véhicule.

Dans cet exemple, les trois premières visites de retrait sont associées à des transitions. avec une distance et une durée nulles, car les trois prises en charge partagent le même emplacement dans la requête.

Pour en savoir plus, consultez la documentation de référence sur ShipmentRoute (REST, gRPC) plus de détails.

Optimisation simple de l'ordre des points de cheminement

Comme le montre cet exemple, l'optimisation des routes modélise les visites en tant que propriétés et n'ont pas la notion de point de cheminement ou d'arrêt en tant que entité. Toutefois, il est possible de représenter des arrêts ou des points de repère en tant qu'envois avec exactement un VisitRequest en tant que ramassage ou livraison. Le véhicule doit toujours se voit attribuer un costPerHour ou un costPerKilometer pour que l'optimiseur trouve le meilleur itinéraire (plutôt que de trouver un itinéraire possible).