我有一个浓度为biomass
的网格随着时间的推移而增加。当浓度变得足够大时,它需要沿着阻力最小的路径分开并推动,这是我在下面的shove_graph
中计算的。我目前使用scipy.sparse.csgraph中的dijkstra算法来计算路径。 scipy的dijkstra执行得非常好,让我可以计算出一次需要更新的所有单元格。
然而,之后我的代码非常慢,我猜是因为不断的分配和释放,但我真的不知道。我遵循的基本想法如下:
# calculates the distance from each index in update_ix to every other
# grid point. predecessors is an array of indices that can backtrack
# from any given index to the starting point, along the shortest
# path (in my case, path of least resistance)
distances, predecessors = dijkstra(shove_graph, indices=update_ix,
return_predecessors=True)
# NOTE: distances.shape = predecessors.shape = (len(update_ix), len(shove_graph))
# For example, if 4 indices need updating on my 10x10 grid,
# the size of shove_graph is 100 (reshaped to 1 dimension above), and
# len(update_ix) = 4, so distances.shape = (4, 100)
# For each of the cells that need updating, find the empty cell and
# the path that satisfies the smallest distance
for (ix, d, p) in itertools.izip(update_ix, distances, predecessors):
empty = np.arange(N)[biomass == 0] # indices of empty cells
d_empty = d[biomass == 0] # those distances
# get the index of the smallest distance, then the whole path
# note: backwards from scipy.sparse.csgraph.dijkstra
ind = min(zip(d_empty, empty), key=lambda pair: pair[0])[1]
path = [ind]
while ind != ix:
ind = p[ind]
path.append(ind)
# Three different pieces get shoved differently.
# Age is 'new' for the first cell (=0), otherwise is shoved
# like everything else
# Half the first eps and active components get pushed into
# the second compartment.
# Each of the rest of the compartments get moved 100% to the
# next cell along the path.
ind = ix
age_ix = age[ix]
active[ind] = 0.5 * active[ind]
eps[ind] = 0.5 * eps[ind]
buffer1['age'] = 0
buffer1['active'] = active[ind]
buffer1['eps'] = eps[ind]
while path != []:
ind = path.pop()
buffer2['age'] = age[ind]
buffer2['active'] = active[ind]
buffer2['eps'] = eps[ind]
age[ind] = buffer1['age']
active[ind] = buffer1['active']
eps[ind] = buffer1['eps']
buffer1 = deepcopy(buffer2)
对于我需要的网格尺寸,这个for循环运行非常慢,所以我想优化它。不幸的是,由于前辈的工作方式,我真的不知道自己能做些什么。
如果您对某些事情有任何建议,我会非常感激!