Ticket #7593: trac_7593.patch

File trac_7593.patch, 2.8 KB (added by ncohen, 11 years ago)
  • sage/graphs/graph.py

    # HG changeset patch
    # User Nathann Cohen <nathann.cohen@gmail.com>
    # Date 1260813556 -3600
    # Node ID cf964062f80b2e2ae11115502e40fdfe869baa9e
    # Parent  964c2f4ce74db0417a771de0b0cfc951b1fab73c
    Matching for graph
    
    diff -r 964c2f4ce74d -r cf964062f80b sage/graphs/graph.py
    a b  
    32543254            v = pv
    32553255        return B, C
    32563256
     3257    def matching(self,value_only=False, use_edge_labels=True):
     3258        r"""
     3259        Returns a maximum weighted matching of the graph
     3260        ( cf. http://en.wikipedia.org/wiki/Matching )
     3261        represented by the list of its edges.
     3262
     3263        Given a graph `G` such that each edge `e` has a weight `w_e`,
     3264        a maximum matching is a subset `S` of the edges of `G` of
     3265        maximum weight such that no two edges of `S` are incident
     3266        with each other.
     3267
     3268        As an optimization problem, it can be expressed as :
     3269
     3270        .. math::
     3271            \mbox{Maximize : }&\sum_{e\in G.edges()} w_e b_e\\
     3272            \mbox{Such that : }&\forall v \in G, \sum_{(u,v)\in G.edges()} b_{(u,v)}\leq 1\\
     3273            &\forall x\in G, b_x\mbox{ is a binary variable}
     3274   
     3275        INPUT:
     3276   
     3277        - ``value_only`` (boolean)
     3278
     3279            - When set to ``True``, only the cardinal
     3280              ( or the weight ) of the the matching
     3281              is returned
     3282
     3283        - ``use_edge_labels`` (boolean)
     3284
     3285            - When set to ``True``, computes a weighted matching
     3286              where each edge is weighted by its label. ( if
     3287              an edge has no label, `1` is assumed )
     3288              when set to ``False``, each edge has weight `1`
     3289   
     3290        EXAMPLE::
     3291       
     3292           sage: g=graphs.PappusGraph()
     3293           sage: g.matching(value_only=True) # optional - requires Glpk or COIN-OR/CBC
     3294           9.0
     3295        """
     3296
     3297        from sage.numerical.mip import MixedIntegerLinearProgram
     3298        g=self
     3299
     3300        # returns the weight of an edge considering it may not be
     3301        # weighted ...
     3302        weight=lambda x: 1 if x==None else x
     3303
     3304        p=MixedIntegerLinearProgram(maximization=True)
     3305
     3306        b=p.new_variable(dim=2)
     3307        [p.set_objective(sum([weight(w)*b[min(u,v)][max(u,v)] for (u,v,w) in g.edges()]))]
     3308
     3309
     3310        # for any vertex v, there is at most one edge incident to v in the maximum matching
     3311        [p.add_constraint(sum([b[min(u,v)][max(u,v)] for u in g.neighbors(v)]),max=1) for v in g.vertices()]
     3312
     3313        p.set_binary(b)
     3314   
     3315        if value_only:
     3316            return p.solve(objective_only=True)
     3317        else:
     3318            p.solve()
     3319            b=p.get_values(b)
     3320            return [(u,v,w) for (u,v,w) in g.edges() if b[min(u,v)][max(u,v)] == 1]
     3321
    32573322    ### Vertex handlers
    32583323
    32593324    def add_vertex(self, name=None):