Find All Cliques of Size K in an Undirected Graph


Finding all cliques of a certain size in an undirected graph is a fundamental graph theory issue that has many applications in social network research, biology, and data mining. A clique is a graph subset with all vertices linked.Recursive backtracking considers each vertex a potential candidate and updates the candidate and excluded sets depending on neighbourhood connections. Backtracking quickly finds all cliques of the appropriate size.

Methods Used

  • Backtracking approach

Backtracking

Recursive backtracking is a frequent method for finding cliques of a certain size in undirected graphs. It verifies all possible vertices combinations for cliques under the provided constraints. The method considers each vertex a candidate in an empty clique. It iteratively adds vertices to the clique and updates the candidate and excluded sets depending on neighbourhood connections. No candidates or eliminated vertices end the algorithm. Backtracking effectively searches the solution space for cliques of the specified size.

Algorithm

  • Make a recursive function with three parameters: the initial node, the length of the current node, and the length of the goal node.

  • Nodes cannot be added below the starting index. It is looped up to n times.

  • If adding a node preserves the clique. If so, the node is added, and the recursive function is run with the parameters length of the current set + 1, desired length, and index of new node + 1.

  • Nodes are printed when the length is achieved.

Example

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

Output

1 2 3 , 3 4 5 

Conclusion

Finding all cliques of a certain size in an undirected network is a hard issue that may be solved in a number of ways, including the recursive backtracking technique and the Bron−Kerbosch algorithm. Each of these approaches has its own unique set of benefits for addressing the issue at hand.The recursive backtracking method, which considers every possible set of connected vertices, provides a straightforward and understandable answer. It's best suited for smaller graphs or situations where the required clique size is modest, as it makes efficient use of backtracking to narrow the search space.

Updated on: 14-Jul-2023

121 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements