zoukankan      html  css  js  c++  java
  • 随机游走

    随机游走

    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
  • 相关阅读:
    php网页,想弹出对话框, 消息框 简单代码
    PHP搜索MYSQL数据库加分页浏览小结
    js验证表单大全
    百度 UEditor 简单安装调试和调用,网上其它的教程太官方了,不适合新手
    百度 迷你版 UMeditor富文本编辑器 使用方法
    mysql开启全文索引功能
    PHP 简单实现MySQL数据搜索、添加数据功能 以设备管理为例
    PHP 只有登陆后才能浏览的简单实现
    mongodb在windows下的安装
    ubuntu上mongodb的安装
  • 原文地址:https://www.cnblogs.com/monkeyT/p/9496246.html
Copyright © 2011-2022 走看看