程式目錄結構
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.選擇一出...