В этом примере показано, как использовать функцию вывода для построения графика и сохранения истории итераций для нелинейной задачи. Эта история включает вычисленные точки, направления поиска, которые решатель использует для генерации точек, и значения целевой функции в вычисленных точках.
Подход к этому примеру на основе решателя см. в разделе Функции вывода для Toolbox™ оптимизации.
Функции печати имеют тот же синтаксис, что и функции вывода, поэтому этот пример также применим к функциям печати.
Как для подхода, основанного на решателях, так и для подхода, основанного на задачах, следует записать функцию вывода в соответствии с подходом, основанным на решателях. В подходе на основе решателя используется одна векторная переменная, обычно обозначаемая xвместо набора переменных оптимизации различных размеров. Таким образом, чтобы записать функцию вывода для подхода на основе задач, необходимо понять соответствие между переменными оптимизации и одним решателем. x. Сопоставление между переменными оптимизации и x, использовать varindex. В этом примере во избежание путаницы с переменной оптимизации с именем x, использовать "in" в качестве имени переменной вектора.
Проблема заключается в минимизации следующей функции переменных x и y:
4xy + 2y + 1).
Кроме того, проблема имеет два нелинейных ограничения:
Чтобы настроить задачу в подходе на основе задач, определите переменные оптимизации и объект задачи оптимизации.
x = optimvar('x'); y = optimvar('y'); prob = optimproblem;
Определите целевую функцию как выражение в переменных оптимизации.
f = exp(x)*(4*x^2 + 2*y^2 + 4*x*y + 2*y + 1);
Включить целевую функцию в prob.
prob.Objective = f;
Чтобы включить нелинейные ограничения, создайте выражения ограничений оптимизации.
cons1 = x + y - x*y >= 1.5; cons2 = x*y >= -10; prob.Constraints.cons1 = cons1; prob.Constraints.cons2 = cons2;
Поскольку это нелинейная проблема, необходимо включить начальную структуру точек x0. Использовать x0.x = –1 и x0.y = 1.
x0.x = -1; x0.y = 1;
outfun функция вывода записывает историю точек, сгенерированных fmincon во время итераций. Функция вывода также отображает точки и сохраняет отдельную историю направлений поиска для sqp алгоритм. Направление поиска - это вектор от предыдущей точки к следующей точке, который fmincon пытается. Во время последнего шага функция вывода сохраняет историю в переменных рабочей области и сохраняет историю значений целевой функции на каждом итеративном шаге.
Необходимый синтаксис функций вывода оптимизации см. в разделах Функция вывода и Синтаксис функции графика.
Функция вывода принимает в качестве входного значения одну векторную переменную. Но у текущей проблемы есть две переменные. Чтобы найти сопоставление между переменными оптимизации и входной переменной, используйте varindex.
idx = varindex(prob); idx.x
ans = 1
idx.y
ans = 2
Сопоставление показывает, что x является переменной 1 и y является переменной 2. Таким образом, если входной переменной присвоено имя in, то x = in(1) и y = in(2).
type outfunfunction stop = outfun(in,optimValues,state,idx)
persistent history searchdir fhistory
stop = false;
switch state
case 'init'
hold on
history = [];
fhistory = [];
searchdir = [];
case 'iter'
% Concatenate current point and objective function
% value with history. in must be a row vector.
fhistory = [fhistory; optimValues.fval];
history = [history; in(:)']; % Ensure in is a row vector
% Concatenate current search direction with
% searchdir.
searchdir = [searchdir;...
optimValues.searchdirection(:)'];
plot(in(idx.x),in(idx.y),'o');
% Label points with iteration number and add title.
% Add .15 to idx.x to separate label from plotted 'o'
text(in(idx.x)+.15,in(idx.y),...
num2str(optimValues.iteration));
title('Sequence of Points Computed by fmincon');
case 'done'
hold off
assignin('base','optimhistory',history);
assignin('base','searchdirhistory',searchdir);
assignin('base','functionhistory',fhistory);
otherwise
end
end
Включите функцию вывода в оптимизацию, установив OutputFcn вариант. Кроме того, установите Algorithm для использования 'sqp' вместо алгоритма по умолчанию 'interior-point' алгоритм. Проход idx к функции вывода в качестве дополнительного параметра на последнем входе. См. раздел Передача дополнительных параметров.
outputfn = @(in,optimValues,state)outfun(in,optimValues,state,idx); opts = optimoptions('fmincon','Algorithm','sqp','OutputFcn',outputfn);
Выполните оптимизацию, включая функцию вывода, с помощью 'Options' аргумент пары имя-значение.
[sol,fval,eflag,output] = solve(prob,x0,'Options',opts)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: -9.5474
y: 1.0474
fval = 0.0236
eflag =
OptimalSolution
output = struct with fields:
iterations: 10
funcCount: 22
algorithm: 'sqp'
message: '...'
constrviolation: 1.2434e-14
stepsize: 1.4785e-07
lssteplength: 1
firstorderopt: 7.1930e-10
bestfeasible: [1x1 struct]
objectivederivative: "reverse-AD"
constraintderivative: "closed-form"
solver: 'fmincon'
Проверьте журнал итераций. Каждая строка optimhistory матрица представляет одну точку. Последние несколько точек очень близки, что объясняет, почему в построенной последовательности показаны надпечатанные числа для точек 8, 9 и 10.
disp('Locations');disp(optimhistory)Locations -1.0000 1.0000 -1.3679 1.2500 -1.6509 1.1813 -3.5870 2.0537 -4.4574 2.2895 -5.8015 1.5531 -7.6498 1.1225 -8.5223 1.0572 -9.5463 1.0464 -9.5474 1.0474 -9.5474 1.0474
Осмотрите searchdirhistory и functionhistory массивы.
disp('Search Directions');disp(searchdirhistory)Search Directions
0 0
-0.3679 0.2500
-0.2831 -0.0687
-1.9360 0.8725
-0.8704 0.2358
-1.3441 -0.7364
-2.0877 -0.6493
-0.8725 -0.0653
-1.0241 -0.0108
-0.0011 0.0010
0.0000 -0.0000
disp('Function Values');disp(functionhistory)Function Values
1.8394
1.8513
1.7757
0.9839
0.6343
0.3250
0.0978
0.0517
0.0236
0.0236
0.0236
fcn2optimexprЕсли целевая функция или функции нелинейных ограничений не состоят из элементарных функций, необходимо преобразовать функции в выражения оптимизации с помощью fcn2optimexpr. См. раздел Преобразование нелинейной функции в выражение оптимизации. В этом примере вводится следующий код:
fun = @(x,y)exp(x)*(4*x^2 + 2*y^2 + 4*x*y + 2*y + 1); f = fcn2optimexpr(fun,x,y);
Список поддерживаемых функций см. в разделе Поддерживаемые операции с переменными и выражениями оптимизации.