[英]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.