В этом руководстве показано, как количество транспортных средств, предоставляемых в решении по оптимизации маршрута, может меняться в зависимости от параметров запроса.
API оптимизации маршрута не только оптимизирует порядок выполнения отправлений, но также распределяет эти отправления по транспортным средствам, чтобы оптимизировать затраты в соответствии с ограничениями, которыми вы управляете.
В первом примере количество транспортных средств соответствует количеству поставок, при этом все транспортные средства имеют одинаковые свойства стоимости и местоположения. У каждого транспортного средства есть стоимость за час работы и стоимость за пройденный километр, что поможет минимизировать время и расстояние в пути. Можно было бы ожидать, что поставкам будут назначены несколько транспортных средств, но пример ответа показывает решение с наименьшей стоимостью при заданных параметрах модели затрат.
См. пример запроса с несколькими транспортными средствами.
{ "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" } ], "penaltyCost": 100.0 }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.789116, "longitude": -122.395080 }, "duration": "250s" } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 5.0 }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.795242, "longitude": -122.399347 }, "duration": "250s" } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 50.0 } ], "vehicles": [ { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerHour": 50.0, "costPerKilometer": 10.0 }, { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerHour": 50.0, "costPerKilometer": 10.0 }, { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerHour": 50.0, "costPerKilometer": 10.0 } ] } }
Посмотреть ответ на запрос с несколькими автомобилями
{ "routes": [ { "vehicleStartTime": "2023-01-14T00:00:00Z", "vehicleEndTime": "2023-01-14T00:28:22Z", "visits": [ { "isPickup": true, "startTime": "2023-01-14T00:00:00Z", "detour": "0s" }, { "shipmentIndex": 2, "isPickup": true, "startTime": "2023-01-14T00:02:30Z", "detour": "150s" }, { "startTime": "2023-01-14T00:08:55Z", "detour": "150s" }, { "shipmentIndex": 2, "startTime": "2023-01-14T00:21:21Z", "detour": "572s" } ], "transitions": [ { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-14T00:00:00Z" }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-14T00:02:30Z" }, { "travelDuration": "235s", "travelDistanceMeters": 795, "waitDuration": "0s", "totalDuration": "235s", "startTime": "2023-01-14T00:05:00Z" }, { "travelDuration": "496s", "travelDistanceMeters": 1893, "waitDuration": "0s", "totalDuration": "496s", "startTime": "2023-01-14T00:13:05Z" }, { "travelDuration": "171s", "travelDistanceMeters": 665, "waitDuration": "0s", "totalDuration": "171s", "startTime": "2023-01-14T00:25:31Z" } ], "metrics": { "performedShipmentCount": 2, "travelDuration": "902s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "800s", "totalDuration": "1702s", "travelDistanceMeters": 3353 }, "routeCosts": { "model.vehicles.cost_per_kilometer": 33.53, "model.vehicles.cost_per_hour": 23.638888888888889 }, "routeTotalCost": 57.168888888888887 }, { "vehicleIndex": 1 }, { "vehicleIndex": 2 } ], "skippedShipments": [ { "index": 1 } ], "metrics": { "aggregatedRouteMetrics": { "performedShipmentCount": 2, "travelDuration": "902s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "800s", "totalDuration": "1702s", "travelDistanceMeters": 3353 }, "usedVehicleCount": 1, "earliestVehicleStartTime": "2023-01-14T00:00:00Z", "latestVehicleEndTime": "2023-01-14T00:28:22Z", "totalCost": 62.168888888888887, "costs": { "model.vehicles.cost_per_hour": 23.638888888888889, "model.shipments.penalty_cost": 5, "model.vehicles.cost_per_kilometer": 33.53 } } }
Решающая программа назначает все поставки только одному транспортному средству, пропуская одну отправку, несмотря на достаточную доступность транспортных средств. Это связано с тем, что затраты на эксплуатацию дополнительных транспортных средств слишком высоки, чтобы их можно было оправдать, и для любого транспортного средства нерентабельно завершать пропущенную партию, учитывая низкую стоимость штрафов. Несмотря на наличие вместимости транспортных средств, одна машина может выполнить все порученные перевозки наиболее экономичным способом. Транспортные средства в запросе не имеют набора свойств usedIfRouteIsEmpty
(подробную информацию см. в документации по сообщениям Vehicle
( REST , gRPC )), поэтому они не несут никаких затрат, если не используются.
Изменение параметров затрат с целью отдать приоритет глобальным более коротким решениям, а не индивидуальным более коротким маршрутам транспортных средств, приводит к тому, что в решении участвует больше транспортных средств. В следующем примере запроса Vehicle.costPerHour
заменяется глобальным ShipmentModel.globalDurationCostPerHour
, отдавая приоритет решениям, которые в целом короче, по времени работы для любого данного транспортного средства. Стоимость штрафа за shipment[1]
также увеличена, чтобы снизить вероятность ее пропуска.
См. пример запроса с использованием globalDurationCostPerHour
{ "model": { "globalStartTime": "2023-01-13T16:00:00-08:00", "globalEndTime": "2023-01-14T16:00:00-08:00", "globalDurationCostPerHour": 150.0, "shipments": [ { "deliveries": [ { "arrivalLocation": { "latitude": 37.789456, "longitude": -122.390192 }, "duration": "250s" } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 100.0 }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.789116, "longitude": -122.395080 }, "duration": "250s" } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 75.0 }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.795242, "longitude": -122.399347 }, "duration": "250s" } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 50.0 } ], "vehicles": [ { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerKilometer": 10.0 }, { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerKilometer": 10.0 }, { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerKilometer": 10.0 } ] } }
Результат показывает, что использование глобального параметра стоимости часа приводит к использованию всех трех транспортных средств вместо одного.
Посмотрите ответ на запрос, используя globalDurationCostPerHour
{ "routes": [ { "vehicleStartTime": "2023-01-14T00:00:00Z", "vehicleEndTime": "2023-01-14T00:16:20Z", "visits": [ { "shipmentIndex": 2, "isPickup": true, "startTime": "2023-01-14T00:00:00Z", "detour": "0s" }, { "shipmentIndex": 2, "startTime": "2023-01-14T00:09:19Z", "detour": "0s" } ], "transitions": [ { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-14T00:00:00Z" }, { "travelDuration": "409s", "travelDistanceMeters": 1371, "waitDuration": "0s", "totalDuration": "409s", "startTime": "2023-01-14T00:02:30Z" }, { "travelDuration": "171s", "travelDistanceMeters": 665, "waitDuration": "0s", "totalDuration": "171s", "startTime": "2023-01-14T00:13:29Z" } ], "metrics": { "performedShipmentCount": 1, "travelDuration": "580s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "400s", "totalDuration": "980s", "travelDistanceMeters": 2036 }, "routeCosts": { "model.vehicles.cost_per_kilometer": 20.36 }, "routeTotalCost": 20.36 }, { "vehicleIndex": 1, "vehicleStartTime": "2023-01-14T00:00:00Z", "vehicleEndTime": "2023-01-14T00:18:54Z", "visits": [ { "shipmentIndex": 1, "isPickup": true, "startTime": "2023-01-14T00:00:00Z", "detour": "0s" }, { "shipmentIndex": 1, "startTime": "2023-01-14T00:08:24Z", "detour": "0s" } ], "transitions": [ { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-14T00:00:00Z" }, { "travelDuration": "354s", "travelDistanceMeters": 1192, "waitDuration": "0s", "totalDuration": "354s", "startTime": "2023-01-14T00:02:30Z" }, { "travelDuration": "380s", "travelDistanceMeters": 1190, "waitDuration": "0s", "totalDuration": "380s", "startTime": "2023-01-14T00:12:34Z" } ], "metrics": { "performedShipmentCount": 1, "travelDuration": "734s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "400s", "totalDuration": "1134s", "travelDistanceMeters": 2382 }, "routeCosts": { "model.vehicles.cost_per_kilometer": 23.82 }, "routeTotalCost": 23.82 }, { "vehicleIndex": 2, "vehicleStartTime": "2023-01-14T00:00:00Z", "vehicleEndTime": "2023-01-14T00:16:14Z", "visits": [ { "isPickup": true, "startTime": "2023-01-14T00:00:00Z", "detour": "0s" }, { "startTime": "2023-01-14T00:06:25Z", "detour": "0s" } ], "transitions": [ { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-14T00:00:00Z" }, { "travelDuration": "235s", "travelDistanceMeters": 795, "waitDuration": "0s", "totalDuration": "235s", "startTime": "2023-01-14T00:02:30Z" }, { "travelDuration": "339s", "travelDistanceMeters": 1276, "waitDuration": "0s", "totalDuration": "339s", "startTime": "2023-01-14T00:10:35Z" } ], "metrics": { "performedShipmentCount": 1, "travelDuration": "574s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "400s", "totalDuration": "974s", "travelDistanceMeters": 2071 }, "routeCosts": { "model.vehicles.cost_per_kilometer": 20.71 }, "routeTotalCost": 20.71 } ], "metrics": { "aggregatedRouteMetrics": { "performedShipmentCount": 3, "travelDuration": "1888s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "1200s", "totalDuration": "3088s", "travelDistanceMeters": 6489 }, "usedVehicleCount": 3, "earliestVehicleStartTime": "2023-01-14T00:00:00Z", "latestVehicleEndTime": "2023-01-14T00:18:54Z", "totalCost": 112.14, "costs": { "model.vehicles.cost_per_kilometer": 64.89, "model.global_duration_cost_per_hour": 47.25 } } }
В этом ответе все три транспортных средства используются (согласно metrics.usedVehicleCount
), причем каждому транспортному средству назначена одна отгрузка для завершения. Имея одинаковые начальные и конечные местоположения и costPerKilometer
, все три транспортных средства фактически взаимозаменяемы, поэтому не имеет значения, какая отгрузка какому транспортному средству назначена.
globalDurationCostPerHour
заставляет оптимизатор найти решение, которое в целом короче: разница между earliestVehicleStartTime
и latestVehicleEndTime
составляет всего 18 минут 54 секунды по сравнению с 28 минутами и 22 секундами в предыдущем ответе. Тем не менее, показатель metrics.costs.model.vehicles.cost_per_kilometer
увеличился, отражая увеличение общего расстояния, пройденного тремя подержанными автомобилями. Это демонстрирует один из способов, с помощью которого модель затрат позволяет вам идти на компромисс :
- Увеличение глобальных затрат времени: увеличьте использование транспортных средств, чтобы минимизировать общее время завершения за счет увеличения расстояния транспортного средства и времени, затрачиваемого на дорогу.
- Увеличение затрат времени на транспортное средство. Уменьшите использование транспортных средств и время, затрачиваемое на транспортировку, за счет более длительного общего решения.
Обратите внимание, что значение globalDurationCostPerHour
, равное 150,0, в этом примере устанавливается в три раза больше costPerHour
отдельных транспортных средств, равной 50,0 из предыдущего примера. Эта глобальная стоимость фактически предполагает, что все три транспортных средства будут работать одновременно, но в практических условиях такие предположения могут не отражать реальность и фактически могут оказать негативное влияние на качество результатов.
Как описано в разделе «Параметры модели затрат» , все параметры затрат выражаются в одних и тех же безразмерных единицах, но могут иметь совершенно разные значения. Как правило, значения параметров модели затрат должны быть максимально приближены к реальности, поскольку искусственные затраты, подобные тем, что показаны в этом примере, могут привести к оптимизации API для целей, которые не соответствуют вашим намерениям.