next up previous
Next: Bipartite and 2-colourable graphs Up: Cycles in Graphs Previous: Acyclic graphs and DAG's

Computing girth (of underlying graphs)

We now present an algorithm to compute the length of the shortest cycle in a graph. For directed graphs we want the shortest cycle of its underlying graph. Thus DAGs may have a defined girth. Our algorithm will use a BFS approach from each vertex of the graph. If a graph has a cycle (of length at least 3) then it will be found by doing a BFS from one of the first tex2html_wrap3149 vertices. Whenever the BFS algorithm hits an already seen vertex then it has found a cycle of length at most twice the current level (depth) of the search. The level of the hit vertex (with respect to the BFS ``growing'' vertex) dictates whether it is an odd or even length cycle. Note that an easy-to-implement DFS idea may not work properly. For example, the DFS tree originating from vertex 0 of the third graph of Example 21 finds only 6-cycles with the back-edges (even though a 4-cycle exists using two of the back-edges). In the following java code we decided to illustrate a slightly different programming style. Instead of calling the BFS method directly (like we did above for our algorithm isAcyclic with DFS) we modify the BFS code as needed. We also use the java BitSet class instead of a boolean array (span) and use Vector and Enumeration classes instead of our Queue class.

static public int girth(Graph Gin)      // returns minimum girth >= 3

{

   uGraph G = new uGraph(Gin);          // compute undirected girth

   int n=G.order();

 

   int best = n+1;                      // girth n+1 if no cycles found

 

   for (int i=0; i<n-2; i++)            // look for a cycle from all but last two

   {

     BitSet span = new BitSet(n);

     span.set(i);

     int depth = 1;                     // do a BFS search keeping track of depth

     Vector distList = new Vector();

     distList.addElement( new Integer(i) );

 

     while (depth*2 <= best && best > 3)

     {

        Vector nextList = new Vector();

 

        for (Enumeration e = distList.elements(); e.hasMoreElements(); )

        {

          Vector nbrs = G.neighbors(((Integer) e.nextElement()).intValue());

 

          for (int k=0; k < nbrs.size(); k++)

          {

            int u = ((Integer) nbrs.elementAt(k)).intValue();

 

            if (!span.get(u))

            {

              span.set(u);

              nextList.addElement(new Integer(u));

            }

            else                        // we have found some walk/cycle

            {

             // is there a cross edge at this level

             //

             if ( distList.contains(new Integer(u)) )

             {

               best = depth*2-1; break;

             }

             // else even length cycle (as an upper bound)

             //

              if ( nextList.contains(new Integer(u)) )

              {

                best = depth*2;

              }

            }

          }

        } // for vertices at current depth

 

        distList = nextList;            // next try set of vertices further away

        depth++;

     }

   }

   return best;

}

Note that we return tex2html_wrap3136 if we do not find any cycles. Since we are originating a BFS from all but two of the vertices we do not have to separately worry about ensuring all components have been checked. The line

while (depth*2 <= best && best > 3)

indicates that we stop searching if the depth of the current BFS tree is greater than an already found cycle. We also break out of a grow loop above if we find a small cycle (a cross edge on the current level).


next up previous
Next: Bipartite and 2-colourable graphs Up: Cycles in Graphs Previous: Acyclic graphs and DAG's

Waltraut Ute Lorch
Tue Mar 28 17:10:00 NZST 2000