我正在尝试对以下问题实施memoization。 数据结构如下:
ROWS = {368: [247, 257], 257: [368], 2468: [357], 357: [2468], 358: [247], 247: [358, 368]}
这是一个字典,其中键的值为列表。在每个键的每个列表中,元素包含与键不同的数字。示例:如果我们采用密钥368:[247,257],我们观察到247不包含其密钥368中的任何数字。同样是257和368,不同的数字。
问题如下:通过使用此数据结构构造具有相互顶部数字的特定高度的墙,使得没有邻居具有相同的数字。 例如,4级的墙将是:
1. 368, 247, 358, 247
2. 368, 257, 368, 257 ... and so on.
问题是:有多少种可能的高度n组合(在我们的例子中是4)?
当从单个元素开始时,我做了基本的递归和非常无效且不优雅的解决方案:
ROWS = {368: [247, 257], 257: [368], 2468: [357], 357: [2468], 358: [247],
247: [358, 368]}
SUM=0
def count_configurations( elem , rows ) :
global SUM
if rows == 1 :
SUM += len(ROWS[elem])
return len(ROWS[elem])
else:
for k in ROWS[elem] :
count_configurations( k, rows-1 )
它工作正常但是当我们在没有Memoization的情况下达到更高的高度时它会永远保持下去。此外,如果尝试返回count_configurations(k,rows-1),它将返回第一个元素,并退出给出错误的答案。 问题是,在处理这个问题时,我们没有像Fibonacci那样的数字返回,但我们将返回一些其他列表。示例: 对于4级将是这样的:
(368, 4) : [(247:3), (257:3)] (composed of 2 elements of level 3, then
(247:3) : [(358:2), (368:2)] and (257:3) :[(368,2)] (composed of elements of level 2)
依此类推,直到我们在第1级结束,我们可以用实际值替换:
(368,1)=2 , (247, 1) = 1 , etc ...
在这种情况下可以实现Memoization吗?我使用了错误的数据结构而不是复杂的东西吗?你能就如何简化事情给我一些建议吗?
非常感谢提前。
答案 0 :(得分:1)
Memoization似乎在这里工作正常:
>>> from functools import lru_cache
>>>
>>> @lru_cache(None)
... def count_configurations( elem , rows ) :
... if rows == 1 :
... return len(ROWS[elem])
... else:
... return sum(count_configurations( k, rows-1 ) for k in ROWS[elem])
示例:
>>> count_configurations(247, 30)
2178309
>>> count_configurations(368, 100)
927372692193078999176
>>> count_configurations(357, 100)
1
>>> count_configurations(257, 100)
573147844013817084101