java hashMap Adjacency列出图分区

时间:2016-09-16 10:33:38

标签: java graph hashmap partition adjacency-list

我有一个HashMap:

Key,Value
A,C
B,C
C,D
E,F

这是邻接名单。带有两个分区的图形,其中第一个分区包含节点{A,B,C,D},第二个分区是{E,F}。

问题:给定代表邻接列表的HashMap返回分区。

换句话说:

Input: {[A,C],[B,C],[C,D],[E,F]}
Output: {[A,B,C,D],[E,F]}

用Java解决这个问题的一些解决方案/算法???

Ps:不限于Java,欢迎任何帮助:)

事先提前:)

2 个答案:

答案 0 :(得分:0)

您可以使用任何图形遍历技术(BFS或DFS)。

例如,如果您使用的是BFS:

  • 从任何节点开始(比方说X)。

  • 访问连接到此节点的所有节点后,检查是否访问了图的所有节点。如果遇到未访问的节点,请从此节点启动一个新的BFS,这将是您的第二个分区。

  • 依旧......

在您的情况下,如果您从A启动BFS,它将访问[C,B,D]。这是第一个分区。

现在检查图表(E)中是否有未访问的节点。所以,现在你从E开始一个BFS,你访问的所有节点都在第二个分区。

答案 1 :(得分:0)

IMO最佳解决方案是Union-Find algorithm

public class UnionFind {
    Map<String, String> parents = new HashMap<>();
    Map<String, Integer> representantElements = new HashMap<>();

    public void union(String p0, String p1) {
        String cp0 = find(p0);
        String cp1 = find(p1);
        if (!cp0.equals(cp1)) {
            int size0 = representantElements.get(cp0);
            int size1 = representantElements.get(cp1);
            if (size1 < size0) {
                String swap = cp0;
                cp0 = cp1;
                cp1 = swap;
            }
            representantElements.put(cp0, size0 + size1);
            parents.put(cp1, cp0);
            representantElements.put(cp1, 0);
        }
    }

    public String find(String p) {
        if (!representantElements.containsKey(p)){
            representantElements.put(p, 1);
            return p;
        }
        String result = parents.get(p);
        if (result == null) {
            result = p;
        } else {
            result = find(result);
            parents.put(p, result);
        }
        return result;
    }

    public Set<Set<String>> getPartitions() {
        Map<String, Set<String>> result = new HashMap<>();
        representantElements.forEach((key, value) -> {if (value > 0) {result.put(key, new HashSet<>(value));};});
        representantElements.forEach((key, value) -> result.get(find(key)).add(key));
        return new HashSet<>(result.values());
    }

    public static Set<Set<String>> partitions(String[][] pairs) {
        UnionFind groups = new UnionFind();
        for (String[] pair : pairs) {
            if (pair.length > 1) {
                String first = pair[0];
                for (int i = 1; i < pair.length; i++) {
                    groups.union(first, pair[i]);
                }
            }
        }
        return groups.getPartitions();
    }

    public static void main(String[] args) {
        String[][] elements = {{"A","C"},{"B","C"},{"C","D"},{"E","F"}};
        for (Set<String> partition : partitions(elements)) {
            System.out.println(partition);
        }
    }
}

打印:

[A, B, C, D]
[E, F]