用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编程中一些重用与缩减的建议
Apr 14 Python
python判断给定的字符串是否是有效日期的方法
May 13 Python
Python简单实现TCP包发送十六进制数据的方法
Apr 16 Python
python下读取公私钥做加解密实例详解
Mar 29 Python
Python构建网页爬虫原理分析
Dec 19 Python
Python将多份excel表格整理成一份表格
Jan 03 Python
python梯度下降法的简单示例
Aug 31 Python
python爬取基于m3u8协议的ts文件并合并
Apr 26 Python
python tkinter之 复选、文本、下拉的实现
Mar 04 Python
python的sys.path模块路径添加方式
Mar 09 Python
pyqt5 textEdit、lineEdit操作的示例代码
Aug 12 Python
python+selenium+chrome实现淘宝购物车秒杀自动结算
Jan 07 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
杏林同学录(七)
2006/10/09 PHP
关于ob_get_contents(),ob_end_clean(),ob_start(),的具体用法详解
2013/06/24 PHP
ASP和PHP实现生成网站快捷方式并下载到桌面的方法
2014/05/08 PHP
php简单判断文本编码的方法
2015/07/30 PHP
Yii2实现上下联动下拉框功能的方法
2016/08/10 PHP
PHP连接MySQL数据库三种实现方法
2020/12/10 PHP
仿迅雷焦点广告效果(JQuery版)
2008/11/19 Javascript
JavaScript实现快速排序(自已编写)
2012/12/19 Javascript
jQuery使用fadeout实现元素渐隐效果的方法
2015/03/27 Javascript
javascript中的作用域和闭包详解
2016/01/13 Javascript
jquery ztree实现树的搜索功能
2016/02/25 Javascript
JS闭包、作用域链、垃圾回收、内存泄露相关知识小结
2016/05/16 Javascript
vuex直接赋值的三种方法总结
2018/09/16 Javascript
VUE+elementui面包屑实现动态路由详解
2019/11/04 Javascript
在Vue中获取自定义属性方法:data-id的实例
2020/09/09 Javascript
Python实现类继承实例
2014/07/04 Python
Python实现的计数排序算法示例
2017/11/29 Python
python opencv检测目标颜色的实例讲解
2018/04/02 Python
Python3中的json模块使用详解
2018/05/05 Python
Python实现爬虫从网络上下载文档的实例代码
2018/06/13 Python
numpy向空的二维数组中添加元素的方法
2018/11/01 Python
详解python使用turtle库来画一朵花
2019/03/21 Python
Django中多种重定向方法使用详解
2019/07/17 Python
Python reshape的用法及多个二维数组合并为三维数组的实例
2020/02/07 Python
CSS3 display知识详解
2015/11/25 HTML / CSS
将HTML5 Canvas的内容保存为图片借助toDataURL实现
2013/05/20 HTML / CSS
HTML5在手机端实现视频全屏展示方法
2020/11/23 HTML / CSS
类如何去实现接口
2013/12/19 面试题
乡镇食品安全责任书
2014/07/28 职场文书
群众路线组织生活会发言材料
2014/10/17 职场文书
关于安全的广播稿
2014/10/23 职场文书
2014年小学教研工作总结
2014/12/06 职场文书
期末复习计划
2015/01/19 职场文书
呼啸山庄读书笔记
2015/06/29 职场文书
幼儿园开学家长寄语(2016春季)
2015/12/03 职场文书
如何Tomcat中使用ipv6地址
2022/05/06 Servers