使用快速查找算法 (Java) 在有向图中查找所有弱连通分量的优化
Posted
技术标签:
【中文标题】使用快速查找算法 (Java) 在有向图中查找所有弱连通分量的优化【英文标题】:Optimization for Find All Weakly Connected Components in Directed Graph Using Quick-Find Algorithm (Java) 【发布时间】:2016-08-17 02:09:16 【问题描述】:我正在寻求改进我的解决方案,以便使用 Quick-Find 算法在有向图中查找所有弱连通分量。
问题陈述
给定DirectedGraphNode
的列表,找到所有岛屿(即弱连接组件)。
public class DirectedGraphNode
String val;
List<DirectedGraphNode> neighbors;
因此,给定以下有向图:
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;
然而,这个算法在最坏的情况下运行在 O(N^3),因为它每次都需要对联合进行线性搜索。我很好奇是否有任何方法可以改善这一点。
感谢您的建议!
【问题讨论】:
我不确定它的性能 jgrapht.org/javadoc/org/jgrapht/alg/ConnectivityInspector.html 来自 JGraphT,所以只是一个提示:“目前,检查器支持无向图的连接组件和有向图的弱连接组件” 【参考方案1】:这是一个经过编辑的答案。抱歉,我对弱连接组件和强连接组件感到困惑。
确定弱连接组件实际上非常简单。只需将所有边转换为无向并执行 BFS 或 DFS。
运行时间为O(|V| + |E|)
,其中V
是顶点集,E
是边集。
【讨论】:
Java 实现:jgrapht.org/javadoc/org/jgrapht/alg/package-summary.html @wookie919 我只是想知道将所有边转换为无向的运行时复杂性。进行这种转换的好方法是什么? @gyoho 如果B
是A
的邻居,则添加A
作为B
的邻居。这将花费O(|E|)
时间。
@wookie919 为了进一步优化,我将neighbors
的数据结构从List
更改为Set
以实现O(1)
查找neighbors
以避免添加重复.以上是关于使用快速查找算法 (Java) 在有向图中查找所有弱连通分量的优化的主要内容,如果未能解决你的问题,请参考以下文章