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在校内发人人网状态(人人网看状态)
Feb 19 Python
浅谈Python 的枚举 Enum
Jun 12 Python
python3.5绘制随机漫步图
Aug 27 Python
使用numba对Python运算加速的方法
Oct 15 Python
python opencv摄像头的简单应用
Jun 06 Python
Python常用模块os.path之文件及路径操作方法
Dec 03 Python
tensorflow实现测试时读取任意指定的check point的网络参数
Jan 21 Python
tensorflow对图像进行拼接的例子
Feb 05 Python
python如何删除文件、目录
Jun 23 Python
套娃式文件夹如何通过Python批量处理
Aug 23 Python
详解pytorch tensor和ndarray转换相关总结
Sep 03 Python
Python实现Matplotlib,Seaborn动态数据图
May 06 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中操作Excel实例代码
2010/04/29 PHP
ThinkPHP提交表单时默认自动转义的解决方法
2014/11/25 PHP
php源码分析之DZX1.5随机数函数random用法
2015/06/17 PHP
PHP QRCODE生成彩色二维码的方法
2016/05/19 PHP
php实现生成带二维码图片并强制下载功能
2018/02/24 PHP
PHP上传文件及图片到七牛的方法
2018/07/25 PHP
php实现获取近几日、月时间示例
2019/07/06 PHP
jQuery+PHP实现图片上传并提交功能
2020/07/27 PHP
js 利用className得到对象的实现代码
2011/11/15 Javascript
页面只能打开一次Cooike如何实现
2012/12/04 Javascript
浅析JavaScript基本类型与引用类型
2014/05/28 Javascript
js+css实现文字散开重组动画特效代码分享
2015/08/21 Javascript
全面解析Bootstrap排版使用方法(标题)
2015/11/30 Javascript
jQuery Mobile动态刷新页面样式的实现方法
2016/05/28 Javascript
DOM 事件的深入浅出(一)
2016/12/05 Javascript
使用原生的javascript来实现轮播图
2017/02/24 Javascript
微信小程序“摇一摇”的实例代码
2017/07/20 Javascript
详解react-router 4.0 下服务器如何配合BrowserRouter
2017/12/29 Javascript
使用vue实现一个电子签名组件的示例代码
2020/01/06 Javascript
JavaScript 中判断变量是否为数字的示例代码
2020/10/22 Javascript
微信小程序实现购物车功能
2020/11/18 Javascript
[02:16]DOTA2英雄基础教程 干扰者
2014/01/15 DOTA
Python 2.7中文显示与处理方法
2018/07/16 Python
[原创]Python入门教程1. 基本运算【四则运算、变量、math模块等】
2018/10/28 Python
python实现图片识别汽车功能
2018/11/30 Python
numpy.random模块用法总结
2019/05/27 Python
python 图像的离散傅立叶变换实例
2020/01/02 Python
基于python的docx模块处理word和WPS的docx格式文件方式
2020/02/13 Python
HTML5在微信内置浏览器下右上角菜单的调整字体导致页面显示错乱的问题
2021/01/19 HTML / CSS
idealfit英国:世界领先的女性健身用品和运动衣物品牌
2017/11/25 全球购物
建筑施工实习自我鉴定
2013/09/19 职场文书
四年大学生活的自我评价范文
2014/02/07 职场文书
高中毕业自我评价
2014/02/08 职场文书
党课知识竞赛主持词
2014/04/01 职场文书
食堂标语大全
2014/06/11 职场文书
办公室规章制度范本
2015/08/04 职场文书