Ticket #7378: trac_7378.patch

File trac_7378.patch, 5.5 KB (added by ncohen, 11 years ago)
  • sage/graphs/generic_graph.py

    # HG changeset patch
    # User Nathann Cohen <nathann.cohen@gmail.com>
    # Date 1270394092 -7200
    # Node ID babb150b8ee4b5e214f1760bff641bab0c827feb
    # Parent  1a774059334288a72aaf5e897fb146eb56e41016
    trac 7378 : subdivide edges in a graph
    
    diff -r 1a7740593342 -r babb150b8ee4 sage/graphs/generic_graph.py
    a b  
    55945594        for e in edges:
    55955595            self.add_edge(e)
    55965596
     5597    def subdivide_edge(self, *args):
     5598        """
     5599        Subdivides an edge `k` times.
     5600
     5601        INPUT:
     5602
     5603        The following forms are all accepted to subdivide `8` times
     5604        the edge between vertices `1` and `2` labeled with
     5605        ``"my_label"``.
     5606       
     5607        - ``G.subdivide_edge( 1, 2, 8 )``
     5608        - ``G.subdivide_edge( (1, 2), 8 )``       
     5609        - ``G.subdivide_edge( (1, 2, "my_label"), 8 )``       
     5610
     5611        .. NOTE::
     5612
     5613            * If the given edge is labelled with `l`, all the edges
     5614              created by the subdivision will have the same label.
     5615
     5616            * If no label is given, the label used will be the one
     5617              returned by the method :meth:`edge_label` on the pair
     5618              ``u,v``
     5619       
     5620        EXAMPLE:
     5621
     5622        Subdividing `5` times an edge in a path of length
     5623        `3` makes it a path of length `8`::
     5624
     5625            sage: g = graphs.PathGraph(3)
     5626            sage: edge = g.edges()[0]
     5627            sage: g.subdivide_edge(edge, 5)
     5628            sage: g.is_isomorphic(graphs.PathGraph(8))
     5629            True
     5630
     5631        Subdividing a labelled edge in two ways ::
     5632
     5633            sage: g = Graph()
     5634            sage: g.add_edge(0,1,"label1")
     5635            sage: g.add_edge(1,2,"label2")
     5636            sage: print sorted(g.edges())
     5637            [(0, 1, 'label1'), (1, 2, 'label2')]
     5638
     5639        Specifying the label::
     5640
     5641            sage: g.subdivide_edge(0,1,"label1", 3)
     5642            sage: print sorted(g.edges())
     5643            [(0, 3, 'label1'), (1, 2, 'label2'), (1, 5, 'label1'), (3, 4, 'label1'), (4, 5, 'label1')]
     5644
     5645        The lazy way::
     5646
     5647            sage: g.subdivide_edge(1,2,"label2", 5)
     5648            sage: print sorted(g.edges())
     5649            [(0, 3, 'label1'), (1, 5, 'label1'), (1, 6, 'label2'), (2, 10, 'label2'), (3, 4, 'label1'), (4, 5, 'label1'), (6, 7, 'label2'), (7, 8, 'label2'), (8, 9, 'label2'), (9, 10, 'label2')]
     5650
     5651        If too many arguments are given, an exception is raised ::
     5652
     5653            sage: g.subdivide_edge(0,1,1,1,1,1,1,1,1,1,1)
     5654            Traceback (most recent call last):
     5655            ...
     5656            ValueError: This method takes at most 4 arguments !
     5657
     5658        The same goes when the given edge does not exist::
     5659
     5660            sage: g.subdivide_edge(0,1,"fake_label",5)
     5661            Traceback (most recent call last):
     5662            ...
     5663            ValueError: The given edge does not exist.
     5664           
     5665        .. SEEALSO::
     5666
     5667        - :meth:`subdivide_edges` -- subdivides multiples edges at a time
     5668
     5669        """
     5670
     5671        if len(args) == 2:
     5672            edge, k = args
     5673
     5674            if len(edge) == 2:
     5675                u,v = edge
     5676                l = self.edge_label(u,v)
     5677            elif len(edge) == 3:
     5678                u,v,l = edge
     5679
     5680        elif len(args) == 3:
     5681            u, v, k = args
     5682            l = self.edge_label(u,v)
     5683
     5684        elif len(args) == 4:
     5685            u, v, l, k = args
     5686
     5687        else:
     5688            raise ValueError("This method takes at most 4 arguments !")
     5689
     5690        if not self.has_edge(u,v,l):
     5691            raise ValueError("The given edge does not exist.")
     5692
     5693        for i in xrange(k):
     5694            self.add_vertex()
     5695
     5696        self.delete_edge(u,v,l)
     5697
     5698        edges = []
     5699        for uu in self.vertices()[-k:] + [v]:
     5700            edges.append((u,uu,l))
     5701            u = uu
     5702
     5703        self.add_edges(edges)
     5704
     5705    def subdivide_edges(self, edges, k):
     5706        """
     5707        Subdivides k times edges from an iterable container.
     5708
     5709        For more information on the behaviour of this method, please
     5710        refer to the documentation of :meth:`subdivide_edge`.
     5711
     5712        INPUT:
     5713
     5714        - ``edges`` -- a list of edges
     5715
     5716        - ``k`` (integer) -- common length of the subdivisions
     5717
     5718
     5719        .. NOTE::
     5720
     5721            If a given edge is labelled with `l`, all the edges
     5722            created by its subdivision will have the same label.
     5723       
     5724        EXAMPLE:
     5725
     5726        If we are given the disjoint union of several paths::
     5727
     5728            sage: paths = [2,5,9]
     5729            sage: paths = map(graphs.PathGraph, paths)
     5730            sage: g = Graph()
     5731            sage: for P in paths:
     5732            ...     g = g + P
     5733
     5734        ... subdividing edges in each of them will only change their
     5735        lengths::
     5736
     5737            sage: edges = [P.edges()[0] for P in g.connected_components_subgraphs()]
     5738            sage: k = 6
     5739            sage: g.subdivide_edges(edges, k)
     5740
     5741        Let us check this by creating the graph we expect to have built
     5742        through subdivision::
     5743
     5744            sage: paths2 = [2+k, 5+k, 9+k]
     5745            sage: paths2 = map(graphs.PathGraph, paths2)
     5746            sage: g2 = Graph()
     5747            sage: for P in paths2:
     5748            ...     g2 = g2 + P
     5749            sage: g.is_isomorphic(g2)
     5750            True
     5751
     5752        .. SEEALSO::
     5753
     5754        - :meth:`subdivide_edge` -- subdivides one edge
     5755        """
     5756        for e in edges:
     5757            self.subdivide_edge(e, k)
     5758
    55975759    def delete_edge(self, u, v=None, label=None):
    55985760        r"""
    55995761        Delete the edge from u to v, returning silently if vertices or edge