zoukankan      html  css  js  c++  java
  • algorithm@ Shortest Path in Directed Acyclic Graph (O(|V|+|E|) time)

    Given a Weighted Directed Acyclic Graph and a source vertex in the graph, find the shortest paths from given source to all other vertices.
    For a general weighted graph, we can calculate single source shortest distances in O(VE) time using Bellman–Ford Algorithm. For a graph with no negative weights, we can do better and calculate single source shortest distances in O(E + VLogV) time using Dijkstra’s algorithm. Can we do even better for Directed Acyclic Graph (DAG)? We can calculate single source shortest distances in O(V+E) time for DAGs. The idea is to use Topological Sorting.

    We initialize distances to all vertices as infinite and distance to source as 0, then we find a topological sorting of the graph. Topological Sorting of a graph represents a linear ordering of the graph (See below, figure (b) is a linear representation of figure (a) ). Once we have topological order (or linear representation), we one by one process all vertices in topological order. For every vertex being processed, we update distances of its adjacent using distance of current vertex.

    Following figure is taken from this source. It shows step by step process of finding shortest paths.

    TopologicalSort

    Following is complete algorithm for finding shortest distances.
    1) Initialize dist[] = {INF, INF, ….} and dist[s] = 0 where s is the source vertex.
    2) Create a toplogical order of all vertices.
    3) Do following for every vertex u in topological order.
    ………..Do following for every adjacent vertex v of u
    ………………if (dist[v] > dist[u] + weight(u, v))
    ………………………dist[v] = dist[u] + weight(u, v)

    // Java program to find single source shortest paths in Directed Acyclic Graphs
    import java.io.*;
    import java.util.*;
     
    class ShortestPath
    {
        static final int INF=Integer.MAX_VALUE;
        class AdjListNode
        {
            private int v;
            private int weight;
            AdjListNode(int _v, int _w) { v = _v;  weight = _w; }
            int getV() { return v; }
            int getWeight()  { return weight; }
        }
     
        // Class to represent graph as an adjcency list of
        // nodes of type AdjListNode
        class Graph
        {
            private int V;
            private LinkedList<AdjListNode>adj[];
            Graph(int v)
            {
                V=v;
                adj = new LinkedList[V];
                for (int i=0; i<v; ++i)
                    adj[i] = new LinkedList<AdjListNode>();
            }
            void addEdge(int u, int v, int weight)
            {
                AdjListNode node = new AdjListNode(v,weight);
                adj[u].add(node);// Add v to u's list
            }
     
            // A recursive function used by shortestPath.
            // See below link for details
            void topologicalSortUtil(int v, Boolean visited[], Stack stack)
            {
                // Mark the current node as visited.
                visited[v] = true;
                Integer i;
     
                // Recur for all the vertices adjacent to this vertex
                Iterator<AdjListNode> it = adj[v].iterator();
                while (it.hasNext())
                {
                    AdjListNode node =it.next();
                    if (!visited[node.getV()])
                        topologicalSortUtil(node.getV(), visited, stack);
                }
                // Push current vertex to stack which stores result
                stack.push(new Integer(v));
            }
     
            // The function to find shortest paths from given vertex. It
            // uses recursive topologicalSortUtil() to get topological
            // sorting of given graph.
            void shortestPath(int s)
            {
                Stack stack = new Stack();
                int dist[] = new int[V];
     
                // Mark all the vertices as not visited
                Boolean visited[] = new Boolean[V];
                for (int i = 0; i < V; i++)
                    visited[i] = false;
     
                // Call the recursive helper function to store Topological
                // Sort starting from all vertices one by one
                for (int i = 0; i < V; i++)
                    if (visited[i] == false)
                        topologicalSortUtil(i, visited, stack);
     
                // Initialize distances to all vertices as infinite and
                // distance to source as 0
                for (int i = 0; i < V; i++)
                    dist[i] = INF;
                dist[s] = 0;
     
                // Process vertices in topological order
                while (stack.empty() == false)
                {
                    // Get the next vertex from topological order
                    int u = (int)stack.pop();
     
                    // Update distances of all adjacent vertices
                    Iterator<AdjListNode> it;
                    if (dist[u] != INF)
                    {
                        it = adj[u].iterator();
                        while (it.hasNext())
                        {
                            AdjListNode i= it.next();
                            if (dist[i.getV()] > dist[u] + i.getWeight())
                                dist[i.getV()] = dist[u] + i.getWeight();
                        }
                    }
                }
     
                // Print the calculated shortest distances
                for (int i = 0; i < V; i++)
                {
                    if (dist[i] == INF)
                        System.out.print( "INF ");
                    else
                        System.out.print( dist[i] + " ");
                }
            }
        }
     
        // Method to create a new graph instance through an object
        // of ShortestPath class.
        Graph newGraph(int number)
        {
            return new Graph(number);
        }
     
        public static void main(String args[])
        {
            // Create a graph given in the above diagram.  Here vertex
            // numbers are 0, 1, 2, 3, 4, 5 with following mappings:
            // 0=r, 1=s, 2=t, 3=x, 4=y, 5=z
            ShortestPath t = new ShortestPath();
            Graph g = t.newGraph(6);
            g.addEdge(0, 1, 5);
            g.addEdge(0, 2, 3);
            g.addEdge(1, 3, 6);
            g.addEdge(1, 2, 2);
            g.addEdge(2, 4, 4);
            g.addEdge(2, 5, 2);
            g.addEdge(2, 3, 7);
            g.addEdge(3, 4, -1);
            g.addEdge(4, 5, -2);
     
            int s = 1;
            System.out.println("Following are shortest distances "+
                                "from source " + s );
            g.shortestPath(s);
        }
    }
    

    Output:

    Following are shortest distances from source 1
    INF 0 2 6 5 3 

    Time Complexity: Time complexity of topological sorting is O(V+E). After finding topological order, the algorithm process all vertices and for every vertex, it runs a loop for all adjacent vertices. Total adjacent vertices in a graph is O(E). So the inner loop runs O(V+E) times. Therefore, overall time complexity of this algorithm is O(V+E).

  • 相关阅读:
    MySQL实战45讲
    mysql查看binlog日志
    Nginx核心知识100讲
    RabbitMQ消息为什么变成数字了呢?
    Spring core中一些API
    [LeetCode] 719. Find K-th Smallest Pair Distance 找第K小的数对儿距离
    Github Upload Large File 上传超大文件
    [LeetCode] Special Binary String 特殊的二进制字符串
    [LeetCode] Range Module 范围模块
    [LeetCode] Find Anagram Mappings 寻找异构映射
  • 原文地址:https://www.cnblogs.com/fu11211129/p/5367252.html
Copyright © 2011-2022 走看看