1. 程式人生 > >Kruskal演算法計算最小生成樹(java)

Kruskal演算法計算最小生成樹(java)

最小生成樹定義:
每一個無向圖可拆分成多個子圖,在這些子圖中,如果圖的各個頂點沒有形成迴路,則是圖的一顆生成樹。
最小生成樹的意識是樹的相鄰節點距離之和最小。

應用場景:
張三被選為他們鎮的鎮長!他其中一個競選承諾就是在鎮上建立起網際網路,並連線到所有的農場。
張三已經給他的農場安排了一條高速的網路線路,他想把這條線路共享給其他農場。為了用最小的消費,他想鋪設最短的光纖去連線所有的農場,問要如何實現。

演算法實現:
有關最小生成樹的問題常見的演算法有兩種,分別是Kruskal(克魯斯卡爾)演算法和Prim(普里姆)演算法,本文講解Kruskal演算法的實現

Kruskal演算法的計算流程大致如下:
1.將無向圖的邊按距離長短遞增式排序,放到集合中
2.遍歷該集合,找出最短的邊,加入到結果生成樹的集合中
3.如果結果生成樹出現迴路,則放棄這條邊
4.重新執行步驟2,直至所有頂點被遍歷
可以看出在每次遍歷過程中採用了貪心演算法

演算法例項圖:


程式碼實現:
Edge類用與封裝無向圖中每條邊的資訊
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);
	}
}
MapBuilder類用於構建資料來源(資料來源結構如上圖所示):
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;
	}
}
Kruskal類用於計算最小生成樹
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)是