В этом примере показано, как использовать атрибуты перехода для определения приоритетов маршрутов, где забор и доставка товаров из близлежащих пунктов выполняются одним и тем же транспортным средством в одном временном блоке. Подробнее об атрибутах перехода см. в статье «Модель бизнес-логики с атрибутами перехода» .
В этом примере:
- Грузы A, B и C доставляются близко друг к другу по одной дороге.
- Дополнительные поставки ожидаются в будущем.
- Поставки не имеют конкретных сроков доставки.
- Независимо от графика визита, автомобилю необходимо проехать по этой дороге дважды: один раз утром по пути из депо и один раз вечером по пути обратно.
- Общее расстояние и продолжительность маршрута всегда одинаковы, независимо от того, когда выполняются этапы A, B и C.
В этой ситуации, а также для запроса, который использует только стоимость за час и стоимость за километр, оптимизированный маршрут может обрабатывать A и B утром, а C — вечером, и стоимость решения будет такой же, как если бы все три обрабатывались одновременно.
Стоимость за километр с порогом
Чтобы сгруппировать близлежащие посещения, сначала необходимо выбрать пороговое расстояние. Это максимальное расстояние между двумя посещениями, которые вы считаете близлежащими. В этом примере используется пороговое значение в 100 метров, что примерно соответствует одному кварталу в городской черте. Вы можете увеличить или уменьшить пороговое значение в соответствии с потребностями вашего бизнеса и предпочтениями ваших водителей.
Чтобы сгруппировать близлежащие посещения в пределах 100 метров друг от друга, установите высокую стоимость первых 100 метров каждого перехода и более низкую стоимость всех последующих метров перехода. Поскольку первые 100 метров являются самыми дорогими, оптимизатор достигает наибольшей экономии, используя переходы короче 100-метрового порога, даже если это означает увеличение общей длины маршрута.
Чтобы настроить затраты, добавьте новую запись в ShipmentModel.transition_attributes
со следующими свойствами:
- Чтобы сопоставить все возможные переходы, выберите тег, который не используется нигде в модели, например,
UNUSED_TAG
. Задайте для него атрибутыTransitionAttributes.excluded_src_tag
иTransitionAttributes.excluded_dst_tag
. - Настройте
TransitionAttributes.distance_limit
с пороговым расстоянием и стоимостью:- Установите
DistanceLimit.soft_max_meters
на выбранное пороговое значение. - Установите
DistanceLimit.cost_per_kilometer_below_soft_max
на стоимость за километр ниже порогового значения. - Установите
DistanceLimit.cost_per_kilometer_above_soft_max
на стоимость за километр сверх порогового значения.
- Установите
{
"model": {
"transitionAttributes": [
{
"excluded_dst_tag": "UNUSED_TAG",
"excluded_src_tag": "UNUSED_TAG",
"distanceLimit": {
"softMaxMeters": 100,
"costPerKilometerBelowSoftMax": 50,
"costPerKilometerAboveSoftMax": 1,
}
}
]
}
}
Тег #unused_tag#
не должен использоваться ни одной поставкой или транспортным средством для сопоставления всех возможных переходов. Подробнее см. в разделе «Как сопоставить все запросы на посещение» .
Как работает высокая стоимость ниже порогового значения
В этом разделе показано, как стоимость ниже и выше порогового значения влияет на общую стоимость различных решений в примере сценария.
Решение 1: Выполнить A, B по пути туда, C по пути обратно.
В этом решении грузы распределяются по двум маршрутам прохождения этой дороги. Два из них доставляются по первому маршруту, а один — по второму. Имеется 5 переходов:
Переход | Расстояние | Ниже порога | Выше порога | ||
---|---|---|---|---|---|
Расстояние | Расходы | Расстояние | Расходы | ||
депо →А | 1000 м | 100 м | 5 | 900 м | 0,9 |
А→Б | 50 м | 50 м | 2.5 | 0 м | 0 |
B→другое | 1030 м | 100 м | 5 | 930 м | 0,93 |
другое→C | 1000 м | 100 м | 5 | 900 м | 0,9 |
C→депо | 1080 м | 100 м | 5 | 980 м | 0,98 |
Общий | 450 м | 22.5 | 3710 м | 3.71 |
Общая стоимость рассчитывается как сумма двух стоимостей за километр:
- стоимость за километр ниже порога (50), умноженная на общее пройденное расстояние ниже порога (450 м = 0,45 км),
- стоимость за километр сверх порога (1), умноженная на общее пройденное расстояние сверх порога (3710 м = 3,71 км).
Общая стоимость таким образом составит 0,45 * 50 + 3,71 * 1 = 22,5 + 3,71 = 26,21.
Решение 2: выполнить пункты A, B, C по пути туда и ничего по пути обратно.
В этом решении, в отличие от решения 1, все три груза доставляются «группой» за один проход по дороге. На другом проходе автомобиль вообще не останавливается. Снова имеется 5 переходов, но их продолжительность и состав различаются:
Переход | Расстояние | Ниже порога | Выше порога | ||
---|---|---|---|---|---|
Расстояние | Расходы | Расстояние | Расходы | ||
депо →А | 1000 м | 100 м | 5 | 900 м | 0,9 |
А→Б | 50 м | 50 м | 2.5 | 0 м | 0 |
Б→С | 30 м | 30 м | 1.5 | 0 м | 0 |
C→другое | 1000 м | 100 м | 5 | 900 м | 0,9 |
другое→депо | 2080 м | 100 м | 5 | 1980 м | 1.98 |
Общий | 380 м | 19 | 3780 м | 3.78 |
Используя те же вычисления, что и в решении 1, получаем общую стоимость 0,38 * 50 + 3,78 * 1 = 19 + 3,78 = 22,78, и выполнение всех посещений в одном временном блоке обходится дешевле, чем выполнение их в двух группах. Этот эффект можно усилить, увеличив DistanceLimit.cost_per_kilometer_below_soft_max
.
Почему низкая стоимость за километр ниже порогового значения не работает
Поскольку вы предпочитаете короткие переходы длинным, у вас может возникнуть соблазн установить высокую стоимость за километр для длинных переходов и оставить низкую стоимость за километр для коротких переходов. Но на самом деле это приводит к обратному эффекту: поскольку первые 100 метров перехода самые дешёвые, оптимизатор использует эти «дешевые» метры с максимальной эффективностью, отдавая предпочтение переходам длиной около 100 метров или более.
Этот эффект можно увидеть на примере двух решений. Если поменять местами стоимость за километр ниже и выше порогового значения, стоимость маршрута изменится:
Высокая стоимость сверх порогового значения | Высокая стоимость ниже порогового значения | |||
---|---|---|---|---|
Решение 1 | Решение 2 | Решение 1 | Решение 2 | |
КМ ниже порогового значения | 0,45 | 0,38 | 0,45 | 0,38 |
Стоимость за км ниже порогового значения | 1.00 | 1.00 | 50.00 | 50.00 |
КМ выше порогового значения | 3.71 | 3.78 | 3.71 | 3.78 |
Стоимость за км сверх порогового значения | 50.00 | 50.00 | 1.00 | 1.00 |
Общая стоимость | 185,95 | 189.38 | 26.21 | 22.78 |
Для каждой версии жирным шрифтом выделено наименьшее из двух значений общей стоимости. Видно, что при использовании высокой стоимости, превышающей пороговое значение, общая стоимость маршрута, где посещения сгруппированы, становится выше, что противоречит желаемому результату.