日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

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

發(fā)布時(shí)間:2023/12/1 python 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python游走代码_介绍一个全局最优化的方法:随机游走算法(Random Walk) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1. 關(guān)于全局最優(yōu)化求解

全局最優(yōu)化是一個(gè)非常復(fù)雜的問題,目前還沒有一個(gè)通用的辦法可以對(duì)任意復(fù)雜函數(shù)求解全局最優(yōu)值。上一篇文章講解了一個(gè)求解局部極小值的方法——梯度下降法。這種方法對(duì)于求解精度不高的情況是實(shí)用的,可以用局部極小值近似替代全局最小值點(diǎn)。但是當(dāng)要求精確求解全局最小值時(shí),梯度下降法就不適用了,需要采用其他的辦法求解。常見的求解全局最優(yōu)的辦法有拉格朗日法、線性規(guī)劃法、以及一些人工智能算法比如遺傳算法、粒子群算法、模擬退火算法等(可以參見我之前的博客)。而今天要講的是一個(gè)操作簡(jiǎn)單但是不易陷入局部極小值的方法:隨機(jī)游走算法。

2. 隨機(jī)游走算法操作步驟

設(shè)\(f(x)\)是一個(gè)含有\(zhòng)(n\)個(gè)變量的多元函數(shù),\(x=(x_1,x_2,…,x_n)\)為\(n\)維向量。

給定初始迭代點(diǎn)\(x\),初次行走步長(zhǎng)\(\lambda\),控制精度\(\epsilon\)(\(\epsilon\)是一個(gè)非常小的正數(shù),用于控制結(jié)束算法)。

給定迭代控制次數(shù)\(N\),\(k\)為當(dāng)前迭代次數(shù),置\(k=1\)。

當(dāng) \(k

計(jì)算函數(shù)值,如果 \(f(x_1)

如果連續(xù)\(N\)次都找不到更優(yōu)的值,則認(rèn)為,最優(yōu)解就在以當(dāng)前最優(yōu)解為中心,當(dāng)前步長(zhǎng)為半徑的\(N\)維球內(nèi)(如果是三維,則剛好是空間中的球體)。此時(shí),如果\(\lambda < \epsilon\),則結(jié)束算法;否則,令\(\lambda = \frac{\lambda}{2}\),回到第1步,開始新一輪游走。

3. 隨機(jī)游走的代碼實(shí)現(xiàn)(使用Python)

這里使用的測(cè)試函數(shù)為\(f(r) = \frac{sin(r)}{r} + 1,r=\sqrt{(x-50)^2+(y-50)^2}+e,0 \leq x,y \leq 100\),求\(f(r)\)的最大值。該函數(shù)是一個(gè)多峰函數(shù),在\((50,50)\)處取得全局最大值\(1.1512\),第二最大值在其全局最大值附近,采用一般的優(yōu)化方法很容易陷入局部極大值點(diǎn)。這里是求解函數(shù)的最大值問題,可以將其轉(zhuǎn)化為求目標(biāo)函數(shù)的相反數(shù)的最小值問題。具體代碼如下:

#!/usr/bin/env python

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

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

# @Author : Lyrichu

# @Email : 919987476@qq.com

# @File : random_walk.py

'''

@Description:使用隨機(jī)游走算法求解函數(shù)極值

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

求解f的最大值,可以轉(zhuǎn)化為求-f的最小值問題

'''

from __future__ import print_function

import math

import random

N = 100 # 迭代次數(shù)

step = 0.5 # 初始步長(zhǎng)

epsilon = 0.00001

variables = 2 # 變量數(shù)目

x = [49,49] # 初始點(diǎn)坐標(biāo)

walk_num = 1 # 初始化隨機(jī)游走次數(shù)

print("迭代次數(shù):",N)

print("初始步長(zhǎng):",step)

print("epsilon:",epsilon)

print("變量數(shù)目:",variables)

print("初始點(diǎn)坐標(biāo):",x)

# 定義目標(biāo)函數(shù)

def function(x):

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

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

return -f

# 開始隨機(jī)游走

while(step > epsilon):

k = 1 # 初始化計(jì)數(shù)器

while(k < N):

u = [random.uniform(-1,1) for i in range(variables)] # 隨機(jī)向量

# u1 為標(biāo)準(zhǔn)化之后的隨機(jī)向量

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)): # 如果找到了更優(yōu)點(diǎn)

k = 1

x = x1

else:

k += 1

step = step/2

print("第%d次隨機(jī)游走完成。" % walk_num)

walk_num += 1

print("隨機(jī)游走次數(shù):",walk_num-1)

print("最終最優(yōu)點(diǎn):",x)

print("最終最優(yōu)值:",function(x))

輸出結(jié)果如下:

迭代次數(shù): 100

初始步長(zhǎng): 0.5

epsilon: 1e-05

變量數(shù)目: 2

初始點(diǎn)坐標(biāo): [49, 49]

第1次隨機(jī)游走完成。

第2次隨機(jī)游走完成。

第3次隨機(jī)游走完成。

......

第16次隨機(jī)游走完成。

隨機(jī)游走次數(shù): 16

最終最優(yōu)點(diǎn): [49.99999305065255, 50.00000102537616]

最終最優(yōu)值: -1.15111524497

基本的隨機(jī)游走算法對(duì)于初始點(diǎn)比較敏感,可以看出,當(dāng)初始點(diǎn)位于最優(yōu)點(diǎn)附件時(shí),可以很好地達(dá)到全局最優(yōu)點(diǎn);如果將初始點(diǎn)設(shè)置得離最優(yōu)點(diǎn)較遠(yuǎn),比如設(shè)置初始點(diǎn)為\((10,10)\)時(shí),其他參數(shù)不變,得到結(jié)果為:

隨機(jī)游走次數(shù): 16

最終最優(yōu)點(diǎn): [10.042835581532445, 11.648866165553416]

最終最優(yōu)值: -1.01720848747

可以發(fā)現(xiàn),隨機(jī)游走陷入了局部最優(yōu)點(diǎn)。當(dāng)然,如果增大迭代次數(shù)\(N\)以及初始步長(zhǎng)\(\lambda\),可以在一定程度上增加尋優(yōu)能力,比如設(shè)置\(N=3000,\lambda=10.0\),得到結(jié)果如下:

迭代次數(shù): 3000

初始步長(zhǎng): 10.0

epsilon: 1e-05

變量數(shù)目: 2

初始點(diǎn)坐標(biāo): [10, 10]

第1次隨機(jī)游走完成。

第2次隨機(jī)游走完成。

第3次隨機(jī)游走完成。

......

第20次隨機(jī)游走完成。

隨機(jī)游走次數(shù): 20

最終最優(yōu)點(diǎn): [49.99999900055026, 50.0000023931389]

最終最優(yōu)值: -1.15111697755

可以看出,當(dāng)增大迭代次數(shù)以及初始步長(zhǎng)之后,函數(shù)最終達(dá)到了全局最優(yōu)點(diǎn)。但是迭代次數(shù)增加的代價(jià)則是運(yùn)行時(shí)間的增加。總得來(lái)說(shuō),基本的隨機(jī)游走算法可以很好地達(dá)到全局最優(yōu)點(diǎn),但是有時(shí)會(huì)依賴于初始點(diǎn)的選擇。

4. 改進(jìn)的隨機(jī)游走算法

改進(jìn)的隨機(jī)游走算法的不同之處是在于第3步,原來(lái)是產(chǎn)生一個(gè)隨機(jī)向量\(u\),現(xiàn)在則是產(chǎn)生\(n\)個(gè)隨機(jī)向量\(u_1,u_2,\cdots,u_n\),\(n\)是給定的一個(gè)正整數(shù)。將\(n\)個(gè)\(u_i(i=1,2,\cdots,n)\)標(biāo)準(zhǔn)化得到\(u_1^{‘},u_2^{‘},\cdots,u_n^{‘}\),利用公式\(x_i = x + \lambda u_i^{‘}\),令\(min\{x_1,x_2,\cdots,x_n\}\)替換原來(lái)的\(x_1\),其他步驟保持不變。通過(guò)這種方式改進(jìn)之后,隨機(jī)游走算法的尋優(yōu)能力大大提高,而且對(duì)于初始值的依賴程度也降低了。令\(n=10\),初始點(diǎn)為\((-100,-10)\),\(N=100,\lambda=10.0,\epsilon = 0.00001\),改進(jìn)的隨機(jī)游走算法實(shí)現(xiàn)代碼如下:

#!/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:改進(jìn)的隨機(jī)游走算法

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

求解f的最大值,可以轉(zhuǎn)化為求-f的最小值問題

'''

from __future__ import print_function

import math

import random

N = 100 # 迭代次數(shù)

step = 10.0 # 初始步長(zhǎng)

epsilon = 0.00001

variables = 2 # 變量數(shù)目

x = [-100,-10] # 初始點(diǎn)坐標(biāo)

walk_num = 1 # 初始化隨機(jī)游走次數(shù)

n = 10 # 每次隨機(jī)生成向量u的數(shù)目

print("迭代次數(shù):",N)

print("初始步長(zhǎng):",step)

print("每次產(chǎn)生隨機(jī)向量數(shù)目:",n)

print("epsilon:",epsilon)

print("變量數(shù)目:",variables)

print("初始點(diǎn)坐標(biāo):",x)

# 定義目標(biāo)函數(shù)

def function(x):

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

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

return -f

# 開始隨機(jī)游走

while(step > epsilon):

k = 1 # 初始化計(jì)數(shù)器

while(k < N):

# 產(chǎn)生n個(gè)向量u

x1_list = [] # 存放x1的列表

for i in range(n):

u = [random.uniform(-1,1) for i1 in range(variables)] # 隨機(jī)向量

# u1 為標(biāo)準(zhǔn)化之后的隨機(jī)向量

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對(duì)應(yīng)的x1

if(f1_min < function(x)): # 如果找到了更優(yōu)點(diǎn)

k = 1

x = x11

else:

k += 1

step = step/2

print("第%d次隨機(jī)游走完成。" % walk_num)

walk_num += 1

print("隨機(jī)游走次數(shù):",walk_num-1)

print("最終最優(yōu)點(diǎn):",x)

print("最終最優(yōu)值:",function(x))

輸出結(jié)果如下:

迭代次數(shù): 100

初始步長(zhǎng): 10.0

每次產(chǎn)生隨機(jī)向量數(shù)目: 10

epsilon: 1e-05

變量數(shù)目: 2

初始點(diǎn)坐標(biāo): [-100, -10]

第1次隨機(jī)游走完成。

第2次隨機(jī)游走完成。

第3次隨機(jī)游走完成。

.....

第20次隨機(jī)游走完成。

隨機(jī)游走次數(shù): 20

最終最優(yōu)點(diǎn): [49.999997561093195, 49.99999839875969]

最終最優(yōu)值: -1.15111685082

可以發(fā)現(xiàn),即使迭代次數(shù)\(N=100\)不大,初始點(diǎn)\((-100,-10)\)離最優(yōu)點(diǎn)\((50,50)\)非常遠(yuǎn),改進(jìn)的隨機(jī)游走算法依然可以達(dá)到最優(yōu)點(diǎn)。這說(shuō)明了改進(jìn)的隨機(jī)游走算法具有更強(qiáng)大的尋優(yōu)能力以及對(duì)于初始點(diǎn)更低的依賴性。

注:經(jīng)過(guò)多次試驗(yàn)發(fā)現(xiàn),無(wú)論是隨機(jī)游走算法還是改進(jìn)的隨機(jī)游走算法,對(duì)于步長(zhǎng)都是非常依賴的。步長(zhǎng)\(\lambda\)越大,意味著初始可以尋找最優(yōu)解的空間越大,但同時(shí)也意味著更多的迭代次數(shù)(要搜索空間變大,尋找次數(shù)變多,相應(yīng)時(shí)間自然要增加)。如果步長(zhǎng)取得過(guò)小,即使\(N\)很大,也很難達(dá)到最優(yōu)解。無(wú)論對(duì)于隨機(jī)游走算法還是改進(jìn)的隨機(jī)游走算法皆是如此。所以理論上步長(zhǎng)\(\lambda\)越大越好。但是步長(zhǎng)越大,迭代總次數(shù)越高,算法運(yùn)行時(shí)間越長(zhǎng)。所以實(shí)踐中可以多試驗(yàn)幾次,將\(\lambda\)取得適當(dāng)?shù)卮蠹纯伞?/p>

總結(jié)

以上是生活随笔為你收集整理的python游走代码_介绍一个全局最优化的方法:随机游走算法(Random Walk)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。