动态编程给出了缓存实现的不同结果

时间:2014-10-02 07:00:03

标签: python recursion dynamic-programming

我正在做一个动态编程算法,并且在整晚无望地调试我的程序之后我完全没有答案。当我使用缓存存储中间结果时,我的程序基本上会返回错误的答案。这是我的计划:

def cachecost(cache, i, j, seq1, seq2):
    if cache[i][j] is None:
        v1 = v2 = v3 = v4 = None

        if i > 0 and j > 0:
            v1 = cachecost(cache, i-1, j-1, seq1, seq2) + 5
        if i > 0 and j >= 0:
            v2 = cachecost(cache, i-1, j, seq1, seq2) + 1
        if i >= 0 and j > 0:
            v3 = cachecost(cache, i, j-1, seq1, seq2) + 1
        if i == 0 and j == 0:
            v4 = 0

        cache[i][j] = max(v1, v2, v3, v4)
    return cache[i][j]


def cost(cache, i, j, seq1, seq2):
    v1 = v2 = v3 = v4 = None

    if i > 0 and j > 0:
        v1 = cost(cache, i-1, j-1, seq1, seq2) + 5
    if i > 0 and j >= 0:
        v2 = cost(cache, i-1, j, seq1, seq2) + 1
    if i >= 0 and j > 0:
        v3 = cost(cache, i, j-1, seq1, seq2) + 1
    if i == 0 and j == 0:
        v4 = 0

    cache[i][j] = max(v1, v2, v3, v4)
    return max(v1, v2, v3, v4)


def main():
    seq1 = 'AATAAT'
    seq2 = 'AAGG'
    cache = [[None] * (len(seq2) + 1)] * (len(seq1) + 1)
    cachescore = cachecost(cache, len(seq1), len(seq2), seq1, seq2)
    score = cost(cache, len(seq1), len(seq2), seq1, seq2)
    print 'Score without cache: %s, score with cache: %s' % (cachescore, score)


# Handle command line execution
if __name__ == '__main__':
    main()

该算法基本上通过递归计算i * j表,其中缓存实现确保表中的每个条目仅计算一次。

运行程序会产生以下输出:

Score without cache: 36, score with cache: 22

我在这里做错了什么?

1 个答案:

答案 0 :(得分:4)

实际问题在于此行

cache = [[None] * (len(seq2) + 1)] * (len(seq1) + 1)

首先创建一个大小为None的{​​{1}}列表,然后创建另一个大小为len(seq2) + 1的列表,其中所有元素都是对同一len(seq1) + 1个的引用名单。因此,如果您要更改其中任何一个,那么所有其他更改也将被重新选择。例如,

None

所以,你需要像这样创建它

lists = [[None] * 2] * 3
print lists
# [[None, None], [None, None], [None, None]]
lists[0][1] = 1
print lists
# [[None, 1], [None, 1], [None, 1]]

现在,在每次迭代中,将创建一个新的cache = [[None] * (len(seq2) + 1) for _ in range(len(seq1) + 1)] 列表,并将所有这些列表放在一个新列表中。

None