# Ticket #8166: trac_8166-rebase.patch

File trac_8166-rebase.patch, 10.2 KB (added by mvngu, 11 years ago)
• ## sage/graphs/generic_graph.py

# HG changeset patch
# User Nathann Cohen <nathann.cohen@gmail.com>
# Date 1274451908 25200
# Node ID 35c219593994239c7763d329c2f510487bb0da01
diff --git a/sage/graphs/generic_graph.py b/sage/graphs/generic_graph.py
 a Please use this method only if you need to copy but change the underlying implementation.  Otherwise simply do copy(g) instead of idoing g.copy(). instead of doing g.copy(). EXAMPLES:: def spanning_trees_count(self, root_vertex=None): """ Returns the number of spanning trees in a graph. In the case of a digraph, couts the number of spanning out-trees rooted in digraph, counts the number of spanning out-trees rooted in root_vertex. Default is to set first vertex as root. .. [AMOZ06] Asahiro, Y. and Miyano, E. and Ono, H. and Zenmyo, K. Graph orientation algorithms to minimize the maximum outdegree Proceedings of the 12th Computing: The Australasian Theroy Symposium Proceedings of the 12th Computing: The Australasian Theory Symposium Volume 51, page 20 Australian Computer Society, Inc. 2006 """ - use_edge_labels -- boolean (default: True) - When set to True, computes a maximun flow - When set to True, computes a maximum flow where each edge has a capacity defined by its label. (If an edge has no label, 1 is assumed.) - solver -- Specify a Linear Program solver to be used. If set to None, the default one is used. function of MixedIntegerLinearProgram. See the documentation  of MixedIntegerLinearProgram.solve for more informations. for more information. - verbose (integer) -- sets the level of verbosity. Set to 0 by default (quiet). sage: g.add_edges([('s',i) for i in range(4)]) sage: g.add_edges([(i,4+j) for i in range(4) for j in range(4)]) sage: g.add_edges([(4+i,'t') for i in range(4)]) sage: [cardinal, flow_graph] = g.flow('s','t',integer=True,value_only=False) # optional - requries GLPK or CBC sage: flow_graph.delete_vertices(['s','t'])                                  # optional - requries GLPK or CBC sage: len(flow_graph.edges(labels=None))                                     # optional - requries GLPK or CBC sage: [cardinal, flow_graph] = g.flow('s','t',integer=True,value_only=False) # optional - requires GLPK or CBC sage: flow_graph.delete_vertices(['s','t'])                                  # optional - requires GLPK or CBC sage: len(flow_graph.edges(labels=None))                                     # optional - requires GLPK or CBC 4 """ return paths def matching(self, value_only=False, use_edge_labels=True, solver=None, verbose=0): def matching(self, value_only=False, algorithm="Edmonds", use_edge_labels=True, solver=None, verbose=0): r""" Returns a maximum weighted matching of the graph represented by the list of its edges. For more information, see the \mbox{Maximize : }&\sum_{e\in G.edges()} w_e b_e\\ \mbox{Such that : }&\forall v \in G, \sum_{(u,v)\in G.edges()} b_{(u,v)}\leq 1\\ &\forall x\in G, b_x\mbox{ is a binary variable} INPUT: INPUT: - value_only -- boolean (default: False). When set to True, only the cardinal (or the weight) of the matching is returned. - algorithm -- string (default: "Edmonds") - "Edmonds" selects Edmonds' algorithm as implemented in NetworkX - "LP" uses a Linear Program formulation of the matching problem - use_edge_labels -- boolean (default: True) - When set to True, computes a weighted matching - When set to False, each edge has weight 1. - solver -- (default: None) Specify a Linear Program (LP) solver to be used. If set to None, the default one is used. For more information on LP solvers and which default solver is used, see - verbose -- integer (default: 0). Sets the level of verbosity. Set to 0 by default, which means quiet. EXAMPLE:: sage: g=graphs.PappusGraph() sage: g.matching(value_only=True) # optional - requires Glpk or COIN-OR/CBC Only useful when algorithm == "LP". ALGORITHM: The problem is solved using Edmond's algorithm implemented in NetworkX, or using Linear Programming depending on the value of algorithm. EXAMPLES: Maximum matching in a Pappus Graph:: sage: g = graphs.PappusGraph() sage: g.matching(value_only=True) 9.0 """ from sage.numerical.mip import MixedIntegerLinearProgram g=self # returns the weight of an edge considering it may not be # weighted ... Same test with the Linear Program formulation:: sage: g = graphs.PappusGraph() sage: g.matching(algorithm="LP", value_only=True) 9.0 TESTS: If algorithm is set to anything different from "Edmonds" or "LP", an exception is raised:: sage: g = graphs.PappusGraph() sage: g.matching(algorithm="somethingdifferent") Traceback (most recent call last): ... ValueError: Algorithm must be set to either "Edmonds" or "LP". """ from sage.rings.real_mpfr import RR weight=lambda x: x if x in RR else 1 p=MixedIntegerLinearProgram(maximization=True) b=p.new_variable(dim=2) p.set_objective(sum([weight(w)*b[min(u,v)][max(u,v)] for (u,v,w) in g.edges()])) # for any vertex v, there is at most one edge incident to v in the maximum matching for v in g.vertices(): p.add_constraint(sum([b[min(u,v)][max(u,v)] for u in g.neighbors(v)]),max=1) p.set_binary(b) if value_only: return p.solve(objective_only=True, solver=solver, log=verbose) else: p.solve(solver=solver, log=verbose) b=p.get_values(b) return [(u,v,w) for (u,v,w) in g.edges() if b[min(u,v)][max(u,v)] == 1] weight = lambda x: x if x in RR else 1 if algorithm == "Edmonds": import networkx if use_edge_labels: g = networkx.Graph() for u, v, l in self.edges(): g.add_edge(u, v, attr_dict={"weight": weight(l)}) else: g = self.networkx_graph(copy=False) d = networkx.max_weight_matching(g) if value_only: return sum([weight(self.edge_label(u, v)) for u, v in d.iteritems()]) * 0.5 else: return [(u, v, self.edge_label(u, v)) for u, v in d.iteritems() if u < v] elif algorithm == "LP": from sage.numerical.mip import MixedIntegerLinearProgram g = self # returns the weight of an edge considering it may not be # weighted ... p = MixedIntegerLinearProgram(maximization=True) b = p.new_variable(dim=2) p.set_objective( sum([weight(w) * b[min(u, v)][max(u, v)] for u, v, w in g.edges()])) # for any vertex v, there is at most one edge incident to v in # the maximum matching for v in g.vertex_iterator(): p.add_constraint( sum([b[min(u, v)][max(u, v)] for u in g.neighbors(v)]), max=1) p.set_binary(b) if value_only: return p.solve(objective_only=True, solver=solver, log=verbose) else: p.solve(solver=solver, log=verbose) b = p.get_values(b) return [(u, v, w) for u, v, w in g.edges() if b[min(u, v)][max(u, v)] == 1] else: raise ValueError( 'Algorithm must be set to either "Edmonds" or "LP".') def dominating_set(self, independent=False, value_only=False, solver=None, verbose=0): r""" def _keys_for_vertices(self): """ Returns a function mapping each vertex to a unique and hopefuly readable string Returns a function mapping each vertex to a unique and hopefully readable string """ from sage.graphs.dot2tex_utils import key, key_with_hash if len(set(key(v) for v in self)) < len(self.vertices()): INPUT: - labels - "string" or "latex" (default: "string"). If labels is string latex command are not interepreted. This option stands for both string latex command are not interpreted. This option stands for both vertex labels and edge labels. - vertex_labels - boolean (default: True) whether to add the labels
diff --git a/sage/graphs/graph.py b/sage/graphs/graph.py