Java Program to Solve Set Cover Problem


The set covering is a well-known NP-hard problem in the combinational optimization technique. We call the set cover problem as NP-Hard, because there is no polynomial real time solution available for this particular problem. There is an algorithm called greedy heuristic is a well-known process for the set cover problem.

Here is the example

Let U be the universe of elements, {S1, S2,.....Sm} be collection of subsets of the set, U and Cost(S1), C(S2),......Cost(Sm) be costs of subsets.
1)Let I is the set of elements included so far.  
  Initialize the process I = {}
2) Do following while I is not same as U.
   a) Find the set Si = {S1, S2, ... Sm} whose cost effectiveness is 
      smallest, i.e., the ratio of cost C(Si) and number of newly added 
      elements is minimum. 
      Basically we pick the particular set for which following value is minimum.
      Cost(Si) / |Si - I| - is the possible equation here. 
   b) Add elements of above picked the Si to I, i.e.,  I = I U Si

Algorithm to solve a set cover problem:-

Here in this particular algorithm, we have tried to show you how to solve a set cover problem by using Java Virtual Machine

  • Step 1 − Start.

  • Step 2 − Declare the possible sets and number combinations as input.

  • Step 3 − Take them all into an array.

  • Step 4 − Create a list.

  • Step 5 − Store the data in them.

  • Step 6 − Call the shortest combination as function.

  • Step 7 − The function takes that set as input.

  • Step 8 − It throws an exception.

  • Step 9 − If the size is more than 20.

  • Step 10 − Else, the process moves forward and go next.

  • Step 11 − Iterate the size of all possible combo.

  • Step 12 − For this we need a new set.

  • Step 13 − After running the operation, right shift the value.

  • Step 14 − End it to 1.

  • Step 15 − Add all the solutions in that array.

  • Step 16 − Eliminate the duplicate value from the array.

  • Step 17 − Terminate the process.

Syntax to solve a set cover problem

Set i / i1*i6 / ;
Set k / k1*k6 / ;
Table d(i,k)
k1 k2 k3 k4 k5 k6

i1 1 1 0 1 0 0

i2 1 1 1 0 0 0

i3 0 1 1 0 0 1

i4 1 0 0 1 1 0

i5 0 0 0 1 1 1

i6 0 0 1 0 1 1 ;


Binary Variable Y(k);
Variables
z "Set Covering"
Equation AgebtoPtoEnc , Def_obj ;
AgebtoPtoEnc..
sum(k, Y(k)*d[i,k)) =g= 1 ;
Def_obj..
z =e= sum(k, Y(k));
Model setcovering / all / ;
Solve setcovering using mip minimizing z;
Display z.l, y.l ;

Here is the possible syntax to solve a set cover problem by using a Java environment. In this syntax we have used the possible methods which will help you to understand the Java codes mentioned below.

Approaches to follow

  • Approach 1− Java program to solve the set cover problem with the value of max. two elements in a subset by Greedy Method

  • Approach 2 − Java program to solve the set cover problem with the value of max. two elements in a subset by using a filter class

Java program to solve the set cover problem with the value of max. two elements in a subset by Greedy Method

In this particular Java code, we have tried to show you to solve a set cover problem with two maximum elements, present in a subset by the greedy method.

Example 1

// Importing some of the input output classes as declaration
import java.io.*;
// Importing some utility classes from the java.util package
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

// Main class here is ARBRDD, as we declared here
public class ARBRDD {

	// Interface Declaration Of The Process
	// Declaring the interface class by taking some abstract methods to operate the interface class
	interface Filter<T> {
      boolean matches(T t);
	}

	// Method 1's declaration for the Set Cover Solving
	// Declaring a combo method. The method is a -'shortcombo'
	// Declaring in a form of set the outputs. A also returning a particular set as an output
	private static <T> Set<T>
	shortcombo(Filter<Set<T> > filter, List<T> sets){
      // Set a particular range as the size of the working set 
      final int size = sets.size();

      // Condition check to run the method 
      // If the size of the content is greater than 25 then--->
      // We will throw an exception a pop up of too many combinations present here 
      if (size > 20)
      	throw new IllegalArgumentException(
            "Too many Combinations present here ---->");

      // Now the combination will left here shift 1 process time of size in total
      int comb = 1 << size;

      // Taking an another set with reference as soon possible
      // this Arraylist combination will contain all of the possible solution present here in the process
      List<Set<T> > possible = new ArrayList<Set<T> >();

      // Declaring a for loop which iterates all the logics till combination
      for (int i = 0; i < comb; i++) {

      	// lInkedHashSet of reference declaration
      	// combination we run this code properly
      	Set<T> combination = new LinkedHashSet<T>();

      	// Taking a loop and iterating till the size present in that combination  
      	for (int j = 0; j < size; j++) {

            // If we perforn the right shift i and j, and then ending it with 1 - it will be the process

            // This possible logic will give us how many combinations are possible at least now in this process
            if (((i >> j) & 1) != 0)

            	// Now set combinations are added to the
            	// array list
            	combination.add(sets.get(j));
      	}

      	// Now add to the particular possible reference here
      	possible.add(combination);
      }
      // using the sort() method over Collections class, we can sort the collection at least
      Collections.sort(
      	possible, new Comparator<Set<T> >() {
      	
            // Find the minimum length of this process by taking
            // the difference is here between the total sizes of possible characters
            // present here list
            public int compare(Set<T> a1, Set<T> a2)
            {
            	return a1.size() - a2.size();
            }
      	});

      // Now we can take the particular iteration process till we can streach possible
      for (Set<T> possibleSol : possible) {

      	// Then we check about the matching of the present possible solution

      	// If it does
      	//return the solution from the process
      	// If it doesnot 
      	//return the null value
      	if (filter.matches(possibleSol))
            return possibleSol;
      }
      return null;
	}

	//Introduction of the Method 2 for the process code
	//Here it is the main method as declared
	public static void main(String[] args){

      // Taking all the possible combinations with some custom entries present in an array
      Integer[][] all = {
         { 1, 2 },  { 3, 4 }, { 8, 9 },
         { 16, 7 }, { 5, 8 }, { 11, 6 },
         { 4, 5 },  { 6, 7 }, { 10, 11 },
      };

      // Some Numbers From The List Choose From The List
      // Again, custom entries making in an array
      Integer[] solution
      	= { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };

      // Here let us take a set to run the logic to pass the code again
      List<Set<Integer> > sets
      	= new ArrayList<Set<Integer> >();

      // Now, take an array of the function all to represent the array
      for (Integer[] array : all)

      	// Now taking those elements to add them 
      	// in an LinkedHashSet itself
      	sets.add(new LinkedHashSet<Integer>(Arrays.asList(array)));

      // Now taking the set of the integer sol present and
      // setting it as a solution for the list
      final Set<Integer> sol = new LinkedHashSet<Integer>(Arrays.asList(solution));

      // Now taking funnel filter for checking the particular values
      Filter<Set<Set<Integer> > > filter
      	= new Filter<Set<Set<Integer> > >() {
            // Now taking a boolean function which matches
            // The function helps to iterate all the values
            // over those integers we have a variable which adds
            // up all that to an union set which will give
            // us the new desired result based on logic
            public boolean matches(
            	Set<Set<Integer> > integers) {
            	Set<Integer> union = new LinkedHashSet<Integer>();

            	// Iterating the whole method by using for-each loop instead
            	for (Set<Integer> ints : integers)
                  union.addAll(ints);

            	return union.equals(sol);
            }
      	};

      // Now the below set present here, will call the particular short combo here
      // This function wil used to sort the shortest from a
      // combo present here
      Set<Set<Integer> > firstSol= shortcombo(filter, sets);

      // Print and display out the same logic for the process
      System.out.println("The short combination present here ---> : "+ firstSol);
	}
}

Output

The short combination present here ---> : [[1, 2], [3, 4], [8, 9], [5, 8], [6, 7], [10, 11]]

Java program to solve the set cover problem with the value of maximum two elements in a subset by using a filter class

In this particular Java build code, we have used a predefined filter class interface to solve the set cover problem with the value of maximum value of maximum two elements.

Example 2

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
 
public class SetCoverMax2Elem {
   interface Filter<T>{
      boolean matches(T t);
   }
 
   private static <T> Set<T> shortestCombination(Filter<Set<T>> filter,List<T> listOfSets){
      final int size = listOfSets.size();
      if (size > 20)
         throw new IllegalArgumentException("Too many combinations");
      int combinations = 1 << size;
      List<Set<T>> possibleSolutions = new ArrayList<Set<T>>();
      for (int l = 0; l < combinations; l++){
         Set<T> combination = new LinkedHashSet<T>();
         for (int j = 0; j < size; j++){
            if (((l >> j) & 1) != 0)
            combination.add(listOfSets.get(j));
         }
         possibleSolutions.add(combination);
      }
      // the possible solutions in order of size.
      Collections.sort(possibleSolutions, new Comparator<Set<T>>(){
         public int compare(Set<T> o1, Set<T> o2){
            return o1.size() - o2.size();
         }
      });
      for (Set<T> possibleSolution : possibleSolutions){
         if (filter.matches(possibleSolution))
         return possibleSolution;
      }
      return null;
   }
   public static void main(String[] args){
      Integer[][] arrayOfSets = { { 1, 2 }, { 3, 8 }, { 9, 10 }, { 1, 10 },
         { 2, 3 }, { 4, 5 }, { 5, 7 }, { 5, 6 }, { 4, 7 }, { 6, 7 },
         { 8, 9 }, };
      Integer[] solution = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
      List<Set<Integer>> listOfSets = new ArrayList<Set<Integer>>();
      for (Integer[] array : arrayOfSets)
         listOfSets.add(new LinkedHashSet<Integer>(Arrays.asList(array)));
      final Set<Integer> solutionSet = new LinkedHashSet<Integer>(
         Arrays.asList(solution));
      Filter<Set<Set<Integer>>> filter = new Filter<Set<Set<Integer>>>(){
         public boolean matches(Set<Set<Integer>> integers) {
            Set<Integer> union = new LinkedHashSet<Integer>();
            for (Set<Integer> ints : integers)
            union.addAll(ints);
            return union.equals(solutionSet);
         }
      };
        Set<Set<Integer>> firstSolution = shortestCombination(filter,listOfSets);
        System.out.println("The shortest combination was as per the input: -----> " + firstSolution);
   }
}

Output

The shortest combination was as per the input: -----> [[1, 2], [3, 8], [9, 10], [5, 6], [4, 7]]

Conclusion

Here in this article, we have learnt about the set cover problem in details. Today we have used here the greedy method to solve this problem by the above mentioned syntax and algorithm. Hope with this article you have gained the broad view about how to solve the set cover problem by using various methods in a Java environment.

Updated on: 12-Apr-2023

358 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements