随机生成树问题的研究与思考

发布时间 2023-09-15 13:37:59作者: xiezheyuan

随机选父亲法

随机选父亲法代码如下:

void RandomFatherGenerator(int n, Graph &g){
	std::mt19937 rnd(time(nullptr));
	for(int i=2;i<=n;i++){
		g.addUndirectedEdge(rnd%(i-1)+1, i);
	}
}

上述代码会生成一个以 \(1\) 为根的树。

每个点的期望深度

用随机选父亲法构造一个 \(n\) 个点的树,求每个点的期望深度。

我们都知道随机选父亲法生成的树深度期望 \(O(\log n)\)。但如果我们需要求精确值呢?

一个朴素的 ytxy 的 \(O(n^3)\) 做法:设 \(f(i,j)\) 表示第 \(i\) 个点深度为 \(j\) 的概率。

容易得到:

\[f(i,j) = \frac{1}{i-1}\sum_{k=1}^{i-1} f(k,j-1) \]

最后第 \(i\) 个点答案:

\[\sum_{k=1}^{i} f(i,k)k \]

一个朴素的 \(O(n^2)\) 做法。我们发现 \(f(,j)\) 中的 \(j\) 完全就是一个多余的东西。因此我们无须这个状态。

\(f(i)\) 为第 \(i\) 个节点的深度期望。

\[f(i)=1+\frac{1}{i-1}\sum_{k=1}^{i-1} f(k) \]

用前缀和即可优化到 \(O(n)\)

给个 python 代码吧:

pre,f,n = 1,1,10
for i in range(1, n + 1):
    print(f)
    f = 1 + (1 / (i)) * pre
    pre += f

整个树的期望深度