Ticket #7364: trac_7364.patch

File trac_7364.patch, 3.9 KB (added by ncohen, 11 years ago)
  • sage/graphs/graph.py

    # HG changeset patch
    # User Nathann Cohen <nathann.cohen@gmail.com>
    # Date 1257072942 -3600
    # Node ID 80ef8aab92854214b04ae43db9d592d84ec62dd1
    # Parent  141a9e4958828eaed5648231aee32d8e0cef7ef2
    Graph : Beginning of an Orientation section, with eulerian_orientation
    
    diff -r 141a9e495882 -r 80ef8aab9285 sage/graphs/graph.py
    a b  
    21052105
    21062106    num_edges = size
    21072107
     2108    ### Orientations
     2109
     2110    def eulerian_orientation(self):
     2111        r"""
     2112        Returns a DiGraph which is an eulerian orientation of the current graph.
     2113
     2114        An eulerian graph being a graph such that any vertex has an even degree,
     2115        an eulerian orientation of a graph is an orientation of its edges such
     2116        that each vertex `v` verifies `d^+(v)=d^-(v)=d(v)/2`, where `d^+` and
     2117        `d^-` respectively represent the out-degree and the in-degree of a vertex.
     2118
     2119        If the graph is not eulerian, the orientation verifies for any vertex `v`
     2120        that `| d^+(v)-d^-(v) | \leq 1`.
     2121
     2122        ALGORITHM:
     2123       
     2124        This algorithm is a random walk through the edges of the graph, which
     2125        orients the edges according to the walk. When a vertex is reached which
     2126        has no non-oriented edge ( this vertex must have odd degree ), the
     2127        walk resumes at another vertex of odd degree, if any.
     2128
     2129        This algorithm has complexity `O(m)`, where `m` is the number of edges
     2130        in the graph.
     2131
     2132        EXAMPLES:
     2133
     2134        The CubeGraph with parameter 4, which is regular of even degree, has an
     2135        eulerian orientation such that `d^+=d^-`::
     2136
     2137            sage: g=graphs.CubeGraph(4)
     2138            sage: g.degree()
     2139            [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
     2140            sage: o=g.eulerian_orientation()
     2141            sage: o.in_degree()
     2142            [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
     2143            sage: o.out_degree()
     2144            [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
     2145       
     2146        Secondly, the Petersen Graph, which is 3 regular has an orientation
     2147        such that the difference between `d^+` and `d^-` is at most 1::
     2148
     2149            sage: g=graphs.PetersenGraph()
     2150            sage: o=g.eulerian_orientation()
     2151            sage: o.in_degree()
     2152            [2, 2, 2, 2, 1, 2, 1, 1, 1, 1]
     2153            sage: o.out_degree()
     2154            [1, 1, 1, 1, 2, 1, 2, 2, 2, 2]
     2155        """
     2156
     2157        g=self.copy()
     2158        d=DiGraph()
     2159        d.add_vertices(g.vertex_iterator())
     2160
     2161
     2162        # list of vertices of odd degree
     2163        from itertools import izip
     2164        odd=[x for (x,deg) in izip(g.vertex_iterator(),g.degree_iterator()) if deg%2==1]
     2165       
     2166        # Picks the first vertex, which is preferably an odd one
     2167        if len(odd)>0:
     2168            v=odd.pop()
     2169        else:
     2170            v=g.edge_iterator(labels=None).next()[0]
     2171            odd.append(v)
     2172        # Stops when there is no edge left
     2173        while True:
     2174
     2175            # If there is an edge adjacent to the current one
     2176            if g.degree(v)>0:
     2177                e = g.edge_iterator(v).next()
     2178                g.delete_edge(e)
     2179                if e[0]!=v:
     2180                    e=(e[1],e[0],e[2])
     2181                d.add_edge(e)
     2182                v=e[1]
     2183
     2184            # The current vertex is isolated
     2185            else:
     2186                odd.remove(v)
     2187
     2188                # jumps to another odd vertex if possible
     2189                if len(odd)>0:
     2190                    v=odd.pop()
     2191                # Else jumps to an ever vertex which is not isolated
     2192                elif g.size()>0:
     2193                    v=g.edge_iterator().next()[0]
     2194                    odd.append(v)
     2195                # If there is none, we are done !
     2196                else:
     2197                    return d
     2198
    21082199    ### Planarity
    21092200
    21102201    def is_planar(self, on_embedding=None, kuratowski=False, set_embedding=False, set_pos=False):