| 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 | |