fcn2optimexpr
将函数转换为优化表达式
语法
说明
示例
要在基于问题的方法中使用某 MATLAB® 函数,当该函数不是由支持的函数组成时,请首先将其转换为优化表达式。请参阅优化变量和表达式支持的运算和将非线性函数转换为优化表达式。
要使用目标函数 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. <stopping criteria details>
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. <stopping criteria details>
[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. <stopping criteria details>
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
函数计算罗森布罗克目标函数和参量的范数以用于约束 。
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.
以秒为单位的求解时间几乎与函数计算的次数相同。此结果表明求解器重用了函数值,并且没有浪费时间对同一点重新求值两次。
有关更广泛的示例,请参阅具有串行或并行共同函数的目标和约束,基于问题。有关使用 fcn2optimexpr
的详细信息,请参阅将非线性函数转换为优化表达式。
输入参数
要转换的函数,指定为函数句柄。
示例: @sin
指定正弦函数。
数据类型: function_handle
输入参量,指定为 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
是无需重新计算即可由求解器在目标函数和约束函数之间重用的标量。
指示分析函数 fcn
,指定为 "on"
或 "off"
。该软件遵循 fcn2optimexpr 算法描述 中的步骤,尝试使用最快、最合适的求解器和算法。
静态分析是当 Analysis
为 "on"
时软件首先尝试执行的操作,其具体内容在 优化表达式的静态分析中有详细描述。
分析函数可确定 fcn
是否完全由支持的操作组成(参阅 优化变量和表达式支持的运算)。如果是这样,软件可以使用自动微分。
如果你希望 fcn2optimexpr
不分析 fcn
,并且因此将 fcn
作为一个黑盒处理而不进行自动微分,请指定 "off"
。在这种情况下,solve
只使用非线性求解器,如 fmincon
或 ga
,而不使用线性或二次求解器,如 linprog
或 quadprog
。
有关 Analysis
的影响的详细信息,请参阅限制。
示例: [out1,out2] = fcn2optimexpr(@fun,x,"Analysis","off")
数据类型: char
| string
报告函数分析详细信息,指定为 "off"
(不报告)或 "on"
(报告)。如果 Analysis
为 "off"
,则不报告任何内容。
示例: [out1,out2] = fcn2optimexpr(@fun,x,"Display","on")
数据类型: char
| string
输出表达式的大小,指定为:
整数向量 - 如果函数有一个输出
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
重用值的指示符,指定为 false
(不重用)或 true
(重用)。
ReuseEvaluation
可以使您的问题求解运行得更快,例如,当目标和一些非线性约束依赖于共同的计算时。在这种情况下,求解器会存储值以便在需要时重用,避免重新计算该值。
可重用值会带来一些开销,因此最好只为共享某值的表达式启用可重用值。
示例: [out1,out2,out3] = fcn2optimexpr(@fun,x,"ReuseEvaluation",true,"Analysis","off")
允许在多次计算中使用 out1
、out2
和 out3
,每个计算点仅计算一次输出。
数据类型: logical
输出参量
输出参量,以 OptimizationExpression
形式返回。表达式的大小取决于输入函数。
限制
Analysis
可能忽略非计算函数
Analysis
算法可能不包含非计算函数。算法的这一特点可能导致以下结果:pause
语句被忽略。不影响结果的全局变量可能被忽略。例如,如果您使用全局变量来计算函数运行的次数,则可能会得到误导性的计数。
如果该函数包含对
rand
或rng
的调用,则该函数可能只执行第一次调用,以后的调用不会设置随机数流。plot
调用可能不会在所有迭代中都更新图窗。可能不会在每次迭代时都将数据保存到
mat
文件或文本文件中。
为了确保非计算函数按预期运行,请将
Analysis
名称-值参量设置为"off"
。
有关详细信息,请参阅静态分析的局限性。
算法
当 Analysis
参量采用默认设置 "on"
时,fcn2optimexpr
会执行几个步骤来尝试创建最高效的优化表达式。请参阅 fcn2optimexpr 算法描述 中的算法描述。
在问题对象中包含目标函数或非线性约束函数时,您有几种选择。
使用重载。如果一个函数中的所有运算均为优化变量和表达式支持的运算,您可以直接对优化变量调用该函数。例如,
prob.Objective = sin(3*x)*exp(-x-y);
对未修改的函数使用
fcn2optimexpr
。如果一个函数中有至少一项运算不受支持,则必须调用fcn2optimexpr
。例如,besselh
函数不受支持,因此要将其包含在目标函数中,必须使用fcn2optimexpr
。prob.Objective = fcn2optimexpr(@(z)besselh(3,z),x);
修改函数,使其内部
for
循环出现在单独的函数中。这样做可以通过静态分析加快循环执行速度。请参阅创建 for 循环进行静态分析和优化表达式的静态分析。将
fcn2optimexpr
中的Analysis
参量设置为"off"
。这样做会使得fcn2optimexpr
将函数封装为黑盒,这是一项速度很快的操作。得到的表达式无法利用自动微分(请参阅自动微分背景),因此会导致求解器使用更多函数计算来进行有限差分梯度估计。
为了在未指定 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 Command
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
选择网站
选择网站以获取翻译的可用内容,以及查看当地活动和优惠。根据您的位置,我们建议您选择:。
您也可以从以下列表中选择网站:
如何获得最佳网站性能
选择中国网站(中文或英文)以获得最佳网站性能。其他 MathWorks 国家/地区网站并未针对您所在位置的访问进行优化。
美洲
- América Latina (Español)
- Canada (English)
- United States (English)
欧洲
- 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)