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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

浅谈最小生成树的算法思路(一)Prim算法

發布時間:2024/2/28 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅谈最小生成树的算法思路(一)Prim算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Prim算法是求最小生成樹的一種常見算法,簡單談一下筆者自己的理解。

算法思路

  • 設已經確定的點集為P,初始為空。設還未確定的點集為Q,初始為該圖所有點的集合。設已經確定的邊為X,初始為空。
  • 選取任意一點作為起始點,將該點添加到集合P中,并從Q中移除該點。
  • 從P中找到一個點A,從Q中找到一個點B,使得2點之間的路徑AB的權值最小。
  • 將路徑AB添加到X,將Q中的點B添加到集合P中,并從Q中移除該點。
  • 重復3~4,直至所有點確定路徑。
  • 代碼思路

  • 采用鄰接矩陣保存圖。
  • 創建一個臨時數組lowcost,長度為總點數,用于表示當前時刻集合P與各點的距離。
    例如lowcost[3]=m,3表示下標為3的點,當m為0表示該點已經在集合P中,即已經確定;當m為65535,表示該點與集合P暫時沒有直接路徑可到達;其他值表示該點與P可以直接通過一條連線到達,并且當前最短距離為m。
    需要說明的是,這個數組是會不斷變化的,最初,當P中只有一個點A的時候,lowcost表示A到各點的距離,這個時候有些點與點A沒有直達路徑,此時這些點是為65535的;而程序結束時,該數組的元素的值將都為0,因為所有點已經都添加到P了,此時各點到P的距離都為0。
  • 創建臨時數組mst,長度為總點數,用于保存步驟2的最短距離m對應的邊關系。即每次添加一個點到P后,會更新P與剩余各點之間的最短距離m,此時會記錄最短距離的邊AB的起始點和結束點。
    例如lowcost[3]=m,mst[3]=2表示下標為3的點A到P的距離為m,該連線是A與P中下標為2的點B的連線。
  • 初始化:選取圖的點集合的下標為0的點A,作為初始點。將圖的邊矩陣中,A與各點的距離(權重)寫入lostcost數組作為初始值,并將mst各元素置零。創建臨時變量n=1,表示已經確定的點數,用作循環結束的判斷。
  • 遍歷lowcost數組,找出最小的值(排除0和65535),即當前集合P中任意一點到Q中任意一點的最短距離(權重)。記錄下標minid。
  • 將lowcost[minid]置為零,表示該點已經添加到P。
  • 更新新添加到P的點minid與Q中各點的距離。即遍歷圖的邊矩陣中起始點為minid的各元素,如果有比lowcost中對應元素的距離小的元素,則更新lostcost,同時更新mst。
    例如,此時P中有3個點{A,B,C},Q中有2個點{D,E},C為剛剛添加的點。由于我們剛剛將C添加到P,所以執行步驟7之前的lostcost數組中保存著{A,B}到{C,D,E}的最短距離,比如lostcost為[0,0,0,Sd,Se]。當C添加進去之后,有可能之前AB到DE都距離比較遠或者沒有直接路徑,而C到DE的距離很近,這個時候就需要比較C到DE的距離Scd和Sce有沒有比Sd,Se更小,如果有則更新lostcost中的Sd,Se為一個新的值。
  • 循環執行5~7,直至所有點的路徑確定,即當n>=總點數跳出循環。
  • 代碼實現(Java版)

    public class Prim {static int MAX = 65535;//表示兩點之間沒有直接路徑public static void prim(int[][] graph, int n) {char[] c = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'E', 'F'};int[] lowcost = new int[n];int[] mst = new int[n];int i, j, min, minid, sum = 0;//初始化數組,即將點A添加到P中,計算與各點的距離for (i = 1; i < n; i++) {lowcost[i] = graph[0][i];mst[i] = 0;}//i為已經確定的點數,由于點A已經確定,故初始化為1for (i = 1; i < n; i++) {min = MAX;minid = 0;//找到P到Q的最短路徑,將點添加到Pfor (j = 1; j < n; j++) {if (lowcost[j] < min && lowcost[j] != 0) {min = lowcost[j];minid = j;}}System.out.println(c[mst[minid]] + "到" + c[minid] + " 權值:" + min);sum += min;lowcost[minid] = 0;//如果新添加到P的點minid帶來了與Q中剩余點的更短路徑,更新lowcost、mst數組for (j = 1; j < n; j++) {if (graph[minid][j] < lowcost[j]) {lowcost[j] = graph[minid][j];mst[j] = minid;}}}System.out.println("sum:" + sum);}public static void main(String[] args) {int[][] map = new int[][]{{0, 10, MAX, MAX, MAX, 11, MAX, MAX, MAX},{10, 0, 18, MAX, MAX, MAX, 16, MAX, 12},{MAX, MAX, 0, 22, MAX, MAX, MAX, MAX, 8},{MAX, MAX, 22, 0, 20, MAX, MAX, 16, 21},{MAX, MAX, MAX, 20, 0, 26, MAX, 7, MAX},{11, MAX, MAX, MAX, 26, 0, 17, MAX, MAX},{MAX, 16, MAX, MAX, MAX, 17, 0, 19, MAX},{MAX, MAX, MAX, 16, 7, MAX, 19, 0, MAX},{MAX, 12, 8, 21, MAX, MAX, MAX, MAX, 0}};prim(map, map.length);} }

    總結

    以上是生活随笔為你收集整理的浅谈最小生成树的算法思路(一)Prim算法的全部內容,希望文章能夠幫你解決所遇到的問題。

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