Class ConnectedComponents

java.lang.Object
org.graphstream.stream.SinkAdapter
org.graphstream.algorithm.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>
Compute and update the number of connected components of a dynamic graph.

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).
  • 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 the init(Graph) method with a reference to a graph so that the computation is able to start. After the init(Graph) method is invoked, the computation starts as soon as and event is received or if the compute() method is invoked.
    • ConnectedComponents

      public ConnectedComponents​(org.graphstream.graph.Graph graph)
      Constructor with the given graph. The computation of the algorithm start only when the init(Graph) method is invoked. This Constructor will call the init(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 the Algorithm.compute() method to initialize or reset the algorithm according to the new given graph.
      Specified by:
      init in interface Algorithm
      Parameters:
      graph - The graph this algorithm is using.
    • compute

      public void compute()
      Description copied from interface: Algorithm
      Run the algorithm. The Algorithm.init(Graph) method has to be called before computing.
      Specified by:
      compute in interface Algorithm
      See Also:
      Algorithm.init(Graph)
    • terminate

      public void terminate()
      Description copied from interface: DynamicAlgorithm
      Terminate the dynamic algorithm.
      Specified by:
      terminate in interface DynamicAlgorithm
      See Also:
      Algorithm.init(org.graphstream.graph.Graph)
    • iterator

      Specified by:
      iterator in interface Iterable<ConnectedComponents.ConnectedComponent>
    • publish

      public void publish​(String nodeAttribute)
      Publish the index of the connected component where the node belongs. This is more efficient than using the setCountAttribute(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

      public ConnectedComponents.ConnectedComponent 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

      public String 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 considered
      sizeCeiling - 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

      public ConnectedComponents.ConnectedComponent getConnectedComponentOf​(String nodeId)
      Same as getConnectedComponentOf(Node) but using the node id.
      Parameters:
      nodeId - a node id
      Returns:
      the connected component containing the node `nodeId`
    • getConnectedComponentOf

      public ConnectedComponents.ConnectedComponent getConnectedComponentOf​(int nodeIndex)
      Same as getConnectedComponentOf(Node) but using the node index.
      Parameters:
      nodeIndex - a node index
      Returns:
      the connected component containing the node `nodeIndex`
    • setCutAttribute

      public 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). 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

      public void setCountAttribute​(String countAttribute)
      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 interface org.graphstream.stream.ElementSink
      Overrides:
      edgeAdded in class org.graphstream.stream.SinkAdapter
    • edgeRemoved

      public void edgeRemoved​(String graphId, long timeId, String edgeId)
      Specified by:
      edgeRemoved in interface org.graphstream.stream.ElementSink
      Overrides:
      edgeRemoved in class org.graphstream.stream.SinkAdapter
    • nodeAdded

      public void nodeAdded​(String graphId, long timeId, String nodeId)
      Specified by:
      nodeAdded in interface org.graphstream.stream.ElementSink
      Overrides:
      nodeAdded in class org.graphstream.stream.SinkAdapter
    • nodeRemoved

      public void nodeRemoved​(String graphId, long timeId, String nodeId)
      Specified by:
      nodeRemoved in interface org.graphstream.stream.ElementSink
      Overrides:
      nodeRemoved in class org.graphstream.stream.SinkAdapter
    • edgeAttributeAdded

      public void edgeAttributeAdded​(String graphId, long timeId, String edgeId, String attribute, Object value)
      Specified by:
      edgeAttributeAdded in interface org.graphstream.stream.AttributeSink
      Overrides:
      edgeAttributeAdded in class org.graphstream.stream.SinkAdapter
    • edgeAttributeRemoved

      public void edgeAttributeRemoved​(String graphId, long timeId, String edgeId, String attribute)
      Specified by:
      edgeAttributeRemoved in interface org.graphstream.stream.AttributeSink
      Overrides:
      edgeAttributeRemoved in class org.graphstream.stream.SinkAdapter
    • graphCleared

      public void graphCleared​(String graphId, long timeId)
      Specified by:
      graphCleared in interface org.graphstream.stream.ElementSink
      Overrides:
      graphCleared in class org.graphstream.stream.SinkAdapter