Dijkstra算法是一种用于解决带权重有向图中单源最短路径问题的算法。本文给出了Dijkstra算法的正确性证明。
问题陈述
给定一个有向图G=(V, E),其中V表示节点集合,E表示边集合,每条边e∈E有一个非负的权重w(e),以及一个指定的起始节点s∈V。问题是找到从起始节点s到图中每个其他节点v∈V的最短路径。
Dijkstra算法的步骤
- 初始化:将起始节点s的距离标签设置为0,将所有其他节点的距离标签初始化为无穷大。创建一个空的优先队列Q来存储待处理的节点。
- 迭代:重复以下步骤直到队列Q为空:
a. 从队列Q中选择具有最小距离标签的节点u。
b. 对于u的每个相邻节点v,计算从s经过u到v的路径的总权重d(s, u) + w(u, v)。
c. 如果d(s, u) + w(u, v)小于v的当前距离标签,更新v的距离标签为d(s, u) + w(u,v)。 - 终止:当队列Q为空时,算法结束。
正确性证明
我们将通过归纳法证明Dijkstra算法的正确性。证明分为以下两部分:
性质1: 在Dijkstra算法的每一轮迭代之后,对于每个节点v∈V,v的距离标签d(s, v)等于从s到v的最短路径的权重。
性质2: 当算法终止时,所有节点的距离标签都等于从s到每个节点的最短路径的权重。
证明:
基础情形: 在算法的初始状态,只有起始节点s的距离标签被初始化为0,其他节点的距离标签为无穷大。性质1和性质2显然成立,因为没有其他节点的距离标签需要比现有的更短的路径。
归纳步骤:
我们假设在算法的第k轮迭代之后,性质1和性质2均成立。我们要证明在第k+1轮迭代之后,这两个性质仍然成立。
- 对于性质1,假设在第k轮迭代之后,所有节点的距离标签d(s, v)等于从s到v的最短路径的权重。在第k+1轮迭代中,我们选择一个距离标签最小的节点u。由于性质1的假设,d(s, u) 等于从s到u的最短路径的权重。然后,对于u的每个相邻节点v,我们计算从s经过u到v的路径的总权重 d(s, u) + w(u, v)。如果这个总权重小于v的当前距离标签d(s, v),我们更新v的距离标签为d(s, u) + w(u, v)。这确保了性质1在第k+1轮迭代之后仍然成立。
- 对于性质2,我们需要证明在算法终止时,所有节点的距离标签等于从s到每个节点的最短路径的权重。当队列Q为空时,我们已经处理了所有节点,所以没有更短的路径可以更新距离标签。因此,性质2在算法终止时成立。
通过归纳法证明,我们可以得出Dijkstra算法的正确性。算法保证了在每一轮迭代后,距离标签d(s, v)等于从s到v的最短路径的权重,最终,当算法终止时,所有节点的距离标签都等于从s到每个节点的最短路径的权重。这意味着Dijkstra算法成功找到了从起始节点s到图中每个其他节点的最短路径。