{"id":26593,"date":"2017-12-21T20:11:52","date_gmt":"2017-12-21T14:41:52","guid":{"rendered":"https:\/\/www.wikitechy.com\/technology\/?p=26593"},"modified":"2017-12-21T20:11:52","modified_gmt":"2017-12-21T14:41:52","slug":"c-programming-kargers-algorithm-minimum-cut-introduction-implementation","status":"publish","type":"post","link":"https:\/\/www.wikitechy.com\/technology\/c-programming-kargers-algorithm-minimum-cut-introduction-implementation\/","title":{"rendered":"C++ Programming &#8211; Karger\u2019s algorithm for Minimum Cut Introduction and Implementation"},"content":{"rendered":"<p>Given an undirected and unweighted graph, find the smallest cut (smallest number of edges that disconnects the graph into two components).<span id=\"more-134854\"><\/span><br \/>\nThe input graph may have parallel edges.<\/p>\n<p>For example consider the following example, the smallest cut has 2 edges.<\/p>\n<p><img fetchpriority=\"high\" decoding=\"async\" class=\"aligncenter size-full wp-image-26598\" src=\"https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Kargerfirst.png\" alt=\"first\" width=\"344\" height=\"264\" srcset=\"https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Kargerfirst.png 344w, https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Kargerfirst-300x230.png 300w\" sizes=\"(max-width: 344px) 100vw, 344px\" \/><\/p>\n<p>A Simple Solution use Max-Flow based s-t cut algorithm to find minimum cut. Consider every pair of vertices as source \u2018s\u2019 and sink \u2018t\u2019, and call minimum s-t cut algorithm to find the s-t cut. Return minimum of all s-t cuts. Best possible time complexity of this algorithm is O(V5) for a graph. [How? there are total possible V2 pairs and s-t cut algorithm for one pair takes O(V*E) time and E = O(V2)].<\/p>\n[ad type=&#8221;banner&#8221;]\n<p>Below is simple Karger\u2019s Algorithm for this purpose. Below Karger\u2019s algorithm can be implemented in O(E) = O(V2) time.<\/p>\n<p>1) Initialize contracted graph CG as copy of original graph<br \/>\n2) While there are more than 2 vertices.<br \/>\na) Pick a random edge (u, v) in the contracted graph.<br \/>\nb) Merge (or contract) u and v into a single vertex (update<br \/>\nthe contracted graph).<br \/>\nc) Remove self-loops<br \/>\n3) Return cut represented by two vertices.<br \/>\nLet us understand above algorithm through the example given.<\/p>\n<p>Let the first randomly picked vertex be \u2018a\u2018 which connects vertices 0 and 1. We remove this edge and contract the graph (combine vertices 0 and 1). We get the following graph.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-26597\" src=\"https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Karger21.png\" alt=\"\" width=\"342\" height=\"222\" srcset=\"https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Karger21.png 342w, https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Karger21-300x195.png 300w\" sizes=\"(max-width: 342px) 100vw, 342px\" \/><\/p>\n<p>Let the next randomly picked edge be \u2018d\u2019. We remove this edge and combine vertices (0,1) and 3.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-26599\" src=\"https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Karger3-1.png\" alt=\"three\" width=\"320\" height=\"131\" srcset=\"https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Karger3-1.png 320w, https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Karger3-1-300x123.png 300w\" sizes=\"(max-width: 320px) 100vw, 320px\" \/><\/p>\n<p>We need to remove self-loops in the graph. So we remove edge \u2018c\u2019<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-26595\" src=\"https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Karger4.png\" alt=\"\" width=\"312\" height=\"92\" srcset=\"https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Karger4.png 312w, https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Karger4-300x88.png 300w\" sizes=\"(max-width: 312px) 100vw, 312px\" \/><\/p>\n<p>Now graph has two vertices, so we stop. The number of edges in the resultant graph is the cut produced by Karger\u2019s algorithm.<\/p>\n<p>Karger\u2019s algorithm is a Monte Carlo algorithm and cut produced by it may not be minimum.<\/p>\n<p>For example, the following diagram shows that a different order of picking random edges produces a min-cut of size 3.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-26596\" src=\"https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Karger11.png\" alt=\"four\" width=\"783\" height=\"510\" srcset=\"https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Karger11.png 783w, https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Karger11-300x195.png 300w, https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Karger11-768x500.png 768w, https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Karger11-130x86.png 130w\" sizes=\"(max-width: 783px) 100vw, 783px\" \/><\/p>\n<p>Below is C++ implementation of above algorithm. The input graph is represented as a collection of edges and union-find data structure is used to keep track of components.<\/p>\n<div class=\"code-embed-wrapper\"> <div class=\"code-embed-infos\"> <span class=\"code-embed-name\">C++ Program<\/span> <\/div> <pre class=\"language-cpp code-embed-pre line-numbers\"  data-start=\"1\" data-line-offset=\"0\"><code class=\"language-cpp code-embed-code\">\/\/ Karger&#039;s algorithm to find Minimum Cut in an<br\/>\/\/ undirected, unweighted and connected graph.<br\/>#include &lt;stdio.h&gt;<br\/>#include &lt;stdlib.h&gt;<br\/>#include &lt;time.h&gt;<br\/> <br\/>\/\/ a structure to represent a unweighted edge in graph<br\/>struct Edge<br\/>{<br\/>    int src, dest;<br\/>};<br\/> <br\/>\/\/ a structure to represent a connected, undirected<br\/>\/\/ and unweighted graph as a collection of edges.<br\/>struct Graph<br\/>{<br\/>    \/\/ V-&gt; Number of vertices, E-&gt; Number of edges<br\/>    int V, E;<br\/> <br\/>    \/\/ graph is represented as an array of edges.<br\/>    \/\/ Since the graph is undirected, the edge<br\/>    \/\/ from src to dest is also edge from dest<br\/>    \/\/ to src. Both are counted as 1 edge here.<br\/>    Edge* edge;<br\/>};<br\/> <br\/>\/\/ A structure to represent a subset for union-find<br\/>struct subset<br\/>{<br\/>    int parent;<br\/>    int rank;<br\/>};<br\/> <br\/>\/\/ Function prototypes for union-find (These functions are defined<br\/>\/\/ after kargerMinCut() )<br\/>int find(struct subset subsets[], int i);<br\/>void Union(struct subset subsets[], int x, int y);<br\/> <br\/>\/\/ A very basic implementation of Karger&#039;s randomized<br\/>\/\/ algorithm for finding the minimum cut. Please note<br\/>\/\/ that Karger&#039;s algorithm is a Monte Carlo Randomized algo<br\/>\/\/ and the cut returned by the algorithm may not be<br\/>\/\/ minimum always<br\/>int kargerMinCut(struct Graph* graph)<br\/>{<br\/>    \/\/ Get data of given graph<br\/>    int V = graph-&gt;V, E = graph-&gt;E;<br\/>    Edge *edge = graph-&gt;edge;<br\/> <br\/>    \/\/ Allocate memory for creating V subsets.<br\/>    struct subset *subsets = new subset[V];<br\/> <br\/>    \/\/ Create V subsets with single elements<br\/>    for (int v = 0; v &lt; V; ++v)<br\/>    {<br\/>        subsets[v].parent = v;<br\/>        subsets[v].rank = 0;<br\/>    }<br\/> <br\/>    \/\/ Initially there are V vertices in<br\/>    \/\/ contracted graph<br\/>    int vertices = V;<br\/> <br\/>    \/\/ Keep contracting vertices until there are<br\/>    \/\/ 2 vertices.<br\/>    while (vertices &gt; 2)<br\/>    {<br\/>       \/\/ Pick a random edge<br\/>       int i = rand() % E;<br\/> <br\/>       \/\/ Find vertices (or sets) of two corners<br\/>       \/\/ of current edge<br\/>       int subset1 = find(subsets, edge[i].src);<br\/>       int subset2 = find(subsets, edge[i].dest);<br\/> <br\/>       \/\/ If two corners belong to same subset,<br\/>       \/\/ then no point considering this edge<br\/>       if (subset1 == subset2)<br\/>         continue;<br\/> <br\/>       \/\/ Else contract the edge (or combine the<br\/>       \/\/ corners of edge into one vertex)<br\/>       else<br\/>       {<br\/>          printf(&quot;Contracting edge %d-%d\\n&quot;,<br\/>                 edge[i].src, edge[i].dest);<br\/>          vertices--;<br\/>          Union(subsets, subset1, subset2);<br\/>       }<br\/>    }<br\/> <br\/>    \/\/ Now we have two vertices (or subsets) left in<br\/>    \/\/ the contracted graph, so count the edges between<br\/>    \/\/ two components and return the count.<br\/>    int cutedges = 0;<br\/>    for (int i=0; i&lt;E; i++)<br\/>    {<br\/>        int subset1 = find(subsets, edge[i].src);<br\/>        int subset2 = find(subsets, edge[i].dest);<br\/>        if (subset1 != subset2)<br\/>          cutedges++;<br\/>    }<br\/> <br\/>    return cutedges;<br\/>}<br\/> <br\/>\/\/ A utility function to find set of an element i<br\/>\/\/ (uses path compression technique)<br\/>int find(struct subset subsets[], int i)<br\/>{<br\/>    \/\/ find root and make root as parent of i<br\/>    \/\/ (path compression)<br\/>    if (subsets[i].parent != i)<br\/>      subsets[i].parent =<br\/>             find(subsets, subsets[i].parent);<br\/> <br\/>    return subsets[i].parent;<br\/>}<br\/> <br\/>\/\/ A function that does union of two sets of x and y<br\/>\/\/ (uses union by rank)<br\/>void Union(struct subset subsets[], int x, int y)<br\/>{<br\/>    int xroot = find(subsets, x);<br\/>    int yroot = find(subsets, y);<br\/> <br\/>    \/\/ Attach smaller rank tree under root of high<br\/>    \/\/ rank tree (Union by Rank)<br\/>    if (subsets[xroot].rank &lt; subsets[yroot].rank)<br\/>        subsets[xroot].parent = yroot;<br\/>    else if (subsets[xroot].rank &gt; subsets[yroot].rank)<br\/>        subsets[yroot].parent = xroot;<br\/> <br\/>    \/\/ If ranks are same, then make one as root and<br\/>    \/\/ increment its rank by one<br\/>    else<br\/>    {<br\/>        subsets[yroot].parent = xroot;<br\/>        subsets[xroot].rank++;<br\/>    }<br\/>}<br\/> <br\/>\/\/ Creates a graph with V vertices and E edges<br\/>struct Graph* createGraph(int V, int E)<br\/>{<br\/>    Graph* graph = new Graph;<br\/>    graph-&gt;V = V;<br\/>    graph-&gt;E = E;<br\/>    graph-&gt;edge = new Edge[E];<br\/>    return graph;<br\/>}<br\/> <br\/>\/\/ Driver program to test above functions<br\/>int main()<br\/>{<br\/>    \/* Let us create following unweighted graph<br\/>        0------1<br\/>        | \\    |<br\/>        |   \\  |<br\/>        |     \\|<br\/>        2------3   *\/<br\/>    int V = 4;  \/\/ Number of vertices in graph<br\/>    int E = 5;  \/\/ Number of edges in graph<br\/>    struct Graph* graph = createGraph(V, E);<br\/> <br\/>    \/\/ add edge 0-1<br\/>    graph-&gt;edge[0].src = 0;<br\/>    graph-&gt;edge[0].dest = 1;<br\/> <br\/>    \/\/ add edge 0-2<br\/>    graph-&gt;edge[1].src = 0;<br\/>    graph-&gt;edge[1].dest = 2;<br\/> <br\/>    \/\/ add edge 0-3<br\/>    graph-&gt;edge[2].src = 0;<br\/>    graph-&gt;edge[2].dest = 3;<br\/> <br\/>    \/\/ add edge 1-3<br\/>    graph-&gt;edge[3].src = 1;<br\/>    graph-&gt;edge[3].dest = 3;<br\/> <br\/>    \/\/ add edge 2-3<br\/>    graph-&gt;edge[4].src = 2;<br\/>    graph-&gt;edge[4].dest = 3;<br\/> <br\/>    \/\/ Use a different seed value for every run.<br\/>    srand(time(NULL));<br\/> <br\/>    printf(&quot;\\nCut found by Karger&#039;s randomized algo is %d\\n&quot;,<br\/>           kargerMinCut(graph));<br\/> <br\/>    return 0;<br\/>}<\/code><\/pre> <\/div>\n<p><strong>Output:<\/strong><\/p>\n<pre>Contracting edge 0-2\r\nContracting edge 0-3\r\n\r\nCut found by Karger's randomized algo is 2<\/pre>\n<p>&nbsp;<\/p>\n<p><em><strong>Note that the above program is based on outcome of a random function and may produce different output.<\/strong><\/em><\/p>\n<p>In this post, we have discussed simple Karger\u2019s algorithm and have seen that the algorithm doesn\u2019t always produce min-cut. The above algorithm produces min-cut with probability greater or equal to that 1\/(n<sup>2<\/sup>).<\/p>\n[ad type=&#8221;banner&#8221;]\n","protected":false},"excerpt":{"rendered":"<p>A Simple Solution use Max-Flow based s-t cut algorithm to find minimum cut. Consider every pair of vertices as source \u2018s\u2019 and sink \u2018t\u2019.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[69969,83515,1,73906],"tags":[79250,79244,79246,79247,79249,79241,79243,79240,79248,79242,79245],"class_list":["post-26593","post","type-post","status-publish","format-standard","hentry","category-algorithm","category-c-programming-3","category-coding","category-graph-algorithms","tag-c-programming-kargers-algorithm-for-minimum-cut","tag-david-karger","tag-david-karger-mit","tag-david-r-karger","tag-ef-karger","tag-karger","tag-karger-algorithm","tag-karger-journals","tag-karger-password","tag-kargers-algorithm","tag-s-karger"],"_links":{"self":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/26593","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\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/comments?post=26593"}],"version-history":[{"count":0,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/26593\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/media?parent=26593"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/categories?post=26593"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/tags?post=26593"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}