Skip to content

Commit

Permalink
Fix same-weight bug (issue #5) (#6)
Browse files Browse the repository at this point in the history
* fix same-weight bug (issue #5)

* Fix weight

* Fix typos

* change to first strategy

* revert to spaces

* correct formatting using blue style

---------

Co-authored-by: etienneINSA <[email protected]>
  • Loading branch information
thchr and etiennedeg authored May 2, 2024
1 parent 7d14c0b commit 76286e2
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 16 deletions.
37 changes: 21 additions & 16 deletions src/blossomv.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""
minimum_weight_perfect_matching(g, w::Dict{Edge,Real})
minimum_weight_perfect_matching(g, w::Dict{Edge,Real}, cutoff)
minimum_weight_perfect_matching(g, w::Dict{Edge,Real})
minimum_weight_perfect_matching(g, w::Dict{Edge,Real}, cutoff)
Given a graph `g` and an edgemap `w` containing weights associated to edges,
returns a matching with the mimimum total weight among the ones containing
Expand All @@ -20,8 +20,10 @@ In case of error try to change the optional argument `tmaxscale` (default is `tm
"""
function minimum_weight_perfect_matching end

function minimum_weight_perfect_matching(g::Graph, w::Dict{E,U}, cutoff, kws...) where {U<:Real, E<:Edge}
wnew = Dict{E, U}()
function minimum_weight_perfect_matching(
g::Graph, w::Dict{E,U}, cutoff, kws...
) where {U<:Real,E<:Edge}
wnew = Dict{E,U}()
for (e, c) in w
if c <= cutoff
wnew[e] = c
Expand All @@ -30,40 +32,43 @@ function minimum_weight_perfect_matching(g::Graph, w::Dict{E,U}, cutoff, kws...)
return minimum_weight_perfect_matching(g, wnew; kws...)
end

function minimum_weight_perfect_matching(g::Graph, w::Dict{E,U}; tmaxscale=10.) where {U<:AbstractFloat, E<:Edge}
wnew = Dict{E, Int32}()
function minimum_weight_perfect_matching(
g::Graph, w::Dict{E,U}; tmaxscale=10.0
) where {U<:AbstractFloat,E<:Edge}
wnew = Dict{E,Int32}()
cmax = maximum(values(w))
cmin = minimum(values(w))
tmax = typemax(Int32) / tmaxscale # /10 is kinda arbitrary,
# hopefully high enough to not occur in overflow problems

tmax = typemax(Int32) / tmaxscale # /10 is kinda arbitrary,
# hopefully high enough to not occur in overflow problems
for (e, c) in w
wnew[e] = round(Int32, (c-cmin) / (cmax-cmin) * tmax)
wnew[e] = round(Int32, (c - cmin) / max(cmax - cmin, 1) * tmax)
end
match = minimum_weight_perfect_matching(g, wnew)
weight = zero(U)
for i=1:nv(g)
for i in 1:nv(g)
j = match.mate[i]
if j > i
weight += w[E(i,j)]
weight += w[E(i, j)]
end
end
return MatchingResult(weight, match.mate)
end

function minimum_weight_perfect_matching(g::Graph, w::Dict{E,U}) where {U<:Integer, E<:Edge}
function minimum_weight_perfect_matching(g::Graph, w::Dict{E,U}) where {U<:Integer,E<:Edge}
m = BlossomV.Matching(nv(g))
for (e, c) in w
BlossomV.add_edge(m, src(e)-1, dst(e)-1, c)
BlossomV.add_edge(m, src(e) - 1, dst(e) - 1, c)
end
BlossomV.solve(m)

mate = fill(-1, nv(g))
totweight = zero(U)
for i=1:nv(g)
j = BlossomV.get_match(m, i-1) + 1
for i in 1:nv(g)
j = BlossomV.get_match(m, i - 1) + 1
mate[i] = j <= 0 ? -1 : j
if i < j
totweight += w[Edge(i,j)]
totweight += w[Edge(i, j)]
end
end
return MatchingResult(totweight, mate)
Expand Down
15 changes: 15 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,21 @@ end
@test match.mate[2] == 3
@test match.mate[3] == 2
@test match.weight 11.5

# Issue #5
g = Graph(Graph([Edge(1,2), Edge(2,3), Edge(4,1)]))
w = Dict(Edge(1,2) => 2.0, Edge(2,3) => 2.0, Edge(1,4) => 2.0)
match = minimum_weight_perfect_matching(g, w)
@test match.mate == [4,3,2,1]
@test match.weight == 4.0

g = Graph([Edge(1,2)])
wFloat = Dict(Edge(1,2) => 2.0)
wInt = Dict(Edge(1,2) => 2)
matchFloat = minimum_weight_perfect_matching(g, wFloat)
matchInt = minimum_weight_perfect_matching(g, wInt)
@test matchFloat.mate == matchInt.mate
@test matchFloat.weight == matchInt.weight
end


Expand Down

0 comments on commit 76286e2

Please sign in to comment.