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使用clear方法清除字典内全部数据实例
Jul 11 Python
Python实现矩阵加法和乘法的方法分析
Dec 19 Python
python SMTP实现发送带附件电子邮件
May 22 Python
根据DataFrame某一列的值来选择具体的某一行方法
Jul 03 Python
python Pillow图像处理方法汇总
Oct 16 Python
Series和DataFrame使用简单入门
Nov 13 Python
Python大数据之使用lxml库解析html网页文件示例
Nov 16 Python
使用Matplotlib 绘制精美的数学图形例子
Dec 13 Python
python读取与处理netcdf数据方式
Feb 14 Python
python基于tkinter制作m3u8视频下载工具
Apr 24 Python
Python集合的基础操作
Nov 01 Python
Python+DeOldify实现老照片上色功能
Jun 21 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分页代码详解
2008/03/27 PHP
简单示例AJAX结合PHP代码实现登录效果代码
2008/07/25 PHP
php中in_array函数用法分析
2014/11/15 PHP
CodeIgniter 完美解决URL含有中文字符串
2016/05/13 PHP
laradock环境docker-compose操作详解
2019/07/29 PHP
javascript中最常用的继承模式 组合继承
2010/08/12 Javascript
JSON语法五大要素图文介绍
2012/12/04 Javascript
动态添加删除表格行的js实现代码
2014/02/28 Javascript
jQuery的观察者模式详解
2014/12/22 Javascript
Node.js Streams文件读写操作详解
2016/07/04 Javascript
javascript宿主对象之window.navigator详解
2016/09/07 Javascript
关于Vue实现组件信息的缓存问题
2017/08/23 Javascript
如何去除vue项目中的#及其ie9兼容性
2018/01/11 Javascript
原生js实现随机点餐效果
2019/12/10 Javascript
Python 搭建Web站点之Web服务器与Web框架
2016/11/06 Python
Python实现读取文件最后n行的方法
2017/02/23 Python
解决python文件字符串转列表时遇到空行的问题
2017/07/09 Python
Python针对给定列表中元素进行翻转操作的方法分析
2018/04/27 Python
Python中Numpy ndarray的使用详解
2019/05/24 Python
利用pyuic5将ui文件转换为py文件的方法
2019/06/19 Python
基于python框架Scrapy爬取自己的博客内容过程详解
2019/08/05 Python
python 图像的离散傅立叶变换实例
2020/01/02 Python
基于python-pptx库中文文档及使用详解
2020/02/14 Python
Python读取Excel一列并计算所有对象出现次数的方法
2020/09/04 Python
乌克兰网上珠宝商店:GoldSoveren
2020/03/31 全球购物
计算机软件个人的自荐信范文
2013/12/01 职场文书
带薪年假请假条
2014/02/04 职场文书
团委书记的竞聘演讲稿
2014/04/24 职场文书
小学生推普周国旗下讲话稿
2014/09/21 职场文书
博士生专家推荐信
2014/09/26 职场文书
交通事故委托书范本
2014/09/28 职场文书
2014年审计工作总结
2014/11/17 职场文书
学习党章心得体会2016
2016/01/15 职场文书
年终工作总结范文
2019/06/20 职场文书
MySQL示例讲解数据库约束以及表的设计
2022/06/16 MySQL
Mysql如何查看是否使用到索引
2022/12/24 MySQL