Tutorial NlOpt¶
Зачем это нужно?¶
В современных компетенциях инженерных или научных специальностей всё чаще приходится сталкиваться с теми или иными задачами требующими оптимизации функции. В общем смысле под оптимизацией понимают поиск экстремума исследуемой функции.
$$f(x,y) \rightarrow max(min)$$
Заметим, что в случае простейших школьных функций одной переменной достаточно всего лишь приравнять производную от этой функции к нулю и решить полученное уравнение. Но в более серьёзных задачах, где функции могут уже зависеть от нескольких переменных, такой метод может стать невозможным. Заметим также, что в зависимости от задачи и самой функции, требуется применять разный алгоритм оптимизации.
К сожалению, использование внутренних команд питон может быть недостаточно для решения поставленной проблемы. В помощь этому приведем туториал по основам использования мультиязычной и мультиплатформенной библиотеки NlOpt https://nlopt.readthedocs.io/en/latest/. В ней реализовано большое количество различных алгоритмов оптимизации число которых растёт, благодаря поддержке со стороны разработчиков. В качестве примера разберём несколько алгоритмов для оптимизации функции Химмельблау на языке питон. Будет приведён готовый программный код, который сразу можно будет использовать на практике.
В туториале опущен вопрос по установке модуля на компьютер. С этим необходимо будет справиться самостоятельно.
Сам процесс написания кода¶
Вид функции Химмельблау $$f(x,y)=(x^2+y-11)^2+(x+y^2-7)^2$$
Вначале введём наши модули
import nlopt
from numpy import *
Вторым этапом распишем функцию myfunc Для этого в строках grad[0] и grad[1] записываются частные производные функции от первой и второй переменных соответственно. myfunc возвращает саму функцию Химмельблау.
def myfunc(x, grad):
if grad.size > 0:
grad[0] = 4.0*x[0]*(x[0]**2+x[1]-11.0)+2.0*(x[0]+x[1]**2-7.0)
grad[1] = 2.0*(x[0]**2+x[1]-11.0)+4.0*x[1]*(x[0]+x[1]**2-7.0)
return ((x[0]**2+x[1]-11.0)**2+(x[0]+x[1]**2-7.0)**2)
Затем выбираем сам алгоритм оптимизации. На сайте представлен полный список всех алгоритмов и их описание. Со списком можно ознакомиться по ссылке https://nlopt.readthedocs.io/en/latest/NLopt_Algorithms/ Обращаем внимание, что 2 означает количество переменных от которых зависит исследуемая функция.
opt = nlopt.opt(nlopt.LN_BOBYQA, 2)
Дальше по пунктам:
- Запускам нашу функцию
- Задаём точность
- Выбираем начальную точку
- Задаём переменную, которая и будет равна оптимальному значению функции
- Вывод полученных результатов
opt.set_min_objective(myfunc)
opt.set_xtol_rel(1e-6)
x= opt.optimize([ 12.5, 1.5])
minf = opt.last_optimum_value()
print ("optimum at ", x[0], x[1])
print ("minimum value = ", minf)
optimum at -2.8051180810418685 3.131312512221773 minimum value = 2.5499918689535215e-15
На этом всё. В дальнейших уроках разберём оптимизацию с ограничением.
Искренне ваш, Александр Васильев