【发布时间】:2023-03-11 12:16:01
【问题描述】:
我想生成将列表中的索引与“插槽”相关联的组合。例如,(0, 0, 1) 表示 0 和 1 属于同一个 slot,而 2 属于另一个 slot。 (0, 1, 1, 1) 表示 1、2、3 属于同一个 slot,而 0 是自己的。在本例中,0 和 1 只是识别这些插槽的方式,但不携带信息供我使用。
因此,就我的目的而言,(0, 0, 0) 与 (1, 1, 1) 完全相同,(0, 0, 1) 等同于 (1, 1, 0)。
经典的笛卡尔积会产生很多我想摆脱的重复。
这是我通过itertools.product 获得的:
>>> LEN, SIZE = (3,1)
>>> list(itertools.product(range(SIZE+1), repeat=LEN))
>>>
[(0, 0, 0),
(0, 0, 1),
(0, 1, 0),
(0, 1, 1),
(1, 0, 0),
(1, 0, 1),
(1, 1, 0),
(1, 1, 1)]
这就是我想要得到的:
>>> [(0, 0, 0),
(0, 0, 1),
(0, 1, 0),
(0, 1, 1)]
使用小列表很容易,但我不太明白如何使用更大的集合来做到这一点。你有什么建议吗?
如果不清楚,请告诉我,以便我澄清我的问题。谢谢!
编辑:根据 Sneftel 的回答,这个函数似乎可以工作,但我不知道它是否真的产生了所有结果:
def test():
for p in product(range(2), repeat=3):
j=-1
good = True
for k in p:
if k> j and (k-j) > 1:
good = False
elif k >j:
j = k
if good:
yield p
【问题讨论】:
-
这样做的目的是什么?你会处理所有的可能性,还是只选择其中的一些?总是有两个“桶”还是有时有更多?
-
我实际上是在计算项目(索引)之间的不兼容性,我想知道如何将它们分布在有限数量的桶中以最小化这个数量。为此,我将枚举所有不同的分布,然后计算不兼容的数量(使用首选项列表),但我不在乎 1、2 和 3 是在存储桶 A 中还是在存储桶 B 中。我只需要知道它们是否相同。在我的现实生活问题中,我有 5 个桶和 12 个项目,这就是为什么我真的需要限制笛卡尔积的枚举。
标签: python algorithm permutation combinatorics