算法学习笔记(23): 马尔可夫链中的期望问题

算法,学习,笔记,马尔可夫,期望,问题 · 浏览次数 : 332

小编点评

**生成内容时需要带简单的排版** **1. 使用数学公式和方程** * 编写数学公式和方程,表示模型的复杂性。 * 例如,模型的复杂性可以表示为 \\(O(n^3)\\),或 \\(O(n^2)\\)。 **2. 使用数学工具进行优化** * 优化模型的复杂性,例如降低参数数量或减少求解步骤。 * 例如,可以优化模型的复杂性,降低参数数量或减少求解步骤。 **3. 使用数学技巧进行特殊优化** * 利用数学技巧,例如高斯消元或稀疏矩阵优化。 * 例如,可以利用高斯消元求解模型的复杂性,或利用稀疏矩阵优化模型的求解过程。 **4. 使用排版进行展示** * 编写排版,展示模型的复杂性,例如参数数量或求解步骤。 * 例如,可以编写排版,展示模型的复杂性,例如参数数量或求解步骤。

正文

马尔可夫链中的期望问题

这个问题是我在做 [ZJOI2013] 抛硬币 - 洛谷 这道题的时候了解的一个概念。

在网上也只找到了一篇相关的内容:# 马尔可夫链中的期望问题

故在这里来分享一下其中的期望问题。

马尔可夫链

定义:马尔科夫链为状态空间中经过从一个状态到另一个状态的转换的随机过程。该过程要求具备“无记忆性”,也就是说当前状态的概率仅与上一个状态相关。

数学定义:假定我们的序列状态为 \(\dots, X_{t-2}, X_{t-1}, X_t, X_{t+1}, X_{t+2}, \dots\),那么在 \(X_{t+1}\)

时刻的状态的条件概率仅依赖于前一刻的状态 \(X_t\),即:

\[P(X_{t+1}| ..., X_{t-2}, X_{t-1}, X_t) = P(X_{t+1} | X_t) \]

既然某一时刻状态转移的概率只依赖于它的前一个状态 ,那么我们只要能求出系统中任意两个状态之间的转换概率,这个马尔科夫链的模型就定了。


概率转移矩阵

通过马尔科夫链的模型转换,我们可以将事件的状态转换成概率矩阵 (又称状态分布矩阵 ),如下例:

其中线上的数字表示是状态转移到另一状态的概率

那么我们可以构造出如下矩阵:

\[P = \begin{pmatrix} & A & B & C & D \\ A & 0 & 0 & 0 & 0.5 \\ B & 0 & 0 & 0.25 & 0.5 \\ C & 1 & 0 & 0.5 & 0 \\ D & 0 & 0 & 0.25 & 0 \end{pmatrix} \]

假定我们初始状态为 \(A\),于是状态矩阵可以定义为

\[S = \begin{pmatrix} 1 \\ 0 \\ 0 \\ 0 \end{pmatrix} \]

那么经过 \(k\) 次转移后的概率分布是什么?

\[S_k = P^kS \]

例如 \(k = 4\)

\[S_4 = \begin{pmatrix} 0.0625 \\ 0.125 \\ 0.25 \\ 0.0625 \end{pmatrix} \]

通过 numpy 计算:

s = np.array([[1], [0], [0], [0]])
P = np.array([
      [0, 0, 0, 0.5],
      [0, 0, 0.25, 0.5],
      [1, 0, 0.5, 0],
      [0, 0, 0.25, 0]
])
i, n = 0, 4
while i < n:
    s = P.dot(s)
    i = i + 1
print(s)

转移矩阵的修订

如果我们到达了某一个点就结束了整个过程,那么我们需要对状态转移做一定的更改:

呃,这部分对于本文似乎有一点偏题了……请适当略过

我们新增了一个节点,将所有转移到 \(B\) 的状态转移为最终状态,也就是对于 \(B\) 的状态累计求和。

于是新的矩阵成为:

s = np.array([[1], [0], [0], [0], [0]])
P = np.array([
      [0, 0, 0, 0.5, 0],
      [0, 0, 0.25, 0.5, 0],
      [1, 0, 0.5, 0, 0], 
      [0, 0, 0.25, 0, 0], 
      [0, 1, 0, 0, 1]
])   

最终 \(S_k = P^kS\) 就是积累后的概率矩阵。


状态中的期望

我们关注的是到达状态 \(B\) 所需要的平均转移次数,所以我们把随机变量 \(X\) 看作到达目标状态所需要的步数。

根据变量期望的定义可得:

\[E(X) = \sum_{k = 1}^{\infty} [k \cdot P(X = k)] \]

那么现在的问题就变为了求 \(P(X = k)\)

根据上文,\(P(X = k) = [B]S_k = [B]P^kS\),也就是取 \(S_k\)\(B\) 相关的那一项。

或许我们可以求得 \([B]S_k\) 的通项(一个多项式?)从而求得期望。

在顶端链接的文章中提到:

事实上,我们可以计算转移矩阵的 \(n\) 次方,即得到各元素关于 \(n\) 的表达式.

由于我没有学过线性代数,所以我就不在本文中展开。

而是采用第二种方法:期望线性方程组


期望线性方程组

显然至少目前对我而言,求通项的方法不可行,所以我们需要利用另外一种方法。

我们仍然求从 \(A\) 转移到 \(B\) 所需要的平均转移次数。

那么我们不妨设 \(E_i\) 表示从状态 \(i\) 转移到 \(B\) 所需要的期望次数,\(p_{ji}\) 表示从状态 \(j\)\(i\) 转移来的概率。

那么有:

\[E_i = 1 + \sum_{j} p_{ji} \cdot E_j \]

也就是说 \(E_i\) 等于 \(i\) 可以直接转移到的状态的期望乘上转移的概率的和再加上 \(1\)(转移的代价,1步)

以上文中例子为例,可以列出:

\[\begin{aligned} E_A &= E_C + 1 \\ E_C &= 0.25E_B + 0.25E_D + 1 \\ E_D &= 0.5E_A + 0.5E_B + 1\\ \end{aligned} \]

而特殊的,\(E_B = 0\),因为已经到达目标了

而可以解出 \(E_A = 4\)

也就是说,从 \(A\) 转移到 \(B\) 的期望步数是 \(4\)


方程矩阵化

如果我们把列出来的方程看作矩阵,那么可以得到:

P = np.array([
    [0-1, 0, 1, 0],
    [0, 0-1, 0, 0],
    [0, 0.25, 0.5-1, 0.25],
    [0.5, 0.5, 0, 0-1]
])

似乎是我原本概率转移矩阵有问题?

也就是原概率矩阵的转置矩阵再在对角线上全部减一。

或者可以表示为

\[P' = P^T - I_n \]

而我们最终求解的方程为:

\[P'E = \begin{pmatrix} -1 \\ -1 \\ \vdots \\ -1 \end{pmatrix} \]

利用死去的高斯消元即可。


例题

链接:[六省联考 2017] 分手是祝愿 - 洛谷

在题解区中全是某种奇怪的 DP 设计。所以这里来讲述一下利用本文中的方法求解的方法。

最开始的模型转化我们就省略了……

我们设 \(E_i\) 表示从剩下 \(i\) 个地方没有按下到全部按下的期望步数。

根据题目,我们有:

\[E_i = \frac in E_{i-1} + \frac {n-i}n E_{i+1} + 1 \]

并且由于最优限制:

\[i \le k \iff E_i = i \]

所以我们可以轻易的利用高斯消元求解……但是很明显,这是不现实的……考虑这个矩阵是一个稀疏矩阵,而且每一个方程是只与临近对角线的 3 个元素相关,所以我们可以轻易的将空间优化到 \(O(3n)\)

参考至知乎:# 数值线性代数|LU分解与稀疏矩阵

于是我们可以 旋转 一下,只存储非0的元素

接下来我们只需要参考 Guass-Jordan 消元法(先从上到下消下三角,再从下到上消上三角)。那么复杂度成功的也被我们降到了 \(O(n)\)。只是常数有点小大……


作者有话说

其实本文讲述的方法存在很大的局限性,尤其的求解的过程,很容易就变成了 \(O(n^3)\)

不过似乎建模的过程还是蛮简单的?

在求期望的问题中,这不失为一个思考的方向。有些时候,可以通过题目相关的特殊性质进行优化,使得复杂度降低。

可是毒瘤出题人们……还是看每道题的正解吧,或许终将有一天,这个方法可以被一种通法优化到 \(O(n^2)\) 呢?

与算法学习笔记(23): 马尔可夫链中的期望问题相似的内容:

算法学习笔记(23): 马尔可夫链中的期望问题

# 马尔可夫链中的期望问题 > 这个问题是我在做 [[ZJOI2013] 抛硬币 - 洛谷](https://www.luogu.com.cn/problem/P3334) 这道题的时候了解的一个概念。 > > 在网上也只找到了一篇相关的内容:[# 马尔可夫链中的期望问题](https://zhua

再谈23种设计模式(3):行为型模式(学习笔记)

行为型模式的关注点在于对象之间的通信和职责分配(描述结构模型中对象的动态特征)。行为型模式关注的是对象之间的交云和协作,即它们是如何相互作用的,以及如何分配职责和算法来完成任务。

VisionPro学习笔记(4)——PatInspect

如果需要了解其他图像处理的文章,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice VisionPro有很多的示例和算子,这里再展示一个最新出的算子Pat Inspect Tool。

算法学习笔记(6): 树链剖分

树链剖分 树链剖分是一个很神奇,但是在树上可以完成一些区间操作问题 简单来说,就是把一棵树分成一条条的链,通过维护链上的信息来维护整棵树的信息 基础知识可以参考我的另外一篇博客:算法学习笔记(5): 最近公共祖先(LCA) 这里假设你已经掌握了上述博客中的所有相关知识,并清晰了其背后的原理 性质?发

算法学习笔记(11): 原根

原根 此文相对困难,请读者酌情食用 在定义原根之前,我们先定义其他的一点东西 阶 通俗一点来说,对于 $a$ 在模 $p$ 意义下的阶就是 $a^x \equiv 1 \pmod p$ 的最小正整数解 $x$ 或者说,$a$ 在模 $p$ 意义下生成子群的阶(群的大小) 再或者说,是 $a$ 在模

算法学习笔记(30):Kruskal 重构树

Kruskal 重构树 这是一种用于处理与最大/最小边权相关的一个数据结构。 其与 kruskal 做最小生成树的过程是类似的,我们考虑其过程: 按边权排序,利用并查集维护连通性,进行合并。 如果我们在合并时,新建一个节点,其权值为当前处理的边的权值,并将合并的两个节点都连向新建的节点,那么就可以得

算法学习笔记(3.1): ST算法

ST表 在RMQ(区间最值)问题中,著名的ST算法就是倍增的产物。ST算法可以在 \(O(n \log n)\) 的时间复杂度能预处理后,以 \(O(1)\) 的复杂度在线回答区间 [l, r] 内的最值。 当然,ST表不支持动态修改,如果需要动态修改,线段树是一种良好的解决方案,是 \(O(n)\

C++算法之旅、09 力扣篇 | 常见面试笔试题(上)算法小白专用

算法学习笔记,记录容易忘记的知识点和难题。详解时空复杂度、50道常见面试笔试题,包括数组、单链表、栈、队列、字符串、哈希表、二叉树、递归、迭代、分治类型题目,均带思路与C++题解

C++算法之旅、08 基础篇 | 质数、约数

算法学习笔记,记录容易忘记的知识点和难题。试除法、分解质因数、筛质数、约数个数、约数之和、最大公约数

算法学习笔记(1): 欧几里得算法及其扩展

扩展欧几里得算法详解 在了解扩欧之前我们应该先了解欧几里得算法 欧几里得算法 这是一个递归求最大公约数(greatest common divisor)的方法 $$ gcd(a, b) = gcd(b, a % b) $$ 可以通过一个类似的简单公式推导而来 好像叫做辗转相减法来着? $$ gcd(