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

mus*_*alp 7 python

我正在尝试从书中解决二维随机游走问题,探索python.但是,我无法弄清楚如何才能解决这个问题.我做了一些研究,但那些太复杂,无法理解它是什么.我是初学者.所以,通过查看我无法理解代码.请详细解释这个问题.

无论如何,问题是:

随机游走的二维变化开始于网格的中间,例如11乘11阵列.醉酒的每一步都有四种选择:上,下,左或右.在本章的前面,我们描述了如何创建二维数字数组.使用此数据类型,编写二维随机游走的模拟.

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

times = [0] * 11
for i in range(0,11):
    times[i] = [0] * 11
Run Code Online (Sandbox Code Playgroud)

我得到了"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()
Run Code Online (Sandbox Code Playgroud)

编辑一

在收到Dan Gerhardsson的一些好建议之后.我决定编辑我的问题.所以我在这个问题上的位置:我明白我怎样才能跟随并检查我醉酒的男人在两分之二的步骤.

用元组来解决这个练习是非常容易理解的.

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

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
Run Code Online (Sandbox Code Playgroud)

我的打印功能是:

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) )   
Run Code Online (Sandbox Code Playgroud)

总而言之,我想在Dan Gerhardsson的帮助下,我解决了这个练习.

但是,为什么我不会用这些提示改变我的一维解决方案.

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) )
Run Code Online (Sandbox Code Playgroud)

编辑二(最后的接触)

我不确定是否有必要编辑我的帖子以应用Dan Gerhardsson的提示.为了帮助那些像我一样错过积分的人,我决定把所有东西组合在一起.

所以这里是我的功能,结合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) )
Run Code Online (Sandbox Code Playgroud)

感谢Dan Gerhardsson的大帮助.我想我终于得到了解决方案.

Dan*_*son 9

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

moves = [(0, 1), (1, 0), (0, -1), (-1, 0)]
Run Code Online (Sandbox Code Playgroud)

要在中心设置起始位置:

grid_size = 11
x = grid_size // 2
y = grid_size // 2
Run Code Online (Sandbox Code Playgroud)

存储醉酒男子的位置并在模拟的每个步骤中更新它.像这样的东西:

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

# Update position:
x += dx
y += dy
Run Code Online (Sandbox Code Playgroud)

这可能不是新手级别的代码,但不是用if语句检查的界限,你可以尝试更新的次数,处理异常,这是如果位置是在网格之外提出:

try:
    # Update counter.
    times[x][y] += 1
except IndexError:
    # Exit the simulation loop.
    break
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.

编辑 - 第二版评论:

由于您希望在每个步骤中打印方向,因此可以将其添加到元组:

moves = [(0, 1, 'up'), (1, 0, 'right'), (0, -1, 'down'), (-1, 0, 'left')]
Run Code Online (Sandbox Code Playgroud)

然后,您可以替换打印方向的if语句:

dx, dy, direction = random.choice(moves)
print('He moved', direction)
Run Code Online (Sandbox Code Playgroud)

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

while True:
    ...
Run Code Online (Sandbox Code Playgroud)

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

我的最后一条建议是用变量替换一些数字文字.网格大小例如出现在多个位置.您应该创建一个变量并在其余代码中引用它:

grid_size = 11
times = [0] * grid_size
    for i in range(grid_size):
        times[i] = [0] * grid_size
Run Code Online (Sandbox Code Playgroud)

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