树上随机游走

树上随机游走

问题描述

给定一颗树,树上有一点,每一时刻都会等概率地移动至邻接节点上,求该点移动至某一点的期望距离。

定义

  • T=(V,E): 所讨论的树;
  • d(u):u 节点的度数;
  • w(u,v):u 结点与 v 结点之间的边的边权;
  • size(u):u 结点的子树大小;
  • pu:u 结点的父节点;
  • sonu:u 结点的子节点集合;
  • siblingu:u 结点的兄弟结点集合。

向父结点走的期望距离

f(u) 代表 u 结点走到其父结点 pu 的期望距离,则有:

f(u)=w(u,pu)+vsonu(w(u,v)+f(v)+f(u))d(u)

分子中的前半部分代表直接走向了父结点的距离;后半部分代表先走向了子结点,再由子结点走回来然后再向父结点走的距离。

u 结点走向其任何邻接点的概率相同,所以总体除以 d(u)

将上式右边和式中的 f(u) 提出来:

f(u)=w(u,pu)+(d(u)1)f(u)+vsonu(w(u,v)+f(v))d(u)

两边同乘 d(u),则有:

d(u)f(u)=w(u,pu)+vsonu(w(u,v)+f(v))+(d(u)1)f(u)

两边同减 (d(u)1)f(u) 得:

f(u)=w(u,pu)+vsonu(w(u,v)+f(v))

再将权值,即 w 整合至一个和式得:

f(u)=(u,s)Ew(u,s)+vsonuf(v)

我们将这个式子设为 (1) 式,下文需要用到。

叶结点的初始值为 1,即 f(leaf)=1(因为它只能直接向父结点走)。

特别地,当边权全部为 1 时,上式可化简为:

f(u)=d(u)+vsonuf(v)

u 子树的所有结点的度数和,同时也是 2size(u)1,因为除 upu 之间的边只有 1 点贡献以外,每条边会产生 2 点度数的贡献(一去一回走两次),而每个结点连向其父亲的边有且只有一条,所以就是 2size(u)1

向子节点走的期望距离

我们再设 g(u) 代表从 u 结点的父节点 pu 走到 u结点的期望距离。注意看清楚,g(u) 不是代表从 u 结点走向其子结点的期望距离。

易得:

g(u)=w(u,pu)+w(pu,ppu)+g(pu)+g(u)+vsiblingu(w(pu,v)+f(v)+g(u))d(pu)

分子中的第一部分代表从 pu 直接走向了结点 u;第二部分代表先走向了 ppu 再走回来,然后再向 u 结点走;第三部分代表先走向 u 结点的兄弟结点再走回来,然后再向 u 结点走。

pu 结点走向其任何邻接点的概率相同,所以总体再除以 d(pu)

上式左右两边同乘 d(pu) 得:

d(pu)g(u)=w(u,pu)+w(pu,ppu)+g(pu)+g(u)+vsiblingu(w(pu,v)+f(v)+g(u))

右边和式中共有 d(pu)2g(u),和式外还有一个 d(u),所以等式左右两边同时减去 (d(pu)1)g(u) 得:

g(u)=w(u,pu)+w(pu,ppu)+g(pu)+vsiblingu(w(pu,v)+f(v))

将所有的权值,即 w 合并到一个和式,得:

g(u)=g(pu)+(pu,s)Ew(pu,s)+vsiblinguf(v)

我们将这个式子设为 (2) 式,下文也需要用到。

再将刚刚得到的 (1) 式:

f(u)=(u,s)Ew(u,s)+vsonuf(v)

转化成

(pu,s)Ew(pu,s)+vsiblinguf(v)+f(u)=f(pu)

(pu,s)Ew(pu,s)+vsiblinguf(v)=f(pu)f(u)

再带入 (2) 式得:

g(u)=g(pu)+f(pu)f(v)

根节点的初始值设为 0,即 g(root)=0

下面是代码(以无权树为例)

void dfs1(int u, int p_u) {
    f[u] = edge[u].size();
    for (int i = 0; i < edge[u].size(); ++ i) {
        int v = edge[u][i];
        if (v == p_u)
            continue;
        dfs1(v, u);
        f[u] += f[v];
    }
}

void dfs2(int u, int p_u) {
    if(u != root)//root 一般为 1
        g[u] = g[p_u] + f[p_u] - f[u];
    for(int i = 0; i < edge[u].size(); ++ i) {
        int v = edge[u][i];
        if(v == p_u)
            continue;
        dfs2(v, u);
    }
}
posted @   流星Meteor  阅读(267)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示