matlab quadprog_MATLAB极小值优化

11.1.2  极小值优化

1.标量最小值优化

求解单变量最优化问题的方法有多种,根据目标函数是否需要求导,可以分为两类,即直接法和间接法。直接法不需要对目标函数进行求导,而间接法则需要用到目标函数的导数。

常用的一维直接法主要有消去法和近似法两种。

(1)消去法:该法利用单峰函数具有的消去性质进行反复迭代,逐渐消去不包含极小点的区间,缩小搜索区间,直到搜索区间缩小到给定的允许精度为止。一种典型的消去法为黄金分割法(Golden Section Search)。黄金分割法的基本思想是在单峰区间内适当地插入两点,将区间分为3段,然后通过比较这两点函数值的大小来确定是删去最左段还是最右段,或同时删去左右两段,而保留中间段。重复该过程可以使区间无限缩小。插入点的位置放在区间的黄金分割点及其对称点上,所以该法称为黄金分割法。该法的优点是算法简单,效率较高,稳定性好。

(2)多项式近似法:该法用于目标函数比较复杂的情况。此时搜索一个与它近似的函数代替目标函数,并用近似函数的极小点作为原函数极小点的近似。常用的近似函数为二次和三次多项式。二次插值法的计算速度比黄金分割法快,但是对于一些强烈扭曲或可能多峰的函数,该法的收敛速度会变得很慢,甚至失败。

间接法需要计算目标函数的导数,优点是计算速度很快。常见的间接法包括牛顿切线法、对分法、割线法和三次插值多项式近似法等。优化工具箱中用得较多的是三次插值法。如果函数的导数容易求得,一般来说应首先考虑使用三次插值法,因为它具有较高的效率。在只需要计算函数值的方法中,二次插值法是一个很好的方法,它的收敛速度较快,特别是在极小点所在区间较小时尤为如此。黄金分割法则是一种十分稳定的方法,并且计算简单。基于以上分析,MATLAB优化工具箱中使用得较多的方法是二次插值法、三次插值法、二次三次混合插值法和黄金分割法。

MATLAB优化工具箱提供了fminbnd函数来进行标量最小值问题的优化求解,其调用语法如下。

(1)x = fminbnd(fun,x1,x2):返回标量函数fun在条件x1 < x < x2下取最小值时自变量x的值。

(2)x = fminbnd(fun,x1,x2,options):用options参数指定的优化参数进行最小化。

(3)x = fminbnd(problem):求解problem的最小值,其中problem是一个用输入变量来表达的结构数组。

(4)[x,fval] = fminbnd(...):返回解x处目标函数的值fval。

(5)[x,fval,exitflag] = fminbnd(...):返回exitflag值描述fminbnd函数的退出条件。

(6)[x,fval,exitflag,output] = fminbnd(...):返回包含优化信息的结构数组output。

其中fun为需要最小化的目标函数。fun函数需要输入标量参数x,返回x处的目标函数标量值f。fun可以是一个匿名函数的函数句柄,如下所示:

x = fminbnd(inline('sin(x*x)'),x0)

同样,fun参数也可以是一个包含函数名的字符串,对应的函数可以是M文件、内部函数或MEX文件。options为优化参数选项,用户可以用optimset函数设置或改变参数的值。至于options参数的具体设置,读者可自行查阅帮助文档。

【例11-1】  对边长为3m的正方形铁板,在4个角处剪去相等的正方形,以制成方形无盖水槽,问如何剪才能使水槽的容积最大?

假设剪去的正方形的边长为x,则水槽的容积为:

93749abfb7b83fb096563d9d21ce84b0.png

现在要求在区间(0,1.5)上确定一个x,使V最大化。因为优化工具箱中要求目标函数最小化,所以需要对目标函数进行转换:V1=-V,即要求V1的最小值。

首先编写此问题的函数M文件:

myfun1.m

function f = myfun1(x)

f = -(3-2*x).^2 * x;

然后在命令行调用fminbnd函数:

>> x = fminbnd(@myfun1,0,1.5)

x =

    0.5000

即剪掉的小正方形的边长为0.5m时水槽的容积最大。我们可以调用myfun1函数来计算水槽的最大容积:

>> y= -myfun1(x)

y =

    2.0000

水槽的最大容积为49f3c77b355e5a3712f1b787df17858b.png

2.无约束最小值优化

无约束最优化问题在实际应用中也比较常见,如工程中常见的参数反演问题。另外,许多有约束最优化问题也可以转化为无约束最优化问题进行求解。

求解无约束最优化问题的方法主要有两类,即直接搜索法(Search method)和梯度法(Gradient method)。

直接搜索法适用于目标函数高度非线性,没有导数或导数很难计算的情况。实际工程中很多问题都是非线性的,因此直接搜索法不失为一种有效的解决办法。常用的直接搜索法为单纯形法,此外还有Hooke-Jeeves搜索法、Pavell共轭方向法等,其缺点是收敛速度慢。

在函数的导数可求的情况下,梯度法是一种更优的方法,该法利用函数的梯度(一阶导数)和Hessian矩阵(二阶导数)构造算法,可以获得更快的收敛速度。函数f(x)的负梯度方向即反映了函数的最大下降方向。当搜索方向取为负梯度方向时,称为最速下降法。但当需要最小化的函数有一狭长的谷形值域时,该法的效率则很低。常见的梯度法有最速下降法、Newton法、Marquart法、共轭梯度法和拟牛顿法(Quasi-Newton method)等。在这些方法中,用得最多的是拟牛顿法。

在MATLAB中,有fminunc和fminsearch两个函数用来求解无约束最优化问题。由于MATLAB优化工具箱表11-1中列出的函数调用语法和参数说明都比较类似,同时篇幅有限,所以下面只举例来说明一下这些函数的用法。

【例11-2】  求函数ede216ab16f1027d62831387542b21c6.png的最小值。

首先编写函数的M文件。需要注意的是:本例中的目标函数具有两个变量,在编写函数的时候需要将这两个自变量作为列向量输入目标函数。M文件的具体内容如下:

myfun2.m

function f = myfun2(x)

f = 3*x(1)^2 + 2*x(1)*x(2) + x(2)^2;    %  目标函数

然后在命令行调用fminunc函数来寻找目标函数在点[1,1]附近的最小值:

x0 = [1,1];

[x,fval] = fminunc(@myfun2,x0)

fminunc函数经过多次迭代之后,给出如下计算结果:

x =                                      %  最小值所对应的x值

  1.0e-006 *

    0.2541   -0.2029

fval =                                  %  最小值的大小

  1.3173e-013

【例11-3】  求banana方程的最小值:

0cdf69f128b9df32bd9d7c77f17adb83.png

通过分析可知,最小值0所对应的点为(a,a2)。可以在指定a的情况下求这个方程的最小值,例如让a = sqrt(2)。下面来创建一个包含参数a的匿名函数:

>> a = sqrt(2);

>> banana = @(x)100*(x(2)-x(1)^2)^2+(a-x(1))^2;

然后在MATLAB命令行中输入以下命令:

>> [x,fval,exitflag] = fminsearch(banana, [-1.2, 1], ...

   optimset('TolX',1e-8))       %  optimset('TolX',1e-8)用来设置算法终止误差

x =

    1.4142    2.0000

fval =

  4.2065e-018

exitflag =

     1

在点(sqrt(2), 2)得到了函数的最小值,fval非常接近于0,这说明本例中fminsearch函数的优化计算是非常成功的。

3.线性规划

线性规划是处理线性目标函数和线性约束的一种较为成熟的方法,目前已经广泛地应用于军事、经济、工业、农业、教育、商业和社会科学等许多方面。线性规划问题的标准形式是:

ad1582c392c44a41f79153adab845805.png

写成矩阵形式为:

e1502af57ad88d1f29e06a6185866c03.png

其中:

7ec6379140f2e9b04587cbefafc63a68.png

线性规划的标准形式要求目标函数最小化,约束条件取等式,变量非负。不符合这几个条件的线性模型要首先转换成标准形。线性规划的求解方法主要是单纯形法。

MATLAB优化工具箱提供了linprog函数用来进行线性规划的求解。

【例11-4】  求如下函数的最小值。

9858810503a1d12f33da07015e5ba3e7.png

首先在MATLAB命令行中输入以下参数:

>> f = [-5; -4; -6];      %  用矩阵表示目标函数

>> A = [1  -1  1

      3   2  4

      3   2  0];          %  用矩阵形式表示约束条件系数

>> b = [20; 42; 30];     %  约束条件

>> lb = zeros(3,1);      %  下界约束

然后调用linprog函数:

>> [x,fval,exitflag,output,lambda] = linprog(f,A,b,[],[],lb);

Optimization terminated.

>> x,lambda.ineqlin,lambda.lower       %  显示结果

x =

    0.0000

   15.0000

    3.0000

ans =

    0.0000

    1.5000                                  %  主动约束

    0.5000                                  %  主动约束

ans =

    1.0000                                  %  主动约束

    0.0000

    0.0000

Lambda域中向量里的非零元素可以反映出求解过程中的主动约束。在本例的结果中可以看出,第2个和第3个不等式约束(lambda.ineqlin)和第1个下界约束(lambda.lower)是主动约束。

4.二次规划

二次规划是非线性规划中一类特殊的数学规划问题,它的解是可以通过求解得到的。通常通过解其库恩-塔克条件(K-T条件),获取一个K-T条件的解,称为K-T对,其中与原问题的变量对应的部分称为K-T点。二次规划的一般形式为:

a11d53562a4a7b3ae51b4d2cddbd00a0.png

其中为对称矩阵。二次规划分为凸二次规划与非凸二次规划两者,前者的K-T点便是其全局极小值点,而后者的K-T点则可能连局部极小值点都不是。若它的目标函数是二次函数,则约束条件是线性的。求解二次规划的方法很多,较简便易行的是沃尔夫法,它是依据K-T条件,在线性规划单纯形法的基础上加以修正而得到的。此外还有莱姆基法、毕尔法、凯勒法等。

MATLAB优化工具箱中提供了quadprog函数用来进行二次规划的求解。

【例11-5】  求下面函数的最小值。

ee78080df8a9faad199d9d9dea348fb5.png

首先,我们注意到这个方程可以用矩阵形式来表示:

a8ace0306fe4bfdb9e0d6da552d2c707.png

其中:

b6faa8d82d041713ed4effdab7caccf7.png

在MATLAB命令行中输入以下参数命令:

>> H = [1 -1; -1 2];

>> f = [-2; -6];

>> A = [1 1; -1 2; 2 1];     %  线性不等式约束

>> b = [2; 2; 3];             %  线性不等式约束

>> lb = zeros(2,1);

然后调用二次规划函数quadprog:

>> [x,fval,exitflag,output,lambda] = quadprog(H,f,A,b,[],[],lb)

Optimization terminated.

x =

    0.6667

    1.3333

fval =

   -8.2222

exitflag =

     1

output =

       iterations: 3

        algorithm: 'medium-scale: active-set'

    firstorderopt: []

     cgiterations: []

          message: 'Optimization terminated.'

lambda =

      lower: [2x1 double]

      upper: [2x1 double]

      eqlin: [0x1 double]

    ineqlin: [3x1 double]

exitflag = 1表示计算的退出条件是收敛于x。output是包含着优化信息的结构数组。lambda返回了x处包含拉格朗日乘子的参数。

5.有约束最小值优化

在有约束最优化问题中,通常要将该问题转换为更简单的子问题,对这些子问题可以求解并作为迭代过程的基础。早期的方法通常是通过构造惩罚函数等,将有约束的最优化问题转换为无约束最优化问题进行求解。现在,这些方法已经被更有效的基于K-T方程解的方法所取代。K-T方程是有约束最优化问题求解的必要条件。

MATLAB优化工具箱提供了fmincon函数用来计算有约束的最小值优化。

【例11-6】  求函数70c72d4bc35171f6083c22335dd110e7.png的最小值,搜索的起始值为x = [10;10;10],同时目标函数中的变量要服从以下约束条件:

4979a22ecfa6f284f04164ab80fd49da.png

首先要写一个以x为变量的目标函数myfun3.m,该目标函数要返回一个标量。

myfun3.m

function f = myfun3(x)

f = -x(1) * x(2) * x(3);

其次,改写约束条件为小于或者等于一个常数的形式: 

bdc0ffffc3956da3c1cba7fb8b0570c3.png

接下来,因为两个约束都是线性的,所以可以将其用矩阵来表示成6559b04d0428d1d0bc7169bc236a961b.png这种形式,其中:

34401c60c5b22ffa48f41096099446cf.png

然后调用fmincon函数进行优化:

>> x0 = [10; 10; 10];    % 求解的起始点

>> A=[-1 -2 -2;1 2 2];

>> b=[0;72];

>> [x,fval] = fmincon(@myfun3,x0,A,b)

x =

   24.0000

   12.0000

   12.0000

fval =

 -3.4560e+003

最后可以对约束条件进行验证:

>> A*x-b

ans =

   -72

     0

8f983d8ac7ab3523cacaa94e9ac36d4f.png

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值