Open In App

Maximal Independent Set in an Undirected Graph

Last Updated : 15 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an undirected graph defined by the number of vertex V and the edges E[ ], the task is to find Maximal Independent Vertex Set in an undirected graph.

Independent Set: An independent set in a graph is a set of vertices which are not directly connected to each other.

Note: It is a given that there is at least one way to traverse from any vertex in the graph to another, i.e. the graph has one connected component. Examples:

Input: V = 3, E = { (1, 2), (2, 3) } Output: {1, 3} Explanation: Since there are no edges between 1 and 3, and we cannot add 2 to this since it is a neighbour of 1, this is the Maximal Independent Set. Input: V = 8, E = { (1, 2), (1, 3), (2, 4), (5, 6), (6, 7), (4, 8) } Output: {2, 3, 5, 7, 8}

Approach: This problem is an NP-Hard problem, which can only be solved in exponential time(as of right now). Follow the steps below to solve the problem:

  • Iterate through the vertices of the graph and use backtracking to check if a vertex can be included in the Maximal Independent Set or not.
  • Two possibilities arise for each vertex, whether it can be included or not in the maximal independent set.
  • Initially start, considering all vertices and edges. One by one, select a vertex. Remove that vertex from the graph, excluding it from the maximal independent set, and recursively traverse the remaining graph to find the maximal independent set.
  • Otherwise, consider the selected vertex in the maximal independent set and remove all its neighbors from it. Proceed to find the maximal independent set possible excluding its neighbors.
  • Repeat this process for all vertices and print the maximal independent set obtained.

Below is the implementation of the above approach: 

C++




// C++ program for above approach
#include <iostream>
#include <map>
#include <vector>
 
using namespace std;
 
// Recursive Function to find the
// Maximal Independent Vertex Set
vector<int> graphSets(map<int, vector<int> > graph)
{
    // Base Case - Given Graph has no nodes
    if (graph.size() == 0) {
        return vector<int>();
    }
 
    // Base Case - Given Graph has 1 node
    if (graph.size() == 1) {
        vector<int> v;
        for (auto const& element : graph) {
            v.push_back(element.first);
        }
        return v;
    }
 
    // Select a vertex from the graph
    int vCurrent = graph.begin()->first;
 
    // Case 1 - Proceed removing the selected vertex
    // from the Maximal Set
    map<int, vector<int> > graph2(graph);
 
    // Delete current vertex from the Graph
    graph2.erase(vCurrent);
 
    // Recursive call - Gets Maximal Set,
    // assuming current Vertex not selected
    vector<int> res1 = graphSets(graph2);
 
    // Case 2 - Proceed considering the selected vertex
    // as part of the Maximal Set
 
    // Loop through its neighbours
    for (auto v : graph.at(vCurrent)) {
        // Delete neighbor from the current subgraph
        if (graph2.count(v)) {
            graph2.erase(v);
        }
    }
 
    // This result set contains vCurrent,
    // and the result of recursive call assuming neighbors
    // of vCurrent are not selected
    vector<int> res2;
    res2.push_back(vCurrent);
    vector<int> res2Sub = graphSets(graph2);
    res2.insert(res2.end(), res2Sub.begin(), res2Sub.end());
 
    // Our final result is the one which is bigger, return
    // it
    if (res1.size() > res2.size()) {
        return res1;
    }
    return res2;
}
 
// Driver Code
int main()
{
    int V = 8;
 
    // Defines edges
    int E[][2] = { { 1, 2 }, { 1, 3 }, { 2, 4 },
                   { 5, 6 }, { 6, 7 }, { 4, 8 } };
 
    map<int, vector<int> > graph;
 
    // Constructs Graph as a dictionary of the following
    // format- graph[VertexNumber V] = list[Neighbors of
    // Vertex V]
    for (int i = 0; i < sizeof(E) / sizeof(E[0]); i++) {
        int v1 = E[i][0];
        int v2 = E[i][1];
        if (graph.count(v1) == 0) {
            graph[v1] = vector<int>();
        }
        if (graph.count(v2) == 0) {
            graph[v2] = vector<int>();
        }
        graph[v1].push_back(v2);
        graph[v2].push_back(v1);
    }
 
    // Recursive call considering all vertices in the
    // maximum independent set
    vector<int> maximalIndependentSet = graphSets(graph);
 
    // Prints the Result
    for (auto i : maximalIndependentSet) {
        cout << i << " ";
    }
    cout << endl;
 
    return 0;
}


Java




// Java program for above approach
import java.util.*;
 
public class Solution {
 
  // Recursive Function to find the
  // Maximal Independent Vertex Set
  static ArrayList<Integer>
    graphSets(HashMap<Integer, ArrayList<Integer> > graph)
  {
    // Base Case - Given Graph
    // has no nodes
    if (graph.size() == 0) {
      return new ArrayList<>();
    }
 
    // Base Case - Given Graph
    // has 1 node
    if (graph.size() == 1) {
      return new ArrayList<Integer>(graph.keySet());
    }
    // Select a vertex from the graph
    int vCurrent
      = (new ArrayList<Integer>(graph.keySet()))
      .get(0);
 
    // Case 1 - Proceed removing
    // the selected vertex
    // from the Maximal Set
    HashMap<Integer, ArrayList<Integer> > graph2
      = new HashMap<>(graph);
 
    // Delete current vertex
    // from the Graph
    graph2.remove(vCurrent);
 
    // Recursive call - Gets
    // Maximal Set,
    // assuming current Vertex
    // not selected
    ArrayList<Integer> res1 = graphSets(graph2);
 
    // Case 2 - Proceed considering
    // the selected vertex as part
    // of the Maximal Set
 
    // Loop through its neighbours
    for (Integer v : graph.get(vCurrent)) {
 
      // Delete neighbor from
      // the current subgraph
      if (graph2.containsKey(v)) {
        graph2.remove(v);
      }
    }
 
    // This result set contains VFirst,
    // and the result of recursive
    // call assuming neighbors of vFirst
    // are not selected
    ArrayList<Integer> res2 = new ArrayList<>();
    res2.add(vCurrent);
    res2.addAll(graphSets(graph2));
 
    // Our final result is the one
    // which is bigger, return it
    if (res1.size() > res2.size())
      return res1;
    return res2;
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    int V = 8;
 
    // Defines edges
    int[][] E = { { 1, 2 }, { 1, 3 }, { 2, 4 },
                 { 5, 6 }, { 6, 7 }, { 4, 8 } };
 
    HashMap<Integer, ArrayList<Integer> > graph
      = new HashMap<>();
 
    // Constructs Graph as a dictionary
    // of the following format-
 
    // graph[VertexNumber V]
    // = list[Neighbors of Vertex V]
    for (int[] e : E) {
      int v1 = e[0];
      int v2 = e[1];
      if (!graph.containsKey(v1)) {
        graph.put(v1, new ArrayList<>());
      }
      if (!graph.containsKey(v2)) {
        graph.put(v2, new ArrayList<>());
      }
      graph.get(v1).add(v2);
      graph.get(v2).add(v1);
    }
 
    // Recursive call considering
    // all vertices in the maximum
    // independent set
    ArrayList<Integer> maximalIndependentSet
      = graphSets(graph);
 
    // Prints the Result
    for (Integer i : maximalIndependentSet)
      System.out.print(i + " ");
  }
}
 
// This code is contributed by karandeep1234.


Python3




# Python Program to implement
# the above approach
 
# Recursive Function to find the
# Maximal Independent Vertex Set   
def graphSets(graph):
     
    # Base Case - Given Graph
    # has no nodes
    if(len(graph) == 0):
        return []
    
    # Base Case - Given Graph
    # has 1 node
    if(len(graph) == 1):
        return [list(graph.keys())[0]]
     
    # Select a vertex from the graph
    vCurrent = list(graph.keys())[0]
     
    # Case 1 - Proceed removing
    # the selected vertex
    # from the Maximal Set
    graph2 = dict(graph)
     
    # Delete current vertex
    # from the Graph
    del graph2[vCurrent]
     
    # Recursive call - Gets
    # Maximal Set,
    # assuming current Vertex
    # not selected
    res1 = graphSets(graph2)
     
    # Case 2 - Proceed considering
    # the selected vertex as part
    # of the Maximal Set
 
    # Loop through its neighbours
    for v in graph[vCurrent]:
         
        # Delete neighbor from
        # the current subgraph
        if(v in graph2):
            del graph2[v]
     
    # This result set contains VFirst,
    # and the result of recursive
    # call assuming neighbors of vFirst
    # are not selected
    res2 = [vCurrent] + graphSets(graph2)
     
    # Our final result is the one
    # which is bigger, return it
    if(len(res1) > len(res2)):
        return res1
    return res2
 
# Driver Code
V = 8
 
# Defines edges
E = [ (1, 2),
      (1, 3),
      (2, 4),
      (5, 6),
      (6, 7),
      (4, 8)]
 
graph = dict([])
 
# Constructs Graph as a dictionary
# of the following format-
 
# graph[VertexNumber V]
# = list[Neighbors of Vertex V]
for i in range(len(E)):
    v1, v2 = E[i]
     
    if(v1 not in graph):
        graph[v1] = []
    if(v2 not in graph):
        graph[v2] = []
     
    graph[v1].append(v2)
    graph[v2].append(v1)
 
# Recursive call considering
# all vertices in the maximum
# independent set
maximalIndependentSet = graphSets(graph)
 
# Prints the Result
for i in maximalIndependentSet:
    print(i, end =" ")


C#




using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
 
class Solution
{
  // Recursive Function to find the
  // Maximal Independent Vertex Set
  static List<int> GraphSets(Dictionary<int, List<int>> graph)
  {
    // Base Case - Given Graph
    // has no nodes
    if (graph.Count == 0)
    {
      return new List<int>();
    }
 
    // Base Case - Given Graph
    // has 1 node
    if (graph.Count == 1)
    {
      return new List<int>(graph.Keys);
    }
 
    // Select a vertex from the graph
    int vCurrent = graph.Keys.First();
 
    // Case 1 - Proceed removing
    // the selected vertex
    // from the Maximal Set
    Dictionary<int, List<int>> graph2 = new Dictionary<int, List<int>>(graph);
 
    // Delete current vertex
    // from the Graph
    graph2.Remove(vCurrent);
 
    // Recursive call - Gets
    // Maximal Set,
    // assuming current Vertex
    // not selected
    List<int> res1 = GraphSets(graph2);
 
    // Case 2 - Proceed considering
    // the selected vertex as part
    // of the Maximal Set
 
    // Loop through its neighbours
    foreach (int v in graph[vCurrent])
    {
      // Delete neighbor from
      // the current subgraph
      if (graph2.ContainsKey(v))
      {
        graph2.Remove(v);
      }
    }
 
    // This result set contains VFirst,
    // and the result of recursive
    // call assuming neighbors of vFirst
    // are not selected
    List<int> res2 = new List<int>();
    res2.Add(vCurrent);
    res2.AddRange(GraphSets(graph2));
 
    // Our final result is the one
    // which is bigger, return it
    if (res1.Count > res2.Count)
    {
      return res1;
    }
    return res2;
  }
 
  // Driver Code
  static void Main(string[] args)
  {
    int V = 8;
 
    // Defines edges
    int[,] E = { { 1, 2 }, { 1, 3 }, { 2, 4 },
                { 5, 6 }, { 6, 7 }, { 4, 8 } };
 
    Dictionary<int, List<int>> graph = new Dictionary<int, List<int>>();
 
    // Constructs Graph as a dictionary
    // of the following format-
 
    // graph[VertexNumber V]
    // = list[Neighbors of Vertex V]
    for (int i = 0; i < E.GetLength(0); i++)
    {
      int v1 = E[i, 0];
      int v2 = E[i, 1];
      if (!graph.ContainsKey(v1))
      {
        graph[v1] = new List<int>();
      }
      if (!graph.ContainsKey(v2))
      {
        graph[v2] = new List<int>();
      }
      graph[v1].Add(v2);
      graph[v2].Add(v1);
    }
 
    // Recursive call considering
    // all vertices in the maximum
    // independent set
    List<int> maximalIndependentSet = GraphSets(graph);
 
    // Prints the Result
    foreach (int i in maximalIndependentSet)
    {
      Console.Write(i + " ");
    }
  }
}


Javascript




// JavaScript program to implement
// the above approach
 
// Recursive Function to find the
// Maximal Independent Vertex Set
function graphSets(graph) {
// Base Case - Given Graph
// has no nodes
if (Object.keys(graph).length === 0) {
return [];
}
 
// Base Case - Given Graph
// has 1 node
if (Object.keys(graph).length === 1) {
return [Object.keys(graph)[0]];
}
 
// Select a vertex from the graph
let vCurrent = Object.keys(graph)[0];
 
// Case 1 - Proceed removing
// the selected vertex
// from the Maximal Set
const graph2 = Object.assign({}, graph);
 
// Delete current vertex
// from the Graph
delete graph2[vCurrent];
 
// Recursive call - Gets
// Maximal Set,
// assuming current Vertex
// not selected
const res1 = graphSets(graph2);
 
// Case 2 - Proceed considering
// the selected vertex as part
// of the Maximal Set
 
// Loop through its neighbours
for (const v of graph[vCurrent]) {
// Delete neighbor from
// the current subgraph
if (v in graph2) {
delete graph2[v];
}
}
 
// This result set contains VFirst,
// and the result of recursive
// call assuming neighbors of vFirst
// are not selected
const res2 = [vCurrent].concat(graphSets(graph2));
 
// Our final result is the one
// which is bigger, return it
if (res1.length > res2.length) {
return res1;
}
return res2;
}
 
// Driver Code
const V = 8;
 
// Defines edges
const E = [
[1, 2],
[1, 3],
[2, 4],
[5, 6],
[6, 7],
[4, 8],
];
 
const graph = {};
 
// Constructs Graph as a dictionary
// of the following format-
 
// graph[VertexNumber V]
// = list[Neighbors of Vertex V]
for (let i = 0; i < E.length; i++) {
const [v1, v2] = E[i];
 
if (!(v1 in graph)) {
graph[v1] = [];
}
if (!(v2 in graph)) {
graph[v2] = [];
}
 
graph[v1].push(v2);
graph[v2].push(v1);
}
 
// Recursive call considering
// all vertices in the maximum
// independent set
const maximalIndependentSet = graphSets(graph);
 
// Prints the Result
for (let i = 0; i < maximalIndependentSet.length; i++) {
console.log(maximalIndependentSet[i] + " ");
}


Output:

2 3 8 5 7

Time Complexity: O(2N
Auxiliary Space: O(N)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads