Python Numpy:如何模拟晶格中的传播
下面是我的低效Python代码:Python Numpy:如何模拟晶格中的传播,python,numpy,Python,Numpy,下面是我的低效Python代码: import numpy as np import random matrix = np.empty( (100,100), dtype=bool ) matrix[:,:] = False matrix[50,50] = True def propagate(matrix, i, j): for (di,dj) in [ (1,0), (0,1), (-1,0), (0,-1) ]: (ni,nj) = (i+di, j+d
import numpy as np
import random
matrix = np.empty( (100,100), dtype=bool )
matrix[:,:] = False
matrix[50,50] = True
def propagate(matrix, i, j):
for (di,dj) in [ (1,0), (0,1), (-1,0), (0,-1) ]:
(ni,nj) = (i+di, j+dj)
if matrix[ni,nj] and flip_coin_is_face():
matrix[i,j] = True
def flip_coin_is_face():
return random.uniform(0,1) < 0.5
for k in xrange(1000):
for i in xrange(1,99):
for j in xrange(1,99):
propagate(matrix, i, j)
将numpy导入为np
随机输入
矩阵=np.空((100100),数据类型=bool)
矩阵[:,:]=假
矩阵[50,50]=真
定义传播(矩阵,i,j):
对于[(1,0),(0,1),(-1,0),(0,-1)]中的(di,dj):
(ni,nj)=(i+di,j+dj)
如果矩阵[ni,nj]和抛硬币是面()
矩阵[i,j]=真
def flip_coin_is_face():
返回随机。均匀(0,1)<0.5
对于X范围内的k(1000):
对于x范围内的i(1,99):
对于X范围内的j(1,99):
传播(矩阵,i,j)
基本上是从矩阵的中心传播真实状态。因为我正在用Python编写循环和传播规则,这当然非常慢
我的问题是,我如何使用Numpy索引来尽可能快地实现这一点 我对numpy不是很在行,但要通过矩阵“传播”,可以使用广度优先搜索之类的方法。如果您以前没有使用过,它看起来是这样的:
import Queue
def neighbors(i, j, mat_shape):
rows = mat_shape[0]
cols = mat_shape[1]
offsets = [(-1, 0), (1, 0), (0, 1), (0, -1)]
neighbors = []
for off in offsets:
r = off[0]+i
c = off[1]+j
if 0 <= r and r <= rows and 0 <= c and c <= cols:
neighbors.append((r,c))
return neighbors
def propagate(matrix, i, j):
# 'parents' is used in two ways. first, it tells us where we've already been
# second, it tells us w
parents = np.empty(matrix.shape)
parents[:,:] = None
# first-in-first-out queue. initially it just has the start point
Q = Queue.Queue()
# do the first step manually; start propagation with neighbors
matrix[i,j] = True
for n in neighbors(i,j,matrix.shape):
Q.put(n)
parents[n[0],n[1]] = (i,j)
# initialization done. on to the propagation
while not Q.empty():
current = Q.get() # get's front element and removes it
parent = parents[current[0], current[1]]
matrix[current[0], current[1]] = matrix[parent[0], parent[1]] and flip_coin_is_face()
# propagate to neighbors, in order
for next in neighbors(current[0], current[1], matrix.shape):
# only propagate there if we haven't already
if parents[next[0], next[1]] is None:
parents[next[0], next[1]] = current
Q.put(next)
return matrix
导入队列
def邻居(i、j、mat_形状):
行=材料形状[0]
cols=材料形状[1]
偏移量=[(-1,0),(1,0),(0,1),(0,-1)]
邻居=[]
对于偏移中的关闭:
r=关[0]+i
c=关闭[1]+j
如果0,我可以想到一种方法,但它与原始代码不同。也就是说,您可以过滤每个步骤数组(k
loop)中的一个,将每个值传播到其对应的时间,即掷骰子4倍于一个数,并计算下一个步骤数组。每个操作都可以使用numpy one liner(使用矩阵的where
,重塑
,+
和*
)来完成),因此不会有内部循环
不同之处在于,我们不考虑在一个步骤中传播的值,一次评估所有更改。事实上,它会减慢传播速度,我想这是很明显的,就完成所有矩阵所需的步骤而言
如果这种方法可行,我可以想出一些代码。我运行了你的代码,结果得到一个矩阵,其中[0,0]为真,其余为假。这肯定不是你想要的吗?@JohnZwinck基于从矩阵中心传播真实状态
我想它应该是矩阵[50,50]=True
而不是矩阵[0,0]=True
@JohnZwinck at alko你们都是对的。我把代码编辑成50,50,但我认为它仍然是错误的,因为底部使用了范围。好吧,我不想再在这件事上扮演通灵师了。另外,你可以使用scipy.ndimage.morphology.binary\u diallation
。我正在寻找更多关于numpy索引的东西。。。我担心在这种情况下,队列不会像在numpy实现后面有一些C代码来完成这项工作那样有帮助……无论如何,感谢您的关注。嗨!谢谢你的回答。我想我可以从那里接受。。。。事实上,现在我认为“不考虑(在传播的步骤中)值”是解决我的问题的正确方法。。。。