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实现模拟登录及表单提交的方法
Jul 25 Python
菜鸟使用python实现正则检测密码合法性
Jan 05 Python
python 读写、创建 文件的方法(必看)
Sep 12 Python
Python实现的插入排序算法原理与用法实例分析
Nov 22 Python
浅谈python数据类型及类型转换
Dec 18 Python
python简单实现操作Mysql数据库
Jan 29 Python
图文详解python安装Scrapy框架步骤
May 20 Python
教你一步步利用python实现贪吃蛇游戏
Jun 27 Python
Python with用法:自动关闭文件进程
Jul 10 Python
Django上使用数据可视化利器Bokeh解析
Jul 31 Python
python接口调用已训练好的caffe模型测试分类方法
Aug 26 Python
详解使用python3.7配置开发钉钉群自定义机器人(2020年新版攻略)
Apr 01 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
古巴咖啡 Cubita琥爵咖啡 独特的加勒比海风味咖啡
2021/03/06 新手入门
用文本文件实现的动态实时发布新闻的程序
2006/10/09 PHP
Array of country list in PHP with Zend Framework
2011/10/17 PHP
PHP解析目录路径的3个函数总结
2014/11/18 PHP
PHP实现图片压缩
2020/09/09 PHP
php+mysql开发中的经验与常识小结
2019/03/25 PHP
jQuery之end()和pushStack()使用介绍
2012/02/07 Javascript
jQuery之尺寸调整组件的深入解析
2013/06/19 Javascript
Javascript:为input设置readOnly属性(示例讲解)
2013/12/25 Javascript
js中定义一个变量并判断其是否为空的方法
2014/05/13 Javascript
JavaScript使用Math.Min返回两个数中较小数的方法
2015/04/06 Javascript
BootStrap与validator 使用笔记(JAVA SpringMVC实现)
2016/09/21 Javascript
JS组件系列之JS组件封装过程详解
2017/04/28 Javascript
Nodejs中获取当前函数被调用的行数及文件名详解
2018/12/12 NodeJs
vue 中几种传值方法(3种)
2019/11/12 Javascript
javascript开发实现贪吃蛇游戏
2020/07/31 Javascript
JavaScript实现点击图片换背景
2020/11/20 Javascript
python如何生成网页验证码
2018/07/28 Python
Python实现从SQL型数据库读写dataframe型数据的方法【基于pandas】
2019/03/18 Python
Python使用Socket实现简单聊天程序
2020/02/28 Python
Django 如何使用日期时间选择器规范用户的时间输入示例代码详解
2020/05/22 Python
Java Unsafe类实现原理及测试代码
2020/09/15 Python
森海塞尔美国官网:Sennheiser耳机与耳麦
2017/07/19 全球购物
荟萃全球保健品:维他购
2018/05/09 全球购物
俄罗斯花园种植材料批发和零售网上商店:Беккер
2019/07/22 全球购物
美术师范毕业生自荐信
2013/11/16 职场文书
教师求职推荐信范文
2013/11/20 职场文书
二年级学生评语大全
2014/04/23 职场文书
公司董事长助理工作职责
2014/07/12 职场文书
公证委托书
2014/08/01 职场文书
调研汇报材料范文
2014/08/17 职场文书
捐助倡议书
2015/01/19 职场文书
谢师宴学生致辞
2015/07/27 职场文书
企业法律事务工作总结
2015/08/11 职场文书
大队委员竞选稿
2015/11/20 职场文书
详解Java实践之建造者模式
2021/06/18 Java/Android