Class ConnectedComponents
- All Implemented Interfaces:
Iterable<ConnectedComponents.ConnectedComponent>
,Algorithm
,DynamicAlgorithm
,org.graphstream.stream.AttributeSink
,org.graphstream.stream.ElementSink
,org.graphstream.stream.Sink
public class ConnectedComponents extends org.graphstream.stream.SinkAdapter implements DynamicAlgorithm, Iterable<ConnectedComponents.ConnectedComponent>
This algorithm computes the connected components for a given graph. Connected components are the set of its connected subgraphs. Two nodes belong to the same connected component when there exists a path (without considering the direction of the edges) between them. Therefore, the algorithm does not consider the direction of the edges. The number of connected components of an undirected graph is equal to the number of connected components of the same directed graph. See wikipedia for details.
Dynamics
This algorithm tries to handle the dynamics of the graph, trying not to recompute all from scratch at each change (kind of re-optimization). In this way, each instance of the algorithm is registered as a graph sink. Each change in the graph topology may affect the algorithm.
Usage
To start using the algorithm, you first need an instance of
Graph
, then you only have to instantiate the
algorithm class. Whether you specify a reference to the graph in the
constructor or you set it with the init(Graph)
method.
The computation of the algorithm starts only when the graph is specified with
the init(Graph)
method or with the appropriated constructor. In case
of a static graph, you may call the compute()
method. In case of a
dynamic graph, the algorithm will compute itself automatically when an event
(node or edge added or removed) occurs.
Finally you may ask the algorithm for the number of connected components at
any moment with a call to the getConnectedComponentsCount()
method.
Example
import org.graphstream.algorithm.ConnectedComponents; import org.graphstream.graph.Graph; import org.graphstream.graph.implementations.DefaultGraph; public class CCTest { public static void main(String[] args) { Graph graph = new DefaultGraph("CC Test"); graph.addNode("A"); graph.addNode("B"); graph.addNode("C"); graph.addEdge("AB", "A", "B"); graph.addEdge("AC", "A", "C"); ConnectedComponents cc = new ConnectedComponents(); cc.init(graph); System.out.printf("%d connected component(s) in this graph, so far.%n", cc.getConnectedComponentsCount()); graph.removeEdge("AC"); System.out.printf("Eventually, there are %d.%n", cc.getConnectedComponentsCount()); } }
Additional features
Threshold and Ceiling
It is possible to get rid of connected components belong a size threshold
when counting the overall number of connected components. It is also possible
to define a ceiling size for the connected component. Above that size
ceiling, connected components will not be counted. Use the
getConnectedComponentsCount(int)
or
getConnectedComponentsCount(int, int)
methods.
Components Identifiers
You can tag each node with an integer that identifies the component it
pertains to using setCountAttribute(String)
. The argument of this
method is an arbitrary name that will be used as attribute on each node of
the graph. The value of this attribute will be an integer (counting from
zero) that is different for each connected component.
Giant component
The getGiantComponent()
method gives you a list of nodes belonging
to the biggest connected component of the graph.
Cut Attribute
The cut attribute is a feature that can optionally simulate a given edge to
be invisible (as if the edge did not exist). In other words if an edge is
given such a cut attribute, it will be ignored by the algorithm when
counting. You can enable (or disable by passing null) the cut attribute by
specifying it with the setCutAttribute(String)
method, and by giving
the special edges the same attribute.
What is it useful for? Well you may want to simulate the removal of a given edge and see if it increases the number of connected components. You may not want to really remove and then re-add that edge in the graph, because such removal event may have consequences on other algorithms, viewer, writers...
Note that setting the cut attribute will trigger a new computation of the algorithm.
- Since:
- June 26 2007
- Author:
- Yoann Pigné, Antoine Dutot, Guillaume-Jean Herbiet, Guilhelm Savin
- Computational Complexity :
- For the initial computation, let n be the number of nodes, then the complexity is 0(n). For the re-optimization steps, let k be the number of nodes concerned by the changes (k <= n), the complexity is O(k).
-
Nested Class Summary
Nested Classes Modifier and Type Class Description class
ConnectedComponents.ConnectedComponent
A representation of a connected component. -
Constructor Summary
Constructors Constructor Description ConnectedComponents()
Construction of an instance with no parameter.ConnectedComponents(org.graphstream.graph.Graph graph)
Constructor with the given graph. -
Method Summary
Modifier and Type Method Description void
compute()
Run the algorithm.String
defaultResult()
void
edgeAdded(String graphId, long timeId, String edgeId, String fromNodeId, String toNodeId, boolean directed)
void
edgeAttributeAdded(String graphId, long timeId, String edgeId, String attribute, Object value)
void
edgeAttributeRemoved(String graphId, long timeId, String edgeId, String attribute)
void
edgeRemoved(String graphId, long timeId, String edgeId)
ConnectedComponents.ConnectedComponent
getConnectedComponentOf(int nodeIndex)
Same asgetConnectedComponentOf(Node)
but using the node index.ConnectedComponents.ConnectedComponent
getConnectedComponentOf(String nodeId)
Same asgetConnectedComponentOf(Node)
but using the node id.ConnectedComponents.ConnectedComponent
getConnectedComponentOf(org.graphstream.graph.Node n)
Return the connected component where a node belonged.int
getConnectedComponentsCount()
Ask the algorithm for the number of connected components.int
getConnectedComponentsCount(int sizeThreshold)
Ask the algorithm for the number of connected components whose size is equal to or greater than the specified threshold.int
getConnectedComponentsCount(int sizeThreshold, int sizeCeiling)
Ask the algorithm for the number of connected components whose size is equal to or greater than the specified threshold and lesser than the specified ceiling.ConnectedComponents.ConnectedComponent
getGiantComponent()
Get the connected component that contains the biggest number of nodes.void
graphCleared(String graphId, long timeId)
void
init(org.graphstream.graph.Graph graph)
Initialization of the algorithm.Iterator<ConnectedComponents.ConnectedComponent>
iterator()
void
nodeAdded(String graphId, long timeId, String nodeId)
void
nodeRemoved(String graphId, long timeId, String nodeId)
void
publish(String nodeAttribute)
Publish the index of the connected component where the node belongs.void
setCountAttribute(String countAttribute)
Enable (or disable by passing null for countAttribute) an optional attribute that will be assigned to each node.void
setCutAttribute(String cutAttribute)
Enable (or disable by passing null) an optional attribute that makes edges that have it invisible (as if the edge did not existed).void
terminate()
Terminate the dynamic algorithm.Methods inherited from class org.graphstream.stream.SinkAdapter
edgeAttributeChanged, graphAttributeAdded, graphAttributeChanged, graphAttributeRemoved, nodeAttributeAdded, nodeAttributeChanged, nodeAttributeRemoved, stepBegins
-
Constructor Details
-
ConnectedComponents
public ConnectedComponents()Construction of an instance with no parameter. The process is not initialized and the algorithm will not receive any event from any graph. You will have to call theinit(Graph)
method with a reference to a graph so that the computation is able to start. After theinit(Graph)
method is invoked, the computation starts as soon as and event is received or if thecompute()
method is invoked. -
ConnectedComponents
public ConnectedComponents(org.graphstream.graph.Graph graph)Constructor with the given graph. The computation of the algorithm start only when theinit(Graph)
method is invoked. This Constructor will call theinit(Graph)
method anyway.- Parameters:
graph
- The graph who's connected components will be computed.
-
-
Method Details
-
init
public void init(org.graphstream.graph.Graph graph)Description copied from interface:Algorithm
Initialization of the algorithm. This method has to be called before theAlgorithm.compute()
method to initialize or reset the algorithm according to the new given graph. -
compute
public void compute()Description copied from interface:Algorithm
Run the algorithm. TheAlgorithm.init(Graph)
method has to be called before computing.- Specified by:
compute
in interfaceAlgorithm
- See Also:
Algorithm.init(Graph)
-
terminate
public void terminate()Description copied from interface:DynamicAlgorithm
Terminate the dynamic algorithm.- Specified by:
terminate
in interfaceDynamicAlgorithm
- See Also:
Algorithm.init(org.graphstream.graph.Graph)
-
iterator
- Specified by:
iterator
in interfaceIterable<ConnectedComponents.ConnectedComponent>
-
publish
Publish the index of the connected component where the node belongs. This is more efficient than using thesetCountAttribute(String)
method. The latter will update the attribute at each change, implying a bigger complexity cost, while this method is a one shot call, so you can use it only when you need to manipulate the connected component indexes.- Parameters:
nodeAttribute
- id of the attribute where the index of the connected component will be stored.
-
getGiantComponent
Get the connected component that contains the biggest number of nodes.- Returns:
- the biggest CC.
-
getConnectedComponentsCount
public int getConnectedComponentsCount()Ask the algorithm for the number of connected components.- Returns:
- the number of connected components in this graph.
-
defaultResult
-
getConnectedComponentsCount
public int getConnectedComponentsCount(int sizeThreshold)Ask the algorithm for the number of connected components whose size is equal to or greater than the specified threshold.- Parameters:
sizeThreshold
- Minimum size for the connected component to be considered- Returns:
- the number of connected components, bigger than the given size threshold, in this graph.
-
getConnectedComponentsCount
public int getConnectedComponentsCount(int sizeThreshold, int sizeCeiling)Ask the algorithm for the number of connected components whose size is equal to or greater than the specified threshold and lesser than the specified ceiling.- Parameters:
sizeThreshold
- Minimum size for the connected component to be consideredsizeCeiling
- Maximum size for the connected component to be considered (use 0 or lower values to ignore the ceiling)- Returns:
- the number of connected components, bigger than the given size threshold, and smaller than the given size ceiling, in this graph.
-
getConnectedComponentOf
public ConnectedComponents.ConnectedComponent getConnectedComponentOf(org.graphstream.graph.Node n)Return the connected component where a node belonged. The validity of the result ends if any new computation is done. So you will have to call this method again to be sure you are manipulating the good component.- Parameters:
n
- a node- Returns:
- the connected component containing `n`
-
getConnectedComponentOf
Same asgetConnectedComponentOf(Node)
but using the node id.- Parameters:
nodeId
- a node id- Returns:
- the connected component containing the node `nodeId`
-
getConnectedComponentOf
Same asgetConnectedComponentOf(Node)
but using the node index.- Parameters:
nodeIndex
- a node index- Returns:
- the connected component containing the node `nodeIndex`
-
setCutAttribute
Enable (or disable by passing null) an optional attribute that makes edges that have it invisible (as if the edge did not existed). Be careful, setting the cut attribute will trigger a new computation of the algorithm.- Parameters:
cutAttribute
- The name for the cut attribute or null if the cut attribute option must be disabled.
-
setCountAttribute
Enable (or disable by passing null for countAttribute) an optional attribute that will be assigned to each node. The value of this attribute will be an integer different for each computed component.- Parameters:
countAttribute
- The name of the attribute to put on each node (pass null to disable this feature).
-
edgeAdded
public void edgeAdded(String graphId, long timeId, String edgeId, String fromNodeId, String toNodeId, boolean directed)- Specified by:
edgeAdded
in interfaceorg.graphstream.stream.ElementSink
- Overrides:
edgeAdded
in classorg.graphstream.stream.SinkAdapter
-
edgeRemoved
- Specified by:
edgeRemoved
in interfaceorg.graphstream.stream.ElementSink
- Overrides:
edgeRemoved
in classorg.graphstream.stream.SinkAdapter
-
nodeAdded
- Specified by:
nodeAdded
in interfaceorg.graphstream.stream.ElementSink
- Overrides:
nodeAdded
in classorg.graphstream.stream.SinkAdapter
-
nodeRemoved
- Specified by:
nodeRemoved
in interfaceorg.graphstream.stream.ElementSink
- Overrides:
nodeRemoved
in classorg.graphstream.stream.SinkAdapter
-
edgeAttributeAdded
public void edgeAttributeAdded(String graphId, long timeId, String edgeId, String attribute, Object value)- Specified by:
edgeAttributeAdded
in interfaceorg.graphstream.stream.AttributeSink
- Overrides:
edgeAttributeAdded
in classorg.graphstream.stream.SinkAdapter
-
edgeAttributeRemoved
- Specified by:
edgeAttributeRemoved
in interfaceorg.graphstream.stream.AttributeSink
- Overrides:
edgeAttributeRemoved
in classorg.graphstream.stream.SinkAdapter
-
graphCleared
- Specified by:
graphCleared
in interfaceorg.graphstream.stream.ElementSink
- Overrides:
graphCleared
in classorg.graphstream.stream.SinkAdapter
-