matlab求单峰函数最小值


测试函数是-x*sin(x),求其在0~4.5上的最小值。

首先绘图观察一下:

fplot(@(x) -x*sin(x),[0,4.5]);
hold on;
fplot(@(x) -sin(x)-x*cos(x),[0,4.5]);
hold off;
legend('f(x)',"f'(x)");
xlabel('x');

[x,fval] = fmincon(@(x) -x*sin(x),2)

x =
2.028757520194786
fval =
-1.819705741159516

可以看到x在2附近f(x)取到最小值。

三点二次插值

下面构建三点二次插值函数:

function [p1,fval]=int2p3(f,xinterval)
p0=xinterval(1);
p2=xinterval(2);
p1=(p0+p2)/2;
while true
    x=[p0,p1,p2];
    y=[f(p0),f(p1),f(p2)];
    c=polyfit(x,y,2);
    p1_=-c(2)/2/c(1);
    if f(p1)

测试:

>> [x,fval]=int2p3(@(x) -x*sin(x),[0,4.5])
x =
2.028757824672632
fval =
-1.819705741159653

点x的迭代过程如下图:

最后收敛到2.029。

牛顿法

function [p1,fval]=newton(f,xinterval)
p0=xinterval(1);
p2=xinterval(2);
p1=(p0+p2)/2;
d=0.001;
while true
    p1_=(f(p1+d)-f(p1))/d;%一阶导数
    p1_2=(f(p1)-f(p1-d))/d;
    p1__=(p1_-p1_2)/d;%二阶导数
    p1next=p1-p1_/p1__;
    if abs(p1next-p1)

>> [x,fval]=newton(@(x) -x*sin(x),[0,4.5])
x =
2.028286879504392
fval =
-1.819705441320462