# Ticket #13188: trac_13188.patch

File trac_13188.patch, 27.7 KB (added by ncohen, 8 years ago)
• ## sage/graphs/chrompoly.pyx

# HG changeset patch
# User Nathann Cohen <nathann.cohen@gmail.com>
# Date 1341072239 -7200
# Node ID f58cebb10eeeb8e1fcaed9f36f953f475c338f95
# Parent  4bf4480e8fd30e0cede481f174fa8630cf558133
Deletion of duplicates in the graph/ files, and update of some deprecation warnings

diff --git a/sage/graphs/chrompoly.pyx b/sage/graphs/chrompoly.pyx
 a def chromatic_polynomial(G, return_tree_basis = False): """ Computes the chromatic polynomial of the graph G. The algorithm used is a recursive one, based on the following observations of Read: - The chromatic polynomial of a tree on n vertices is x(x-1)^(n-1). - If e is an edge of G, G' is the result of deleting the edge e, and G'' is the result of contracting e, then the chromatic polynomial of G is equal to that of G' minus that of G''. EXAMPLES: is the result of contracting e, then the chromatic polynomial of G is equal to that of G' minus that of G''. EXAMPLES:: sage: graphs.CycleGraph(4).chromatic_polynomial() x^4 - 4*x^3 + 6*x^2 - 3*x sage: graphs.CycleGraph(3).chromatic_polynomial()
• ## sage/graphs/cliquer.pyx

diff --git a/sage/graphs/cliquer.pyx b/sage/graphs/cliquer.pyx
 a - Jeroen Demeyer (2011-05-06): Make cliquer interruptible (#11252) REFERENCE: .. [NisOst2003] Sampo Niskanen and Patric R. J. Ostergard, "Cliquer User's  Guide, Version 1.0," Communications Laboratory, Helsinki University of Technology, Espoo, Finland, Tech. Rep. T48, 2003. Methods ------- """ #***************************************************************************** #       Copyright (C) 2009 Nathann Cohen # def all_max_clique(graph): """ Returns the vertex sets of *ALL* the maximum complete subgraphs. Currently only implemented for undirected graphs. Use to_undirected to convert a digraph to an undirected graph. Returns the list of all maximum cliques, with each clique represented by a list of vertices. A clique is an induced complete subgraph, and a maximum clique is one of maximal order. .. NOTE:: Currently only implemented for undirected graphs. Use to_undirected to convert a digraph to an undirected graph. ALGORITHM: This function is based on Cliquer [NisOst2003]_. EXAMPLES:: sage: C=graphs.PetersenGraph() sage: all_max_clique(C) [[2, 7], [7, 9], [6, 8], [6, 9], [0, 4], [4, 9], [5, 7], [0, 5], [5, 8], [3, 4], [2, 3], [3, 8], [1, 6], [0, 1], [1, 2]] sage: graphs.ChvatalGraph().cliques_maximum() [[0, 1], [0, 4], [0, 6], [0, 9], [1, 2], [1, 5], [1, 7], [2, 3], [2, 6], [2, 8], [3, 4], [3, 7], [3, 9], [4, 5], [4, 8], [5, 10], [5, 11], [6, 10], [6, 11], [7, 8], [7, 11], [8, 10], [9, 10], [9, 11]] sage: G = Graph({0:[1,2,3], 1:, 3:[0,1]}) sage: G.show(figsize=[2,2]) sage: G.cliques_maximum() [[0, 1, 2], [0, 1, 3]] sage: C=graphs.PetersenGraph() sage: C.cliques_maximum() [[0, 1], [0, 4], [0, 5], [1, 2], [1, 6], [2, 3], [2, 7], [3, 4], [3, 8], [4, 9], [5, 7], [5, 8], [6, 8], [6, 9], [7, 9]] sage: C = Graph('DJ{') sage: C.cliques_maximum() [[1, 2, 3, 4]] """ graph,d = graph.relabel(inplace=False, return_map=True) else: b.append(list_composition(c,d_inv)) c=[] return b return sorted(b) #computes the clique number of a graph #computes the clique number of a graph def clique_number(graph): """ Returns the size of the largest clique of the graph (clique number). number). Currently only implemented for undirected graphs. Use to_undirected to convert a digraph to an undirected graph.
• ## sage/graphs/digraph.py

diff --git a/sage/graphs/digraph.py b/sage/graphs/digraph.py
 a """ return self._backend.is_directed_acyclic(certificate = certificate) def is_transitive(self, certificate = False): r""" Tests whether the given digraph is transitive. A digraph is transitive if for any pair of vertices u,v\in G linked by a uv-path the edge uv belongs to G. INPUT: - certificate -- whether to return a certificate for negative answers. - If certificate = False (default), this method returns True or False according to the graph. - If certificate = True, this method either returns True answers or yield a pair of vertices uv such that there exists a uv-path in G but uv\not\in G. EXAMPLE:: sage: digraphs.Circuit(4).is_transitive() False sage: digraphs.Circuit(4).is_transitive(certificate = True) (0, 2) sage: digraphs.RandomDirectedGNP(30,.2).is_transitive() False sage: digraphs.DeBruijn(5,2).is_transitive() False sage: digraphs.DeBruijn(5,2).is_transitive(certificate = True) ('00', '10') sage: digraphs.RandomDirectedGNP(20,.2).transitive_closure().is_transitive() True """ from sage.graphs.comparability import is_transitive return is_transitive(self, certificate = certificate) def to_directed(self): """ Since the graph is already directed, simply returns a copy of def in_degree_iterator(self, vertices=None, labels=False): """ Same as degree_iterator, but for in degree. EXAMPLES:: sage: D = graphs.Grid2dGraph(2,4).to_directed() sage: for i in D.in_degree_iterator(): ...    print i else: raise ValueError("implementation must be set to one of \"default\" or \"NetworkX\"") def topological_sort_generator(self): """ Returns a list of all topological sorts of the digraph if it is acyclic, and raises a TypeError if the digraph contains a directed cycle. A topological sort is an ordering of the vertices of the digraph such that each vertex comes before all of its successors. That is, if u comes before v in the sort, then there may be a directed path from u to v, but there will be no directed path from v to u. See also Graph.topological_sort(). AUTHORS: - Mike Hansen - original implementation - Robert L. Miller: wrapping, documentation REFERENCE: -  Pruesse, Gara and Ruskey, Frank. Generating Linear Extensions Fast. SIAM J. Comput., Vol. 23 (1994), no. 2, pp. 373-386. EXAMPLES:: sage: D = DiGraph({ 0:[1,2], 1:, 2:[3,4] }) sage: D.plot(layout='circular').show() sage: D.topological_sort_generator() [[0, 1, 2, 3, 4], [0, 1, 2, 4, 3], [0, 2, 1, 3, 4], [0, 2, 1, 4, 3], [0, 2, 4, 1, 3]] :: sage: for sort in D.topological_sort_generator(): ...       for edge in D.edge_iterator(): ...           u,v,l = edge except AttributeError: return len(self.strongly_connected_components()) == 1 import types import sage.graphs.comparability DiGraph.is_transitive = types.MethodType(sage.graphs.comparability.is_transitive, None, DiGraph)
• ## sage/graphs/distances_all_pairs.pyx

diff --git a/sage/graphs/distances_all_pairs.pyx b/sage/graphs/distances_all_pairs.pyx
 a - Nathann Cohen (2011) REFERENCE: .. [KRG96b] S. Klavzar, A. Rajapakse, and I. Gutman. The Szeged and the Wiener index of graphs. *Applied Mathematics Letters*, 9(5):45--49, 1996. .. [GYLL93c] I. Gutman, Y.-N. Yeh, S.-L. Lee, and Y.-L. Luo. Some recent results in the theory of the Wiener number. *Indian Journal of Chemistry*, 32A:651--661, 1993. Functions --------- sage: w=lambda x: (x*(x*x -1)/6) sage: g.wiener_index()==w(10) True REFERENCE: .. [KRG96b] S. Klavzar, A. Rajapakse, and I. Gutman. The Szeged and the Wiener index of graphs. *Applied Mathematics Letters*, 9(5):45--49, 1996. .. [GYLL93c] I. Gutman, Y.-N. Yeh, S.-L. Lee, and Y.-L. Luo. Some recent results in the theory of the Wiener number. *Indian Journal of Chemistry*, 32A:651--661, 1993. """ if not G.is_connected(): from sage.rings.infinity import Infinity
• ## sage/graphs/generic_graph.py

diff --git a/sage/graphs/generic_graph.py b/sage/graphs/generic_graph.py
 a sage: g.set_planar_positions(test=True) True This method is deprecated. Please use instead: This method is deprecated since Sage-4.4.1.alpha2. Please use instead: sage: g.layout(layout = "planar", save_pos = True) {0: [1, 1], 1: [2, 2], 2: [3, 2], 3: [1, 4], 4: [5, 1], 5: [0, 5], 6: [1, 0]} raise ValueError("The algorithm keyword can be equal to either \"BFS\" or \"Floyd-Warshall\" or \"auto\"") def distances_distribution(self): r""" Returns the distances distribution of the (di)graph in a dictionary. This method *ignores all edge labels*, so that the distance considered is the topological distance. OUTPUT: A dictionary d such that the number of pairs of vertices at distance k (if any) is equal to d[k] \cdot |V(G)| \cdot (|V(G)|-1). .. NOTE:: We consider that two vertices that do not belong to the same connected component are at infinite distance, and we do not take the trivial pairs of vertices (v, v) at distance 0 into account. Empty (di)graphs and (di)graphs of order 1 have no paths and so we return the empty dictionary {}. EXAMPLES: An empty Graph:: sage: g = Graph() sage: g.distances_distribution() {} A Graph of order 1:: sage: g = Graph() sage: g.add_vertex(1) sage: g.distances_distribution() {} A Graph of order 2 without edge:: sage: g = Graph() sage: g.add_vertices([1,2]) sage: g.distances_distribution() {+Infinity: 1} The Petersen Graph:: sage: g = graphs.PetersenGraph() sage: g.distances_distribution() {1: 1/3, 2: 2/3} A graph with multiple disconnected components:: sage: g = graphs.PetersenGraph() sage: g.add_edge('good','wine') sage: g.distances_distribution() {1: 8/33, 2: 5/11, +Infinity: 10/33} The de Bruijn digraph dB(2,3):: sage: D = digraphs.DeBruijn(2,3) sage: D.distances_distribution() {1: 1/4, 2: 11/28, 3: 5/14} """ from sage.graphs.distances_all_pairs import distances_distribution return distances_distribution(self) def eccentricity(self, v=None, dist_dict=None, with_labels=False): """ Return the eccentricity of vertex (or vertices) v. return dist, pred def wiener_index(self): r""" Returns the Wiener index of the graph. The Wiener index of a graph G can be defined in two equivalent ways [KRG96]_ : - W(G) = \frac 1 2 \sum_{u,v\in G} d(u,v) where d(u,v) denotes the distance between vertices u and v. - Let \Omega be a set of \frac {n(n-1)} 2 paths in G such that \Omega contains exactly one shortest u-v path for each set \{u,v\} of vertices in G. Besides, \forall e\in E(G), let \Omega(e) denote the paths from \Omega containing e. We then have W(G) = \sum_{e\in E(G)}|\Omega(e)|. EXAMPLE: From [GYLL93b]_, cited in [KRG96]_:: sage: g=graphs.PathGraph(10) sage: w=lambda x: (x*(x*x -1)/6) sage: g.wiener_index()==w(10) True REFERENCES: .. [KRG96] S. Klavzar, A. Rajapakse, and I. Gutman. The Szeged and the Wiener index of graphs. *Applied Mathematics Letters*, 9(5):45--49, 1996. .. [GYLL93b] I. Gutman, Y.-N. Yeh, S.-L. Lee, and Y.-L. Luo. Some recent results in the theory of the Wiener number. *Indian Journal of Chemistry*, 32A:651--661, 1993. """ from sage.graphs.distances_all_pairs import wiener_index return wiener_index(self) def average_distance(self): r""" Returns the average distance between vertices of the graph. else: return H import types import sage.graphs.distances_all_pairs GenericGraph.distances_distribution = types.MethodType(sage.graphs.distances_all_pairs.distances_distribution, None, GenericGraph) GenericGraph.wiener_index = types.MethodType(sage.graphs.distances_all_pairs.wiener_index, None, GenericGraph) def tachyon_vertex_plot(g, bgcolor=(1,1,1), vertex_colors=None, vertex_size=0.06,
• ## sage/graphs/graph.py

diff --git a/sage/graphs/graph.py b/sage/graphs/graph.py
 a :meth:~Graph.centrality_betweenness | Returns the betweenness centrality **Graph properties:** .. csv-table:: :meth:~Graph.is_weakly_chordal | Tests whether self is weakly chordal. :meth:~Graph.is_strongly_regular | Tests whether self is strongly regular. **Connectivity and orientations:** .. csv-table:: :meth:~Graph.degree_constrained_subgraph | Returns a degree-constrained subgraph. **Clique-related methods:** .. csv-table:: sage: for g in Q: ...     show(g) Visualization ------------- #***************************************************************************** from sage.rings.integer import Integer from sage.misc.superseded import deprecated_function_alias import sage.graphs.generic_graph_pyx as generic_graph_pyx from sage.graphs.generic_graph import GenericGraph from sage.graphs.digraph import DiGraph This graph is not very interesting as it is by default the empty graph. But Sage contains a large collection of pre-defined graph classes that can be listed this way: * Within a Sage session, type graphs. (Do not press "Enter", and do not forget the final period ".") * Hit "tab". You will see a list of methods which will construct named graphs. For example:: by using the almost 200 functions on graphs in the Sage library! If your graph is named g, you can list these functions as previously this way * Within a Sage session, type g. (Do not press "Enter", and do not forget the final period "." ) * Hit "tab". As usual, you can get some information about what these functions do by If you have defined a graph g having several connected components (i.e. g.is_connected() returns False), you can print each one of its connected components with only two lines:: sage: for component in g.connected_components(): ...      g.subgraph(component).plot() INPUT: -  data -- can be any of the following (see the format argument): #.  An integer specifying the number of vertices return left, right def chromatic_polynomial(self): """ Returns the chromatic polynomial of the graph G. EXAMPLES:: sage: G = Graph({0:[1,2,3],1:}) sage: factor(G.chromatic_polynomial()) (x - 2) * x * (x - 1)^2 :: sage: g = graphs.trees(5).next() sage: g.chromatic_polynomial().factor() x * (x - 1)^4 :: sage: seven_acre_wood = sum(graphs.trees(7), Graph()) sage: seven_acre_wood.chromatic_polynomial() x^77 - 66*x^76 ... - 2515943049305400*x^60 ... - 66*x^12 + x^11 :: sage: for i in range(2,7): ...     graphs.CompleteGraph(i).chromatic_polynomial().factor() (x - 1) * x (x - 2) * (x - 1) * x (x - 3) * (x - 2) * (x - 1) * x (x - 4) * (x - 3) * (x - 2) * (x - 1) * x (x - 5) * (x - 4) * (x - 3) * (x - 2) * (x - 1) * x """ from sage.graphs.chrompoly import chromatic_polynomial return chromatic_polynomial(self) def chromatic_number(self, algorithm="DLX", verbose = 0): r""" Returns the minimal number of colors needed to color the vertices return rs_dict def rank_decomposition(self, verbose = False): """ Returns an rank-decomposition of self achieving optiml rank-width. See the documentation of the rankwidth module :mod:rankwidth . INPUT: - verbose (boolean) -- whether to display progress information while computing the decomposition. OUTPUT: A pair (rankwidth, decomposition_tree), where rankwidth is a numerical value and decomposition_tree is a ternary tree describing the decomposition (cf. the module's documentation). See the documentation of the rankwidth module for more information on the tree :mod:rankwidth . .. WARNING:: The current implementation cannot handle graphs of more than 32 vertices. EXAMPLE:: sage: g = graphs.PetersenGraph() sage: rw, tree = g.rank_decomposition() sage: rw 3 sage: tree Graph on 19 vertices sage: tree.is_tree() True """ from sage.graphs.graph_decompositions.rankwidth import rank_decomposition return rank_decomposition(self, verbose = verbose) ### Matching def matching_polynomial(self, complement=True, name=None): """ Computes the matching polynomial of the graph G. If p(G, k) denotes the number of k-matchings (matchings with k edges) in G, then the matching polynomial is defined as [Godsil93]_: .. MATH:: \mu(x)=\sum_{k \geq 0} (-1)^k p(G,k) x^{n-2k} INPUT: - complement - (default: True) whether to use Godsil's duality theorem to compute the matching polynomial from that of the graphs complement (see ALGORITHM). - name - optional string for the variable name in the polynomial .. NOTE:: The complement option uses matching polynomials of complete graphs, which are cached. So if you are crazy enough to try computing the matching polynomial on a graph with millions of vertices, you might not want to use this option, since it will end up caching millions of polynomials of degree in the millions. ALGORITHM: The algorithm used is a recursive one, based on the following observation [Godsil93]_: - If e is an edge of G, G' is the result of deleting the edge e, and G'' is the result of deleting each vertex in e, then the matching polynomial of G is equal to that of G' minus that of G''. (the algorithm actually computes the *signless* matching polynomial, for which the recursion is the same when one replaces the substraction by an addition. It is then converted into the matching polynomial and returned) Depending on the value of complement, Godsil's duality theorem [Godsil93]_ can also be used to compute \mu(x) : .. MATH:: \mu(\overline{G}, x) = \sum_{k \geq 0} p(G,k) \mu( K_{n-2k}, x) Where \overline{G} is the complement of G, and K_n the complete graph on n vertices. EXAMPLES:: sage: g = graphs.PetersenGraph() sage: g.matching_polynomial() x^10 - 15*x^8 + 75*x^6 - 145*x^4 + 90*x^2 - 6 sage: g.matching_polynomial(complement=False) x^10 - 15*x^8 + 75*x^6 - 145*x^4 + 90*x^2 - 6 sage: g.matching_polynomial(name='tom') tom^10 - 15*tom^8 + 75*tom^6 - 145*tom^4 + 90*tom^2 - 6 sage: g = Graph() sage: L = [graphs.RandomGNP(8, .3) for i in [1..5]] sage: prod([h.matching_polynomial() for h in L]) == sum(L, g).matching_polynomial()  # long time (7s on sage.math, 2011) True """ from matchpoly import matching_polynomial return matching_polynomial(self, complement=complement, name=name) ### Convexity def convexity_properties(self): """ Since the graph is already undirected, simply returns a copy of itself. EXAMPLES:: sage: graphs.PetersenGraph().to_undirected() Petersen graph: Graph on 10 vertices """ .. NOTE:: * This function can be expected to be *very* slow, especially where the topological minor does not exist. (CPLEX seems to be *much* more efficient than GLPK on this kind of problem) This function can be expected to be *very* slow, especially where the topological minor does not exist. (CPLEX seems to be *much* more efficient than GLPK on this kind of problem) EXAMPLES: import networkx return sorted(networkx.find_cliques(self.networkx_graph(copy=False))) def cliques(self): """ (Deprecated) alias for cliques_maximal. See that function for more details. EXAMPLE:: sage: C = Graph('DJ{') sage: C.cliques() doctest:...: DeprecationWarning: The function 'cliques' has been deprecated. Use 'cliques_maximal' or 'cliques_maximum'. See http://trac.sagemath.org/5793 for details. [[4, 0], [4, 1, 2, 3]] """ from sage.misc.superseded import deprecation deprecation(5793, "The function 'cliques' has been deprecated. Use " + \ "'cliques_maximal' or 'cliques_maximum'.") return self.cliques_maximal() def cliques_maximum(self): """ Returns the list of all maximum cliques, with each clique represented by a list of vertices. A clique is an induced complete subgraph, and a maximum clique is one of maximal order. .. NOTE:: Currently only implemented for undirected graphs. Use to_undirected to convert a digraph to an undirected graph. ALGORITHM: This function is based on Cliquer [NisOst2003]_. REFERENCE: .. [NisOst2003] Sampo Niskanen and Patric R. J. Ostergard, "Cliquer User's Guide, Version 1.0," Communications Laboratory, Helsinki University of Technology, Espoo, Finland, Tech. Rep. T48, 2003. EXAMPLES:: sage: graphs.ChvatalGraph().cliques_maximum() [[0, 1], [0, 4], [0, 6], [0, 9], [1, 2], [1, 5], [1, 7], [2, 3], [2, 6], [2, 8], [3, 4], [3, 7], [3, 9], [4, 5], [4, 8], [5, 10], [5, 11], [6, 10], [6, 11], [7, 8], [7, 11], [8, 10], [9, 10], [9, 11]] sage: G = Graph({0:[1,2,3], 1:, 3:[0,1]}) sage: G.show(figsize=[2,2]) sage: G.cliques_maximum() [[0, 1, 2], [0, 1, 3]] sage: C=graphs.PetersenGraph() sage: C.cliques_maximum() [[0, 1], [0, 4], [0, 5], [1, 2], [1, 6], [2, 3], [2, 7], [3, 4], [3, 8], [4, 9], [5, 7], [5, 8], [6, 8], [6, 9], [7, 9]] sage: C = Graph('DJ{') sage: C.cliques_maximum() [[1, 2, 3, 4]] """ from sage.graphs.cliquer import all_max_clique return sorted(all_max_clique(self)) cliques = deprecated_function_alias(5739, cliques_maximal) def clique_maximum(self,  algorithm="Cliquer"): """ OUTPUT: graph with labeled edges A graph with labeled edges EXAMPLE: sage: (2*g).gomory_hu_tree().is_connected() False On the other hand, such a tree has lost nothing of the initial On the other hand, such a tree has lost nothing of the initial graph connectedness:: sage: all([ t.flow(u,v) == g.flow(u,v) for u,v in Subsets( g.vertices(), 2 ) ]) Graph.is_long_antihole_free = types.MethodType(sage.graphs.weakly_chordal.is_long_antihole_free, None, Graph) Graph.is_weakly_chordal = types.MethodType(sage.graphs.weakly_chordal.is_weakly_chordal, None, Graph) import sage.graphs.chrompoly Graph.chromatic_polynomial = types.MethodType(sage.graphs.chrompoly.chromatic_polynomial, None, Graph) import sage.graphs.graph_decompositions.rankwidth Graph.rank_decomposition = types.MethodType(sage.graphs.graph_decompositions.rankwidth.rank_decomposition, None, Graph) import sage.graphs.matchpoly Graph.matching_polynomial = types.MethodType(sage.graphs.matchpoly.matching_polynomial, None, Graph) import sage.graphs.cliquer Graph.cliques_maximum = types.MethodType(sage.graphs.cliquer.all_max_clique, None, Graph) def compare_edges(x, y): """
• ## sage/graphs/matchpoly.pyx

diff --git a/sage/graphs/matchpoly.pyx b/sage/graphs/matchpoly.pyx
 a - Robert Miller, Tom Boothby - original implementation REFERENCE: Chris Godsil, Algebraic Combinatorics. .. [Godsil93] Chris Godsil (1993) Algebraic Combinatorics. Methods ------- \mu(x)=\sum_{k \geq 0} (-1)^k p(G,k) x^{n-2k} INPUT: - complement - (default: True) whether to use Godsil's duality x^12 - 66*x^10 + 1485*x^8 - 13860*x^6 + 51975*x^4 - 62370*x^2 + 10395 sage: matching_polynomial(graphs.CompleteGraph(13), complement=False) x^13 - 78*x^11 + 2145*x^9 - 25740*x^7 + 135135*x^5 - 270270*x^3 + 135135*x REFERENCE: .. [Godsil93] Chris Godsil (1993) Algebraic Combinatorics. """ cdef int nverts, nedges, i, j, v, cur