我有这个使用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的最长路径,其中成本由路径上每个节点的表给出。处理此类问题的标准"矩阵方法"是Floy Warshall算法,该算法进行n次矩阵乘法运算,其中n是节点数,在您的情况下为r*c。你的算法实际上已经是Floyd-Warshall的优化变体,它使用了从(i,j(到(0,0(的每条路径都必须通过(i-1,j(或(i,j-1(的事实。
这已经是一个巨大的优化!
我认为如果不在所有坐标上进行迭代,就没有办法解决这个问题。
但也许你可以使用一些图库将其编码为一个图问题,这将把迭代部分推到(高效的(图库中。
更好:
您可以在对角线上迭代,例如使用fill_diagonal。这样,你只会在对角线的数量上迭代。
我不完全确定你想要实现什么。
您正在创建一个新的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循环,就无法获得相同的结果。