В этом примере показано, как решить ограниченную нелинейную задачу оптимизации с помощью подхода, основанного на проблеме. Пример демонстрирует типичный поток операций: создайте целевую функцию, создайте ограничения, решите задачу и исследуйте результаты.
Примечание:
Если ваша целевая функция или нелинейные ограничения не состоят из элементарных функций, необходимо преобразовать нелинейные функции в выражения оптимизации с помощью fcn2optimexpr
.
Смотрите последнюю часть этого примера, Альтернативной Формулировки Используя fcn2optimexpr, или Преобразуйте Нелинейную Функцию в Выражение Оптимизации.
Для основанного на решателе подхода к этой проблеме смотрите, Решают Ограниченную Нелинейную задачу, Основанную на решателе.
Рассмотрите задачу минимизации функции Розенброка
по единичному диску, означая диск радиуса 1 с центром в начале координат. Другими словами, найти это минимизирует функцию на множестве . Этой проблемой является минимизация нелинейного функционального предмета к нелинейному ограничению.
Функция Розенброка является стандартной тестовой функцией в оптимизации. Это имеет уникальное минимальное значение 0 достигнутых в точке [1,1]
. Нахождение минимума является проблемой для некоторых алгоритмов, потому что функция имеет неглубокий минимум в очень кривом овраге. Решением для этой проблемы не является в точке [1,1]
потому что та точка не удовлетворяет ограничению.
Этот рисунок показывает два представления функции Розенброка на единичном диске. Вертикальная ось имеет логарифмическое масштабирование; другими словами, график показывает . Линии контура лежат ниже графика поверхности.
rosenbrock = @(x)100*(x(:,2) - x(:,1).^2).^2 + (1 - x(:,1)).^2; % Vectorized function figure1 = figure('Position',[1 200 600 300]); colormap('gray'); axis square; R = 0:.002:1; TH = 2*pi*(0:.002:1); X = R'*cos(TH); Y = R'*sin(TH); Z = log(1 + rosenbrock([X(:),Y(:)])); Z = reshape(Z,size(X)); % Create subplot subplot1 = subplot(1,2,1,'Parent',figure1); view([124 34]); grid('on'); hold on; % Create surface surf(X,Y,Z,'Parent',subplot1,'LineStyle','none'); % Create contour contour(X,Y,Z,'Parent',subplot1); % Create subplot subplot2 = subplot(1,2,2,'Parent',figure1); view([234 34]); grid('on'); hold on % Create surface surf(X,Y,Z,'Parent',subplot2,'LineStyle','none'); % Create contour contour(X,Y,Z,'Parent',subplot2); % Create textarrow annotation(figure1,'textarrow',[0.4 0.31],... [0.055 0.16],... 'String',{'Minimum at (0.7864,0.6177)'}); % Create arrow annotation(figure1,'arrow',[0.59 0.62],... [0.065 0.34]); title("Rosenbrock's Function: Two Views") hold off
rosenbrock
указатель на функцию вычисляет функцию Розенброка в любом количестве 2D точек целиком. Эта Векторизация ускоряет графический вывод функции и может быть полезна в других контекстах для ускорения оценки функции в нескольких точках.
Функция называется целевой функцией. Целевая функция является функцией, которую вы хотите минимизировать. Неравенство называется ограничением. Ограничения ограничивают набор по которому решатель ищет минимум. У вас может быть любое количество ограничений, которые являются неравенствами или уравнениями.
Подход, основанный на проблеме к оптимизации использует переменные оптимизации, чтобы задать цель и ограничения. Существует два подхода для создания выражений с помощью этих переменных:
Для полиномиальных или рациональных функций напишите выражения непосредственно в переменных.
Для других типов функций преобразуйте функции в выражения оптимизации с помощью fcn2optimexpr
. Смотрите, что альтернативная формулировка Использует fcn2optimexpr
в конце этого примера.
Для этой проблемы и целевая функция и нелинейное ограничение являются полиномами, таким образом, можно записать выражения непосредственно в терминах переменных оптимизации. Создайте 2D переменную оптимизации под названием 'x'
.
x = optimvar('x',1,2);
Создайте целевую функцию как полином от переменной оптимизации.
obj = 100*(x(2) - x(1)^2)^2 + (1 - x(1))^2;
Создайте задачу оптимизации под названием prob
наличие obj
как целевая функция.
prob = optimproblem('Objective',obj);
Создайте нелинейное ограничение как полином в переменной оптимизации.
nlcons = x(1)^2 + x(2)^2 <= 1;
Включайте нелинейное ограничение в проблему.
prob.Constraints.circlecons = nlcons;
Рассмотрите проблему.
show(prob)
OptimizationProblem : Solve for: x minimize : ((100 .* (x(2) - x(1).^2).^2) + (1 - x(1)).^2) subject to circlecons: (x(1).^2 + x(2).^2) <= 1
Чтобы решить задачу оптимизации, вызовите solve
. Для проблемы нужна начальная точка, которая является структурой, дающей начальное значение переменной оптимизации. Создайте начальную структуру точки x0
наличие - значение [0 0]
.
x0.x = [0 0]; [sol,fval,exitflag,output] = solve(prob,x0)
Solving problem using fmincon. Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance.
sol = struct with fields:
x: [0.7864 0.6177]
fval = 0.0457
exitflag = OptimalSolution
output = struct with fields:
iterations: 24
funcCount: 34
constrviolation: 0
stepsize: 6.9161e-06
algorithm: 'interior-point'
firstorderopt: 2.1625e-08
cgiterations: 4
message: '...'
bestfeasible: [1x1 struct]
objectivederivative: "reverse-AD"
constraintderivative: "closed-form"
solver: 'fmincon'
Решение показывает exitflag = OptimalSolution
. Этот выходной флаг указывает, что решение является локальным оптимумом. Для получения информации о попытке найти лучшее решение, смотрите, Когда Решатель Успешно выполнится.
Выходное сообщение указывает, что решение удовлетворяет ограничениям. Можно проверить, что решение действительно является допустимым, несколькими способами.
Проверяйте сообщение о неосуществимости в constrviolation
поле output
структура.
infeas = output.constrviolation
infeas = 0
Недопустимость 0 указывает, что решение допустимо.
Вычислите недопустимость в решении.
infeas = infeasibility(nlcons,sol)
infeas = 0
Снова, недопустимость 0 указывает, что решение допустимо.
Вычислите норму x
гарантировать, что это меньше чем или равно 1.
nx = norm(sol.x)
nx = 1.0000
output
структура дает больше информации о процессе решения, таком как количество итераций (24), решатель (fmincon
), и количество вычислений функции (84). Для получения дополнительной информации об этих статистических данных смотрите Допуски и Критерий остановки.
fcn2optimexpr
Для более сложных выражений запишите файлы функции для цели или ограничительных функций, и преобразуйте их в выражения оптимизации с помощью fcn2optimexpr
. Например, базис нелинейной ограничительной функции находится в disk.m
файл:
type disk
function radsqr = disk(x) radsqr = x(1)^2 + x(2)^2;
Преобразуйте этот файл функции в выражение оптимизации.
radsqexpr = fcn2optimexpr(@disk,x);
Кроме того, можно также преобразовать rosenbrock
указатель на функцию, который был задан в начале стандартной программы графического вывода в выражение оптимизации.
rosenexpr = fcn2optimexpr(rosenbrock,x);
Создайте задачу оптимизации с помощью этих конвертированных выражений оптимизации.
convprob = optimproblem('Objective',rosenexpr,'Constraints',radsqexpr <= 1);
Просмотрите новую проблему.
show(convprob)
OptimizationProblem : Solve for: x minimize : anonymousFunction2(x) where: anonymousFunction2 = @(x)100*(x(:,2)-x(:,1).^2).^2+(1-x(:,1)).^2; subject to : disk(x) <= 1
Решите новую задачу. Решение является по существу тем же самым как прежде.
[sol,fval,exitflag,output] = solve(convprob,x0)
Solving problem using fmincon. Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance.
sol = struct with fields:
x: [0.7864 0.6177]
fval = 0.0457
exitflag = OptimalSolution
output = struct with fields:
iterations: 24
funcCount: 84
constrviolation: 0
stepsize: 6.9162e-06
algorithm: 'interior-point'
firstorderopt: 2.4373e-08
cgiterations: 4
message: '...'
bestfeasible: [1x1 struct]
objectivederivative: "finite-differences"
constraintderivative: "finite-differences"
solver: 'fmincon'
Для списка поддерживаемых функций смотрите Поддерживаемые Операции для Переменных и выражений Оптимизации.