主要内容

优化工具箱™教程

本教程包括多个示例,展示如何使用两个非线性优化求解器,Fminunc.粉刺以及如何设置选项。本教程中概述的原则适用于其他非线性求解器,例如fgoalattainFminimax.lsqnonlin.lsqcurvefit, 和FSOLVE.

教程示例涵盖了这些任务:

  • 最小化目标函数

  • 用附加参数最小化相同的函数

  • 用约束最小化目标函数

  • 通过提供梯度或Hessian,或通过改变选项,获得更有效或准确的解决方案

不受约束的优化例子

考虑寻找函数的最小值的问题

x exp. - x 2 + y 2 + x 2 + y 2 / 2 0

绘制函数以查看最小化的位置。

exp(-x.^2-y.^2)+(x.^2+y.^2)/20;fsurf (f (2, 2),'showcontours'“上”

图中包含一个坐标轴。坐标轴包含一个函数曲面类型的对象。

该曲线表明最小近点(-1 / 2,0)。

通常您通常将目标函数定义为Matlab®文件。在这种情况下,该功能足以定义为匿名功能。

Fun = @(x) f(x(1),x(2));

设置找到解决方案的初始点。

x0 =[闲置;0);

设置优化选项以使用Fminunc.默认“拟牛顿”算法。此步骤可确保教程在每个Matlab版本中都有相同的工作。

选项= Optimoptions('fminunc'“算法”“拟牛顿”);

查看迭代,因为求解器执行其计算。

选项。显示=“通路”

称呼Fminunc.,无约束非线性极小化器。

[x,fval,exitflag,输出] = fminunc(有趣,x0,选项);
一阶迭代函数计数f(x)步长最优性03 -0.3769 0.339 1 6 -0.379694 1 0.286 2 9 -0.405023 1 0.0284 3 12 -0.405233 1 0.00386 4 15 -0.405237 1 3.17e-05 5 18 -0.405237 1 3.35e-08找到局部最小值。由于梯度的大小小于最优性公差的值,优化完成。

显示求解器找到的解决方案。

uncx = x
uncx =2×1-0.6691 0.0000

在解处查看函数值。

uncf = fval
UNCF = -0.4052.

这些示例使用函数评估的数量作为效率的衡量标准。查看函数求值的总数。

output.funcCount
ans = 18

无约束优化示例具有附加参数

接下来,将额外的参数作为目标函数的其他参数传递给目标函数,首先使用MATLAB文件,然后使用嵌套功能。

考虑前面示例中的目标函数。

f x y x exp. - x 2 + y 2 + x 2 + y 2 / 2 0

用(a,b,c)参数化函数如下:

f x y 一个 b c x - 一个 exp. - x - 一个 2 + y - b 2 + x - 一个 2 + y - b 2 / c

此功能是原始目标函数的移位和缩放版本。

MATLAB文件函数

考虑一个MATLAB文件目标函数名为Bowlpeakfun.定义如下。

类型Bowlpeakfun.
function y = bowlpeakfun(x, a, b, c) %% 2008年版权MathWorks公司y = (x(1)——)。* exp (- ((x(1)——)^ 2 + (x (2) - b) ^ 2)) + ((x(1)——)^ 2 + (x (2) - b) ^ 2) / c;

定义参数。

= 2;b = 3;c = 10;

为MATLAB文件创建一个匿名函数句柄。

f = @(x)bownakfun(x,a,b,c)
f =function_handle具有值:@ (x) bowlpeakfun (x, a, b, c)

称呼Fminunc.求最小值。

x0 =[闲置;0);选项= Optimoptions('fminunc'“算法”“拟牛顿”);[x, fval] = fminunc(f,x0,options)
发现本地最低限度。由于梯度的大小小于最优性公差的值,优化完成。
X =2×11.3639 3.0000
fval = -0.3840

嵌套函数

考虑到巢钵塞函数,它将目标实现为嵌套函数。

类型巢钵塞
function [x,fval] = nestedbowlpeak(a,b,c,x0,options) %% Copyright 2008 The MathWorks, Inc. [x,fval] = fminunc(@nestedfun,x0,options);函数y = nestedfun (x) y = (x(1)——)。* exp (- ((x(1)——)^ 2 + (x (2) - b) ^ 2)) + ((x(1)——)^ 2 + (x (2) - b) ^ 2) / c;结束结束

参数(a,b,c)对嵌套的目标函数是可见的巢德福.外功能,巢钵塞Fminunc.然后通过目标函数,巢德福

定义参数,初始猜测和选项:

= 2;b = 3;c = 10;x0 =[闲置;0);选项= Optimoptions('fminunc'“算法”“拟牛顿”);

运行优化:

[x,fval] = instedbowlpeak(a,b,c,x0,选项)
发现本地最低限度。由于梯度的大小小于最优性公差的值,优化完成。
X =2×11.3639 3.0000
fval = -0.3840

这两种方法产生相同的答案,所以您可以使用您认为最方便的方法。

约束优化示例:不平等

考虑前面的约束条件问题:

最小化 x exp. - x 2 + y 2 + x 2 + y 2 / 2 0

x y / 2 + x + 2 2 + y - 2 2 / 2 ≤. 2

约束组是倾斜椭圆的内部。查看目标函数的轮廓与倾斜椭圆形式绘制。

exp(-x.^2-y.^2)+(x.^2+y.^2)/20;g = @(x,y)x。* y / 2 +(x + 2)。^ 2+(y-2)。^ 2 / 2-2;FIMPLIC(g)轴([ -  6 0 -1 7])保持fcontour(f)绘图( - 。9727,.4685,“罗”);传奇('约束'“f轮廓”'最低限度');抓住离开

图中包含一个坐标轴。轴包含隐函数线、函数轮廓线、直线三个对象。这些对象代表约束,f线,最小值。

绘图表明椭圆内的目标函数的最低值发生在椭圆的右下部分附近。在计算绘制的最小值之前,请猜测解决方案。

X0 = [-2 1];

设置优化选项以使用内部点算法并在每次迭代中显示结果。

选项= Optimoptions(“fmincon”“算法”“内点”“显示”“通路”);

求解器要求非线性约束函数给出两个输出,一个用于非线性不等式,一个用于非线性等式。要给出两个输出,使用交易函数。

gfun = @(x)交易(g(x(1),x(2)),[]);

呼叫非线性约束求解器。问题没有线性平等或不等式或界限,因此为这些参数传递[]。

[x,fval,出口,输出] = fmincon(fun,x0,[],[],[],[],[],[],Gfun,选项);
Iter的一阶范数f(x)可行性优化步骤03 2.365241e-01 0.000e+00 1.972e-01 16 1.748504e-01 0.000e+00 1.734e-01 2.260e-01 2 10 -1.570560e-01 0.000e+00 2.608e-01 9.347e-01 3 14 -6.629160e- 01 0.000e+00 1.241e-01 3.103e-01 4 17 -1.584082e-01 0.000e+00 7.934e-02 1.826e-01 6 23-2。255299e-01 0.000e+00 1.955e-02 1.993e-02 7 26 -2.444225e-01 0.000e+00 4.293e-03 3.821e-02 8 29 -2.446931e-01 0.000e+00 8.100e-04 4.035e-03 9 32 -2.446933e-01 0.000e+00 1.999e-04 8.126e-04 10 35 -2.448531e-01 0.000e+00 4.004e-05 3.289e-04 11 38 -2.448927e-01 0.000e+00 4.036e-07 8.156e-05 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.

显示求解器找到的解决方案。

x
X =1×2-0.9727 - 0.4686

在解处查看函数值。

fval
fval = -0.2449

查看函数求值的总数。

fevals = output.funccount.
函数宏指令= 38

在解决方案中满足不等式约束。

[c, ceq] = gfun(x)
c = -2.4608 e-06
CEQ = []

因为c(x)接近于0,约束条件是积极的,这意味着它会影响解决方案。回想一下无约束解。

uncx
uncx =2×1-0.6691 0.0000

召回无限制的目标职能。

uncf
UNCF = -0.4052.

看看约束在多大程度上移动了解决方案并增加了目标。

fval-uncf
ans = 0.1603

约束优化示例:用户提供的渐变

通过提供梯度,可以更有效、更准确地解决优化问题。这个例子和前面的例子一样,解决了不等式约束问题

最小化 x exp. - x 2 + y 2 + x 2 + y 2 / 2 0

x y / 2 + x + 2 2 + y - 2 2 / 2 ≤. 2

提供F(x)的梯度粉刺,将目标函数写成MATLAB文件的形式。

类型onehump
功能[f,gf] = OneHump(x)%Onehump辅助功能,用于优化工具箱的教程Demo%2008-2009 Mathworks,Inc.R = x(1)^ 2 + x(2)^ 2;s = exp(-R);f = x(1)* s + r / 20;如果nargout> 1 gf = [(1-2 * x(1)^ 2)* s + x(1)/ 10;-2 * x(1)* x(2)* s + x(2)/ 10];结尾

约束及其梯度包含在MATLAB文件中tiltellipse

类型tiltellipse
功能[c,ceq,gc,gceq] = tiltellipse(x)%tiltellipse帮助函数,用于优化工具箱的教程Demo%2008-2009 MathWorks,Inc.C = x(1)* x(2)/ 2 +(x(1)+2)^ 2 +(x(2)-2)^ 2/2  -  2;CEQ = [];如果nargout> 2 gc = [x(2)/ 2 + 2 *(x(1)+2);X(1)/ 2 + x(2)-2];gceq = [];结尾

设置找到解决方案的初始点。

x0 = [-2;1];

设置优化选项以使用与前一个示例中相同的算法以进行比较。

选项= Optimoptions(“fmincon”“算法”“内点”);

设置选项以在目标函数和约束函数中使用梯度信息。注意:这些选项必须打开,否则渐变信息将被忽略。

选项= Optimoptions(选项,......“SpecifyObjectiveGradient”,真的,......'specifyconstraintgradient',真的);

因为粉刺不需要使用有限差分估计梯度,求解器应该有更少的函数计数。设置在每次迭代时显示结果的选项。

选项。显示=“通路”

解算器。

[x,fval,extflag,输出] = fmincon(@ OneHump,X0,[],[],[],[],[],[],......@tiltellipse选项);
一阶规范的ITER F计法(x)可行性最优性步骤0 1 2.365241E-01 0.000E + 00 1.972E-01 11 2 1.748504E-01 0.000E + 00 1.734E-01 2.260E-01 2 4-1.570560E-01 0.000E + 00 2.608E-01 9.347E-01 3 6 -6.629161E-02 0.000E + 00 1.241E-01 3.103E-01 4 7 -1.584082E-01 0.000E + 00 7.934E-02 1.826E-01 5 8 -2.349124E-01 0.000E + 00 1.912E-02 1.571E-01 6 9 -2.255299E-01 0.000E + 00 1.955E-02 1.993E-02 7 10 -2.444225E-010.000E + 00 4.293E-03 3.821E-02 8 11 -2.446931E-01 0.000E + 00 8.100E-04 4.035E-03 9 12 -2.446933E-01 0.000E + 00 1.9999E-04 8.126E-0410 13 -2.448531E-01 0.000E + 00 4.004E-05 3.289E-04 11 14 -2.448927E-01 0.000E + 00 4.036E-07 8.156E-05发现满足约束的局部最小值。优化完成,因为目标函数在可行的方向上不降低,到在最优性公差的值内,并且对约束公差的值满足约束。

粉刺估计梯度在前面的示例中,因此该示例中的迭代是相似的。

显示求解器找到的解决方案。

xold = x
xold =2×1-0.9727 - 0.4686

在解处查看函数值。

minfval = fval.
minfval = -0.2449.

查看函数求值的总数。

Fgradevals = output.funcCount
fgradevals = 14.

将这个数字与没有梯度的函数求值的数量进行比较。

函数宏指令
函数宏指令= 38

约束优化示例:更改默认终止公差

这个例子继续使用梯度并解决了相同的约束问题

最小化 x exp. - x 2 + y 2 + x 2 + y 2 / 2 0

x y / 2 + x + 2 2 + y - 2 2 / 2 ≤. 2

在这种情况下,通过覆盖默认终止标准来实现更准确的解决方案(选项。StepToleranceoptions.optimalanytolerance.)。默认值粉刺内部点算法是选项.steptolerance = 1e-10options.optimalanytolerance = 1E-6

覆盖这两个默认终止条件。

选项= Optimoptions(选项,......'steptolerance',1e-15,......“OptimalityTolerance”1 e-8);

解算器。

[x,fval,extflag,输出] = fmincon(@ OneHump,X0,[],[],[],[],[],[],......@tiltellipse选项);
一阶规范的ITER F计法(x)可行性最优性步骤0 1 2.365241E-01 0.000E + 00 1.972E-01 11 2 1.748504E-01 0.000E + 00 1.734E-01 2.260E-01 2 4-1.570560E-01 0.000E + 00 2.608E-01 9.347E-01 3 6 -6.629161E-02 0.000E + 00 1.241E-01 3.103E-01 4 7 -1.584082E-01 0.000E + 00 7.934E-02 1.826E-01 5 8 -2.349124E-01 0.000E + 00 1.912E-02 1.571E-01 6 9 -2.255299E-01 0.000E + 00 1.955E-02 1.993E-02 7 10 -2.444225E-010.000E + 00 4.293E-03 3.821E-02 8 11 -2.446931E-01 0.000E + 00 8.100E-04 4.035E-03 9 12 -2.446933E-01 0.000E + 00 1.9999E-04 8.126E-0410 13 -2.448531E-01 0.000E + 00 4.004E-05 3.289E-04 11 14 -2.448927E-01 0.000E + 00 4.036E-07 8.156E-05 12 15 -2.448931E-01 0.000E + 00 4.000E-09 8.230E-07发现满足约束的本地最小值。优化完成,因为目标函数在可行的方向上不降低,到在最优性公差的值内,并且对约束公差的值满足约束。

要更准确地看到新公差所做的差异,请在解决方案中显示更多小数。

格式

显示求解器找到的解决方案。

x
X =2×1-0.972742227363546 0.468569289098342

将这些值与前一个示例中的值进行比较。

xold.
xold =2×1-0.972742694488360 0.468569966693330

确定值的变化。

x  -  xold.
ans =2×110.-6×0.467124813385844 - -0.677594988729435

在解处查看函数值。

fval
fval = -0.244893137879894

看看解决方案改进了多少。

fval  -  minfval.
ans = -3.996450220755676 e-07

答案是负的,因为新解更小。

查看函数求值的总数。

output.funcCount
ans = 15

将此编号与用户提供的渐变和默认公差进行解决的示例中的函数评估数。

Fgradevals.
fgradevals = 14.

约束优化示例:用户提供的Hessian

如果除了梯度之外,如果您提供粗鸽,则求解器更加准确和高效。

粉刺内点算法将Hessian矩阵作为一个单独的函数(不属于目标函数的一部分)。Hessian函数H(x,)计算拉格朗日的Hessian;看fmincon内点算法的Hessian

求解器计算这些值lambda.ineqnonlin.lambda.eqlin;你的Hessian函数告诉求解者如何使用这些值。

此示例具有一个不等式约束,因此黑森州被定义为给出的hessfordemo函数。

类型hessfordemo
功能H = Hessfordemo(x,lambda)%hessfordemo帮助函数,用于优化工具箱的教程Demo%2008-2009 Mathworks,Inc.S = Exp( - (x(1)^ 2 + x(2)^ 2));h = [2 * x(1)*(2 * x(1)^ 2-3)* s + 1/10,2 * x(2)*(2 * x(1)^ 2-1)* s;2 * x(2)*(2 * x(1)^ 2-1)* s,2 * x(1)*(2 * x(2)^ 2-1)* s + 1/10];Hessc = [2,1 / 2; 1 / 2,1];h = h + lambda.ineqnonlin(1)* hessc;

为了使用Hessian,您需要适当地设置选项。

选项= Optimoptions(“fmincon”......“算法”“内点”......'specifyconstraintgradient',真的,......“SpecifyObjectiveGradient”,真的,......'hessianfcn', @hessfordemo);

公差被设置为默认值,这应该导致函数计数较少。设置在每次迭代时显示结果的选项。

选项。显示=“通路”

解算器。

[x,fval,extflag,输出] = fmincon(@ OneHump,X0,[],[],[],[],[],[],......@tiltellipse选项);
一阶规范的ITER F计F(x)可行性最优性步骤0 1 2.365241E-01 0.000E + 00 1.972E-01 1 3 5.821325E-02 0.000E + 00 1.443E-01 8.728E-01 2 5-1.218829E-01 0.000E + 00 1.007E-01 4.927E-01 3 6 -1.421167E-01 0.000E + 00 8.486E-02 5.165E-02 4 7 -2.261916E-01 0.000E + 00 1.989E-02 1.667E-01 5 8 -2.433609E-01 0.000E + 00 1.537E-03 3.486E-02 6 9 -2.446875E-01 0.000E + 00 2.057E-04 2.727E-03 7 10 -2.448911E-010.000E + 00 2.068E-06 4.191E-04 8 11 -2.448931E-01 0.000E + 00 2.001E-08 4.218E-06发现满足约束的局部最小值。优化完成,因为目标函数在可行的方向上不降低,到在最优性公差的值内,并且对约束公差的值满足约束。

结果显示较少和不同的迭代。

显示求解器找到的解决方案。

x
X =2×1-0.972742246093537 0.468569316215571

在解处查看函数值。

fval
fval = -0.244893121872758

查看函数求值的总数。

output.funcCount
ans = 11

将此编号与仅使用梯度评估进行解决的示例中的函数评估数,具有相同的默认公差。

Fgradevals.
fgradevals = 14.

相关话题