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