优化dijkstra路径上的循环

时间:2015-06-15 15:29:55

标签: python optimization

我有一个浓度为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循环运行非常慢,所以我想优化它。不幸的是,由于前辈的工作方式,我真的不知道自己能做些什么。

如果您对某些事情有任何建议,我会非常感激!

0 个答案:

没有答案