Path: blob/master/src/sage/graphs/generators/degree_sequence.py
8815 views
# -*- coding: utf-8 -*-1r"""2Graphs with a given degree sequence34The methods defined here appear in :mod:`sage.graphs.graph_generators`.5"""67###########################################################################8#9# Copyright (C) 2006 Robert L. Miller <[email protected]>10# and Emily A. Kirkman11# Copyright (C) 2009 Michael C. Yurko <[email protected]>12#13# Distributed under the terms of the GNU General Public License (GPL)14# http://www.gnu.org/licenses/15###########################################################################1617# import from Sage library18from sage.graphs.graph import Graph19from sage.misc.randstate import current_randstate202122def DegreeSequence(deg_sequence):23"""24Returns a graph with the given degree sequence. Raises a NetworkX25error if the proposed degree sequence cannot be that of a graph.2627Graph returned is the one returned by the Havel-Hakimi algorithm,28which constructs a simple graph by connecting vertices of highest29degree to other vertices of highest degree, resorting the remaining30vertices by degree and repeating the process. See Theorem 1.4 in31[CharLes1996]_.3233INPUT:3435- ``deg_sequence`` - a list of integers with each36entry corresponding to the degree of a different vertex.373839EXAMPLES::4041sage: G = graphs.DegreeSequence([3,3,3,3])42sage: G.edges(labels=False)43[(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]44sage: G.show() # long time4546::4748sage: G = graphs.DegreeSequence([3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3])49sage: G.show() # long time5051::5253sage: G = graphs.DegreeSequence([4,4,4,4,4,4,4,4])54sage: G.show() # long time5556::5758sage: G = graphs.DegreeSequence([1,2,3,4,3,4,3,2,3,2,1])59sage: G.show() # long time6061REFERENCE:6263.. [CharLes1996] Chartrand, G. and Lesniak, L.: Graphs and Digraphs.64Chapman and Hall/CRC, 1996.65"""66import networkx67return Graph(networkx.havel_hakimi_graph([int(i) for i in deg_sequence]))6869def DegreeSequenceBipartite(s1 ,s2 ):70r"""71Returns a bipartite graph whose two sets have the given72degree sequences.7374Given two different sequences of degrees `s_1` and `s_2`,75this functions returns ( if possible ) a bipartite graph76on sets `A` and `B` such that the vertices in `A` have77`s_1` as their degree sequence, while `s_2` is the degree78sequence of the vertices in `B`.7980INPUT:8182- ``s_1`` -- list of integers corresponding to the degree83sequence of the first set.84- ``s_2`` -- list of integers corresponding to the degree85sequence of the second set.8687ALGORITHM:8889This function works through the computation of the matrix90given by the Gale-Ryser theorem, which is in this case91the adjacency matrix of the bipartite graph.9293EXAMPLES:9495If we are given as sequences ``[2,2,2,2,2]`` and ``[5,5]``96we are given as expected the complete bipartite97graph `K_{2,5}` ::9899sage: g = graphs.DegreeSequenceBipartite([2,2,2,2,2],[5,5])100sage: g.is_isomorphic(graphs.CompleteBipartiteGraph(5,2))101True102103Some sequences being incompatible if, for example, their sums104are different, the functions raises a ``ValueError`` when no105graph corresponding to the degree sequences exists. ::106107sage: g = graphs.DegreeSequenceBipartite([2,2,2,2,1],[5,5])108Traceback (most recent call last):109...110ValueError: There exists no bipartite graph corresponding to the given degree sequences111112TESTS:113114Trac ticket #12155::115116sage: graphs.DegreeSequenceBipartite([2,2,2,2,2],[5,5]).complement()117complement(): Graph on 7 vertices118"""119120from sage.combinat.integer_vector import gale_ryser_theorem121from sage.graphs.bipartite_graph import BipartiteGraph122123s1 = sorted(s1, reverse = True)124s2 = sorted(s2, reverse = True)125126m = gale_ryser_theorem(s1,s2)127128if m is False:129raise ValueError("There exists no bipartite graph corresponding to the given degree sequences")130else:131return Graph(BipartiteGraph(m))132133def DegreeSequenceConfigurationModel(deg_sequence, seed=None):134"""135Returns a random pseudograph with the given degree sequence. Raises136a NetworkX error if the proposed degree sequence cannot be that of137a graph with multiple edges and loops.138139One requirement is that the sum of the degrees must be even, since140every edge must be incident with two vertices.141142INPUT:143144- ``deg_sequence`` - a list of integers with each145entry corresponding to the expected degree of a different vertex.146147- ``seed`` - for the random number generator.148149150EXAMPLES::151152sage: G = graphs.DegreeSequenceConfigurationModel([1,1])153sage: G.adjacency_matrix()154[0 1]155[1 0]156157Note: as of this writing, plotting of loops and multiple edges is158not supported, and the output is allowed to contain both types of159edges.160161::162163sage: G = graphs.DegreeSequenceConfigurationModel([3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3])164sage: G.edges(labels=False)165[(0, 2), (0, 10), (0, 15), (1, 6), (1, 16), (1, 17), (2, 5), (2, 19), (3, 7), (3, 14), (3, 14), (4, 9), (4, 13), (4, 19), (5, 6), (5, 15), (6, 11), (7, 11), (7, 17), (8, 11), (8, 18), (8, 19), (9, 12), (9, 13), (10, 15), (10, 18), (12, 13), (12, 16), (14, 17), (16, 18)]166sage: G.show() # long time167168REFERENCE:169170.. [Newman2003] Newman, M.E.J. The Structure and function of complex171networks, SIAM Review vol. 45, no. 2 (2003), pp. 167-256.172"""173if seed is None:174seed = current_randstate().long_seed()175import networkx176return Graph(networkx.configuration_model([int(i) for i in deg_sequence], seed=seed), loops=True, multiedges=True, sparse=True)177178def DegreeSequenceTree(deg_sequence):179"""180Returns a tree with the given degree sequence. Raises a NetworkX181error if the proposed degree sequence cannot be that of a tree.182183Since every tree has one more vertex than edge, the degree sequence184must satisfy len(deg_sequence) - sum(deg_sequence)/2 == 1.185186INPUT:187188- ``deg_sequence`` - a list of integers with each189entry corresponding to the expected degree of a different vertex.190191192EXAMPLE::193194sage: G = graphs.DegreeSequenceTree([3,1,3,3,1,1,1,2,1])195sage: G.show() # long time196"""197import networkx198return Graph(networkx.degree_sequence_tree([int(i) for i in deg_sequence]))199200def DegreeSequenceExpected(deg_sequence, seed=None):201"""202Returns a random graph with expected given degree sequence. Raises203a NetworkX error if the proposed degree sequence cannot be that of204a graph.205206One requirement is that the sum of the degrees must be even, since207every edge must be incident with two vertices.208209INPUT:210211- ``deg_sequence`` - a list of integers with each212entry corresponding to the expected degree of a different vertex.213214- ``seed`` - for the random number generator.215216217EXAMPLE::218219sage: G = graphs.DegreeSequenceExpected([1,2,3,2,3])220sage: G.edges(labels=False)221[(0, 2), (0, 3), (1, 1), (1, 4), (2, 3), (2, 4), (3, 4), (4, 4)]222sage: G.show() # long time223224REFERENCE:225226.. [ChungLu2002] Chung, Fan and Lu, L. Connected components in random227graphs with given expected degree sequences.228Ann. Combinatorics (6), 2002 pp. 125-145.229"""230if seed is None:231seed = current_randstate().long_seed()232import networkx233return Graph(networkx.expected_degree_graph([int(i) for i in deg_sequence], seed=seed), loops=True)234235236