ЛР-01: Линейное программирование для начинающих#
1) Что это вообще такое#
Линейное программирование (ЛП) это способ найти лучшее решение (максимум прибыли, минимум затрат и т.д.) при ограниченных ресурсах.
Есть три обязательные части:
переменные (что выбираем)
целевая функция (что хотим максимизировать или минимизировать)
ограничения (чего нельзя нарушать)
Ключевое слово: линейное. Это значит, что все формулы состоят из сумм вида:
без квадратов, произведений переменных и т.п.
2) Интуитивный пример#
Вы производите 2 вида продукции:
изделие A: прибыль 40
изделие B: прибыль 30
Ресурсы:
сырье: на A нужно 2, на B нужно 1, всего 100
время: на A нужно 1, на B нужно 1, всего 80
Переменные:
\(x_1\) = сколько сделать A
\(x_2\) = сколько сделать B
Модель:
при
Смысл:
максимизируем прибыль
не выходим за лимиты ресурсов
отрицательное производство запрещено
3) Общая математическая постановка#
Векторная форма#
при
Где:
\(x \in \mathbb{R}^n\) — вектор переменных
\(c \in \mathbb{R}^n\) — коэффициенты целевой функции
\(A \in \mathbb{R}^{m \times n}\) — матрица ограничений
\(b \in \mathbb{R}^m\) — доступные ресурсы
Если по-человечески, то A — это большая таблица норм расхода, b — это запас ресурсов, а c — это ценность каждой переменной в целевой функции.
Покомпонентно#
при
4) Какие бывают ограничения#
\(\le\) (ресурс не превысить)
\(\ge\) (минимум обеспечить)
\(=\) (точный баланс)
Если переменная свободная по знаку, то её заменяют:
5) Стандартная и каноническая формы#
Часто для алгоритмов задачу переводят в специальный вид.
Стандартная форма (частый вариант)#
Для max-задачи:
Каноническая форма (для аккуратной записи ограничений)#
Неравенства \(\le\) превращают в равенства добавлением добавочных переменных (slack, то есть запаса ресурса):
\(s_1\) и \(s_2\) показывают остаток ресурса. Если ребёнку объяснить совсем просто, то это «сколько ресурса осталось в коробке после выполнения плана».
6) Геометрический смысл (очень важно)#
Каждое линейное ограничение задаёт полуплоскость (в 2D) или полупространство (в nD).
Пересечение всех ограничений даёт допустимую область.
Целевая функция это семейство параллельных гиперплоскостей.
Оптимум достигается в одной из вершин допустимого многогранника.
Почему вершина? Это фундаментальный факт ЛП: если оптимум существует, то одна из вершин допустимой области оптимальна.
7) Что именно изучаем в этой ЛР#
В этой лабораторной мы целенаправленно изучаем четыре вещи:
Геометрический метод для задачи с двумя переменными.
Формы математической записи ЛП (обычная, матричная, канонизированная через добавочные переменные).
Теоретическую связку через Лагранж/ККТ и двойственность.
Программное решение в Python через
linprog.
Симплекс-таблицы, пивот-правила и пошаговый табличный алгоритм здесь не рассматриваются.
8) Как не перепутать обозначения (методически важно)#
Чтобы не смешивать подходы, держите простое правило:
Геометрический метод:
переменные \(x_1, x_2\);
ограничения как прямые/полуплоскости;
оптимум ищем по вершинам допустимой области.
Формы записи задачи:
векторно-матрично: \(c, A, b\);
после канонизации: добавочные переменные \(s_1, s_2, \dots\).
Лагранж/ККТ:
множители Лагранжа для ограничений обозначаем \(y\) (и \(s\) для \(x \ge 0\) в выбранной записи);
условия ККТ: допустимость + стационарность + комплементарная нежёсткость.
Python (
scipy.optimize.linprog):
используем
c,A_ub,b_ub,bounds, результатres.x,res.fun.
Это полезно помнить так: теория говорит «что означает задача», а linprog помогает честно проверить наши вычисления на компьютере.
Обозначения симплекс-таблиц (например, «входящая/выходящая переменная», пивот и т.п.) в этой ЛР не используем.
9) Когда задача «плохая»#
Недопустима: ограничений слишком много/жёсткие, нет ни одной точки.
Неограничена: цель можно улучшать бесконечно.
Вырождение: в вершине одновременно активны «лишние» ограничения, из-за чего анализ чувствителен к малым изменениям.
Множественные оптимумы: целая грань оптимальных решений.
10) Двойственная задача: зачем она нужна на практике#
Очень частый вопрос: «Мы уже нашли оптимальный план выпуска. Зачем ещё одна (двойственная) задача?»
Короткий ответ:
прямая задача отвечает на вопрос «сколько производить?»;
двойственная задача отвечает на вопрос «сколько стоит дополнительная единица каждого ресурса?».
10.1. Практическая польза двойственной задачи#
Показывает «узкие места» по ресурсам:
если теневая цена ресурса положительна, ресурс дефицитный и реально ограничивает прибыль;
если теневая цена ноль, запас этого ресурса сейчас не ограничивает оптимум.
Даёт быстрые оценки «что будет, если увеличить лимит ресурса»:
при малых изменениях прирост оптимума примерно равен теневой цене.
Помогает экономически объяснять решение:
не просто «получилось \(x_1=...,x_2=...\)», а «вот ценность каждого ресурса для бизнеса».
Даёт проверку корректности:
в оптимуме значения прямой и двойственной задач совпадают (сильная двойственность).
10.2. Формально#
Прямая задача:
Двойственная задача:
Здесь \(y_i\) — теневая цена ресурса \(i\).
10.3. Как получить двойственную задачу пошагово (откуда берутся коэффициенты)#
Ниже правило именно для формы, которую мы используем в ЛР:
Шаги преобразования:
Каждому ограничению прямой задачи соответствует одна двойственная переменная:
если в прямой \(m\) ограничений, то в двойственной будет \(m\) переменных \(y_1,\dots,y_m\).
Каждой переменной прямой задачи соответствует одно ограничение двойственной:
если в прямой \(n\) переменных \(x_1,\dots,x_n\), то в двойственной будет \(n\) ограничений.
Коэффициенты целевой функции двойственной берутся из правых частей прямой:
в прямой были \(b_1,\dots,b_m\);
в двойственной цель: \(\min \sum_{i=1}^m b_i y_i\).
Правые части ограничений двойственной берутся из коэффициентов цели прямой:
в прямой цель: \(\max \sum_{j=1}^n c_j x_j\);
в двойственной в правых частях стоят \(c_1,\dots,c_n\).
Матрица коэффициентов «переворачивается» (транспонируется):
коэффициент \(a_{ij}\) из ограничения \(i\) при переменной \(x_j\) в прямой становится коэффициентом при \(y_i\) в ограничении \(j\) двойственной.
Короткая шпаргалка знаков для нашей формы:
\(\max \rightarrow \min\);
\(\le \rightarrow \ge\);
\(x \ge 0 \rightarrow y \ge 0\).
Пример «по элементам» на числах#
Пусть прямая задача:
Здесь
Как строим двойственную:
из \(b=(10,8)\) получаем цель \(\min \phi = 10y_1 + 8y_2\);
1-е ограничение двойственной строится из 1-го столбца \(A\): \((2,1)\) и правой части \(c_1=5\): \(2y_1 + y_2 \ge 5\);
2-е ограничение двойственной строится из 2-го столбца \(A\): \((1,2)\) и правой части \(c_2=4\): \(y_1 + 2y_2 \ge 4\);
знаки: \(y_1, y_2 \ge 0\).
Итоговая двойственная:
10.4. Как «читать» двойственные ограничения#
Ограничение вида
означает: «оценённая стоимость ресурсов, нужных на 1 единицу продукта \(j\), не должна быть меньше прибыли \(c_j\) от этой единицы».
Это важный экономический фильтр согласованности цен ресурсов и ценности продукции.
10.5. Реалистичный мини-сюжет (управленческий взгляд)#
Используем ту же пару прямой и двойственной задач из раздела 10.3. Чтобы не дублировать одинаковые формулы, здесь фокусируемся только на интерпретации чисел.
Интерпретация:
\(y_1\) — «внутренняя цена» 1 единицы ресурса 1;
\(y_2\) — «внутренняя цена» 1 единицы ресурса 2;
минимум \(\phi\) — минимальная оценка стоимости всего запаса ресурсов при таких ценах.
Для этой же модели в оптимуме получается \(y_1=2,\;y_2=1\), и
Это ровно совпадает с максимальной прибылью прямой задачи:
Управленческий смысл:
если можно купить ещё 1 единицу ресурса 1 «дешевле чем 2», это выгодно;
если 1 единица ресурса 2 стоит «дешевле чем 1», это тоже выгодно;
если дороже, расширение ресурса обычно не даёт экономического смысла в текущей точке.
10.6. Ещё одна простая числовая пара: обычная (прямая) и двойственная#
Обычная (прямая) задача:
Двойственная к ней:
Короткая проверка:
для прямой задачи оптимум в точке \(x_1=1,\;x_2=3\), поэтому \(z_{\max}=3\cdot1+2\cdot3=9\);
для двойственной задачи оптимум в точке \(y_1=1,\;y_2=1\), поэтому \(\phi_{\min}=4\cdot1+5\cdot1=9\).
Получилось \(z_{\max}=\phi_{\min}=9\), то есть сильная двойственность подтверждается на конкретных числах.
10.7. Производственный пример для контроля затрат и защиты от завышения цен#
Сценарий: предприятие выпускает два изделия, а отдел закупок хочет контролировать, чтобы деньги на ресурсы расходовались целево и без завышений.
Прямая (производственная) задача:
Интерпретация:
\(x_1, x_2\) — объёмы выпуска;
1-е ограничение — расход сырья (лимит 40 единиц);
2-е ограничение — загрузка времени/персонала (лимит 30 единиц).
Двойственная (контур внутреннего ценового контроля):
Здесь:
\(y_1\) — внутренняя предельная цена 1 единицы сырья;
\(y_2\) — внутренняя предельная цена 1 единицы времени/персонала.
Для этой пары задач оптимум:
Что это даёт для финансового контроля:
Защита от завышения цен на ресурс:
если поставщик предлагает 1 единицу сырья по цене заметно выше \(3\), это сигнал риска переплаты;
если 1 единица времени/услуги стоит заметно выше \(3\), логика та же.
Проверка конкретной заявки на закупку:
пусть планируют докупить \(\Delta r_1\) единиц сырья и \(\Delta r_2\) единиц времени;
экономически обоснованный верхний предел затрат:
если счёт \(C_{\text{invoice}}\) существенно выше \(C_{\max}\) (с учётом допустимого порога), заявку нужно эскалировать на пересмотр условий.
Защита от нецелевого расхода:
если статья затрат не связана ни с одним ресурсом модели (не попадает в ограничения), у неё нет обоснованной теневой цены в этой задаче;
такие расходы должны проходить отдельное согласование, а не закрываться «производственным» бюджетом ЛП-модели.
11) Сильная двойственность и комплементарная нежёсткость#
Сильная двойственность#
Если у прямой и двойственной задач есть оптимум, то
Комплементарная нежёсткость#
Для оптимальных \(x^{*}, y^{*}\):
Смысл:
если ограничение «с запасом», его двойственная цена 0
если переменная > 0, её reduced cost = 0
12) Метод функции Лагранжа и ККТ (когда применимо)#
12.1. В чём идея метода Лагранжа#
Метод Лагранжа добавляет ограничения в целевую функцию через множители. Так мы ищем не просто «лучшее значение функции», а точку, где одновременно выполнены и цель, и ограничения.
Для задач только с равенствами используют классическую функцию Лагранжа. Для задач с неравенствами (как в ЛП) обычно используют условия Каруша-Куна-Таккера (ККТ), это расширение метода Лагранжа.
12.2. Общие правила составления лагранжиана (и применение к нашей max-задаче)#
Общий вид (для задачи минимизации)#
Пусть задача записана так:
Тогда лагранжиан:
Правило знаков (чтобы не перепутать)#
Ограничение вида \(\le\):
в минимизации удобно писать как \(g(x) \le 0\) и добавлять \(+\lambda g(x)\), где \(\lambda \ge 0\).
Ограничение вида \(\ge\):
можно либо умножить на \(-1\) и свести к \(\le\);
либо оставить как есть и добавить с противоположным знаком (эквивалентно).
Ограничение-равенство:
множитель добавляется линейно, без ограничения знака.
Для максимизации:
либо перейти к эквивалентной минимизации \(-f(x)\);
либо использовать ту же логику напрямую, но строго согласовать знак множителя с формой ограничения.
практично: если в задаче max ограничение записано как \(q(x) \ge 0\), используйте \(+\lambda q(x)\) при \(\lambda \ge 0\); если как \(q(x) \le 0\), используйте \(-\lambda q(x)\) при \(\lambda \ge 0\).
Чек-лист составления лагранжиана#
Привести ограничения к единому удобному виду.
Назначить по одному множителю на каждое ограничение.
Проверить знаки множителей в соответствии с типом ограничения.
Записать сумму: «цель + множители * ограничения».
Проверить размерности и физический смысл каждого слагаемого.
Применение к нашей max-постановке ЛП#
Прямая задача:
Выбираем форму ограничений:
для ресурса: \(b-Ax \ge 0\);
для неотрицательности: \(x \ge 0\).
Для удобства возьмём обозначения:
\(\lambda\) — множители для ресурсных ограничений;
\(\nu\) — множители для ограничений неотрицательности переменных.
Тогда лагранжиан можно записать как:
Здесь:
\(\lambda\) — множители для ограничений \(Ax \le b\) (в форме \(b-Ax \ge 0\));
\(\nu\) — множители для ограничений \(x \ge 0\).
12.3. Условия ККТ для ЛП#
В точке оптимума (при выполнении условий регулярности, а для ЛП это стандартный случай) выполняются:
Прямая допустимость:
Двойственная допустимость:
Комплементарная нежёсткость:
Почему это важно методически:
если ограничение по ресурсу не активно (есть запас), соответствующий множитель равен 0;
если переменная положительна, её «штраф» \(\nu_j\) равен 0.
12.4. Связь с двойственной задачей#
Из условия
следует
Это ровно ограничение двойственной задачи. Поэтому метод Лагранжа/ККТ естественно приводит к двойственности в ЛП.
12.5. Связанный пример: геометрия -> ККТ -> экономический вывод#
Возьмём ту же задачу из ЛР-01 (реальная интерпретация: два продукта и два ограниченных ресурса):
Из геометрического решения уже известно:
Запишем лагранжиан:
Проверим активность ограничений в оптимуме:
Оба ресурсных ограничения активны (запаса нет).
Так как \(x_1^{*}>0,\;x_2^{*}>0\), по комплементарной нежёсткости:
Условия стационарности по \(x_1, x_2\):
Отсюда:
Проверка экономического смысла:
ресурс 1 ценнее ресурса 2 (2 против 1), значит именно первый ресурс чаще становится главным ограничителем роста прибыли;
эти значения совпадают с интерпретацией двойственной задачи и с сильной двойственностью.
если в разделе про двойственную задачу используется обозначение \(y\), то здесь просто \(y \equiv \lambda\).
Итог: мы связали три уровня одной и той же математики:
геометрический оптимум;
формальные условия ККТ;
управленческая интерпретация через цены ресурсов.
13) Чувствительность решения#
После нахождения оптимума обычно спрашивают:
что будет, если изменить прибыль \(c_j\)?
что будет, если увеличить ресурс \(b_i\)?
Анализ чувствительности показывает диапазоны, где не меняется активный набор ограничений и структура оптимума.
Практическая польза:
быстро оценивать «а если» без полного пересчёта
понимать, какой ресурс самый ценный
14) Как решать ЛП на практике#
Ввести переменные (понятный физический смысл).
Записать цель в линейной форме.
Записать все ограничения (единицы измерения проверять обязательно).
Добавить условия знака.
Проверить модель на здравый смысл (например, нулевое решение должно быть интерпретируемым).
Решить (геометрически для 2D, через Лагранж/ККТ для теоретического анализа, либо solver в Python).
Интерпретировать результат на языке предметной области.
15) Типичные ошибки начинающих#
Перепутан \(\max\) и \(\min\).
Перепутаны знаки \(\le\) и \(\ge\).
Не добавлены ограничения неотрицательности.
Смешаны единицы измерения (часы, минуты, кг).
Нелинейная зависимость записана как линейная (или наоборот).
«Решили математику», но не проверили реалистичность решения.
16) Мини-шпаргалка формул#
Прямая (max)#
Двойственная (min)#
Сильная двойственность#
Комплементарная нежёсткость#
17) Что важно вынести для ЛР-01#
ЛП это не «сложная магия», а аккуратная запись реальной задачи в линейных формулах.
Самый критичный этап это правильно построить модель, а не нажать кнопку «solve».
Оптимум ищется среди вершин допустимой области.
Двойственные переменные дают экономический смысл: ценность ресурсов.
Если в ЛР-01 требуется отчёт, структура обычно такая:
постановка задачи словами
математическая модель
метод решения
вычислительный результат
экономическая/предметная интерпретация