我有使用numpy的python代码:
import numpy as np
table = np.array([[23, 54, 12],
[17, 32, 25],
[43, 19, 11],
[31, 22, 10],
[21, 19, 35]])
r, c = table.shape
out = np.zeros((r,c))
out[0, :] = np.cumsum(table[0,:])
out[:, 0] = np.cumsum(table[:,0])
for j in range(1, c):
for i in range(1, r):
out[i,j] = max( out[i-1,j], out[i,j-1] ) + table[i,j]
out[-1,-1]
我首先计算数组“ out”的第一行和第一列,而其余的值则通过for循环内的方程式进行计算。我只对表的最后一个值(out [-1,-1])感兴趣,我想使其尽可能快。我能以某种方式删除两个“ for”循环吗?
答案 0 :(得分:0)
我不确定您要完成什么。
您要创建一个新的out
数组,该数组复制原始表的第一(第0)行和列。 (顺便说一下,您在out[:, 0] = np.cumsum(table[:,0])
处的元素被覆盖了。)
然后,通过获取前一行中的元素或前一列中的元素的最大值来填充[0, 0]
数组的其余部分。
然后在该位置将原始数组out
的内容添加到最大。
由于要在table
数组中查找以前的行和列,因此经常会发现自己被覆盖了这些值,然后再检查它们。
例如,当您在out
时,就得到了数组
i=2, j=1
您在[[ 23. 77. 89.]
[ 40. 109. 0.]
[ 83. *?* 0.]
[114. 0. 0.]
[135. 0. 0.]]
处,检查109和83。您刚刚在上一个迭代中插入了109。
因此,如果不使用for循环,就无法获得相同的结果。
答案 1 :(得分:0)
这实际上是找到从每个坐标到0,0的最长路径,其中,表中给出了路径上每个节点的成本。处理此类问题的标准“矩阵方式”是Floy-Warshall算法,它进行n次矩阵乘法,其中n是节点数,在您的情况下为r * c。您的算法实际上已经是Floyd-Warshall的优化变体,它利用了这样一个事实:从(i,j)到(0,0)的每条路径都必须经过(i-1,j)或(i,j-1) 。
这已经是一个巨大的优化!
我认为没有一种方法可以在不重复所有坐标的情况下进行处理。
但是也许您可以使用一些图形库将其编码为图形问题,这会将迭代部分推入(有效的)图形库中。
更好:
您可以迭代对角线,例如使用fill_diagonal。这样,ou只会迭代对角线的数量。