當前位置:
首頁 >
随机游走
發布時間:2024/8/24
47
生活家
隨機游走
1.布朗運動是隨機游走的一種,隨機游走廣泛應用于對物理過程、生物過程(eg:DNA在異源雙鏈中替換RNA的動力學過程)和社會過程(eg:股市走向)的建模
本文主要通過醉漢游走來進行闡述
問題提出
一個酩酊大醉的農夫站在一片田地的正中央,他每秒鐘都會向一個隨機的方向邁出一步。那么1000秒之后,他與原點的期望距離是多少?如果他走了很多步,那么會離原點越來越遠,還是更可能一遍又一遍地走回原點,并停留在附近?
問題建模
針對問題中的情形,創建出3個明顯的類型:Location、Field、Drunk
1.Location:明確體現兩個重要的決策,第一我們在模擬中至多有兩個維度。第二提供的deltaX和deltaY的值可以是浮點數,不要求是整數。
2.Field:將醉漢與位置進行映射,它對位置沒有限制,可以認為Field是無限的。
3.Drunk和UsualDrunk類定義了醉漢的游走方式。
在UsualDrunk類中的stepChoices的值引入一個限制,每一步都是一個長度單位,并且必須平行于X軸或Y軸。
代碼
1.三大類
class Location(object):
def __init__(self, x, y):
"""x和y為數值型"""
self.x, self.y = x, y
def move(self, deltaX, deltaY):
"""deltaX和deltaY為數值型"""
return Location(self.x + deltaX, self.y + deltaY)
def getX(self):
return self.x
def getY(self):
return self.y
def distFrom(self, other):
ox, oy = other.x, other.y
xDist, ydist = self.x – ox, self.y – oy
return (xDist**2 + yDist**2)**0.5
def __str__(self):
return '<' + str(self.x) + ', ' + str(self.y) + '>'
class Field(object):
def __init__(self):
self.drunks = {}
def addDrunk(self, drunk, loc):
if drunk in self.drunks:
raise ValueError('Duplicate drunk')
else:
self.drunks[drunk] = loc
def moveDrunk(self, drunk):
if drunk not in self.drunks:
raise ValueError('Drunk not in field')
xDist, yDist = drunk.takeStep()
currentLocation = self.drunks[drunk]
#使用Location的move方法獲得一個新位置
self.drunks[drunk] = currentLocation.move(xDist, yDist)
def getLoc(self, drunk):
if drunk not in self.drunks:
raise ValueError('Drunk not in field')
return self.drunks[drunk]
import random
class Drunk(object):
def __init__(self, name = None):
"""假設name是字符串"""
self.name = name
def __str__(self):
if self != None:
return self.name
return 'Anonymous'
class UsualDrunk(Drunk):
def takeStep(self):
stepChoices = [(0,1), (0,-1), (1, 0), (-1, 0)]
return random.choice(stepChoices)
return random.choice(stepChoices)
2.建立模擬模型
def walk(f, d, numSteps):
"""假設f是一個Field對象,d是f中的一個Drunk對象,numSteps是正整數。
將d移動numSteps次;返回這次游走最終位置與開始位置之間的距離"""
start = f.getLoc(d)
for s in range(numSteps):
f.moveDrunk(d)
return start.distFrom(f.getLoc(d))
def simWalks(numSteps, numTrials, dClass):
"""假設numSteps是非負整數,numTrials是正整數,
dClass是Drunk的一個子類。
模擬numTrials次游走,每次游走numSteps步。
返回一個列表,表示每次模擬的最終距離"""
Homer = dClass()
origin = Location(0, 0)
distances = []
for t in range(numTrials):
f = Field()
f.addDrunk(Homer, origin)
distances.append(round(walk(f, Homer, numTrials), 1))
return distances
def drunkTest(walkLengths, numTrials, dClass):
"""假設walkLengths是非負整數序列
numTrials是正整數,dClass是Drunk的一個子類
對于walkLengths中的每個步數,運行numTrials次simWalks函數,并輸出結果"""
for numSteps in walkLengths:
distances = simWalks(numSteps, numTrials, dClass)
print(dClass.__name__, 'random walk of', numSteps, 'steps')
print(' Mean =', round(sum(distances)/len(distances), 4))
print(' Max =', max(distances), 'Min =', min(distances))
代碼解釋
1.函數walk模擬了numSteps步的一次游走;函數simWalks調用了walk模擬numTrials次游走,每次numSteps步;函數drunkTest電泳simWalks模擬多次不同長度的游走。
2.simWalks的參數dClass是一個class類型,用于在函數第一行創建一個合適的Drunk子類;然后,從Field。moveDrunk中調用drunktakeStep時,會自動選擇相應的子方法。
3.函數drunkTest中也有一個class類型的參數dClass,他被使用了兩次,一次在調用simWalks時,一次在print語句中,在print語句中,使用class類型的內置屬性__name__得到一個字符串,這個字符串就是類名。
運行結果
最后drunkTest((10,100,1000,10000),100,UsualDrunk)輸出結果:
UsualDrunk random walk of 10 steps
Mean = 8.634
Max = 21.6 Min = 1.4
UsualDrunk random walk of 100 steps
Mean = 8.57
Max = 22.0 Min = 0.0
UsualDrunk random walk of 1000 steps
Mean = 9.206
Max = 21.6 Min = 1.4
UsualDrunk random walk of 10000 steps
Mean = 8.727
Max = 23.5 Min = 1.4
Monkey
總結
- 上一篇: 伊力特酒(伊力特酒的前世今生)
- 下一篇: 湖南旅游攻略(盘点湖南必玩景点及实用行程