Для привязки пунктов посещения к конкретной машине придется добавить переменных. Потому что даже в самом простом случае с двумя машинами (и маршрутами) нам необходимо как-то выделить оба подмаршрута для расчета загрузки машин.
- Идея для новой переменной довольно проста:
- один из подмаршрутов (маршрут одной машины) обозначим единицами;
- второй подмаршрут обозначим нулями;
- тогда перемножая этот набор переменных на потребности торговых точек в товаре получим загрузку первой машины, а на долю второй достанется остаток товара
1
Решение задачи построения маршрута для двух машин и 28 точек посещения.
Примем, что две грузовые машины выезжают из одного и того же пункта, расположенного в центре района (X=10 и Y=10).Для построения двух маршрутов совместим пункты
Таблица расстояний.
Воспользуемся Таблицей расстояний из задачи для трех мусоровозов и 28 точек посещений.
Напомню, что мы моделировали координаты 27 точек посещения датчиком случайных чисел и вычисляли расстояния между этими точками посещения по известной математической формуле.
Получим примерно такую Таблицу расстояний:Напомню, что мы моделировали координаты 27 точек посещения датчиком случайных чисел и вычисляли расстояния между этими точками посещения по известной математической формуле.
- Замечания к таблице расстояний:
- в каждую серую ячейку с правой
стороны таблицы вводится формула, связывающая таблицу расстояний с таблицей переменных: каждая ячейка таблицы расстояний умножается на
соответствующую ячейку таблицы переменных и полученные произведения складываются.
Тем самым находится расстояния от точки выхода машины до следующей точки входа. - в конце все значения в сером столбце складываются и находится длина всего маршрута.
Таблица переменных.
Подготовим таблицу переменных, добавив слева стандартной таблицы запросы каждой торговой точки.При этом будем считать, что точки
Запрос в товаре определяет необходимое число машин. В чем измеряется запрос каждой торговой точки нам неважно, пусть это будут картонные короба с товаром. Общее количество коробов, которые нужно развести по торговым точкам - 1777, а вместимость машин 950. Следовательно, для развоза товара достаточно будет двух машин.
Для решения с двумя машинами выключим посещение точки
- Пояснения к таблице:
- Желтое поле - ячейки и
оранжевые ячейки
- это область бинарных переменных. Именно эти ячейки мы будем указывать в качестве переменных в установках OpenSolver.
В найденном решении 1 - это заезд в точку, 0 - заезда нет. - Значения оранжевых ячеек -
при решении задачи всегда будут равны
0 . - В каждую коричневую ячейку
введем формулу, которая находит сумму желтых ячеек в соответствующей строке или в соответствующем столбце.
Эти суммы должны быть равны 1 (значениям, указанным в светло-коричневых ячейках ), а для выключенных точек 0. - числа в зеленых ячейках - это потребности каждой торговой точки в товаре.
Таблица специальных ограничений.
- Модифицируем таблицу специальных ограничений
( подробнее о таблице специальных ограничений):
- здесь есть переменные, которые определят порядок посещения точек
желтые ячейки, в которые введены числа от 0 до 29.- добавим новые переменные (желтые ячейки с нулевым значением -
0), к которым предъявим следующие требования:- переменные бинарны (могут быть равны 0 или 1)
- привяжем эти переменные к переменным, определяющим порядок посещения точек машинами, с помощью формулы, которая вводится в голубые ячейки справа.
- В светло-серые ячейки введем формулу, контролирующую корректность решения.
- Пояснения к таблице специальных ограничений:
- Мы выделили ячейку темно-желтого цвета
в строке
n02 желтого столбца переменных, определяющих порядок посещения точек, так как точкаn02 является разделителем общего маршрута на два подмаршрута для двух машин.
Пусть OpenSolver после решения задачи оптимизации присвоит этой ячейке значениеN, а все остальные ячейки этого столбца будут иметь значениеi, гдеi - любое число от 0 до 29. - В каждую голубую ячейку
запишем формулу
= N-i+0*29
и в установках OpenSolver потребуем, чтобы значения этих ячеек были неменьше 0.
при этом ссылки ячейкиNи29остаются неизменными, а ячейкиiи0имеют индекс соответсвующей строки.-
Рассмотрим смысл этой формулы:
- для второго подмаршрута все i>N, поэтому неравенство
N-i+0*29≥ 0, будет верным только в том случае, если в ячейке0будет 1 (1).
Таким образом, мы найдем все все пременные1второго подмаршрута. - для первого подмаршрута все
i≤N, поэтому неравенство
N-i+0*29≥ 0, будет верным и в случае, если наша новая бинарная переменная равна 0 (0), и в случае, если она равна 1 (1). Однако разность29-Nвсегда показывает, сколько в нашем бинарном столбце0должно быть 1.
Эта разность находится в ячейке
- для второго подмаршрута все
- в темно-коричневой ячейке подсчитываем сумму единичек в столбце новой бинарной переменной
- если решение найдено правильно (т.е. 1 и 0 в новой переменной расставлены верно ), то во всех ячейках серого цвета должны быть 0, так как в них введена контрольная формула:
(Еслиi>N, то1 иначе0 ) -0
если номер порядка посещения точки больше номера посещения точкиn02 , то поставь 1, если иначе, то поставь 0, затем из этого значения вычти значение бинарной переменной. - Чтобы вычислить загрузку машин каждого рейса, достаточно найти сумму произведений новой бинарной переменной на потребности торговых точек.
Так как для рейса одного маршрута все бинарные переменные равны 1, а для другого 0, то получим загрузку одной машины. Именно это мы вычисляем в ячейке - Осталось найти загрузку второй машины. Для этого из общей потребности магазинов вычтем значение темно-синей ячейки
Результат запишем в ячейку бирюзового цвета - Для контроля в установках OpenSolver мы потребуем, чтобы загрузка машин не превышала 950 коробов (значения в ячейке
950таблицы специальных ограничений)
Установки OpenSolver.
Все подготовленно для решения задачи. Для поиска оптимального маршрута используем OpenSolver- Данные и ограничения OpenSolver - Model:
- цель: найти самый короткий маршрут - значение ячейки
$AI$36 должно быть минимальным; - переменные в задаче - желтые ячейки в таблице переменных и желтые ячейки в таблице специальных ограничений (столбец с переменными,
определяющими порядок посещения точек и столбец с новой бинарной переменной )
$E$40:$AH$69 ;$AI$74:$AI$103 ;$AM$74:$AM$103 - ограничения задачи:
- переменные из таблицы переменных должны быть бинарными (принимать значение
0 или1 -
$E$40:$AH$69 bin - суммы выездов из пунктов посещения и суммы въездов в каждый из них равны заданному числу -
$AI$40:$AI$69 = $AJ$40:$AJ$69
$E$70:$AH$70 = $E$71:$AH$71 - условие, запрещающее короткие циклы
$E$75:$AH$103 <= $AK$72 - ограничим переменные
AI74:AI103 сверху
$AI$74:$AI$103 <= $AJ$72 .
Если этого не сделать, то оптимизатор найдет решение для одного связного маршрута: начнет отсчет от точкиn02 , присвоив ей значение, например, 10, а остальные номера будет отсчитывать от этого значения так, что последняя точка посещения будет иметь номер 39. - новые переменные в таблице ограничений должны бинарны:
$AM$74:$AM$103 bin -
привязываем эти переменные к переменным, определяющим порядок посещения точек машинами:
$AN$74:$AN$103 >= 0 - указываем, что количество коробов, которая повезет первая машина должно быть небольше максимальной вместимости машины:
$AK$78 < $AK$82 - указываем, что количество коробов, которая повезет вторая машина должно быть небольше максимальной вместимости машины:
$AK$80 < $AK$82 -
сумма найденных бинарных единиц общего маршрута должна быть равна расчетной:
$AM$104 = $AM$105
- переменные из таблицы переменных должны быть бинарными (принимать значение
Решение, найденное OpenSolver.
При оптимизации можно использовать и Gurobi, и CBC, но решение с последним может занять полчаса или больше. В результате получим маршрут, общая длина которого 95,54 км.
Таким образом, первая машина посещает 19 точек и развозит 936 коробов, а вторая машина посещает 10 точек и развозит 841 короб.2
Решение задачи для трех машин с учетом их вместимости.
К сожалению, получение планов для трёх и более машин приходится добывать экстенсивным методом: каждая новая машина требует дополнительного набора переменных, аналогичных уже введенным.
Предположим, что вместимость машины - 750 коробов, а не 950, как мы рассматривали выше. Тогда для развоза товара необходимо задействовать 3 машины.
Что нужно изменить в уже созданных таблицах.
Таблицу расстояний менять не нужно, а в таблице переменных необходимо включить точкуn03 .
В таблицу специальных ограничений нужно ввести две дополнительные переменные.
Будем искать точки посещения для 1 и 3 маршрута, а точки посещения 2 маршрута найдем как разность между всеми точками и точками 1 и 3 маршрута.
- Пояснения к таблице специальных ограничений:
- в столбце переменных, определяющих порядок посещения точек выделены две ячейки:
-
для строки
n02 , так как пунктn02 является концом первого маршрута и началом второго -
для строки
n03 , так как пунктn03 является концом второго маршрута и началом третьего
-
для строки
- в ячейках темно-синего , бирюзового
и
светло-бирюзового
цветов считаем количество коробов, которые будут развезены по каждому маршруту :
- в ячейке находим сумму произведений бинарной переменной 1 маршрута на потребности торговых точек
- в ячейке находим сумму произведений бинарной переменной 3 маршрута на потребности торговых точек
- в ячейке находим разность между суммарной потребности торговых точек и значений, найденных в темно-синей ячейке и светло-бирюзовой
- серые ячейки слева от столбцов с новыми бинарными переменными
по прежнему выполняют контрольные функции. Формула контроля такая же,которую мы вводили для двух маршрутов. Только в контрольной фомуле 1 маршрута используем значение ячейки
для
n02 , а в формуле 3 маршрута используем значение ячейки дляn03 в столбце переменных, определяющих порядок посещения точек - в голубые
ячейки вновь вставляем формулу, связывающую новую бинарную переменную с переменной, определяющей порядок посещения точек.
Для 3 маршрута формула остается такой же, как мы рассматривали ранее в задаче для двух машин, только ссылаемся на значение ячейки дляn03 столбца переменных, определяющих порядок посещения точек.
А для 1 маршрута формула будет выглядеть так
= i-n02- 1 +0*29
вычитаем 1 для того, чтобы номер посещения точкиn02 был включен в 1 маршрут. - в зеленой ячейке под бинарной переменной 1 маршрута
вычислим количество точек, которая должна посетить машина 1 маршрута
=n02+ 1
на единицу больше, чем номер точкив зеленой ячейке под бинарной переменной 3 маршрута остается таже формула, которую мы использовали при построении задачи для 2 машин.n02 , так как SolverOpen ведет нумерацию точек от 0.
Что нужно изменить в установках OpenSolver.
- Внесем в установки OpenSolver - Model следующие изменения:
- в поле Variable Cells добавим столбец с бинарными переменными для 3 маршрута
$AQ$74:$AQ$103 - в поле Constraints добавим новые ограничения:
- новые переменные для 3 маршрута должны бинарны:
$AQ$74:$AQ$103 bin -
привязываем эти переменные к переменным, определяющим порядок посещения точек машинами:
$AR$74:$AR$103 >= 0 - указываем, что количество коробов, которая повезет первая машина должно быть небольше максимальной вместимости машины:
$AK$78 < $AK$84 - указываем, что количество коробов, которая повезет вторая машина должно быть небольше максимальной вместимости машины:
$AK$80 < $AK$84 - указываем, что количество коробов, которая повезет третья машина должно быть небольше максимальной вместимости машины:
$AK$82 < $AK$84 -
сумма найденных бинарных единиц 1 маршрута должна быть равна расчетной:
$AM$104 = $AM$105 -
сумма найденных бинарных единиц 3 маршрута должна быть равна расчетной:
$AQ$104 = $AQ$105
- новые переменные для 3 маршрута должны бинарны:
- После вычислений мы получим следующее решение:
- суммарный маршрут - 102,63 км
- подмаршрут 1 машины - 4 точки, 450 коробов
- подмаршрут 2 машины - 8 точек, 634 короба
- подмаршрут 3 машины - 15 точек, 693 короба
Теперь не меняя ничего в установках OpenSolver, можно исследовать построенную модель, например, изменив максимальную вместимость машины.
- Так для максимальной вместимости 675 коробов получим такое решение:
- суммарный маршрут - 102,76 км
- подмаршрут 1 машины - 4 точки, 450 коробов
- подмаршрут 2 машины - 9 точек, 673 короба
- подмаршрут 3 машины - 14 точек, 654 короба
Скачать файл "garbage_truck_route 6m.xlsx" (примерно 383 Кб) - Этот файл содержит:
- генератор произвольного набора координат для 23 и 30 пунктов посещения
- модель решения задачи для 2 машин и 30 точек посещения
- модель решения задачи для 2 машин, учитывающую их вместимость
- модели решения задачи для трех машин, 23 и 30 точек посещения без учета вместимости и с учетом вместимости машин.
Далее, чтобы использовать рассмотренную нами модель решения задачи нужно автоматизировать создание новых переменных програмным путем, либо разбивать задачу на подзадачи. Последний вариант ухудшит красоту решения, поскольку мы в модели все время искали единый оптимальный маршрут.
- В чем ценность предложенной модели решения и ее различных модификаций?
- Решение находим не с помощью специальных алгоритмоа, а с помощью общего подхода к решиению задач оптимизации, используя знакомый и доступный для всех инструмент MS Excel и OpenSolver
- Построенные модели легко модифицировать и исследовать различные варианты, отвечая на вопросы Что если..., анализировать возможные результаты, выбирая направления развития бизнеса. Ведь часто бывает так, что целесообразность включения в маршрут той или иной точки не просчитывается или просчитывается формально.
✉ Если у вас появились вопросы или замечания, вы можете предложить лучшее решение, то пишите мне на электронную почту. - добавим новые переменные (желтые ячейки с нулевым значением -