拉格朗日乘子法的目的就是将有等式约束极值问题转化为无约束非线性优化问题,通常这种无约束极值问题我们称之为经典极值问题。
这类问题通常有参数拟合(包括阵列中的MVDR最优系数加权系数)、选址问题等。
可行域内极值点称为全局最优解,邻域内极值点称为局部最优解。
一阶导数 = 梯度;二阶导数 = 海塞矩阵(hesse)
一阶导数是列向量,二阶导数是一阶倒数转置再求导,每一个函数求导后还是按列排放
1、二次函数求极值
1.1、正定二次函数求极值
多元二次函数求极值点时非线性规划中最重要的一种规划类型,矩阵MVDR算法就是这样一个问题。
该类型函数的梯度:
该类型函数的海塞矩阵:
而且根据定理,Q正定时候,二次函数f(X)有唯一极小点,唯一极小值点可以算出解析解:,MVDR的求解就是根据此原理来的。
正定矩阵的判断可以通过matlab的特征值分解实现:
[c,s] = eig(Q);
if min(min(s))>0
正定
else
非正定
end
1.2、半正定二次函数求极值
如果海塞矩阵半正定(包括正定),则可以断定f(X)是凸函数(包括线性规划,也是凸优化的一种),半正定二次函数优化问题又称之为凸优化,凸优化问题中局部最优解就是全局最优解,且此解唯一。
[c,s] = eig(Q);
if min(min(s))>=0
半正定
else
非半正定
end
2、一维搜索求解二次函数极值
求解:
求解代码如下
clc
clear all
close all
syms x;
% fx = x^2 + 2x
% 首先确定搜索区间
%{
1、确定一个初始点 x0,搜索步长 h
2、比较符号,迭代确定区间
%}
%% 首先第一步,确定一个搜索区间
% 选定一个初始点x0=5,步长h=0.3
x0 = 5;
h = 0.5;
% 比较f(x0) 与 f(x0+h) 的大小
fx0 = x0^2 + 2*x0;
fx0h = (x0 + h)^2 + 2*(x0 + h);
fxdif = fx0-fx0h;
% 分情况讨论搜索区间
switch fxdif<0
case 1
fx0_h = (x0 - h)^2 + 2*(x0 - h);
if fx0-fx0_h < 0
dmin = x0-h;
dmax = x0+h;
else
m = 1;
while (1)
fx0_mh = (x0 - 2^m*h)^2 + 2*(x0 - 2^m*h);
fx0_m1h = (x0 - 2^(m-1)*h)^2 + 2*(x0 - 2^(m-1)*h);
fx0_m2h = (x0 - 2^(m-2)*h)^2 + 2*(x0 - 2^(m-2)*h);
if fx0_mh > fx0_m1h
if fx0_m1h <= fx0_m2h
u = x0 - 2^(m-2)*h;
v = x0 - 2^(m-1)*h;
w = x0 - 2^(m)*h;
r = (w + v)/2;
fv = v^2 + 2*v;
fr = r^2 + 2*r;
if fv >= fr
dmin = w;
dmax = v;
else
dmin = r;
dmax = u;
end
break;
end
end
m = m+1;
end
end
case 0
m = 1;
while (1)
fx0mh = (x0 + 2^m*h)^2 + 2*(x0 + 2^m*h);
fx0m1h = (x0 + 2^(m-1)*h)^2 + 2*(x0 + 2^(m-1)*h);
fx0m2h = (x0 + 2^(m-2)*h)^2 + 2*(x0 + 2^(m-2)*h);
if fx0mh > fx0m1h
if fx0m1h <= fx0m2h
u = x0 + 2^(m-2)*h;
v = x0 + 2^(m-1)*h;
w = x0 + 2^(m)*h;
r = (w + v)/2;
fv = v^2 + 2*v;
fr = r^2 + 2*r;
if fv >= fr
dmin = v;
dmax = w;
else
dmin = u;
dmax = r;
end
break;
end
end
m = m+1;
end
end
%% 显示图形
x = dmin:0.01:dmax;
y = x.^2 + 2*x;
plot(x,y)
%% 黄金分割法搜索极小值
while (1)
lambda1 = dmin + (dmax - dmin)*0.382;
lambda2 = dmin + (dmax - dmin)*0.618;
flambda1 = lambda1^2 + 2*lambda1;
flambda2 = lambda2^2 + 2*lambda2;
if flambda1 <= flambda2
dmax = lambda2;
else
dmin = lambda1;
end
if dmax - dmin < 0.01
lambda = (dmax + dmin)/2;
fmin = lambda^2 + 2*lambda;
break;
end
end
fprintf('lambda = %f\n',lambda)
fprintf('fmin = %f',fmin)
运行结果

运行结果
lambda = -0.998354
fmin = -0.999997>>
通过运行结果,可以看出程序给出的极小值点取在x=-0.998354,与真正的极小值解析解x=-1误差极小,可以认为满足题目要求,极小值点处的函数值=-0.999997