Привет, меня зовут Абай Баймуканов, я работают алгоритмистом в ИТ-компании Relog, разрабатывающей облачный сервис для оптимизации городской доставки.

Для решения транспортных задач в логистике нужны лучшие алгоритмы, поэтому мы решили провести собственное исследование и выбрали для него два самых популярных открытых алгоритма - Vroom и Jsprit.

Нужно было понять какой из них лучше не только по качеству, но и выдает решение (построение маршрутов с учетом различных транспортных задач) за короткое время.

Какую задачу решали

Есть разные виды VRP-задач, например, CVRP (учет весогабаритных параметров), VRPTW (учет временных окон), MDVRP (задача с несколькими складами) и PDVRP(задача с забор-доставка). Для теста мы взяли CVRPTW (CVRP+VRPTW), поскольку это самая актуальная для наших клиентов задача.

Про сами алгоритмы. В чем их разница и преимущества

Для решения задач мы использовали два солвера Vroom и Jsprit. Оба они являются движками с открытым исходным кодом и решают CVRPTW, а также имеют много звезд Github.

VROOM

Vroom — это движок оптимизации с открытым исходным кодом, написанный на C++17, предназначенный для поиска эффективных решений разных реальных задач маршрутизации транспортных средств (VRP) за небольшое вычислительное время. Он решает задачу в 2 этапа:

  1. поиск изначального решения, для которого он применяет 5 видов эвристик и regret coefficient;

  2. поиск локального минимума для этого решения, Vroom использует 14 видов операторов.

Vroom использует 32 вида заранее подготовленных настроек (типы эвристики и regret coefficient) поиска изначального решения.

JSPRIT

Jsprit – движок для решения VRP-задач, написанный на Java. Он имеет открытый исходный код, использует идею симуляции отжига, а именно идею ruin and recreate.

Так же как и Vroom, Jsprit находит изначальное решение и итеративно оптимизирует его в 2 этапа:

  1. на этапе ruin он ломает собственное изначальное решение;

  2. на стадии recreate этот солвер его восстанавливает.

Как тестировали

Для исследования мы обезличили данные наших клиентов – запланированные маршруты - стандартизировали их, привели к задаче CVRPTW. Взяли для планирования ~700 маршрутов, у которых количество заявок составляло с 50 до 3 000.

Метрики:

  1. Количество назначенных заявок;

  2. Суммарная время и дистанция;

  3. Количество назначенных водителей;

  4. Вычислительное время.

Что показало исследование

В процессе эксперимента было выявлено, что Jsprit решает задачи медленно (для получения такого же результата как у Vroom он решал задачу в 10 раз дольше), поэтому мы решили сократить количество итерации до 128 и продолжили эксперимент.

При таких условиях Jsprit выдает результаты в среднем хуже, при этом вычислительное время у него оказалось больше.

Для сравнения результатов использовали метрику: a - b / max(a, b), что показывает долю отклонения от лучшего результат (далее del-max).

График по дистанции:

delmx_distance = del-max(voom_distance, jsprit_distance)

nu_services = количество заявок

График по количеству назначенных заявок:

delmx_assigned = del-max(voom_assigned, jsprit_assigned)

nu_services = количество заявок


Сравнение гибкости

Так же мы сравнили насколько легко реализовывать новые фичи в этих алгоритмах.

Jsrpit имеет готовые интерфейсы hard/soft constraints, они могут быть на уровне подбора транспорта для заявки или при вставке заявки в определенную часть маршрута.

Что бы реализовать ограничение во Vroom нужно дописывать логику ограничения во все операторы (их 15) и это не просто copy-paste, поскольку у каждого оператора своя логика, т.е. нужно иметь хорошую экспертность в написании кода движка.

Также в Jsprit можно реализовать свою целевую функцию, для этого есть интерфейс ObjectiveFunction или решать задачу Time Dependent VRP, в которой меняются дистанция/время проезда относительно времени и т.д.

Выводы

Для решения наших задач Jsprit более гибкий, чем Vroom, и позволяет решать больший спектр задач. Что же касается других алгоритмистов, то придется решать, готовы ли они ждать дольше, чтобы получить лучшее решение и потестить Vroom для своих задач.

Комментарии (0)