Dijkstra 在Java中使用 PriorityQueue 的最短路径算法
Dijkstra 的算法与 Prim 的最小生成树算法非常相似。与 Prim 的 MST 一样,我们生成以给定源为根的SPT(最短路径树) 。我们维护两组,一组包含包含在最短路径树中的顶点,另一组包含尚未包含在最短路径树中的顶点。在算法的每一步,我们都会找到另一个集合(尚未包含的集合)中的一个顶点,并且与源的距离最小。
这里 Dijkstra 算法的唯一缺点是,在找到如下所列的最短路径时,我们需要通过整个成本数组来找到成本最低的路径。对于小图来说没什么大不了的,同时对于大图来说也是一个效率问题,因为每次我们在遍历时都需要遍历一个数组。现在我们知道队列可以为我们工作,所以我们将优先级队列的概念应用到这个算法中,以消除一些缺点并使复杂性变得更好。
现在让我们讨论问题陈述,而根据标题,它似乎是一种称为优先级队列的数据结构的纯粹实现,其中涉及算法分析。因此,让我们从下面列出的问题陈述开始,因为整个概念都围绕邻接矩阵表示展开。
Note: Dijkstra’s shortest Path implementations like Dijkstra’s Algorithm for Adjacency Matrix Representation (With time complexity O(v2)
问题陈述
给定一个具有节点之间边的邻接表表示的图,任务是使用Java中的 Priority Queue 实现 Dijkstra 的单源最短路径算法。给定一个图和图中的一个源顶点,找到从源到给定图中所有顶点的最短路径。
插图:
Input : Source = 0
Output :
Vertex Distance from Source
0 0
1 4
2 12
3 19
4 21
5 11
6 9
7 8
8 14
执行:
Java
// Java Program to Implement Dijkstra's Algorithm
// Using Priority Queue
// Importing utility classes
import java.util.*;
// Main class DPQ
public class GFG {
// Member variables of this class
private int dist[];
private Set settled;
private PriorityQueue pq;
// Number of vertices
private int V;
List > adj;
// Constructor of this class
public GFG(int V)
{
// This keyword refers to current object itself
this.V = V;
dist = new int[V];
settled = new HashSet();
pq = new PriorityQueue(V, new Node());
}
// Method 1
// Dijkstra's Algorithm
public void dijkstra(List > adj, int src)
{
this.adj = adj;
for (int i = 0; i < V; i++)
dist[i] = Integer.MAX_VALUE;
// Add source node to the priority queue
pq.add(new Node(src, 0));
// Distance to the source is 0
dist[src] = 0;
while (settled.size() != V) {
// Terminating condition check when
// the priority queue is empty, return
if (pq.isEmpty())
return;
// Removing the minimum distance node
// from the priority queue
int u = pq.remove().node;
// Adding the node whose distance is
// finalized
if (settled.contains(u))
// Continue keyword skips exwcution for
// following check
continue;
// We don't have to call e_Neighbors(u)
// if u is already present in the settled set.
settled.add(u);
e_Neighbours(u);
}
}
// Method 2
// To process all the neighbours
// of the passed node
private void e_Neighbours(int u)
{
int edgeDistance = -1;
int newDistance = -1;
// All the neighbors of v
for (int i = 0; i < adj.get(u).size(); i++) {
Node v = adj.get(u).get(i);
// If current node hasn't already been processed
if (!settled.contains(v.node)) {
edgeDistance = v.cost;
newDistance = dist[u] + edgeDistance;
// If new distance is cheaper in cost
if (newDistance < dist[v.node])
dist[v.node] = newDistance;
// Add the current node to the queue
pq.add(new Node(v.node, dist[v.node]));
}
}
}
// Main driver method
public static void main(String arg[])
{
int V = 5;
int source = 0;
// Adjacency list representation of the
// connected edges by declaring List class object
// Declaring object of type List
List > adj
= new ArrayList >();
// Initialize list for every node
for (int i = 0; i < V; i++) {
List item = new ArrayList();
adj.add(item);
}
// Inputs for the GFG(dpq) graph
adj.get(0).add(new Node(1, 9));
adj.get(0).add(new Node(2, 6));
adj.get(0).add(new Node(3, 5));
adj.get(0).add(new Node(4, 3));
adj.get(2).add(new Node(1, 2));
adj.get(2).add(new Node(3, 4));
// Calculating the single source shortest path
GFG dpq = new GFG(V);
dpq.dijkstra(adj, source);
// Printing the shortest path to all the nodes
// from the source node
System.out.println("The shorted path from node :");
for (int i = 0; i < dpq.dist.length; i++)
System.out.println(source + " to " + i + " is "
+ dpq.dist[i]);
}
}
// Class 2
// Helper class implementing Comparator interface
// Representing a node in the graph
class Node implements Comparator {
// Member variables of this class
public int node;
public int cost;
// Constructors of this class
// Constructor 1
public Node() {}
// Constructor 2
public Node(int node, int cost)
{
// This keyword refers to current instance itself
this.node = node;
this.cost = cost;
}
// Method 1
@Override public int compare(Node node1, Node node2)
{
if (node1.cost < node2.cost)
return -1;
if (node1.cost > node2.cost)
return 1;
return 0;
}
}
The shorted path from node :
0 to 0 is 0
0 to 1 is 8
0 to 2 is 6
0 to 3 is 5
0 to 4 is 3