深度學習普里姆演算法(Prim)

2021-10-05 01:47:33 字數 3716 閱讀 4625

如果你對資料結構了解不深,又想要學習普里姆演算法,建議你看看我這篇,我盡量往細緻的方向寫,如果有些大佬認為我寫的比較囉嗦,請見諒,畢竟我的目的是為了讓資料結構小白能夠在理解普里姆演算法上相對容易一些。由於為了清楚地說明普里姆演算法,可能會犧牲一些嚴謹性,但只講嚴謹的術語會加大理解難度,尤其對於非科班出身的人。如遇大佬,請勿噴。
我個人學習圖結構已經有相當長一段時間了,圖這塊對於初學者來說真的相當難學,建議在學習資料結構之前先修計算機數學或者離散數學。我學習資料機構是為了畢業設計服務,本身並非計算機出身,學起來有難度。主要是為路徑規劃服務。非科班出身可以參考一下我的學習經驗。
由於要詳解,全文的內容可能會比較長,先做個提綱,可以從自己需要的部分看下去,不過建議從頭看。
圖結構的必要了解知識

普里姆演算法簡介

演算法詳解

總結

普里姆演算法是用來解決求圖的最小生成樹的經典演算法。即求連通圖的n個頂點的n-1條邊的權值之和最小。使用這個演算法有個稱之為mst的性質,首先假設實際網n(帶權圖)是乙個連通網(從圖的任意乙個頂點出發,都能到達其他的頂點),對於網n,已經找到的最小生成樹的頂點必然是最終的最小生成樹的頂點,說簡單一點,就是你已經找到頂點v3是當前的最小生成樹的頂點,這個點你可以不用找了,放心大膽地找其餘的點,不會有更優的路徑。這一點詳見嚴蔚敏老師《資料結構》。如果你對圖結構有一定了解但不熟悉,從這裡開始看。

關於普里姆演算法的流程。它的大致步驟如下:

2、從找到的這個頂點開始,用之前的頂點的邊權值修正這個頂點的邊權值,取兩者之中最小的。

3、從修正後的頂點中繼續找最小權值的邊,儲存頂點和邊到最小生成樹的點集和邊集中。

4、重複步驟2,3,直到最小生成樹的頂點集達到圖的頂點數停止。

普里姆演算法本質上是圖的遍歷和求最小值。但它既不是深度優先演算法,也不是廣度優先演算法,結合例項會理解的更深刻一些。

有了前面的鋪墊,再繼續講會更容易理解一些,如果你已經學習過圖結構,但是對於普里姆演算法又不是很理解,很會用。建議從這裡開始看起。
鄰接矩陣

對下面的**做入下解釋

∞–inf;

由於本例中的圖是無向圖,它的鄰接矩陣是對稱陣,所以可以輸入其中一半,另一半直接賦值。對於稀疏圖,可以採用把鄰接矩陣的所有元素都賦值為inf,然後把相互連通的頂點的邊權值賦值。lowcost陣列存放當前正在搜尋的邊權值,adjvex陣列存放已經找到的最小生成樹頂點。

**的主要流程

將lowcost陣列初始化為圖的與第乙個頂點v0相關聯的邊的權值,將第乙個頂點v0納入最小生成樹的頂點,這個點對應的列權值以後不再搜尋;

搜尋lowcost陣列中的最小值(v1),記下最小值的標號給k(1),這個點將作為找到變的終點(後繼)以後的lowcost的第0和1個元素不在搜尋(置0),做記號,而搜尋其餘的元素2,3,…,8;

更新lowcost,把和新找到的這個頂點(v1)相關聯的邊的權值(0,1不再參與搜尋)和lowcost陣列的對應元素作比較,找出更小的權值,儲存在lowcost中,從圖中來看就是,從已經找到的頂點(v0,v1)向下搜尋,找最小值,如果乙個頂點和兩個已經找出的頂點都相連通,那麼取兩條邊權值較小的那乙個。並把k對應的值作為找到的邊的起點(前驅)。

重複2,3過程,直到所有的頂點都被遍歷,即所有的lowcost都被置0;

在這裡對比較難細節性的問題再做一下說明。主要是第二個for迴圈那裡,他做了兩件事,一是用找到的這乙個新的頂點(k)的這一頂點的所有邊去更新lowcost。如果你願意的話,你可以用普里姆演算法的流程在人腦裡執行這個過程。舉個例子,在我們已經找到v0,v1之後的下一步,你要查詢和v0,v1相關聯的邊,這個更新的過程對人來說的流程是先從v0找起,找到和它相關聯的邊,再找v1。但對於計算機來說就不是這樣,它不管你是v0還是v1,把v0和v1的值都比較一番,誰小就取誰,顯然(v0,v5)小,不僅如此,每次把比較之後修改的值也做上記號,好知道他是來自**的資料,比如,經過比較,發現(v1,v2)小,把它的頂點資訊記在adjvex[2](1)裡面,作為前驅。人和計算機的邏輯差別有點像兩種招人方式,有的單位招人看學校和成績,有的公司看能力,不管你的學校和學歷,只要你幹得好,初中我都要。

總結一下,普里姆演算法就幹了三件事。第一,更新lowcost,始終都把當前能找到的最小路徑放在裡面,而且記下被修改的資料的頂點資訊,以方便後面找它的根(前驅);第二,在更新後的lowcost中搜尋最小值,儲存編號到k中,這是下乙個要更新的頂點序列的編號(後繼);第三,有前驅有後繼,把這條路徑列印出來。

**入下

#include

#define inf 65535

#define max 10

/*定義圖結構體*/

typedef

struct

mgraph;

/*圖的初始化,頂點數,鄰接矩陣*/

void

graphiint

(mgraph *g)

printf

("\n");

}/*除錯輸出用*/

for(i =

0; i < g->numvertex; i++

)printf

("\n");

}/*除錯輸出用*/

}/*普里姆演算法最小生成樹*/

void

minispantree_prim

(mgraph g)

/*prim真正核心*/

for(i =

1; i < g.numvertex; i++

)

j++;}

/*列印路徑邊 */

printf

("(%d,%d)"

, adjvex[k]

, k)

; lowcost[k]=0

;/*更新lowcost陣列*/

for(j =

1; j < g.numvertex; j++)}

}}intmain

(void);

//建立圖

graphiint

(&g)

;//圖的初始化

minispantree_prim

(g);

//普里姆最小生成樹

return0;

}

程式執行結果

為什麼我要花這麼多的筆墨說明普里姆演算法呢,第一它確有實際的工程應用,第二,後面要介紹的迪傑斯特拉演算法(最短路徑演算法)和它有密切聯絡。

普里姆演算法算是資料結構中比較讓人費解的演算法之一了花費了我很長時間理解,這裡把我遇到的問題和我的思考和大家分享一下,我個人不是很提倡老師上課的那一套,就是預設我講的你都會,對於某些細節問題不展開講,靠自己理解,這當然無可厚非,但是對於工程實踐來說,沒有細節是不行的,最多就是搬運工,所以我盡可能細緻地往下講,裡面可能會有一些表述上的問題,但是只要你理解了,我想這些描述上的問題對你來說就不是問題。

寫這篇文章真的很不容易,中間電腦還斷網了,有一段沒有儲存上,重寫的,覺得好的話,厚著臉求個贊。

參考文獻

程杰. 大話資料結構.[m]. 北京:清華大學出版社,2011.

嚴蔚敏,吳偉民.資料結構:c語言版[m]. 北京:清華大學出版 社,2007.

普里姆(Prim)演算法

普里姆 prim 演算法 網類 template class netgraph 析構函式 void print 列印鄰接矩陣 void minispantree prim prim演算法生成最小生成樹 獲取資料el在頂點表中的位置 template int netgraph getposition ...

普里姆Prim演算法介紹

普里姆 prim 演算法,和克魯斯卡爾演算法一樣,是用來求加權連通圖的最小生成樹的演算法。基本思想 對於圖g而言,v是所有頂點的集合 現在,設定兩個新的集合u和t,其中u用於存放g的最小生成樹中的頂點,t存放g的最小生成樹中的邊。從所有u u,v v u v u表示出去u的所有頂點 的邊中選取權值最...

演算法之 普里姆(Prim)演算法

普里姆演算法 prim s algorithm 是圖中的一種演算法,可在加權連通圖中搜尋最小生成樹。該演算法的作用就是根據圖中權值找到連線所有頂點的最短路徑,也就是連線所有頂點的最小權值之和,也是這個加權圖中的最小生成樹。1.選取權值最小邊的其中乙個頂點作為起始點。2.找到離當前頂點權值最小的邊,並...