我从Cormen改编了优化二进制搜索树算法的伪代码以运行一些示例数据,但在某个地方存在一个逻辑错误阻止了根列表中的正确输出。
我已经多次检查过针对Cormen的代码,问题出现在我的列表索引(下标)中。
但是因为在这种情况下Cormen在图中使用了从零开始和基于一个数组,我完全不知道如何修改列表索引来纠正问题。看来作者打破了这个特定算法的典型文本的基于单一的惯例。
任何有OBST经验的人都能看到纠正以下Python所需的调整吗?
def obst(p,q):
"""Adapted from Cormen, pg. 402"""
n = len(q)
rn = range(n)
e = [[99999]*n for _ in rn]
w = [[0]*n for _ in rn]
root = [[0]*n for _ in rn]
for i in range(1, n):
e[i][i - 1] = w[i][i - 1] = q[i - 1]
for l in range(1,n):
for i in range(1, n-l):
j = i+l-1
w[i][j] = w[i][j-1] + p[j] + q[j]
for r in range(i,j+1):
t = e[i][r-1] + e[r+1][j] + w[i][j]
if t < e[i][j]:
e[i][j] = t
root[i][j] = r
return (e,root)
if __name__ == "__main__":
p = [0, 0.15, 0.1, 0.05, 0.1, 0.2]
q = [0.05, 0.1, 0.05, 0.05, 0.05, 0.1]
assert len(p) == len(q)
d = obst(p,q,len(p))
print(d[1])
编辑:我改变了一些指数。根据Cormen的说法,单独根表的预期输出(在返回的元组的第二个元素中)如下:
[
[0, 0, 0, 0, 0, 0],
[0, 1, 1, 2, 2, 2],
[0, 0, 2, 2, 2, 4],
[0, 0, 0, 3, 4, 5],
[0, 0, 0, 0, 4, 5],
[0, 0, 0, 0, 0, 5],
[0, 0, 0, 0, 0, 0]
]
当n为len(p)
时的输出:
[
[0, 0, 0, 0, 0, 0],
[0, 1, 2, 3, 4, 0],
[0, 0, 2, 3, 4, 0],
[0, 0, 0, 3, 4, 0],
[0, 0, 0, 0, 4, 0],
[0, 0, 0, 0, 0, 0]
]
答案 0 :(得分:0)
鉴于你可以将1..n + 1映射回0..n,那么它可以使事情变得更加简单:
def obst(p, q):
pn = len(p)
qn = len(q)
e = [[0]*qn for _ in range(qn)]
w = [[0]*qn for _ in range(qn)]
root = [[0]*pn for _ in range(pn)]
for i in range(qn):
e[i][i] = q[i]
w[i][i] = q[i]
for l in range(1, qn):
for i in range(0, qn-l):
j = i + l
e[i][j] = float('inf')
w[i][j] = w[i][j-1] + p[j-1] + q[j]
for r in range(i, j):
t = e[i][r] + e[r+1][j] + w[i][j]
if t < e[i][j]:
e[i][j] = t
root[i][j-1] = r+1
return (e, root)
这仅适用于矩阵的三角形 输出:
>>> p = [0.15, 0.1, 0.05, 0.1, 0.2]
>>> q = [0.05, 0.1, 0.05, 0.05, 0.05, 0.1]
>>> d = obst(p, q)
>>> d[1]
[[1, 1, 2, 2, 2],
[0, 2, 2, 2, 4],
[0, 0, 3, 4, 5],
[0, 0, 0, 4, 5],
[0, 0, 0, 0, 5]]
>>> d[0]
[[0.05, 0.45000000000000007, 0.9, 1.25, 1.75, 2.75],
[0, 0.1, 0.4, 0.7, 1.2, 2.0],
[0, 0, 0.05, 0.25, 0.6, 1.2999999999999998],
[0, 0, 0, 0.05, 0.30000000000000004, 0.9],
[0, 0, 0, 0, 0.05, 0.5],
[0, 0, 0, 0, 0, 0.1]]
注意:我删除了p中的填充0.0
注意:我将r添加1以输出与示例相同的完全相同
注意:我检查了e
和w
的值,这些也是正确的