Выходная функция для основанной на проблеме оптимизации

В этом примере показано, как использовать выходную функцию, чтобы построить и сохранить историю итераций для нелинейной проблемы. Эта история включает оцененные точки, поисковые направления что использование решателя, чтобы сгенерировать точки и значения целевой функции в оцененных точках.

Для основанного на решателе подхода к этому примеру смотрите Выходные функции.

Функции построения графика имеют тот же синтаксис как выходные функции, таким образом, этот пример также применяется к функциям построения графика, также.

И для основанного на решателе подхода и для подхода, основанного на проблеме, запишите выходную функцию, как будто вы используете основанный на решателе подход. В основанном на решателе подходе вы используете одну векторную переменную, обычно обозначал x, вместо набора переменных оптимизации различных размеров. Таким образом, чтобы записать выходную функцию для подхода, основанного на проблеме, необходимо изучить соответствие между переменными оптимизации и одним основанным на решателе x. Сопоставлять между переменными оптимизации и x, используйте varindex. В этом примере, чтобы избежать беспорядка с переменной оптимизации под названием x, используйте "in" как векторное имя переменной.

Описание проблемы

Проблема состоит в том, чтобы минимизировать следующую функцию переменных x и y:

f=exp(x)(4x2+2y2+4xy+2y+1).

Кроме того, проблема имеет два нелинейных ограничения:

x+y-xy1.5xy10.

Основанный на проблеме Setup

Чтобы настроить проблему в подходе, основанном на проблеме, задайте переменные оптимизации и объект задачи оптимизации.

x = optimvar('x');
y = optimvar('y');
prob = optimproblem;

Целевая функция находится в objfun.m файл.

type objfun
function f = objfun(x,y)
%OBJFUN Objective function.
% Documentation example.

%   Copyright 2018 The MathWorks, Inc.

f = exp(x) * (4*x^2 + 2*y^2 + 4*x*y + 2*y + 1);

Это выражение не является рациональной функцией своих переменных. Поэтому, чтобы включать его в цель, сначала преобразуйте функцию в выражение оптимизации при помощи fcn2optimexpr.

prob.Objective = fcn2optimexpr(@objfun,x,y);

Чтобы включать нелинейные ограничения, создайте ограничительные выражения оптимизации.

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: 34
          algorithm: 'sqp'
            message: '...'
    constrviolation: 0
           stepsize: 1.4788e-07
       lssteplength: 1
      firstorderopt: 8.0068e-10
             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

Смотрите также

Похожие темы