В этом примере показано, как использовать выходную функцию, чтобы построить и сохранить историю итераций для нелинейной проблемы. Эта история включает оцененные точки, поисковые направления что использование решателя, чтобы сгенерировать точки и значения целевой функции в оцененных точках.
Для основанного на решателе подхода к этому примеру смотрите Выходные функции для Optimization Toolbox™.
Функции построения графика имеют тот же синтаксис как выходные функции, таким образом, этот пример также применяется к функциям построения графика.
И для основанного на решателе подхода и для подхода, основанного на проблеме, запишите выходную функцию согласно основанному на решателе подходу. В основанном на решателе подходе вы используете одну векторную переменную, обычно обозначал x
, вместо набора переменных оптимизации различных размеров. Таким образом, чтобы записать выходную функцию для подхода, основанного на проблеме, необходимо изучить соответствие между переменными оптимизации и одним основанным на решателе x
. Сопоставлять между переменными оптимизации и x
, используйте varindex
. В этом примере, чтобы избежать беспорядка с переменной оптимизации под названием x
, используйте "in"
как векторное имя переменной.
Проблема состоит в том, чтобы минимизировать следующую функцию переменных x
и y
:
Кроме того, проблема имеет два нелинейных ограничения:
Чтобы настроить проблему в подходе, основанном на проблеме, задайте переменные оптимизации и объект задачи оптимизации.
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 outfun
function 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);
Для списка поддерживаемых функций смотрите Поддерживаемые Операции на Переменных и выражениях Оптимизации.