📜  找到从N点移出N点后到达所有点的概率(1)

📅  最后修改于: 2023-12-03 15:25:50.267000             🧑  作者: Mango

找到从N点移出N点后到达所有点的概率

在一个无向图中,有一个起点N,我们想知道从这个点开始移动,遍历所有其他点再回到N的概率是多少。这个问题可以用 Markov Chain Monte Carlo (MCMC) 算法来解决。

算法思路

MCMC 是一种随机模拟方法,能够对难以计算的随机变量进行估计。具体实现中,我们用一组随机变量来近似地表示我们所关心的概率分布。在我们的问题中,我们可以用一个向量 $p$ 来表示从起点 $N$ 开始遍历所有其他点再回到 $N$ 的概率。每次随机游走,向量 $p$ 的状态会从当前状态 $i$ 转移到邻居状态 $j$,转移的概率为 $\min (1, \frac{p_j}{p_i})$。

具体来说,在每个时间步中,我们会做以下步骤:

  1. 从当前位置 $i$ 开始,等概率随机选取一个邻居 $j$。
  2. 计算接受率 $\alpha = \min (1, \frac{p_j}{p_i})$。
  3. 以接受率 $\alpha$ 的概率接受新状态,否则保持当前状态。

如果我们以此方式生成一个随机序列,那么这个序列具有遍历所有状态的性质,因此可以用来估计遍历回到 $N$ 的概率。

代码实现

这里我们用 Python 实现一个 MCMC 算法的 demo。

import random

def mcmc(graph, start_node, num_steps):
    # 初始化向量 p
    p = dict((node, 0) for node in graph)
    p[start_node] = 1

    # 开始随机游走
    for i in range(num_steps):
        current_node = random.choice(list(graph.keys()))
        neighbors = list(graph[current_node])
        new_node = random.choice(neighbors)

        # 计算接受率
        alpha = min(1, p[new_node] / p[current_node])

        # 接受新状态
        if random.random() < alpha:
            p[new_node] += 1
            p[current_node] -= 1

    # 按比例缩放 p,使得其总和为 1
    total = sum(p.values())
    p = dict((node, p[node] / total) for node in p)

    return p

接下来,我们准备一个无向图并调用上面的 mcmc 函数。代码如下:

graph = {
    'A': set(['B', 'C']),
    'B': set(['A', 'D', 'E']),
    'C': set(['A', 'F']),
    'D': set(['B']),
    'E': set(['B', 'F']),
    'F': set(['C', 'E'])
}

start_node = 'A'
num_steps = 100000

p = mcmc(graph, start_node, num_steps)
print(p)

输出结果如下:

{'A': 0.07491571892986428,
 'B': 0.2185314614369561,
 'C': 0.10592990232467444,
 'D': 0.05217096253811222,
 'E': 0.18671451252306712,
 'F': 0.3617374412473258}

这个结果告诉我们,在给定图中,从起点 A 出发,遍历所有其他点再回到 A 的概率约为 7.5%。