普利姆算法通俗講解

 

文章作者:duguyue100

今天就來討論一下貪心法中另一個解決最小生成樹的算法:prim算法。在解決最小生成樹的算法中,prim算法應該是最優的了,時間複雜是O(n² ㏒n)。下面我們來了解一下算法的運作原理。    在prim算法中,最小生成樹是一步步建立起來的,他不同於kruskal算法的方面就是kruskal算法剛開始構造的時候是支離破碎的線連接起來的,而prim算法則是一步一步拓展來的。剛開始的時候,令一個無向圖中的任意點(以下稱x)作爲起點。然後遍歷與x連同的所有點,找出最小的點並併入最小生成樹的集合中,這樣一步一步,直到把圖中所有的點都併入生成樹的集合中,而他們權值的和,也就是最小的了。另外,再你每次把一條邊並上之後,你要考慮的不只是這一條邊的聯通的邊,而是把他們當做一個整體,將所有點除了已經連接上的邊外剩下所有的邊中選擇一個最小的。這但最重要,因爲樹結構不是一條線,而是一個真正的樹一樣的形狀。
   我們先不給出爲什麼這樣做就是正確的證明。我們知道,對於一個無向圖,他的最小生成樹有可能只有1棵,也有可能是很多棵,我們的算法只是要找到其中一種,也就是說我們並不關心到底有多少最小生成樹,所以我們應該允許結果有不一樣的時候,比如對於一個圖,分別用kruskal和prim算法得到了不同的最小生成樹,但只要兩個權值是一樣的,那麼我們就可以說我們得到的都是正確結果。
   好的,我們來具體從圖上看一下prim算法到底是怎麼運作的。我們選用的圖還是上次講kruskal算法的時候用的那個圖,如下:


prim算法運作圖,假定B點是初始點,過程如下:

怎麼?不相信有這麼神奇?那麼你自己動手試一下用C作爲起始點看看。
那麼怎麼實現呢?我們下面給出算法過程:
首先是一個帶權連通的無向圖G=(V,E)。輸出的時候是圖G的一棵最小生成樹:
第一步:令x是V中任意頂點,令X={x},Y=V-{x};//最小生成樹根的初始化
第二步:從E中選擇一條邊(u,v),使得u∈X,v∈Y,並且(u,v)是頂點集X與Y之間的邊中權值最小的;//構造生成樹規則
第三步:將u連接到v,令X=X∪{v},Y=Y∪{v};//刪去已經加入的邊,這一步千萬不能忘
第四步:如果Y是空的,那麼終止,那麼產生的樹是最小生成樹;否則,返回第二步;//如果是空的,就表明已經生成完畢,因爲Y中保存着圖一共有多少個頂點,但是我們不要驗證集合X,因爲我們難以統計圖中一共有多少個頂點。如果不是空的,那麼回到第二步,繼續構造生成樹,在這裏,建議利用相當於PASCAL中的repeat循環。因爲既然是帶權連通無向圖,一定有2個以上點,所以一定要至少執行一次才能看出生成樹到底是什麼。
好了,至於prim算法的證明,我在這裏就不多講了。因爲大家先要理解了這個算法是怎麼運作的,在總結完貪心法的一些算法之後,我會發出一個證明的總彙,因爲數學的東西講多了,雖然能幫助我們從根上了結一個算法的實現,但是講了這麼多,我覺得大家一定很暈,先掌握了。理解是以後的事情。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章