Skip to content

Commit 7afc16f

Browse files
add function maximum_weight_matching_reduction based on a reduction using minimum_weight_perfect_matching function
1 parent 76286e2 commit 7afc16f

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

src/maximum_weight_matching.jl

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,49 @@ function default_weights(g::G) where {G<:AbstractGraph}
7777
end
7878
return m
7979
end
80+
81+
"""
82+
maximum_weight_matching_reduction(g::Graph, w::Matrix{Real}) -> Array{Edge}
83+
84+
Given a graph `g` and an edgemap `w` containing weights associated to edges,
85+
returns a matching with the maximum total weight.
86+
`w` is a dictionary that maps edges i => j to weights.
87+
If no weight parameter is given, all edges will be considered to have weight 1
88+
89+
This algorithm use a reduction based on the minimum_weight_perfect_matching function
90+
to find the maximum weight matching.
91+
92+
Return an array of edges contained in the matching.
93+
"""
94+
function maximum_weight_matching_reduction(g::Graph,
95+
w::AbstractMatrix{U} = default_weights(g)) where {U <:Real}
96+
97+
h = deepcopy(g)
98+
iter = collect(edges(h))
99+
l = nv(h)
100+
add_vertices!(h,l)
101+
weights = Dict{typeof(iter[1]),typeof(w[1][1])}()
102+
for edge in iter
103+
add_edge!(h,src(edge) + l,dst(edge) + l)
104+
weights[edge] = -w[src(edge),dst(edge)]
105+
weights[Edge(dst(edge),src(edge))] = -w[src(edge),dst(edge)]
106+
weights[Edge(src(edge) + l,dst(edge) + l)] = -w[src(edge),dst(edge)]
107+
weights[Edge(dst(edge) + l,src(edge) + l)] = -w[src(edge),dst(edge)]
108+
end
109+
for i in 1:l
110+
add_edge!(g,i,i+l)
111+
weights[Edge(i,i+l)] = 0
112+
end
113+
114+
match = minimum_weight_perfect_matching(h,weights)
115+
116+
result = Edge[]
117+
118+
for i in 1:l
119+
if(match.mate[i] <= l && match.mate[i] > 0)
120+
push!(result,Edge(i,match.mate[i]))
121+
end
122+
end
123+
124+
return result
125+
end

test/runtests.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,22 @@ using LinearAlgebra: I
77

88
@testset "GraphsMatching" begin
99

10+
@testset "maximum_weight_matching_reduction" begin
11+
N = Int(1e2)
12+
g = complete_graph(N)
13+
m = ne(g)
14+
w = randn(N,N)
15+
w = transpose(w)*w
16+
match_sol = maximum_weight_matching(g, optimizer_with_attributes(Cbc.Optimizer, "LogLevel" => 0), w)
17+
match_red = maximum_weight_matching_reduction(g,w)
18+
sol = Edge[]
19+
for i in 1:m
20+
if(match_sol[i] > 0)
21+
push!(sol,Edge(i,match_sol[i]))
22+
end
23+
@test sol = match_red
24+
end
25+
1026
@testset "maximum_weight_matching" begin
1127
g = complete_graph(3)
1228
w = [

0 commit comments

Comments
 (0)