Dijkstra算法的效率是否正确?

时间:2015-12-08 10:48:31

标签: java performance big-o dijkstra

我有一个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;
    }

} 

0 个答案:

没有答案