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的Flask框架中使用日期和时间的教程
Apr 21 Python
Python制作简易注册登录系统
Dec 15 Python
python中模块的__all__属性详解
Oct 26 Python
200 行python 代码实现 2048 游戏
Jan 12 Python
selenium python 实现基本自动化测试的示例代码
Feb 25 Python
python创造虚拟环境方法总结
Mar 04 Python
基于python if 判断选择结构的实例详解
May 06 Python
Python之Class&amp;Object用法详解
Dec 25 Python
TensorFlow加载模型时出错的解决方式
Feb 06 Python
使用Python将语音转换为文本的方法
Aug 10 Python
Python函数递归调用实现原理实例解析
Aug 11 Python
Python操作dict时避免出现KeyError的几种解决方法
Sep 20 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学习笔记汇总
2014/10/05 PHP
PHP实现登陆表单提交CSRF及验证码
2017/01/24 PHP
PHP实践教程之过滤、验证、转义与密码详解
2017/07/24 PHP
ThinkPHP5分页paginate代码实例解析
2020/11/10 PHP
利用JS重写Cognos右键菜单的实现代码
2010/04/11 Javascript
一个可拖拽列宽表格实例演示
2012/11/26 Javascript
javascript检测对象中是否存在某个属性判断方法小结
2013/05/19 Javascript
一个支付页面DEMO附截图
2014/07/22 Javascript
js简单实现Select互换数据的方法
2015/08/17 Javascript
JS监听微信、支付宝等移动app及浏览器的返回、后退、上一页按钮的事件方法
2016/08/05 Javascript
BootStrap Table复选框默认选中功能的实现代码(从数据库获取到对应的状态进行判断是否为选中状态)
2017/07/11 Javascript
Vue.js中组件中的slot实例详解
2017/07/17 Javascript
详解使用webpack打包编写一个vue-toast插件
2017/11/08 Javascript
原生JS实现动态添加新元素、删除元素方法
2019/05/05 Javascript
一文快速详解前端框架 Vue 最强大的功能
2019/05/21 Javascript
Element-UI+Vue模式使用总结
2020/01/02 Javascript
vue webpack build资源相对路径的问题及解决方法
2020/06/04 Javascript
[03:08]TI9战队档案 - Vici Gaming
2019/08/20 DOTA
python中list循环语句用法实例
2014/11/10 Python
Python编程使用tkinter模块实现计算器软件完整代码示例
2017/11/29 Python
tensorflow训练中出现nan问题的解决
2018/02/10 Python
Python延时操作实现方法示例
2018/08/14 Python
python+opencv边缘提取与各函数参数解析
2020/03/09 Python
Scrapy 配置动态代理IP的实现
2020/09/28 Python
Python paramiko使用方法代码汇总
2020/11/20 Python
matplotlib制作雷达图报错ValueError的实现
2021/01/05 Python
美国演唱会和体育门票购买网站:Ticketnetwork
2018/10/19 全球购物
汽车专业人才自我鉴定范文
2013/12/29 职场文书
毕业生的自我评价
2013/12/30 职场文书
五好关工委申报材料
2014/05/31 职场文书
职工小家建设活动方案
2014/08/25 职场文书
反腐倡廉剖析材料
2014/09/30 职场文书
终止劳动合同通知书
2015/04/16 职场文书
志愿者服务活动总结报告
2015/05/06 职场文书
mysql备份策略的实现(全量备份+增量备份)
2021/07/07 MySQL
MySQL 逻辑备份 into outfile
2022/05/15 MySQL