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标准日志模块logging的使用方法
Nov 01 Python
Python 多线程实例详解
Mar 25 Python
python实现对指定输入的字符串逆序输出的6种方法
Apr 26 Python
Python中flatten( )函数及函数用法详解
Nov 02 Python
Django rest framework jwt的使用方法详解
Aug 08 Python
Python jieba库用法及实例解析
Nov 04 Python
python numpy数组复制使用实例解析
Jan 10 Python
python爬虫实现获取下一页代码
Mar 13 Python
详解基于python的图像Gabor变换及特征提取
Oct 26 Python
python 利用panda 实现列联表(交叉表)
Feb 06 Python
Python读写Excel表格的方法
Mar 02 Python
再谈python_tkinter弹出对话框创建
Mar 20 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实现根据字符串生成对应数组的方法
2014/09/22 PHP
PHP实现清除wordpress里恶意代码
2015/10/21 PHP
PHP实现多关键字加亮功能
2016/10/21 PHP
PHP defined()函数的使用图文详解
2019/07/20 PHP
javascript密码强度校验代码(两种方法)
2015/08/10 Javascript
JS实现可点击展开与关闭的左侧广告代码
2015/09/02 Javascript
JS实现响应鼠标点击动画渐变弹出层效果代码
2016/03/25 Javascript
用JS实现轮播图效果(二)
2016/06/26 Javascript
基于JS实现发送短信验证码后的倒计时功能(无视页面刷新,页面关闭不进行倒计时功能)
2016/09/02 Javascript
基于vue2框架的机器人自动回复mini-project实例代码
2017/06/13 Javascript
详解redux异步操作实践
2018/08/15 Javascript
jQuery实现表格隔行换色
2018/09/01 jQuery
JavaScript实现联动菜单特效
2020/01/07 Javascript
JavaScript HTML DOM 元素 (节点)新增,编辑,删除操作实例分析
2020/03/02 Javascript
AJAX XMLHttpRequest对象创建使用详解
2020/08/20 Javascript
原生js实现拖拽移动与缩放效果
2020/08/24 Javascript
Python+matplotlib+numpy绘制精美的条形统计图
2018/01/02 Python
pygame游戏之旅 添加游戏介绍
2018/11/20 Python
python批量获取html内body内容的实例
2019/01/02 Python
python分割一个文本为多个文本的方法
2019/07/22 Python
python用线性回归预测股票价格的实现代码
2019/09/04 Python
基于pytorch的lstm参数使用详解
2020/01/14 Python
Python flask框架如何显示图像到web页面
2020/06/03 Python
CSS3实现类似翻书效果的过渡动画的示例代码
2019/09/06 HTML / CSS
JD Sports丹麦:英国领先的运动时尚零售商
2020/11/24 全球购物
DBA数据库管理员JAVA程序员架构师必看
2016/02/07 面试题
七一党建活动方案
2014/01/28 职场文书
优秀语文教师事迹
2014/05/18 职场文书
爱国主义教育演讲稿
2014/08/26 职场文书
医院护士见习期自我鉴定
2014/09/15 职场文书
幼儿园端午节活动总结
2015/05/05 职场文书
有关水浒传的读书笔记
2015/06/25 职场文书
生产实习心得体会范文
2016/01/22 职场文书
MongoDB使用profile分析慢查询的步骤
2021/04/30 MongoDB
小程序实现侧滑删除功能
2022/06/25 Javascript
CentOS7设置ssh服务以及端口修改方式
2022/12/24 Servers