Третья часть тренинга по решению задач оптимизации в пакете GLPK. На примере решения транспортной задачи рассматриваются операции с множествами, доступные в MathProg
1. Основы моделирования в
пакете GUSEK/GLPK
v 0.3 2015-03-09
Решение задач транспортного типа
Операции с множествами
Заходякин Г.В. postlogist@gmail.com
2. План занятия
• Содержательная постановка транспортной задачи
• Модель на языке MathProg
• Полезные операции с множествами в MathProg
2
3. Содержательная постановка
• Компания располагает тремя складами, расположенными в Подмосковье (Химки, Чехов и
Ногинск)
• Продукция со складов доставляется клиентам в ближайших областях. В этом примере спрос
клиентов каждой области агрегирован до областного центра
• Известен объем заказов, полученных от клиентов и запасов, доступных на каждом складе
• Известно расстояние от каждого склада до каждого клиента
• Требуется найти план перевозок (распределения), обеспечивающий минимальные
транспортные затраты и при этом удовлетворить спрос всех клиентов
3
4. Транспортная задача на карте…
Требуется составить план перевозок
с минимальными затратами, при
котором полностью удовлетворяется
весь спрос 4
5. Математическая постановка задачи
𝐹𝐹 = �
𝑤𝑤∈𝑊𝑊
�
𝑚𝑚∈𝑀𝑀
𝑐𝑐 ⋅ 𝑑𝑑𝑤𝑤𝑤𝑤 ⋅ 𝑥𝑥𝑤𝑤𝑤𝑤 → 𝑚𝑚𝑚𝑚𝑚𝑚
�
𝑚𝑚∈𝑀𝑀
𝑥𝑥𝑤𝑤𝑤𝑤 = 𝐼𝐼𝑤𝑤, ∀𝑤𝑤 ∈ 𝑊𝑊
�
𝑤𝑤∈𝑊𝑊
𝑥𝑥𝑤𝑤𝑤𝑤 = 𝐷𝐷𝑚𝑚, ∀𝑚𝑚 ∈ 𝑀𝑀
𝑥𝑥𝑤𝑤𝑤𝑤 ≥ 0, ∀𝑤𝑤 ∈ 𝑊𝑊, ∀𝑚𝑚 ∈ 𝑀𝑀
Обозначения:
• 𝑊𝑊 – множество складов
• 𝑀𝑀 – множество рынков
• 𝑥𝑥𝑤𝑤𝑤𝑤 - объем перевозок по маршруту 𝑤𝑤 → 𝑚𝑚
• 𝑑𝑑 𝑤𝑤𝑤𝑤- расстояние между пунктами
• с – тариф, в расчете на ед. продукта на км
• 𝐼𝐼𝑤𝑤 - запасы склада 𝑤𝑤
• 𝐷𝐷𝑚𝑚 - спрос на рынке 𝑚𝑚
Влади
мир
…
Ниж-
ний
500Запасы
M (рынки)
W (склады)
𝑥𝑥Химки,Владимир
Х Ч Н
500 1000
100Спрос 300
структура
данных
решения
5
8. Множества и параметры модели
• На рисунке показано объявление множеств и параметров модели
– Для каждого параметра мы задали проверку на допустимое значение, а также разумное значение
по умолчанию. Например, если между какими-то пунктами маршрут прокладывать
нецелесообразно, можно пропустить в данных это расстояние; при этом по умолчанию длина
маршрута станет очень большой, и маршрут не будет использоваться
– Ключевое слово check позволяет задать более сложную проверку: мы можем проверять не просто
отдельные значения загружаемых данных, а использовать произвольные выражения для контроля
правильности. Поскольку эта проверка не является частью математической постановки модели,
здесь можно использовать произвольные нелинейные функции
– В классической постановке транспортной задачи, которую мы используем, запасы на складах и
спрос клиентов в точности равны. На практике, такое условие редко реализуется, поэтому
контролируемое условие может оказаться чрезмерно строгим
8
9. Переменные и целевая функция
• На рисунке показано объявление переменных модели
и выражение для целевой функции
– В этой задаче переменные решения (план перевозок)
имеют структуру таблицы: строки таблицы – склады,
столбцы – клиенты (на рисунке для компактности показана
транспонированная таблица)
– Целевая функция - транспортные затраты - зависит
от объемов перевозок по каждому маршруту и его длины
– Мы считаем, что транспортные тарифы по всем
направлениям одинаковые, поэтому не важно, какое именно
значение принимает параметр tariff. Сумма будет изменяться пропорционально значению
параметра, а оптимальное решение не изменится. В этой задаче примем tariff за 1
– Целевую функцию можно записать несколькими способами. Наиболее компактный – одна сумма, в
индексирующем выражении которой присутствуют оба множества. Порядок написания индексов
здесь не важен. Порядок важен тогда, когда мы обращаемся к переменной или таблице расстояний.
Поскольку мы задали их индексы как {склад, клиент}, - правильно писать: trans[w, m].
Наоборот – trans[m, w] – нельзя.
9
10. Ограничения
• На рисунке показана система ограничений
– В модели присутствуют 2 вида ограничений: для каждого склада –
возможный объем поставок, для каждого клиента – требование по
выполнению спроса; при этом клиент, в принципе, может снабжаться
с разных складов
– Оба ограничения представляют собой множество ограничений
(индексирующее выражение задано в {} после имени ограничения)
10
11. Данные
• На рисунке показан раздел данных для решения задачи (в одном файле с моделью)
– Мы, по возможности, используем одновременное определение элементов множества и свойств
этих элементов (в реляционном формате)
– В модели мы определили индексы для параметра distance – склад, модель. Но, поскольку клиентов
много, такую таблицу неудобно вводить. Поэтому в разделе данных можно указать, что таблица
приведена в транспонированном виде (tr), тогда ошибки не будет
– Можно использовать русские символы для элементов множеств, но тогда нужны кавычки❶
❷
11
12. Проба
• Добавьте перед разделом данных команды solve и display, чтобы вывести значение
транспортных затрат и план перевозок
• Запустите модель, чтобы проверить решение
• На рисунке приведен фрагмент плана перевозок. Очевидно, что выдаваемый автоматически
отчет крайне неудобен для анализа: он содержит все переменные решения, даже если
какой-либо маршрут не предполагается использовать
12
13. Фильтрация в индексных выражениях
• До сих пор при записи индексирующих выражений в MathProg мы использовали все элементы
некоторого множества, или все возможные сочетания элементов из нескольких множеств. Однако часто
требуются не все элементы, а лишь те, которые обладают нужными свойствами
• Для отбора нужных элементов используются фильтры. После двоеточия в индексном выражении можно
записать условие. Если записанное в условии выражение истинно для текущего элемента, то он
включается в индекс и используется. Иначе – пропускается
• Несколько условий можно объединить в одно с помощью союзов: И (&&), ИЛИ (||), например:
trans[w, m] > 0 && trans[w, m] < 100 – оба условия должны выполняться одновременно
• Фильтры работают в любой ситуации – и при определении компонентов модели тоже
• На рисунке мы вывели план перевозок только по используемым маршрутам. Обратите внимание, что из-
за порядка индексов список получился отсортированным по рынкам
13
14. Форматированный отчет
• Команды для получения форматированного отчета
показаны на рисунке внизу
• Мы используем для вывода строк таблицы
команду for, которая повторяет для каждого
клиента (строки) команды printf для печати
объемов перевозок с разных складов (столбцы)
• При необходимости, вы можете обратиться за
пояснениями об использовании специальных
символов (n) и спецификаторов формата (%)
к тренингу по задаче о рационе
14
16. Решение на карте…
• Сравнение решения с картой позволяет утверждать, что план перевозок в нашей задаче получился
довольно разумным: каждый город снабжается с ближайшего склада
• Однако в задаче реалистичного размера – с большим числом клиентов – выбранный нами способ
формализации модели приведет к проблеме: число переменных решения определяется произведением
числа складов и клиентов (30)
• Можно несколько снизить размерность задачи, если рассматривать не все возможные маршруты, а
только те, которые
целесообразно
использовать
• Даже текущая
постановка позволяет
исключить часть
маршрутов, если
удалить для них
расстояние в таблице
данных (значение
по умолчанию очень
велико)
• Однако, есть более
элегантное решение
16
17. Модель 2: множества
• Сохраните копию модели 1 под именем transportation2.mod
• Мы модифицируем старую модель, чтобы учесть возможность явно задавать списком допустимые
маршруты
• На рисунке показан раздел с объявлением множеств в новой версии модели
– Добавилось новое множество – маршруты (ROUTES)
– Под маршрутом мы будем понимать пару элементов – (склад, магазин). Именно пары таких
сочетаний являются элементами множества ROUTES
– В принципе, для объявления такого двухэлементного множества достаточно было написать:
set ROUTES dimen 2; #элементы множества – это пары значений
– В данном случае мы дополнительно указали, что множество ROUTES – это подмножество декартова
произведения множеств WH и MARKETS:
𝑅𝑅𝑅𝑅𝑅𝑅𝑅𝑅𝑅𝑅𝑅𝑅 ⊆ 𝑊𝑊𝑊𝑊 × 𝑀𝑀𝑀𝑀𝑀𝑀𝑀𝑀𝑀𝑀𝑀𝑀𝑀𝑀
То есть, в это множество может входить часть или все сочетания склада и магазина.
Но, например, пары: (склад, склад) – не подойдут
– При нарушении требования к элементам маршрута будет выведено сообщение об ошибке
17
18. Модель 2: параметры
• Измените объявление параметра distance, как показано на рисунке
18
19. Модель 2: переменные и критерий
• Измените объявление переменной trans и выражение для целевой функции, как
показано на рисунке
– Теперь переменная определена только на возможных маршрутах, задаваемых множеством ROUTES,
мы рассматриваем не все сочетания складов и магазинов
– При определении целевой функции, в сумме, мы, как и раньше вводим индексные переменные.
Однако отличие в том, что теперь мы получаем эти индексы из элементов множества ROUTES:
как было определено ранее, это множество состоит из пар: (склад, магазин). Поэтому первый
индекс (w) соответствует складу, а второй (m) – магазину. В выражении под знаком суммы отличий
нет, мы можем использовать заданные таким образом индексы как обычно
19
20. Модель 2: ограничения
• Выражения для ограничений в новой модели показаны на рисунке:
• Ранее мы рассматривали для каждого склада сумму по всем клиентам. Теперь же для
подсчета суммы будут использоваться только те клиенты, к которым заданы маршруты, т.е. в
множестве ROUTES к ним есть маршрут, который начинается на этом складе
• Эквивалентная, но более громоздкая запись ограничения – с использованием фильтра:
• Рекомендуем применять краткую форму, показанную вначале
20
21. Модель 2: вывод решения
• Поскольку теперь используются не все маршруты, необходимо модифицировать команды
для вывода решения:
• В коде для вывода таблицы необходимо модифицировать выражение для плана перевозок
по маршруту (печать, вложенная в for). Теперь мы используем условное выражение:
if условие then формула1 else формула2
• Условное выражение работает подобно функции ЕСЛИ() в Excel: если условие – истина, то
результат вычисляется по формуле1, иначе – по формуле 2. В плане для невозможных
маршрутов будут стоять нули
21
22. Модель 2: данные
• В разделе данных необходимо изменить
определение параметра distance и задать
элементы множества допустимых маршрутов
(ROUTES)
• Оба этих объекта определяются одновременно,
как показано на рисунке
• Первые два значения (строки) – это пара элементов
маршрута (начало и конец), числовое значение
в третьем столбце – расстояние
• Обратите внимание на порядок индексов:
он должен совпадать с тем, который был указан
при объявлении параметра и множества, т.е.:
склад, клиент
22
23. Модель 2: решение
• Для сравнения, на рисунке показаны результаты по моделям 1 и 2
• Мы ограничили область допустимых решений, убрав часть маршрутов, поэтому затраты получились выше
• Но этот результат точнее отражает наши требования
23
25. Модель 3: индексированные множества
• Сохраните копию модели под именем transportation3.mod. В этом примере мы немного модифицируем
модель, чтобы сделать более удобной запись ограничений
• На рисунке показаны два дополнительных множества, которые создаются на основе списка маршрутов:
– множество CUST задает для каждого склада множество рынков, к которым от этого склада есть
маршрут (т.е. это множество возможных клиентов данного склада). Чтобы узнать, кого снабжает
склад w, нужно написать: CUST[w]
– множество SUPL задает для каждого рынка множество возможных поставщиков
• в MathProg такие индексированные множества называются “indexed collection of sets” – индексированная
коллекция множеств (для краткости будем называть их «индексированные множества»)
25
26. Оператор setof
• Оператор setof очень полезен, т.к. он позволяет конструировать новые множества на основе существующих.
Рассмотрим его работу на примере:
– Мы определяем индексированное множество CUST
– Рассматриваются все элементы множества складов WH
– Для каждого склада множество клиентов формируется
с помощью оператора setof
– В скобках после setof написано выражение,
порождающее некоторое множество. В данном
случае это выражение выбирает из множества
маршрутов все маршруты, которые начинаются
на складе w
– Маршрут представляет собой пару значений:
(склад, рынок). Мы можем ссылаться на эти значения,
соответственно, как w и m
– Сразу после скобок {} указан шаблон, который
определяет, какие части элементов сгенерированного
множества нам нужны. В данном случае – только
рынок (m)
– В результате для каждого склада получится список
клиентов, которые с него снабжаются. Например,
для склада в Чехове получим:
CUST[“Чехов”] = “Калуга”, “Рязань”, “Москва”, “Тула”
26
27. Модель 3: использование индексированных множеств
• Используя созданные нами дополнительные множества, можно более понятно записать
ограничения в модели:
• Например, для ограничения по складам, в индексе для суммы теперь явно указано, что
необходимо включать все рынки, снабжаемые со склада w – CUST[w]
• Другие элементы модели изменения не требуют. Поскольку мы не меняли математическую
постановку, результаты расчета в точности совпадают с прежними
27
28. Операции с множествами
• Полезно знать основные операции с множествами. Рассмотрим их на примере
• Пусть 𝐴𝐴 = 𝑎𝑎, 𝑏𝑏, 𝑐𝑐 , 𝐵𝐵 = {𝑏𝑏, 𝑐𝑐, 𝑑𝑑}
Операция Результат Математическая
запись
Оператор MathProg
Объединение {𝑎𝑎, 𝑏𝑏, 𝑐𝑐, 𝑑𝑑} 𝐴𝐴⋃𝐵𝐵 A union B
Пересечение {𝑏𝑏, 𝑐𝑐, 𝑑𝑑} 𝐴𝐴⋂𝐵𝐵 A inter B
Декартово
произведение
{ 𝑎𝑎, 𝑏𝑏 , 𝑎𝑎, 𝑐𝑐 , 𝑎𝑎, 𝑑𝑑 ,
𝑏𝑏, 𝑏𝑏 , 𝑏𝑏, 𝑐𝑐 , 𝑏𝑏, 𝑑𝑑 ,
𝑐𝑐, 𝑏𝑏 , 𝑐𝑐, 𝑐𝑐 , 𝑐𝑐, 𝑑𝑑 }
𝐴𝐴 × 𝐵𝐵 A cross B
Разность {𝑎𝑎} 𝐴𝐴B A diff B
Симметричная
разность
{𝑎𝑎, 𝑑𝑑} 𝐴𝐴⨁𝐵𝐵 A symdiff B
𝐴𝐴⋃𝐵𝐵 𝐴𝐴⋂𝐵𝐵 𝐴𝐴 × 𝐵𝐵 𝐴𝐴B 𝐴𝐴⨁𝐵𝐵
(𝑎𝑎, 𝑏𝑏)
28
29. Для чего это можно использовать
• Операции с множествами очень полезны для приведения данных к нужному формату и удобной записи
компонентов модели
• Вспомним, например, задачу о составлении рациона (см. тренинг): в каждом виде корма содержалось
4 компонента: 3 полезных и 1 вредный. Из-за этого пришлось писать «универсальные» ограничения,
задающие нижнюю и верхнюю границу на содержание компонента в рационе. Из-за этого потребовалось
ввести искусственные границы для максимального содержания компонентов, которые в большинстве
случаев не имели смысла
• Теперь эту задачу мы можем решить более адекватно (здесь приведены только измененные компоненты
модели и данных):
29