python游走代码_介绍一个全局最优化的方法:随机游走算法(Random Walk)

1. 关于全局最优化求解

全局最优化是一个非常复杂的问题,目前还没有一个通用的办法可以对任意复杂函数求解全局最优值。上一篇文章讲解了一个求解局部极小值的方法——梯度下降法。这种方法对于求解精度不高的情况是实用的,可以用局部极小值近似替代全局最小值点。但是当要求精确求解全局最小值时,梯度下降法就不适用了,需要采用其他的办法求解。常见的求解全局最优的办法有拉格朗日法、线性规划法、以及一些人工智能算法比如遗传算法、粒子群算法、模拟退火算法等(可以参见我之前的博客)。而今天要讲的是一个操作简单但是不易陷入局部极小值的方法:随机游走算法。

2. 随机游走算法操作步骤

设\(f(x)\)是一个含有\(n\)个变量的多元函数,\(x=(x_1,x_2,…,x_n)\)为\(n\)维向量。

给定初始迭代点\(x\),初次行走步长\(\lambda\),控制精度\(\epsilon\)(\(\epsilon\)是一个非常小的正数,用于控制结束算法)。

给定迭代控制次数\(N\),\(k\)为当前迭代次数,置\(k=1\)。

当 \(k

计算函数值,如果 \(f(x_1)

如果连续\(N\)次都找不到更优的值,则认为,最优解就在以当前最优解为中心,当前步长为半径的\(N\)维球内(如果是三维,则刚好是空间中的球体)。此时,如果\(\lambda < \epsilon\),则结束算法;否则,令\(\lambda = \frac{\lambda}{2}\),回到第1步,开始新一轮游走。

3. 随机游走的代码实现(使用Python)

这里使用的测试函数为\(f(r) = \frac{sin(r)}{r} + 1,r=\sqrt{(x-50)^2+(y-50)^2}+e,0 \leq x,y \leq 100\),求\(f(r)\)的最大值。该函数是一个多峰函数,在\((50,50)\)处取得全局最大值\(1.1512\),第二最大值在其全局最大值附近,采用一般的优化方法很容易陷入局部极大值点。这里是求解函数的最大值问题,可以将其转化为求目标函数的相反数的最小值问题。具体代码如下:

#!/usr/bin/env python

# -*- coding: utf-8 -*-

# @Time : 2017/7/20 10:08

# @Author : Lyrichu

# @Email : 919987476@qq.com

# @File : random_walk.py

'''

@Description:使用随机游走算法求解函数极值

这里求解:f = sin(r)/r + 1,r = sqrt((x-50)^2+(y-50)^2)+e,0<=x,y<=100 的最大值

求解f的最大值,可以转化为求-f的最小值问题

'''

from __future__ import print_function

import math

import random

N = 100 # 迭代次数

step = 0.5 # 初始步长

epsilon = 0.00001

variables = 2 # 变量数目

x = [49,49] # 初始点坐标

walk_num = 1 # 初始化随机游走次数

print("迭代次数:",N)

print("初始步长:",step)

print("epsilon:",epsilon)

print("变量数目:",variables)

print("初始点坐标:",x)

# 定义目标函数

def function(x):

r = math.sqrt((x[0]-50)**2 + (x[1]-50)**2) + math.e

f = math.sin(r)/r + 1

return -f

# 开始随机游走

while(step > epsilon):

k = 1 # 初始化计数器

while(k < N):

u = [random.uniform(-1,1) for i in range(variables)] # 随机向量

# u1 为标准化之后的随机向量

u1 = [u[i]/math.sqrt(sum([u[i]**2 for i in range(variables)])) for i in range(variables)]

x1 = [x[i] + step*u1[i] for i in range(variables)]

if(function(x1) < function(x)): # 如果找到了更优点

k = 1

x = x1

else:

k += 1

step = step/2

print("第%d次随机游走完成。" % walk_num)

walk_num += 1

print("随机游走次数:",walk_num-1)

print("最终最优点:",x)

print("最终最优值:",function(x))

输出结果如下:

迭代次数: 100

初始步长: 0.5

epsilon: 1e-05

变量数目: 2

初始点坐标: [49, 49]

第1次随机游走完成。

第2次随机游走完成。

第3次随机游走完成。

......

第16次随机游走完成。

随机游走次数: 16

最终最优点: [49.99999305065255, 50.00000102537616]

最终最优值: -1.15111524497

基本的随机游走算法对于初始点比较敏感,可以看出,当初始点位于最优点附件时,可以很好地达到全局最优点;如果将初始点设置得离最优点较远,比如设置初始点为\((10,10)\)时,其他参数不变,得到结果为:

随机游走次数: 16

最终最优点: [10.042835581532445, 11.648866165553416]

最终最优值: -1.01720848747

可以发现,随机游走陷入了局部最优点。当然,如果增大迭代次数\(N\)以及初始步长\(\lambda\),可以在一定程度上增加寻优能力,比如设置\(N=3000,\lambda=10.0\),得到结果如下:

迭代次数: 3000

初始步长: 10.0

epsilon: 1e-05

变量数目: 2

初始点坐标: [10, 10]

第1次随机游走完成。

第2次随机游走完成。

第3次随机游走完成。

......

第20次随机游走完成。

随机游走次数: 20

最终最优点: [49.99999900055026, 50.0000023931389]

最终最优值: -1.15111697755

可以看出,当增大迭代次数以及初始步长之后,函数最终达到了全局最优点。但是迭代次数增加的代价则是运行时间的增加。总得来说,基本的随机游走算法可以很好地达到全局最优点,但是有时会依赖于初始点的选择。

4. 改进的随机游走算法

改进的随机游走算法的不同之处是在于第3步,原来是产生一个随机向量\(u\),现在则是产生\(n\)个随机向量\(u_1,u_2,\cdots,u_n\),\(n\)是给定的一个正整数。将\(n\)个\(u_i(i=1,2,\cdots,n)\)标准化得到\(u_1^{‘},u_2^{‘},\cdots,u_n^{‘}\),利用公式\(x_i = x + \lambda u_i^{‘}\),令\(min\{x_1,x_2,\cdots,x_n\}\)替换原来的\(x_1\),其他步骤保持不变。通过这种方式改进之后,随机游走算法的寻优能力大大提高,而且对于初始值的依赖程度也降低了。令\(n=10\),初始点为\((-100,-10)\),\(N=100,\lambda=10.0,\epsilon = 0.00001\),改进的随机游走算法实现代码如下:

#!/usr/bin/env python

# -*- coding: utf-8 -*-

# @Time : 2017/7/20 10:48

# @Author : Lyrichu

# @Email : 919987476@qq.com

# @File : improve_random_walk.py

'''

@Description:改进的随机游走算法

这里求解:f = sin(r)/r + 1,r = sqrt((x-50)^2+(y-50)^2)+e,0<=x,y<=100 的最大值

求解f的最大值,可以转化为求-f的最小值问题

'''

from __future__ import print_function

import math

import random

N = 100 # 迭代次数

step = 10.0 # 初始步长

epsilon = 0.00001

variables = 2 # 变量数目

x = [-100,-10] # 初始点坐标

walk_num = 1 # 初始化随机游走次数

n = 10 # 每次随机生成向量u的数目

print("迭代次数:",N)

print("初始步长:",step)

print("每次产生随机向量数目:",n)

print("epsilon:",epsilon)

print("变量数目:",variables)

print("初始点坐标:",x)

# 定义目标函数

def function(x):

r = math.sqrt((x[0]-50)**2 + (x[1]-50)**2) + math.e

f = math.sin(r)/r + 1

return -f

# 开始随机游走

while(step > epsilon):

k = 1 # 初始化计数器

while(k < N):

# 产生n个向量u

x1_list = [] # 存放x1的列表

for i in range(n):

u = [random.uniform(-1,1) for i1 in range(variables)] # 随机向量

# u1 为标准化之后的随机向量

u1 = [u[i3]/math.sqrt(sum([u[i2]**2 for i2 in range(variables)])) for i3 in range(variables)]

x1 = [x[i4] + step*u1[i4] for i4 in range(variables)]

x1_list.append(x1)

f1_list = [function(x1) for x1 in x1_list]

f1_min = min(f1_list)

f1_index = f1_list.index(f1_min)

x11 = x1_list[f1_index] # 最小f1对应的x1

if(f1_min < function(x)): # 如果找到了更优点

k = 1

x = x11

else:

k += 1

step = step/2

print("第%d次随机游走完成。" % walk_num)

walk_num += 1

print("随机游走次数:",walk_num-1)

print("最终最优点:",x)

print("最终最优值:",function(x))

输出结果如下:

迭代次数: 100

初始步长: 10.0

每次产生随机向量数目: 10

epsilon: 1e-05

变量数目: 2

初始点坐标: [-100, -10]

第1次随机游走完成。

第2次随机游走完成。

第3次随机游走完成。

.....

第20次随机游走完成。

随机游走次数: 20

最终最优点: [49.999997561093195, 49.99999839875969]

最终最优值: -1.15111685082

可以发现,即使迭代次数\(N=100\)不大,初始点\((-100,-10)\)离最优点\((50,50)\)非常远,改进的随机游走算法依然可以达到最优点。这说明了改进的随机游走算法具有更强大的寻优能力以及对于初始点更低的依赖性。

注:经过多次试验发现,无论是随机游走算法还是改进的随机游走算法,对于步长都是非常依赖的。步长\(\lambda\)越大,意味着初始可以寻找最优解的空间越大,但同时也意味着更多的迭代次数(要搜索空间变大,寻找次数变多,相应时间自然要增加)。如果步长取得过小,即使\(N\)很大,也很难达到最优解。无论对于随机游走算法还是改进的随机游走算法皆是如此。所以理论上步长\(\lambda\)越大越好。但是步长越大,迭代总次数越高,算法运行时间越长。所以实践中可以多试验几次,将\(\lambda\)取得适当地大即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/373828.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

iOS单元测试

iOS单元测试异步测试需要建立预期&#xff0c;因为苹果的单元测试都是同步的&#xff0c;测试到异步的时候建立一个预期&#xff0c;预期如果在规定时间&#xff08;自定义&#xff09;完成&#xff0c;代表单元测试通过。 还有 猴子测试 &#xff0c;就是去github上找到猴子测…

调试JVM

在某些&#xff08;极少数&#xff09;情况下&#xff0c;您可能会遇到使JVM本身崩溃的情况。 我最近通过将ThreadGroup的名称设置为null来进行管理 。 在这些情况下&#xff0c;调试JVM本身很有用&#xff0c;这样可以更精确地定位崩溃。 这是完成此操作的步骤&#xff08;它们…

javaScript DOM编程常用的方法与属性

DOM是Document Object Model文档对象模型的缩写。根据W3C DOM规范,DOM是一种与浏览器&#xff0c;平台&#xff0c;语言无关的接口&#xff0c;使得你可以访问页面其他的标准组件。 Node接口的特性和方法 特性/方法类型/放回类型说明nodeName String 节点的名字&#xff1b;根…

一:验证微信的Token

前言:申请到微信公众号的同学&#xff0c;可能会挺感兴趣的&#xff0c;毕竟微信公众号&#xff0c;确实是一个好东西&#xff0c;它提供了一个很好的平台&#xff0c;而且它自带有一套管理模板&#xff0c;对于微信公众号可以很好的管理。 但是也仅仅是很好的管理&#xff0c;…

三、 将DataTable 转换为List

1. 方法public static IList<T> ConvertTo<T>(DataTable table) { if (table null) { return null; } List<DataRow> rows new List<DataRow>(); foreach (DataRow row in table.Rows) { rows.Add(row); } return ConvertTo<T>(rows); }2. 调用…

ActiveMQ已准备好黄金时段

ActiveMQ项目始于2005年-在很大程度上&#xff0c;它一直是Apache Software Foundation的顶级项目。 ActiveMQ项目的目的一直是提供世界一流的企业消息传递解决方案&#xff0c;其中经纪人能够提供从支持IP的智能设备一直到企业后端的高可用性的连通性。 ActiveMQ提供跨语言客户…

r语言 adf检验_r语言中如何进行两组独立样本秩和检验

r语言中如何进行两组独立样本秩和检验​tecdat.cn安装所需的包wants <- c("coin") has <- wants %in% rownames(installed.packages()) if(any(!has)) install.packages(wants[!has])>一个样本测试set.seed(123) medH0 <- 30 DV <- sample(0:100, 20,…

MyEclipse 8.5安装Aptana

Aptana简介 Aptana是一个非常强大,开源,专注于JavaScript的Ajax开发IDE它的特性包括&#xff1a; 1、JavaScript,JavaScript函数,HTML,CSS语言的Code Assist功能 2、Outliner(大纲)&#xff1a;显示JavaScript,HTML和CSS的代码结构 3、支持 JavaScript&#xff0c…

2016-1-10 手势解锁demo的实现

一&#xff1a;实现自定义view&#xff0c;在.h,.m文件中代码如下: #import <UIKit/UIKit.h> class ZLLockView; protocol ZLLockViewDelegate <NSObject> - (void)lockView:(ZLLockView *)lockView didSelectedPwd: (NSString *)pwd; end interface ZLLockView : …

php与JAVA的RSA加密互通

Java 版本RSA 进行加密解密 在网上查询了好几天&#xff0c;最终找到解决方案&#xff0c;网络上都是通过Cipher.getInstance("RSA"); 而改成Cipher.getInstance("RSA/ECB/PKCS1Padding");就可以实现与php版本公钥和密钥互通了。 Cipher cipher Cipher.ge…

GWT入门

GWT是Google Web Development Kit的缩写&#xff0c;可让程序员使用Java开发Ajax Web应用程序。 GWT编译器将Java代码转换为JavaScript和html代码。 GWT应用程序称为模块&#xff0c;并且使用xml文件描述模块&#xff0c;假定该模块名称为xml文件的“ mymodule”名称为“ mymod…

JavaScript省市二级联动

XML文件负责保存所需要的数据&#xff0c;而HTML文件负责通过javascript解析XML数据并显示在页面上。代码如下&#xff1a; cities.xml <?xml version"1.0" encoding"GB2312"?> <china><province name"吉林省"><city>…

poj 3579 Median 二分套二分 或 二分加尺取

MedianTime Limit: 1000MS Memory Limit: 65536KTotal Submissions: 5118 Accepted: 1641Description Given N numbers, X1, X2, ... , XN, let us calculate the difference of every pair of numbers: ∣Xi - Xj∣ (1 ≤ i &#xff1c; j ≤ N). We can get C(N,2)differenc…

qt 嵌入web页面_Qt嵌入浏览器(三)——QWebEngine与Https

本篇简介&#xff1a;本篇的小目标&#xff1a;挑战通过Qt WebEngine实现与服务端的Https双向认证双向认证&#xff0c;Qt WebEngine和Chromium这里先说结论&#xff1a;挑战失败了。至少使用Qt WebEngine目前已实现的组件没有办法直接实现双向认证。先来简要分析一下实现双向认…

python模块;opencv安装

http://www.lfd.uci.edu/~gohlke/pythonlibs/ 1. 步骤1. 下载Python2.73, 安装, 并配置Python环境变量:".\Program Files\Python27;";注意: OpenCV仅支持2.6&2.7, Python不能使用3.x版本;2. 下载OpenCV2.46, 安装, 并配置OpenCV环境变量:".\Program Files\o…

Java中的正则表达式–软介绍

正则表达式是一种可以应用于文本&#xff08;Java中的String&#xff09;的模式。 Java提供了java.util.regex包&#xff0c;用于与正则表达式进行模式匹配。 Java正则表达式与Perl编程语言非常相似&#xff0c;并且非常易于学习。 正则表达式匹配文本&#xff08;或文本的一部…

AJAX入门——工作原理

理解同步交互和异步交互 举个例子&#xff1a;普通B/S模式(同步) AJAX技术(异步) * 同步&#xff1a; 提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事。 发送方发出数据后&#xff0c;等接收方发回响应以后才发下一个数据包的…

Couldn’t communicate with a helper application.

出现此问题 的情景 我在提交svn之前&#xff0c;在Xcode中的Images.xcassets里添加了文件夹后又删除了&#xff0c; 但是 在Xcode中提交的时候&#xff0c;左侧勾选文件那一栏中 出现了此文件夹及里边的文件。 解决&#xff1a; 我在conerstore中将此文件夹 remove后&#xff0…

python 复制文件夹内容 并结构一致_Python比较文件夹比另一同名文件夹多出的文件并复制出来的方法...

本文实例讲述了Python比较文件夹比另一同名文件夹多出的文件并复制出来的方法。分享给大家供大家参考。具体如下&#xff1a;这个东东本来是做来给公司数据同步用的&#xff1a;新服务器还没正式启用&#xff0c;旧的服务器还在使用&#xff0c;每天都有大量图片传到旧服务器上…

css控制页面文字不能被选中user-select:none;

现象&#xff1a;html中可能有些地方不想让用户复制文字&#xff0c;或是用a标签做了个点击按钮&#xff0c;点快的时候文字会被选中&#xff0c;很丑&#xff0c;这个时候可以使用下面的方案禁止文字选中。原因&#xff1a;鼠标点快了文字会被选中。解决方案&#xff1a;不同的…