Find all cliques of size K in an undirected graph
Given an undirected graph with N nodes and E edges and a value K, the task is to print all set of nodes which form a K size clique.
A clique is a complete subgraph of a graph.
Examples:
Input: N = 5, edges[] = { {1, 2}, {2, 3}, {3, 1}, {4, 3}, {4, 5}, {5, 3} }, K = 3
Output: 1 2 3, 3 4 5
Explanation: Clearly from the image, 1->2->3 and 3->4->5 are the two complete subgraphs.
Input: N = 4, edges[] = { {1, 2}, {2, 3}, {3, 1}, {4, 3} }, k = 3
Output: 1 2 3
Explanation: Subgraph 1-> 2->3 forms a complete subgraph from the given graph.
Approach: The idea is to use recursion to solve the above problem. All the vertices whose degree is greater than or equal to (K-1) are found and checked which subset of K vertices form a clique. When another edge is added to the present list, it is checked if by adding that edge, the list still forms a clique or not.
The following steps can be followed to compute the result:
- Form a recursive function with three parameters starting node, length of the present set of nodes and desired length of nodes.
- The starting index resembles that no node can be added to the present set less than that index. So a loop is run from that index to n.
- If it is found that after adding a node to the present set, the set of nodes remains a clique. If yes, that node is added and the recursive function is called with parameters index of new added node +1, length of current set + 1 and the desired length.
- If the desired length is reached, the nodes are printed.
Below is the implementation of the above approach:
C++
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std; const int MAX = 100; // Stores the vertices int store[MAX], n; // Graph int graph[MAX][MAX]; // Degree of the vertices int d[MAX]; // Function to check if the given set of vertices // in store array is a clique or not bool is_clique( int b) { // Run a loop for all the set of edges // for the select vertex for ( int i = 1; i < b; i++) { for ( int j = i + 1; j < b; j++) // If any edge is missing if (graph[store[i]][store[j]] == 0) return false ; } return true ; } // Function to print the clique void print( int n) { for ( int i = 1; i < n; i++) cout << store[i] << " " ; cout << ", " ; } // Function to find all the cliques of size s void findCliques( int i, int l, int s) { // Check if any vertices from i+1 can be inserted for ( int j = i + 1; j <= n - (s - l); j++) // If the degree of the graph is sufficient if (d[j] >= s - 1) { // Add the vertex to store store[l] = j; // If the graph is not a clique of size k // then it cannot be a clique // by adding another edge if (is_clique(l + 1)) // If the length of the clique is // still less than the desired size if (l < s) // Recursion to add vertices findCliques(j, l + 1, s); // Size is met else print(l + 1); } } // Driver code int main() { int edges[][2] = { { 1, 2 }, { 2, 3 }, { 3, 1 }, { 4, 3 }, { 4, 5 }, { 5, 3 } }, k = 3; int size = sizeof (edges) / sizeof (edges[0]); n = 5; for ( int i = 0; i < size; i++) { graph[edges[i][0]][edges[i][1]] = 1; graph[edges[i][1]][edges[i][0]] = 1; d[edges[i][0]]++; d[edges[i][1]]++; } findCliques(0, 1, k); return 0; } |
Java
// Java implementation of the approach class GFG { static int MAX = 100 ; // Stores the vertices static int []store = new int [MAX]; static int n; // Graph static int [][]graph = new int [MAX][MAX]; // Degree of the vertices static int []d = new int [MAX]; // Function to check if the given set of vertices // in store array is a clique or not static boolean is_clique( int b) { // Run a loop for all the set of edges // for the select vertex for ( int i = 1 ; i < b; i++) { for ( int j = i + 1 ; j < b; j++) // If any edge is missing if (graph[store[i]][store[j]] == 0 ) return false ; } return true ; } // Function to print the clique static void print( int n) { for ( int i = 1 ; i < n; i++) System.out.print(store[i] + " " ); System.out.print( ", " ); } // Function to find all the cliques of size s static void findCliques( int i, int l, int s) { // Check if any vertices from i+1 can be inserted for ( int j = i + 1 ; j <= n - (s - l); j++) // If the degree of the graph is sufficient if (d[j] >= s - 1 ) { // Add the vertex to store store[l] = j; // If the graph is not a clique of size k // then it cannot be a clique // by adding another edge if (is_clique(l + 1 )) // If the length of the clique is // still less than the desired size if (l < s) // Recursion to add vertices findCliques(j, l + 1 , s); // Size is met else print(l + 1 ); } } // Driver code public static void main(String[] args) { int edges[][] = { { 1 , 2 }, { 2 , 3 }, { 3 , 1 }, { 4 , 3 }, { 4 , 5 }, { 5 , 3 } }, k = 3 ; int size = edges.length; n = 5 ; for ( int i = 0 ; i < size; i++) { graph[edges[i][ 0 ]][edges[i][ 1 ]] = 1 ; graph[edges[i][ 1 ]][edges[i][ 0 ]] = 1 ; d[edges[i][ 0 ]]++; d[edges[i][ 1 ]]++; } findCliques( 0 , 1 , k); } } // This code is contributed by 29AjayKumar |
Python3
# Python3 implementation of the approach import numpy as np MAX = 100 ; # Stores the vertices store = [ 0 ] * MAX ; # Graph graph = np.zeros(( MAX , MAX )); # Degree of the vertices d = [ 0 ] * MAX ; # Function to check if the given set of vertices # in store array is a clique or not def is_clique(b) : # Run a loop for all the set of edges # for the select vertex for i in range ( 1 , b) : for j in range (i + 1 , b) : # If any edge is missing if (graph[store[i]][store[j]] = = 0 ) : return False ; return True ; # Function to print the clique def print_cli(n) : for i in range ( 1 , n) : print (store[i], end = " " ); print ( "," , end = " " ); # Function to find all the cliques of size s def findCliques(i, l, s) : # Check if any vertices from i+1 can be inserted for j in range ( i + 1 , n - (s - l) + 1 ) : # If the degree of the graph is sufficient if (d[j] > = s - 1 ) : # Add the vertex to store store[l] = j; # If the graph is not a clique of size k # then it cannot be a clique # by adding another edge if (is_clique(l + 1 )) : # If the length of the clique is # still less than the desired size if (l < s) : # Recursion to add vertices findCliques(j, l + 1 , s); # Size is met else : print_cli(l + 1 ); # Driver code if __name__ = = "__main__" : edges = [ [ 1 , 2 ], [ 2 , 3 ], [ 3 , 1 ], [ 4 , 3 ], [ 4 , 5 ], [ 5 , 3 ] ]; k = 3 ; size = len (edges); n = 5 ; for i in range (size) : graph[edges[i][ 0 ]][edges[i][ 1 ]] = 1 ; graph[edges[i][ 1 ]][edges[i][ 0 ]] = 1 ; d[edges[i][ 0 ]] + = 1 ; d[edges[i][ 1 ]] + = 1 ; findCliques( 0 , 1 , k); # This code is contributed by AnkitRai01 |
C#
// C# implementation of the approach using System; class GFG { static int MAX = 100; // Stores the vertices static int []store = new int [MAX]; static int n; // Graph static int [,]graph = new int [MAX, MAX]; // Degree of the vertices static int []d = new int [MAX]; // Function to check if the given set of vertices // in store array is a clique or not static bool is_clique( int b) { // Run a loop for all the set of edges // for the select vertex for ( int i = 1; i < b; i++) { for ( int j = i + 1; j < b; j++) // If any edge is missing if (graph[store[i], store[j]] == 0) return false ; } return true ; } // Function to print the clique static void print( int n) { for ( int i = 1; i < n; i++) Console.Write(store[i] + " " ); Console.Write( ", " ); } // Function to find all the cliques of size s static void findCliques( int i, int l, int s) { // Check if any vertices from i+1 can be inserted for ( int j = i + 1; j <= n - (s - l); j++) // If the degree of the graph is sufficient if (d[j] >= s - 1) { // Add the vertex to store store[l] = j; // If the graph is not a clique of size k // then it cannot be a clique // by adding another edge if (is_clique(l + 1)) // If the length of the clique is // still less than the desired size if (l < s) // Recursion to add vertices findCliques(j, l + 1, s); // Size is met else print(l + 1); } } // Driver code public static void Main() { int [,]edges = { { 1, 2 }, { 2, 3 }, { 3, 1 }, { 4, 3 }, { 4, 5 }, { 5, 3 } }; int k = 3; int size = edges.GetLength(0); n = 5; for ( int i = 0; i < size; i++) { graph[edges[i, 0], edges[i, 1]] = 1; graph[edges[i, 1], edges[i, 0]] = 1; d[edges[i, 0]]++; d[edges[i, 1]]++; } findCliques(0, 1, k); } } // This code is contributed by AnkitRai01 |
Javascript
<script> // JavaScript implementation of the approach const MAX = 100; // Stores the vertices let store = new Array(MAX).fill(0), n = 0; // Graph let graph = new Array(MAX).fill(0).map(() => new Array(MAX).fill(0)); // Degree of the vertices let d = new Array(MAX).fill(0); // Function to check if the given set of vertices // in store array is a clique or not const is_clique = (b) => { // Run a loop for all the set of edges // for the select vertex for (let i = 1; i < b; i++) { for (let j = i + 1; j < b; j++) // If any edge is missing if (graph[store[i]][store[j]] == 0) return false ; } return true ; } // Function to print the clique const print = (n) => { for (let i = 1; i < n; i++) document.write(`${store[i]} `); document.write( ", " ); } // Function to find all the cliques of size s const findCliques = (i, l, s) => { // Check if any vertices from i+1 can be inserted for (let j = i + 1; j <= n - (s - l); j++) // If the degree of the graph is sufficient if (d[j] >= s - 1) { // Add the vertex to store store[l] = j; // If the graph is not a clique of size k // then it cannot be a clique // by adding another edge if (is_clique(l + 1)) // If the length of the clique is // still less than the desired size if (l < s) // Recursion to add vertices findCliques(j, l + 1, s); // Size is met else print(l + 1); } } // Driver code const edges = [ [1, 2], [2, 3], [3, 1], [4, 3], [4, 5], [5, 3] ]; let k = 3; let size = edges.length; n = 5; for (let i = 0; i < size; i++) { graph[edges[i][0]][edges[i][1]] = 1; graph[edges[i][1]][edges[i][0]] = 1; d[edges[i][0]]++; d[edges[i][1]]++; } findCliques(0, 1, k); // This code is contributed by rakeshsahni </script> |
1 2 3 , 3 4 5 ,
Time Complexity: O(2^(n/2)) where n is the number of vertices in the graph. The worst case occurs when the graph is a complete graph and all cliques of the given size are present.
Space Complexity : O(n^2) to store the graph
Please Login to comment...