【发布时间】:2023-03-28 05:48:01
【问题描述】:
我认为这是一个常见的组合问题,但我似乎找不到它的名称或任何关于它的资料。我在 Python 和 numpy 中做这个,但是如果有一个快速的矩阵方法,我可能可以翻译。
基本上,给定 n 个项目,我需要生成将它们放入 m 个箱的所有方法。例如,将 4 个项目分箱到 3 个箱中会得到类似 [(4, 0, 0), (3, 1, 0), (3, 0, 1), (2, 2, 0), (2, 1, 1), ...] 的结果。这是一个有固定总数的产品。
使用 itertools 实现这一点很简单。
import itertools
def fixed_total_product(bins, num_items):
""" Return iterator of all item binning possibilities. """
return itertools.ifilter(lambda combo: sum(combo) == num_items,
itertools.product(xrange(num_items + 1), repeat=bins))
不幸的是,我认为在循环中进行后续计算会效率低下。稍后将其用作 2D numpy 数组会更快,但我无法找到一种有效的方法来构建数组。我可以遍历 ifilter 结果,构建一个可能性列表,然后使用它来构建数组,但这似乎是一种巨大的浪费。
我猜最好的方法是“以 numpy 的方式”构建所有东西,但我不确定如何做到这一点。 stackoverflow 上有一个快速的产品实现:Using numpy to build an array of all combinations of two arrays。我猜你只能修改它以输出具有正确总和的产品。数组的大小应该是 ((m-1) + n) 选择 n,因为有 m-1 个 bin 边界。
有什么想法吗?基准非常受欢迎,但不是必需的。
【问题讨论】:
-
我提到了the integer partition problem,它给出了相似序列的长度。不过,我认为这并不遥远,因为一旦有了整数分区序列,就很容易删除顺序(添加所有排列)并强制执行多个 bin(
nbins 中的m意味着最大的数字在任何 bin 最多可以是m-n)。 -
抱歉。我以为我以前见过解决/关闭。不过,我不得不不同意解决方案。我添加了一个文档字符串和更具描述性的变量来帮助理解算法......
标签: python algorithm numpy combinatorics cartesian-product