关于Prim算法为什么一定能得出最小生成树的一些理解

        在学习图的最小生成树时,关于构建最小生成树的算法,一开始书上是鼓励读者自己先进行思考,然而由于本人天赋实在一般,在散步过程中思考了一个多小时无果后,无奈只能学习经典的Prim算法。

        由于书上没有严谨的证明过程,在自行阅读了Prim算法的内容之后,我对为什么通过每次寻找当前情况下最小权值的边就一定能够得到最小生成树产生了一些疑问。以下是我自己对于通过Prim算法能够得到最小生成树证明的一些理解与思考。

一种比较简单粗暴的理解

        由于N个节点的最小生成树,仅能包含原来的连通图中的N-1条边,因此每次都选择最小权值的边,理论上好像确实应该能够实现最小生成树。但我一开始觉得这种说法并不足以充分证明,因为Prim算法是能够从任意一个节点开始进行的,如果节点和边较多的话,总感觉从相距较远的节点处开始进行求算,会得到不同的结果。

我个人可能稍微有一点道理的理解

        在简单粗暴的理解中,我认为的最大问题是从“任意一点开始的局部最优是否会通向同一个全局最优”。后来我换了一种思路,从结果来分析。最小生成树代表的含义,其实是“连接图中所有节点所需要的最小代价”,那么如果我在每一步中都能够保证连接当前已经被连接的所有节点所需要的代价是最小的,是不是就可以解决之前提出的问题了呢?

        回到Prim算法,首先作出如下的假定/声明如下事实:

对于连通图\small G = \(V, \{E\}\), 存在最小生成树\small T = \( V^{'}, \{ E^{'} \} \);

(这里先假定最小生成树是唯一的)

         由于图的最小生成树必须包含图中的所有节点,即\small V = V^{'},因此以任何一个节点为根开始建树,都可以导出T

        我首先将节点划分为了两个部分——连通域非连通域。算法的目标,则变为“以最小的代价,将所有节点加入连通域”

        初始可以随意选择一个节点(设为\small V_0),作为连通域中的第一个节点,从该节点(也就是连通域)出发,找出所有与连通域相连的路径,并选择其中权值最小的路径(设为\small \(V_0, V_1\)),该路径上对应的权值即为“将节点\small V_0\small V_1加入连通域所需要的最小代价”。依此法类推,可以将 \small V_0\small V_1(也就是连通域)看做是一个节点,在此基础上寻找与该节点相连的所有路径中权值最小的路径(假设为\small (V_0, V_2)),则将该路径上权值与之前累积的权值相加,即为“将节点\small V_0\small V_1\small V_2加入连通域所需要的最小代价”。使用这种方法,可以保证无论从哪个节点开始,每次向连通域中添加节点时,所得到的都是对于全局最优的结果,因而进行到最后,从任何一个节点开始的过程,得到的结果都是“将V中所有节点加入连通域中所需要的最小代价”,也就解决了一开始提出的问题。而以上所述的方法,正是Prim算法的求解过程。

         最后,以上的一些证明与思考,仅代表我个人的观点,可能也比较抽象,不符合严谨证明的规范,因此就当做是记录一下自己在学习算法时的所思所想吧。如果碰巧能够对你有所帮助的话,那便是极好的了。

你可能感兴趣的:(数据结构与算法,算法)