Unconstrained-Optimization

本文最后更新于:2023年6月19日 晚上

无约束优化

单变量优化(最小值)

`fminbnd’命令–查找单变量函数在定区间上的最小值

x = fminbnd(fun,x1,x2) 返回一个值 x,该值是 fun 中描述的标量值函数在区间 x1 < x < x2 中的局部最小值。
x = fminbnd(fun,x1,x2,options) 如 options = optimset(‘Display’,’iter’)在常微分方程中有详细的描述
x = fminbnd(problem)
[x,fval] = fminbnd(___) 返回目标函数在 fun 的解 x 处计算出的值。

即求最小值的位置和函数值

1
2
3
4
5
fun = @sin;
[x,fval] = fminbnd(fun,1,2*pi)
%输出
x = 4.7124
fval = -1.0000

[x,fval,exitflag] = fminbnd(___)
[x,fval,exitflag,output] = fminbnd(___)

双变量优化(最小值)

fminunc信赖域法和拟牛顿法

x = fminunc(fun,x0)
x = fminunc(fun,x0,options)
x = fminunc(problem)
[x,fval] = fminunc(___)
[x,fval,exitflag,output] = fminunc(___)
[x,fval,exitflag,output,grad,hessian] = fminunc(___)
这里看一个双变量加传参的特殊例子。求
函数文件

1
2
function x = examfminunc(x,a,b)
x = x(1)^2/a+x(2)^2/b;

源程序x = fminunc(@examfminunc,[1,1],[],2,2)%x=1,y=1是初始值

我也不知道这是怎么传进去的参……这个顺序就很迷,但去掉那个[]就会报错无法执行赋值,因为此类型的变量不支持使用点进行索引后期在看书的时候发现那里似乎是 opt 字段,传空数组即不对 opt 进行修改于是我尝试修改成 x = fminunc(@examfminunc,[1,1],'',2,2),发现果然也能运行

lsqnonlin 拟合非线性最小二乘系数

语法

x = lsqnonlin(fun,x0)
x = lsqnonlin(fun,x0,lb,ub) defines a set of lower and upper bounds on the design variables in x, so that the solution is always in the range . You can fix the solution component x(i) by specifying .
x = lsqnonlin(fun,x0,lb,ub,options)
主要用于最小二乘法寻找最优点。(直接把函数值传进去寻找最小值)

示例:飞机定位

函数文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function f = feijidingwei(x,x0,y0,theta,sigma,d4,sigma4)
for i = 1:3
f(i) = (atan2(x(1)-x0(i),x(2)-y0(i))-theta(i))/sigma(i);%最小二乘的1~3个参数(注意没有平方,lsqcurvefit函数会加上)
end
f(4) = (sqrt((x(1)-x0(4))^2+(x(2)-y0(4))^2)-d4)/sigma4;%最小二乘的第四个参数
主程序
X = [746 629 1571 155];
Y = [1393 375 259 987];
theta = [161.2,45.1,309.0-360]*2*pi/360;
sigma = [0.8,0.6,1.3]*2*pi/360;
d4 = 864.3;
sigma4 = 2;
x0 = [900,700];%大约估计的飞机位置
[x,norm,res,exit,out] = lsqnonlin(@feijidingwei,x0,[],[],[],X,Y,theta,sigma,d4,sigma4)%注意这里主初始值就是x0,然后接着三个空数组,然后才能把额外参数传进来
%输出
x =

1.0e+02 *

9.783070295413857 7.239837766517786


norm =

0.668471174541973

lsqcurvefit 也可以最小二乘但是尝试了许多方法它都无法传入更多的参数……遂放弃