# Ticket #9581: trac_9581-edge_incident.patch

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

apply only this patch which takes care of Nathan remark

• ## sage/graphs/generic_graph.py

```# HG changeset patch
# User Vincent Delecroix <20100.delecroix at gmail.com>
# Date 1286705749 -7200
# Node ID 00006287cba84791d416da68764b00a5ce4ab96e
# Parent  de197be456daa35faa368faeb11e4a711cd41200
#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 de197be456da -r 00006287cba8 sage/graphs/generic_graph.py```
 a def edges(self, labels=True, sort=True): """ Return a list of edges. Each edge is a triple (u,v,l) where u and v are vertices and l is a label. INPUT: -  ``labels`` - (bool; default: True) if False, each edge is a tuple (u,v) of vertices. -  ``sort`` - (bool; default: True) if True, ensure that the list of edges is sorted. Return a list of edges. Each edge is a triple (u,v,l) where u and v are vertices and l is a label. If the parameter ``labels`` is False then a list of couple (u,v) is returned where u and v are vertices. INPUT: -  ``labels`` - (bool; default: True) if False, each edge is a tuple (u,v) of vertices. -  ``sort`` - (bool; default: True) if True, ensure that the list of edges is sorted. OUTPUT: A list of tuples. It is safe to change the returned list. sage: D.edges(labels = False) [(0, 1), (0, 10), (0, 19), (1, 0), (1, 2), (1, 8), (2, 1), (2, 3), (2, 6), (3, 2), (3, 4), (3, 19), (4, 3), (4, 5), (4, 17), (5, 4), (5, 6), (5, 15), (6, 2), (6, 5), (6, 7), (7, 6), (7, 8), (7, 14), (8, 1), (8, 7), (8, 9), (9, 8), (9, 10), (9, 13), (10, 0), (10, 9), (10, 11), (11, 10), (11, 12), (11, 18), (12, 11), (12, 13), (12, 16), (13, 9), (13, 12), (13, 14), (14, 7), (14, 13), (14, 15), (15, 5), (15, 14), (15, 16), (16, 12), (16, 15), (16, 17), (17, 4), (17, 16), (17, 18), (18, 11), (18, 17), (18, 19), (19, 0), (19, 3), (19, 18)] """ L = list(self.edge_iterator(labels=labels)) if sort: L.sort() return L def edge_boundary(self, vertices1, vertices2=None, labels=True): """ Returns a list of edges `(u,v,l)` with `u` in ``vertices1`` return sorted(self.edge_iterator(labels=labels)) return list(self.edge_iterator(labels=labels)) def edge_boundary(self, vertices1, vertices2=None, labels=True, sort=True): """ Returns a list of edges in the boundary of some vertices. Returns the list of edges `(u,v,l)` with `u` in ``vertices1`` and `v` in ``vertices2``. If ``vertices2`` is ``None``, then it is set to the complement of ``vertices1``. In a digraph, the external boundary of a vertex `v` are those vertices `u` with an arc `(v, u)`. INPUT: -  ``labels`` - if ``False``, each edge is a tuple `(u,v)` of vertices. In a digraph, the external boundary of a vertex `u` are the vertices `v` with an arc `(u, v)`. INPUT: -  ``labels`` - bool (default: True) - if ``False``, each edge is a tuple `(u,v)` of  vertices. - ``sort`` - bool (default: True) - sort the returned list. EXAMPLES:: sage: G = graphs.DiamondGraph() sage: G.edge_boundary([0,1]) [(0, 2, {}), (1, 2, {}), (1, 3, {})] sage: G = graphs.PetersenGraph() sage: G.edge_boundary([0], [0]) [] """ vertices1 = [v for v in vertices1 if v in self] output = [] if self._directed: output.extend(self.outgoing_edge_iterator(vertices1,labels=labels)) sage: G.edge_boundary([2], [0]) [(0, 2, {})] """ vertices1 = set([v for v in vertices1 if v in self]) if self._directed: if vertices2 is not None: output = [e for e in output if e[1] in vertices2] else: output = [e for e in output if e[1] not in vertices1] return output else: output.extend(self.edge_iterator(vertices1,labels=labels)) output2 = [] vertices2 = set([v for v in vertices2 if v in self]) output = [e for e in self.outgoing_edge_iterator(vertices1,labels=labels) if e[1] in vertices2] else: output = [e for e in self.outgoing_edge_iterator(vertices1,labels=labels) if e[1] not in vertices1] else: if vertices2 is not None: for e in output: if e[0] in vertices1: if e[1] in vertices2: output2.append(e) elif e[0] in vertices2: # e[1] in vertices1 output2.append(e) else: for e in output: if e[0] in vertices1: if e[1] not in vertices1: output2.append(e) elif e[0] not in vertices1: # e[1] in vertices1 output2.append(e) return output2 vertices2 = set([v for v in vertices2 if v in self]) output = [e for e in self.edge_iterator(vertices1,labels=labels) if (e[0] in vertices1 and e[1] in vertices2) or (e[1] in vertices1 and e[0] in vertices2)] else: output = [e for e in self.edge_iterator(vertices1,labels=labels) if e[1] not in vertices1 or e[0] not in vertices1] if sort: output.sort() return output def edge_iterator(self, vertices=None, labels=True, ignore_direction=False): """ Returns an iterator over the edges incident with any vertex given. If the graph is directed, iterates over edges going out only. If vertices is None, then returns an iterator over all edges. If self is directed, returns outgoing edges only. INPUT: Returns an iterator over edges. The iterator returned is over the edges incident with any vertex given in the parameter ``vertices``. If the graph is directed, iterates over edges going out only. If vertices is None, then returns an iterator over all edges. If self is directed, returns outgoing edges only. INPUT: - ``vertices`` - (default: None) a vertex, a list of vertices or None -  ``labels`` - if False, each edge is a tuple (u,v) of vertices. -  ``ignore_direction`` - (default False) only applies -  ``ignore_direction`` - bool (default: False) - only applies to directed graphs. If True, searches across edges in either direction. else: vertices = [v for v in vertices if v in self] if ignore_direction and self._directed: for e in self._backend.iterator_out_edges(vertices, labels): yield e for e in self._backend.iterator_in_edges(vertices, labels): yield e from itertools import chain return chain(self._backend.iterator_out_edges(vertices, labels), self._backend.iterator_in_edges(vertices, labels)) elif self._directed: for e in self._backend.iterator_out_edges(vertices, labels): yield e else: for e in self._backend.iterator_edges(vertices, labels): yield e def edges_incident(self, vertices=None, labels=True): """ Returns a list of edges incident with any vertex given. If vertices return self._backend.iterator_out_edges(vertices, labels) else: return self._backend.iterator_edges(vertices, labels) def edges_incident(self, vertices=None, labels=True, sort=True): """ Returns incident edges to some vertices. If ``vertices` is a vertex, then it returns the list of edges incident to that vertex. If ``vertices`` is a list of vertices then it returns the list of all edges adjacent to those vertices. If ``vertices`` is None, returns a list of all edges in graph. For digraphs, only lists outward edges. INPUT: -  ``label`` - if False, each edge is a tuple (u,v) of vertices. - ``vertices`` - object (default: None) - a vertex, a list of vertices or None. -  ``labels`` - bool (default: True) - if False, each edge is a tuple (u,v) of vertices. - ``sort`` - bool (default: True) - if True the returned list is sorted. EXAMPLES:: [(0, 1, None)] sage: D.edges_incident([1]) [] TESTS:: sage: G = Graph({0:[0]}, loops=True)  # ticket 9581 sage: G.edges_incident(0) [(0, 0, None)] """ if vertices in self: vertices = [vertices] v = list(self.edge_boundary(vertices, labels=labels)) v.sort() return v if sort: return sorted(self.edge_iterator(vertices=vertices,labels=labels)) return list(self.edge_iterator(vertices=vertices,labels=labels)) def edge_label(self, u, v=None): """