简体   繁体   English

Dijkstra算法是否跟踪访问的节点以找到最短路径?

[英]Does Dijkstra algorithm keep track of visited nodes to find the shortest path?

I found this code for Dijkstra algorithm to find shortest path between two nodes in a weighted graph. 我发现Dijkstra algorithm 这个代码可以在加权图中找到两个节点之间的最短路径。 what I see is that the code does not keep track of visited nodes. 我看到的是代码没有跟踪被访问的节点。 however it works fine for all inputs I tried. 但它适用于我尝试的所有输入。 I added a line of code to keep track of visited nodes. 我添加了一行代码来跟踪访问过的节点。 It still works fine. 它仍然可以正常工作。 I have commented out in this code. 我在这段代码中已经注释掉了。 so is it a requirement to have the visited nodes or not? 那么是否要求访问节点? does it have any influence O 它有什么影响O

import java.util.PriorityQueue;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

class Vertex implements Comparable<Vertex>
{
    public final String name;
    public Edge[] adjacencies;
    public double minDistance = Double.POSITIVE_INFINITY;
    public Vertex previous;
    public Vertex(String argName) { name = argName; }
    public String toString() { return name; }
    public int compareTo(Vertex other)
    {
        return Double.compare(minDistance, other.minDistance);
    }
}

class Edge
{
    public final Vertex target;
    public final double weight;
    public Edge(Vertex argTarget, double argWeight)
    { target = argTarget; weight = argWeight; }
}

public class Dijkstra
{
    public static void computePaths(Vertex source)
    {
        source.minDistance = 0.;
        PriorityQueue<Vertex> vertexQueue = new PriorityQueue<Vertex>();
        //Set<Vertex> visited = new HashSet<Vertex>();
        vertexQueue.add(source);

    while (!vertexQueue.isEmpty()) {
        Vertex u = vertexQueue.poll();

            // Visit each edge exiting u
            for (Edge e : u.adjacencies)
            {
                Vertex v = e.target;
                double weight = e.weight;
                double distanceThroughU = u.minDistance + weight;
           //if (!visited.contains(u)){
        if (distanceThroughU < v.minDistance) {
            vertexQueue.remove(v);
            v.minDistance = distanceThroughU ;
            v.previous = u;
            vertexQueue.add(v);
                visited.add(u)
        //}
            }
        }
    }
}

    public static List<Vertex> getShortestPathTo(Vertex target)
    {
        List<Vertex> path = new ArrayList<Vertex>();
        for (Vertex vertex = target; vertex != null; vertex = vertex.previous)
            path.add(vertex);
        Collections.reverse(path);
        return path;
    }

    public static void main(String[] args)
    {
        Vertex v0 = new Vertex("Redvile");
    Vertex v1 = new Vertex("Blueville");
    Vertex v2 = new Vertex("Greenville");
    Vertex v3 = new Vertex("Orangeville");
    Vertex v4 = new Vertex("Purpleville");

    v0.adjacencies = new Edge[]{ new Edge(v1, 5),
                                 new Edge(v2, 10),
                               new Edge(v3, 8) };
    v1.adjacencies = new Edge[]{ new Edge(v0, 5),
                                 new Edge(v2, 3),
                                 new Edge(v4, 7) };
    v2.adjacencies = new Edge[]{ new Edge(v0, 10),
                               new Edge(v1, 3) };
    v3.adjacencies = new Edge[]{ new Edge(v0, 8),
                                 new Edge(v4, 2) };
    v4.adjacencies = new Edge[]{ new Edge(v1, 7),
                               new Edge(v3, 2) };
    Vertex[] vertices = { v0, v1, v2, v3, v4 };
        computePaths(v0);
        for (Vertex v : vertices)
    {
        System.out.println("Distance to " + v + ": " + v.minDistance);
        List<Vertex> path = getShortestPathTo(v);
        System.out.println("Path: " + path);
    }
    }
}

Dijkstra's algorithm does not need to track visited vertices because it prioritizes those with the shortest total path. Dijkstra的算法不需要跟踪被访问的顶点,因为它优先考虑具有最短总路径的那些顶点。

For vertices that are not immediately connected to the starting node, they are considered to have an infinitely long path when the algorithm starts. 对于未立即连接到起始节点的顶点,当算法启动时,它们被认为具有无限长的路径。 Once a vertex is visited, all of its neighbors' total distances are updated with the distance to the current vertex plus the cost to travel between the two. 一旦访问了一个顶点,其所有邻居的总距离都会根据到当前顶点的距离加上两者之间的旅行成本进行更新。

The code could have been simpler, but irrespective of that, Djikstra is greedy, so at each node, we try to find the node with the shortest path. 代码本来可以更简单,但无论如何,Djikstra都很贪婪,所以在每个节点,我们都试图找到最短路径的节点。 Unless there are negative edges, then nodes that are already visited would already be populated with the shortest path, so naturally, the condition if (distanceThroughU < v.minDistance) will never be true for visited nodes. 除非存在负边缘,否则已经访问过的节点已经填充了最短路径,因此自然地,条件if(distanceThroughU <v.minDistance)对于访问节点永远不会成立。

Regarding the run time complexity, there would be not much difference between your two implementations. 关于运行时复杂性,两个实现之间没有太大区别。

None of commented lines contain code which is responsible for adding Vertex object to visited Set. 评论行中没有一行包含负责将Vertex 对象添加到访问集的代码。 It looks like: 看起来像:

(!visited.contains(u))

is always true :) 永远是真的:)

Apart from this, you don't need to know visited nodes to make use of algorithm. 除此之外,您不需要知道访问过的节点就可以使用算法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM