prim演算法與kruskal演算法學習與分析

2021-10-10 12:42:05 字數 3850 閱讀 8509

程式目錄結構

densegraph.h是鄰接矩陣的類

edge.h是邊的類,成員有兩個端點與邊的權重

kruskal是實現kruskal的類

lazyprimmst是惰性prim演算法的類

primmst是prim演算法的類

minheap是最小堆的類,用於實現獲取最小邊

indexminheap是最小索引堆的類,用於實現獲取最小邊,並且淘汰不需要的邊

unionfind5是並查集的類,用於判環

思想:每次選出與選中點的集合相連的最短的邊,並將其所連的點加入選中點的集合

核心**

#ifndef inc_03_lazy_prim_lazyprimmst_h

#define inc_03_lazy_prim_lazyprimmst_h

#include #include #include #include "edge.h"

#include "minheap.h"

using namespace std;

// 使用prim演算法求圖的最小生成樹

templateclass lazyprimmst

}public:

lazyprimmst(graph &graph):g(graph),pq(minheap>(graph.e()))

mst.push_back(e);

if(!marked[e.v()])

else

}mstweight = mst[0].wt();

for(int i=1; i> mstedges()

weight result()

};#endif

lazyprim的問題當乙個未選中的點與已選中的點的集合有多條邊相連時,會將所有的邊都加入最小堆中,雖然當每次取出時取出最小的邊,並跳過兩端都被選中的邊,這樣可以保證結果正確,但與此同時也使每次的堆排操作產生不必要的耗時,複雜度為o(eloge).e為邊數思路:利用最小索引堆,在插入最小堆時只是儲存未選點與已選點集合之間的最短邊,將複雜度降為o(elo**),v為點數

核心**

#ifndef inc_05_implementation_of_optimized_prim_algorithm_primmst_h

#define inc_05_implementation_of_optimized_prim_algorithm_primmst_h

#include #include #include #include "edge.h"

#include "indexminheap.h"

using namespace std;

// 使用優化的prim演算法求圖的最小生成樹

templateclass primmst

else if(e->wt() < edgeto[w]->wt())}}

}public:

primmst(graph &graph):g(graph),ipq(indexminheap(graph.v()))

weight result()

};#endif // inc_05_implementation_of_optimized_prim_algorithm_primmst_h

思路:每次找出圖中最短且不成環的邊

核心**

#ifndef inc_03_kruskal_h

#define inc_03_kruskal_h

#include #include #include #include "edge.h"

#include "minheap.h"

#include "unionfind5.h"

using namespace std;

// kruskal演算法

template class kruskalmst

// 建立乙個並查集, 來檢視已經訪問的節點的聯通情況

unionfind uf = unionfind(graph.v());

while(!pq.isempty()&&mst.size()e = pq.extractmin();

//利用判斷根節點是否相同來判斷是否成環

if(uf.isconnected(e.v(),e.w()))

continue;

mst.push_back(e);

//連線兩個點

uf.unionelements(e.v(),e.w());

}mstweight = mst[0].wt();

for( int i = 1 ; i < mst.size() ; i ++ )

mstweight += mst[i].wt();

}~kruskalmst()

// 返回最小生成樹的所有邊

vector> mstedges();

// 返回最小生成樹的權值

weight result();

};#endif

主程式

迴圈生成節點數為100到2000的全通圖

#include #include #include#include "densegraph.h"

#include "readergraph.h"

#include "lazyprimmst.h"

#include "primmst.h"

#include "kruskal.h"

#includeusing namespace std;

// 測試有權圖和有權圖的讀取

int main()

{ string filename = "testg1.txt";

double starttime,endtime;

double time1 = 0.0;

for(int v = 100; v<=2000; v+=100)

{densegraphg1 = densegraph(v, false,true);

//// // test lazy prim mst

cout< lazyprimmst1(g1);

endtime=clock();

time1=double(endtime - starttime)/clocks_per_sec;

cout primmst(g1);

endtime=clock();

time1=double(endtime - starttime)/clocks_per_sec;

// out kruskalmst(g1);

endtime=clock();

time1=double(endtime - starttime)/clocks_per_sec;

// out結果

無論是prim演算法還是kruskal演算法都是將尋找最小生成樹的方法差分為每次尋找最短邊的方法,獲得區域性最優解,最後構成最小樹。

最小生成樹 Prim演算法與Kruskal演算法

乙個連通圖的生成樹是乙個極小的連通子圖,包含有圖中全部的頂點,但只有足以構成一棵樹的n 1條邊。我們把構造連通網的最小代價生成樹稱為最小生成樹 mi nimu mcos tspa nnin gtre e minimum cost spanning tree minim umco stsp anni ...

Prim演算法 Kruskal演算法

一 prim演算法 1 要求 1 生成一顆連通的樹 2 生成樹 包含全部頂點,v 1條邊,沒有迴路,並且新增一條邊會變成有迴路 3 權重和最小 2 過程模擬 最重要 貪心的思想,每一步都要選擇權值最小的,這棵樹所有跟頂點相連的邊中最小的。從根節點開始,讓樹慢慢的長大。過程 從v1開始 跟v1有聯絡的...

Prim演算法 Kruskal演算法

prim演算法 kruskal演算法 prim演算法和kruskal演算法,都是用來找出圖中最小生成樹的演算法,兩個演算法有些小差別。prim演算法 又稱普里姆演算法,以圖上的頂點為出發點,逐次選擇到最小生成樹頂點集距離最短的頂點為最小生成樹的頂點,並加入到該頂點集,直到包含所有的頂點。1.選擇一出...