查找将两个集合划分为大小为m的n个箱的所有方法,其中必须包括第一个集合(但不是第二个集合)中的所有项目

时间:2019-01-07 02:27:24

标签: python combinations itertools

我遇到的这个问题的特殊情况-查找长度 s 的所有球员组合,这些球员的组合可以适合 n 个法院(其中包含 m < / em>每个玩家)。

但是,还有一个额外的限制:至少必须将一些球员 包括在内。让我们将它们设为“ Set_A”。场上剩余的位置由“ Set_B”中的玩家填补。

具有所需输出的玩具示例:

Set_A = {0, 1, 2}
Set_B = {3, 4}

def func(set_a, set_b, courts, court_size):
  #insert code here
  return answer

>>>func(Set_A, Set_B, 2, 2)
(((0,1),(2,3)),((0,1),(2,4)),((0,2),(1,3)),((0,2),(1,4)),((0,3),(1,2)),((0,4),(1,2)))

在一个真实的例子中,可能有3个法院,每个法院适合4名球员。 “ Set_A”中有10个玩家,在“ Set_B”中有12个玩家。我想找到所有组合,其中包括“ Set_A”中的所有10个玩家和“ Set_B”中的2个玩家。

以下代码(我发现here)足以在球场上的空间等于“ Set_A”中的玩家人数时找到所有组合,例如通过调用list(partitions(range(12), 4))

def partitions(s, r):
"""
Generate partitions of the iterable `s` into subsets of size `r`.

>>> list(partitions(set(range(4)), 2))
[((0, 1), (2, 3)), ((0, 2), (1, 3)), ((0, 3), (1, 2))]
"""
s = set(s)
assert(len(s) % r == 0)
if len(s) == 0:
    yield ()
    return
first = next(iter(s))
rest = s.difference((first,))
for c in combinations(rest, r - 1):
    first_subset = (first,) + c
    for p in partitions(rest.difference(c), r):
        yield (first_subset,) + p

但是,这对我来说还不够。

另一个问题是速度和内存。每次运行'partitions(16,4)'大约需要14秒,而'partitions(20,4)'返回MemoryError。很有可能组合爆炸意味着对于我要使用的某些值来说,这简直是难以处理的。 (但是,我认为大多数情况下都是合理的,特别是如果将这些计算结果缓存起来以便以后查找的话。)

1 个答案:

答案 0 :(得分:0)

您正在错误地看待您的问题,并尝试过早优化来启动。

您并不是要查看12个插槽中20个玩家的所有组合。组合不关心顺序,因此您有两组。 Set_A仅占据插槽,因此您只想查看其余2个插槽中12个B组球员的组合。

如果您想了解那些球员在三个球场上的不同表现方式,请在弄清楚谁在打球之后再进行。它仍然不是组合,因为组合不会排序。由于这两个集合的复杂性,我也不确定排列是否适用。

弄清楚您关心的每个法庭中的细节水平-如果只是每个法庭中有四个球员,那么三个法庭案件中的20个球员给您45种组合(set_A + set_B中的2套)到进入第一场,然后有22,275套没有进入第一场的球员,看看谁进入第二场,谁进入第三场。这基本上为您提供了150万种不同法院法官的可能性。但是,如果您关心的是谁在与谁相争,或者谁在球场上的每个席位,那么...我所能做的就是祝您好运和晚安。