[英]Enumerate all possible combinations in labeled balls and labeled bins problem in Python
I'm looking for a Pythonic way of enumerating all possible options for the " labeled balls into labeled bins " problem.我正在寻找一种 Pythonic 方式来枚举“标记的球进入标记的箱子”问题的所有可能选项。 For example, given 2 labeled balls and 2 labeled bins I would like to get:
例如,给定 2 个带标签的球和 2 个带标签的箱子,我想得到:
(A, B) (甲,乙)
(AB, ) (AB, )
(,AB) (,AB)
(B, A) (乙,甲)
That is (2^2) 4 options.即 (2^2) 4 个选项。 In case we give 3 balls and 3 bins, there are 27 possibilities 3^3.
如果我们给出 3 个球和 3 个箱子,则有 27 种可能性 3^3。 For example:
例如:
(A, B, C) (ABC, , ) (, , ABC) (AB, C, ) (C, , AB) (,BC, A) and so on... (A, B, C) (ABC, , ) (, , ABC) (AB, C, ) (C, , AB) (,BC, A) 等等...
I'm considering the solution (AB, ) and (BA, ) the same item.我正在考虑解决方案 (AB, ) 和 (BA, ) 相同的项目。
These objects are also called k-partitions in many places.这些对象在很多地方也被称为 k 分区。
We could count them at first, and then use the counting methods to test if we're generating the right amount of objects.我们可以先对它们进行计数,然后使用计数方法来测试我们是否生成了正确数量的对象。
The Stirling numbers of the 2nd kind are counting the number of placements of n
balls into b
non-empty bins. 第二类斯特林数是计算
n
球放入b
个非空箱的次数。
We can extend that to the following formula to allow for empty bins我们可以将其扩展到以下公式以允许空箱
\sum_{e=0}^{b} {b\choose e} S(n,be) (be)!
In the sum above, e
represents the number of empty bins, so we're allowing between 0
and b
empty bins, the term binomial(b,e)
will account for any position of the empty bins, while the remaining be
non-empty bins are counted by S(n,be)
, but we still need to allow for all permutations of the non-empty bins which we're doing through (be)!
在上面的总和中,
e
表示空 bin 的数量,因此我们允许0
到b
个空 bin,术语binomial(b,e)
将占空 bin 的任何 position, be
其余为非空垃圾箱由S(n,be)
计数,但我们仍然需要允许我们通过(be)!
. .
We can count this using the following program:我们可以使用以下程序来计算:
#!/usr/bin/python3
from sympy import *
from sympy.functions.combinatorial.numbers import stirling
#
# Counting the number of ways to place n balls into b boxes, allowing
# for empty boxes.
#
def count_k_partitions(n,b):
ans = 0
for e in range(0,b+1):
ans += binomial(b,e) * stirling(n,b-e,kind=2) * factorial(b-e)
return ans
print("c(2,2):",count_k_partitions(2,2))
print("c(3,3):",count_k_partitions(3,3))
print("c(6,7):",count_k_partitions(6,7))
OUTPUT: OUTPUT:
c(2,2): 4
c(3,3): 27
c(6,7): 117649
See also:也可以看看:
This thread derives the same formula该线程得出相同的公式
These two threads discuss the probability of having e
empty bins after placing the balls link1 , link2这两个线程讨论了放置球后有
e
空箱的概率link1 , link2
Here is a recursive algorithm that generates the placements of balls into bins.这是一个递归算法,可生成将球放置到箱中的位置。 Each ball is placed in one of the bins, then the algorithm recurses further into the remaining balls to place the next ball.
每个球被放置在一个箱子中,然后算法进一步递归到剩余的球中以放置下一个球。 When there are no more balls to place, we're printing the contents of all bins.
当没有更多的球可以放置时,我们将打印所有垃圾箱的内容。
#!/usr/bin/python3
import string
import copy
#
# This generates all the possible placements of
# balls into boxes (configurations with empty boxes are allowed).
#
class BinPartitions:
def __init__(self, balls, num_bins):
self.balls = balls
self.bins = [{} for x in range(num_bins)]
def print_bins(self, bins):
L = []
for b in bins:
buf = ''.join(sorted(b.keys()))
L += [buf]
print(",".join(L))
def _gen_helper(self,balls,bins):
if len(balls) == 0:
self.print_bins(bins)
else:
A,B = balls[0],balls[1:]
for i in range(len(bins)):
new_bins = copy.deepcopy(bins)
new_bins[i].update({A:1})
self._gen_helper(B,new_bins)
def get_all(self):
self._gen_helper(self.balls,self.bins)
BinPartitions(string.ascii_uppercase[:3],3).get_all()
#BinPartitions(string.ascii_uppercase[:2],2).get_all()
#BinPartitions(string.ascii_uppercase[:3],3).get_all()
#BinPartitions(string.ascii_uppercase[:6],3).get_all()
OUTPUT: OUTPUT:
ABC,,
AB,C,
AB,,C
AC,B,
A,BC,
A,B,C
AC,,B
A,C,B
A,,BC
BC,A,
B,AC,
B,A,C
C,AB,
,ABC,
,AB,C
C,A,B
,AC,B
,A,BC
BC,,A
B,C,A
B,,AC
C,B,A
,BC,A
,B,AC
C,,AB
,C,AB
,,ABC
Partition-based algorithms: link1 ;基于分区的算法: link1 ; link2
链接2
Knuth's Algorithm U: link1 ; Knuth 算法 U: link1 ; link2 ;
链接2 ; link3
链接3
All the code used in this post is also available here这篇文章中使用的所有代码也可以在这里找到
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.