[英]All possible ways to place colored balls into bins
I have a number of bins. 我有几个箱子。 Each bin accommodates only one ball.
每个垃圾箱只能容纳一个球。
Let's say, I have 让我们说,我有
Na number of red balls Na数量的红球
Nb number of blue balls Nb数量的蓝色球
Nc number of green balls Nc数量的绿球
and so on. 等等。
I want to find out all possible ways of placing the balls into bins of length (Na+Nb+Nc). 我想找出将球放入长度(Na + Nb + Nc)箱中的所有可能方法。
For example, let's say I have only two red balls and two blue balls. 例如,假设我只有两个红球和两个蓝球。 I want to place them into 4 bins.
我想把它们放进4个箱子里。 The possible ways of arrangements are:
可能的安排方式是:
R R B B
R B R B
R B B R
B R R B
B R B R
B B R R
( I hope I did not miss any combination) (我希望我没有错过任何组合)
Is there any easy way to generate the indices for the different colors, for example: 有没有简单的方法来生成不同颜色的索引,例如:
First row is : R=(0,1) B=(2,3)
Second row is : R=(0,2) B=(1,3)
Is there an easy way to generate this in numpy? 是否有一种简单的方法可以在numpy中生成这个?
The bins actually have different weights, something like: 箱子实际上有不同的重量,如:
[0.1, 0.3, 0.2, 0.5]
So for the combination RRBB represented as R at (0,1) and B at (2,3)
, the total weight for R is 0.1+0.3=0.4
and for B is 0.2+0.5=0.7
因此,对于表示为
R at (0,1) and B at (2,3)
RRBB组合, R at (0,1) and B at (2,3)
的总重量为0.1+0.3=0.4
,B的总重量为0.2+0.5=0.7
I ultimately am interested in the total weight for each color in the different arrangements and want to choose the best one from another cost function f(total_weight(R), total_weight(B)). 我最终对不同排列中每种颜色的总重量感兴趣,并希望从另一种成本函数f(total_weight(R),total_weight(B))中选择最佳颜色。 Any comments if the generation of total weight could be done in a different easy way in numpy?
如果总重量的产生可以在numpy中以不同的简单方式完成吗?
Generate the permutations and remove duplicates. 生成排列并删除重复项。
>>> 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')
You can solve that with itertools: 你可以用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
Here's a "multi-combinations" implementation that doesn't require eliminating duplicate permutations. 这是一个“多组合”实现,不需要消除重复的排列。 The first argument,
n
, is the list [Na, Nb, Nc, ...]. 第一个参数
n
是列表[Na,Nb,Nc,...]。
It is implemented as a recursive generator, so you can iterate through the combinations without having them all in memory at once. 它被实现为一个递归生成器,因此您可以迭代组合,而不必将它们全部存储在内存中。 You say in a comment that Na + Nb + ... is typically around 20 but could be as high as 50 or 100. That means you almost certainly do not want to store all the combinations in memory.
你在评论中说Na + Nb + ...通常在20左右但可能高达50或100.这意味着你几乎肯定不想将所有组合存储在内存中。 Consider an example with four "colors" where Na = Nb = Nc = Nd = 5. The number of combinations is
choose(20, 5) * choose(15, 5) * choose(10, 5) = 11732745024
, where choose(n, k)
is the binomial coefficient . 考虑具有四个“颜色”的示例,其中Na = Nb = Nc = Nd = 5.组合的数量是
choose(20, 5) * choose(15, 5) * choose(10, 5) = 11732745024
,其中choose(n, k)
是二项式系数 。 My computer has just 16 GB of RAM, so the storage required for that number of combinations would far exceed my computer's memory. 我的计算机只有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
It generates a list of tuples. 它生成一个元组列表。 That is, where your description of the first row is "First row is : R=(0,1) B=(2,3)", the first value generated by
multicombinations([2, 2])
is [(0, 1), (2, 3)]
. 也就是说,你对第一行的描述是“第一行是:R =(0,1)B =(2,3)”,
multicombinations([2, 2])
生成的第一个值是[(0, 1), (2, 3)]
。 (This might not be the best format for the result, given the description of the weight calculation that you want to do next.) (考虑到您接下来要做的重量计算的描述,这可能不是结果的最佳格式。)
Some examples: 一些例子:
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)]]
Here is one possible way of implementing: 这是一种可能的实现方式:
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
Usage: 用法:
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']
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.