Dijkstra演算法求最短路徑(java)
Dijkstra(迪傑斯特拉)演算法是典型的最短路徑路由演算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。
Dijkstra一般的表述通常有兩種方式,一種用永久和臨時標號方式,一種是用OPEN, CLOSE表方式
用OPEN,CLOSE表的方式,其採用的是貪心法的演算法策略,大概過程如下:
1.宣告兩個集合,open和close,open用於儲存未遍歷的節點,close用來儲存已遍歷的節點
2.初始階段,將初始節點放入close,其他所有節點放入open
3.以初始節點為中心向外一層層遍歷,獲取離指定節點最近的子節點放入close並從新計算路徑,直至close包含所有子節點
程式碼例項如下:
Node物件用於封裝節點資訊,包括名字和子節點
public class Node { private String name; private Map<Node,Integer> child=new HashMap<Node,Integer>(); public Node(String name){ this.name=name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Map<Node, Integer> getChild() { return child; } public void setChild(Map<Node, Integer> child) { this.child = child; } }
MapBuilder用於初始化資料來源,返回圖的起始節點
圖的結構如下圖所示:public class MapBuilder { public Node build(Set<Node> open, Set<Node> close){ Node nodeA=new Node("A"); Node nodeB=new Node("B"); Node nodeC=new Node("C"); Node nodeD=new Node("D"); Node nodeE=new Node("E"); Node nodeF=new Node("F"); Node nodeG=new Node("G"); Node nodeH=new Node("H"); nodeA.getChild().put(nodeB, 1); nodeA.getChild().put(nodeC, 1); nodeA.getChild().put(nodeD, 4); nodeA.getChild().put(nodeG, 5); nodeA.getChild().put(nodeF, 2); nodeB.getChild().put(nodeA, 1); nodeB.getChild().put(nodeF, 2); nodeB.getChild().put(nodeH, 4); nodeC.getChild().put(nodeA, 1); nodeC.getChild().put(nodeG, 3); nodeD.getChild().put(nodeA, 4); nodeD.getChild().put(nodeE, 1); nodeE.getChild().put(nodeD, 1); nodeE.getChild().put(nodeF, 1); nodeF.getChild().put(nodeE, 1); nodeF.getChild().put(nodeB, 2); nodeF.getChild().put(nodeA, 2); nodeG.getChild().put(nodeC, 3); nodeG.getChild().put(nodeA, 5); nodeG.getChild().put(nodeH, 1); nodeH.getChild().put(nodeB, 4); nodeH.getChild().put(nodeG, 1); open.add(nodeB); open.add(nodeC); open.add(nodeD); open.add(nodeE); open.add(nodeF); open.add(nodeG); open.add(nodeH); close.add(nodeA); return nodeA; } }
Dijkstra物件用於計算起始節點到所有其他節點的最短路徑
public class Dijkstra { Set<Node> open=new HashSet<Node>(); Set<Node> close=new HashSet<Node>(); Map<String,Integer> path=new HashMap<String,Integer>();//封裝路徑距離 Map<String,String> pathInfo=new HashMap<String,String>();//封裝路徑資訊 public Node init(){ //初始路徑,因沒有A->E這條路徑,所以path(E)設定為Integer.MAX_VALUE path.put("B", 1); pathInfo.put("B", "A->B"); path.put("C", 1); pathInfo.put("C", "A->C"); path.put("D", 4); pathInfo.put("D", "A->D"); path.put("E", Integer.MAX_VALUE); pathInfo.put("E", "A"); path.put("F", 2); pathInfo.put("F", "A->F"); path.put("G", 5); pathInfo.put("G", "A->G"); path.put("H", Integer.MAX_VALUE); pathInfo.put("H", "A"); //將初始節點放入close,其他節點放入open Node start=new MapBuilder().build(open,close); return start; } public void computePath(Node start){ Node nearest=getShortestPath(start);//取距離start節點最近的子節點,放入close if(nearest==null){ return; } close.add(nearest); open.remove(nearest); Map<Node,Integer> childs=nearest.getChild(); for(Node child:childs.keySet()){ if(open.contains(child)){//如果子節點在open中 Integer newCompute=path.get(nearest.getName())+childs.get(child); if(path.get(child.getName())>newCompute){//之前設定的距離大於新計算出來的距離 path.put(child.getName(), newCompute); pathInfo.put(child.getName(), pathInfo.get(nearest.getName())+"->"+child.getName()); } } } computePath(start);//重複執行自己,確保所有子節點被遍歷 computePath(nearest);//向外一層層遞迴,直至所有頂點被遍歷 } public void printPathInfo(){ Set<Map.Entry<String, String>> pathInfos=pathInfo.entrySet(); for(Map.Entry<String, String> pathInfo:pathInfos){ System.out.println(pathInfo.getKey()+":"+pathInfo.getValue()); } } /** * 獲取與node最近的子節點 */ private Node getShortestPath(Node node){ Node res=null; int minDis=Integer.MAX_VALUE; Map<Node,Integer> childs=node.getChild(); for(Node child:childs.keySet()){ if(open.contains(child)){ int distance=childs.get(child); if(distance<minDis){ minDis=distance; res=child; } } } return res; } }
Main用於測試Dijkstra物件
public class Main {
public static void main(String[] args) {
Dijkstra test=new Dijkstra();
Node start=test.init();
test.computePath(start);
test.printPathInfo();
}
}
列印輸出如下:
D:A->D
E:A->F->E
F:A->F
G:A->C->G
B:A->B
C:A->C
H:A->B->H
相關推薦
Dijkstra演算法求最短路徑(java)
任務描述:在一個無向圖中,獲取起始節點到所有其他節點的最短路徑描述 Dijkstra(迪傑斯特拉)演算法是典型的最短路徑路由演算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。 Dijkstra一般的表述通常有
Dijkstra演算法求最短路徑問題完整C程式碼
<pre name="code" class="cpp">/* Dijkstra演算法求圖的最短路徑問題C程式碼 */ #include <stdio.h> #include <string.h> #include <stdlib.h> #define Ma
Floyd演算法求最短路徑——Java
前面講述了利用貪心演算法求解最短路徑的兩種演算法,分別是BFS以及Dijkstra演算法。接下來要介紹的這種是一種動態規劃的演算法——弗洛伊德演算法。 用通俗的語言來描述的話,首先我們的目標是尋找從點i到點j的最短路徑。從動態規劃的角度看問題,我們需要為這個目
dijkstra演算法求最短路徑
希望大家能看完prim演算法後再來看這個演算法,因為兩者思路差不多。 先來看一下自定義的結構體 typedef char VexType; typedef int AdjType; typedef struct{ int n; VexTy
隨機生成圖,dijkstra演算法求最短路徑,深度、廣度優先歷遍【待更新其他演算法】
graph_node.h (鄰接連結串列節點類):#pragma once #include "pre_definition.h" //代表邊的節點 class graph_node { int serial_num; int weight;//每條邊的權值 publi
資料結構-基於鄰接矩陣實現圖的遍歷視覺化及使用Floyd、Dijkstra演算法求解最短路徑(JavaScript實現)
使用 JavaScript 基於鄰接矩陣實現了圖的深度、廣度遍歷,以及 Floyd、Dijkstra 演算法求解最短路徑。另外使用 SVG 實現圖的遍歷視覺化。一、輸入首先,輸入資料主要有兩個,一個是存放節點名的陣列,另一個是存放邊物件的陣列。例如://存放圖結點的陣列 va
Floyd演算法與Dijkstra演算法(最短路徑)
#include <iostream> #include <cstdio> #include <vector> using namespace std; int Dis[101]; bool mark[101]; struct E { int next; i
資料結構-基於鄰接表實現圖的遍歷視覺化及使用Floyd、Dijkstra演算法求解最短路徑(JavaScript實現)
使用 JavaScript 基於鄰接表實現了圖的深度、廣度遍歷,以及 Floyd、Dijkstra 演算法求解最短路徑。另外使用 SVG 實現圖的遍歷視覺化。<!DOCTYPE html> <html lang="en"> <head>
迪傑斯特拉演算法求最短路徑 C++程式碼實現
#include<iostream> #include<string> using namespace std; /*鄰接矩陣的型別定義*/ #define MAX 10000000 #define MAX_VERTEX_NUM 20 typedef
Floyd演算法求最短路徑(附程式碼例項)
Floyd演算法 使用範圍: 1)求每對頂點的最短路徑; 2)有向圖、無向圖和混合圖; 演算法思想: 直接在圖的帶權鄰接矩陣中用插入頂點的方法依次遞推地構造出n個矩陣D(1), D(2), …, D(n), D(n)是圖的距離矩陣, 同時引入一個後繼
資料結構學習之弗洛伊德floyd演算法求最短路徑
#include "stdio.h" #include "stdlib.h" #define MAX 20 #define INFINITY 9999 typedef bool PathMatrix[MAX+1][MAX+1][MAX+1]; typedef int Di
pku openjudge 我愛北大 floyd演算法求最短路徑
總時間限制: 1000ms 記憶體限制: 65535kB描述 “紅樓飛雪,一時英傑……”耳邊傳來了那熟悉的歌聲。而這,只怕是我最後一次聽到這個聲音了。 想當年,我們曾經懷著豪情壯志,許下心願,走過靜園,走過一體,走過未名湖畔的每個角落。 想當年,我們也曾慷慨高歌,瞻仰民主與科學,瞻仰博雅塔頂,那百年之前的遺
貪心演算法 迪傑斯特拉演算法求最短路徑
之前我們學習過弗洛伊德演算法求最短路徑,但是使用了三重迴圈,導致時間複雜度是O(n^3),而迪傑斯特拉演算法應該是求最短路徑的最好的演算法了。 迪傑斯特拉演算法原理 迪傑斯特拉演算法實際上是使用貪心演算法和bfs來求最短問題的,它的核心思想是,按照頂點來迭代
Dijkstra演算法(最短路徑)
基本思想 每次找到離源點最近的一個頂點,然後以該頂點為中心進行擴充套件,最終得到源點到其餘所有點的最短路徑。 基本歩驟 將所有頂點分為兩部分:已知最短路徑的頂點集合P和未知最短路徑的頂點集合Q。最開始,已知最短路徑的頂點集合P中只有源點
(Java資料結構和演算法)最短路徑---Dijkstra+Floyd
參考博文 Floyd演算法和Dijkstra演算法都不能針對帶有負權邊的圖,否則一直走負權邊,沒有最小,只有更小!! Floyd演算法 import java.util.Scanner; //Floyd演算法 class Graph{ public int[][] ad
sdut 2622 最短路徑(Dijkstra演算法求最短路)
最短路徑 Time Limit: 1000ms Memory limit: 65536K 有疑問?點這裡^_^ 題目描述 為了準備一年一度的校賽,大家都在忙著往賽場搬運東西
C++ 求最短路徑問題之Dijkstra演算法(一)
求最短路徑之Dijkstra演算法 Dijkstra演算法是用來求單源最短路徑問題,即給定圖G和起點s,通過演算法得到s到達其他每個頂點的最短距離。 基本思想:對圖G(V,E)設定集合S,存放已被訪問的頂點,然後每次從集合V-S中選擇與起點s的最短距離最小的一個頂點(記為u
無向圖求最短路徑 迪傑斯特拉(dijkstra)演算法實現
Dijkstra演算法說明 http://ibupu.link/?id=29namespace ConsoleApp14 { class Program { public static int M = -1; static
POJ 3255 Roadblocks (Dijkstra求最短路徑的變形)(Dijkstra求次短路徑)
ber emp accept backtrack cau scrip 直接 hang input Roadblocks Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 16425 Ac
求最短路徑(Bellman-Ford算法與Dijkstra算法)
dijk jks 結點 include 分組 負環 由於 blog 進行 前言 Dijkstra算法是處理單源最短路徑的有效算法,但它局限於邊的權值非負的情況,若圖中出現權值為負的邊,Dijkstra算法就會失效,求出的最短路徑就可能是錯的。這時候,就需要使用其他的算法來求