#8273: Enumeration of cycles in directed graphs
----------------------------+-----------------------------------------------
   Reporter:  abmasse       |       Owner:  rlm               
       Type:  enhancement   |      Status:  needs_work        
   Priority:  major         |   Milestone:  sage-4.3.3        
  Component:  graph theory  |    Keywords:  cycle, enumeration
     Author:  abmasse       |    Upstream:  N/A               
   Reviewer:                |      Merged:                    
Work_issues:                |  
----------------------------+-----------------------------------------------

Comment(by ncohen):

 Hello !!!

 It would be good to get (cheaply) rid of this "bug" happening when the
 vertices are in no non-trivial strongly connected components... Perhaps
 some other parameter meant to be used only internally, in this case too...
 But this would mean a lot of them in the end :-)

 I continued to read some parts of your code, and have some other remarks :

  * you write :
    {{{
         sccs = self.strongly_connected_components()
         from operator import add
         vertices = reduce(add, sccs)
         edges = reduce(add, [self.subgraph(scc).edges() for scc in sccs])
         h = self.subgraph(vertices, edges)
    }}}
    Well, you seem trying to get rid of "bridges" -- edges whose removal
 disconnect the graph. Obviously, there will be no cycle going through
 them. Doing so, you create a lot of copies of the graph (the subgraph()
 command), which could be costly... Here is another way to do it :

    First, create the list of strongly connected components
    {{{
         sccs = self.strongly_connected_components()
    }}}

    Then, associate to each vertex the id of its connected component :

    {{{
         d = {}
         for id, component in enumerate(sccs):
             for v in component:
                 d[v] = id
    }}}

    Once it is done, create a copy of your first graph using the copy
 command (these commands are low-level, written in Cython). Then remove the
 bad edges :

    {{{
         h = self.copy()
         h.delete_edges([ e for e in g.edge_iterator() if d[e[0]] !=
 d[e[1]] ])
    }}}

    This way most of the work is done using dictionaries, and no heavy
 structure like graphs.

  * How is this :

    {{{
         vertices = reduce(add, sccs)
    }}}

    different from setting

    {{{
         vertices = self.vertices()
    }}}

    I think it comes from the same fact that you will have in sccs some
 connected components equal to singletons.

   * You write :

     {{{
         for vi in vertex_iterators.values():
             try:
                 cycles.append(vi.next())
             except(StopIteration):
                 pass
     }}}

     I do not know much about iterators, but... Well, the values of
 vertex_iterators are iterators, so

     {{{
         for vi in vertex_iterators.values():
              cycles.extend(list(vi))
     }}}

     should work, shouldn't it ?

  * This :

    {{{
         while len(cycles) > 0:
    }}}

    Can be replaced by

    {{{
         while cycles:
    }}}

  * In this situation :
    {{{
             for i in range(len(cycles)):
                 if len(cycles[i]) < len(shortest_cycle):
                     shortest_cycle = cycles[i]
                     imin = i
    }}}

    You can write

    {{{
             for i, cycle_i in enumerate(cycles):
                 if len(cycle_i) < len(shortest_cycle):
                     shortest_cycle = cycle_i
                     imin = i
    }}}

    I have been told about this "enumerate" trick when working on Cython
 files... This command is optimized in Cython, so writing Python code this
 way will help if we are to Cythonize it later :-)

    For example :

    {{{
    a = ['pie', 'cake', 'coffee']
    list(enumerate(a))
    [(0, 'pie'), (1, 'cake'), (2, 'coffee')]
    }}}

    Anyway, if you are trying to get the minimum element of such a list,
 you could have also written :

    {{{
    i_min, cycle_min = min( enumerate(cycles), key = lambda x: len(x[1]) )
    }}}

 I'll give a look again at your next version of the patch... Each time I
 get more used to what it does :-)

 Nathann

-- 
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/8273#comment:4>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica, 
and MATLAB

-- 
You received this message because you are subscribed to the Google Groups 
"sage-trac" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sage-trac?hl=en.

Reply via email to