Ticket #14536: trac_14536.patch

File trac_14536.patch, 10.0 KB (added by ncohen, 8 years ago)
  • sage/graphs/base/sparse_graph.pyx

    # HG changeset patch
    # User Nathann Cohen <nathann.cohen@gmail.com>
    # Date 1367848265 -7200
    # Node ID 1314d7f0ad47da9a203e97266704c8f37d69ebf8
    # Parent  3ddb704c55985ca9fe68e7580b9da3c926604948
    Random tournaments, a misnamed method and a segfault
    
    diff --git a/sage/graphs/base/sparse_graph.pyx b/sage/graphs/base/sparse_graph.pyx
    a b  
    291291            sage: from sage.graphs.base.sparse_graph import SparseGraph
    292292            sage: S = SparseGraph(nverts = 10, expected_degree = 3, extra_vertices = 10)
    293293
    294          """
     294        TESTS::
     295
     296            sage: Graph(-1)
     297            Traceback (most recent call last):
     298            ...
     299            ValueError: The number of vertices cannot be strictly negative!
     300        """
    295301        cdef int i = 1
     302        if nverts < 0:
     303            raise ValueError("The number of vertices cannot be strictly negative!")
    296304        if nverts == 0 and extra_vertices == 0:
    297305            raise RuntimeError('Sparse graphs must allocate space for vertices!')
    298306        self.num_verts = nverts
  • sage/graphs/digraph_generators.py

    diff --git a/sage/graphs/digraph_generators.py b/sage/graphs/digraph_generators.py
    a b  
    2121    :meth:`~DiGraphGenerators.RandomDirectedGNP`   | Returns a random digraph on `n` nodes.
    2222    :meth:`~DiGraphGenerators.RandomDirectedGN`    | Returns a random GN (growing network) digraph with `n` vertices.
    2323    :meth:`~DiGraphGenerators.RandomDirectedGNR`   | Returns a random GNR (growing network with redirection) digraph.
    24     :meth:`~DiGraphGenerators.Tournament`          | Returns a tournament on `n` vertices.
     24    :meth:`~DiGraphGenerators.RandomTournament`    | Returns a random tournament on `n` vertices.
     25    :meth:`~DiGraphGenerators.TransitiveTournament`| Returns a transitive tournament on `n` vertices.
     26    :meth:`~DiGraphGenerators.tournaments_nauty`   | Returns all tournaments on `n` vertices using Nauty.
    2527
    2628AUTHORS:
    2729
     
    7678                    - Kautz
    7779                    - Path
    7880                    - ImaseItoh
    79                     - Tournament
     81                    - RandomTournament
     82                    - TransitiveTournament
     83                    - tournaments_nauty
    8084
    8185           
    8286   
     
    304308            sage: g.automorphism_group().cardinality()
    305309            1
    306310        """
    307         if n<0:
    308             raise ValueError("The number of vertices must be a positive integer.")
    309 
    310         g = DiGraph()
    311         g.name("Path on "+str(n)+" vertices")
     311        g = DiGraph(n)
     312        g.name("Path")
    312313
    313314        if n:
    314315            g.add_path(range(n))
     
    316317        g.set_pos({i:(i,0) for i in range(n)})
    317318        return g
    318319
    319     def Tournament(self,n):
     320    def TransitiveTournament(self,n):
    320321        r"""
    321         Returns a tournament on `n` vertices.
     322        Returns a transitive tournament on `n` vertices.
    322323
    323324        In this tournament there is an edge from `i` to `j` if `i<j`.
    324325
     
    328329
    329330        EXAMPLES::
    330331
    331             sage: g = digraphs.Tournament(5)
     332            sage: g = digraphs.TransitiveTournament(5)
    332333            sage: g.vertices()
    333334            [0, 1, 2, 3, 4]
    334335            sage: g.size()
    335336            10
    336337            sage: g.automorphism_group().cardinality()
    337338            1
     339
     340        TESTS::
     341
     342            sage: digraphs.TransitiveTournament(-1)
     343            Traceback (most recent call last):
     344            ...
     345            ValueError: The number of vertices cannot be strictly negative!
    338346        """
    339         if n<0:
    340             raise ValueError("The number of vertices must be a positive integer.")
    341 
    342         g = DiGraph()
    343         g.name("Tournament on "+str(n)+" vertices")
     347        g = DiGraph(n)
     348        g.name("Transitive Tournament")
    344349
    345350        for i in range(n-1):
    346351            for j in range(i+1, n):
     
    352357
    353358        return g
    354359
     360    def RandomTournament(self,n):
     361        r"""
     362        Returns a random tournament on `n` vertices.
     363
     364        The tournament returned has an edge from `i` to `j` with probability
     365        `1/2`.
     366
     367        INPUT:
     368
     369        - ``n`` (integer) -- number of vertices.
     370
     371        EXAMPLES::
     372
     373            sage: digraphs.RandomTournament(10)
     374            Random Tournament: Digraph on 10 vertices
     375            sage: digraphs.RandomTournament(-1)
     376            Traceback (most recent call last):
     377            ...
     378            ValueError: The number of vertices cannot be strictly negative!
     379        """
     380        from sage.misc.prandom import random
     381        g = DiGraph(n)
     382        g.name("Random Tournament")
     383
     384        for i in range(n-1):
     385            for j in range(i+1, n):
     386                if random()<=.5:
     387                    g.add_edge(i,j)
     388                else:
     389                    g.add_edge(j,i)
     390
     391        if n:
     392            from sage.graphs.graph_plot import _circle_embedding
     393            _circle_embedding(g, range(n))
     394
     395        return g
     396
     397    def tournaments_nauty(self, n,
     398                          min_out_degree = None, max_out_degree = None,
     399                          strongly_connected = False, debug=False, options=""):
     400        r"""
     401        Returns all tournaments on `n` vertices using Nauty.
     402
     403        INPUT:
     404
     405        - ``n`` (integer) -- number of vertices.
     406
     407        - ``min_out_degree``, ``max_out_degree`` (integers) -- if set to
     408          ``None`` (default), then the min/max out-degree is not constrained.
     409
     410        - ``debug`` (boolean) -- if ``True`` the first line of genbg's output to
     411          standard error is captured and the first call to the generator's
     412          ``next()`` function will return this line as a string.  A line leading
     413          with ">A" indicates a successful initiation of the program with some
     414          information on the arguments, while a line beginning with ">E"
     415          indicates an error with the input.
     416
     417        - ``options`` (string) -- anything else that should be forwarded as
     418          input to Nauty's genbg. See its documentation for more information :
     419          `<http://cs.anu.edu.au/~bdm/nauty/>`_.
     420
     421
     422        .. NOTE::
     423
     424            To use this method you must first install the Nauty spkg.
     425
     426        EXAMPLES::
     427
     428            sage: for g in digraphs.tournaments_nauty(4): # optional - nauty
     429            ....:    print g.edges(labels = False)        # optional - nauty
     430            [(1, 0), (2, 0), (2, 1), (3, 0), (3, 1), (3, 2)]
     431            [(1, 0), (1, 3), (2, 0), (2, 1), (3, 0), (3, 2)]
     432            [(0, 2), (1, 0), (2, 1), (3, 0), (3, 1), (3, 2)]
     433            [(0, 2), (0, 3), (1, 0), (2, 1), (3, 1), (3, 2)]
     434            sage: tournaments = digraphs.tournaments_nauty
     435            sage: [len(list(tournaments(x))) for x in range(1,8)] # optional - nauty
     436            [1, 1, 2, 4, 12, 56, 456]
     437            sage: [len(list(tournaments(x, strongly_connected = True))) for x in range(1,9)] # optional - nauty
     438            [1, 0, 1, 1, 6, 35, 353, 6008]
     439        """
     440        import subprocess
     441        from sage.misc.package import is_package_installed
     442        if not is_package_installed("nauty"):
     443            raise TypeError("The optional nauty spkg does not seem to be installed")
     444
     445        nauty_input = options
     446
     447        if min_out_degree is None:
     448            min_out_degree = 0
     449        if max_out_degree is None:
     450            max_out_degree = n-1
     451
     452        nauty_input += " -d"+str(min_out_degree)
     453        nauty_input += " -D"+str(max_out_degree)
     454
     455        if strongly_connected:
     456            nauty_input += " -c"
     457
     458        nauty_input +=  " "+str(n) +" "
     459
     460        sp = subprocess.Popen("nauty-gentourng {0}".format(nauty_input), shell=True,
     461                              stdin=subprocess.PIPE, stdout=subprocess.PIPE,
     462                              stderr=subprocess.PIPE, close_fds=True)
     463
     464        if debug:
     465            yield sp.stderr.readline()
     466
     467        gen = sp.stdout
     468        while True:
     469            try:
     470                s = gen.next()
     471            except StopIteration:
     472                raise StopIteration("Exhausted list of graphs from nauty geng")
     473
     474            G = DiGraph(n)
     475            i = 0
     476            j = 1
     477            for b in s[:-1]:
     478                if b == '0':
     479                    G.add_edge(i,j)
     480                else:
     481                    G.add_edge(j,i)
     482
     483                if j == n-1:
     484                    i += 1
     485                    j  = i+1
     486                else:
     487                    j += 1
     488
     489            yield G
     490
    355491    def Circuit(self,n):
    356492        r"""
    357493        Returns the circuit on `n` vertices
     
    366502            sage: len(circuit.strongly_connected_components()) == 1
    367503            True
    368504        """
    369         if n<0:
    370             raise ValueError("The number of vertices must be a positive integer.")
    371 
    372         g = DiGraph()
    373         g.name("Circuit on "+str(n)+" vertices")
     505        g = DiGraph(n)
     506        g.name("Circuit")
    374507
    375508        if n==0:
    376509            return g
     
    405538            Traceback (most recent call last):
    406539            ...
    407540            ValueError: The list must contain only relative integers.
    408             sage: digraphs.Circulant(-2,[3,5,7,3])
    409             Traceback (most recent call last):
    410             ...
    411             ValueError: n must be a positive integer
    412541            sage: digraphs.Circulant(3,[3,5,7,3.4])
    413542            Traceback (most recent call last):
    414543            ...
     
    419548
    420549        # Bad input and loops
    421550        loops = False
    422         if not n in ZZ or n <= 0:
    423             raise ValueError("n must be a positive integer")
    424 
    425551        for i in integers:
    426552            if not i in ZZ:
    427553                raise ValueError("The list must contain only relative integers.")
     
    870996            [(1, 0), (1, 2), (3, 6), (3, 7), (4, 5), (4, 7), (4, 8), (5, 2), (6, 0), (7, 2), (8, 1), (8, 9), (9, 4)]
    871997        """
    872998        from sage.graphs.graph_generators_pyx import RandomGNP
    873         if n < 0:
    874             raise ValueError("The number of nodes must be positive or null.")
    875999        if 0.0 > p or 1.0 < p:
    8761000            raise ValueError("The probability p must be in [0..1].")
    8771001