Open In App

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

Last Updated : 03 Dec, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

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 vertexes 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 don’t have any adjacent vertex labeled with 0.

Approach:

The basic idea about the functioning of call by references in java and concepts of the 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.

Procedure: 

It is illustrated along with the help of methods that are used in the program are explained for understanding purposes sequentially as follows:

  1. The input of the program is an adjacent matrix of the graph and the max size of a set is given here. First, we have to make the adjacency list of the graph matrix. Now we will be running a loop for each vertex, by first giving the ith vertex color ‘0’ and then finding all other possible vertices which can be given color ‘0’(included in the set).
  2. So we are making a vector named ‘color’ and initialize the vector with the color of all index (vertices) as ‘1’ and the ith vertex as ‘0’. Then we will be checking for all the possible vertices that can be given the color ‘0’ (included in the set) using a Util() method, described below.
  3. Util() method  calls other two method named can_remove() and remove_all(). The main aim of this method is to remove all those vertices which can be removed from the color vector if the ‘ith’ vertex is removed(assigned ‘0’). This method finds the index of the vertex that can be removed using the above two methods. Then it assigns ‘0’ to that vertex, and it continues doing this till there is no more vertex left to be removed. It returns the modified color vector.
  4. can_remove() method checks for whether the given vertex can be assigned ‘0’ without any difficulty. It compares each neighbor vertex for the given vertex and checks whether there is any neighbor with ‘0’ or not. If no vertex is there with such a case then this vertex is assigned a value ‘0’. It returns a bool value indicating yes or no.
  5. remove_all() method is used to find the vertex whose removal will give numerous vertices to be removed each time. This step is mainly a greedy approach. It finds the number of vertices that can be removed after the removal of a particular vertex and finds the max value of all those numbers and returns the index of that particular vertex whose removal will result in the removal of maximum vertices. Then this vertex is removed in Util() method.
  6. So till now we had understood what Util(), remove_all() and can_remove() method are doing. Basically for each ‘i’th color vector with ‘ith’ vertex being ‘0’, these methods try to find the number of vertices that can be removed from the graph (assigned ‘0’). so after calling this Util() method the color vector is being modified and the number of vertices that can be assigned ‘0’ is given that value.
  7. Now since the color vector is modified, so we have to count the number of vertices that are assigned’0′ (which means the vertices which can be included in the set). If the count is larger than the desired size then we have found the solution and found variable is set to true and output is done and loops break else it continues trying the next color vector with the next vertex being removed. The count is done by Util3() method.
    • Still, we are missing out on edge case which is 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 vertexes as shown in the second figure 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 a value ‘1’ (uncolored) and having only one colored adjacent vertex as shown above.
  8. *Util2() method basically checks for each vertex that is not removed (having ‘1’), whether that vertex is having only one adjacent vertex colored (value ‘1’). If found any such vertex then this method will swap the color among the vertices and recall the Util() method to refresh the color vector. This can be proved easily that this method will always either increase the number of the vertex with ‘0’ or the number will remain the same. It will never decrease the count of colored vertices.

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

So this approach proves extra beneficial for our approach.

Note: Why it always increases?

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.

Implementation:

Till now if we have any solution then we will set found true otherwise will save the configuration of the color vector for further use. All this is done for each ‘ith’ vertex in the loop and the modified color vector is stored in the vector of vectors named set_found in the program.

If the desired size is not found till now, then we will try our last case that we will be performing pairwise intersection of all the generated sets of configurations.

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 configurations (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 the best part, the above procedure will be the same, to check the maximum size of the set possible and the above case.

Example

Java




// Java Program to Find Independent Sets in a Graph
// by Graph Coloring
 
// Importing input output classes
import java.io.*;
// Importing utility classes from java.util package
import java.util.*;
 
// Class 1
// Helper class
class GFGUTIL {
 
    // Method 1
    // Utility function to label maximum vertices with
    // 0,that can be included in the set
    public static void
    Util(Vector<Vector<Integer> > adjacency_list,
         Vector<Integer> color)
    {
        int a = 0;
 
        // Condition check
        while (a != -1) {
            a = remove_all(adjacency_list, color);
            if (a != -1)
                color.set(a, 0);
        }
    }
 
    // Method 2
    // This method that tries whether it is possible to
    // remove any adjacent vertex of any removed vertex
    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));
    }
 
    // Method 3
    // 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;
    }
 
    // Method 4
    // Returning the index of the vertex
    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;
                }
            }
        }
 
        // Index of the vertex
        return a;
    }
 
    // Method 5
    // To check whether 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;
    }
}
 
// Class 2
// Main class
public class GFG {
 
    // Main driver method
    public static void main(String[] args) throws Exception
    {
        // inputting the graph and forming it's adjacency
        // list.
 
        // Display message for better readability
        System.out.println("The number of vertices in the graph is taken as 4");
 
        // Custom input is taken here
        int n = 4;
 
        // Creating a vector object for adjacency matrix.
        Vector<Vector<Integer> > adjacency_matrix = new Vector<Vector<Integer> >(n, (n));
 
        // Input matrix is
        // 0111
        // 1011
        // 1101
        // 1110
 
        // Nested for loops for iterations
        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);
        }
 
        // Creating a vector object for adjacency list
        Vector<Vector<Integer> > adjacency_list
            = new Vector<Vector<Integer> >();
 
        // Nested for loops for iterations
        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);
        }
 
        // Display message only for
        // taking the minimum size of the set required.
        System.out.println("The minimum size of the set required is taken as 2");
 
        // Declaring and initializing variable with
        // 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;
 
        // Creating a set found vector to
        // store all the possible set
        Vector<Vector<Integer> > set_found = new Vector<Vector<Integer> >();
 
        // Display message
        System.out.println("Searching for the set");
 
        for (int i = 0; i < n; ++i) {
 
            // If set is found
            if (found == 1)
 
                // Hault the further execution of Program
                break;
 
            // 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
            GFGUTIL.Util(adjacency_list, color);
 
            // Finding the number of those which cannot be
            // pushed in set
            size = GFGUTIL.Util3(color);
            if (size < min)
                min = size;
 
            // If the number of elements in set are more or
            // equal
            if (size <= y) {
 
                // Print and display the 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);
 
                // Set flag to 1
                found = 1;
 
                // Hault the further execution of Program
                break;
            }
 
            // If sufficient nodes are not found then
            // we call util2 function
 
            for (int j = 0; j < x; ++j)
                GFGUTIL.Util2(adjacency_list, color, j);
 
            size = GFGUTIL.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();
 
        // Now searching pairwise and
        // repeating same procedure as above discussed
        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);
 
                GFGUTIL.Util(adjacency_list, color);
                size = GFGUTIL.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)
                    GFGUTIL.Util2(adjacency_list, color, j);
                size = GFGUTIL.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)
 
            // Display command
            System.out.println("Found the set of given least possible size");
        else
 
            // Display command
            System.out.println("Couldn't find the set of least size given");
    }
}


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

 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads