python实现共轭梯度法

作者:Tomator01 时间:2021-10-06 22:39:01 

共轭梯度法是介于最速下降法与牛顿法之间的一个方法,它仅需利用一阶导数信息,但克服了最速下降法收敛慢的缺点,又避免了牛顿法需要存储和计算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

来源:https://blog.csdn.net/Big_Pai/article/details/88540147

标签:python,共轭梯度法
0
投稿

猜你喜欢

  • [js效果] 图片加载进度实时显示

    2007-09-12 19:27:00
  • SQL0290N表空间状态问题:停顿的独占处理

    2008-12-26 17:24:00
  • PHP Session变量不能传送到下一页的解决方法

    2023-11-15 01:41:29
  • Python实现获取nginx服务器ip及流量统计信息功能示例

    2023-08-03 02:03:26
  • python中as用法实例分析

    2023-08-11 01:12:26
  • python采集博客中上传的QQ截图文件

    2021-03-03 16:45:25
  • 深入理解typescript中的infer关键字的使用

    2023-10-13 19:19:33
  • PHP For循环字母A-Z当超过26个字母时输出AA,AB,AC

    2023-10-07 08:09:10
  • python文件的读取、写入与删除

    2022-01-21 21:17:12
  • ASP sql:rs.open语句详细说明

    2008-03-17 11:30:00
  • JS实现二维数组横纵列转置的方法

    2023-08-29 21:54:05
  • Golang算法问题之整数拆分实现方法分析

    2023-07-01 00:39:36
  • 盗亦有道 Web2.0网站优秀模仿者逐个数

    2007-09-11 19:46:00
  • Firefox 的 Jetpack 扩展案例分析:Gmail 邮件提醒

    2009-10-15 12:41:00
  • oracle数据库在客户端建立dblink语法

    2023-07-14 19:51:23
  • SQL语句操作主从关系表

    2011-06-19 13:19:05
  • Python测试线程应用程序过程解析

    2023-09-11 03:04:25
  • 解决SQLServer最大流水号的两个好方法

    2009-01-13 14:15:00
  • 限制文本框只能输入数字和小数点

    2009-05-29 18:19:00
  • 浅谈视觉设计的准确性

    2007-09-18 17:59:00
  • asp之家 网络编程 m.aspxhome.com