Преобразуйте нелинейную функцию в выражение оптимизации

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

Используйте поддерживаемые операции, когда возможно

Обычно создайте свои объективные или нелинейные ограничительные функции при помощи поддерживаемых операций на переменных и выражениях оптимизации. Выполнение так имеет эти преимущества:

В общем случае поддерживаемые операции включают все элементарные математические операции: сложение, вычитание, умножение, деление, степени и элементарные функции, такие как показательные и тригонометрические функции и их инверсии. Несглаженные операции, такие как maxabs, if, и case не поддерживаются. Для полного описания смотрите Поддерживаемые Операции для Переменных и выражений Оптимизации.

Например, предположите, что ваша целевая функция

f(x,y,r)=100(y-x2)2+(r-x)2

где r параметр, который вы предоставляете, и проблема состоит в том, чтобы минимизировать f x и y . Эта целевая функция является суммой квадратов и принимает минимальное значение 0 в точке x=r, y=r2.

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

r = 2;
x = optimvar('x');
y = optimvar('y');
f = 100*(y - x^2)^2 + (r - x)^2;
prob = optimproblem("Objective",f);
x0.x = -1;
x0.y = 2;
[sol,fval] = solve(prob,x0) 
Solving problem using lsqnonlin.

Local minimum found.

Optimization completed because the size of the gradient is less than
the value of the optimality tolerance.
sol = struct with fields:
    x: 2.0000
    y: 4.0000

fval = 8.0661e-29

Решать ту же задачу путем преобразования целевой функции с помощью fcn2optimexpr (не рекомендуемый), сначала запишите цель как анонимную функцию.

fun = @(x,y)100*(y - x^2)^2 + (r - x)^2;
prob.Objective = fcn2optimexpr(fun,x,y);
[sol2,fval2] = solve(prob,x0)
Solving problem using fminunc.

Local minimum found.

Optimization completed because the size of the gradient is less than
the value of the optimality tolerance.
sol2 = struct with fields:
    x: 2.0000
    y: 3.9998

fval2 = 1.7143e-09

Заметьте, что solve использование fminunc на этот раз вместо более эффективного lsqnonlin, и решение, о котором сообщают, для y немного отличается, чем правильное решение 4. Кроме того, fval, о котором сообщают, о 1e-9 вместо 1e-20 (фактическое значение решения точно 0). Эти небольшие погрешности происходят из-за solve не используя более эффективный решатель.

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

Файл функции

Чтобы использовать файл функции в подходе, основанном на проблеме, необходимо преобразовать файл в выражение с помощью fcn2optimexpr.

Например, expfn3.m файл содержит следующий код:

type expfn3.m
function [f,g,mineval] = expfn3(u,v)
mineval = min(eig(u));
f = v'*u*v;
f = -exp(-f);
t = u*v;
g = t'*t + sum(t) - 3;

Эта функция не полностью состоит из поддерживаемых операций из-за min(eig(u)). Поэтому использовать expfn3(u,v) как выражение оптимизации, необходимо сначала преобразовать его с помощью fcn2optimexpr.

Использовать expfn3 как выражение оптимизации, сначала создайте переменные оптимизации соответствующих размеров.

u = optimvar('u',3,3,'LowerBound',-1,'UpperBound',1); % 3-by-3 variable
v = optimvar('v',3,'LowerBound',-2,'UpperBound',2); % 3-by-1 variable

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

[f,g,mineval] = fcn2optimexpr(@expfn3,u,v);

Поскольку все возвращенные выражения являются скаляром, можно сэкономить вычислительное время путем определения размеров выражения с помощью 'OutputSize' аргумент пары "имя-значение". Кроме того, потому что expfn3 вычисляет все выходные параметры, можно сэкономить более вычислительное время при помощи ReuseEvaluation пара "имя-значение".

[f,g,mineval] = fcn2optimexpr(@expfn3,u,v,'OutputSize',[1,1],'ReuseEvaluation',true)
f = 
  Nonlinear OptimizationExpression

    [argout,~,~] = expfn3(u, v)

g = 
  Nonlinear OptimizationExpression

    [~,argout,~] = expfn3(u, v)

mineval = 
  Nonlinear OptimizationExpression

    [~,~,argout] = expfn3(u, v)

Анонимная функция

Чтобы использовать общий нелинейный указатель на функцию в подходе, основанном на проблеме, преобразуйте указатель на выражение оптимизации с помощью fcn2optimexpr. Например, запишите указатель на функцию, эквивалентный mineval и преобразуйте его.

fun = @(u)min(eig(u));
funexpr = fcn2optimexpr(fun,u,'OutputSize',[1,1])
funexpr = 
  Nonlinear OptimizationExpression

    anonymousFunction2(u)

  where:

    anonymousFunction2 = @(u)min(eig(u));

Создайте цель

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

prob = optimproblem;
prob.Objective = f;

Задайте ограничения

Задайте ограничение g <= 0 в задаче оптимизации.

prob.Constraints.nlcons1 = g <= 0;

Также задайте ограничения что u симметрично и это mineval-1/2.

prob.Constraints.sym = u == u.';
prob.Constraints.mineval = mineval >= -1/2;

Просмотрите проблему.

show(prob)
  OptimizationProblem : 

	Solve for:
       u, v

	minimize :
       [argout,~,~] = expfn3(u, v)


	subject to nlcons1:
       arg_LHS <= 0

       where:

         [~,arg_LHS,~] = expfn3(u, v);

	subject to sym:
       u(2, 1) - u(1, 2) == 0
       u(3, 1) - u(1, 3) == 0
       -u(2, 1) + u(1, 2) == 0
       u(3, 2) - u(2, 3) == 0
       -u(3, 1) + u(1, 3) == 0
       -u(3, 2) + u(2, 3) == 0

	subject to mineval:
       arg_LHS >= (-0.5)

       where:

         [~,~,arg_LHS] = expfn3(u, v);

	variable bounds:
       -1 <= u(1, 1) <= 1
       -1 <= u(2, 1) <= 1
       -1 <= u(3, 1) <= 1
       -1 <= u(1, 2) <= 1
       -1 <= u(2, 2) <= 1
       -1 <= u(3, 2) <= 1
       -1 <= u(1, 3) <= 1
       -1 <= u(2, 3) <= 1
       -1 <= u(3, 3) <= 1

       -2 <= v(1) <= 2
       -2 <= v(2) <= 2
       -2 <= v(3) <= 2

Решите задачу

Чтобы решить задачу, вызовите solve. Установите начальную точку x0.

rng default % For reproducibility
x0.u = 0.25*randn(3);
x0.u = x0.u + x0.u.';
x0.v = 2*randn(3,1);
[sol,fval,exitflag,output] = solve(prob,x0)
Solving problem using fmincon.

Feasible point with lower objective function value found.


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:
    u: [3x3 double]
    v: [3x1 double]

fval = -403.4288
exitflag = 
    OptimalSolution

output = struct with fields:
              iterations: 74
               funcCount: 1156
         constrviolation: 0
                stepsize: 1.6235e-06
               algorithm: 'interior-point'
           firstorderopt: 1.1203e-04
            cgiterations: 122
                 message: '...'
            bestfeasible: [1x1 struct]
     objectivederivative: "finite-differences"
    constraintderivative: "finite-differences"
                  solver: 'fmincon'

Просмотрите решение.

disp(sol.u)
    0.5486    0.2067   -0.8420
    0.2067    0.1909    0.4842
   -0.8420    0.4842    0.8262
disp(sol.v)
    2.0000
   -2.0000
    2.0000

Матрица решения u issymmetric. Все значения v в границах.

Copyright 2018–2020 The MathWorks, Inc.

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

|

Похожие темы