cdc.graphs.core.GraphConnectedComponents Maven / Gradle / Ivy
package cdc.graphs.core;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import cdc.graphs.EdgeDirection;
import cdc.graphs.EdgeTip;
import cdc.graphs.GraphAdapter;
import cdc.graphs.impl.ExtensionSubGraph;
/**
* Utility dedicated to computation of connected components of a graph.
*
* @author Damien Carbonne
*
* @param Node class
* @param Edge class
*/
public class GraphConnectedComponents extends GraphBase {
public GraphConnectedComponents(GraphAdapter adapter) {
super(adapter);
}
/**
* Computes the connected components containing a particular node.
*
* @param node The node whose connected components subgraph must be
* computed.
* @return The connected components containing node.
*/
public GraphAdapter computeConnectedComponents(N node) {
if (adapter.containsNode(node)) {
final ExtensionSubGraph result = new ExtensionSubGraph<>(adapter);
// Nodes to process. Initialized with node
final Set todo = new HashSet<>();
todo.add(node);
// Nodes that have been processed
final Set done = new HashSet<>();
while (!todo.isEmpty()) {
// Process next node
final N next = todo.iterator().next();
todo.remove(next);
done.add(next);
// Add node to result graph
result.addNode(next);
// Add outgoing edges to result graph
for (final E edge : adapter.getEdges(next, EdgeDirection.OUTGOING)) {
result.addEdge(edge);
final N target = adapter.getTip(edge, EdgeTip.TARGET);
if (!done.contains(target)) {
todo.add(target);
}
}
// Add ingoing edges to result graph
for (final E edge : adapter.getEdges(next, EdgeDirection.INGOING)) {
result.addEdge(edge);
final N source = adapter.getTip(edge, EdgeTip.SOURCE);
if (!done.contains(source)) {
todo.add(source);
}
}
}
return result;
} else {
throw new IllegalArgumentException("Node (" + node + ") does not belong to delegate");
}
}
/**
* Computes all connected components of a graph.
*
* @return A list of all connected components subgraphs.
*/
public List> computeConnectedComponents() {
final List> result = new ArrayList<>();
final Set todo = new HashSet<>();
for (final N node : adapter.getNodes()) {
todo.add(node);
}
while (!todo.isEmpty()) {
final N node = todo.iterator().next();
final GraphAdapter subgraph = computeConnectedComponents(node);
result.add(subgraph);
for (final N n : subgraph.getNodes()) {
todo.remove(n);
}
}
return result;
}
}