# Java Program to Find Independent Sets in a Graph By 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 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:

- 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).
- 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. calls other two method named**Util() method***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.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.**can_remove() 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.**remove_all() method**- 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.
- 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.

- *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.

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