【发布时间】:2014-07-01 11:46:39
【问题描述】:
我有一棵有向树,我想知道它的大小。我没有关于其深度或节点分布的信息。有两个主要障碍:
1) 树非常大(~十亿个节点)
2) 边遍历开销很大。
是否有统计方法可用于快速估计其大小(节点数)且误差有界?不幸的是,谷歌搜索只会导致精确计数的算法在这些限制下表现不佳。
奖金
如果我放宽从树到 DAG(有向无环图)的约束,我可以获得它的大小和唯一路径的数量吗?例如。对于这个 DAG(每个边缘都向下)
有 19 个节点(大小)和 23 条路径(4 个额外的路径,因为红色边缘为其目标节点提供了 1 条路径,并为其目标节点的子节点提供了 3 条路径)
我尝试过的事情
对于树的情况,我正在考虑以下内容:
amounts = []
def estimateHelper(node):
amounts[node.depth].push(len(node.children))
for each child in small random sample of node.children:
estimateHelper(child)
def estimate(root):
estimateHelper(root)
reach = 0
for (j = len(amounts) - 1; j >= 0; --j):
avgChildrenPerNodeAtThisLevel = avg(amounts[j])
reach = avgChildrenPerNodeAtThisLevel + avgChildrenPerNodeAtThisLevel * reach
return reach
它本质上计算树的最深节点处的“范围”,然后将其传播回上面的级别以找到该级别的范围。它这样做直到最终找到树根的“范围”。我不确定我是否在上述算法中对节点的均匀分布做出任何假设。重申一下,我不知道给定的树会有什么样的分布。
假设它有效,这也解决了 DAG 的“路径”。一旦你有了所有的“路径”,我正在考虑使用生日悖论的逆来计算有多少个唯一节点。生日悖论的答案是“我们需要选择多少天(路径),直到我们以某种概率在一年中 365 天的情况下遇到重复的一天”。所以我们不断尝试随机路径(天),直到我们遇到重复节点,我们重复几次以找到该事件的概率,然后我们将其插入生日悖论以找到唯一节点的数量(唯一的天数)年)。但请注意,生日悖论也做出了一致性假设。
这些都不是很严格。理想的情况是给我一个带有误差范围的估计,以及一篇足够严谨地描述算法的论文。非常感谢任何指向正确方向的指针。
【问题讨论】:
-
获取它的大小是什么意思?计算节点数?给定节点的子节点数量是否有限制?例如,您可以落后一步并尝试另一种方法:这棵树是如何构建的?也许您可以存储一个计数器并在每次插入时递增它并在每次删除时递减它?也许在构建时存储其他信息就是您想要的?
-
嗨菲利普。大小是节点的数量。一个节点有多少孩子没有真正的限制,但实际限制约为 100,000。树不是我建的,而是大量分布式服务器建的。我想在本地(在我的笔记本电脑上)快速估计大小,边缘遍历很昂贵,因为对于每个节点,我需要向相应的服务器发出网络请求。
-
尝试验证您的算法:运行 100 次并计算其相对离散度。还可以尝试不同的 avg-s(二次均值、几何均值等),并调整样本大小。
-
@SergiuToarca 您无法遍历节点,也无法从服务器获取有关树的任何其他信息,但您拥有每个节点的平均子节点数 (AVG)。这是可怕的情况)如果您可以获得以 KB 或 MB(TOTAL)为单位的树的总大小 - 通过除法 TOTAL/(NODESZ + AVG * CHILDSZ)计算节点数。这将是估计的上限(如果 AVG 没问题)。
-
除非您查看所有可能的路径,否则我认为您不会遇到有界错误。如果您不查看的路径的节点数是整个树其余部分的十倍怎么办?
标签: python algorithm tree statistics duplicates