Find all cliques of size K in an undirected graph
Last Updated :
20 Feb, 2023
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++
#include <bits/stdc++.h>
using namespace std;
const int MAX = 100;
int store[MAX], n;
int graph[MAX][MAX];
int d[MAX];
bool is_clique( int b)
{
for ( int i = 1; i < b; i++) {
for ( int j = i + 1; j < b; j++)
if (graph[store[i]][store[j]] == 0)
return false ;
}
return true ;
}
void print( int n)
{
for ( int i = 1; i < n; i++)
cout << store[i] << " " ;
cout << ", " ;
}
void findCliques( int i, int l, int s)
{
for ( int j = i + 1; j <= n - (s - l); j++)
if (d[j] >= s - 1) {
store[l] = j;
if (is_clique(l + 1))
if (l < s)
findCliques(j, l + 1, s);
else
print(l + 1);
}
}
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
class GFG
{
static int MAX = 100 ;
static int []store = new int [MAX];
static int n;
static int [][]graph = new int [MAX][MAX];
static int []d = new int [MAX];
static boolean is_clique( int b)
{
for ( int i = 1 ; i < b; i++)
{
for ( int j = i + 1 ; j < b; j++)
if (graph[store[i]][store[j]] == 0 )
return false ;
}
return true ;
}
static void print( int n)
{
for ( int i = 1 ; i < n; i++)
System.out.print(store[i] + " " );
System.out.print( ", " );
}
static void findCliques( int i, int l, int s)
{
for ( int j = i + 1 ; j <= n - (s - l); j++)
if (d[j] >= s - 1 )
{
store[l] = j;
if (is_clique(l + 1 ))
if (l < s)
findCliques(j, l + 1 , s);
else
print(l + 1 );
}
}
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);
}
}
|
Python3
import numpy as np
MAX = 100 ;
store = [ 0 ] * MAX ;
graph = np.zeros(( MAX , MAX ));
d = [ 0 ] * MAX ;
def is_clique(b) :
for i in range ( 1 , b) :
for j in range (i + 1 , b) :
if (graph[store[i]][store[j]] = = 0 ) :
return False ;
return True ;
def print_cli(n) :
for i in range ( 1 , n) :
print (store[i], end = " " );
print ( "," , end = " " );
def findCliques(i, l, s) :
for j in range ( i + 1 , n - (s - l) + 1 ) :
if (d[j] > = s - 1 ) :
store[l] = j;
if (is_clique(l + 1 )) :
if (l < s) :
findCliques(j, l + 1 , s);
else :
print_cli(l + 1 );
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);
|
C#
using System;
class GFG
{
static int MAX = 100;
static int []store = new int [MAX];
static int n;
static int [,]graph = new int [MAX, MAX];
static int []d = new int [MAX];
static bool is_clique( int b)
{
for ( int i = 1; i < b; i++)
{
for ( int j = i + 1; j < b; j++)
if (graph[store[i], store[j]] == 0)
return false ;
}
return true ;
}
static void print( int n)
{
for ( int i = 1; i < n; i++)
Console.Write(store[i] + " " );
Console.Write( ", " );
}
static void findCliques( int i, int l, int s)
{
for ( int j = i + 1; j <= n - (s - l); j++)
if (d[j] >= s - 1)
{
store[l] = j;
if (is_clique(l + 1))
if (l < s)
findCliques(j, l + 1, s);
else
print(l + 1);
}
}
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);
}
}
|
Javascript
<script>
const MAX = 100;
let store = new Array(MAX).fill(0), n = 0;
let graph = new Array(MAX).fill(0).map(() => new Array(MAX).fill(0));
let d = new Array(MAX).fill(0);
const is_clique = (b) => {
for (let i = 1; i < b; i++) {
for (let j = i + 1; j < b; j++)
if (graph[store[i]][store[j]] == 0)
return false ;
}
return true ;
}
const print = (n) => {
for (let i = 1; i < n; i++)
document.write(`${store[i]} `);
document.write( ", " );
}
const findCliques = (i, l, s) => {
for (let j = i + 1; j <= n - (s - l); j++)
if (d[j] >= s - 1) {
store[l] = j;
if (is_clique(l + 1))
if (l < s)
findCliques(j, l + 1, s);
else
print(l + 1);
}
}
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);
</script>
|
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
Share your thoughts in the comments
Please Login to comment...