【问题标题】:All possible ways to place colored balls into bins将彩球放入垃圾箱的所有可能方式
【发布时间】:2017-05-18 10:24:46
【问题描述】:

我有很多垃圾箱。每个垃圾箱只能容纳一个球。

比方说,我有

Na 个红球

Nb 个蓝球

Nc 绿球个数

等等。

我想找出将球放入长度为 (Na+Nb+Nc) 的箱子的所有可能方法。

例如,假设我只有两个红球和两个蓝球。我想将它们放入 4 个垃圾箱中。可能的安排方式有:

R R B B
R B R B
R B B R
B R R B
B R B R
B B R R

(希望没有错过任何组合)

有没有简单的方法可以生成不同颜色的索引,例如:

First row is : R=(0,1) B=(2,3)
Second row is : R=(0,2) B=(1,3)

有没有一种简单的方法可以在 numpy 中生成它?

这些垃圾箱实际上具有不同的权重,例如:

[0.1, 0.3, 0.2, 0.5]

因此,对于表示为 R at (0,1) and B at (2,3) 的组合 R R B B ,R 的总权重是 0.1+0.3=0.4 而 B 的总权重是 0.2+0.5=0.7

我最终对不同排列中每种颜色的总重量感兴趣,并希望从另一个成本函数 f(total_weight(R), total_weight(B)) 中选择最好的一个。如果总重量的生成可以在 numpy 中以不同的简单方式完成,是否有任何 cmets?

【问题讨论】:

  • 那么,基本上你想要所有排列?!
  • 不完全是。有不止一个球具有相同的颜色。
  • 实际上这些是排列。您只需要删除重复项,这是微不足道的。
  • 是的。它们在某种程度上是排列。请注意,不同颜色的球的数量是不一样的。
  • 现在我明白你所说的删除重复项是什么意思了。有没有其他方法不需要删除重复项 - 依赖标准 itertools.permutations 最初会生成一个非常大的集合。

标签: python numpy combinatorics


【解决方案1】:

这是一个不需要消除重复排列的“多重组合”实现。第一个参数n 是列表 [Na, Nb, Nc, ...]。

它是作为递归生成器实现的,因此您可以遍历组合,而无需一次将它们全部放在内存中。您在评论中说 Na + Nb + ... 通常约为 20,但可能高达 50 或 100。这意味着您几乎肯定不想将所有组合存储在内存中。考虑一个有四种“颜色”的例子,其中 Na = Nb = Nc = Nd = 5。组合的数量是choose(20, 5) * choose(15, 5) * choose(10, 5) = 11732745024,其中choose(n, k)binomial coefficient。我的计算机只有 16 GB 的 RAM,因此该数量的组合所需的存储空间将远远超过我计算机的内存。

from itertools import combinations


def multicombinations(n, bins=None):
    if bins is None:
        bins = set(range(sum(n)))
    if len(n) == 0:
        yield []
    else:
        for c in combinations(bins, n[0]):
            for t in multicombinations(n[1:], bins - set(c)):
                yield [c] + t

它生成一个元组列表。也就是说,如果您对第一行的描述是“第一行是:R=(0,1) B=(2,3)”,则multicombinations([2, 2]) 生成的第一个值是[(0, 1), (2, 3)]。 (考虑到您接下来要进行的权重计算的描述,这可能不是结果的最佳格式。)

一些例子:

In [74]: list(multicombinations([2, 2]))
Out[74]: 
[[(0, 1), (2, 3)],
 [(0, 2), (1, 3)],
 [(0, 3), (1, 2)],
 [(1, 2), (0, 3)],
 [(1, 3), (0, 2)],
 [(2, 3), (0, 1)]]

In [75]: list(multicombinations([3, 2]))
Out[75]: 
[[(0, 1, 2), (3, 4)],
 [(0, 1, 3), (2, 4)],
 [(0, 1, 4), (2, 3)],
 [(0, 2, 3), (1, 4)],
 [(0, 2, 4), (1, 3)],
 [(0, 3, 4), (1, 2)],
 [(1, 2, 3), (0, 4)],
 [(1, 2, 4), (0, 3)],
 [(1, 3, 4), (0, 2)],
 [(2, 3, 4), (0, 1)]]

In [76]: list(multicombinations([2, 3, 2]))
Out[76]: 
[[(0, 1), (2, 3, 4), (5, 6)],
 [(0, 1), (2, 3, 5), (4, 6)],
 [(0, 1), (2, 3, 6), (4, 5)],
 [(0, 1), (2, 4, 5), (3, 6)],
 [(0, 1), (2, 4, 6), (3, 5)],
 [(0, 1), (2, 5, 6), (3, 4)],
 [(0, 1), (3, 4, 5), (2, 6)],
 [(0, 1), (3, 4, 6), (2, 5)],
 [(0, 1), (3, 5, 6), (2, 4)],
 [(0, 1), (4, 5, 6), (2, 3)],
 [(0, 2), (1, 3, 4), (5, 6)],
 [(0, 2), (1, 3, 5), (4, 6)],
 [(0, 2), (1, 3, 6), (4, 5)],
 [(0, 2), (1, 4, 5), (3, 6)],
 [(0, 2), (1, 4, 6), (3, 5)],
 [(0, 2), (1, 5, 6), (3, 4)],
 [(0, 2), (3, 4, 5), (1, 6)],
 [(0, 2), (3, 4, 6), (1, 5)],
 [(0, 2), (3, 5, 6), (1, 4)],
 [(0, 2), (4, 5, 6), (1, 3)],
 [(0, 3), (1, 2, 4), (5, 6)],
 [(0, 3), (1, 2, 5), (4, 6)],
 [(0, 3), (1, 2, 6), (4, 5)],
 [(0, 3), (1, 4, 5), (2, 6)],
 [(0, 3), (1, 4, 6), (2, 5)],
 [(0, 3), (1, 5, 6), (2, 4)],
 [(0, 3), (2, 4, 5), (1, 6)],
 [(0, 3), (2, 4, 6), (1, 5)],
 [(0, 3), (2, 5, 6), (1, 4)],
 [(0, 3), (4, 5, 6), (1, 2)],
 [(0, 4), (1, 2, 3), (5, 6)],
 [(0, 4), (1, 2, 5), (3, 6)],
 [(0, 4), (1, 2, 6), (3, 5)],
 [(0, 4), (1, 3, 5), (2, 6)],
 [(0, 4), (1, 3, 6), (2, 5)],
 [(0, 4), (1, 5, 6), (2, 3)],
 [(0, 4), (2, 3, 5), (1, 6)],
 [(0, 4), (2, 3, 6), (1, 5)],
 [(0, 4), (2, 5, 6), (1, 3)],
 [(0, 4), (3, 5, 6), (1, 2)],
 [(0, 5), (1, 2, 3), (4, 6)],
 [(0, 5), (1, 2, 4), (3, 6)],
 [(0, 5), (1, 2, 6), (3, 4)],
 [(0, 5), (1, 3, 4), (2, 6)],
 [(0, 5), (1, 3, 6), (2, 4)],
 [(0, 5), (1, 4, 6), (2, 3)],
 [(0, 5), (2, 3, 4), (1, 6)],
 [(0, 5), (2, 3, 6), (1, 4)],
 [(0, 5), (2, 4, 6), (1, 3)],
 [(0, 5), (3, 4, 6), (1, 2)],
 [(0, 6), (1, 2, 3), (4, 5)],
 [(0, 6), (1, 2, 4), (3, 5)],
 [(0, 6), (1, 2, 5), (3, 4)],
 [(0, 6), (1, 3, 4), (2, 5)],
 [(0, 6), (1, 3, 5), (2, 4)],
 [(0, 6), (1, 4, 5), (2, 3)],
 [(0, 6), (2, 3, 4), (1, 5)],
 [(0, 6), (2, 3, 5), (1, 4)],
 [(0, 6), (2, 4, 5), (1, 3)],
 [(0, 6), (3, 4, 5), (1, 2)],
 [(1, 2), (0, 3, 4), (5, 6)],
 [(1, 2), (0, 3, 5), (4, 6)],
 [(1, 2), (0, 3, 6), (4, 5)],
 [(1, 2), (0, 4, 5), (3, 6)],
 [(1, 2), (0, 4, 6), (3, 5)],
 [(1, 2), (0, 5, 6), (3, 4)],
 [(1, 2), (3, 4, 5), (0, 6)],
 [(1, 2), (3, 4, 6), (0, 5)],
 [(1, 2), (3, 5, 6), (0, 4)],
 [(1, 2), (4, 5, 6), (0, 3)],
 [(1, 3), (0, 2, 4), (5, 6)],
 [(1, 3), (0, 2, 5), (4, 6)],
 [(1, 3), (0, 2, 6), (4, 5)],
 [(1, 3), (0, 4, 5), (2, 6)],
 [(1, 3), (0, 4, 6), (2, 5)],
 [(1, 3), (0, 5, 6), (2, 4)],
 [(1, 3), (2, 4, 5), (0, 6)],
 [(1, 3), (2, 4, 6), (0, 5)],
 [(1, 3), (2, 5, 6), (0, 4)],
 [(1, 3), (4, 5, 6), (0, 2)],
 [(1, 4), (0, 2, 3), (5, 6)],
 [(1, 4), (0, 2, 5), (3, 6)],
 [(1, 4), (0, 2, 6), (3, 5)],
 [(1, 4), (0, 3, 5), (2, 6)],
 [(1, 4), (0, 3, 6), (2, 5)],
 [(1, 4), (0, 5, 6), (2, 3)],
 [(1, 4), (2, 3, 5), (0, 6)],
 [(1, 4), (2, 3, 6), (0, 5)],
 [(1, 4), (2, 5, 6), (0, 3)],
 [(1, 4), (3, 5, 6), (0, 2)],
 [(1, 5), (0, 2, 3), (4, 6)],
 [(1, 5), (0, 2, 4), (3, 6)],
 [(1, 5), (0, 2, 6), (3, 4)],
 [(1, 5), (0, 3, 4), (2, 6)],
 [(1, 5), (0, 3, 6), (2, 4)],
 [(1, 5), (0, 4, 6), (2, 3)],
 [(1, 5), (2, 3, 4), (0, 6)],
 [(1, 5), (2, 3, 6), (0, 4)],
 [(1, 5), (2, 4, 6), (0, 3)],
 [(1, 5), (3, 4, 6), (0, 2)],
 [(1, 6), (0, 2, 3), (4, 5)],
 [(1, 6), (0, 2, 4), (3, 5)],
 [(1, 6), (0, 2, 5), (3, 4)],
 [(1, 6), (0, 3, 4), (2, 5)],
 [(1, 6), (0, 3, 5), (2, 4)],
 [(1, 6), (0, 4, 5), (2, 3)],
 [(1, 6), (2, 3, 4), (0, 5)],
 [(1, 6), (2, 3, 5), (0, 4)],
 [(1, 6), (2, 4, 5), (0, 3)],
 [(1, 6), (3, 4, 5), (0, 2)],
 [(2, 3), (0, 1, 4), (5, 6)],
 [(2, 3), (0, 1, 5), (4, 6)],
 [(2, 3), (0, 1, 6), (4, 5)],
 [(2, 3), (0, 4, 5), (1, 6)],
 [(2, 3), (0, 4, 6), (1, 5)],
 [(2, 3), (0, 5, 6), (1, 4)],
 [(2, 3), (1, 4, 5), (0, 6)],
 [(2, 3), (1, 4, 6), (0, 5)],
 [(2, 3), (1, 5, 6), (0, 4)],
 [(2, 3), (4, 5, 6), (0, 1)],
 [(2, 4), (0, 1, 3), (5, 6)],
 [(2, 4), (0, 1, 5), (3, 6)],
 [(2, 4), (0, 1, 6), (3, 5)],
 [(2, 4), (0, 3, 5), (1, 6)],
 [(2, 4), (0, 3, 6), (1, 5)],
 [(2, 4), (0, 5, 6), (1, 3)],
 [(2, 4), (1, 3, 5), (0, 6)],
 [(2, 4), (1, 3, 6), (0, 5)],
 [(2, 4), (1, 5, 6), (0, 3)],
 [(2, 4), (3, 5, 6), (0, 1)],
 [(2, 5), (0, 1, 3), (4, 6)],
 [(2, 5), (0, 1, 4), (3, 6)],
 [(2, 5), (0, 1, 6), (3, 4)],
 [(2, 5), (0, 3, 4), (1, 6)],
 [(2, 5), (0, 3, 6), (1, 4)],
 [(2, 5), (0, 4, 6), (1, 3)],
 [(2, 5), (1, 3, 4), (0, 6)],
 [(2, 5), (1, 3, 6), (0, 4)],
 [(2, 5), (1, 4, 6), (0, 3)],
 [(2, 5), (3, 4, 6), (0, 1)],
 [(2, 6), (0, 1, 3), (4, 5)],
 [(2, 6), (0, 1, 4), (3, 5)],
 [(2, 6), (0, 1, 5), (3, 4)],
 [(2, 6), (0, 3, 4), (1, 5)],
 [(2, 6), (0, 3, 5), (1, 4)],
 [(2, 6), (0, 4, 5), (1, 3)],
 [(2, 6), (1, 3, 4), (0, 5)],
 [(2, 6), (1, 3, 5), (0, 4)],
 [(2, 6), (1, 4, 5), (0, 3)],
 [(2, 6), (3, 4, 5), (0, 1)],
 [(3, 4), (0, 1, 2), (5, 6)],
 [(3, 4), (0, 1, 5), (2, 6)],
 [(3, 4), (0, 1, 6), (2, 5)],
 [(3, 4), (0, 2, 5), (1, 6)],
 [(3, 4), (0, 2, 6), (1, 5)],
 [(3, 4), (0, 5, 6), (1, 2)],
 [(3, 4), (1, 2, 5), (0, 6)],
 [(3, 4), (1, 2, 6), (0, 5)],
 [(3, 4), (1, 5, 6), (0, 2)],
 [(3, 4), (2, 5, 6), (0, 1)],
 [(3, 5), (0, 1, 2), (4, 6)],
 [(3, 5), (0, 1, 4), (2, 6)],
 [(3, 5), (0, 1, 6), (2, 4)],
 [(3, 5), (0, 2, 4), (1, 6)],
 [(3, 5), (0, 2, 6), (1, 4)],
 [(3, 5), (0, 4, 6), (1, 2)],
 [(3, 5), (1, 2, 4), (0, 6)],
 [(3, 5), (1, 2, 6), (0, 4)],
 [(3, 5), (1, 4, 6), (0, 2)],
 [(3, 5), (2, 4, 6), (0, 1)],
 [(3, 6), (0, 1, 2), (4, 5)],
 [(3, 6), (0, 1, 4), (2, 5)],
 [(3, 6), (0, 1, 5), (2, 4)],
 [(3, 6), (0, 2, 4), (1, 5)],
 [(3, 6), (0, 2, 5), (1, 4)],
 [(3, 6), (0, 4, 5), (1, 2)],
 [(3, 6), (1, 2, 4), (0, 5)],
 [(3, 6), (1, 2, 5), (0, 4)],
 [(3, 6), (1, 4, 5), (0, 2)],
 [(3, 6), (2, 4, 5), (0, 1)],
 [(4, 5), (0, 1, 2), (3, 6)],
 [(4, 5), (0, 1, 3), (2, 6)],
 [(4, 5), (0, 1, 6), (2, 3)],
 [(4, 5), (0, 2, 3), (1, 6)],
 [(4, 5), (0, 2, 6), (1, 3)],
 [(4, 5), (0, 3, 6), (1, 2)],
 [(4, 5), (1, 2, 3), (0, 6)],
 [(4, 5), (1, 2, 6), (0, 3)],
 [(4, 5), (1, 3, 6), (0, 2)],
 [(4, 5), (2, 3, 6), (0, 1)],
 [(4, 6), (0, 1, 2), (3, 5)],
 [(4, 6), (0, 1, 3), (2, 5)],
 [(4, 6), (0, 1, 5), (2, 3)],
 [(4, 6), (0, 2, 3), (1, 5)],
 [(4, 6), (0, 2, 5), (1, 3)],
 [(4, 6), (0, 3, 5), (1, 2)],
 [(4, 6), (1, 2, 3), (0, 5)],
 [(4, 6), (1, 2, 5), (0, 3)],
 [(4, 6), (1, 3, 5), (0, 2)],
 [(4, 6), (2, 3, 5), (0, 1)],
 [(5, 6), (0, 1, 2), (3, 4)],
 [(5, 6), (0, 1, 3), (2, 4)],
 [(5, 6), (0, 1, 4), (2, 3)],
 [(5, 6), (0, 2, 3), (1, 4)],
 [(5, 6), (0, 2, 4), (1, 3)],
 [(5, 6), (0, 3, 4), (1, 2)],
 [(5, 6), (1, 2, 3), (0, 4)],
 [(5, 6), (1, 2, 4), (0, 3)],
 [(5, 6), (1, 3, 4), (0, 2)],
 [(5, 6), (2, 3, 4), (0, 1)]]

【讨论】:

  • 谢谢,我刚刚实现了类似的逻辑。很高兴看到我和你的想法一样。我的实现被添加为答案。
【解决方案2】:

生成排列并删除重复项。

>>> import itertools
>>> Na = 2
>>> Nb = 2
>>> p = itertools.permutations(['R']*Na + ['B']*Nb)
>>> for perm in sorted(list(set(p)), reverse=True):
...     print perm
... 
('R', 'R', 'B', 'B')
('R', 'B', 'R', 'B')
('R', 'B', 'B', 'R')
('B', 'R', 'R', 'B')
('B', 'R', 'B', 'R')
('B', 'B', 'R', 'R')

【讨论】:

  • 你打败了我一秒钟。另外你的代码更短xD
  • 但它并没有那么优化。但我想更好的可读性:)
  • 有没有其他有效的方法可以做到这一点,而不必首先生成大量的项目。目前的实现仅适用于非常小的 Na、Nb。
  • 我不确定。也许 numpy 数组加上在 p 上使用 .next() 而不是一次性使用它可能会有所帮助。
  • 你期望的NaNb有多大?
【解决方案3】:

你可以用 itertools 解决这个问题:

import itertools
last = None
result = []
for v in itertools.permutations(['A','A','B','B']):
    key = "".join(v)
    if key == last: continue
    last = key
    result.append(v)
print result

【讨论】:

    【解决方案4】:

    这是一种可能的实现方式:

    def permutations(colors, l):
        if l == 0:
            yield []
        else:
            for i in range(len(colors)):
                if colors[i]:
                    la = colors[:i]
                    lb = [colors[i][1:]]
                    lc = colors[i + 1:]
                    choice = colors[i][0]
                    for rest in permutations(la + lb + lc, l - 1):
                        yield [choice] + rest
    

    用法:

    for choice in permutations([['R'] * 2, ['B'] * 2], 4):
        print(choice)
    
    
    ['R', 'R', 'B', 'B']
    ['R', 'B', 'R', 'B']
    ['R', 'B', 'B', 'R']
    ['B', 'R', 'R', 'B']
    ['B', 'R', 'B', 'R']
    ['B', 'B', 'R', 'R']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-20
      • 1970-01-01
      • 1970-01-01
      • 2016-05-22
      • 1970-01-01
      • 2020-02-19
      相关资源
      最近更新 更多