在Python中的2d地图上有效地进行扩散

时间:2011-11-12 05:38:46

标签: python multidimensional-array

我对Python很陌生,所以我正在做一个项目。其中一部分包括在地图上的扩散。我正在实现它,并使当前的瓦片等于.2 *它的邻居n,w,s,e的总和。如果我在C中这样做,我只是做一个双循环,循环通过一个数组做arr [i * width + j] = arr的j + 1,j-1,i + i,i-1邻居)并有几个不同的阵列,我会做同样的事情(地图的不同质量,我将改变)。但是,我不确定这是否真的是Python中最快的方式。有些人我曾经问过像numPy这样的东西,但是宽度可能不会超过200(最多40-50k元素),我不确定开销是否值得。我真的不知道任何内置函数来做我想要的。有什么建议吗?

编辑:这将是非常密集的,即每个地点将有一个非平凡的计算

3 个答案:

答案 0 :(得分:3)

使用NumPy进行安排非常简单。函数np.roll返回数组的副本,在指定的方向上“滚动”。

例如,给定数组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.roll,边界就像环面一样被包裹。如果您不想要包装边界,可以使用零边缘填充数组,并在每次迭代之前将边缘重置为零。

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()

答案 1 :(得分:1)

使用卷积。

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')

这是针对蚂蚁的挑战吗?如果是这样,在蚂蚁环境中,在我的实现中,convolve2d的工作速度比循环快20倍。

答案 2 :(得分:0)

对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