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.pswp.cn/news/373828.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/373828.shtml
英文地址,請注明出處:http://en.pswp.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;不同的…