我有一个Dijkstra算法的版本,我试图确定效率。我不太确定我是否正确,并且想知道我是否做对了。
我知道优先队列版本的效率更高。我将放下伪代码,然后放下下面的java代码,以防我遗漏。
请参阅伪代码中的注释,了解其来源:
O(E^2 * V^2)
DijkstraAlgorithm Pseudocode class
execute method
Input: Source vertex for graph
Output: None
while (unvisited vertexes != 0) { //----> O(V)
node := getMinimum unvisited
visitedNodes.add(node)
unvisitedNodes.remove(node)
findMinimalDistances(node) }
findMinimalDistances method
Input: Vertex
Output: None
adjacentNodes := getAdjacent(node)
for(target to adjacentNodes) {
if (getShortestDistance(target) > getShortestDistance(node) + getDistance(node,target)) {
distance.put(target, distance)
predecessors.put(target, node)
unvisitedNodes.add(target) }
}
getDistance method
Input: Vertex being evaluated and target vertex
Output: Integer distance
for (edge to edges) { //--------------> O(E)
if (edge.source(node) && edge.destination(target)) {
return edge.getWeight }
}
getAdjacent method
Input: Vertex to find ajacent vertexes
Output: ArrayList of adjacent vertexes
for (edge to edges) { // -----------------> O(E)
if (edge.getSource.equals(node) && is not visited)
neighbors.add(node)
}
getMinimum method
Input: ArrayList of unvisited vertexes
Output: Minimum vertex
for (vertex to vertexes) { //---------> O(V)
if (minimum = null)
minimum := vertex
else
if (getShortestDistance(vertex) < getShortestDistance(minimum))
minimum := vertex
}
getShortestDistance method
Input: Node to find shortest distance to source
Output: Integer distance
d := distance.get(node)
if (d = null)
return Infinity
else
return d
以下代码:
package shortestPath;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class DijkstraAlgorithm {
private final List<Vertex> nodes;
private final List<Edge> edges;
private Set<Vertex> visitedNodes;
private Set<Vertex> unvisitedNodes;
private Map<Vertex, Vertex> predecessors;
private Map<Vertex, Integer> distance;
public DijkstraAlgorithm(Graph graph) {
// create a copy of the array so that we can operate on this array
this.nodes = new ArrayList<Vertex>(graph.getVertexes());
this.edges = new ArrayList<Edge>(graph.getEdges());
}
public void execute(Vertex source) {
visitedNodes = new HashSet<Vertex>();
unvisitedNodes = new HashSet<Vertex>();
// Create hashmap for shortest distance to each node
distance = new HashMap<Vertex, Integer>();
predecessors = new HashMap<Vertex, Vertex>();
// Start with the source node
distance.put(source, 0);
unvisitedNodes.add(source);
// While there are still unvisited nodes
while (unvisitedNodes.size() > 0) {
// Hold minimum unvisited node
Vertex node = getMinimum(unvisitedNodes);
visitedNodes.add(node);
unvisitedNodes.remove(node);
// Put the node's distance in the distance map
findMinimalDistances(node);
}
}
// Find shortest distance from current minimum node to neighbors
private void findMinimalDistances(Vertex node) {
// Initialize list to find adjacent nodes
List<Vertex> adjacentNodes = getAdjacent(node);
// Cycle through neighbors
for (Vertex target : adjacentNodes) {
// If i is greater than the node current shortest distance + the distance from node to i
if (getShortestDistance(target) > getShortestDistance(node) + getDistance(node, target)) {
// Update i node to shorter distance in distance map
distance.put(target, getShortestDistance(node) + getDistance(node, target));
predecessors.put(target, node);
unvisitedNodes.add(target);
}
}
}
// Gets distance of node to target vertex
private int getDistance(Vertex node, Vertex target) {
// Cycle through all edges
for (Edge edge : edges) {
// If edge begins at node and ends at target get the distance
if (edge.getSource().equals(node) && edge.getDestination().equals(target)) {
return edge.getWeight();
}
}
throw new RuntimeException("Should not happen");
}
// Find adjacent nodes to input node and return arraylist of neighbors
private List<Vertex> getAdjacent(Vertex node) {
List<Vertex> neighbors = new ArrayList<Vertex>();
// Cycle through all edges
for (Edge edge : edges) {
// If edge source is the input node and destination node of edge is not in visited list
// add as neighbor
if (edge.getSource().equals(node) && !isVisited(edge.getDestination())) {
neighbors.add(edge.getDestination());
}
}
return neighbors;
}
// Returns minimum of unvisited nodes
private Vertex getMinimum(Set<Vertex> vertexes) {
// First pass initialize minimum node to null
Vertex minimum = null;
// Cycle through entire unvisited list for minimum unvisited node
// --> Note: Minimum unvisited node on first iteration is (source node, 0 distance)
for (Vertex vertex : vertexes) {
// If minimum is set to null (first pass), set minimum to first unvisited node
if (minimum == null) {
minimum = vertex;
// Else if next node is less, set it to minimum
} else {
if (getShortestDistance(vertex) < getShortestDistance(minimum)) {
minimum = vertex;
}
}
}
return minimum;
}
private boolean isVisited(Vertex vertex) {
return visitedNodes.contains(vertex);
}
// Get shortest distance of node from source
private int getShortestDistance(Vertex destination) {
// Set d equal to the distance assigned to the node currently in distance map, if available
Integer d = distance.get(destination);
// If node not yet added to distance map
if (d == null) {
// Return infinity
return Integer.MAX_VALUE;
// Else return distance assigned to that node
} else {
return d;
}
}
/*
* This method returns the path from the source to the selected target and
* NULL if no path exists
*/
public LinkedList<Vertex> getPath(Vertex target) {
LinkedList<Vertex> path = new LinkedList<Vertex>();
Vertex step = target;
// check if a path exists
if (predecessors.get(step) == null) {
return null;
}
path.add(step);
while (predecessors.get(step) != null) {
step = predecessors.get(step);
path.add(step);
}
// Put it into the correct order
Collections.reverse(path);
return path;
}
}