{"id":26420,"date":"2017-10-26T22:07:38","date_gmt":"2017-10-26T16:37:38","guid":{"rendered":"https:\/\/www.wikitechy.com\/technology\/?p=26420"},"modified":"2017-10-26T22:07:38","modified_gmt":"2017-10-26T16:37:38","slug":"python-algorithm-find-maximum-number-edge-disjoint-paths-two-vertices","status":"publish","type":"post","link":"https:\/\/www.wikitechy.com\/technology\/python-algorithm-find-maximum-number-edge-disjoint-paths-two-vertices\/","title":{"rendered":"Python Algorithm &#8211; Find maximum number of edge disjoint paths between two vertices"},"content":{"rendered":"<p>Given a directed graph and two vertices in it, source \u2018s\u2019 and destination \u2018t\u2019, find out the maximum number of edge disjoint paths from s to t.<span id=\"more-123305\"><\/span> Two paths are said edge disjoint if they don\u2019t share any edge.<\/p>\n<p>&nbsp;<\/p>\n<p>There can be maximum two edge disjoint paths from source 0 to destination 7 in the above graph. Two edge disjoint paths are highlighted below in red and blue colors are 0-2-6-7 and 0-3-6-5-7.<\/p>\n<p>&nbsp;<\/p>\n<p>Note that the paths may be different, but the maximum number is same. For example, in the above diagram, another possible set of paths is 0-1-2-6-7 and 0-3-6-5-7 respectively.<\/p>\n<p>This problem can be solved by reducing it to <a href=\"http:\/\/www.geeksforgeeks.org\/ford-fulkerson-algorithm-for-maximum-flow-problem\/\" target=\"_blank\" rel=\"noopener noreferrer\">maximum flow problem<\/a>. Following are steps.<br \/>\n<strong>1)<\/strong> Consider the given source and destination as source and sink in flow network. Assign unit capacity to each edge.<br \/>\n<strong>2)<\/strong> Run Ford-Fulkerson algorithm to find the maximum flow from source to sink.<br \/>\n<strong>3)<\/strong> The maximum flow is equal to the maximum number of edge-disjoint paths.<\/p>\n<p>When we run Ford-Fulkerson, we reduce the capacity by a unit. Therefore, the edge can not be used again. So the maximum flow is equal to the maximum number of edge-disjoint paths.<\/p>\n[ad type=&#8221;banner&#8221;]\n<p>Following is C++ implementation of the above algorithm. Most of the code is taken from <a href=\"http:\/\/www.geeksforgeeks.org\/ford-fulkerson-algorithm-for-maximum-flow-problem\/\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a>.<\/p>\n<p><strong>Python Programming:<\/strong><\/p>\n<div class=\"code-embed-wrapper\"> <div class=\"code-embed-infos\"> <\/div> <pre class=\"language-python code-embed-pre line-numbers\"  data-start=\"1\" data-line-offset=\"0\"><code class=\"language-python code-embed-code\"># Python program to find maximum number of edge disjoint paths<br\/># Complexity : (E*(V^3))<br\/># Total augmenting path = VE <br\/># and BFS with adj matrix takes :V^2 times<br\/>  <br\/>from collections import defaultdict<br\/>  <br\/>#This class represents a directed graph using <br\/># adjacency matrix representation<br\/>class Graph:<br\/>  <br\/>    def __init__(self,graph):<br\/>        self.graph = graph # residual graph<br\/>        self. ROW = len(graph)<br\/>         <br\/>  <br\/>    &#039;&#039;&#039;Returns true if there is a path from source &#039;s&#039; to sink &#039;t&#039; in<br\/>    residual graph. Also fills parent[] to store the path &#039;&#039;&#039;<br\/>    def BFS(self,s, t, parent):<br\/> <br\/>        # Mark all the vertices as not visited<br\/>        visited =[False]*(self.ROW)<br\/>         <br\/>        # Create a queue for BFS<br\/>        queue=[]<br\/>         <br\/>        # Mark the source node as visited and enqueue it<br\/>        queue.append(s)<br\/>        visited[s] = True<br\/>         <br\/>        # Standard BFS Loop<br\/>        while queue:<br\/> <br\/>            #Dequeue a vertex from queue and print it<br\/>            u = queue.pop(0)<br\/>         <br\/>            # Get all adjacent vertices of the dequeued vertex u<br\/>            # If a adjacent has not been visited, then mark it<br\/>            # visited and enqueue it<br\/>            for ind, val in enumerate(self.graph[u]):<br\/>                if visited[ind] == False and val &gt; 0 :<br\/>                    queue.append(ind)<br\/>                    visited[ind] = True<br\/>                    parent[ind] = u<br\/> <br\/>        # If we reached sink in BFS starting from source, then return<br\/>        # true, else false<br\/>        return True if visited[t] else False<br\/>             <br\/>     <br\/>    # Returns tne maximum number of edge-disjoint paths from <br\/>    #s to t in the given graph<br\/>    def findDisjointPaths(self, source, sink):<br\/> <br\/>        # This array is filled by BFS and to store path<br\/>        parent = [-1]*(self.ROW)<br\/> <br\/>        max_flow = 0 # There is no flow initially<br\/> <br\/>        # Augment the flow while there is path from source to sink<br\/>        while self.BFS(source, sink, parent) :<br\/> <br\/>            # Find minimum residual capacity of the edges along the<br\/>            # path filled by BFS. Or we can say find the maximum flow<br\/>            # through the path found.<br\/>            path_flow = float(&quot;Inf&quot;)<br\/>            s = sink<br\/>            while(s !=  source):<br\/>                path_flow = min (path_flow, self.graph[parent[s]][s])<br\/>                s = parent[s]<br\/> <br\/>            # Add path flow to overall flow<br\/>            max_flow +=  path_flow<br\/> <br\/>            # update residual capacities of the edges and reverse edges<br\/>            # along the path<br\/>            v = sink<br\/>            while(v !=  source):<br\/>                u = parent[v]<br\/>                self.graph[u][v] -= path_flow<br\/>                self.graph[v][u] += path_flow<br\/>                v = parent[v]<br\/> <br\/>        return max_flow<br\/> <br\/>  <br\/># Create a graph given in the above diagram<br\/> <br\/>graph = [[0, 1, 1, 1, 0, 0, 0, 0],<br\/>        [0, 0, 1, 0, 0, 0, 0, 0],<br\/>        [0, 0, 0, 1, 0, 0, 1, 0],<br\/>        [0, 0, 0, 0, 0, 0, 1, 0],<br\/>        [0, 0, 1, 0, 0, 0, 0, 1],<br\/>        [0, 1, 0, 0, 0, 0, 0, 1],<br\/>        [0, 0, 0, 0, 0, 1, 0, 1],<br\/>        [0, 0, 0, 0, 0, 0, 0, 0]]<br\/>  <br\/> <br\/>g = Graph(graph)<br\/> <br\/>source = 0; sink = 7<br\/>  <br\/>print (&quot;There can be maximum %d edge-disjoint paths from %d to %d&quot; %<br\/>            (g.findDisjointPaths(source, sink), source, sink))<br\/> <br\/> <br\/>#This code is contributed by Neelam Yadav<\/code><\/pre> <\/div>\n<p><strong>Output:<\/strong><\/p>\n<pre>There can be maximum 2 edge-disjoint paths from 0 to 7<\/pre>\n<p><strong>Time Complexity: <\/strong>Same as time complexity of Edmonds-Karp implementation of Ford-Fulkerson<\/p>\n[ad type=&#8221;banner&#8221;]\n","protected":false},"excerpt":{"rendered":"<p>Python Algorithm &#8211; Find maximum number of edge disjoint paths between two vertices &#8211; Graph Algorithm &#8211; Given a directed graph and two vertices in it, source<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[69969,1,73906,78429,4148],"tags":[78743,78742,78746,78741,78738,78745,78747,78736,78740,78739,78748],"class_list":["post-26420","post","type-post","status-publish","format-standard","hentry","category-algorithm","category-coding","category-graph-algorithms","category-maximum-flow","category-python","tag-disjoint-paths-in-a-network","tag-edge-disjoint-definition","tag-edge-disjoint-path-definition","tag-edge-disjoint-paths-example","tag-edge-disjoint-paths-undirected-graph","tag-edge-disjoint-subgraph","tag-node-disjoint-path","tag-vertex-disjoint-path","tag-vertex-disjoint-path-problem","tag-vertex-disjoint-paths-max-flow","tag-what-is-edge-disjoint-path"],"_links":{"self":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/26420","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/comments?post=26420"}],"version-history":[{"count":0,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/26420\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/media?parent=26420"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/categories?post=26420"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/tags?post=26420"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}