Open In App

Java Program to Find Independent Sets in a Graph using Graph Coloring

Independent sets are set of vertices or edges in which the pair of any two vertices or edges are not adjacent to each other. Assuming that Independent sets mean Independent sets of vertices, we have to find a set of such vertices in which any two pairs of the vertex are not adjacent to each other.

Using graph coloring we can solve this problem. We will modify the graph coloring method as instead of using different colors we will only use two colors i.e 0,1. So we will assume that those vertices which are labeled 0 are a part of the set and others are not. So the vertices labeled with 0 doesn’t have any adjacent vertex labeled with 0.



The basic idea about the functioning of the call by references in java and concepts of vector is a must. Also, we are assuming the index labeled as the vertex name and the value in the vector at that index as the color of that vertex (either 0 or 1). The initially found variable is set to false i.e no set of the desired size is found. We will be making use of the word removed and the color ‘0’ for any vertex. Both indicate the same thing that the particular vertex can be removed from the graph and can be included in the set.

Approach:



But we are forgetting one case as shown in the following image :

Here instead of coloring the second colored vertex in the first diagram, we will color one of its adjacent vertex as shown in the second fig. In doing so we will get many vertices in the set. Hence, for each color vector, we will call Util2() method. This case can arise only when there is a certain vertex which is having the value ‘1’ (uncolored) and having only one colored adjacent vertex as shown above.

Why always increase?

There is only swap of color between two adjacent vertices. Hence, the count will remain same till now. Thinking for rest of the configuration we can say that before swap the newly colored vertex is not having more than one colored adjacent vertex. So, after swap also there are no adjacent vertices to it that are colored. This will maintain the property of independent sets.

In this, we will repeat the same procedure starting with the color vector again and maintaining the configurations generated. The only difference is that we will not begin by assigning ‘0’ to the ith vertex. Instead of that, we will check pairs of configuration (in the set_found) for those vertexes that are labeled with ‘0’ and are common to both sets. They will be labeled ‘0’ in the color vector and for the rest part the above procedure will be the same, to check the maximum size of set possible and the above case.

Implementation:




// Java Program to Find Independent Sets
// in a Graph using Graph Coloring
 
import java.io.*;
import java.util.*;
 
// save file with the name "GFG2.java"
 
public class GFG2 {
   
    // main class
    public static void main(String[] args) throws Exception
    {
        // inputting the graph and forming it's adjacency
        // list.
 
        System.out.println("The number of vertices in the graph is taken as 4");
       
        int n = 4;
        Vector<Vector<Integer> > adjacency_matrix
            = new Vector<Vector<Integer> >(n, (n));
       
        /* the input matrix is
           0111
           1011
           1101
           1110
        */
       
        for (int i = 0; i < n; ++i) {
           
            Vector<Integer> adj = new Vector<Integer>(n);
           
            for (int j = 0; j < n; ++j)
                if (i == j)
                    adj.add(0);
                else
                    adj.add(1);
           
            adjacency_matrix.add(adj);
        }
       
        Vector<Vector<Integer> > adjacency_list  = new Vector<Vector<Integer> >();
 
        for (int i = 0; i < n; ++i) {
           
            Vector<Integer> adj_list  = new Vector<Integer>();
           
            for (int j = 0; j < n; ++j) {
                if (adjacency_matrix.get(i).get(j) == 1)
                    adj_list.add(j);
            }
            adjacency_list.add(adj_list);
        }
       
        // taking the minimum size of the set required.
        System.out.println("The minimum size of the set required is taken as 2");
       
        // the least size of the set required
        int x = 2;
       
        // complement of the size
        int y = n - x;
       
        int found = 0;
        int size = 0;
        int min = n + 1;
       
        // making a set_found vector to store all the
        // possible sets .
        Vector<Vector<Integer> > set_found
            = new Vector<Vector<Integer> >();
 
        System.out.println("Searching for the set");
 
        for (int i = 0; i < n; ++i) {
           
            // if set is found
            if (found == 1)
                break;
           
            // a cover vector to have the state of all the
            // vertices initially.
            Vector<Integer> color = new Vector<Integer>(n);
           
            for (int j = 0; j < n; ++j)
                color.add(1);
           
            // starting by putting the ith node in set
            color.set(i, 0);
           
            // then finding all the nodes to be pushed in
            // the set by calling function
            Util(adjacency_list, color);
           
            // finding the number of those which cannot be
            // pushed in set
            size = Util3(color);
           
            if (size < min)
                min = size;
           
            // if the number of elements in set are more or
            // equal to the amount required.
            if (size <= y) {
               
                System.out.println("Independent set of size " + (n - size)
                    + "found");
               
                for (int j = 0; j < n; ++j)
                    if (color.get(j) == 0)
                        System.out.print(j + 1 + " ");
               
                System.out.println();
               
                set_found.add(color);
                found = 1;
                break;
            }
           
            // not sufficient nodes found
            // calling util2 function
            // main aim of calling this function 'x' times
            // is that for any undirected graph the maximum
            // number of edges with x nodes is x(x+1)/2; so
            // we are trying for each possible edge .
            for (int j = 0; j < x; ++j)
                Util2(adjacency_list, color, j);
           
            // repeating same procedure as discussed above
            size = Util3(color);
           
            if (size < min)
                min = size;
            System.out.println("Independent set of size "
                               + (n - size) + "found");
           
            for (int j = 0; j < n; ++j)
                if (color.get(j) == 0)
                    System.out.print(j + 1 + " ");
           
            System.out.println();
           
            set_found.add(color);
           
            if (size <= y) {
                found = 1;
                break;
            }
        }
       
        int r = set_found.size();
       
        // searching pairwise.
        // repeating same procedure as above
        // this time taking those set which have common
        // vertices in them and again trying for uncommon
        // ones.
 
        for (int a = 0; a < r; ++a) {
            if (found == 1)
                break;
            for (int b = a + 1; b < r; ++b) {
                if (found == 1)
                    break;
               
                Vector<Integer> color = new Vector<Integer>(n);
               
                for (int j = 0; j < n; ++j)
                    color.add(1);
               
                for (int c = 0; c < n; ++c)
                    if (set_found.get(a).get(c) == 0
                        && set_found.get(b).get(c) == 0)
                        color.set(c, 0);
               
                Util(adjacency_list, color);
               
                size = Util3(color);
               
                if (size < min)
                    min = size;
                if (size <= y) {
                    System.out.println("Independent set of size"
                        + (n - size));
                   
                    for (int j = 0; j < n; ++j)
                        if (color.get(j) == 0)
                            System.out.print(j + 1 + " ");
                   
                    System.out.println();
                    found = 1;
                    break;
                }
               
                for (int j = 0; j < y; ++j)
                    Util2(adjacency_list, color, j);
               
                size = Util3(color);
               
                if (size < min)
                    min = size;
                System.out.println("Independent set of size " + (n - size)
                    + "found");
               
                for (int j = 0; j < n; ++j)
                    if (color.get(j) == 0)
                        System.out.print(j + 1 + " ");
               
                System.out.println();
               
                if (size <= y) {
                    found = 1;
                    break;
                }
               
            }
        }
       
        // if found
        if (found == 1)
            System.out.println(
                "Found the set of given least possible size");
        else
            System.out.println(
                "Couldn't find the set of least size given");
    }
   
    // utility function to label maximum vertices with
    // 0,that can be included in the set. It takes the
    // maximum number of vertices which can be removed each
    // time.
    public static void Util(Vector<Vector<Integer> > adjacency_list,
         Vector<Integer> color)
    {
        int a = 0;
        while (a != -1) {
            a = remove_all(adjacency_list, color);
            if (a != -1)
                color.set(a, 0);
        }
    }
   
    // This method tries whether it is possible to
    // remove any adjacent vertex of any removed vertex if
    // yes then it will remove that and call Util again and
    // modify the set.
    public static void Util2(Vector<Vector<Integer> > adjacency_list,
          Vector<Integer> color, int j)
    {
 
        int cnt = 0;
       
        Vector<Integer> tmp_color = new Vector<Integer>();
       
        for (int g = 0; g < color.size(); ++g)
            tmp_color.add(color.get(g));
 
        for (int i = 0; i < color.size(); ++i) {
           
            if (tmp_color.get(i) == 1) {
               
                int sum = 0;
                int idx = -1;
               
                for (int g = 0; g < adjacency_list.get(i).size(); ++g)
                    if (tmp_color.get(adjacency_list.get(i).get(g))== 0)
                    {
                        idx = g;
                        sum++;
                    }
               
                if (sum == 1 && color.get(adjacency_list.get(i).get(idx)) == 0)
                {
                    tmp_color.set(adjacency_list.get(i).get(idx), 1);
                   
                    tmp_color.set(i, 0);
                   
                    Util(adjacency_list, tmp_color);
                   
                    ++cnt;
                }
               
                if (cnt > j)
                    break;
            }
        }
       
        for (int g = 0; g < color.size(); ++g)
            color.set(g, tmp_color.get(g));
    }
   
    // returning the number of vertices that can't be
    // included in the set.
    public static int Util3(Vector<Integer> color)
    {
        int cnt = 0;
        for (int i = 0; i < color.size(); i++)
            if (color.get(i) == 1)
                ++cnt;
        return cnt;
    }
   
    // returns the index of the vertex whose removal will
    // give more vertex to be removed. This is basically a
    // greedy approach to get the maximum possible set size.
    public static int remove_all(Vector<Vector<Integer> > adjacency_list,
               Vector<Integer> color)
    {
        int a = -1, max = -1;
       
        for (int i = 0; i < color.size(); ++i)
        {
            if (color.get(i) == 1
                && can_remove(adjacency_list.get(i), color) == 1)
            {
                Vector<Integer> tmp_color = new Vector<Integer>();
               
                for (int j = 0; j < color.size(); ++j)
                    tmp_color.add(color.get(j));
               
                tmp_color.set(i, 0);
               
                int sum = 0;
               
                for (int j = 0; j < tmp_color.size(); ++j)
                    if (tmp_color.get(j) == 1
                        && can_remove(adjacency_list.get(j),
                                      tmp_color)== 1)
                        ++sum;
               
                if (sum > max)
                {
                    max = sum;
                    a = i;
                }
            }
        }
        return a;
    }
   
    // checking that a vertex can be removed or not
    public static int can_remove(Vector<Integer> adj_list,
                                 Vector<Integer> color)
    {
        int check = 1;
       
        for (int i = 0; i < adj_list.size(); ++i)
            if (color.get(adj_list.get(i)) == 0)
                check = 0;
       
        return check;
    }
}

 
 

Output
The number of vertices in the graph is taken as 4
The minimum size of the set required is taken as 2
Searching for the set
Independent set of size 1found
1 
Independent set of size 1found
2 
Independent set of size 1found
2 
Independent set of size 1found
2 
Independent set of size 1found
1 
Independent set of size 1found
1 
Independent set of size 1found
1 
Independent set of size 1found
2 
Independent set of size 1found
2 
Independent set of size 1found
2 
Couldn't find the set of least size given

 


Article Tags :