Kruskal演算法計算最小生成樹(java)
每一個無向圖可拆分成多個子圖,在這些子圖中,如果圖的各個頂點沒有形成迴路,則是圖的一顆生成樹。
最小生成樹的意識是樹的相鄰節點距離之和最小。
應用場景:
張三被選為他們鎮的鎮長!他其中一個競選承諾就是在鎮上建立起網際網路,並連線到所有的農場。
張三已經給他的農場安排了一條高速的網路線路,他想把這條線路共享給其他農場。為了用最小的消費,他想鋪設最短的光纖去連線所有的農場,問要如何實現。
演算法實現:
有關最小生成樹的問題常見的演算法有兩種,分別是Kruskal(克魯斯卡爾)演算法和Prim(普里姆)演算法,本文講解Kruskal演算法的實現
Kruskal演算法的計算流程大致如下:
1.將無向圖的邊按距離長短遞增式排序,放到集合中
2.遍歷該集合,找出最短的邊,加入到結果生成樹的集合中
3.如果結果生成樹出現迴路,則放棄這條邊
4.重新執行步驟2,直至所有頂點被遍歷
可以看出在每次遍歷過程中採用了貪心演算法
演算法例項圖:
程式碼實現:
Edge類用與封裝無向圖中每條邊的資訊
MapBuilder類用於構建資料來源(資料來源結構如上圖所示):public class Edge implements Comparable<Edge>{ private String start; private String end; private int distance; public Edge(String start,String end,int distance){ this.start=start; this.end=end; this.distance=distance; } public String getStart() { return start; } public void setStart(String start) { this.start = start; } public String getEnd() { return end; } public void setEnd(String end) { this.end = end; } public int getDistance() { return distance; } public void setDistance(int distance) { this.distance = distance; } @Override public String toString() { return start + "->" + end; } @Override public int compareTo(Edge obj) { int targetDis=obj.getDistance(); return distance>targetDis?1:(distance==targetDis?0:-1); } }
Kruskal類用於計算最小生成樹public class MapBuilder { public TreeSet<Edge> build(){ TreeSet<Edge> edges=new TreeSet<Edge>(); edges.add(new Edge("A","B",1)); edges.add(new Edge("A","C",4)); edges.add(new Edge("A","F",6)); edges.add(new Edge("B","D",8)); edges.add(new Edge("B","E",3)); edges.add(new Edge("C","F",5)); edges.add(new Edge("C","E",9)); edges.add(new Edge("D","E",7)); edges.add(new Edge("D","F",10)); edges.add(new Edge("E","F",2)); return edges; } public int getPointNum(){ return 6; } }
public class Kruskal {
private Set<String> points=new HashSet<String>();
private List<Edge> treeEdges=new ArrayList<Edge>();
public void buildTree(){
MapBuilder builder=new MapBuilder();
TreeSet<Edge> edges=builder.build();
int pointNum=builder.getPointNum();
for(Edge edge:edges){
if(isCircle(edge)){
continue;
}else{//沒有出現迴路,將這條邊加入treeEdges集合
treeEdges.add(edge);
//如果邊數等於定點數-1,則遍歷結束
if(treeEdges.size()==pointNum-1){
return;
}
}
}
}
public void printTreeInfo(){
int totalDistance=0;
for(Edge edge:treeEdges){
totalDistance+=edge.getDistance();
System.out.println(edge.toString());
}
System.out.println("總路徑長度:"+totalDistance);
}
private boolean isCircle(Edge edge){
int size=points.size();
if(!points.contains(edge.getStart())){
size++;
}
if(!points.contains(edge.getEnd())){
size++;
}
if(size==treeEdges.size()+1){
return true;
}else{
points.add(edge.getStart());
points.add(edge.getEnd());
return false;
}
}
}
Main類用於測試Kruskal演算法public class Main {
public static void main(String[] args) {
Kruskal test=new Kruskal();
test.buildTree();
test.printTreeInfo();
}
}
列印輸出:A->B
E->F
B->E
A->C
D->E
總路徑長度:17
相關推薦
Kruskal演算法計算最小生成樹(java)
最小生成樹定義: 每一個無向圖可拆分成多個子圖,在這些子圖中,如果圖的各個頂點沒有形成迴路,則是圖的一顆生成樹。 最小生成樹的意識是樹的相鄰節點距離之和最小。 應用場景: 張三被選為他們鎮的鎮長!他其中一個競選承諾就是在鎮上建立起網際網路,並連線到所有的農場。 張三已經給他
Kruskal演算法實現最小生成樹MST(java)
Kruskal演算法用於生成圖的最小生成樹MST,不多說下面直接進入主題! 一、實現Kruskal演算法需要會的資料結構知識 1、最小堆:包括最小堆的初始化、插入和刪除操作 最小堆的作用:每次從邊的集合中選出權重最小的邊,將其加入到MST中(當然此邊當和M
Kruskal演算法實現最小生成樹(鄰接矩陣儲存圖)
程式碼如下: #include <stdio.h> #include <stdlib.h> #define MAXSIZE 100 typedef struct { int u; int v; int w; }Edges; void Bubblesort(
Project-2: Prim 和 Kruskal 演算法尋找最小生成樹
Prim 和 Kruskal 演算法尋找最小生成樹 實驗原理 堆 堆是一種經過排序的完全二叉樹,其中任一非終端節點的資料值均不大於(或不小於)其左子節點和右子節點的值。最大堆和最小堆是二叉堆的兩種形式。最大堆:根結點的鍵值是所有堆結點鍵值中最大者。最小堆:
Prim演算法和Kruskal演算法(最小生成樹)
Prim演算法 1.概覽 普里姆演算法(Prim演算法),圖論中的一種演算法,可在加權連通圖裡搜尋最小生成樹。意即由此演算法搜尋到的邊子集所構成的樹中,不但包括了連通圖裡的所有頂點(英語:Vertex (graph theory)),且其所有邊的權值之和亦為最小。該演算法於1930年由捷克數學家沃伊捷赫·
Kruskal演算法求最小生成樹-演算法設計與分析實驗3
題目: 求如圖所示,用kruskal演算法求下面圖的最小生成樹: 話不多說,程式如下: #include<iostream> #include<stdlib.h> #define N 7 using namespace std; typedef
利用Kruskal演算法求最小生成樹解決聰明的猴子問題 -- 資料結構
題目:聰明的猴子 連結:https://ac.nowcoder.com/acm/problem/19964 在一個熱帶雨林中生存著一群猴子,它們以樹上的果子為生。昨天下了一場大雨,現在雨過天晴,但整個雨林的地 表還是被大水淹沒著,部分植物的樹冠露在水面上。猴子不會游泳,但跳躍能力比
(Java資料結構和演算法)最小生成樹---Kruskal演算法(並查集)
該文章利用prime演算法求得連通圖的最小生成樹對應的邊權最小和,prime演算法是從頂點的角度思考和解決問題。本文介紹的Kruskal演算法將從邊的角度考慮並解決問題,利用了並查集方便地解決了最小生成樹的問題。 本文參考博文 //並查集 class UnionSameSet{
(Java資料結構和演算法)最小生成樹---prime演算法
參考博文 public class Main { public static void main(String[] args){ int inf = 1000000;//無窮大 //圖,可以這樣認為:圖的任意兩個頂點之間都有邊,兩頂點無法到達的,可以認為他們之間的邊權是
【最小生成樹】Prim 普里姆演算法,Kruskal 克魯斯卡爾演算法生成 最小生成樹
1.Analyse 來自兩位科學家。 生成最小生成樹,從0頂點出發,最小生成樹包含所以頂點>_<,這個作業難道好像就是似乎改個矩陣? 最好還是把最小生成樹變成一條路線,這樣就不用去,自己找路線了。 題目圖如圖 2.源自老師的Code Print 1Prim
【NOJ1596、1597】【貪心演算法之最小生成樹】最少修建多長的公路能把所有村莊連起來(圖示Prim與Kruskal演算法)
1596.最少修建多長的公路能把所有村莊連起來(一) 時限:1000ms 記憶體限制:10000K 總時限:3000ms 描述 一個地區有n個村莊,有一些村子之間可以修路,已知每條路的長度,問最少修建多長的公路可以把所有的村子連線起來。 輸入 先輸入兩個正整數n,
克魯斯卡爾(Kruskal)演算法求最小生成樹
1、基本思想:設無向連通網為G=(V, E),令G的最小生成樹為T=(U, TE),其初態為U=V,TE={ },然後,按照邊的權值由小到大的順序,考察G的邊集E中的各條邊。若被考察的邊的兩個頂點屬於T的兩個不同的連通分量,則將此邊作為最小生成樹的邊加入到T中,同時把兩個連通分
演算法導論--最小生成樹(Kruskal和Prim演算法)
關於圖的幾個概念定義: 連通圖:在無向圖中,若任意兩個頂點vi與vj都有路徑相通,則稱該無向圖為連通圖。 強連通圖:在有向圖中,若任意兩個頂點vi與vj都有路徑相通,則稱該有向圖為強連通圖。 連通網:在連通圖中,若圖的邊具有一定的意義,每一條邊都對應
例題:最短網路 圖論演算法之最小生成樹 prim//kruskal 學習筆記
圖論演算法之最小生成樹 prim//kruskal 最小生成樹簡單的說就是在一個圖裡選取一些邊,使這些邊以及它們所連線的結點組成一棵樹(兩兩結點之間可以到達),並且使選取的邊的邊權最
克魯斯卡爾演算法(Kruskal)圖的最小生成樹
演算法競賽中常用的演算法,求圖的最小生成樹 過程: 對邊集排序, 選取最小邊,將連線的節點放到一個集合中 選取次小的邊,當邊連線的定點不在同一個集合中時,合併集合。 #include<c
Prim演算法求解最小生成樹的Java實現
上一篇既然提到了Krusal演算法,這裡就不得不說Prim演算法了,這兩個演算法都是求解最小生成樹的經典的貪婪演算法。與Krusal演算法不同的是,Prim演算法在求解過程中始終保持臨時結果是一顆聯通的樹。該演算法的虛擬碼如下 //假設網路中至少有一個個頂點 設T為所選邊的
大話資料結構--圖的最小生成樹-java實現
普利姆(Prim)演算法 最小生成樹 * A * / | \ * B- -F- -E * \ / \ / * C -- D * A B C D E F * 0 1 2 3 4 5 * * A-B 6 A-
Prim演算法實現最小生成樹(鄰接矩陣儲存圖)
程式碼如下 #include <stdio.h> #include <stdlib.h> #define MAXSIZE 100 typedef struct { int vertex[MAXSIZE]; int edges[MAXSIZE][MAXSIZE];
資料結構--C語言--圖的深度優先遍歷,廣度優先遍歷,拓撲排序,用prime演算法實現最小生成樹,用迪傑斯特拉演算法實現關鍵路徑和關鍵活動的求解,最短路徑
實驗七 圖的深度優先遍歷(選做,驗證性實驗,4學時) 實驗目的 熟悉圖的陣列表示法和鄰接表儲存結構,掌握構造有向圖、無向圖的演算法 ,在掌握以上知識的基礎上,熟悉圖的深度優先遍歷演算法,並實現。 實驗內容 (1)圖的陣列表示法定義及
演算法之最小生成樹
1. 問題描述:利用貪心演算法設計策略構造一個無向連通帶權圖的最小生成樹。 最小生成樹:設G=(V,E)是無向連通帶權圖,即一個網路。E中每條邊(v,w)的權為c[v][w]。包含G所有頂點的樹且該生成樹各邊權的總和最小(即耗費最小),則稱該生成樹為G的最小生成樹。 設G=(V,E)是