Skip to content

Commit b177018

Browse files
Merge pull request #460 from shubhamgpt198/master
Karger's Algo/C++/Karger_Algo.cpp
2 parents 89106c0 + bb9b8ee commit b177018

File tree

1 file changed

+193
-0
lines changed

1 file changed

+193
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
// Karger's algorithm to find Minimum Cut in an
2+
// undirected, unweighted and connected graph.
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
#include <time.h>
6+
7+
// a structure to represent a unweighted edge in graph
8+
struct edge
9+
{
10+
int src, dest;
11+
};
12+
13+
// a structure to represent a connected, undirected
14+
// and unweighted graph as a collection of edges.
15+
struct Graph
16+
{
17+
// V-> Number of vertices, E-> Number of edges
18+
int V, E;
19+
20+
// graph is represented as an array of edges.
21+
// Since the graph is undirected, the edge
22+
// from src to dest is also edge from dest
23+
// to src. Both are counted as 1 edge here.
24+
edge* edge;
25+
};
26+
27+
// A structure to represent a sub_set for union-find
28+
struct sub_set
29+
{
30+
int parent;
31+
int rank;
32+
};
33+
34+
// Function prototypes for union-find (These functions are defined
35+
// after karger_min_cut() )
36+
int find(struct sub_set subsets[], int i);
37+
void union(struct sub_set subsets[], int x, int y);
38+
39+
// A very basic implementation of Karger's randomized
40+
// algorithm for finding the minimum cut. Please note
41+
// that Karger's algorithm is a Monte Carlo Randomized algo
42+
// and the cut returned by the algorithm may not be
43+
// minimum always
44+
int karger_min_cut(struct Graph* graph)
45+
{
46+
// Get data of given graph
47+
int V = graph->V, E = graph->E;
48+
edge *edge = graph->edge;
49+
50+
// Allocate memory for creating V subsets.
51+
struct sub_set *subsets = new sub_set[V];
52+
53+
// Create V subsets with single elements
54+
for (int v = 0; v < V; ++v)
55+
{
56+
subsets[v].parent = v;
57+
subsets[v].rank = 0;
58+
}
59+
60+
// Initially there are V vertices in
61+
// contracted graph
62+
int vertices = V;
63+
64+
// Keep contracting vertices until there are
65+
// 2 vertices.
66+
while (vertices > 2)
67+
{
68+
// Pick a random edge
69+
int i = rand() % E;
70+
71+
// Find vertices (or sets) of two corners
72+
// of current edge
73+
int subset1 = find(subsets, edge[i].src);
74+
int subset2 = find(subsets, edge[i].dest);
75+
76+
// If two corners belong to same sub_set,
77+
// then no point considering this edge
78+
if (subset1 == subset2)
79+
continue;
80+
81+
// Else contract the edge (or combine the
82+
// corners of edge into one vertex)
83+
else
84+
{
85+
printf("Contracting edge %d-%d\n",
86+
edge[i].src, edge[i].dest);
87+
vertices--;
88+
union(subsets, subset1, subset2);
89+
}
90+
}
91+
92+
// Now we have two vertices (or subsets) left in
93+
// the contracted graph, so count the edges between
94+
// two components and return the count.
95+
int cutedges = 0;
96+
for (int i=0; i<E; i++)
97+
{
98+
int subset1 = find(subsets, edge[i].src);
99+
int subset2 = find(subsets, edge[i].dest);
100+
if (subset1 != subset2)
101+
cutedges++;
102+
}
103+
104+
return cutedges;
105+
}
106+
107+
// A utility function to find set of an element i
108+
// (uses path compression technique)
109+
int find(struct sub_set subsets[], int i)
110+
{
111+
// find root and make root as parent of i
112+
// (path compression)
113+
if (subsets[i].parent != i)
114+
subsets[i].parent =
115+
find(subsets, subsets[i].parent);
116+
117+
return subsets[i].parent;
118+
}
119+
120+
// A function that does union of two sets of x and y
121+
// (uses union by rank)
122+
void union(struct sub_set subsets[], int x, int y)
123+
{
124+
int xroot = find(subsets, x);
125+
int yroot = find(subsets, y);
126+
127+
// Attach smaller rank tree under root of high
128+
// rank tree (union by Rank)
129+
if (subsets[xroot].rank < subsets[yroot].rank)
130+
subsets[xroot].parent = yroot;
131+
else if (subsets[xroot].rank > subsets[yroot].rank)
132+
subsets[yroot].parent = xroot;
133+
134+
// If ranks are same, then make one as root and
135+
// increment its rank by one
136+
else
137+
{
138+
subsets[yroot].parent = xroot;
139+
subsets[xroot].rank++;
140+
}
141+
}
142+
143+
// Creates a graph with V vertices and E edges
144+
struct Graph* create_graph(int V, int E)
145+
{
146+
Graph* graph = new Graph;
147+
graph->V = V;
148+
graph->E = E;
149+
graph->edge = new edge[E];
150+
return graph;
151+
}
152+
153+
// Driver program to test above functions
154+
int main()
155+
{
156+
/* Let us create following unweighted graph
157+
0------1
158+
| \ |
159+
| \ |
160+
| \|
161+
2------3 */
162+
int V = 4; // Number of vertices in graph
163+
int E = 5; // Number of edges in graph
164+
struct Graph* graph = create_graph(V, E);
165+
166+
// add edge 0-1
167+
graph->edge[0].src = 0;
168+
graph->edge[0].dest = 1;
169+
170+
// add edge 0-2
171+
graph->edge[1].src = 0;
172+
graph->edge[1].dest = 2;
173+
174+
// add edge 0-3
175+
graph->edge[2].src = 0;
176+
graph->edge[2].dest = 3;
177+
178+
// add edge 1-3
179+
graph->edge[3].src = 1;
180+
graph->edge[3].dest = 3;
181+
182+
// add edge 2-3
183+
graph->edge[4].src = 2;
184+
graph->edge[4].dest = 3;
185+
186+
// Use a different seed value for every run.
187+
srand(time(NULL));
188+
189+
printf("\nCut found by Karger's randomized algo is %d\n",
190+
karger_min_cut(graph));
191+
192+
return 0;
193+
}

0 commit comments

Comments
 (0)