另一个使用Python的简单随机行走模拟(二维)

2024-05-14 03:22:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试解决书中的二维随机行走问题,探索python。 但是,我不知道如何解决这个问题。我做了一些研究,但是这些研究太复杂了,无法理解它是关于什么的。我是个初学者。所以,我看不懂代码。请详细地向我解释这个问题。

不管怎样,问题是:

The two dimensional variation on the random walk starts in the middle of a grid, such as an 11 by 11 array. At each step the drunk has four choices: up, down, left or right. Earlier in the chapter we described how to create a two-dimensional array of numbers. Using this data type, write a simulation of the two-dimensional random walk.

好吧,我知道的; 我知道如何在python中创建二维数组:

times = [0] * 11
for i in range(0,11):
    times[i] = [0] * 11

我想到了“randint”函数:

我最近也写了这个问题的一维变化。但这是一个意大利面代码,它是非常脏,而且我也不确定它是否正确。

我的代码在这里:

'''
Created on Feb 11, 2012

@author: msarialp
'''
from random import randint

def drunken_man():
    steps = 0
    times = [0] * 11
    left_move = 0
    right_move = 0
    i = 0
    while left_move < 5 or right_move < 5:
        value = randint(0,1)
        times[5] = 1
        if value == 1:
            steps += 1
            print("He moved left")
            left_move += 1
            if right_move > 0:
                right_move -= 1
            if left_move == 1:
                times[4] += 1
            elif left_move == 2:
                times[3] += 1
            elif left_move == 3:
                times[2] += 1
            elif left_move == 4:
                times[1] += 1
            #elif left_move == 5:
                #times[0] += 1
        elif value == 0:
            steps += 1
            print("He moved right")
            right_move += 1
            if left_move > 0:
                left_move -= 1
            if right_move == 1:
                times[6] += 1
            elif right_move == 2:
                times[7] += 1
            elif right_move == 3:
                times[8] += 1
            elif right_move == 4:
                times[9] += 1
            #elif right_move == 5:
                #times[10] += 1
        times[i] += 1                
    for i in range(1,10):
        print("He took {steps} steps until he reaches end of the sidewalk.".format(steps = steps),  "He stood on {1} square at {0} times".format(times[i], i) )

def main():
    drunken_man()

    return 0
if __name__ == '__main__':
    main()

编辑一个

在听取了丹·格哈德森的一些好建议之后。 我决定修改我的问题。 所以我在这个问题上的立场是: 我知道我怎样才能一分为二地跟踪和检查醉汉的脚步。

用tuple来解决这个问题是很容易理解和清楚的。

所以,我的代码段在这里之后,请检查并给我任何反馈。

def two_dimensional_random_walk():
    steps = 0
    times = [0] * 11
    for i in range(0,11):
        times[i] = [0] * 11
    x = 5
    y = 5
    moves = [(1,0), (0,1), (-1,0), (0,-1)]  
    while x<11 and x >= 0 or y < 11 and y >= 0:  
        dx, dy = moves[randint(0,3)]
        x += dx
        y += dy
        if dx == 1 and dy == 0:
            print("He moved right")
        elif dx == 0 and dy == 1:
            print("He moved up")
        elif dx == -1 and dy == 0:
            print("He moved left")
        elif dx == 0 and dy == -1:
            print("He moved down")
        try:
            times[x][y] += 1
            steps += 1
        except IndexError:
            break

我的打印功能是:

for i in range(0,11):
    for j in range(0,11):
        print("He took {steps} steps until he reaches end of the sidewalk.".format(steps = steps),  "He stood on {1}x{2} square at {0} times".format(times[i][j], i+1,j+1) )   

总之,我想在丹·格哈德森的帮助下,我解决了这个问题。

但是,为什么我不用这些暗示来改变我的一维解呢。

def drunken_man():
steps = 0
x = 6
times = [0] * 11
moves = [(1), (-1)]

while x < 11 and x >= 0:
    dx = moves[randint(0,1)]
    print(dx, x)
    x += dx
    try:
        times[x] += 1
        steps += 1
    except IndexError:
        break           
for i in range(1,11):
    print("He took {0} steps until he reaches end of the sidewalk.".format(steps),  "He stood on {1} square at {0} times".format(times[i], i) )

编辑两次(最后一次)

我不确定是否有必要编辑我的帖子来应用丹·格哈德森的提示。为了帮助像我这样失分的人,我决定把所有的事情都结合起来。

下面是我的函数,它结合了Dan Gerhardsson的提示:

def two_dimensional_random_walk():
steps = 0 # Steps counter for understand how many steps that our drunken man take
grid_size = 11 # Grid size variable,
# Creating Two dimensional array by using lists
times = [0] * grid_size 
for i in range(0,grid_size):
    times[i] = [0] * grid_size
# Initial variables to start in the middle of grid
x = 5
y = 5
# Tuples to get directions and decide where to go
moves = [(1,0, "right"), (0,1, "up"), (-1,0, "left"), (0,-1, "down")] 
# My loop for evaluate the steps
while True:  
    dx, dy, position = moves[randint(0,3)] # By using randint I could make decision randomly
    x += dx
    y += dy
    print("He moved", position)
    try:
        times[x][y] += 1 # And here is, how many times have he stood on each square
        steps += 1
    except IndexError: # The exit of loop
        break
# My print function which answers these questions (How long will it be until he reaeches the end of the sidewalk, and how many times will he have stood on each square)
for i in range(0,11):
    for j in range(0,11):
        print("He took {steps} steps until he reaches end of the sidewalk.".format(steps = steps),  "He stood on {1}x{2} square at {0} times".format(times[i][j], i+1,j+1) )

谢谢你的大力帮助。 我想我终于找到了解决办法。


Tags: andoftheinrightformoverange
2条回答

我做了一个类似的随机行走程序,允许醉汉在三维空间中用球坐标向任何方向行走。

import random
import math
def rw3(n,tries):
    s = 0
    for m in range(1,tries+1):
        x = 0
        y = 0
        z = 0
        pi = math.pi
        for step in range(1,n+1):
            t = random.uniform(0,2*pi)
            f = random.uniform(0,2*pi)
            p = 1
            x += p*math.sin(f)*math.cos(t)
            y += p*math.sin(f)*math.sin(t)
            z += p*math.cos(f)
        s += (x**2+y**2+z**2)**.5
    return s/tries
life = 42
while life:
    n = int(input("Please enter the number of steps: "))
    tries = int(input("How many times should I perform the experiment? "))
    print()
    print(rw3(n,tries))
    print()

我至少可以给你一些提示。所以你有四个可能的动作。每个移动都可以用一个元组表示,元组是x和y方向上的位移:

moves = [(0, 1), (1, 0), (0, -1), (-1, 0)]

要在中心设置起始位置:

grid_size = 11
x = grid_size // 2
y = grid_size // 2

存储醉汉的位置,并在模拟的每个步骤中更新。像这样的:

# Displacement:
dx, dy = random.choice(moves)

# Update position:
x += dx
y += dy

这可能不是初级代码,但您可以尝试更新计数并处理异常,而不是使用if语句检查边界,如果位置在网格之外,则会引发异常:

try:
    # Update counter.
    times[x][y] += 1
except IndexError:
    # Exit the simulation loop.
    break

希望这有帮助。

编辑-对第二个版本的评论:

由于要打印每个步骤中的方向,可以将其添加到元组:

moves = [(0, 1, 'up'), (1, 0, 'right'), (0, -1, 'down'), (-1, 0, 'left')]

然后可以替换if语句,在其中打印方向:

dx, dy, direction = random.choice(moves)
print('He moved', direction)

在当前解决方案中使用try except时,不需要检查while语句中的边界。你可以这样做:

while True:
    ...

因为异常处理程序中的中断将退出循环。

我的最后一条建议是用变量替换一些数字文本。网格大小(例如)出现在多个地方。您应该创建一个变量并在代码的其余部分中引用它:

grid_size = 11
times = [0] * grid_size
    for i in range(grid_size):
        times[i] = [0] * grid_size

使用变量而不是数字文本意味着,如果要使用不同的网格大小运行代码,只需在一个位置进行更改。

相关问题 更多 >