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

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

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

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

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

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

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

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

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

x+y-xy1.5xy-10.

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

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

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.

Figure contains an axes object. The axes object with title Sequence of Points Computed by fmincon contains 22 objects of type line, text.

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: 0
                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);

Для списка поддерживаемых функций смотрите Поддерживаемые Операции для Переменных и выражений Оптимизации.

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

Похожие темы