算法笔记(第二部分)-- 图算法之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直至所有节点都遍历完。

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

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 DijkstraAlgorithm(Hashtable> ajacencyList, String source){
//store shortest path from source to current calculating point
Hashtable distance = new Hashtable();
//store the paths
Hashtable previous = new Hashtable();
//store all need to be computed nodes
List nodes = new ArrayList();

//inialize the dist and previous;
for (Entry> 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 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 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 dist, List nodes){
int distance = LARGE_NUMBER;
String node = "";
for(Entry entry : dist.entrySet()){
String key = entry.getKey();
if(nodes.contains(key)){
int value = entry.getValue().intValue();
if(value distance = value;
node = key;
}
}
}
return node;
}
//print the route from source to target
public void printOutPath(Hashtable path, String source, String target) {
for (Entry entry : path.entrySet()) {
String currentNode = entry.getKey();
String previousNode = entry.getValue();
if (currentNode.equals(target)) {
List pathList = new ArrayList();
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 path, String source){
for (Entry entry : path.entrySet()) {
String currentNode = entry.getKey();
String previousNode = entry.getValue();

List pathList = new ArrayList();
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> graph = new Hashtable>();

Hashtable neighbors1 = new Hashtable();
neighbors1.put("B", 2);
neighbors1.put("C", 1);
graph.put("A", neighbors1);

Hashtable neighbors2 = new Hashtable();
neighbors2.put("D", 3);
graph.put("B", neighbors2);

Hashtable neighbors3 = new Hashtable();
neighbors3.put("D", 1);
graph.put("C", neighbors3);

Hashtable neighbors4 = new Hashtable();
neighbors4.put("E", 2);
neighbors4.put("F", 3);
graph.put("D", neighbors4);

Hashtable neighbors5 = new Hashtable();
graph.put("E", neighbors5);

Hashtable neighbors6 = new Hashtable();
graph.put("F", neighbors6);

DijkstraAlgorithm dijkstra = new DijkstraAlgorithm();
Hashtable path = dijkstra.DijkstraAlgorithm(graph, "A");
dijkstra.printOutRoutes(path, "A");
dijkstra.printOutPath(path, "A", "E");

}

}


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

你可能感兴趣的:(算法笔记)