В этом примере показано, как использовать loadDemands и loadLimits для управления ограничениями вместимости транспортных средств в запросе к API оптимизации маршрута.
Для получения полного концептуального обзора см. документ «Основные понятия, касающиеся требований и ограничений к нагрузке» .
Пример запроса
Следующий пример демонстрирует сценарий, в котором одно транспортное средство с ограничением по грузоподъемности должно доставить три груза разного веса.
Данный пример запроса содержит следующие параметры, связанные с нагрузкой:
-
shipments[0]с требуемымamountгруза 50weightKg. -
shipments[1]с требуемымamountгруза 10weightKg. -
shipments[2]с требуемымamountгруза 80weightKg. -
vehicles[0]с пределом нагрузкиmaxLoad100weightKg.
См. пример запроса с указанием требуемой и предельной нагрузки.
{ "populatePolylines": false, "populateTransitionPolylines": false, "model": { "globalStartTime": "2023-01-13T16:00:00Z", "globalEndTime": "2023-01-14T16:00:00Z", "shipments": [ { "deliveries": [ { "arrivalLocation": { "latitude": 37.789456, "longitude": -122.390192 }, "duration": "250s" } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 100.0, "loadDemands": { "weightKg": { "amount": "50" } } }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.789116, "longitude": -122.395080 }, "duration": "250s" } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 15.0, "loadDemands": { "weightKg": { "amount": "10" } } }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.795242, "longitude": -122.399347 }, "duration": "250s" } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 50.0, "loadDemands": { "weightKg": { "amount": "80" } } } ], "vehicles": [ { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerHour": 40.0, "costPerKilometer": 10.0, "loadLimits": { "weightKg": { "maxLoad": "100" } } } ] } }
Пример ответа
В ответе отображается оптимизированный маршрут для транспортного средства. Поскольку общая загрузка всех грузов превышает грузоподъемность транспортного средства, оптимизатор создает последовательность погрузок и разгрузок, чтобы гарантировать соблюдение loadLimits .
См. ответ на запрос с указанием требуемой и предельной нагрузки.
{ "routes": [ { "vehicleStartTime": "2023-01-13T16:00:00Z", "vehicleEndTime": "2023-01-13T16:43:27Z", "visits": [ { "isPickup": true, "startTime": "2023-01-13T16:00:00Z", "detour": "0s", "loadDemands": { "weightKg": { "amount": "50" } } }, { "shipmentIndex": 1, "isPickup": true, "startTime": "2023-01-13T16:02:30Z", "detour": "150s", "loadDemands": { "weightKg": { "amount": "10" } } }, { "startTime": "2023-01-13T16:08:55Z", "detour": "150s", "loadDemands": { "weightKg": { "amount": "-50" } } }, { "shipmentIndex": 1, "startTime": "2023-01-13T16:16:37Z", "detour": "343s", "loadDemands": { "weightKg": { "amount": "-10" } } }, { "shipmentIndex": 2, "isPickup": true, "startTime": "2023-01-13T16:27:07Z", "detour": "1627s", "loadDemands": { "weightKg": { "amount": "80" } } }, { "shipmentIndex": 2, "startTime": "2023-01-13T16:36:26Z", "detour": "0s", "loadDemands": { "weightKg": { "amount": "-80" } } } ], "transitions": [ { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T16:00:00Z", "vehicleLoads": { "weightKg": {} } }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T16:02:30Z", "vehicleLoads": { "weightKg": { "amount": "50" } } }, { "travelDuration": "235s", "travelDistanceMeters": 795, "waitDuration": "0s", "totalDuration": "235s", "startTime": "2023-01-13T16:05:00Z", "vehicleLoads": { "weightKg": { "amount": "60" } } }, { "travelDuration": "212s", "travelDistanceMeters": 791, "waitDuration": "0s", "totalDuration": "212s", "startTime": "2023-01-13T16:13:05Z", "vehicleLoads": { "weightKg": { "amount": "10" } } }, { "travelDuration": "380s", "travelDistanceMeters": 1190, "waitDuration": "0s", "totalDuration": "380s", "startTime": "2023-01-13T16:20:47Z", "vehicleLoads": { "weightKg": {} } }, { "travelDuration": "409s", "travelDistanceMeters": 1371, "waitDuration": "0s", "totalDuration": "409s", "startTime": "2023-01-13T16:29:37Z", "vehicleLoads": { "weightKg": { "amount": "80" } } }, { "travelDuration": "171s", "travelDistanceMeters": 665, "waitDuration": "0s", "totalDuration": "171s", "startTime": "2023-01-13T16:40:36Z", "vehicleLoads": { "weightKg": {} } } ], "metrics": { "performedShipmentCount": 3, "travelDuration": "1407s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "1200s", "totalDuration": "2607s", "travelDistanceMeters": 4812, "maxLoads": { "weightKg": { "amount": "80" } } }, "routeCosts": { "model.vehicles.cost_per_kilometer": 48.12, "model.vehicles.cost_per_hour": 28.966666666666665 }, "routeTotalCost": 77.086666666666659 } ], "metrics": { "aggregatedRouteMetrics": { "performedShipmentCount": 3, "travelDuration": "1407s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "1200s", "totalDuration": "2607s", "travelDistanceMeters": 4812, "maxLoads": { "weightKg": { "amount": "80" } } }, "usedVehicleCount": 1, "earliestVehicleStartTime": "2023-01-13T16:00:00Z", "latestVehicleEndTime": "2023-01-13T16:43:27Z", "totalCost": 77.086666666666659, "costs": { "model.vehicles.cost_per_hour": 28.966666666666665, "model.vehicles.cost_per_kilometer": 48.12 } } }
Поскольку суммарная loadDemands трех грузов (50 + 10 + 80 = 140) превышает loadLimits транспортного средства (100), транспортное средство не может забрать все грузы одновременно. Оптимизатор рассматривает только маршруты, где shipment[0] и shipment[2] не находятся в транспортном средстве одновременно, поскольку именно эти грузы превышают допустимую нагрузку транспортного средства по сумме своих весов.
Маршрут включает следующие visits , чтобы не превысить допустимую нагрузку на транспортное средство:
-
shipment[0]забран -
shipment[1]забран -
shipment[0]доставлен -
shipment[1]доставлен -
shipment[2]забран -
shipment[2]доставлен
На протяжении всего маршрута груз транспортного средства меняется, что можно наблюдать в массиве transitions . Например, transitions[2] показывает, что транспортное средство перевозит груз weightKg после получения первых двух партий (50 + 10).
Свойство maxLoads в metrics показывает, что максимальная перевозимая нагрузка в любой точке маршрута составляла 80 weightKg , что подтверждает успешное соблюдение решения в пределах допустимой нагрузки транспортного средства в 100 weightKg .
Мягкие пределы нагрузки
В следующем примере показано, как использовать ограничение по мягкой нагрузке для оптимизации маршрута с несколькими транспортными средствами. Решение распределяет грузы между двумя транспортными средствами, чтобы избежать дополнительных затрат, связанных с превышением ограничения по мягкой нагрузке для каждого транспортного средства.
Пример запроса
В этот запрос теперь включены три поставки только с доставкой и два транспортных средства с одинаковыми параметрами loadLimits и softMaxLoad .
Ключевые параметры для этого примера:
- Три партии имеют суммарный
loadDemands140weightKg(50 кг).- 60 + 30).
- Доступны два транспортных средства с
softMaxLoad"100"weightKgиcostPerUnitAboveSoftMax5,0.
См. пример запроса с мягким ограничением нагрузки.
{ "populatePolylines": false, "populateTransitionPolylines": false, "model": { "globalStartTime": "2023-01-13T16:00:00Z", "globalEndTime": "2023-01-14T16:00:00Z", "shipments": [ { "deliveries": [ { "arrivalLocation": { "latitude": 37.789456, "longitude": -122.390192 }, "duration": "250s" } ], "loadDemands": { "weightKg": { "amount": "50" } } }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.789116, "longitude": -122.395080 }, "duration": "250s" } ], "loadDemands": { "weightKg": { "amount": "60" } } }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.795242, "longitude": -122.399347 }, "duration": "250s" } ], "loadDemands": { "weightKg": { "amount": "30" } } } ], "vehicles": [ { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerHour": 40.0, "costPerKilometer": 10.0, "loadLimits": { "weightKg": { "maxLoad": "150", "softMaxLoad": "100", "costPerUnitAboveSoftMax": 5.0 } } }, { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerHour": 40.0, "costPerKilometer": 10.0, "loadLimits": { "weightKg": { "maxLoad": "150", "softMaxLoad": "100", "costPerUnitAboveSoftMax": 5.0 } } } ] } }
Пример ответа
В ответе теперь содержатся два маршрута, по одному для каждого транспортного средства. Оптимизатор определяет, что использование обоих транспортных средств более экономически выгодно, чем использование одного транспортного средства и связанные с этим штрафы за превышение лимита трафика.
См. ответ на запрос с мягким ограничением нагрузки.
{ "routes": [ { "vehicleStartTime": "2023-01-13T16:00:00Z", "vehicleEndTime": "2023-01-13T16:13:31Z", "visits": [ { "startTime": "2023-01-13T16:03:53Z", "detour": "0s", "loadDemands": { "weightKg": { "amount": "-50" } } } ], "transitions": [ { "travelDuration": "233s", "travelDistanceMeters": 794, "waitDuration": "0s", "totalDuration": "233s", "startTime": "2023-01-13T16:00:00Z", "vehicleLoads": { "weightKg": { "amount": "50" } } }, { "travelDuration": "328s", "travelDistanceMeters": 1188, "waitDuration": "0s", "totalDuration": "328s", "startTime": "2023-01-13T16:08:03Z", "vehicleLoads": { "weightKg": {} } } ], "metrics": { "performedShipmentCount": 1, "travelDuration": "561s", "visitDuration": "250s", "totalDuration": "811s", "travelDistanceMeters": 1982, "maxLoads": { "weightKg": { "amount": "50" } } }, "routeCosts": { "model.vehicles.cost_per_kilometer": 19.82, "model.vehicles.cost_per_hour": 9.01 }, "routeTotalCost": 28.83 }, { "vehicleIndex": 1, "vehicleStartTime": "2023-01-13T16:00:00Z", "vehicleEndTime": "2023-01-13T16:21:43Z", "visits": [ { "shipmentIndex": 1, "startTime": "2023-01-13T16:05:54Z", "detour": "0s", "loadDemands": { "weightKg": { "amount": "-60" } } }, { "shipmentIndex": 2, "startTime": "2023-01-13T16:13:52Z", "detour": "473s", "loadDemands": { "weightKg": { "amount": "-30" } } } ], "transitions": [ { "travelDuration": "354s", "travelDistanceMeters": 1196, "waitDuration": "0s", "totalDuration": "354s", "startTime": "2023-01-13T16:00:00Z", "vehicleLoads": { "weightKg": { "amount": "90" } } }, { "travelDuration": "228s", "travelDistanceMeters": 808, "waitDuration": "0s", "totalDuration": "228s", "startTime": "2023-01-13T16:10:04Z", "vehicleLoads": { "weightKg": { "amount": "30" } } }, { "travelDuration": "221s", "travelDistanceMeters": 655, "waitDuration": "0s", "totalDuration": "221s", "startTime": "2023-01-13T16:18:02Z", "vehicleLoads": { "weightKg": {} } } ], "metrics": { "performedShipmentCount": 2, "travelDuration": "803s", "visitDuration": "500s", "totalDuration": "1303s", "travelDistanceMeters": 2659, "maxLoads": { "weightKg": { "amount": "90" } } }, "routeCosts": { "model.vehicles.cost_per_kilometer": 26.59, "model.vehicles.cost_per_hour": 14.48 }, "routeTotalCost": 41.07 } ], "metrics": { "aggregatedRouteMetrics": { "performedShipmentCount": 3, "travelDuration": "1364s", "visitDuration": "750s", "totalDuration": "2114s", "travelDistanceMeters": 4641, "maxLoads": { "weightKg": { "amount": "90" } } }, "usedVehicleCount": 2, "earliestVehicleStartTime": "2023-01-13T16:00:00Z", "latestVehicleEndTime": "2023-01-13T16:21:43Z", "totalCost": 69.90, "costs": { "model.vehicles.cost_per_kilometer": 46.41, "model.vehicles.cost_per_hour": 23.49 } } }
В следующих полях показано, как оптимизатор распределяет грузы между двумя транспортными средствами, чтобы поддерживать вес грузов в пределах установленного лимита в 100 weightKg .
- Первый маршрут (
vehicleIndex: 0) обрабатывает груз весом 50weightKg. ЕгоmaxLoadsсоставляет "50", что ниже установленного лимита. - Второй маршрут (
vehicleIndex: 1) обрабатывает грузыweightKg60 и 30 кг. ЕгоmaxLoadsсоставляет "90", что также ниже установленного лимита. - Поскольку ни одно из транспортных средств не нарушает свой лимит,
routeCostsдля обоих маршрутов не отображается штрафcostPerUnitAboveSoftMax.