В этом примере показано, как использовать 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 .
Ключевые параметры для этого примера:
- Три партии имеют общую
loadDemandsвеса 140weightKg(50- 60 + 30).
- Доступны два автомобиля с
softMaxLoadweightKgи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 } } }
В следующих полях показано, как оптимизатор разделяет поставки между двумя транспортными средствами, чтобы удерживать грузы в пределах мягкого ограничения weightKg в 100 кг.
- Первый маршрут (
vehicleIndex: 0) обслуживает груз весом 50weightKg. ЕгоmaxLoadsравен 50, что ниже мягкого лимита. - Второй маршрут (
vehicleIndex: 1) обслуживает грузыweightKg60 и 30 кг. ЕгоmaxLoadsсоставляет 90 кг, что также ниже установленного лимита. - Поскольку ни одно из транспортных средств не нарушает мягкий лимит,
routeCostsдля обоих маршрутов не отображает штрафcostPerUnitAboveSoftMax.