项目Euler#18 - 如何使用Python强制执行树状结构中的所有可能路径?

时间:2012-10-28 22:35:06

标签: python

我正在尝试学习Python大西洋way并且我坚持使用Project Euler#18。

我在canfind web的所有内容(并且除了那之外还有更多的谷歌搜索)是​​“你可以蛮力地嘲笑它”的一些变化,但是这是一个更优雅的解决方案'...

我明白了,我完全做到了。那里有非常简洁的解决方案,我期待着'acyclic graph'这句话让我想起的东西不仅仅是一个朦胧的,100万像素的分辨率。但是在我跑到这里之前我需要走路,see the state,并用蛮力的回答玩弄它。

那么,问题:如何生成(枚举?)Project Euler #18中三角形的所有有效路径并将它们存储在适当的python数据结构中? (列表清单是我最初的倾向?)。我不想要答案 - 我想知道如何强制所有路径并将它们存储到数据结构中。

这就是我所拥有的。我肯定是在错误地循环数据集。期望的行为是“深度优先(?)”而不是仅仅无效地循环每一行..我读了ch。 Norvig的书3但无法翻译伪代码。尝试阅读AIMA python library for ch。但是它实现了太多的飞跃。

triangle = [
    [75],
    [95, 64],
    [17, 47, 82],
    [18, 35, 87, 10],
    [20,  4, 82, 47, 65],
    [19,  1, 23, 75,  3, 34],
    [88,  2, 77, 73,  7, 63, 67],
    [99, 65,  4, 28,  6, 16, 70, 92],
    [41, 41, 26, 56, 83, 40, 80, 70, 33],
    [41, 48, 72, 33, 47, 32, 37, 16, 94, 29],
    [53, 71, 44, 65, 25, 43, 91, 52, 97, 51, 14],
    [70, 11, 33, 28, 77, 73, 17, 78, 39, 68, 17, 57],
    [91, 71, 52, 38, 17, 14, 91, 43, 58, 50, 27, 29, 48],
    [63, 66,  4, 68, 89, 53, 67, 30, 73, 16, 69, 87, 40, 31],
    [04, 62, 98, 27, 23,  9, 70, 98, 73, 93, 38, 53, 60,  4, 23],
]


def expand_node(r, c):
    return [[r+1,c+0],[r+1,c+1]]

all_paths = []
my_path = []

for i in xrange(0, len(triangle)):
    for j in xrange(0, len(triangle[i])):
        print 'row ', i, ' and col ', j, ' value is ', triangle[i][j]
        ??my_path = somehow chain these together???
        if my_path not in all_paths
            all_paths.append(my_path)

首选避免使用外部库(如itertools)的答案。

1 个答案:

答案 0 :(得分:5)

这里使用递归更容易:

def all_paths(r, c):
    current = triangle[r][c]
    if r < len(triangle) - 1:
        below_paths = all_paths(r+1, c) + all_paths(r+1, c+1)
        return [[current] + path for path in below_paths]
    else:
        return [[current]]

这里的想法是all_paths(r, c)返回从行r开始的所有路径,列c,这通常是通过从它下面的两个节点递归获取所有路径获得的,并且前置所有这些元素的当前元素。

如果我们在最后一行,我们只返回由单个元素组成的路径。

要从顶部开始获取所有路径,请致电all_paths(0, 0)

然后可以很容易地修改此函数以返回每个路径的总和而不是路径本身,并且通过进一步修改,它只能返回最大的总和而不是所有路径。 &#34;正确的方式&#34;解决这个问题基本上只是一个记忆版本。