3

I am coding with java so if you can share code with java it would be nice :)

Lets say I have a group of (1,2,3,4,5) and I want to create all subgroups of this group with maximum size of a given natural number (for example 3).

I have found already a code that returns all subgroups however, in my project my group size can reach up to 40 Therefore I it takes too much time to calculate and its very problematic. I am also preferring it to be a function rather than an object. Efficiency is important as well, I can't create all possible groups and then filter them out.

public static <T> Set<Set<T>> powerSet(Set<T> originalSet) {
        Set<Set<T>> sets = new HashSet<>();
        if (originalSet.isEmpty()) {
            sets.add(new HashSet<>());
            return sets;
        }
        List<T> list = new ArrayList<>(originalSet);
        T head = list.get(0);
        Set<T> rest = new HashSet<>(list.subList(1, list.size()));
        for (Set<T> set : powerSet(rest)) {
            Set<T> newSet = new HashSet<>();
            newSet.add(head);
            newSet.addAll(set);
            sets.add(newSet);
            sets.add(set);
        }
        return sets;
    }

I have found it here: Obtaining a powerset of a set in Java.

3 Answers3

2

I saw your code and adjusted it a little.

You now enter the maximum size of the inner set and it will be the size of the biggest Set.

    public static <T> Set<Set<T>> powerSet(Set<T> originalSet, int size) {
        Set<Set<T>> sets = new HashSet<>();
        if (originalSet.isEmpty()) {
            sets.add(new HashSet<>());
            return sets;
        }
        List<T> list = new ArrayList<>(originalSet);
        T head = list.get(0);
        Set<T> rest = new HashSet<>(list.subList(1, list.size()));
        for (Set<T> set : powerSet(rest, size)) {
            if(set.size() <= size-1 ){
                Set<T> newSet = new HashSet<>();
                newSet.add(head);
                newSet.addAll(set);
                sets.add(newSet);
                sets.add(set);
            }

        }

        return sets;
    }
LeoSegol
  • 110
  • 10
1

I have worked on similar questions during my college time, here have a look:

  static Set<String> setA = new HashSet<>();

  public static Set<String> permutation(String prefix, String str, int len) {
    int n = str.length();
    if (prefix.length() == len) {
      setA.add(prefix);
    } else {
      for (int i = 0; i < n; i++) {
        permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i + 1, n), len);
      }
    }
    return setA;
  }

The above will return the all possible combination of String str = 12345 with size int len=3 , Now your JOB is to filter the unique elements because 123 is equal to 312 from Powerset definition.

  public static void main(String[] args) {
    Set<String> setB = new HashSet<>();
    setB.addAll(permutation("", "12345", 3));
    Set<String> collect = setB.stream().map(
        s -> {
          Optional<String> reduce = Arrays.stream(s.split("")).sorted(Comparator.naturalOrder())
              .reduce((a, b) -> a + b);
          return reduce.get();
        })
        .collect(Collectors.toSet());
    System.out.println(collect);
  }

This should work without any doubt, let me know if you have any doubt.

Full code, I have on Github: https://github.com/vishwaratna/Practice-Codes/blob/master/src/main/java/BenchmarkingWithJMH.java

Vishwa Ratna
  • 5,567
  • 5
  • 33
  • 55
0

I have researched about this subject a bit more. I think I managed to solve the problem with much simpler syntax. Have a look:

public static <T> Set<Set<T>> powerSet(Collection<T> workedList, int len ) {
    List<T> powerGroup = new LinkedList<>(workedList);
    Set<Set<T>> groups = new HashSet<>();
    for (int groupSize = 1; groupSize <= len; groupSize ++){
        for (int start = 0; start < powerGroup.size() - groupSize; start ++){
            groups.add(new HashSet<>(powerGroup.subList(start, groupSize)));
        }
    }
    return groups;
}