2

I have set

{A,B,C,D,E}

And I have a map (someMapWithSets in the code example) of sets which indicates if elements are compatible:

A: B,C - (means A is compatible with B and C and etc) 
B: A,E,C
C: A,B
D: E
E: B,D

I need to have a map of sets where all possible combinations of compatible elements are present (largest set possible) with values like (don't care about key):

A,B,C
B,E
D,E

So as I part of the solution I thought I could create a method that retains only compatible elements for the given set and chosen element.

public static Map<String, Set<String>> defineCompatibility(Set<String> set) {
    if (set.isEmpty()) {
        return new HashMap<>();
    }
    Map<String, Set<String>> finalResult = new HashMap<>();
    Set<String> elementsToDefine = new HashSet<>(set);
    while (!elementsToDefine.isEmpty()) {
        String currentElement = elementsToDefine.stream().findFirst().get();
        Set<String> definedSet = defineForElement(set, currentElement);
        finalResult.put(currentElement, definedSet);
        elementsToDefine.remove(currentElement);
    }
    return finalResult;
}

private static Set<String> defineForElement(Set<String> set, String rootElement) {
    Set<String> result = someMapWithSets.get(rootElement);
    result.retainAll(set);
    result.add(rootElement);
    Set<String> tmpHolder = new HashSet<>(result);
    for (String next : tmpHolder) {
        if (!result.contains(next)) {
            break;
        }
        Set<String> strings = someMapWithSets.get(next);
        strings.add(next);
        result.retainAll(strings);
    }
    return result;
}

But this code does not work properly because it is not capable to define all possible combinations, only a few of them. I've tried to store data about elements that were not processed but the code became very complex to be understandable.

I am stuck with implementation. Please help. Maybe there is some well-known algorithm for this task? Thank you.

Alfred Moon
  • 987
  • 1
  • 10
  • 21
  • 1
    To me, this problem looks like finding the number of complete subgraphs. Is this question part of competitive coding? – Deepak Patankar Oct 01 '20 at 17:11
  • Hi Deepak Patankar! No. It is not related to interview questions, some competitions or something like this. I am just trying to go deeper into algorithms and that is the task I’ve created for myself (maybe it is typical, I don’t know). – Alfred Moon Oct 02 '20 at 04:51
  • 1
    Hey @Alfred Moon, this is a very interesting question. I tried solving it like assuming each element as a node in a graph and representing the isCompatable with as a directed edge. If I am correct, then we need to find a subgraph where all the elements are connected to each other. This problem is NP Complete https://stackoverflow.com/questions/2801138/find-all-complete-sub-graphs-within-a-graph – Deepak Patankar Oct 02 '20 at 06:37
  • Thanks @DeepakPatankar! I will try to find solution from this point of view. – Alfred Moon Oct 02 '20 at 14:50

1 Answers1

0

Bron-Kerbosch is used in result.

https://en.wikipedia.org/wiki/Bron%E2%80%93Kerbosch_algorithm

https://iq.opengenus.org/bron-kerbosch-algorithm/

Brute force code looks like this

private static void define(Set<String> r, Set<String> p, Set<String> x) {

    if (p.isEmpty() && x.isEmpty()) {
        System.out.println("Here is maximal clique: " + r);
        return;
    }

    Set<String> p1 = new HashSet<>(p);

    for (String v : p) {
        r.add(v);
        define(r, intersect(p1, someMapWithSets.get(v)), intersect(x, someMapWithSets.get(v)));
        r.remove(v);
        p1.remove(v);
        x.add(v);
    }
}

    private static Set<String> intersect(Set<String> first, Set<String> second) {
    Set<String> holder = new HashSet<>(first);
    holder.retainAll(second);
    return holder;
}
Alfred Moon
  • 987
  • 1
  • 10
  • 21