我对Python很陌生,所以我正在用它做一个项目。它的一部分包括在地图上的扩散。我通过遍历使当前贴图等于。2 *它的邻居n w s e的和来实现它。如果我在C语言中做这个,我只需要做一个double for循环循环遍历数组arr[I *width + j] = arr (j+1, j-1, I + I, I -1)并且有几个不同的数组我要做同样的事情(我要改变的地图的不同质量)。然而,我不确定这是否是Python中最快的方法。我问过的一些人建议使用numPy之类的东西,但宽度可能不会超过200(所以最多40-50k个元素),我不确定这样的开销是否值得。我真的不知道有什么内置函数可以做我想做的事。任何建议吗?
编辑:这将是非常密集的,即每个位置都将有一个重要的计算
这在NumPy中很容易安排。函数np。Roll返回数组的副本"rolled"
例如,给定数组x
,
x=np.arange(9).reshape(3,3)
# array([[0, 1, 2],
# [3, 4, 5],
# [6, 7, 8]])
可以使用
将列向右滚动np.roll(x,shift=1,axis=1)
# array([[2, 0, 1],
# [5, 3, 4],
# [8, 6, 7]])
使用np。滚,边界像环面一样被包裹起来。如果你不想要换行边界,你可以用零边填充数组,并在每次迭代之前将边缘重置为零。
import numpy as np
def diffusion(arr):
while True:
arr+=0.2*np.roll(arr,shift=1,axis=1) # right
arr+=0.2*np.roll(arr,shift=-1,axis=1) # left
arr+=0.2*np.roll(arr,shift=1,axis=0) # down
arr+=0.2*np.roll(arr,shift=-1,axis=0) # up
yield arr
N=5
initial=np.random.random((N,N))
for state in diffusion(initial):
print(state)
raw_input()
使用卷积
from numpy import *
from scipy.signal import convolve2d
mapArr=array(map)
kernel=array([[0 , 0.2, 0],
[0.2, 0, 0.2],
[0 , 0.2, 0]])
diffused=convolve2d(mapArr,kernel,boundary='wrap')
这是为了蚂蚁的挑战吗?如果是这样,在ants上下文中,在我的实现中,convolve2d的工作速度比循环快20倍。
对unutbu代码的修改保持了数组的全局和不变,同时扩散了数组的值:
import numpy as np
def diffuse(arr, d):
contrib = (arr * d)
w = contrib / 8.0
r = arr - contrib
N = np.roll(w, shift=-1, axis=0)
S = np.roll(w, shift=1, axis=0)
E = np.roll(w, shift=1, axis=1)
W = np.roll(w, shift=-1, axis=1)
NW = np.roll(N, shift=-1, axis=1)
NE = np.roll(N, shift=1, axis=1)
SW = np.roll(S, shift=-1, axis=1)
SE = np.roll(S, shift=1, axis=1)
diffused = r + N + S + E + W + NW + NE + SW + SE
return diffused