Ticket #9581: trac_9581-edge_incident.2.patch

File trac_9581-edge_incident.2.patch, 7.8 KB (added by vdelecroix, 10 years ago)

rebased version (apply only this one)

  • sage/graphs/generic_graph.py

    # HG changeset patch
    # User Vincent Delecroix <20100.delecroix at gmail.com>
    # Date 1286705749 -7200
    # Node ID 4b23c26b5c30da957eba2e4d848c2614d16d9c73
    # Parent  7ae7b5175304fea5b08c9ee313c372a3936baa1e
    #9581: edges_incident does not return the right answer
    
    This patch correct edges_incident, add a sort option to many edge function and
    improve many algorithms which involve iteration.
    
    diff -r 7ae7b5175304 -r 4b23c26b5c30 sage/graphs/generic_graph.py
    a b  
    71857185
    71867186    def edges(self, labels=True, sort=True, key=None):
    71877187        r"""
    7188         Return a list of the edges of the graph as triples (u,v,l)
    7189         where u and v are vertices and l is a label.
     7188        Return a list of edges.
     7189
     7190        Each edge is a triple (u,v,l) where u and v are vertices and l is a
     7191        label. If the parameter ``labels`` is False then a list of couple (u,v)
     7192        is returned where u and v are vertices.
    71907193
    71917194        INPUT:
    71927195
     
    72697272            L.sort(key=key)
    72707273        return L
    72717274
    7272     def edge_boundary(self, vertices1, vertices2=None, labels=True):
     7275    def edge_boundary(self, vertices1, vertices2=None, labels=True, sort=True):
    72737276        """
    72747277        Returns a list of edges `(u,v,l)` with `u` in ``vertices1``
    72757278        and `v` in ``vertices2``. If ``vertices2`` is ``None``, then
     
    73147317            sage: G = graphs.DiamondGraph()
    73157318            sage: G.edge_boundary([0,1])
    73167319            [(0, 2, {}), (1, 2, {}), (1, 3, {})]
    7317             sage: G = graphs.PetersenGraph()
    73187320            sage: G.edge_boundary([0], [0])
    73197321            []
    7320 
    7321         """
    7322         vertices1 = [v for v in vertices1 if v in self]
    7323         output = []
    7324         if self._directed:
    7325             output.extend(self.outgoing_edge_iterator(vertices1,labels=labels))
     7322            sage: G.edge_boundary([2], [0])
     7323            [(0, 2, {})]
     7324        """
     7325        vertices1 = set([v for v in vertices1 if v in self])
     7326        if self._directed:
    73267327            if vertices2 is not None:
    7327                 output = [e for e in output if e[1] in vertices2]
    7328             else:
    7329                 output = [e for e in output if e[1] not in vertices1]
    7330             return output
    7331         else:
    7332             output.extend(self.edge_iterator(vertices1,labels=labels))
    7333             output2 = []
     7328                vertices2 = set([v for v in vertices2 if v in self])
     7329                output = [e for e in self.outgoing_edge_iterator(vertices1,labels=labels)
     7330                            if e[1] in vertices2]
     7331            else:
     7332                output = [e for e in self.outgoing_edge_iterator(vertices1,labels=labels)
     7333                            if e[1] not in vertices1]
     7334        else:
    73347335            if vertices2 is not None:
    7335                 for e in output:
    7336                     if e[0] in vertices1:
    7337                         if e[1] in vertices2:
    7338                             output2.append(e)
    7339                     elif e[0] in vertices2: # e[1] in vertices1
    7340                         output2.append(e)
    7341             else:
    7342                 for e in output:
    7343                     if e[0] in vertices1:
    7344                         if e[1] not in vertices1:
    7345                             output2.append(e)
    7346                     elif e[0] not in vertices1: # e[1] in vertices1
    7347                         output2.append(e)
    7348             return output2
     7336                vertices2 = set([v for v in vertices2 if v in self])
     7337                output = [e for e in self.edge_iterator(vertices1,labels=labels)
     7338                            if (e[0] in vertices1 and e[1] in vertices2) or
     7339                            (e[1] in vertices1 and e[0] in vertices2)]
     7340            else:
     7341                output = [e for e in self.edge_iterator(vertices1,labels=labels)
     7342                            if e[1] not in vertices1 or e[0] not in vertices1]
     7343        if sort:
     7344            output.sort()
     7345        return output
    73497346
    73507347    def edge_iterator(self, vertices=None, labels=True, ignore_direction=False):
    73517348        """
    7352         Returns an iterator over the edges incident with any vertex given.
    7353         If the graph is directed, iterates over edges going out only. If
    7354         vertices is None, then returns an iterator over all edges. If self
    7355         is directed, returns outgoing edges only.
    7356        
    7357         INPUT:
    7358        
     7349        Returns an iterator over edges.
     7350
     7351        The iterator returned is over the edges incident with any vertex given
     7352        in the parameter ``vertices``. If the graph is directed, iterates over
     7353        edges going out only. If vertices is None, then returns an iterator over
     7354        all edges. If self is directed, returns outgoing edges only.
     7355       
     7356        INPUT:
     7357       
     7358        - ``vertices`` - (default: None) a vertex, a list of vertices or None
    73597359       
    73607360        -  ``labels`` - if False, each edge is a tuple (u,v) of
    73617361           vertices.
    73627362       
    7363         -  ``ignore_direction`` - (default False) only applies
     7363        -  ``ignore_direction`` - bool (default: False) - only applies
    73647364           to directed graphs. If True, searches across edges in either
    73657365           direction.
    73667366       
     
    73997399        else:
    74007400            vertices = [v for v in vertices if v in self]
    74017401        if ignore_direction and self._directed:
    7402             for e in self._backend.iterator_out_edges(vertices, labels):
    7403                 yield e
    7404             for e in self._backend.iterator_in_edges(vertices, labels):
    7405                 yield e
     7402            from itertools import chain
     7403            return chain(self._backend.iterator_out_edges(vertices, labels),
     7404                         self._backend.iterator_in_edges(vertices, labels))
    74067405        elif self._directed:
    7407             for e in self._backend.iterator_out_edges(vertices, labels):
    7408                 yield e
    7409         else:
    7410             for e in self._backend.iterator_edges(vertices, labels):
    7411                 yield e
    7412 
    7413     def edges_incident(self, vertices=None, labels=True):
    7414         """
    7415         Returns a list of edges incident with any vertex given. If vertices
     7406            return self._backend.iterator_out_edges(vertices, labels)
     7407        else:
     7408            return self._backend.iterator_edges(vertices, labels)
     7409
     7410    def edges_incident(self, vertices=None, labels=True, sort=True):
     7411        """
     7412        Returns incident edges to some vertices.
     7413
     7414        If ``vertices` is a vertex, then it returns the list of edges incident to
     7415        that vertex. If ``vertices`` is a list of vertices then it returns the
     7416        list of all edges adjacent to those vertices. If ``vertices``
    74167417        is None, returns a list of all edges in graph. For digraphs, only
    74177418        lists outward edges.
    74187419       
    74197420        INPUT:
    7420        
    7421        
    7422         -  ``label`` - if False, each edge is a tuple (u,v) of
    7423            vertices.
     7421
     7422        - ``vertices`` - object (default: None) - a vertex, a list of vertices
     7423          or None.
     7424       
     7425        -  ``labels`` - bool (default: True) - if False, each edge is a tuple
     7426           (u,v) of vertices.
     7427
     7428        - ``sort`` - bool (default: True) - if True the returned list is sorted.
    74247429       
    74257430       
    74267431        EXAMPLES::
     
    74327437            [(0, 1, None)]
    74337438            sage: D.edges_incident([1])
    74347439            []
     7440
     7441        TESTS::
     7442
     7443            sage: G = Graph({0:[0]}, loops=True)  # ticket 9581
     7444            sage: G.edges_incident(0)
     7445            [(0, 0, None)]
    74357446        """
    74367447        if vertices in self:
    74377448            vertices = [vertices]
    7438         v = list(self.edge_boundary(vertices, labels=labels))
    7439         v.sort()   
    7440         return v
     7449
     7450        if sort:
     7451            return sorted(self.edge_iterator(vertices=vertices,labels=labels))
     7452        return list(self.edge_iterator(vertices=vertices,labels=labels))
    74417453
    74427454    def edge_label(self, u, v=None):
    74437455        """