日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

实验1 最小生成树问题【Kruskal+Prim】

發布時間:2024/10/5 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实验1 最小生成树问题【Kruskal+Prim】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.貪心算法思想

貪心算法的基本思想是找出整體當中每個小的局部的最優解,并且將所有的這些局部最優解合起來形成整體上的一個最優解。因此能夠使用貪心算法的問題必須滿足下面的兩個性質:

  • 1.整體的最優解可以通過局部的最優解來求出;
  • 2.一個整體能夠被分為多個局部,并且這些局部都能夠求出最優解。

2.貪心算法的基本策略 :

1、從問題的某個初始解出發。
2、采用循環語句,當可以向求解目標前進一步時,就根據局部最優策略,得到一個部分解,縮小問題的范圍或規模。
3、將所有部分解綜合起來,得到問題的最終解。

(2-1)Kruskal算法

  • 將所有邊按照權值的大小進行升序排序,然后從小到大一一判斷,條件為:如果這個邊不會與之前選擇的所有邊組成回路,就可以作為最小生成樹的一部分;反之,舍去。直到具有 n 個頂點的連通網篩選出來 n-1 條邊為止。篩選出來的邊和所有的頂點構成此連通網的最小生成樹。

(2-2)Prim算法

  • Prim算法從任意一個頂點開始,每次選擇一個與當前頂點集最近的一個頂點,并將兩頂點之間的邊加入到樹中。

3.數據結構
Prim算法:

  • a. 在一個加權連通圖中,頂點集合V,邊集合為E
  • b. 任意選出一個點作為初始頂點,標記為visit,計算所有與之相連接的點的距離,選擇距離最短的,標記visit.
  • c. 重復以下操作,直到所有點都被標記為visit:
    在剩下的點鐘,計算與已標記visit點距離最小的點,標記visit,證明加入了最小生成樹。

Kruskal算法

  • a.假定拓撲圖的邊的集合是E,初始化最小生成樹邊集合G={}。
  • b. 遍歷集合E中的所有元素,并且按照權值的大小進行排序。
  • c. 找出E中權值最小的邊e 。
  • d .如果邊e不和最小生成樹集合G中的邊構成環路,則將邊e加到邊集合G中;否則測試下一條權值次小的邊,直到滿足條件為止。
  • e. 重復步驟b,直到G=E。

4.數據模型

5.程序代碼
Kruskal算法Java代碼實現

public class Kruskal {public int edgeNums; //邊的數量public char[] data; //存儲結點public int[][] matrix; //鄰接矩陣存儲權重private static final int INF = Integer.MAX_VALUE; //表示結點不通public Kruskal(char[] data, int[][] matrix) {int length = data.length;this.data = new char[length];this.matrix = new int[length][length];for (int i = 0; i < length; i++) {this.data[i] = data[i];}for (int s = 0; s < length; s++) {for (int k = 0; k < length; k++) {this.matrix[s][k] = matrix[s][k];}}for (int m = 0; m < length; m++) {for (int n = m + 1; n < length; n++) {if (matrix[m][n] != INF) {this.edgeNums++;}}}}/*** 將遍歷鄰接矩陣將邊加入到Edge數組中** @return Edge數組*/public Edge[] getEdges() {int length = this.data.length;int index = 0;Edge[] edges = new Edge[this.edgeNums];for (int m = 0; m < length; m++) {for (int n = m + 1; n < length; n++) {if (matrix[m][n] != INF) {edges[index] = new Edge(data[m], data[n], matrix[m][n]);index++;}}}return edges;}/*** 對Edge數組進行排序** @param edges 數組引用*/public void sortEdges(Edge[] edges) {for (int k = 0; k < edges.length - 1; k++) {for (int s = 0; s < edges.length - k - 1; s++) {if (edges[s].weight > edges[s + 1].weight) {Edge temp = edges[s];edges[s] = edges[s + 1];edges[s + 1] = temp;}}}}/*** 克魯斯卡爾核心方法* 流程:* 1.將圖中的邊放到集合中* 2.邊排序 - 》 權重 T集合* 3.對T集合進行遍歷* T*/public void kruskal() {Edge[] edges = getEdges();sortEdges(edges);Edge[] result = new Edge[edgeNums];int[] ends = new int[edgeNums];int index = 0;for (int k = 0; k < edgeNums; k++) {int front = getPosition(edges[k].front);int after = getPosition(edges[k].after);int m = getEnd(ends, front);int n = getEnd(ends, after);if (m != n) {ends[m] = n;result[index++] = edges[k];}}System.out.println(Arrays.toString(result));}/*** 得到末尾的結點** @param ends 存儲* @param k 元素下標* @return 返回元素*/public int getEnd(int[] ends, int k) {while (ends[k] != 0) {k = ends[k];}return k;}/*** 獲取元素對于的下標** @param ch 待查詢字符* @return 下標*/private int getPosition(char ch) {for (int i = 0; i < data.length; i++) {if (data[i] == ch) {return i;}}return -1;}public void printMatrix() {System.out.println("二維矩陣列表為:");for (int[] cur : matrix) {System.out.println(Arrays.toString(cur));}System.out.println("邊的大小為:" + this.edgeNums);}/ /main測試public static void main(String[] args) {char[] vertex = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};int[][] matrix = {{0, 12, INF, INF, INF, 16, 14},{12, 9, 10, INF, INF, 7, INF},{INF, 10, 0, 3, 5, 6, INF},{INF, INF, 3, 0, 4, INF, INF},{INF, INF, 5, 4, 0, 2, 8},{16, 7, 6, INF, 2, 0, 9},{14, INF, INF, INF, 8, 9, 0}};Kruskal kruskal = new Kruskal(vertex, matrix);kruskal.printMatrix();kruskal.kruskal();} }class Edge {public char front;public char after;public int weight;public Edge(char front, char after, int weight) {this.front = front;this.after = after;this.weight = weight;}@Overridepublic String toString() {return "Edge{" +"front=" + front +", after=" + after +", weight=" + weight +'}';} }Prim算法Java代碼實現 public class Prim {public static void main(String[] args) {char[] data = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};int nodes = data.length;int[][] weight = {{10000, 5, 7, 10000, 10000, 10000, 2},{5, 10000, 10000, 9, 10000, 10000, 3},{7, 10000, 10000, 10000, 8, 10000, 10000},{10000, 9, 10000, 10000, 10000, 4, 10000},{10000, 10000, 8, 10000, 10000, 5, 4},{10000, 10000, 10000, 4, 5, 10000, 6},{2, 3, 10000, 10000, 4, 6, 10000},};MinTree minTree = new MinTree();Graph graph = new Graph(nodes);minTree.createGraph(nodes, data, weight, graph);minTree.showGraph(graph);minTree.prim(graph, 0);} }class MinTree {/*** 初始化無向圖* @param nodes 結點數* @param data 結點數組* @param weight 權重鄰接矩陣* @param graph 無向圖*/public void createGraph(int nodes, char[] data, int[][] weight, Graph graph) {int i, j;for (i = 0; i < nodes; i++) {graph.data[i] = data[i];for (j = 0; j < nodes; j++) {graph.weight[i][j] = weight[i][j];}}}/*** 最小生成樹問題* 1.給定一個無向連通圖,如果選取生成一棵樹,使得樹上所有的權總和最小,這就是最小生成樹* 2.給定n個結點,一定有n-1條邊* 兩種算法 1.普里姆算法 和 克魯斯卡爾算法* @param graph 鄰接圖* @param v 開始結點的下標** 1.創建V集合保存結點 --- 遍歷* 2.從某個結點出發, 每次取出 A E T*/public void prim(Graph graph, int v) {int x1 = -1, x2 = -1;int nodeNums = graph.nodes;int[] visited = new int[nodeNums];visited[v] = 1;int minWeight = 10000; //先自定義最大權重,后面替換for (int k = 1; k < nodeNums; k++) { //n個結點需要n-1條邊for (int al = 0; al < nodeNums; al++) { //已經標記的for (int not = 0; not < nodeNums; not++) { //未標記的if (visited[al] == 1 && visited[not] == 0 && graph.weight[al][not] < minWeight) {minWeight = graph.weight[al][not];x1 = al;x2 = not;}}}visited[x2] = 1;minWeight = 10000;System.out.println("邊<"+graph.data[x1]+"-"+graph.data[x2]+">"+"權值為:"+graph.weight[x1][x2]);}}//顯示鄰接矩陣public void showGraph(Graph graph) {for (int[] cur : graph.weight) {System.out.println(Arrays.toString(cur));}} }class Graph {protected int nodes; //結點的個數protected char[] data; //結點的數據protected int[][] weight; //結點的鄰接矩陣public Graph(int nodes) {this.nodes = nodes;data = new char[nodes];weight = new int[nodes][nodes];} }

6.測試
(1)Kruskal算法測試數據如下

(其中的INF表示兩頂點之間不通)

控制臺結果如下:

(2)Prim算法測試數據如下:

(1000表示兩個頂點不連通,也可也和上面的Kruskal算法一樣使用int的最大值65535表示)
控制臺結果如下:

7.結果分析:
Prim
通過鄰接矩陣圖表示的簡易實現中,找到所有最小權邊共需O(V)的運行時間。使用簡單的二叉堆與鄰接表來表示的話,普里姆算法的運行時間則可縮減為O(ElogV),其中E為連通圖的邊數,V為頂點數。如果使用較為復雜的斐波那契堆,則可將運行時間進一步縮短為O(E+VlogV),這在連通圖足夠密集時,可較顯著地提高運行速度

Kruskal
克魯斯卡爾算法的時間復雜度主要由排序方法決定,而克魯斯卡爾算法的排序方法只與網中邊的條數有關,而與網中頂點的個數無關,當使用時間復雜度為O(elog2e)的排序方法時,克魯斯卡爾算法的時間復雜度即為O(log2e),因此當網的頂點個數較多、而邊的條數較少時,使用克魯斯卡爾算法構造最小生成樹效果較好

總結

以上是生活随笔為你收集整理的实验1 最小生成树问题【Kruskal+Prim】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 九九热在线观看视频 | 欧美精品四区 | 三级性生活视频 | 嫩草一二三 | 国产专区视频 | 四虎精品 | 激情综合丁香五月 | 五月婷婷在线播放 | 美女性高潮视频 | 欧美日韩在线不卡 | 69精品人人人人 | 日本久久99 | 国内偷拍av | 亚洲综合国产 | 精品在线你懂的 | 日韩一区网站 | 在线免费视频一区二区 | 精品久久BBBBB精品人妻 | 国产日韩欧美综合在线 | 草草在线影院 | 久草中文在线观看 | 噜噜噜噜私人影院 | www.亚洲激情 | 亚洲涩涩视频 | 91极品视频 | 亚洲国产日韩精品 | 欧美精品 在线观看 | 久久99一区二区 | 女人洗澡一级特黄毛片 | 在线观看欧美一区 | 制服丝袜av电影 | 精品人妻人人做人人爽夜夜爽 | 看一级片 | 国产视频一区二区在线 | 国产69精品久久久久久久久久 | 久久国产柳州莫菁门 | 国产精品二区视频 | 国产主播av在线 | 麻豆传媒一区二区 | 国产群p视频 | 国产精品一区在线免费观看 | 一级片黄色| 日韩色区 | 亚洲精品成a人在线观看 | 尤物在线免费视频 | 国产毛片视频 | 中文字幕日产av | 五月天婷婷激情 | 中文字幕乱码视频 | 国产 xxxx | 国产成人视屏 | 粉嫩小泬无遮挡久久久久久 | 成人黄色小说在线观看 | 91视频精品| 操操日日 | 久久久成人精品一区二区三区 | 美国做爰xxxⅹ性视频 | 国产精品乱码久久久久久久久 | h网站免费在线观看 | 探花国产 | 一区二区三区免费观看 | 日本美女一级视频 | 日韩亚洲精品在线 | wwwwxxxx欧美| 国产高潮网站 | 欧美性aaa | 久久综合亚洲 | 中文字幕日韩精品在线 | 岛国av免费在线 | 久久艹中文字幕 | www污网站 | 日日骚影院| 五月天婷婷在线观看 | 99色播| 欧美性大战久久久久久 | 国产自精品 | 亚洲在线观看一区二区 | 伊人久久精品 | 国产中文视频 | 国产精品12区 | 黑森林av凹凸导航 | 极品美妇后花庭翘臀娇吟小说 | 毛茸茸毛片 | 日本公妇乱偷中文字幕 | 色av吧| 国产视频自拍一区 | 91黄色大片 | 伊人网久久久 | 天天干天天摸天天操 | 婷婷五月小说 | 麻豆国产av超爽剧情系列 | 久久精品日韩 | 午夜国产一区二区三区 | 与亲女洗澡时伦了毛片 | a级一a一级在线观看 | 国产美女精品一区二区三区 | 超碰在线图片 | 插吧插吧网 | 亚洲成人va |