繁体   English   中英

为什么不能为大量 n 个元素正确计算贝尔数?

[英]Why isn't the Bell number calculated correctly for a large set of n elements?

我正在尝试使用 integer 分区和 Faà di Bruno 公式计算大量元素的贝尔数。 贝尔数是可以在一组 n 个元素中进行的可能分区的数量。 我希望能够通过计算一组 n 元素的每个特定 integer 分区中可能的组合数量,然后将它们全部相加来做到这一点。 那么总和应该是贝尔数。

我使用Nicolas Blanc 的代码来计算一个集合中的所有 integer 个分区。 然后我使用Faà di Bruno 的公式,如本视频中所述,通过每个 integer 分区计算 go 并计算可能的组合。

代码输出插入数字的公式。左边的阶乘数是 integer 分区中的子集,右边的阶乘数是每个子集的数量。 名词然后除以这些数字。 然后将组合的数量附加到列表的末尾。

对于较小的集合,代码工作得很好。 这是一组 4 个元素的 output。

4! / (1!1!1!1! * 4!)
[1, 1, 1, 1, [1])

4! / (2!1!1! * 1!2!)
[2, 1, 1, [6]]

4! / (3!1! * 1!1!)
[3, 1, [4]]

4! / (2!2! * 2!)
[2, 2, [3]]

4! / (4! * 1!)
[4, [1]]

Bell Number: 15

直到您输入数字 12 及以上时,Bell 号码才不正确。 整个 output 很长,但输入12会产生4213663而不是4213597 ,输入13会产生27645945而不是27644437

仔细研究之后,我无法弄清楚为什么只在 11 点之后才会发生这种情况。这可能是我使用的公式有问题,或者我的代码有误或其他原因。

其他重要链接:贝尔多项式集合划分贝尔数

import math

in_par = []
stack = []
bell = 0  

def partitions(remainder, start_number = 1):
    if remainder == 0:
        in_par.append(list(stack))
        #print(stack)
    else:
        for nb_to_add in range(start_number, remainder+1):
            stack.append(nb_to_add)
            partitions(remainder - nb_to_add, nb_to_add)
            stack.pop()

x = partitions(13) # <------- input element count here

for part in in_par:
    combo = 1
    n = 13 # <------- input element count here
    
    part.reverse()
    refined = []
    counts = []
    
    for elem in part:
        if str(refined).find(str(elem)) == -1:
            refined.append(elem)

        #print(str(combo) + " * " + str(math.factorial(elem)) + " a")
        combo = combo * math.factorial(elem)
    
    for elem in refined:
        
        #print(str(combo) + " * !" + str(part.count(elem)) + " b")
        combo = combo * math.factorial(part.count(elem))
        
        counts.append(str(part.count(elem)))
    
    
    for i in range(len(part)):
        part[i] = str(part[i])
    
    print(str(n) + "! / (" + ("!").join(part) + "! * " + ("!").join(counts) + "!)")
    
    for i in range(len(part)):
        part[i] = int(part[i])
    
    combo = math.factorial(n) // combo
    bell = bell + combo
    part.append([combo])
    
    print(part)
    print("")
    
    #print(str(bell))

print("Bell Number: " + str(bell))

我稍微重新组织了一些东西,但关键是你对整数的字符串搜索:

import math

bell = 0  
N = 13  # <------- input element count here

stack = []
def partitions(remainder, start_number = 1):
    if remainder == 0:
        yield list(reversed(stack))
    else:
        for nb_to_add in range(start_number, remainder+1):
            stack.append(nb_to_add)
            yield from partitions(remainder - nb_to_add, nb_to_add)
            stack.pop()

for part in partitions(N):
    combo = 1
    n = N
    
    refined = []
    counts = []
    
    for elem in part:
        if elem not in refined:
            refined.append(elem)

        combo = combo * math.factorial(elem)
    
    for elem in refined:
        combo = combo * math.factorial(part.count(elem))
        counts.append(str(part.count(elem)))
    
    for i in range(len(part)):
        part[i] = str(part[i])
    
    print(str(n) + "! / (" + ("!").join(part) + "! * " + ("!").join(counts) + "!)")
    
    for i in range(len(part)):
        part[i] = int(part[i])
    
    combo = math.factorial(n) // combo
    bell = bell + combo
    part.append([combo])
    
    print(part)
    print("")

print("Bell Number:", bell)

Output:

...
Bell Number: 27644437

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM