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 相关文章推荐
使用Protocol Buffers的C语言拓展提速Python程序的示例
Apr 16 Python
Python File readlines() 使用方法
Mar 19 Python
Python利用公共键如何对字典列表进行排序详解
May 19 Python
python使用xlrd模块读取xlsx文件中的ip方法
Jan 11 Python
对IPython交互模式下的退出方法详解
Feb 16 Python
Python统计一个字符串中每个字符出现了多少次的方法【字符串转换为列表再统计】
May 05 Python
详解用pyecharts Geo实现动态数据热力图城市找不到问题解决
Jun 26 Python
python库matplotlib绘制坐标图
Oct 18 Python
python编程进阶之异常处理用法实例分析
Feb 21 Python
Python如何爬取qq音乐歌词到本地
Jun 01 Python
Python控制台实现交互式环境执行
Jun 09 Python
Python实现视频自动打码的示例代码
Apr 08 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写的MySQL数据库用户认证系统代码
2007/03/22 PHP
php _autoload自动加载类与机制分析
2012/02/10 PHP
phpmail类发送邮件函数代码
2012/02/20 PHP
深入file_get_contents与curl函数的详解
2013/06/25 PHP
zend Framework中的Layout(模块化得布局)详解
2013/06/28 PHP
php购物车实现方法
2015/01/03 PHP
简单谈谈PHP中的include、include_once、require以及require_once语句
2016/04/23 PHP
php实现购物车功能(以大苹果购物网为例)
2017/03/09 PHP
PHP实现获取毫秒时间戳的方法【使用microtime()函数】
2019/03/01 PHP
thinkphp5 + ajax 使用formdata提交数据(包括文件上传) 后台返回json完整实例
2020/03/02 PHP
javascript的parseFloat()方法精度问题探讨
2013/11/26 Javascript
Javascript获取当前日期的农历日期代码
2014/10/08 Javascript
javascript实现捕捉键盘上按下的键
2015/05/05 Javascript
半个小时学json(json传递示例)
2016/12/25 Javascript
Vue.js实现文章评论和回复评论功能
2020/05/30 Javascript
VueJS 集成 Medium Editor的示例代码 (自定义编辑器按钮)
2017/08/24 Javascript
解决bootstrap模态框数据缓存的问题方法
2018/08/10 Javascript
trackingjs+websocket+百度人脸识别API实现人脸签到
2018/11/26 Javascript
vue-cli系列之vue-cli-service整体架构浅析
2019/01/14 Javascript
nodejs微信开发之接入指南
2019/03/17 NodeJs
VUE UPLOAD 通过ACTION返回上传结果操作
2020/09/07 Javascript
Vue+Vant 图片上传加显示的案例
2020/11/03 Javascript
[47:48]DOTA2上海特级锦标赛D组小组赛#2 Liquid VS VP第三局
2016/02/28 DOTA
[43:24]2018DOTA2亚洲邀请赛3月29日 小组赛A组 LGD VS Liquid
2018/03/30 DOTA
[01:59][TI9趣味视频] 全明星赛奖励
2019/08/23 DOTA
python给微信好友定时推送消息的示例
2019/02/20 Python
Python调用钉钉自定义机器人的实现
2020/01/03 Python
Lombok插件安装(IDEA)及配置jar包使用详解
2020/11/04 Python
Html5 audio标签样式的修改
2016/01/28 HTML / CSS
流行文化收藏品:Sideshow(DC漫画,星球大战,漫威)
2019/03/17 全球购物
Mountain Warehouse波兰官方网站:英国户外品牌
2019/08/29 全球购物
2014年劳动部工作总结
2014/12/11 职场文书
2015年社区消防安全工作总结
2015/10/14 职场文书
演讲稿:态度决定一切
2019/04/02 职场文书
MySQL中你可能忽略的COLLATION实例详解
2021/05/12 MySQL
阿里云k8s服务升级时502错误 springboot项目应用
2022/04/09 Servers