1. 程式人生 > >Dijkstra最短路徑演算法的java實現

Dijkstra最短路徑演算法的java實現

package graph;

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Map.Entry;

/**
 * @author wyhong
 *
 */
public class Dijkstra {

	public class Node{
		/**
		 * 節點的識別符號
		 */
		private Integer identifier;
		/**
		 * 該節點是否被訪問過
		 */
		private boolean visited = false;
		/**
		 * 該節點與其他節點的對映關係
		 */
		private Map<Node,Integer> mapping = new HashMap<Node,Integer>();
		
		public Integer getIdentifier() {
			return identifier;
		}
		public void setIdentifier(Integer identifier) {
			this.identifier = identifier;
		}
		public boolean isVisited() {
			return visited;
		}
		public void setVisited(boolean visited) {
			this.visited = visited;
		}
		public Map<Node, Integer> getMapping() {
			return mapping;
		}
	}
	
	/**
	 * Getting optimal path by Dijkstra algorithm
	 * @param src
	 * @param dest
	 * @return
	 */
	public static LinkedList<Node> getOptimalPath(Node src, Node dest){
		return dijkstra(src, dest, 0, 0, new LinkedList<Node>());
	}
	
	/**
	 * Dijkstra algorithm
	 * @param src 起始節點
	 * @param dest 目標節點
	 * @param adjacentDist 起始節點與目標節點相鄰時的距離
	 * @param optimalDist 最短路徑權值之和
	 * @param optimalPath 最短路徑
	 * @return
	 */
	private static LinkedList<Node> dijkstra(Node src, Node dest, int adjacentDist, int optimalDist, LinkedList<Node> optimalPath){
		if(optimalPath.size()==0){
			optimalPath.add(src);
		}
		//當前節點與其他節點的對映關係
		Map<Node,Integer> mapping = src.getMapping();
		//當前節點與其相鄰節點的最小距離
		int partialMinDist = 0;
		//當前預選的下一最優節點
		Node partialOptimalNode = null;
		Iterator<Entry<Node, Integer>> entryIterator = mapping.entrySet().iterator();
		while (entryIterator.hasNext()) {
			Entry<Node, Integer> entry = (Entry<Node, Integer>) entryIterator.next();
			Node nextNode = entry.getKey();
			//判斷該相鄰節點是否被訪問過
			if (nextNode.isVisited()) continue;
			int dist = entry.getValue(); 
			//終點與起點相鄰,但未必路徑最短
			if(nextNode.getIdentifier() == dest.getIdentifier() && optimalPath.size() == 1) adjacentDist = dist;
			if (partialMinDist != 0) {
				boolean currentIsOptimal = partialMinDist > dist ? false : true;
				if(!currentIsOptimal){
					partialMinDist = dist;
					partialOptimalNode = nextNode;
				}
			}else{
				partialMinDist = dist;
				partialOptimalNode = nextNode;
			}
		}
		//設定當前節點已被訪問
		src.setVisited(true);
		//加入連結串列
		optimalPath.add(partialOptimalNode);
		optimalDist += partialMinDist;
		if(partialOptimalNode.getIdentifier()!=dest.getIdentifier()){
			//若未到終點時當前最優路徑長度已大於終點與起點相鄰的距離,則最短路徑為起點--->終點
			if(adjacentDist != 0 && optimalDist > adjacentDist) {
				src = optimalPath.removeFirst();
				optimalPath.clear();
				optimalPath.add(src);
				optimalPath.add(dest);
				optimalDist = adjacentDist;
				return optimalPath;
			}
			//否則以當前節點遞迴
			return dijkstra(partialOptimalNode, dest, adjacentDist, optimalDist, optimalPath);
		}else{
			return optimalPath;
		}
	}
}

測試用例:

package graph.test;

import graph.Dijkstra;
import graph.Dijkstra.Node;

import java.util.Iterator;
import java.util.LinkedList;

public class DijkstraTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Dijkstra dijkstra = new Dijkstra();
		Dijkstra.Node node_1 = dijkstra.new Node();
		Dijkstra.Node node_2 = dijkstra.new Node();
		Dijkstra.Node node_3 = dijkstra.new Node();
		Dijkstra.Node node_4 = dijkstra.new Node();
		Dijkstra.Node node_5 = dijkstra.new Node();
		Dijkstra.Node node_6 = dijkstra.new Node();
		
		node_1.setIdentifier(1);
		node_1.getMapping().put(node_2, 7);
		node_1.getMapping().put(node_3, 9);
		node_1.getMapping().put(node_6, 14);
		
		node_2.setIdentifier(2);
		node_2.getMapping().put(node_1, 7);
		node_2.getMapping().put(node_3, 10);
		node_2.getMapping().put(node_4, 15);
		
		node_3.setIdentifier(3);
		node_3.getMapping().put(node_1,7);
		node_3.getMapping().put(node_2,10);
		node_3.getMapping().put(node_4,11);
		node_3.getMapping().put(node_6,2);
		
		node_4.setIdentifier(4);
		node_4.getMapping().put(node_3, 11);
		node_4.getMapping().put(node_2, 15);
		node_4.getMapping().put(node_5, 6);
		
		node_5.setIdentifier(5);
		node_5.getMapping().put(node_4, 6);
		node_5.getMapping().put(node_6, 9);
		
		node_6.setIdentifier(6);
		node_6.getMapping().put(node_5, 9);
		node_6.getMapping().put(node_1, 14);
		
		LinkedList<Node> optimalPath = Dijkstra.getOptimalPath(node_1, node_5);
		System.out.println("-------The optimal path--------");
		for (Iterator<Node> iterator = optimalPath.iterator(); iterator.hasNext();) {
			Node node = (Node) iterator.next();
			if (iterator.hasNext()) {
				System.out.print(node.getIdentifier()+"-->");
			}else{
				System.out.print(node.getIdentifier());
			}
		}
	}

}
結果:


相關推薦

Dijkstra路徑演算法java實現

package graph; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.Map; import java.util.

Java鄰接表表示加權有向圖,附dijkstra路徑演算法

圖這種adt(abstract data type)及相關的演算法,之前一直是我未曾涉足過的領域。 主要是作為一個小測試,在平常的工作中也用不著,就算面試,至今也未曾碰到過相關考題。 但是前幾天,原公司的小美女談到面試過程中就碰到一題: 從A到B,有多條路線,要找出最短路

演算法分析與設計課程設計-Dijkstra路徑演算法

演算法分析與設計課程設計報告書         題目:Dijkstra最短路徑演算法 設計人:張欽穎 班級:14計科2班    學號:1414080901218   一、  

dijkstra 路徑演算法

 Dijkstra(迪傑斯特拉)演算法是典型的最短路徑路由演算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。Dijkstra演算法能得出最短路徑的最優解,但由於它遍歷計算的節點很多,所以效率低。   Dij

圖論之Dijkstra路徑演算法

圖論中最有名的問題可能就屬最短路徑了。最短路徑問題要求解的是:如果從圖中某一頂點(稱為源點)到達另一頂點(稱為終點)的路徑可能不止一條,如何找到一條路徑,使得沿此路徑各邊上的權值總和(即從源點到終點的距離)達到最小,這條路徑稱為最短路徑(shortestpath)。最短路徑有很多特殊的情況,包括有向圖還是無向

C++ dijkstra 路徑演算法、top排序、DFS、BFS 示例 C++11

好一段時間前寫的了。。。正好現在在複習資料結構,重構了一下程式碼 首先先是 圖、點Vertex和邊AdjACent的定義 class JpGraph { public: class Vertex; class

關於對Dijkstra路徑演算法理解(無程式碼版)

演算法步驟: (1)、設定兩個結點集合U、T,將源點v新增到U,其餘所有頂點新增到T; (2)、從給定點v開始,搜尋其鄰接結點,生成多條初始路徑,並新增到路徑集合Path; (3)、從Path中計算路徑長度最短的路徑,如果U中不存在該路徑的終點,則說明已經找到v到該結點的最

雲端計算期末報告無圖 kmeans和路徑演算法hadoop實現詳解

《雲端計算應用開發實驗》大作業報告 一.實驗環境與實驗工具 ubuntu 16.04真機 + hadoop2.6 + 本地偽分佈   二.實驗原理 以下內容為科普性內容,不過裡面還是有一些關鍵的解釋在配環境的時候用得上 Hadoop是一個

單源路徑及其java實現

演算法思想連結:演算法思想及c++實現 本文采用java實現,並帶有略微詳細的註解。 package com.qf.greaph; import java.util.ArrayList; import java.util.Arrays; import

DIJKSTRA路徑演算法

這個也是最短路徑演算法,在嚴巍敏的書上也有提到過,具體的思想忘記了,(老了*0*)和FLOYD演算法做個對照,記得他們各有優缺點,一個是從全域性出發,一個是從區域性生成的。很強大的演算法。 C程式碼如下: #include<stdio.h> #define

基於C++的Dijkstra路徑演算法

#include "stdafx.h" #include<cstdio> #include<algorithm> #include<cmath> #include<vector> #include<queue> #i

一篇文章講透Dijkstra路徑演算法

![](https://img2020.cnblogs.com/blog/1060878/202005/1060878-20200531104733621-717670920.gif) Dijkstra是典型最短路徑演算法,計算一個起始節點到路徑中其他所有節點的最短路徑的演算法和思想。在一些專業課程中如資

路徑演算法比較(Dijkstra、Bellman-Ford、SPFA)及實現Java

Bellman-Ford(Java) package com; import java.util.Scanner; public class Bellman_Ford { private static E edge[]; private static int

圖的路徑演算法——Dijkstra演算法java 實現

首先,定義Graph類,主要用於儲存圖的鄰接矩陣,實際上儲存的是每個節點的出邊(outgoing arcs)集合。 Graph 類繼承自 SparseMatrix 類,因為大多數圖(網路)都是稀疏的,所以用稀疏矩陣來儲存圖的邊及每條邊的權值非常方便。 packa

A Star 路徑演算法Java實現

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

路徑演算法dijkstra的matlab實現

function Dijkstra(Graph, source):  2  3      create vertex set Q  4  5      f

資料結構-基於鄰接矩陣實現圖的遍歷視覺化及使用Floyd、Dijkstra演算法求解路徑(JavaScript實現

使用 JavaScript 基於鄰接矩陣實現了圖的深度、廣度遍歷,以及 Floyd、Dijkstra 演算法求解最短路徑。另外使用 SVG 實現圖的遍歷視覺化。一、輸入首先,輸入資料主要有兩個,一個是存放節點名的陣列,另一個是存放邊物件的陣列。例如://存放圖結點的陣列 va

圖的鄰接矩陣表示與路徑演算法Dijkstra )程式碼實現

#include <stdio.h> #define MAX_VERTEX_NUM 20 //最大頂點個數 typedef int VRTYPE, InfoType; typedef enum {DG, DN, UDG, UD

圖的路徑演算法(Dijkstra,Floyd)的實現

從某個源點到其餘各頂點的最短路徑 迪杰特斯拉演算法 Dijkstra(迪傑斯特拉)演算法是典型的單源最短路徑演算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。 演算法步驟如下:

求圖中路徑演算法Dijkstra演算法——C++實現並優化

Dijkstra演算法是一種比較經典的求圖中最短路徑演算法,它是一種貪心演算法,可以求出從源節點到圖中其他所有節點的最短路徑。適用範圍:用於求有向或無向加權圖中兩點間的最短路徑,其中邊的權值不能為負。 最近重新學習了該演算法,並用C++將其實現,同時對程式碼進行了優化,優化