Условие остановки, если случайное блуждание находится в диапазоне случайно инициализированных значений - PullRequest
0 голосов
/ 08 октября 2018

У меня есть случайное блуждание по двумерной сетке со случайно инициализированными позициями.Я ищу условие, при котором, если случайное блуждание находится в некотором диапазоне от начальных положений других случайных блужданий, оно остановится.

Хотя я обнаружил, что это легко реализовать в простом случае, явозникли проблемы с его реализацией в случае N случайных блужданий.Это связано с тем, что код должен проверять диапазон значений вокруг каждой начальной позиции, кроме той, которая находится вокруг текущей случайной прогулки.

PS Это мой первый пост в стекепереполнение.Пожалуйста, дайте мне знать, если я был слишком расплывчатым или не следовал инструкциям для того, чтобы задавать вопросы здесь.

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 голосов
/ 08 октября 2018

Это хорошо заданный вопрос, за исключением того факта, что вы могли бы лучше определить «в некотором диапазоне начальных положений других случайных блужданий».Я предполагаю, что вы имеете в виду некоторое расстояние в 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

...