java圖論弗洛伊德和迪杰斯特拉算法解決最短路徑問題
弗洛伊德算法
算法介紹
算法圖解分析?
?
?第一輪循環(huán)中,以A(下標(biāo)為:0)作為中間頂點(diǎn)
【即把作為中間頂點(diǎn)的所有情況都進(jìn)行遍歷,就會得到更新距離表和前驅(qū)關(guān)系】,距離表和前驅(qū)關(guān)系更新為:
弗洛伊德算法和迪杰斯特拉算法的最大區(qū)別是:
弗洛伊德算法是從各個頂點(diǎn)出發(fā),求最短路徑;
迪杰斯特拉算法是從某個頂點(diǎn)開始,求最短路徑。
/** * 弗洛伊德算法 * 容易理解,容易實(shí)現(xiàn) */ public void floyd() { int len = 0;//變量保存距離 //對中間頂點(diǎn)遍歷,k就是中間頂點(diǎn)的下標(biāo)[A,B,C,D,E,F,G] for(int k = 0;k < dis.length;k++) { //從i頂點(diǎn)開始出發(fā)[A,B,C,D,E,F,G] for(int i = 0;i < dis.length;i++) { //到達(dá)j頂點(diǎn) //[A,B,C,D,E,F,G] for(int j = 0;j < dis.length;j++) { len = dis[i][k] + dis[k][j];//=>求出從i頂點(diǎn)出發(fā),經(jīng)過k中間頂點(diǎn),到達(dá)j頂點(diǎn)距離 if(len < dis[i][j]) {//如果len小于dis[i][j] dis[i][j] = len;//更新距離 pre[i][j] = pre[k][j];//更新前驅(qū)頂點(diǎn) } } } } }
?迪杰斯特拉算法
算法介紹
算法過程?
public class DijkstraAlgorithm { public static void main(String[] args) { char[] vertex = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' }; // 鄰接矩陣 int[][] matrix = new int[vertex.length][vertex.length]; final int N = 65535;// 表示不可以連接 matrix[0] = new int[] { N, 5, 7, N, N, N, 2 }; matrix[1] = new int[] { 5, N, N, 9, N, N, 3 }; matrix[2] = new int[] { 7, N, N, N, 8, N, N }; matrix[3] = new int[] { N, 9, N, N, N, 4, N }; matrix[4] = new int[] { N, N, 8, N, N, 5, 4 }; matrix[5] = new int[] { N, N, N, 4, 5, N, 6 }; matrix[6] = new int[] { 2, 3, N, N, 4, 6, N }; // 創(chuàng)建Graph對象 Graph graph = new Graph(vertex, matrix); // 測試,圖的鄰接矩陣是否ok graph.showGraph(); // 測試迪杰斯特拉算法 graph.dsj(6); graph.showDijkstra(); } } class Graph { private char[] vertex;// 頂點(diǎn)數(shù)組 private int[][] matrix;// 鄰接矩陣 private VisitedVertex vv;// 已經(jīng)訪問過的頂點(diǎn)的集合 // 構(gòu)造器 public Graph(char[] vertex, int[][] matrix) { this.vertex = vertex; this.matrix = matrix; } // 顯示結(jié)果 public void showDijkstra() { vv.show(); } // 顯示圖 public void showGraph() { for (int[] link : matrix) { System.out.println(Arrays.toString(link)); } } /** * 迪杰斯特拉算法實(shí)現(xiàn) * * @param index 表示出發(fā)頂點(diǎn)對應(yīng)的下標(biāo) */ public void dsj(int index) { vv = new VisitedVertex(vertex.length, index); update(index);// 更新index頂點(diǎn)到周圍頂點(diǎn)的距離和前驅(qū)頂點(diǎn) for (int j = 1; j < vertex.length; j++) { index = vv.updateArr();// 選擇并返回新的訪問頂點(diǎn) update(index);// 更新index頂點(diǎn)到周圍頂點(diǎn)的距離和前驅(qū)頂點(diǎn) } } /** * 更新index下標(biāo)頂點(diǎn)到周圍頂點(diǎn)的距離和周圍頂點(diǎn)的前驅(qū)頂點(diǎn) */ private void update(int index) { int len = 0; // 根據(jù)遍歷鄰接矩陣的 matrix[index]行 for (int j = 0; j < matrix[index].length; j++) { // len含義是:出發(fā)頂點(diǎn)到index頂點(diǎn)的距離 + 從index頂點(diǎn)到j(luò)頂點(diǎn)的距離的和 len = vv.getDis(index) + matrix[index][j]; // 如果j頂點(diǎn)沒有被訪問過,并且len小于出發(fā)頂點(diǎn)到j(luò)頂點(diǎn)的距離,就需要更新 if (!vv.in(j) && len < vv.getDis(j)) { vv.updateDis(j, index);// 更新j頂點(diǎn)的前驅(qū)為index頂點(diǎn) vv.updateDis(j, len);// 更新出發(fā)頂點(diǎn)到j(luò)頂點(diǎn)的距離 } } } } //已訪問頂點(diǎn)集合 class VisitedVertex { // 記錄各個頂點(diǎn)是否訪問過; 1表示訪問過,0未訪問,會動態(tài)更新 public int[] already_arr; // 每個下標(biāo)對應(yīng)的值為前一個頂點(diǎn)下標(biāo),會動態(tài)更新 public int[] pre_visited; // 記錄出發(fā)頂點(diǎn)到其他所有頂點(diǎn)的距離,比如G為出發(fā)頂點(diǎn),就會記錄G到其他頂點(diǎn)的距離,動態(tài)更新,求的最短距離放到dis public int[] dis; /** * 構(gòu)造器 * * @param length 表示頂點(diǎn)的個數(shù) * @param index 出發(fā)頂點(diǎn)對應(yīng)的下標(biāo),比如G頂點(diǎn),下標(biāo)就是6 */ public VisitedVertex(int length, int index) { this.already_arr = new int[length]; this.pre_visited = new int[length]; this.dis = new int[length]; // 初始化dis數(shù)組 Arrays.fill(dis, 65535); this.already_arr[index] = 1;// 設(shè)置出發(fā)頂點(diǎn)被訪問過 this.dis[index] = 0;// 設(shè)置出發(fā)頂點(diǎn)的訪問距離為0 } /** * 判斷index頂點(diǎn)是否被訪問過 * * @param index * @return 如果訪問過,就返回true,否則返回false */ public boolean in(int index) { return already_arr[index] == 1; } /** * 更新出發(fā)頂點(diǎn)到index頂點(diǎn)的距離 * * @param index * @param len */ public void updateDis(int index, int len) { dis[index] = len; } /** * 更新pre這個頂點(diǎn)的前驅(qū)頂點(diǎn)為index頂點(diǎn) * * @param pre * @param index */ public void updatePre(int pre, int index) { pre_visited[pre] = index; } /** * @return 返回出發(fā)頂點(diǎn)到index頂點(diǎn)的距離 */ public int getDis(int index) { return dis[index]; } public int updateArr() { int min = 65535, index = 0; for (int i = 0; i < already_arr.length; i++) { if (already_arr[i] == 0 && dis[i] < min) { min = dis[i]; index = i; } } // 更新index頂點(diǎn)被訪問過 already_arr[index] = 1; return index; } // 顯示最后的結(jié)果 // 即將三個數(shù)組的情況輸出 public void show() { System.out.println("=========================="); // 輸出already_arr for (int i : already_arr) { System.out.print(i + " "); } // 輸出pre_visited for (int i : pre_visited) { System.out.print(i + " "); } // 輸出dis for (int i : dis) { System.out.print(i + " "); } System.out.println(); // 為了好看最后的最短距離,如下處理 char[] vertex = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' }; int count = 0; for (int i : dis) { if (i != 65535) { System.out.print(vertex[count] + "(" + i + ")"); } else { System.out.println("N"); } count++; } System.out.println(); } }
以上就是java圖論弗洛伊德和迪杰斯特拉算法解決最短路徑問題的詳細(xì)內(nèi)容,更多關(guān)于弗洛伊德和迪杰斯特拉算法解決最短路徑的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
javaweb 國際化:DateFormat,NumberFormat,MessageFormat,ResourceBu
本文主要介紹javaWEB國際化的知識,這里整理了詳細(xì)的資料及實(shí)現(xiàn)代碼,有興趣的小伙伴可以參考下2016-09-09IDEA代碼規(guī)范&質(zhì)量檢查的實(shí)現(xiàn)
這篇文章主要介紹了IDEA代碼規(guī)范&質(zhì)量檢查的實(shí)現(xiàn),文中通過圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08使用Java創(chuàng)建數(shù)據(jù)透視表并導(dǎo)出為PDF的方法
數(shù)據(jù)透視分析是一種強(qiáng)大的工具,可以幫助我們從大量數(shù)據(jù)中提取有用信息并進(jìn)行深入分析,本文將介紹如何使用Java來構(gòu)建PivotTable以及實(shí)現(xiàn)數(shù)據(jù)透視分析,并將其導(dǎo)出為PDF2023-10-10詳解openfeign集成spring?cloud?loadbalancer實(shí)現(xiàn)負(fù)載均衡流程
這篇文章主要介紹了openfeign集成spring?cloud?loadbalancer實(shí)現(xiàn)負(fù)載均衡流程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07Idea 2020.2安裝MyBatis Log Plugin 不可用的解決方法
小編在使用時發(fā)現(xiàn)Idea 2020.2 MyBatis Log Plugin 收費(fèi)了,這個可以替代用,小編特此把解決方案分享到腳本之家平臺供大家參考,感興趣的朋友一起看看吧2020-11-11使用log4j2自定義配置文件位置和文件名(附log4j2.xml配置實(shí)例)
這篇文章主要介紹了使用log4j2自定義配置文件位置和文件名(附log4j2.xml配置實(shí)例),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12