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 03 Python
Python实现的简单模板引擎功能示例
Sep 02 Python
详解python实现识别手写MNIST数字集的程序
Aug 03 Python
通过shell+python实现企业微信预警
Mar 07 Python
pandas 如何分割字符的实现方法
Jul 29 Python
python使用pandas抽样训练数据中某个类别实例
Feb 28 Python
Django 项目布局方法(值得推荐)
Mar 22 Python
python爬虫快速响应服务器的做法
Nov 24 Python
使用python将微信image下.dat文件解密为.png的方法
Nov 30 Python
Python Selenium库的基本使用教程
Jan 04 Python
python实现图片转字符画的完整代码
Feb 21 Python
Python time库的时间时钟处理
May 02 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连接SQLServer2005方法及代码
2013/12/26 PHP
php采用curl实现伪造IP来源的方法
2014/11/21 PHP
php实现指定字符串中查找子字符串的方法
2015/03/17 PHP
PHP程序员必须知道的两种日志实例分析
2020/05/14 PHP
基于PHP实现发微博动态代码实例
2020/12/11 PHP
JS实多级联动下拉菜单类,简单实现省市区联动菜单!
2007/05/03 Javascript
javascript 操作文件 实现方法小结
2009/07/02 Javascript
JS 非图片动态loading效果实现代码
2010/04/09 Javascript
jQuery创建自己的插件(自定义插件)的方法
2010/06/10 Javascript
JSONP之我见
2015/03/24 Javascript
Javascript中的return作用及javascript return关键字用法详解
2015/11/05 Javascript
js前端解决跨域问题的8种方案(最新最全)
2016/11/18 Javascript
BootStrap Table对前台页面表格的支持实例讲解
2016/12/22 Javascript
JS 调用微信扫一扫功能
2016/12/22 Javascript
浅谈Vue.js路由管理器 Vue Router
2018/08/16 Javascript
JS实现数组去重,显示重复元素及个数的方法示例
2019/01/21 Javascript
微信小程序swiper禁止用户手动滑动代码实例
2019/08/23 Javascript
在vue中对数组值变化的监听与重新响应渲染操作
2020/07/17 Javascript
[02:45]2016年中国刀塔全程回顾,完美“圣”典即将上演
2016/12/15 DOTA
python如何实现excel数据添加到mongodb
2015/07/30 Python
windows下python之mysqldb模块安装方法
2017/09/07 Python
一篇文章快速了解Python的GIL
2018/01/12 Python
Python selenium根据class定位页面元素的方法
2019/02/26 Python
实例详解Matlab 与 Python 的区别
2019/04/26 Python
解决python tkinter界面卡死的问题
2019/07/17 Python
python找出因数与质因数的方法
2019/07/25 Python
Python生成验证码、计算具体日期是一年中的第几天实例代码详解
2019/10/16 Python
实习自我鉴定
2013/12/15 职场文书
大学生职业生涯规划书模板
2014/01/18 职场文书
区优秀教师事迹材料
2014/02/10 职场文书
餐厅楼面部长岗位职责范文
2014/02/16 职场文书
少先队学雷锋活动总结范文
2014/03/09 职场文书
竞选班干部演讲稿300字
2014/08/20 职场文书
医生党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
为什么MySQL选择Repeatable Read作为默认隔离级别
2021/07/26 MySQL
漫画「古见同学有交流障碍症」第25卷封面公开
2022/03/21 日漫