-最近在学习图算法,其中最为经典的就是Dijstra算法,虽然网上有很多用java实现Dijstra算法的代码,但很少使用优先队列进行优化,这段代码是根据《算法导论》一书中所介绍的Dijstra算法的伪代码编写的,简单、通用、高效。
class vertex {
String name;// 节点名称
vertex preNode;// 前驱节点
double distance;// 源节点到该节点的最短路径的估计值
private HashMap<vertex, Double> child = new HashMap<vertex, Double>();// 边的信息,
public vertex(String node) {
// TODO Auto-generated constructor stub
this.name = node;
initial();// 初始化节点信息
}
private void initial() {
this.distance = Integer.MAX_VALUE;
this.preNode = null;
}
public void setDistance(double distance) {
this.distance = distance;
}
public void setPreNode(vertex preNode) {
this.preNode = preNode;
}
public HashMap<vertex, Double> getChild() {
return child;
}
}
public class Dijkstra {
Queue<vertex> Q;// 存储所有节点的优先队列
List<vertex> array_list;// 存储最短路径估计最小的节点
public Dijkstra() {
// TODO Auto-generated constructor stub
Q = new PriorityQueue<>(disComparator);
array_list = new ArrayList<>();
}
Comparator<vertex> disComparator = new Comparator<vertex>() {
@Override
// 以distance作为排序的关键值
public int compare(vertex node1, vertex node2) {
if (node1.distance > node2.distance)
return 1;
else if (node1.distance == node2.distance)
return 0;
else
return -1;
}
};
public void initialGraphy() {
vertex S = new vertex("S");
vertex A = new vertex("A");
vertex B = new vertex("B");
vertex C = new vertex("C");
vertex D = new vertex("D");
// 构造边
S.getChild().put(A, 10.0);
S.getChild().put(C, 5.0);
A.getChild().put(B, 1.0);
A.getChild().put(C, 2.0);
B.getChild().put(D, 4.0);
C.getChild().put(D, 2.0);
C.getChild().put(B, 9.0);
C.getChild().put(A, 3.0);
D.getChild().put(B, 6.0);
D.getChild().put(S, 7.0);
// 设置S为起点
S.setDistance(0.0);
// 将所有节点加入优先队列Q中
Q.offer(S);
Q.offer(A);
Q.offer(B);
Q.offer(C);
Q.offer(D);
}
public void dijstra() {
vertex node;
long time = System.currentTimeMillis();
while ((node = Q.poll()) != null) {
// 进行松弛
for (vertex v : node.getChild().keySet()) {
if (v.distance > node.distance + node.getChild().get(v)) {
v.distance = node.distance + node.getChild().get(v);
v.setPreNode(node);
}
}
array_list.add(node);
}
System.out.println("计算耗时:" + (System.currentTimeMillis() - time) + "ms");
}
public void exportPath() {
for (vertex node : array_list) {
ArrayList<String> path = new ArrayList<>();
double shortestDistance = node.distance;
while (node.preNode != null) {
path.add(node.name);
node = node.preNode;
}
path.add("S");
Collections.reverse(path);
System.out.println(path + "\t最短距离为:" + shortestDistance);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Dijkstra Dijkstra = new Dijkstra();
Dijkstra.initialGraphy();
Dijkstra.dijstra();
Dijkstra.exportPath();
}
}
-测试结果如下:
计算耗时:0ms
[S] 最短距离为:0.0
[S, C, D] 最短距离为:7.0
[S, C] 最短距离为:5.0
[S, C, A] 最短距离为:8.0
[S, C, A, B] 最短距离为:9.0