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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


Output:

1 2 3 , 3 4 5 ,

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Recommended Posts: