用Python实现最速下降法求极值的方法


Posted in Python onJuly 10, 2019

对于一个多元函数用Python实现最速下降法求极值的方法,用最速下降法(又称梯度下降法)求其极小值的迭代格式为

用Python实现最速下降法求极值的方法

其中用Python实现最速下降法求极值的方法为负梯度方向,即最速下降方向,αkαk为搜索步长。

一般情况下,最优步长αkαk的确定要用到线性搜索技术,比如精确线性搜索,但是更常用的是不精确线性搜索,主要是Goldstein不精确线性搜索和Wolfe法线性搜索。

为了调用的方便,编写一个Python文件,里面存放线性搜索的子函数,命名为linesearch.py,这里先只编写了Goldstein线性搜索的函数,关于Goldstein原则,可以参看最优化课本。

线性搜索的代码如下(使用版本为Python3.3):

'''
线性搜索子函数
'''

import numpy as np
import random

def goldsteinsearch(f,df,d,x,alpham,rho,t):

  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
    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

上述函数的输入参数主要包括一个多元函数f,其导数df,当前迭代点x和当前搜索方向d,返回值是根据Goldstein准则确定的搜索步长。

我们仍以Rosenbrock函数为例,即有

用Python实现最速下降法求极值的方法

于是可得函数的梯度为

用Python实现最速下降法求极值的方法

最速下降法的代码如下:

"""
最速下降法
Rosenbrock函数
函数 f(x)=100*(x(2)-x(1).^2).^2+(1-x(1)).^2
梯度 g(x)=(-400*(x(2)-x(1)^2)*x(1)-2*(1-x(1)),200*(x(2)-x(1)^2))^(T)
"""

import numpy as np
import matplotlib.pyplot as plt
import random
import linesearch
from linesearch import goldsteinsearch

def rosenbrock(x):
  return 100*(x[1]-x[0]**2)**2+(1-x[0])**2

def jacobian(x):
  return np.array([-400*x[0]*(x[1]-x[0]**2)-2*(1-x[0]),200*(x[1]-x[0]**2)])


X1=np.arange(-1.5,1.5+0.05,0.05)
X2=np.arange(-3.5,2+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条轮廓线

def steepest(x0):

  print('初始点为:')
  print(x0,'\n')  
  imax = 20000
  W=np.zeros((2,imax))
  W[:,0] = x0
  i = 1   
  x = x0
  grad = jacobian(x)
  delta = sum(grad**2) # 初始误差


  while i<imax and delta>10**(-5):
    p = -jacobian(x)
    x0=x
    alpha = goldsteinsearch(rosenbrock,jacobian,p,x,1,0.1,2)
    x = x + alpha*p
    W[:,i] = x
    grad = jacobian(x)
    delta = sum(grad**2)
    i=i+1

  print("迭代次数为:",i)
  print("近似最优解为:")
  print(x,'\n')  
  W=W[:,0:i] # 记录迭代点
  return W

x0 = np.array([-1.2,1])
W=steepest(x0)

plt.plot(W[0,:],W[1,:],'g*',W[0,:],W[1,:]) # 画出迭代点收敛的轨迹
plt.show()

为了实现不同文件中函数的调用,我们先用import函数导入了线性搜索的子函数,也就是下面的2行代码

import linesearch
from linesearch import goldsteinsearch

当然,如果把定义goldsteinsearch函数的代码直接放到程序里面,就不需要这么麻烦了,但是那样的话,不仅会使程序显得很长,而且不便于goldsteinsearch函数的重用。

此外,Python对函数式编程也支持的很好,在定义goldsteinsearch函数时,可以允许抽象的函数f,df作为其输入参数,只要在调用时实例化就可以了。与Matlab不同的是,传递函数作为参数时,Python是不需要使用@将其变为函数句柄的。

运行结果为

初始点为:

[-1.2 1. ] 

迭代次数为: 1504

近似最优解为:

[ 1.00318532 1.00639618]

迭代点的轨迹为

用Python实现最速下降法求极值的方法

由于在线性搜索子程序中使用了随机函数,初始搜索点是随机产生的,因此每次运行的结果不太相同,比如再运行一次程序,得到

初始点为:
[-1.2 1. ] 

迭代次数为: 1994

近似最优解为:
[ 0.99735222 0.99469882]

所得图像为

用Python实现最速下降法求极值的方法

以上这篇用Python实现最速下降法求极值的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python ElementTree 基本读操作示例
Apr 09 Python
python生成器的使用方法
Nov 21 Python
python列表操作使用示例分享
Feb 21 Python
Python第三方库的安装方法总结
Jun 06 Python
python基于twisted框架编写简单聊天室
Jan 02 Python
Python 数值区间处理_对interval 库的快速入门详解
Nov 16 Python
python2和python3的输入和输出区别介绍
Nov 20 Python
pygame游戏之旅 计算游戏中躲过的障碍数量
Nov 20 Python
pyqt 多窗口之间的相互调用方法
Jun 19 Python
在python里面运用多继承方法详解
Jul 01 Python
python实现银行账户系统
Feb 22 Python
Python深度学习之Pytorch初步使用
May 20 Python
python networkx 根据图的权重画图实现
Jul 10 #Python
python networkx 包绘制复杂网络关系图的实现
Jul 10 #Python
python卸载后再次安装遇到的问题解决
Jul 10 #Python
Python求离散序列导数的示例
Jul 10 #Python
Python Matplotlib 基于networkx画关系网络图
Jul 10 #Python
我们为什么要减少Python中循环的使用
Jul 10 #Python
详解Python中的各种转义符\n\r\t
Jul 10 #Python
You might like
php 运行效率总结(提示程序速度)
2009/11/26 PHP
使用php记录用户通过搜索引擎进网站的关键词
2014/02/13 PHP
PHP调用VC编写的COM组件实例
2014/03/29 PHP
php使用curl存储cookie的示例
2014/03/31 PHP
php使用ZipArchive函数实现文件的压缩与解压缩
2015/10/27 PHP
PHP explode()函数的几个应用和implode()函数有什么区别
2015/11/05 PHP
基于PHP实现用户在线状态检测
2020/11/10 PHP
javascript import css实例代码
2008/07/18 Javascript
js,jQuery 排序的实现代码,网页标签排序的实现,标签排序
2011/04/27 Javascript
基于jquery的文本框与autocomplete结合使用(asp.net+json)
2012/05/30 Javascript
jQuery提交表单ajax查询实例代码
2012/10/07 Javascript
浅析JavaScript中的CSS属性及命名规范
2013/11/28 Javascript
JS根据生日算年龄的方法
2015/05/05 Javascript
论JavaScript模块化编程
2016/03/07 Javascript
一步一步封装自己的HtmlHelper组件BootstrapHelper(三)
2016/09/14 Javascript
js实现自定义路由
2017/02/04 Javascript
vue拦截器Vue.http.interceptors.push使用详解
2017/04/22 Javascript
Vue利用canvas实现移动端手写板的方法
2018/05/03 Javascript
vue 在服务器端直接修改请求的接口地址
2020/12/19 Vue.js
[17:00]DOTA2 HEROS教学视频教你分分钟做大人-帕克
2014/06/10 DOTA
python监控网卡流量并使用graphite绘图的示例
2014/04/27 Python
在Django中创建第一个静态视图
2015/07/15 Python
Python判断文件和字符串编码类型的实例
2017/12/21 Python
使用python实现http及ftp服务进行数据传输的方法
2018/10/26 Python
python 修改本地网络配置的方法
2019/08/14 Python
Python实现把类当做字典来访问
2019/12/16 Python
计算机专业个人求职自荐信
2013/09/21 职场文书
生产主管岗位职责
2013/11/10 职场文书
金融行业职业生涯规划范文
2014/01/17 职场文书
争论的故事教学反思
2014/02/06 职场文书
《油菜花开了》教学反思
2014/02/22 职场文书
意向协议书范本
2014/04/23 职场文书
迎国庆演讲稿
2014/09/05 职场文书
2015年毕业生自我鉴定模板
2014/09/19 职场文书
车间统计员岗位职责
2015/04/14 职场文书
java.util.NoSuchElementException原因及两种解决方法
2022/06/28 Java/Android