表示集合分区的紧凑方式是什么?


11

存在用于表示集合分区的有效数据结构。这些数据结构对诸如Union和Find这样的操作具有良好的时间复杂性,但是它们并不是特别节省空间。

一种节省空间的方式来表示集合的分区是什么?

这是一个可能的起点:

我知道 具有元素的集合的分区数是,即第个贝尔数。因此,表示具有元素的集合分区的最佳空间复杂度是 位。为了找到这样的表示,我们可以寻找(一组元素的分区集合)与(一组从到的整数)之间的一对一映射。NBNNNlog2(BN)N1BN

有没有这样的映射可以有效地计算?我所说的“高效”是指我想将此紧凑表示形式转换为或时间多项式中的/易于操作的表示形式(例如列表列表。Nlog2(BN)


想知道,与仅将唯一整数分配给集合中每个元素(其中整数表示分区#的天真/自然编码有多远?也许是“差别不大” ...log2(BN)
vzn13年

Answers:


7

您可以使用以下递归公式的派生方式来找到您的编码: 通过考虑在包含元素的部分中还有多少其他元素来证明这一点。如果有个,那么我们有选择,还有用于划分其余部分的选择。

Bn+1=k=0n(nk)Bk.
n+1nk(nnk)=(nk)Bk

使用此方法,我们可以提供一种递归算法,将任何分区转换为范围内的数字。我假设您已经有一种方法可以将的大小为的子集转换为范围内的数字(这种算法可以使用Pascal的递归来以相同的方式设计。n+10,,Bn+11k{1,,n}0,,(nk)1(nk)=(n1k)+(n1k1)

假设包含的部分包含其他元素。找到他们的代码。通过将所有其余元素“压缩”到该范围计算的分区。递归计算其代码。新代码为n+1kC1{1,,nk}C2

C=l=0nk1(nl)Bl+C1Bnk+C2.

在另一个方向上,给定代码,找到唯一的,使得 并定义 由于,因此可以写成,其中。现在编码包含的部分中的元素,而编码的分区Ck

l=0nk1(nl)BlC<l=0nk(nl)Bl,
C=Cl=0nk1(nl)Bl.
0C<(nk)BnkC1Bnk+C20C2<BnkC1n+1C2{1,,nk},可以递归解码。要完成解码,您必须“解压缩”后面的分区,以便它包含未出现在包含的部分中的所有元素。n+1


这是如何使用相同的技术递归编码大小为的的子集的方法。如果则代码为,因此假设。如果则令为,作为的大小的子集;的代码为。如果则令为的代码,作为的大小的子集;的代码S{1,,n}kk=00k>0nSC1S{n}k1{1,,n1}SC1nSC1Sk{1,,n1}S是。C1+(n1k1)

为了解码代码,有两种情况。如果则解码大小为的的子集,其代码为,并输出。否则,解码大小为的的子集,其代码为,然后输出。CC<(n1k1)S{1,,n1}k1CS{n}S{1,,n1}kC(n1k1)S


极好的答案;谢谢。小错误:在顶部的递归公式的证明草图中,我认为您的意思是“有个”而不是“有个”-然后可以用方式划分其余的元素。nkkkBk
cberzan
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.