Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用快速查找算法(Java)优化查找有向图中所有弱连通分量_Java_Algorithm_Graph_Connected Components_Union Find - Fatal编程技术网

用快速查找算法(Java)优化查找有向图中所有弱连通分量

用快速查找算法(Java)优化查找有向图中所有弱连通分量,java,algorithm,graph,connected-components,union-find,Java,Algorithm,Graph,Connected Components,Union Find,我正在寻求改进我的解决方案,使用快速查找算法查找有向图中的所有弱连通分量 问题陈述 给定DirectedGraphNode列表,查找所有孤岛(即弱连接组件) 我使用快速查找算法解决了这个问题。代码如下: public static List<List<Node>> connectedComponents(List<Node> nodes) { if (nodes == null || nodes.size() == 0) { throw

我正在寻求改进我的解决方案,使用快速查找算法查找有向图中的所有弱连通分量

问题陈述

给定
DirectedGraphNode
列表,查找所有孤岛(即弱连接组件)

我使用快速查找算法解决了这个问题。代码如下:

public static List<List<Node>> connectedComponents(List<Node> nodes) {
    if (nodes == null || nodes.size() == 0) {
        throw new IllegalArgumentException("List node is empty");
    }

    // Maintain array with name for each element
    String[] labels = new String[nodes.size()];
    // Initially, set the labels of each element to itself
    // Use HashMap to memorize the index
    Map<String, Integer> map = new HashMap<>();
    for (int i = 0; i < labels.length; i++) {
        labels[i] = nodes.get(i).val;
        map.put(nodes.get(i).val, i);
    }

    for (Node node : nodes) {
        if (node.neighbors == null || node.neighbors.isEmpty()) {
            continue;
        }

        int changerIdx = map.get(node.val);
        for (Node nbr : node.neighbors) {
            int changeeIdx = map.get(nbr.val);
            String symbol = labels[changeeIdx];
            for (int i = 0; i < labels.length; i++) {
                if (labels[i] == symbol) {
                    labels[i] = labels[changerIdx];
                }
            }
        }
    }
    return createIslandList(labels, nodes);
}

private static List<List<Node>> createIslandList(String[] labels, List<Node> nodes) {
    List<List<Node>> res = new ArrayList<List<Node>>();
    if (labels == null || labels.length == 0) {
        return res;
    }

    Map<String, List<Node>> map = new HashMap<String, List<Node>>();
    for (int i = 0; i < labels.length; i++) {
        if (!map.containsKey(labels[i])) {
            List<Node> island = new ArrayList<>();
            island.add(nodes.get(i));
            map.put(labels[i], island);
        } else {
            map.get(labels[i]).add(nodes.get(i));
        }
    }

    for (String key : map.keySet()) {
        res.add(map.get(key));
    }

    return res;
}
公共静态列表已连接组件(列表节点){
if(nodes==null | | nodes.size()==0){
抛出新的IllegalArgumentException(“列表节点为空”);
}
//使用每个元素的名称维护数组
String[]labels=新字符串[nodes.size()];
//最初,将每个元素的标签设置为自身
//使用HashMap来记忆索引
Map Map=newhashmap();
对于(int i=0;i
然而,在最坏的情况下,该算法在O(N^3)中运行,因为每次它都需要对并集进行线性搜索。我很好奇是否有任何方法可以改进这一点


谢谢你的建议

这是一个经过编辑的答案。很抱歉,我混淆了弱连接组件和强连接组件

确定弱连接组件实际上非常简单。只需将所有边转换为无向,并执行BFS或DFS


运行时间将是
O(|V |+| E |)
其中
V
是顶点集,
E
是边集。

我不确定JGraphT的性能,所以只需提示一下:“目前,inspector支持无向图的连接组件和有向图的弱连接组件”Java实现:@wooke919我只是想知道将所有边转换为无向的运行时复杂性。进行此转换的好方法是什么?@gyoho如果
B
a
的邻居,则添加
a
作为
B
的邻居。这将花费
O(| E |)
时间。@Wooke919为了进一步优化,我将
邻居的数据结构从
List
更改为
Set
,以实现
O(1)
查找以搜索
邻居,以避免添加重复项。
A —> B —> <— C 
     ^
     |
     E <— F —> D —> G

X -> <- Y

node : neighbors
  A  :  [B]
  B  :  [C, E]
  C  :  [B]
  D  :  [G]
  E  :  []
  F  :  [E, D]
  G  :  []
  X  :  [Y]
  Y  :  [X]
[
   [A, B, C, E, D, F, G],
   [X, Y]
]
public static List<List<Node>> connectedComponents(List<Node> nodes) {
    if (nodes == null || nodes.size() == 0) {
        throw new IllegalArgumentException("List node is empty");
    }

    // Maintain array with name for each element
    String[] labels = new String[nodes.size()];
    // Initially, set the labels of each element to itself
    // Use HashMap to memorize the index
    Map<String, Integer> map = new HashMap<>();
    for (int i = 0; i < labels.length; i++) {
        labels[i] = nodes.get(i).val;
        map.put(nodes.get(i).val, i);
    }

    for (Node node : nodes) {
        if (node.neighbors == null || node.neighbors.isEmpty()) {
            continue;
        }

        int changerIdx = map.get(node.val);
        for (Node nbr : node.neighbors) {
            int changeeIdx = map.get(nbr.val);
            String symbol = labels[changeeIdx];
            for (int i = 0; i < labels.length; i++) {
                if (labels[i] == symbol) {
                    labels[i] = labels[changerIdx];
                }
            }
        }
    }
    return createIslandList(labels, nodes);
}

private static List<List<Node>> createIslandList(String[] labels, List<Node> nodes) {
    List<List<Node>> res = new ArrayList<List<Node>>();
    if (labels == null || labels.length == 0) {
        return res;
    }

    Map<String, List<Node>> map = new HashMap<String, List<Node>>();
    for (int i = 0; i < labels.length; i++) {
        if (!map.containsKey(labels[i])) {
            List<Node> island = new ArrayList<>();
            island.add(nodes.get(i));
            map.put(labels[i], island);
        } else {
            map.get(labels[i]).add(nodes.get(i));
        }
    }

    for (String key : map.keySet()) {
        res.add(map.get(key));
    }

    return res;
}