1. 关于全局最优化求解

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

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

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

  1. 给定初始迭代点\(x\),初次行走步长\(\lambda\),控制精度\(\epsilon\)(\(\epsilon\)是一个非常小的正数,用于控制结束算法)。
  2. 给定迭代控制次数\(N\),\(k\)为当前迭代次数,置\(k=1\)。
  3. 当 \(k<N\)时,随机生成一个\((-1,1)\)之间的\(n\)维向量\(u = (u_1,u_2,\cdots,u_n),(-1<u_i<1,i=1,2,\cdots,n)\),并将其标准化得到\(u^{'} = \frac{u}{\sqrt{\sum_{i=1}^{n} u_i ^2 }}\)。令\(x_1 = x + \lambda u^{'}\),完成第一步游走。
  4. 计算函数值,如果 \(f(x_1)<f(x)\),即找到了一个比初始值好的点,那么\(k\)重新置为1,将\(x_1\)变为\(x\),回到第2步;否则\(k = k+1\),回到第3步。
  5. 如果连续\(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\)取得适当地大即可。

介绍一个全局最优化的方法:随机游走算法(Random Walk)的更多相关文章

  1. 随机游走模型(Random Walk)

    给定了一个时间顺序向量\(z_1,...,z_T\),rw模型是由次序r来定义的,\(z_t\)仅取决于前\(t-r\)个元素.当r = 1时为最简单的RW模型. 给定了向量的其他元素,\(z_t\) ...

  2. 重启随机游走算法(RWR:Random Walk with Restart)

    1 pagerank算法的基本原理 Pagerank算法是Google的网页排名算法,由拉里佩奇发明.其基本思想是民主表决.在互联网上,如果一个网页被很多其他网页所链接,说明它受到普遍的承认和信赖,那 ...

  3. 推荐系统之基于图的推荐:基于随机游走的PersonalRank算法

    转自http://blog.csdn.net/sinat_33741547/article/details/53002524 一 基本概念 基于图的模型是推荐系统中相当重要的一种方法,以下内容的基本思 ...

  4. 图推荐-基于随机游走的personrank算法

    转自http://blog.csdn.net/sinat_33741547/article/details/53002524 一 基本概念 基于图的模型是推荐系统中相当重要的一种方法,以下内容的基本思 ...

  5. 基于随机游走的三维网格分割算法(Random Walks)

    首先以一维随机游走(1D Random Walks)为例来介绍下随机游走(Random Walks)算法,如下图所示,从某点出发,随机向左右移动,向左和向右的概率相同,都为1/2,并且到达0点或N点则 ...

  6. [PKUWC 2018]随机游走

    Description 题库链接 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次询问给定一个集合 \(S\) ...

  7. Loj #2542. 「PKUWC2018」随机游走

    Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...

  8. LOJ #2542. 「PKUWC 2018」随机游走(最值反演 + 树上期望dp + FMT)

    写在这道题前面 : 网上的一些题解都不讲那个系数是怎么推得真的不良心 TAT (不是每个人都有那么厉害啊 , 我好菜啊) 而且 LOJ 过的代码千篇一律 ... 那个系数根本看不出来是什么啊 TAT ...

  9. 【LOJ2542】【PKUWC 2018】随机游走 min-max容斥 树上高斯消元

    题目描述 有一棵 \(n\) 个点的树.你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(q\) 次询问,每次询问给定一个集合 \(S\),求如果从 \(x\) 出发一 ...

随机推荐

  1. STM32伺服编码器接口

    在STM32的高级定时器和一般定时器中有Encoder interface mode(编码器接口),TI1和TI2分别对应TIM_CH1 和TIM_CH2 通道. 一.计数规则如下: 表55的是编码器 ...

  2. 构建自己的PHP框架--构建模版引擎(2)

    自从来到新公司就一直很忙,最近这段时间终于稍微闲了一点,赶紧接着写这个系列,感觉再不写就烂尾了. 之前我们说到,拿到{{ $name }}这样一段内容时,我们只需要将它转化成<?php echo ...

  3. 排序算法 - 插入排序(Insertion sort)

    插入排序对于少量元素的排序是很高效的,而且这个排序的手法在每个人生活中也是有的哦. 你可能没有意识到,当你打牌的时候,就是用的插入排序. 概念 从桌上的牌堆摸牌,牌堆内是杂乱无序的,但是我们摸上牌的时 ...

  4. Github 开源:高效好用的对象间属性拷贝工具:升讯威 Mapper( Sheng.Mapper)

    Github 地址:https://github.com/iccb1013/Sheng.Mapper 对象属性值映射/拷贝工具.不需要创建映射规则,不要求对象类型一致,适用于简单直接的拷贝操作,可以全 ...

  5. JS 冒泡排序从学到优化

    目的:理解算法 深化算法 冒泡排序: 直接上动图好于文字 一个冒泡实例 45,67,23,88,21,6,99// 第一轮 6次// 45 67 23 88 21 6 99// 45 23 67 88 ...

  6. js前端实现多图图片上传预览

    <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="C ...

  7. noip模拟 市长选举

    题目描述 利贝尔王国的卢安市因为前段时间的市长被捕事件,导致没有市长管理城市.他们需要一个新的市长. 竞选的人有两位.一位是诺曼,因支持旅游业而受到支持者的拥护.一位是波尔多斯,代表的是卢安的传统行业 ...

  8. jquery操作表格总结

    返回表格行 或 列的索引 td是列,tr是行: <script type="text/javascript"> $(document).ready(function() ...

  9. Java 9 揭秘(6. 封装模块)

    Tips 做一个终身学习的人. 在这章节中, 主要介绍以下内容: 封装Java模块的不同格式 JAR格式增强 什么是多版本JAR 如何创建和使用多版本JAR JMOD是什么格式 如何使用jmod工具来 ...

  10. 【Android Developers Training】 95. 创建一个同步适配器

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...