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

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

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

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

И для основанного на решателе подхода и для основанного на проблеме подхода, запишите выходную функцию, как будто вы используете основанный на решателе подход. В основанном на решателе подходе вы используете одну векторную переменную, обычно обозначал 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)

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

Исследуйте массивы functionhistory и searchdirhistory.

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

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

Похожие темы