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的Django框架中包装视图函数
Jul 20 Python
Python简单连接MongoDB数据库的方法
Mar 15 Python
python实现SMTP邮件发送功能
Jun 16 Python
python实现发送邮件功能代码
Dec 14 Python
python提取log文件内容并画出图表
Jul 08 Python
python在openstreetmap地图上绘制路线图的实现
Jul 11 Python
Python 操作 ElasticSearch的完整代码
Aug 04 Python
numpy ndarray 取出满足特定条件的某些行实例
Dec 05 Python
python绘制封闭多边形教程
Feb 18 Python
python链表类中获取元素实例方法
Feb 23 Python
Python使用paramiko连接远程服务器执行Shell命令的实现
Mar 04 Python
解决numpy和torch数据类型转化的问题
May 23 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编程注意事项的小结
2013/04/27 PHP
又十个超级有用的PHP代码片段
2015/09/24 PHP
Yii2组件之多图上传插件FileInput的详细使用教程
2016/06/20 PHP
PHP AjaxForm提交图片上传并显示图片源码
2016/11/29 PHP
PHP7 mongoDB扩展使用的方法分享
2019/05/02 PHP
浅谈laravel5.5 belongsToMany自身的正确用法
2019/10/17 PHP
Prototype使用指南之selector.js
2007/01/10 Javascript
nicejforms——美化表单不用愁
2007/02/20 Javascript
JS无限树状列表实现代码
2011/01/11 Javascript
JQuery实现当鼠标停留在某区域3秒后自动执行
2014/09/09 Javascript
复制网页内容,粘贴之后自动加上网址的实现方法(脚本之家特别整理)
2014/10/16 Javascript
JS中的数组方法笔记整理
2016/07/26 Javascript
jQuery实现底部浮动窗口效果
2016/09/07 Javascript
JavaScript原型继承_动力节点Java学院整理
2017/06/30 Javascript
详解create-react-app 自定义 eslint 配置
2018/06/07 Javascript
React 源码中的依赖注入方法
2018/11/07 Javascript
你可能不知道的CORS跨域资源共享
2019/03/13 Javascript
python批量下载图片的三种方法
2013/04/22 Python
从Python的源码来解析Python下的freeblock
2015/05/11 Python
在Python 字典中一键对应多个值的实例
2019/02/03 Python
Python Numpy中数据的常用保存与读取方法
2020/04/01 Python
Python内置方法和属性应用:反射和单例(推荐)
2020/06/19 Python
详解Python流程控制语句
2020/10/28 Python
香港网上花店:FlowerAdvisor香港
2019/05/30 全球购物
电子信息毕业生自荐信
2013/11/16 职场文书
公司合作协议书范本
2014/04/18 职场文书
小班上学期评语
2014/05/05 职场文书
储备店长岗位职责
2015/04/14 职场文书
纪检监察立案决定书
2015/06/24 职场文书
国家助学金受助感言
2015/08/01 职场文书
2016年乡镇七一建党节活动总结
2016/04/05 职场文书
2016年少先队活动总结
2016/04/06 职场文书
mysql部分操作
2021/04/05 MySQL
SpringCloud之@FeignClient()注解的使用方式
2021/09/25 Java/Android
MySQL数据库如何使用Shell进行连接
2022/04/12 MySQL
LeetCode189轮转数组python示例
2022/08/05 Python