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