Этот раздел показывает, как выбрать, преобразовать ли нелинейную функцию в выражение оптимизации или создать выражение из поддерживаемых операций на переменных оптимизации. Раздел также показывает, как преобразовать функцию, при необходимости, при помощи fcn2optimexpr.
Обычно создайте свои объективные или нелинейные ограничительные функции при помощи поддерживаемых операций на переменных и выражениях оптимизации. Выполнение так имеет эти преимущества:
solve включает градиенты, вычисленные автоматическим дифференцированием. Смотрите Эффект Автоматического Дифференцирования в Основанной на проблеме Оптимизации.
solve имеет более широкий выбор доступных решателей. При использовании fcn2optimexpr, solve использование только fmincon или fminunc.
В общем случае поддерживаемые операции включают все элементарные математические операции: сложение, вычитание, умножение, деление, степени и элементарные функции, такие как показательные и тригонометрические функции и их инверсии. Несглаженные операции, такие как maxabs, if, и case не поддерживаются. Для полного описания смотрите Поддерживаемые Операции на Переменных и выражениях Оптимизации.
Например, предположите, что ваша целевая функция
где параметр, который вы предоставляете, и проблема состоит в том, чтобы минимизировать и . Эта целевая функция является суммой квадратов и принимает минимальное значение 0 в точке , .
Целевая функция является полиномом, таким образом, можно записать его в терминах элементарных операций на переменных оптимизации.
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.mfunction [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 симметрично и это .
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: 87
funcCount: 1448
constrviolation: 6.3860e-12
stepsize: 7.4093e-05
algorithm: 'interior-point'
firstorderopt: 0.0012
cgiterations: 172
message: '...'
bestfeasible: [1x1 struct]
objectivederivative: "finite-differences"
constraintderivative: "finite-differences"
solver: 'fmincon'
Просмотрите решение.
disp(sol.u)
0.8419 0.5748 -0.7670
0.5748 0.3745 0.2997
-0.7670 0.2997 0.5667
disp(sol.v)
2.0000
-2.0000
2.0000
Матрица решения u issymmetric. Все значения v в границах.
Copyright 2018–2020 The MathWorks, Inc.