簡體   English   中英

枚舉 Python 中標記球和標記箱問題中的所有可能組合

[英]Enumerate all possible combinations in labeled balls and labeled bins problem in Python

我正在尋找一種 Pythonic 方式來枚舉“標記的球進入標記的箱子”問題的所有可能選項。 例如,給定 2 個帶標簽的球和 2 個帶標簽的箱子,我想得到:

(甲,乙)

(AB, )

(,AB)

(乙,甲)

即 (2^2) 4 個選項。 如果我們給出 3 個球和 3 個箱子,則有 27 種可能性 3^3。 例如:

(A, B, C) (ABC, , ) (, , ABC) (AB, C, ) (C, , AB) (,BC, A) 等等...

我正在考慮解決方案 (AB, ) 和 (BA, ) 相同的項目。

計算對象

這些對象在很多地方也被稱為 k 分區。

我們可以先對它們進行計數,然后使用計數方法來測試我們是否生成了正確數量的對象。

第二類斯特林數是計算n球放入b個非空箱的次數。

我們可以將其擴展到以下公式以允許空箱

\sum_{e=0}^{b} {b\choose e} S(n,be) (be)!

在此處輸入圖像描述

在上面的總和中, e表示空 bin 的數量,因此我們允許0b個空 bin,術語binomial(b,e)將占空 bin 的任何 position, be其余為非空垃圾箱由S(n,be)計數,但我們仍然需要允許我們通過(be)! .

我們可以使用以下程序來計算:

#!/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:

c(2,2): 4
c(3,3): 27
c(6,7): 117649

也可以看看:

  • 該線程得出相同的公式

  • 這兩個線程討論了放置球后有e空箱的概率link1 , link2

生成對象

這是一個遞歸算法,可生成將球放置到箱中的位置。 每個球被放置在一個箱子中,然后算法進一步遞歸到剩余的球中以放置下一個球。 當沒有更多的球可以放置時,我們將打印所有垃圾箱的內容。

#!/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:

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

其他生成對象的算法

基於分區的算法: link1 鏈接2

Knuth 算法 U: link1 鏈接2 鏈接3

這篇文章中使用的所有代碼也可以在這里找到

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM