Введение в Оптимизацию с ограничениями на SciPy 2023
1. Введение
Оптимизация на SciPy
Оптимизация - это процесс выбора наилучших элементов из набора потенциальных кандидатов для достижения конкретной цели.
Мы выполняем множество задач по оптимизации в нашей повседневной жизни: находим кратчайший или быстрейший маршрут, чтобы добраться до пункта назначения, готовим список дел с ежедневными заданиями, упорядоченными по приоритету, покупаем продукты.
Мы можем описать такие проблемы, начиная с определения целевой функции f(x).
Давайте представим, что мы организуем поездку в другой город и пытаемся определить подходящее время отправления. В этом примере целевая функция f(x) представляет собой продолжительность поездки в зависимости от времени отправления x.
Мы можем сформулировать задачу оптимизации как определение минимального или максимального значения целевой функции. В нашем примере мы хотим определить время отправления, которое сведёт к минимуму продолжительность поездки:
В других сценариях мы можем захотеть максимизировать f(x). Например, когда цель представляет собой вероятность или возврат инвестиций. Тем не менее, максимизация функции эквивалентна минимизации её отрицательного значения. Таким образом, можно сосредоточиться только на проблемах минимизации:
В реальных приложениях нам может потребоваться применить ограничения к нашей задаче оптимизации. Например, мы можем захотеть найти самый быстрый маршрут, но не хотим платить за проезд или путешествовать ночью. Мы определяем ограниченную оптимизацию как процесс минимизации целевой функции при некоторых логических условиях, которые могут отражать:
- ограничения реального мира;
- физический смысл входных переменных;
- контекстуальные обстоятельства.
В этом посте мы делимся примером оптимизации с использованием SciPy, популярной библиотеки Python для научных вычислений. В частности, мы исследуем наиболее распространённые типы ограничений: границы, линейные и нелинейные ограничения.
2. Реализация
2.1 Неограниченная оптимизация
Мы начинаем с простой задачи неограниченной оптимизации и позже добавляем ограничения к входным переменным.
Импортируйте необходимые библиотеки:
Представьте себе следующую многомерную целевую функцию:
Её уклон относительно x₀ и x₁ равен...
Давайте сгенерируем данные и понаблюдаем за значениями функции для x₀, x₁ ∈ [-1, 1]:
В нашем примере целевая функция невыпуклая и обладает несколькими минимумами.
Это подразумевает, что, в зависимости от начальной точки, проблема может сходиться к другому минимизатору.
Мы можем решить проблему оптимизации, используя полезную функцию scipy.optimize.minimize следующим образом:
Примечательно, что мы применяем метод trust-constr. Он позволяет оптимизировать функцию с учётом ограничений. Более подробная информация о методе доступна в документации к пакету и в "Trust-region methods" (Conn, Gould and Toint; 2000).
Приведённый выше фрагмент кода возвращает найденный минимизатор:
Давайте построим его:
Теперь мы можем поэкспериментировать с добавлением ограничений.
2.2 Границы
Давайте рассмотрим наш предыдущий пример о поиске самой быстрой поездки между двумя городами с использованием времени отправления в качестве входной переменной. Мы можем ожидать большего или меньшего трафика в зависимости от часа дня. Стремясь свести к минимуму продолжительность поездки, модель может также предложить, например, путешествовать ночью.
Хотя это может привести к самой короткой поездке, мы можем предпочесть путешествовать в дневное время. Таким образом, мы могли бы попросить модель найти кратчайшую поездку, учитывая время отправления только с 7.00 утра до 6.00 вечера.
Вот тут-то и появляются границы. Границы - это просто ограничения на равенство или неравенство входных переменных. Они позволяют оценивать целевую функцию исключительно в пределах указанных диапазонов.
В нашем случае предположим, что у нас есть следующие приемлемые значения для x₀ и x₁:
Мы можем легко передать эти значения объекту Bounds и выполнить новый эксперимент по оптимизации следующим образом:
Задача оптимизации теперь приводит к другому решению, поскольку предыдущий массив точек ([0, 0]) не попадает в допустимую область:
Наконец, мы можем построить новый минимум и допустимую область и наблюдать область, в которой оценивалось f (x):
2.3 Линейные ограничения
Линейные ограничения определяют линейные отношения между переменными оптимизации. Например, давайте представим, что это x₀ и x₁:
Мы можем легко переписать эти условия как линейную систему и передать их объекту LinearConstraint перед выполнением задачи оптимизации:
Новое решение заключается в...
Допустимая область f(x) соответствует части пространства, ограниченной пересечением гиперплоскостей. Давайте наметим эти границы:
2.4 Нелинейные ограничения
Мы также можем исследовать целевую функцию в пределах области, определяемой нелинейными ограничениями, используя объект NonlinearConstraint. Предположим, что это x₀ и x₁:
Мы оптимизируем f(x) следующим образом:
Аналогично предыдущим примерам, мы могли бы наблюдать цель и найденный минимизатор, учитывая текущее ограничение:
2.5 Совместное применение различных типов ограничений
Мы можем комбинировать границы, а также линейные и нелинейные ограничения следующим образом:
Отметим, что не все методы оптимизации поддерживают границы и/или ограничения. Дополнительную информацию можно найти в документации к пакету.
3. Заключение
В этом посте мы рассмотрели различные типы Оптимизации с ограничениями. В частности, мы поделились практическими примерами Python с использованием библиотеки SciPy. Примеры сопровождаются графиками, которые позволяют визуально проверить различные ограничения.
Статья была взята из этого источника: