【问题标题】:Generating binary lists that sum to a given number生成总和为给定数字的二进制列表
【发布时间】:2015-11-25 15:32:12
【问题描述】:

我正在尝试 Project Euler #15,它本质上减少了计算长度为 2*size 的二进制列表的数量,使得它们的条目总和为 size,对于特殊情况 size = 20。例如,如果 size = 2 有 6 个这样的列表:[1,1,0,0], [1,0,1,0], [1,0,0,1], [0,1,1,0],[0,1,1,0],[0,1,0,1],[0,0,1,1]。当然,对于任何值 size 计算此类序列的数量是微不足道的,并且等于一些二项式系数,但我有兴趣在 Python 中显式生成正确的序列。我尝试了以下方法:

import itertools

size = 20

binary_lists = itertools.product(range(2), repeat = 2*size)

lattice_paths = {lists for lists in binary_lists if sum(lists) == size}

但最后一行让我遇到了内存错误。什么是完成此任务的巧妙方法?

【问题讨论】:

  • 这和问“我可以在 2*size 个槽中放置 size 1 的方法有多少种?”基本上不一样吗?
  • @NightShadeQueen:如果您想查看所有列出的方式,请不要这样做。

标签: python


【解决方案1】:

对于 size=20 的情况,要迭代的次数太多了(即使我们不实现它们,137846528820 也不是我们可以在合理时间内循环遍历的数字),所以它并不是特别有用。

但您仍然可以通过考虑 1 的 位置 来使用内置工具:

from itertools import combinations

def bsum(size):
    for locs in combinations(range(2*size), size):
        vec = [0]*(2*size)
        for loc in locs:
            vec[loc] = 1
        yield vec

给了

>>> list(bsum(1))
[[1, 0], [0, 1]]
>>> list(bsum(2))
[[1, 1, 0, 0], [1, 0, 1, 0], [1, 0, 0, 1], [0, 1, 1, 0], [0, 1, 0, 1], [0, 0, 1, 1]]
>>> sum(1 for x in bsum(12))
2704156
>>> factorial(24)//factorial(12)**2
2704156

【讨论】:

  • 虽然对于 size = 20 这似乎需要很长时间来计算...比他们在 Project Euler 中的“1 分钟规则”要多得多.但是,我真的想不出一个更简洁的解决方案。
  • 我不明白。在这个答案的第一句话中,我提醒你有太多的迭代。这不是您打算解决 Euler #15 的方式。为此,您应该 (1) 使用组合公式,或 (2) 使用动态规划。许多欧拉问题都有一个蛮力解决方案,它需要很长时间,甚至可能在示例中有效,但在真正的问题上会失败。
【解决方案2】:

我不是 100% 确定这个问题的数学,但你的最后一行是使用一个生成器并将其转储到一个列表中,并且根据你的示例和 20 的大小,这是一个庞大的列表。如果你想总结它,只需迭代,但我认为你不能很好地了解每个组合

【讨论】:

    猜你喜欢
    • 2018-04-25
    • 2019-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-07
    • 2021-10-20
    • 2013-08-19
    相关资源
    最近更新 更多