python实现共轭梯度法


Posted in Python onJuly 03, 2019

共轭梯度法是介于最速下降法与牛顿法之间的一个方法,它仅需利用一阶导数信息,但克服了最速下降法收敛慢的缺点,又避免了牛顿法需要存储和计算Hesse矩阵并求逆的缺点,共轭梯度法不仅是解决大型线性方程组最有用的方法之一,也是解大型非线性最优化最有效的算法之一。 在各种优化算法中,共轭梯度法是非常重要的一种。其优点是所需存储量小,具有步收敛性,稳定性高,而且不需要任何外来参数。

算法步骤:

python实现共轭梯度法

import random
import numpy as np
import matplotlib.pyplot as plt
 
def goldsteinsearch(f,df,d,x,alpham,rho,t):
 '''
 线性搜索子函数
 数f,导数df,当前迭代点x和当前搜索方向d,t试探系数>1,
 '''
 flag = 0
 
 a = 0
 b = alpham
 fk = f(x)
 gk = df(x)
 
 phi0 = fk
 dphi0 = np.dot(gk, d)
 alpha=b*random.uniform(0,1)
 
 while(flag==0):
  newfk = f(x + alpha * d)
  phi = newfk
  # print(phi,phi0,rho,alpha ,dphi0)
  if (phi - phi0 )<= (rho * alpha * dphi0):
   if (phi - phi0) >= ((1 - rho) * alpha * dphi0):
    flag = 1
   else:
    a = alpha
    b = b
    if (b < alpham):
     alpha = (a + b) / 2
    else:
     alpha = t * alpha
  else:
   a = a
   b = alpha
   alpha = (a + b) / 2
 return alpha
 
 
def Wolfesearch(f,df,d,x,alpham,rho,t):
 '''
 线性搜索子函数
 数f,导数df,当前迭代点x和当前搜索方向d
 σ∈(ρ,1)=0.75
 '''
 sigma=0.75
 
 flag = 0
 
 a = 0
 b = alpham
 fk = f(x)
 gk = df(x)
 
 phi0 = fk
 dphi0 = np.dot(gk, d)
 alpha=b*random.uniform(0,1)
 
 while(flag==0):
  newfk = f(x + alpha * d)
  phi = newfk
  # print(phi,phi0,rho,alpha ,dphi0)
  if (phi - phi0 )<= (rho * alpha * dphi0):
   # if abs(np.dot(df(x + alpha * d),d))<=-sigma*dphi0:
   if (phi - phi0) >= ((1 - rho) * alpha * dphi0):
    flag = 1
   else:
    a = alpha
    b = b
    if (b < alpham):
     alpha = (a + b) / 2
    else:
     alpha = t * alpha
  else:
   a = a
   b = alpha
   alpha = (a + b) / 2
 return alpha
 
def frcg(fun,gfun,x0):
 
 
 # x0是初始点,fun和gfun分别是目标函数和梯度
 # x,val分别是近似最优点和最优值,k是迭代次数
 # dk是搜索方向,gk是梯度方向
 # epsilon是预设精度,np.linalg.norm(gk)求取向量的二范数
 maxk = 5000
 rho = 0.6
 sigma = 0.4
 k = 0
 epsilon = 1e-5
 n = np.shape(x0)[0]
 itern = 0
 W = np.zeros((2, 20000))
 
 f = open("共轭.txt", 'w')
 
 while k < maxk:
   W[:, k] = x0
   gk = gfun(x0)
   itern += 1
   itern %= n
   if itern == 1:
    dk = -gk
   else:
    beta = 1.0 * np.dot(gk, gk) / np.dot(g0, g0)
    dk = -gk + beta * d0
    gd = np.dot(gk, dk)
    if gd >= 0.0:
     dk = -gk
   if np.linalg.norm(gk) < epsilon:
    break
 
   alpha=goldsteinsearch(fun,gfun,dk,x0,1,0.1,2)
   # alpha=Wolfesearch(fun,gfun,dk,x0,1,0.1,2)
   x0+=alpha*dk
 
   f.write(str(k)+' '+str(np.linalg.norm(gk))+"\n")
   print(k,alpha)
   g0 = gk
   d0 = dk
   k += 1
 
 W = W[:, 0:k+1] # 记录迭代点
 return [x0, fun(x0), k,W]
 
def fun(x):
 return 100 * (x[1] - x[0] ** 2) ** 2 + (1 - x[0]) ** 2
def gfun(x):
 return np.array([-400 * x[0] * (x[1] - x[0] ** 2) - 2 * (1 - x[0]), 200 * (x[1] - x[0] ** 2)])
 
 
if __name__=="__main__":
 X1 = np.arange(-1.5, 1.5 + 0.05, 0.05)
 X2 = np.arange(-3.5, 4 + 0.05, 0.05)
 [x1, x2] = np.meshgrid(X1, X2)
 f = 100 * (x2 - x1 ** 2) ** 2 + (1 - x1) ** 2 # 给定的函数
 plt.contour(x1, x2, f, 20) # 画出函数的20条轮廓线
 
 x0 = np.array([-1.2, 1])
 x=frcg(fun,gfun,x0)
 print(x[0],x[2])
 # [1.00318532 1.00639618]
 W=x[3]
 # print(W[:, :])
 plt.plot(W[0, :], W[1, :], 'g*-') # 画出迭代点收敛的轨迹
 plt.show()

代码中求最优步长用得是goldsteinsearch方法,另外的Wolfesearch是试验的部分,在本段程序中不起作用。

迭代轨迹:

python实现共轭梯度法

python实现共轭梯度法

三种最优化方法的迭代次数对比:

最优化方法 最速下降法 共轭梯度法 牛顿法
迭代次数 1702 240 5

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
从零学python系列之数据处理编程实例(一)
May 22 Python
python使用正则表达式分析网页中的图片并进行替换的方法
Mar 26 Python
浅谈Python类里的__init__方法函数,Python类的构造函数
Dec 10 Python
Python类的继承和多态代码详解
Dec 27 Python
Python 通配符删除文件的实例
Apr 24 Python
python按时间排序目录下的文件实现方法
Oct 17 Python
Linux CentOS Python开发环境搭建教程
Nov 28 Python
解决python线程卡死的问题
Feb 18 Python
如何运行.ipynb文件的图文讲解
Jun 27 Python
python 计算平均平方误差(MSE)的实例
Jun 29 Python
Python+opencv 实现图片文字的分割的方法示例
Jul 04 Python
应用OpenCV和Python进行SIFT算法的实现详解
Aug 21 Python
python实现微信自动回复及批量添加好友功能
Jul 03 #Python
Python 中Django安装和使用教程详解
Jul 03 #Python
利用python求积分的实例
Jul 03 #Python
python可视化爬虫界面之天气查询
Jul 03 #Python
python读写配置文件操作示例
Jul 03 #Python
Python正则表达式匹配数字和小数的方法
Jul 03 #Python
在python中利用numpy求解多项式以及多项式拟合的方法
Jul 03 #Python
You might like
PHP的一个完整SMTP类(解决邮件服务器需要验证时的问题)
2006/10/09 PHP
php HtmlReplace输入过滤安全函数
2010/07/03 PHP
PHP基于数组实现的分页函数实例
2014/08/20 PHP
Zend Framework教程之分发器Zend_Controller_Dispatcher用法详解
2016/03/07 PHP
php5.2的curl-bug 服务器被php进程卡死问题排查
2016/09/19 PHP
PHP数组相加操作及与array_merge的区别浅析
2016/11/26 PHP
基于win2003虚拟机中apache服务器的访问
2017/08/01 PHP
jquery的键盘事件修改代码
2011/02/24 Javascript
jquery checkbox实现单选小例
2013/11/27 Javascript
Javascript:为input设置readOnly属性(示例讲解)
2013/12/25 Javascript
js 获取页面高度和宽度兼容 ie firefox chrome等
2014/05/14 Javascript
JavaScript bold方法入门实例(把指定文字显示为粗体)
2014/10/17 Javascript
详解handlebars+require基本使用方法
2016/12/21 Javascript
React BootStrap用户体验框架快速上手
2018/03/06 Javascript
vue axios登录请求拦截器
2018/04/02 Javascript
react 创建单例组件的方法
2018/04/26 Javascript
浅谈webpack SplitChunksPlugin实用指南
2018/09/17 Javascript
vue设置动态请求地址的例子
2019/11/01 Javascript
vue实现几秒后跳转新页面代码
2020/09/09 Javascript
对python读写文件去重、RE、set的使用详解
2018/12/11 Python
python实现kmp算法的实例代码
2019/04/03 Python
python怎么调用自己的函数
2020/07/01 Python
详解vscode实现远程linux服务器上Python开发
2020/11/10 Python
让IE下支持Html5的placeholder属性的插件
2014/09/02 HTML / CSS
C#中的验证控件有几种
2014/03/08 面试题
EJB的基本架构
2016/09/22 面试题
汽车技术服务与营销专业在籍生自荐信
2013/09/28 职场文书
毕业生就业自荐信
2013/12/04 职场文书
车辆年审委托书范本
2014/09/18 职场文书
购房个人委托书范本
2014/10/11 职场文书
2014年党建工作总结
2014/11/11 职场文书
优秀共产党员推荐材料
2014/12/18 职场文书
预备党员个人总结
2015/02/14 职场文书
上课讲话检讨书范文
2015/05/07 职场文书
SpringBoot 整合mongoDB并自定义连接池的示例代码
2022/02/28 MongoDB
Python几种酷炫的进度条的方式
2022/04/11 Python