【问题标题】:Return a sequence of a variable length whose summation is equal to a given integer返回一个可变长度的序列,其总和等于给定的整数
【发布时间】:2011-03-31 20:32:26
【问题描述】:

f(x,y,z) 的形式,其中x 是给定的整数和,y 是序列的最小长度,z 是序列的最大长度。但是现在让我们假设我们正在处理一个固定长度的序列,因为否则我会花很长时间来写这个问题。

所以我们的函数是f(x,r),其中x 是给定的整数和,r 是可能序列列表中序列的长度。

对于x = 10r = 2,这些是可能的组合:

1 + 9
2 + 8
3 + 7
4 + 6
5 + 5

让我们在 Python 中将其存储为对列表:

[(1,9), (2,8), (3,7), (4,6), (5,5)]

所以用法如下:

>>> f(10,2)
[(1,9), (2,8), (3,7), (4,6), (5,5)]

回到最初的问题,在(y,x) 范围内为每个长度返回一个序列。我采用前面定义的f(x,y,z) 形式,省略了长度为1(其中y-z == 0)的序列,如下所示:

>>> f(10,1,3)
[{1: [(1,9), (2,8), (3,7), (4,6), (5,5)],
  2: [(1,1,8), (1,2,7), (1,3,6) ... (2,4,4) ...],
  3: [(1,1,1,7) ...]}]

所以输出是字典列表,其中值是对列表。不完全是最优的。

所以我的问题是:

  1. 是否已经有一个库可以处理这个问题?
  2. 如果没有,有人可以帮我编写我提到的两个函数吗? (先固定序列长度)?
  3. 由于我对相当琐碎的数学知识存在巨大差距,您能否忽略我的整数存储方法并使用最有意义的任何结构?

对今天所有这些算术问题感到抱歉。谢谢!

【问题讨论】:

  • 输出是一个元组列表
  • 您真的需要生成完整的序列列表吗?这似乎有点笨拙(更不用说慢了)......也许更好的看待这个的方法是编写一个函数g(sum, nterms, index),它返回所有长度为nterms的序列的排序列表的indexth序列总和为sum。我认为这会更容易——而且我强烈怀疑它最终会是递归的。
  • 现在输出的是字典列表,这是我的初衷。
  • 你想要一个随机序列还是所有序列?标题或描述都需要更改。
  • 开枪,对不起。我可以自己做一些随机的事情。

标签: python math permutation combinations


【解决方案1】:

itertools 模块在我们处理前置突变时肯定会有所帮助 - 但是,这看起来有点像家庭作业......

编辑:不过看起来很有趣,所以我会尝试一下。

编辑 2:这是你想要的?

from itertools import combinations_with_replacement
from pprint import pprint

f = lambda target_sum, length: [sequence for sequence in combinations_with_replacement(range(1, target_sum+1), length) if sum(sequence) == target_sum]

def f2(target_sum, min_length, max_length):
    sequences = {}
    for length in range(min_length, max_length + 1):
        sequence = f(target_sum, length)
        if len(sequence):
            sequences[length] = sequence
    return sequences

if __name__ == "__main__":
    print("f(10,2):")
    print(f(10,2))
    print()
    print("f(10,1,3)")
    pprint(f2(10,1,3))

输出:

f(10,2):
[(1, 9), (2, 8), (3, 7), (4, 6), (5, 5)]

f(10,1,3)
{1: [(10,)],
 2: [(1, 9), (2, 8), (3, 7), (4, 6), (5, 5)],
 3: [(1, 1, 8),
     (1, 2, 7),
     (1, 3, 6),
     (1, 4, 5),
     (2, 2, 6),
     (2, 3, 5),
     (2, 4, 4),
     (3, 3, 4)]}

【讨论】:

  • f, f2, r, c... 我认为您应该为变量或函数使用有意义的词。
  • OP 只将它们命名为 f,我真的想不出更合乎逻辑的...
  • 本身不是我的作业,但它确实计算了我的作业。 (这绝不是作弊。)
  • @odonnel 这就是你需要的吗?
  • 好的,但是输出应该像问题中一样分成长度一致的序列。
【解决方案2】:

这个问题被称为Integer Partitions,并已被广泛研究。

Here 你可以找到一篇比较几种算法的性能的论文(并提出了一个特定的算法),但是网上有很多参考资料。

【讨论】:

    【解决方案3】:

    我刚刚写了一个递归生成器函数,你应该自己想办法从中得到一个列表......

    def f(x,y):
        if y == 1:
            yield (x, )
        elif y > 1:
            for head in range(1, x-y+2):
                for tail in f(x-head, y-1):
                    yield tuple([head] + list(tail))
    
    def f2(x,y,z):
        for u in range(y, z+1):
            for v in f(x, u):
                yield v
    

    编辑:我只是看到它不完全是您想要的,我的版本还会生成重复项,其中只有排序不同。但是您可以通过对所有结果排序并检查重复的元组来简单地过滤掉它们。

    【讨论】:

      猜你喜欢
      • 2015-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-05
      • 2020-06-30
      相关资源
      最近更新 更多