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人脸识别初探
Dec 21 Python
python中ASCII码和字符的转换方法
Jul 09 Python
python logging重复记录日志问题的解决方法
Jul 12 Python
wxPython的安装与使用教程
Aug 31 Python
Python制作exe文件简单流程
Jan 24 Python
通过python爬虫赚钱的方法
Jan 29 Python
Python3简单爬虫抓取网页图片代码实例
Aug 26 Python
tensorflow模型保存、加载之变量重命名实例
Jan 21 Python
tensorflow获取预训练模型某层参数并赋值到当前网络指定层方式
Jan 24 Python
Python嵌入C/C++进行开发详解
Jun 09 Python
python操作微信自动发消息的实现(微信聊天机器人)
Jul 14 Python
python控制台打印log输出重复的解决方法
May 14 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
文章推荐系统(二)
2006/10/09 PHP
解析php中array_merge与array+array的区别
2013/06/21 PHP
PHP数学运算函数大汇总(经典值得收藏)
2016/04/01 PHP
详谈PHP面向对象中常用的关键字和魔术方法
2017/02/04 PHP
PHP封装的多文件上传类实例与用法详解
2017/02/07 PHP
laravel-admin 实现在指定的相册下添加照片
2019/10/21 PHP
基于jquery.Jcrop的头像编辑器
2010/03/01 Javascript
javascript 图片上一张下一张链接效果代码
2010/03/12 Javascript
jQuery实现类似淘宝购物车全选状态示例
2013/06/26 Javascript
使用coffeescript编写node.js项目的方法汇总
2015/08/05 Javascript
jQuery实现的数值范围range2dslider选取插件特效多款代码分享
2015/08/27 Javascript
JavaScript实现ASC转汉字及汉字转ASC的方法
2016/01/23 Javascript
利用select实现年月日三级联动的日期选择效果【推荐】
2016/12/13 Javascript
微信小程序 label 组件详解及简单实例
2017/01/10 Javascript
vue props传值失败 输出undefined的解决方法
2018/09/11 Javascript
手把手教你 CKEDITOR 4 实现Dialog 内嵌 IFrame操作详解
2019/06/18 Javascript
浅谈vue单页面中有多个echarts图表时的公用代码写法
2020/07/19 Javascript
[01:36:17]DOTA2-DPC中国联赛 正赛 Ehome vs iG BO3 第一场 1月31日
2021/03/11 DOTA
python 遍历字符串(含汉字)实例详解
2017/04/04 Python
Python微信库:itchat的用法详解
2017/08/14 Python
Django使用Mysql数据库已经存在的数据表方法
2018/05/27 Python
python爬虫实例详解
2018/06/19 Python
Python 存储字符串时节省空间的方法
2019/04/23 Python
Python弹出输入框并获取输入值的实例
2019/06/18 Python
Pycharm激活方法及详细教程(详细且实用)
2020/05/12 Python
Python日志处理模块logging用法解析
2020/05/19 Python
关于tf.matmul() 和tf.multiply() 的区别说明
2020/06/18 Python
Python GUI之tkinter窗口视窗教程大集合(推荐)
2020/10/20 Python
使用HTML和CSS实现的标签云效果(附demo)
2021/02/03 HTML / CSS
Hotels.com爱尔兰:全球酒店预订
2017/02/24 全球购物
授权委托书样本
2014/04/03 职场文书
中职生自荐信范文
2014/06/15 职场文书
2014教师“四风问题”对照检查材料思想汇报
2014/09/16 职场文书
现役军人家属慰问信
2015/03/24 职场文书
漂亮妈妈观后感
2015/06/08 职场文书
vue中的可拖拽宽度div的实现示例
2022/04/08 Vue.js