Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding connected components of adjacency matrix graph

I have a random graph represented by an adjacency matrix in Java, how can I find the connected components (sub-graphs) within this graph?

I have found BFS and DFS but not sure they are suitable, nor could I work out how to implement them for an adjacency matrix.

Any ideas?

like image 939
Denti Avatar asked Nov 14 '11 16:11

Denti


People also ask

How do you find the component of adjacency matrix?

Suppose the graph has adjacency matrix A and n vertices. Compute M=(A+I)n. Now define vertices u and v to be equivalent if Mu,v≠0. The equivalence classes of this relation are the connected components of the graph.

How do you find the number of connected components on a graph?

First, mark all vertices as unvisited. Iterate over all vertices. If a vertex is not visited, perform DFS on that vertex and increment the count by 1. After iterating over all vertices, the value of count will be the number of connected components in the graph.

How do you find connected components in a directed graph?

A strongly connected component (SCC) of a directed graph is a maximal strongly connected subgraph. For example, there arel 3 SCCs in the following graph. We can find all strongly connected components in O(V+E) time using Kosaraju's algorithm.


2 Answers

You need to allocate marks - int array of length n, where n is the number of vertex in graph and fill it with zeros. Then:

1) For BFS do the following:

Components = 0;

Enumerate all vertices, if for vertex number i, marks[i] == 0 then

    ++Components;

    Put this vertex into queue, and 

    while queue is not empty, 

        pop vertex v from q

        marks[v] = Components;

        Put all adjacent vertices with marks equal to zero into queue.

2) For DFS do the following.

Components = 0;

Enumerate all vertices, if for vertex number i, marks[i] == 0 then

    ++Components;

    Call DFS(i, Components), where DFS is

    DFS(vertex, Components)
    {
        marks[vertex] = Components;
        Enumerate all vertices adjacent to vertex and 
        for all vertex j for which marks[j] == 0
            call DFS(j, Components);
    }

After performing any of this procedures, Components will have number of connected components, and for each vertex i, marks[i] will represent index of connected component i belongs.

Both complete on O(n) time, using O(n) memory, where n is matrix size. But I suggest you BFS as far as it doesn't suffer from stack overflow problem, and it doesn't spend time on recursive calls.

BFS code in Java:

  public static boolean[] BFS(boolean[][] adjacencyMatrix, int vertexCount, int givenVertex){
      // Result array.
      boolean[] mark = new boolean[vertexCount];

      Queue<Integer> queue = new LinkedList<Integer>();
      queue.add(givenVertex);
      mark[givenVertex] = true;

      while (!queue.isEmpty())
      {
        Integer current = queue.remove();

        for (int i = 0; i < vertexCount; ++i)
            if (adjacencyMatrix[current][i] && !mark[i])
            {
                mark[i] = true;
                queue.add(i);
            }
      }

      return mark;
  }


  public static void main(String[] args) {
      // Given adjacencyMatrix[x][y] if and only if there is a path between x and y.
      boolean[][] adjacencyMatrix = new boolean[][]
              {
                      {false,true,false,false,false},
                      {true,false,false,true,true},
                      {false,false,false,false,false},
                      {true,false,false,false,false},
                      {true,false,false,false,false}
              };
      // Mark[i] is true if and only if i belongs to the same connected component as givenVertex vertex does.
      boolean[] mark = BFS(adjacencyMatrix, 5, 0);

      for (int i = 0; i < 5; ++i)
          System.out.println(mark[i]);
}
like image 131
Wisdom's Wind Avatar answered Oct 01 '22 17:10

Wisdom's Wind


You can implement DFS iteratively with a stack, to eliminate the problems of recursive calls and call stack overflow. The implementation is very similar to BFS with queue - you just have to mark vertices when you pop them, not when you push them in the stack.

like image 29
plamKaTa Avatar answered Oct 01 '22 17:10

plamKaTa