MATLAB中使用基础优化算法求解二次函数问题
2020-03-01 10:04
1066 查看
啊第一次在csdn上写东西,在前些时候优化方法的计算实习老师留了一些上机作业,第一道题目是用不同的优化算法结合最速下降法求解二次函数。
二次函数及梯度的生成
先贴代码/matlab:
function Function_value = Quadratic_function(x) %Quadratic_function(x)函数用来对给定的x返回二次函数值 n = 146; a = unidrnd(10,n,1); G = a*a'+unidrnd(2)*eye(n); b = 0.5*G*ones(n,1); Function_value = 1/2*(x')*G*x-(b')*x;
我们使用unidrnd函数生成随机整数的列向量,我们的基础二次函数的形式是:
以及写出的梯度函数为之后做准备,不过这个函数的梯度特别好求,写不写都可。
function Gradient_value = Function_gradient(x) %我们将要计算函数Quadratic_function对146个变量的导数 Gradient_value = G*x - b;
最速下降法加精确线搜索
function xk = Steepest_plus_Exact_line_search() %我们采用精确线搜索加最速下降法 x0 = zeros(146,1); eps = 0.001; n = 146; a = unidrnd(10,n,1); G = a*a'+unidrnd(2)*eye(n); b = 0.5*G*ones(n,1); %做循环的准备条件 k = 0;xk = x0; res = norm(Function_gradient(xk)); while res > eps && k<=10000 %dk gk = G*xk-b; dk = -gk; %alphak alphak = (gk'*gk)/(gk'*G*gk); xk = xk + alphak*dk; %更新k k = k+1; res = norm(gk); %打印循环情况 fprintf('在%d-th轮,梯度的值为——%f\n',k,res); end
啊最速下降法的收敛速度是最慢的。
牛顿法加精确线搜索
function [xk,k] = Newtown_plus_Exact_line_search() %我们采用精确线搜索加最速下降法 x0 = zeros(146,1); eps = 0.001; n = 146; a = unidrnd(10,n,1); G = a*a'+unidrnd(2)*eye(n); b = 0.5*G*ones(n,1); %做循环的准备条件 gk = Function_gradient(x0); res = norm(gk); k = 0; xk = x0; G_inverse = inv(G); alphak = 1; while res > eps && k<=10000 %dk dk = -G_inverse*gk; gk = G*xk-b; alphak = -(dk'*gk)/(dk'*G*dk); %xk xk = xk + alphak * dk; %f = Quadratic_function(xk); k = k + 1; res = norm(gk); %打印循环结果 fprintf('在%d-th轮,梯度的值为——%f\n',k,res); end
然后牛顿法是最快的,因为实际上对于二次函数问题来说的话,牛顿法可以一步达到最小值点。
共轭梯度法
function [x_star]=Conjugate_gradient_method() %在该脚本下我们使用共轭梯度法进行求解 %给定x0,eps x0 = zeros(146,1); eps = 0.001; %为方便使用将条件列出: n = 146; a = unidrnd(10,n,1); G = a*a'+unidrnd(2)*eye(n); b = 0.5*G*ones(n,1); gradk = G*x0 - b; k=0; %选择初始点,最大迭代次数 xk=x0; maxit=10000; while 1 %gradk的二范数 res=norm(gradk); %第k次迭代 k=k+1; %算法停止条件 if res<=eps||k>maxit break; end %确定下降方向 dk=-gradk; %计算步长 alphak=-gradk'*dk/(dk'*G*dk); %迭代核心 xk=xk+alphak*dk; %计算Beta grad_temp=gradk; gradk=G*xk-b; Betak=gradk'*gradk/(grad_temp'*grad_temp); dk=-gradk+Betak*dk; fprintf('At the %d-th iteration,the residual is %f\n',k,res); end x_star=xk;
共轭梯度达到最小值不超过n步,但迭代一段时间之后,正交性会消失,实际步数可能会比n多。
BFGS加精确线搜索
function[x_star]= BFGS_plus_Exact_line_search() %在该脚本下我们使用BFGS加精确线搜索求解问题 %给定x0,eps x0 = zeros(146,1); eps = 0.001; xk=x0; %为方便使用将条件列出: n = 146; a = unidrnd(10,n,1); G = a*a'+unidrnd(2)*eye(n); b = 0.5*G*ones(n,1); %gk,hess阵 gradk = Function_gradient(xk);hess = G; res=norm(gradk);k=0;Hk=eye(146); %开始循环 while res>eps&&k<=10000 dk=-Hk*gradk; %exact line search alphak=-dk'*gradk/(dk'*hess*dk); %保存xk xkk=xk; %计算下一点 xk=xk+alphak*dk; %两点差 deltak=xk-xkk; %保存xk的梯度 gradkk=gradk; %unidrnd生成的数是随机的,要用第一次hess阵和b gradk=hess*xk-b; %两点梯度差 yk=gradk-gradkk; %bfgs公式 Hk=(eye(146)-(deltak*yk')/(deltak'*yk))*Hk*(eye(146)-(yk*deltak')/(deltak'*yk))+(deltak*deltak')/(deltak'*yk); k=k+1; %下一点梯度范数 res=norm(gradk); fprintf('At the %d-th iteration,the residual is:----%f\n',k,res) end x_star=xk; end
最后通过这四种方法计算出来的结果应该均是收敛到0.5,所以到此就做完了这道题!
- 不过有一说一,在做完之后看代码确实有好多问题,其实我觉得首先梯度文件就不用写,每次要求梯度的时候直接用Gx-b就很方便,而且写的过程中,也要一直用初始的G和b,但是如果多次调用function_value函数的话就每次随机得到的也是不同的矩阵,所以就会出问题,也是自己遇到的问题之一。
- 第二个问题是写这种算法,很容易思路混乱,所以下次如果再有类似的情况,希望自己可以先将算法一步一步写出来,这样的话编程序的时候也思路比较清楚,而且修改代码也更容易。
啊到这第一篇就写完了!!完事 收工!!
- 点赞 1
- 收藏
- 分享
- 文章举报
相关文章推荐
- poj-1322-Chocolate 使用动态规划求解的一种概率问题的算法
- 粒子群算法求解优化问题(MATLAB)
- 算法问题求解基础
- 使用MATLAB进行一次和二次规划问题求解
- 算法之使用递归求解迷宫问题
- 算法基础-使用循环不变式解决插入排序问题
- 使用不同的算法求解0-1背包问题
- Matlab优化工具箱(optimization toolbox)使用时出现的一个问题
- 【Algorithm】一般约束优化问题——PHR算法及其Matlab实现
- 双弹簧系统中最小势能问题的基础优化算法研究
- 使用matlab实现遗传算法解决飞行员侦查问题
- matlab求解非线性约束+线性规划+超定欠定普通方程组等优化问题
- 使用MATLAB自带函数求解二次特征值问题
- 第一篇:算法之使用递归求解迷宫问题
- 使用 Matlab 的 bvp4c 求解边值问题
- 回溯算法基础---皇后问题,骑士游历,迷宫求解
- 三分算法及利用三分算法求解二次函数问题
- 使用matlab用优化后的梯度下降法求解达最小值时参数
- 算法实例一 算法问题求解基础--欧几里得递归算法和递归算法
- 利用Matlab优化工具箱求解旅行商最短路径问题