1. 基本思想
以 H_k * ▽f(x_k) 作为下降方向,通过 DFP 方法迭代 H_k,保证 H_k * ▽f(x_k) 一直是函数下降方向。
2. DFP 函数
function [xValue, yValue, k] = DFP_method(f, yDiff, x, xStart, H, e, alpha1)
yDk1 = subs(yDiff, x, xStart);
d = -H * yDk1;
k = 0;
while true
k = k + 1;
%精确一维线搜索,此处用 fminsearch 替代
xcell = num2cell(xStart + alpha1 * d);
f_tmp = matlabFunction(f);
f_alpha = f_tmp(xcell{:});
f_alpha = matlabFunction(f_alpha);
alphaMin = fminsearch(f_alpha, 0);
xStart = xStart + alphaMin * d; % x_k+1 = x_k + alpha * d;
yDk = subs(yDiff, x, xStart); % ▽f(x_k+1)
if norm(yDk) < e
xValue = xStart;
yValue = subs(f, x, xStart);
break;
end
deltaX = alphaMin * d;
deltaY = yDk - yDk1;
yDk1 = yDk;
%DFP方法
H = H + (deltaX * deltaX') / (deltaX' * deltaY) - (H * deltaY) * (H * deltaY)' / (deltaY' * H * deltaY);
d = -H * yDk1;
end
end
程序中,输入参数分别为:
f : 需要求最小值的函数,可以是 matlab 函数
yDiff : 是函数 f 的偏导数,雅可比矩阵
x : f 自变量的形式
xStart : 自变量起始迭代点
H: 起始的正定矩阵 H_0
e : 阈值,函数中止条件
alpha1 : 步长变量,每一次迭代通过精确一维线搜索计算
3. 测试函数
%定义目标函数
syms x1 x2;
x = [x1; x2];
y = x1 * x1 + x2 * x2 - 3 * x1 - x1 * x2 + 3;
%求导数
yDiff = jacobian(y, x);
yDiff = yDiff';
%初始正定阵
H = [1 0; 0 1];
xStart = [0; 0];
syms alpha1;
[xValue, yValue, k] = DFP_method(y, yDiff, x, xStart, H, 0.00001, alpha1);
4. 总结
代码相对简单,主要还是 H 矩阵的选取,H 矩阵又 DFP 公式即为 DFP 方法; 如果用 BFGS 公式就是 BFGS 方法,都是秩二方法。