`
SCYForce
  • 浏览: 40824 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

算法笔记(第二部分)-- 图算法之Dijkstra最短路径算法

阅读更多
Dijkstra算法由著名的荷兰计算机科学家Dijkstra于1959年提出(这位老人家已于2002年过世,过世前任教于University Of Texas,Austin)。简单的说,这个算法解决的就是对于图中的任意一个节点,求出该点到其他节点的最短路径。

Dijkstra算法过程:
1. 创建一个节点之间的距离表,一个目标节点上一个节点表,一个访问过的节点表和一个当前节点。
2. 初始化距离表值,初始节点设为0,其他设为无穷大。
3. 所有访问过的节点表中的值设为“false”。
4. 将目标节点上一个节点链表中的值设为“undefined”。
5. 当前节点设置为初始节点。
6. 将当前节点设置为“visited”。
7. 根据图的结构更新距离表与目标节点上一个节点表。
8. 更新从初始节点到目标节点的最短路径:当前节点->未访问过节点+初始节点->当前节点。
9. 重复步骤6-8直至所有节点都遍历完。

算法动画演示(个人觉得做得很好):http://www.cs.usfca.edu/galles/visualization/visualization.jar

Dijkstra算法简易实现
package com.interview.graph;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Map.Entry;

public class DijkstraAlgorithm {
    public static int LARGE_NUMBER = 10000;
    public static String UNDEFINED = "undefined";
	
	public Hashtable<String, String> DijkstraAlgorithm(Hashtable<String, Hashtable<String, Integer>> ajacencyList, String source){
		//store shortest path from source to current calculating point
		Hashtable<String, Integer> distance = new Hashtable<String, Integer>();
		//store the paths
		Hashtable<String, String> previous = new Hashtable<String, String>();
		//store all need to be computed nodes
		List<String> nodes = new ArrayList<String>();
		
		//inialize the dist and previous;
		for (Entry<String, Hashtable<String, Integer>> entry : ajacencyList.entrySet()) {
			String key = entry.getKey();
			distance.put(key, LARGE_NUMBER);
			previous.put(key, UNDEFINED);
			nodes.add(key);
		}		
		distance.put(source, 0);
		
		String nextNode;
		Hashtable<String, Integer> neighbors;
		while(!nodes.isEmpty()){
			nextNode = findNode(distance, nodes);
			nodes.remove(nextNode);
			neighbors = ajacencyList.get(nextNode);						
			//make sure the shortest path from source to the destination
			for(Entry<String, Integer> entry : neighbors.entrySet()){
				int alt =  (distance.get(nextNode)).intValue()+entry.getValue();
				String neighbor = entry.getKey();
				if(alt<(distance.get(neighbor)).intValue()){
					distance.put(neighbor, alt);
					previous.put(neighbor, nextNode);
				}
			}
		}
		return previous;
	}
	
	//find the lowest cost between point A and point B
	public String findNode(Hashtable<String, Integer> dist, List<String> nodes){
    	int distance = LARGE_NUMBER;
    	String node = "";
    	for(Entry<String, Integer> entry : dist.entrySet()){
    		String key = entry.getKey();
    		if(nodes.contains(key)){
    			int value = entry.getValue().intValue();
    			if(value<distance){
    				distance = value;
    				node = key;
    			}
    		}
    	}
    	return node;
    }
        //print the route from source to target
	public void printOutPath(Hashtable<String, String> path, String source, String target) {
		for (Entry<String, String> entry : path.entrySet()) {
    		String currentNode = entry.getKey();
    		String previousNode = entry.getValue();
    		if (currentNode.equals(target)) {
    			List<String> pathList = new ArrayList<String>();
        		pathList.add(currentNode);
        		if (!UNDEFINED.equals(previousNode)) {
        			pathList.add(previousNode);
        		}   		
        		while (!previousNode.equals(source)&&!previousNode.equals(UNDEFINED)) {
        			previousNode = path.get(previousNode);
        			pathList.add(previousNode);
        		}
        		Collections.reverse(pathList);    		
        		int index = 0;
        		for (String node : pathList) {
        			System.out.print(node);
        			if (index!=pathList.size()-1) {
        				System.out.print("->");
        			}
        			index++;
        		}
        		System.out.println();
        		break;    		
    		}   		    				
    	}
	}
	//print out all routes from the source
	public void printOutRoutes(Hashtable<String, String> path, String source){
		for (Entry<String, String> entry : path.entrySet()) {
    		String currentNode = entry.getKey();
    		String previousNode = entry.getValue();
    		
    		List<String> pathList = new ArrayList<String>();
    		pathList.add(currentNode);
    		if (!UNDEFINED.equals(previousNode)) {
    			pathList.add(previousNode);
    		}   		
    		while (!previousNode.equals(source)&&!previousNode.equals(UNDEFINED)) {
    			previousNode = path.get(previousNode);
    			pathList.add(previousNode);
    		}
    		Collections.reverse(pathList);    		
    		int index = 0;
    		for (String node : pathList) {
    			System.out.print(node);
    			if (index!=pathList.size()-1) {
    				System.out.print("->");
    			}
    			index++;
    		}
			System.out.println();
    	}
    }

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Hashtable<String, Hashtable<String, Integer>> graph = new Hashtable<String, Hashtable<String,Integer>>();
		
		Hashtable<String, Integer> neighbors1 = new Hashtable<String, Integer>();
		neighbors1.put("B", 2);
		neighbors1.put("C", 1);		
		graph.put("A", neighbors1);

		Hashtable<String, Integer> neighbors2 = new Hashtable<String, Integer>();
		neighbors2.put("D", 3);
		graph.put("B", neighbors2);
		
		Hashtable<String, Integer> neighbors3 = new Hashtable<String, Integer>();
		neighbors3.put("D", 1);
		graph.put("C", neighbors3);
		
		Hashtable<String, Integer> neighbors4 = new Hashtable<String, Integer>();
		neighbors4.put("E", 2);
		neighbors4.put("F", 3);
		graph.put("D", neighbors4);
		
		Hashtable<String, Integer> neighbors5 = new Hashtable<String, Integer>();
		graph.put("E", neighbors5);
		
		Hashtable<String, Integer> neighbors6 = new Hashtable<String, Integer>();
		graph.put("F", neighbors6);
		
		DijkstraAlgorithm dijkstra = new DijkstraAlgorithm();
		Hashtable<String, String> path = dijkstra.DijkstraAlgorithm(graph, "A");
		dijkstra.printOutRoutes(path, "A");
		dijkstra.printOutPath(path, "A", "E");

	}

}


在这个简易实现中,因为节点之间的距离为1,我就是用了简化版的邻接表(Hashtable)。代码应该很容易能看懂,核心:1. 从距离表中找出未访问过的拥有初始节点至该节点最小距离的作为下一个计算节点 2.若当前节点->未访问节点+初始节点->当前节点的值小于记录则进行替换,直至所有节点都被访问。算法写的不是很优,希望各位多多拍砖。
8
1
分享到:
评论
1 楼 cywhoyi 2010-01-30  
非常感谢

相关推荐

    算法笔记算法笔记算法笔记

    根据给定的信息,我们可以分析出这是一篇关于图论中的最短路径算法的代码实现,具体来说是Dijkstra算法的一种实现方式。以下是对该代码的关键知识点进行详细解析: ### 一、基本概念 #### 图的基本定义 在图论中,...

    算法笔记7.15

    7. 图算法:如最短路径问题的Dijkstra算法、Bellman-Ford算法、拓扑排序、关键路径算法等。 8. 加密算法:如RSA算法,在描述中提到了RSA、RSA-OAEP、Magma等,这些属于公钥加密技术范畴。 由于文档的乱码内容部分...

    Algorithms Notes For Professionals(给专业人士的算法笔记)

    第5章“Dijkstra算法”讲解了Dijkstra的最短路径算法,它用于在带权重的图中找到两点之间的最短路径。而第6章“A*寻路算法”则是介绍了在带有启发式信息的搜索算法中如何找到最优路径,章节中也包含了启发式搜索的...

    离散数学笔记(5--10).zip

    在这一章,可能会深化对图论的理解,包括欧拉路径、哈密顿回路、最短路径算法(如Dijkstra算法和Floyd-Warshall算法)、网络流问题、匹配理论等。 综上所述,这些笔记提供了离散数学关键概念的深入理解,对学习...

    考研杭电计算机数据结构笔记最终版!-

    - **最短路径算法**:如Dijkstra算法、Floyd算法等,用于找到图中两个顶点之间的最短路径。 - **最小生成树算法**:如Prim算法、Kruskal算法等,用于在加权图中找到一棵包含所有顶点且总权重最小的生成树。 ### 3. ...

    算法导论读书笔记

    这一章讨论了图的表示方法、遍历(深度优先搜索和广度优先搜索)、最短路径算法(Dijkstra、Floyd-Warshall)、最小生成树(Prim、Kruskal)等。这些算法在网络路由、社交网络分析等领域有着广泛应用。 通过阅读和...

    数据结构算法实现--严蔚敏的书的算法

    4. **ch5**:第五章可能讲解图的理论,包括图的表示(邻接矩阵和邻接表)、图的遍历(深度优先搜索和广度优先搜索)、最短路径算法(如Dijkstra算法和Floyd-Warshall算法)和最小生成树算法(如Prim算法和Kruskal...

    屈婉玲《算法设计与分析》视频课程及课件

    - **最短路径问题**:Dijkstra算法和Floyd算法。 - **最小生成树**:Prim算法和Kruskal算法。 #### 5. 动态规划 - **动态规划的基本思想**:介绍动态规划的原理和适用条件。 - **典型问题**:背包问题、最长公共子...

    Java数据结构与算法15天笔记.zip

    8. **day12 ͼ.md** - 这个可能是“图”的拼音缩写,图数据结构包括邻接矩阵和邻接表,用于表示节点间的关系,常见算法有深度优先搜索(DFS)、广度优先搜索(BFS)以及最短路径算法(Dijkstra、Floyd-Warshall等)...

    算法导论第二版书与习题答案

    6. 图算法:包括最短路径问题(Dijkstra算法,Floyd-Warshall算法)和最小生成树(Prim算法,Kruskal算法)。 7. 概率算法和随机化技术:如Monte Carlo方法和Las Vegas算法。 8. 数据结构:如堆、平衡二叉树、哈希表...

    clrs-notes-solutions, 算法导论,第3版,学习笔记,习题答案.zip

    2. **数据结构**:数组、链表、栈、队列、树(二叉树、平衡树如AVL树和红黑树)、图(图的遍历、最小生成树、最短路径等)。 3. **递归与分治策略**:通过递归解决问题的方法,如快速排序、归并排序、汉诺塔问题、...

    《算法导论》第三版英文版-带书签目录文字版1313页完整版

    2. **搜索算法**:如二分查找、广度优先搜索(BFS)和深度优先搜索(DFS),以及在图中寻找最短路径的Dijkstra算法和Floyd-Warshall算法。 3. **数据结构**:数组、链表、栈、队列、树(二叉树、平衡二叉树如AVL树和...

    计算机网络-甘晴void学习笔记

    - **OSPF**: Open Shortest Path First, 基于Dijkstra算法计算最短路径。 - **IS-IS**: Intermediate System to Intermediate System, 也使用链路状态算法。 - **距离矢量路由选择算法**: - **RIP**: Routing ...

    数据结构中的代码,算法和电子笔记,字典,图解

    图的遍历方法有深度优先搜索(DFS)和广度优先搜索(BFS),还有最短路径算法,如Dijkstra算法和Floyd-Warshall算法。 5. **算法**:数据结构与算法是密不可分的。这个文件夹可能包含了排序算法(如冒泡排序、选择...

    有关路由的中文笔记--精简版

    4. **SPF算法计算:** 每个路由器使用Dijkstra算法根据LSDB计算到达每个目的地的最短路径。 ##### 三、OSPF中的路径选择和路径交换 OSPF不仅负责路径的选择,还负责路径的交换。这意味着它不仅要确定最优路径,...

    CCIE-经典的OSPF笔记

    - **名称来源**:“Open Shortest Path First”(开放最短路径优先),因采用SPF算法(Dijkstra算法),支持多厂商设备而得名。 - **发展历程**: - 1987年,IETF成立OSPF工作组。 - 1991年,OSPF v2在RFC1247中...

    【软考-软件设计师精华知识点笔记】第八章 算法分析设计

    9. **图论算法**:包括最短路径问题(Dijkstra算法、Floyd-Warshall算法)、最小生成树问题(Prim算法、Kruskal算法)、拓扑排序等。 10. **递归与迭代**:递归是函数调用自身,常用于树形结构的遍历和动态规划问题...

    算法导论学习资料

    在图算法部分,书中详细讲解了最短路径问题(如Dijkstra算法和Floyd-Warshall算法)以及最小生成树问题(如Prim算法和Kruskal算法)。动态规划则用于解决最优化问题,如背包问题、最长公共子序列等。贪心算法和分治...

    《算法概论》读书笔记及读后感.pdf

    最后,广度优先搜索(BFS)在第四章中被引入,主要用于解决图中顶点的最短路径问题,如Dijkstra算法和Bellman-Ford算法。BFS通常用于寻找优化路径,而DFS则更侧重于图的结构分析。作者强调了理论学习与实践解题相结合...

    leetcode分类-Algorithm-leetcode-python:python刷leetcode,整理算法笔记

    5. 图论:图的遍历、最短路径算法(Dijkstra、Floyd等)、最小生成树(Prim、Kruskal)等,这些都是解决复杂网络问题的关键。 通过系统性的学习和实践,可以形成自己的算法思维体系,这对于提升编程能力和解决实际...

Global site tag (gtag.js) - Google Analytics