在Python中查找优化二进制搜索树时,列表索引的逻辑错误

时间:2015-04-07 16:35:02

标签: python algorithm python-3.x optimization binary-search-tree

我从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]
]

1 个答案:

答案 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以输出与示例相同的完全相同 注意:我检查了ew的值,这些也是正确的