# Ticket #7289: trac_7289-rebased.patch

File trac_7289-rebased.patch, 6.4 KB (added by rlm, 11 years ago)
• ## sage/graphs/generic_graph.py

# HG changeset patch
# User Nathann Cohen <nathann.cohen@gmail.com>
# Date 1270388381 -7200
# Node ID f5960102b5f61491d3281fc2d8a733a0c749eca3
# Parent  487b54a279b6135f044f3e0a1f3e873903e06426
trac #7289 : Multiway cut for Graphs

diff -r 487b54a279b6 -r f5960102b5f6 sage/graphs/generic_graph.py
 a return tuple(answer) def multiway_cut(self, vertices, value_only = False, use_edge_labels = False, **kwds): r""" Returns a minimum edge multiway cut corresponding to the given set of vertices ( cf. http://www.d.kth.se/~viggo/wwwcompendium/node92.html ) represented by a list of edges. A multiway cut for a vertex set S in a graph or a digraph G if a set C of edges such that any two vertices u,v in S are disconnected when removing from G the edges from C. Such a cut is said to be minimum when its cardinality (or weight) is minimum. INPUT: - vertices (iterable)-- the set of vertices - value_only (boolean) - When set to True, only the value of a minimum multiway cut is returned. - When set to False (default), the list of edges is returned - use_edge_labels (boolean) - When set to True, computes a weighted minimum cut where each edge has a weight defined by its label. ( if an edge has no label, 1 is assumed ) - when set to False (default), each edge has weight 1. - **kwds -- arguments to be passed down to the solve function of MixedIntegerLinearProgram. See the documentation of MixedIntegerLinearProgram.solve for more information. EXAMPLES: Of course, a multiway cut between two vertices correspond to a minimum edge cut :: sage: g = graphs.PetersenGraph() sage: g.edge_cut(0,3) == g.multiway_cut([0,3], value_only = True) # optional - requires GLPK, CBC or CPLEX True As Petersen's graph is 3-regular, a minimum multiway cut between three vertices contains at most 2\times 3 edges (which could correspond to the neighborhood of 2 vertices):: sage: g.multiway_cut([0,3,9], value_only = True) == 2*3          # optional - requires GLPK, CBC or CPLEX True In this case, though, the vertices are an independent set. If we pick instead vertices 0,9, and 7, we can save 4 edges in the multiway cut :: sage: g.multiway_cut([0,7,9], value_only = True) == 2*3 - 1      # optional - requires GLPK, CBC or CPLEX True This example, though, does not work in the directed case anymore, as it is not possible in Petersen's graph to mutualise edges :: sage: g = DiGraph(g) sage: g.multiway_cut([0,7,9], value_only = True) == 3*3           # optional - requires GLPK, CBC or CPLEX True Of course, a multiway cut between the whole vertex set contains all the edges of the graph:: sage: C = g.multiway_cut(g.vertices())                            # optional - requires GLPK, CBC or CPLEX sage: set(C) == set(g.edges())                                    # optional - requires GLPK, CBC or CPLEX True """ from sage.numerical.mip import MixedIntegerLinearProgram from itertools import combinations, chain p = MixedIntegerLinearProgram(maximization = False) # height[c][v] represents the height of vertex v for commodity c height = p.new_variable(dim = 2) # cut[e] represents whether e is in the cut cut = p.new_variable() # Reorder R = lambda x,y : (x,y) if x .5, self.edge_iterator()) else: return filter(lambda (u,v,l) : cut[R(u,v)] > .5, self.edge_iterator()) def vertex_cover(self, algorithm="Cliquer", value_only=False, solver=None, verbose=0): r""" Returns a minimum vertex cover of self represented