如果随机游走在随机初始化值的范围内,则停止条件

时间:2018-10-07 22:45:58

标签: python numpy random-walk

我在带有随机初始化位置的2D网格上随机行走。我正在寻找一种条件,如果随机游走在其他随机游走的初始位置的某个范围内,它将停止。

虽然我发现在简单情况下易于实现,但在N次随机游走的情况下却难以实现。这是由于这样的事实,代码需要检查每个初始位置周围的一系列值,除了当前随机游走周围的那个位置。

P.S这是我关于堆栈溢出的第一篇文章。请让我知道我是否太模糊或不遵循此处的提问准则。

import numpy.random as rd               #importing libraries
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import numpy.ma as ma

lsize=100
T=1000 #n of steps
N=5 #n of walks
xvec=np.zeros(N)
yvec=np.zeros(N)
xstore=np.zeros(T+1)
ystore=np.zeros(T+1)
xmat=np.zeros((T+1,N))
ymat=np.zeros((T+1,N))

for i in range(N):    #randomly assigns initial position
    xcor=rd.randint(1,lsize)
    ycor=rd.randint(1,lsize)
    xvec[i]=xcor
    yvec[i]=ycor

for i in range(N):
    xstore[0]=xvec[i]
    ystore[0]=yvec[i]
    for j in range(T):
            A=[0,1,2,3]
            temp=rd.choice(A)
            if temp==0:
                ystore[j+1]=ystore[j]+1 #up
                xstore[j+1]=xstore[j]
            elif temp==1:
                xstore[j+1]=xstore[j]+1 #right
                ystore[j+1]=ystore[j]
            elif temp==2:
                ystore[j+1]=ystore[j]-1 #down
                xstore[j+1]=xstore[j]
            elif temp==3:
                xstore[j+1]=xstore[j]-1 #left
                ystore[j+1]=ystore[j]
            xstore[j+1]=np.mod(xstore[j+1], lsize+1)
            ystore[j+1]=np.mod(ystore[j+1], lsize+1)
    xmat[:,i]=xstore
    ymat[:,i]=ystore
plt.plot(xmat,ymat)
plt.show()

1 个答案:

答案 0 :(得分:0)

除了可以更好地定义“在其他随机游走的初始位置的某个范围内”这一事实外,这是一个很好问的问题。我假设您是指x或y中的某个距离或x,y平面中的某个距离标准。以下仅概述了x中距离标准的解决方案,但对其他标准的扩展很简单。

基本上,您希望在内部for循环的末尾有一个检查条件:

distance_in_x = np.mod(np.abs(xvec - xstore[j+1]), lsize)
distance_in_x[i] = np.inf # effectively mask that position
if np.any(distance_in_x <= min_distance_in_x):
    break

这假定您已在上方某处定义了min_distance_in_x。 基本技巧是通过添加无穷大来掩盖步行本身的距离。同样,您也可以只添加min_distance_in_x以确保下一行中的支票从不接受该来源。

编辑

对于起点周围的正方形,脚本变为:

import numpy.random as rd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import numpy.ma as ma

lsize=100
T=1000 #n of steps
N=10 #n of walks
xvec=np.zeros(N)
yvec=np.zeros(N)
xmat=np.full((T+1,N), np.nan)
ymat=np.full((T+1,N), np.nan)

min_distance_in_x = 3
min_distance_in_y = 3

# randomly assigns initial position
for i in range(N):
    xcor=rd.randint(1,lsize)
    ycor=rd.randint(1,lsize)
    xvec[i]=xcor
    yvec[i]=ycor

# walk
for i in range(N):
    xstore=np.full(T+1, np.nan)
    ystore=np.full(T+1, np.nan)
    xstore[0]=xvec[i]
    ystore[0]=yvec[i]

    for j in range(T):
        A=[0,1,2,3]
        temp=rd.choice(A)
        if temp==0:
            ystore[j+1]=ystore[j]+1 #up
            xstore[j+1]=xstore[j]
        elif temp==1:
            xstore[j+1]=xstore[j]+1 #right
            ystore[j+1]=ystore[j]
        elif temp==2:
            ystore[j+1]=ystore[j]-1 #down
            xstore[j+1]=xstore[j]
        elif temp==3:
            xstore[j+1]=xstore[j]-1 #left
            ystore[j+1]=ystore[j]

        xstore[j+1]=np.mod(xstore[j+1], lsize+1)
        ystore[j+1]=np.mod(ystore[j+1], lsize+1)

        distance_in_x = np.abs(xvec - xstore[j+1])
        distance_in_x[i] = np.inf # effectively mask that position

        distance_in_y = np.abs(yvec - ystore[j+1])
        distance_in_y[i] = np.inf # effectively mask that position

        if np.any(np.logical_and(distance_in_x <= min_distance_in_x,
                                 distance_in_y <= min_distance_in_y)):
            print("Got too close on run #{}!".format(i))
            break

    xmat[:,i]=xstore
    ymat[:,i]=ystore

for x, y in zip(xmat.T, ymat.T):
    # break the line by inserting NaNs where the boundary is crossed (i.e. a step size > 1)
    linebreaks, = np.where((np.abs(np.diff(x)) > 1) | (np.abs(np.diff(y)) > 1))
    if linebreaks.size > 0 :
        x = np.insert(x, linebreaks+1, np.nan)
        y = np.insert(y, linebreaks+1, np.nan)

    # plot lines
    plt.plot(x, y)

# plot start points
plt.gca().set_prop_cycle(None) # resets color cycle
for x, y in zip(xmat[0,:], ymat[0,:]):
    plt.plot(x, y, 'o', ms=10)

# plot end points
plt.gca().set_prop_cycle(None) # resets color cycle
for x, y in zip(xmat.T, ymat.T):
    # select last non-nan entry
    x = x[~np.isnan(x)][-1]
    y = y[~np.isnan(y)][-1]
    plt.plot(x, y, '^', ms=10)

plt.show()

enter image description here