fcn2optimexpr
语法
说明
示例
将目标函数转换为表达式
要在基于问题的方法中使用某 MATLAB® 函数,当该函数不是由支持的函数组成时,请首先将其转换为优化表达式。请参阅Supported Operations for Optimization Variables and Expressions和将非线性函数转换为优化表达式。
要使用目标函数 gamma
(数学函数 ,阶乘函数的扩展),请创建一个优化变量 x
并在转换后的匿名函数中使用它。
x = optimvar('x'); obj = fcn2optimexpr(@gamma,x); prob = optimproblem('Objective',obj); show(prob)
OptimizationProblem : Solve for: x minimize : gamma(x)
要求解生成的问题,请给出初始点结构体并调用 solve
。
x0.x = 1/2; sol = 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.
sol = struct with fields:
x: 1.4616
对于更复杂的函数,请转换函数文件。函数文件 gammabrock.m
计算两个优化变量的一个目标。
type gammabrock
function f = gammabrock(x,y) f = (10*(y - gamma(x)))^2 + (1 - x)^2;
在问题中包含此目标。
x = optimvar('x','LowerBound',0); y = optimvar('y'); obj = fcn2optimexpr(@gammabrock,x,y); prob = optimproblem('Objective',obj); show(prob)
OptimizationProblem : Solve for: x, y minimize : gammabrock(x, y) variable bounds: 0 <= x
gammabrock
函数是平方和。通过将函数表示为优化表达式的显式平方和,可以得到更高效的问题表示。
f = fcn2optimexpr(@(x,y)y - gamma(x),x,y);
obj2 = (10*f)^2 + (1-x)^2;
prob2 = optimproblem('Objective',obj2);
要查看效率差异,请求解 prob
和 prob2
,并检查迭代次数的差异。
x0.x = 1/2; x0.y = 1/2; [sol,fval,~,output] = solve(prob,x0);
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.
[sol2,fval2,~,output2] = solve(prob2,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.
fprintf('prob took %d iterations, but prob2 took %d iterations\n',output.iterations,output2.iterations)
prob took 21 iterations, but prob2 took 2 iterations
如果您的函数有若干个输出,您可以将它们用作目标函数的元素。在本例中,u
是一个 2×2 变量,v
是一个 2×1 变量,expfn3
有三个输出。
type expfn3
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;
创建适当大小的优化变量,并根据前两个输出创建一个目标函数。
u = optimvar('u',2,2); v = optimvar('v',2); [f,g,mineval] = fcn2optimexpr(@expfn3,u,v); prob = optimproblem; prob.Objective = f*g/(1 + f^2); show(prob)
OptimizationProblem : Solve for: u, v minimize : ((arg2 .* arg3) ./ (1 + arg1.^2)) where: [arg1,~,~] = expfn3(u, v); [arg2,~,~] = expfn3(u, v); [~,arg3,~] = expfn3(u, v);
您可以在后续约束表达式中使用 mineval
输出。
基于函数创建非线性约束
在基于问题的优化中,约束是两个优化表达式,它们之间有一个比较运算符(==
、<=
或 >=
)。您可以使用 fcn2optimexpr
创建一个或两个优化表达式。请参阅将非线性函数转换为优化表达式。
创建 gammafn2
小于或等于 –1/2 的非线性约束。包含两个变量的此函数在 gammafn2.m
文件中。
type gammafn2
function f = gammafn2(x,y) f = -gamma(x)*(y/(1+y^2));
创建优化变量,将函数文件转换为优化表达式,然后将约束表示为 confn
。
x = optimvar('x','LowerBound',0); y = optimvar('y','LowerBound',0); expr1 = fcn2optimexpr(@gammafn2,x,y); confn = expr1 <= -1/2; show(confn)
gammafn2(x, y) <= -0.5
另外创建一个 gammafn2
大于或等于 x + y
的约束。
confn2 = expr1 >= x + y;
创建一个优化问题,并将这些约束放在该问题中。
prob = optimproblem; prob.Constraints.confn = confn; prob.Constraints.confn2 = confn2; show(prob)
OptimizationProblem : Solve for: x, y minimize : subject to confn: gammafn2(x, y) <= -0.5 subject to confn2: gammafn2(x, y) >= (x + y) variable bounds: 0 <= x 0 <= y
高效计算公共目标和约束
如果您的问题涉及使用一个常见的、耗时的函数来计算目标和非线性约束,您可以通过使用 ReuseEvaluation
名称-值参数来节省时间。rosenbrocknorm
函数计算 Rosenbrock 目标函数和参数的范数以用于约束 。
type rosenbrocknorm
function [f,c] = rosenbrocknorm(x) pause(1) % Simulates time-consuming function c = dot(x,x); f = 100*(x(2) - x(1)^2)^2 + (1 - x(1))^2;
创建一个二维优化变量 x
。然后使用 fcn2optimexpr
将 rosenbrocknorm
转换为优化表达式,并将 ReuseEvaluation
名称-值参数设置为 true
。要确保 fcn2optimexpr
保留 pause
语句,请将 Analysis
名称-值参数设置为 'off'
。
x = optimvar('x',2); [f,c] = fcn2optimexpr(@rosenbrocknorm,x,... 'ReuseEvaluation',true,'Analysis','off');
根据返回的表达式创建目标和约束表达式。在优化问题中包含目标和约束表达式。使用 show
检查问题。
prob = optimproblem('Objective',f);
prob.Constraints.cineq = c <= 4;
show(prob)
OptimizationProblem : Solve for: x minimize : [argout,~] = rosenbrocknorm(x) subject to cineq: arg_LHS <= 4 where: [~,arg_LHS] = rosenbrocknorm(x);
从初始点 x0.x = [-1;1]
开始求解问题,对结果计时。
x0.x = [-1;1]; tic [sol,fval,exitflag,output] = solve(prob,x0)
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. <stopping criteria details>
sol = struct with fields:
x: [2×1 double]
fval = 4.5793e-11
exitflag = OptimalSolution
output = struct with fields:
iterations: 44
funcCount: 164
constrviolation: 0
stepsize: 4.3124e-08
algorithm: 'interior-point'
firstorderopt: 5.1691e-07
cgiterations: 10
message: '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.↵↵<stopping criteria details>↵↵Optimization completed: The relative first-order optimality measure, 5.169074e-07,↵is less than options.OptimalityTolerance = 1.000000e-06, and the relative maximum constraint↵violation, 0.000000e+00, is less than options.ConstraintTolerance = 1.000000e-06.'
bestfeasible: [1×1 struct]
objectivederivative: "finite-differences"
constraintderivative: "finite-differences"
solver: 'fmincon'
toc
Elapsed time is 165.623157 seconds.
以秒为单位的求解时间几乎与函数计算的次数相同。此结果表明求解器重用了函数值,并且没有浪费时间对同一点重新求值两次。
有关更广泛的示例,请参阅Objective and Constraints Having a Common Function in Serial or Parallel, Problem-Based。有关使用 fcn2optimexpr
的详细信息,请参阅将非线性函数转换为优化表达式。
输入参数
fcn
— 要转换的函数
函数句柄
要转换的函数,指定为函数句柄。
示例: @sin
指定正弦函数。
数据类型: function_handle
in
— 输入参数
MATLAB® 变量
输入参数,指定为 MATLAB 变量。输入可以具有任何数据类型和任何大小。您可以在输入参数 in
中包含任何问题变量或数据;请参阅在基于问题的方法中传递额外的参数。
数据类型: single
| double
| int8
| int16
| int32
| int64
| uint8
| uint16
| uint32
| uint64
| logical
| char
| string
| struct
| table
| cell
| function_handle
| categorical
| datetime
| duration
| calendarDuration
| fi
复数支持: 是
名称-值参数
将可选的参数对组指定为 Name1=Value1,...,NameN=ValueN
,其中 Name
是参数名称,Value
是对应的值。名称-值参数必须出现在其他参数之后,但参数对组的顺序无关紧要。
在 R2021a 之前,使用逗号分隔每个名称和值,并用引号将 Name
引起来。
示例: [out1,out2] = fcn2optimexpr(@fun,x,y,'OutputSize',[1,1],'ReuseEvaluation',true)
指定 out1
和 out2
是无需重新计算即可由求解器在目标函数和约束函数之间重用的标量。
Analysis
— 指示是否分析函数
"on"
(默认) | "off"
指示是否分析函数 fcn
以确定它是否完全由支持的运算组成(请参阅Supported Operations for Optimization Variables and Expressions),指定为 "on"
或 "off"
。
如果您希望使用
fcn2optimexpr
来分析fcn
并尽可能使用支持的运算来实现fcn
,请指定"on"
。此设定使fcn
能够使用自动微分并选择合适的求解器,如Solver
中所述。如果您不希望使用
fcn2optimexpr
来分析fcn
,并因此将fcn
视为不使用自动微分的黑盒,请指定"off"
。在这种情况下,solve
仅使用fmincon
、fminunc
或lsqnonlin
作为求解器。
有关 Analysis
的影响的详细信息,请参阅局限性。
示例: [out1,out2] = fcn2optimexpr(@fun,x,"Analysis","off")
数据类型: char
| string
Display
— 报告函数分析详细信息
"off"
(默认) | "on"
报告函数分析详细信息,指定为 "off"
(不报告)或 "on"
(报告)。如果 Analysis
为 "off"
,则不报告任何内容。
示例: [out1,out2] = fcn2optimexpr(@fun,x,"Display","on")
数据类型: char
| string
OutputSize
— 输出表达式的大小
整数向量 | 整数向量元胞数组
输出表达式的大小,指定为:
整数向量 - 如果函数有一个输出
out
1,OutputSize
指定out
1 的大小。如果函数有多个输出out
1、…、out
N,OutputSize
指定所有输出都具有相同大小。整数向量元胞数组 - 输出
out
j 的大小是OutputSize
的第 j 个元素。
注意
一个标量的大小为 [1,1]
。
如果未指定 'OutputSize'
名称-值对组参数,则 fcn2optimexpr
会将数据传递给 fcn
,以确定输出的大小(请参阅算法)。通过指定 'OutputSize'
,您可以使 fcn2optimexpr
跳过此步骤,从而节省时间。此外,如果您未指定 'OutputSize'
,则当 fcn
的计算因任何原因失败时,fcn2optimexpr
也会失败。
示例: [out1,out2,out3] = fcn2optimexpr(@fun,x,'OutputSize',[1,1])
指定 [out1,out2,out3]
这三个输出是标量。
示例: [out1,out2] = fcn2optimexpr(@fun,x,'OutputSize',{[4,4],[3,5]})
指定 out1
的大小为 4×4,out2
的大小为 3×5。
数据类型: double
| cell
ReuseEvaluation
— 重用值的指示符
false
(默认) | true
重用值的指示符,指定为 false
(不重用)或 true
(重用)。
ReuseEvaluation
可以使您的问题求解运行得更快,例如,当目标和一些非线性约束依赖于共同的计算时。在这种情况下,求解器会存储值以便在需要时重用,避免重新计算该值。
可重用值会带来一些开销,因此最好只为共享某值的表达式启用可重用值。
示例: [out1,out2,out3] = fcn2optimexpr(@fun,x,"ReuseEvaluation",true,"Analysis","off")
允许在多次计算中使用 out1
、out2
和 out3
,每个计算点仅计算一次输出。
数据类型: logical
输出参数
out
— 输出参数
OptimizationExpression
输出参数,以 OptimizationExpression
形式返回。表达式的大小取决于输入函数。
局限性
Analysis
可能忽略非计算函数
Analysis
算法可能不包含非计算函数。算法的这一特点可能导致以下结果:pause
语句被忽略。不影响结果的全局变量可能被忽略。例如,如果您使用全局变量来计算函数运行的次数,则可能会得到误导性的计数。
如果该函数包含对
rand
或rng
的调用,则该函数可能只执行第一次调用,以后的调用不会设置随机数流。plot
调用可能不会在所有迭代中都更新图窗。可能不会在每次迭代时都将数据保存到
mat
文件或文本文件中。
为了确保非计算函数按预期运行,请将
Analysis
名称-值参数设置为"off"
。
有关详细信息,请参阅Limitations of Static Analysis。
算法
分析
当 Analysis
参数采用默认设置 "on"
时,fcn2optimexpr
会执行几个步骤来尝试创建最高效的优化表达式。请参阅 fcn2optimexpr Algorithm Description 中的算法描述。
在问题对象中包含目标函数或非线性约束函数时,您有几种选择。
使用重载。如果一个函数中的所有运算均为Supported Operations for Optimization Variables and Expressions,您可以直接对优化变量调用该函数。例如,
prob.Objective = sin(3*x)*exp(-x-y);
对未修改的函数使用
fcn2optimexpr
。如果一个函数中有至少一项运算不受支持,则必须调用fcn2optimexpr
。例如,besselh
函数不受支持,因此要将其包含在目标函数中,必须使用fcn2optimexpr
。prob.Objective = fcn2optimexpr(@(z)besselh(3,z),x);
修改函数,使其内部
for
循环出现在单独的函数中。这样做可以通过静态分析加快循环执行速度。请参阅Create for Loop for Static Analysis和Static Analysis of Optimization Expressions。将
fcn2optimexpr
中的Analysis
参数设置为"off"
。这样做会使得fcn2optimexpr
将函数封装为黑盒,这是一项速度很快的操作。得到的表达式无法利用自动微分(请参阅Automatic Differentiation Background),因此会导致求解器使用更多函数计算来进行有限差分梯度估计。
输出大小
为了在未指定 OutputSize
时查找每个返回的表达式的输出大小,fcn2optimexpr
在以下点为问题变量的每个元素计算函数。
变量特性 | 计算点 |
---|---|
有限上界 ub 和有限下界 lb | (lb + ub)/2 + ((ub - lb)/2)*eps |
有限下界和无上界 | lb + max(1,abs(lb))*eps |
有限上界和无下界 | ub - max(1,abs(ub))*eps |
没有边界 | 1 + eps |
变量指定为整数 | 之前给出的点的 floor |
计算点可能会导致函数计算错误。要避免此错误,请指定 OutputSize
。
版本历史记录
在 R2019a 中推出
MATLAB 命令
您点击的链接对应于以下 MATLAB 命令:
请在 MATLAB 命令行窗口中直接输入以执行命令。Web 浏览器不支持 MATLAB 命令。
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list:
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)