醉汉随机行走/随机漫步问题(Random Walk Drunk Python)

世界上有些问题看似是随机的(stochastic),没有规律可循,但很可能是人类还未发现和掌握这类事件的规律,所以说它们是随机发生的。

随机漫步(Random  Walk)是一种解决随机问题的方法,它与人类生活息息相关,例如醉汉行走的轨迹、布朗运动(Brownian Motion)、股票的涨跌等都可以用它来模拟。随机漫步已经应用到数学,物理,生物学,医学,经济等领域。

假设某地有一个醉汉,每一秒钟会朝“东”,“南”,“西”,“北”中的一个方向走一步,那么这个醉汉在走了500步之后会在什么地方?1000步呢?是不是随着时间的增长,醉汉离原点越来越远呢?这个问题看似很随机,无法解决,但是如果用电脑程序来模拟,那么就可以很容易地把醉汉行走的轨迹,醉汉离原点的距离展现出来。

解决思路:

设计四个class,分别是:Location(表示醉汉所在的位置),Direction(表示醉汉行走的方向,如果要增加或修改方向,在这个class中修改即可),Field(表示一个醉汉所在的平面区域,如果要增加醉汉的数量,在这个class中修改即可),Drunk(表示醉汉本身)

代码如下:

import math, random, pylab

class Location:
    def __init__(self,x,y):  #定义醉汉的位置,即平面上的一点,用x和y坐标表示
        self.x=x
        self.y=y
    def move(self,xc,yc):  #输入x和y坐标的变动值,返回变动后的坐标
        return Location(self.x+xc,self.y+yc)
    def getLocation(self):
        return self.x,self.y
    def getDistance(self,other):  #输入另一个点的坐标,根据x轴和y轴变动的距离,算出原点和另一个点之间的直线距离
        ox,oy=other.getLocation()
        xDist=ox-self.x
        yDist=oy-self.y
        return math.sqrt(xDist**2+yDist**2)

class Direction:
    possibleDirection=("S","W","E","N")  #可能的四种方向
    def __init__(self,direc):  #定义方向,如果此方向不在可能的四种方向里面,那么报错
        if direc in self.possibleDirection:
            self.direc=direc
        else:
            raise ValueError("in direction:__init__")
    def move(self,dist):  #输入移动距离,根据不同的方向返回平面距离
        if self.direc=="S": return (0,-dist)
        if self.direc=="W": return (-dist,0)
        if self.direc=="E": return (dist,0)
        if self.direc=="N": return (0,dist)
        else: raise ValueError("in direction: move")

class Field:
    def __init__(self,drunk,loc):  #定义醉汉和其所在的平面
        self.drunk=drunk
        self.loc=loc
    def move(self,direc,dist):  #输入方向和移动距离,获得x和y坐标的变动值,在原点上移动该值,获得变动后的坐标
        oldLoc=self.loc
        xc,yc=direc.move(dist)
        self.loc=oldLoc.move(xc,yc)
    def getLocation(self):
        return self.loc
    def getDrunk(self):
        return self.drunk

class Drunk:
    def __init__(self,name):
        self.name=name
    def move(self,field,step=1):
        if field.getDrunk()!=self:
            raise ValueError("No such drunk is found on the field")
        for i in range(step):
            direc=Direction(random.choice(Direction.possibleDirection))
            field.move(direc,1)

def performTrial(step,f):
    startLoc=f.getLocation()
    distances=[0]
    for t in range(1,step+1):
        f.getDrunk().move(f)
        newLoc=f.getLocation()
        distance=newLoc.getDistance(startLoc)
        distances.append(distance)
    return distances

drunk=Drunk("Baichi")
for i in range(3):
    f=Field(drunk,Location(0,0))
    distances=performTrial(500,f)
    pylab.plot(distances)
pylab.title("Baichi Walk")
pylab.xlabel("Time")
pylab.ylabel("Distance")
pylab.show()

运行结果如下:

可以看出,随着时间的推移,醉汉离原点越来越远。

人们通常想当然地以为醉汉随机朝四种方向行走,来来回回,兜兜转转,估计最后还是走到离原点不远的地方。但其实醉汉每走一步,之前的基点都会随之变化。(走第一步时,100%的几率会离原点更远;走第二步时,75%的几率会离原点更远,只有25%的几率会回到原点。这就是因为走第一步时,基点是原点,而走第二步时,基点变成了走完第一步后所在的点。)

在现实生活中,假如有一天你的股票大跌,这意味着你想要收回成本的可能性就很低了。因为基点已经被拉低。。。(啊啊啊啊。。。不要告诉我这个惨痛的事实啊!!!)

参考:麻省理工学院公开课:计算机科学及编程导论(第17集)

时间: 2024-10-13 08:17:13

醉汉随机行走/随机漫步问题(Random Walk Drunk Python)的相关文章

随机漫步(random walk)

1.题目 有一类问题总称为"随机漫步"(Random Walk)问题,这类问题长久以来吸引着数学界的兴趣.所有这些问题即使是最简单的解决起来也是极其困难的.而且它们在很大程度上还远没有得到解决.一个这样的问题可以描述为: 在矩形的房间里,铺有n×m块瓷砖,现将一只(醉酒的)蟑螂放在地板中间一个指定方格里.蟑螂随机地从一块瓷砖"漫步"到另一块瓷砖(可能是在找一片阿司匹林).假设它可能从其所在的瓷砖移动到其周围八块瓷砖中的任何一个(除非碰到墙壁),那么它把每一块瓷砖都至

二维有限格点上的随机行走

对于一个10x10的网格,从网格的中心出发,向四个方向行进的概率都是1/4,如果行走过程中遇到边界(撞到墙了),那么拒绝这一步行走.那么最终得到的分布是不是均匀分布呢?从结果上来最终得到的是均匀分布.我们可以用Metroplis抽样来解释.首先抽样过程中满足细致平衡,因为我们在撞墙的时候进行了REJECT,算法中隐含的Markov转移矩阵显然也是各态遍历的,所以最终得到均匀分布并不奇怪. % random_walk bounded 001 % 2 dimensional random walk

HDU 4487 Maximum Random Walk 概率 dp

D - Maximum Random Walk Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4487 Appoint description:  System Crawler  (2016-05-03) Description Consider the classic random walk: at each step, you ha

加入商品分类信息,考虑用户所处阶段的 图模型 推荐算法 Rws(random walk with stage)

场景: 一个新妈妈给刚出生的宝宝买用品,随着宝宝的长大,不同的阶段需要不同的物品. 这个场景中涉及到考虑用户所处阶段,给用户推荐物品的问题. 如果使用用户协同过滤,则需要根据购买记录,找到与用户处于同一阶段的用户. 不加入分类信息,单纯使用物品信息,则可能因为买了不同牌子的尿布,而判断为非相似用户, 所以加入商品分类信息 算法步骤: 1.   加入分类信息 1)   根据时间将用户交易记录分成若干阶段(比如,近90天,近360天-近90天,...) 2)   对于中的记录(以中的为例),在向量的

2013ACM-ICPC杭州赛区全国邀请赛——Random Walk

题目链接 题意: n个点,按照题中给的公式可以求出任意两个点转移的概率.求从1到n的期望转移次数 分析: 设dp[i]为从i到n的期望,那么可以得到公式dp[i] = sigma(dp[i + j] * p(i + j, i)),1 <= j <= m 把这个式子展开来:dp[i - m] * p(i - m, i) + dp[i - m + 1] * dp(i - m + 1, i) + ... + dp[i] * p(i, i) + ... + dp[i + m] * p(i + m, i

HDOJ 4579 Random Walk 解方程

Random Walk Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others) Total Submission(s): 200    Accepted Submission(s): 117 Problem Description Yuanfang is walking on a chain. The chain has n nodes numbered from 1 to n. Ev

HDU 4487 Maximum Random Walk

Maximum Random Walk Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 756    Accepted Submission(s): 419 三维dp,一维的话根本没有办法开展,二维的话没办法保存当前位置或者最远位置,所以只能用三维的. 看不懂滚动数组之类的操作,只能傻傻的写. 具体内容在代码里标注了,三重循环,从i,j,

随机游走模型(Random Walk)

给定了一个时间顺序向量\(z_1,...,z_T\),rw模型是由次序r来定义的,\(z_t\)仅取决于前\(t-r\)个元素.当r = 1时为最简单的RW模型. 给定了向量的其他元素,\(z_t\)的条件分布为: \(z_t|z_{t-1} ~ Normal(z_{t-1} ,\sigma^2)\) 原文地址:https://www.cnblogs.com/jiaxinwei/p/12304503.html

python 随机生成验证码,应用random和chr函数

四位的随机验证码,chr函数的用法 b=[] for i in range(4): import random c=random.randint(97,122)#仅小写的ascll码范围 b.append(chr(c)) d=''.join(b) print(d) 四位随机验证码,包含大小写和数字 codelist=[] import random for i in range(48,58):#ascll码的数字范围,也可以直接用数字1-10 codelist.append(str(chr(i)