我有值池,我想通过从某些池中进行选择来生成每种可能的无序组合。
例如,我想从池0,池0和池1中进行选择:
>>> pools = [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
>>> part = (0, 0, 1)
>>> list(product(*(pools[i] for i in part)))
[(1, 1, 2), (1, 1, 3), (1, 1, 4), (1, 2, 2), (1, 2, 3), (1, 2, 4), (1, 3, 2), (1, 3, 3), (1, 3, 4), (2, 1, 2), (2, 1, 3), (2, 1, 4), (2, 2, 2), (2, 2, 3), (2, 2, 4), (2, 3, 2), (2, 3, 3), (2, 3, 4), (3, 1, 2), (3, 1, 3), (3, 1, 4), (3, 2, 2), (3, 2, 3), (3, 2, 4), (3, 3, 2), (3, 3, 3), (3, 3, 4)]
这通过从池0,池0和池1中进行选择来生成每种可能的组合。
但是顺序对我来说并不重要,因此许多组合实际上都是重复的。例如,由于我使用了笛卡尔乘积,所以(1, 2, 4)和(2, 1, 4)都生成了。
我想出了一种简单的方法来缓解此问题。对于从单个池中挑选的成员,我选择时不进行排序combinations_with_replacement。我计算从每个池中抽奖的次数。代码如下:
cnt = Counter()
for ind in part: cnt[ind] += 1
blocks = [combinations_with_replacement(pools[i], cnt[i]) for i in cnt]
return [list(chain(*combo)) for combo in product(*blocks)]
如果我碰巧多次从同一个池中进行选择,这将减少对重复项的排序。但是,所有池都有很多重叠,并且combinations_with_replacement在合并的多个池上使用会产生一些无效的组合。有没有更有效的方法来生成无序组合?
编辑:有关输入的额外信息:零件和池的数量很小(〜5和〜20),为简单起见,每个元素都是一个整数。我已经解决了实际的问题,因此这只是出于学术目的。假设每个池中有成千上万个整数,但有些池很小,只有几十个。因此,某种结合或相交似乎是可行的方法。
喵喵时光机
慕尼黑5688855
相关分类