Skip to content

Commit 2ecb87e

Browse files
committed
introduce AbstractMinimumWeightPerfectMatchingAlgorithm for ease of dispatch for MWPM implementations -- currently only BlossomVAlgorithm is implemented
1 parent 4aa2f1f commit 2ecb87e

File tree

1 file changed

+58
-12
lines changed

1 file changed

+58
-12
lines changed

src/blossomv.jl

Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,85 @@
11
"""
2-
minimum_weight_perfect_matching(g, w::Dict{Edge,Real})
3-
minimum_weight_perfect_matching(g, w::Dict{Edge,Real}, cutoff)
2+
minimum_weight_perfect_matching(g, w::Dict{Edge,Real}; tmaxscale)
3+
minimum_weight_perfect_matching(g, w::Dict{Edge,Real}, cutoff; tmaxscale)
4+
minimum_weight_perfect_matching(g, w::Dict{Edge,Real}, algorithm::AbstractMinimumWeightPerfectMatchingAlgorithm; tmaxscale)
5+
minimum_weight_perfect_matching(g, w::Dict{Edge,Real}, cutoff, algorithm::AbstractMinimumWeightPerfectMatchingAlgorithm; tmaxscale)
46
57
Given a graph `g` and an edgemap `w` containing weights associated to edges,
68
returns a matching with the mimimum total weight among the ones containing
79
exactly `nv(g)/2` edges.
810
911
Edges in `g` not present in `w` will not be considered for the matching.
1012
11-
This function relies on the BlossomV.jl package, a julia wrapper
12-
around Kolmogorov's BlossomV algorithm.
13+
You can use the `algorithm` argument to specify the algorithm to use.
1314
14-
Eventually a `cutoff` argument can be given, to the reduce computational time
15+
A `cutoff` argument can be given, to reduce the computational time by
1516
excluding edges with weights higher than the cutoff.
1617
17-
The returned object is of type `MatchingResult`.
18+
When the weights are non-integer types, the keyword argument `tmaxscale` can be used to
19+
scale the weights to integer values.
20+
In case of error try to change `tmaxscale` (default is `tmaxscale=10`).
21+
The scaling is as follows:
22+
```
23+
tmax = typemax(Int32) / tmaxscale
24+
weight = round(Int32, (weight-minimum_weight) / max(maximum_weight-minimum_weight, 1) * tmax)
25+
```
1826
19-
In case of error try to change the optional argument `tmaxscale` (default is `tmaxscale=10`).
27+
The returned object is of type [`MatchingResult`](@ref).
28+
29+
See also: [`BlossomVAlgorithm`](@ref)
2030
"""
2131
function minimum_weight_perfect_matching end
2232

33+
"""
34+
AbstractMinimumWeightPerfectMatchingAlgorithm
35+
36+
Abstract type that allows users to pass in their preferred algorithm
37+
38+
See also: [`minimum_weight_perfect_matching`](@ref), [`BlossomVAlgorithm`](@ref)
39+
"""
40+
abstract type AbstractMinimumWeightPerfectMatchingAlgorithm end
41+
42+
"""
43+
BlossomVAlgorithm()
44+
45+
Use the BlossomV algorithm to find the minimum weight perfect matching.
46+
Depends on the BlossomV.jl package. You have to call `using BlossomV`
47+
before using this algorithm.
48+
49+
This algorithm dispatches to the BlossomV library, a C library for finding
50+
minimum weight perfect matchings in general graphs.
51+
The BlossomV library is not open source, and thus we can not distribute a
52+
a precompiled binary with GraphsMatching.jl. We attempt to build it on
53+
installation, but unlike typical Julia packages, the build process is prone
54+
to failure if you do not have all the dependencies installed.
55+
If BlossomV.jl does not work on your system,
56+
consider using the LEMONGraphs.jl algorithm instead (the default algorithm),
57+
which we distribute precompiled on all platforms.
58+
59+
See also: [`minimum_weight_perfect_matching`](@ref)
60+
"""
61+
struct BlossomVAlgorithm <: AbstractMinimumWeightPerfectMatchingAlgorithm end
62+
63+
function minimum_weight_perfect_matching(
64+
g::Graph, w::Dict{E,U}
65+
) where {U<:Integer,E<:Edge}
66+
return minimum_weight_perfect_matching(g, w, BlossomVAlgorithm())
67+
end
68+
2369
function minimum_weight_perfect_matching(
24-
g::Graph, w::Dict{E,U}, cutoff, kws...
70+
g::Graph, w::Dict{E,U}, cutoff, algorithm::AbstractMinimumWeightPerfectMatchingAlgorithm=BlossomVAlgorithm(); kws...
2571
) where {U<:Real,E<:Edge}
2672
wnew = Dict{E,U}()
2773
for (e, c) in w
2874
if c <= cutoff
2975
wnew[e] = c
3076
end
3177
end
32-
return minimum_weight_perfect_matching(g, wnew; kws...)
78+
return minimum_weight_perfect_matching(g, wnew, algorithm; kws...)
3379
end
3480

3581
function minimum_weight_perfect_matching(
36-
g::Graph, w::Dict{E,U}; tmaxscale=10.0
82+
g::Graph, w::Dict{E,U}, algorithm::AbstractMinimumWeightPerfectMatchingAlgorithm=BlossomVAlgorithm(); tmaxscale=10.0
3783
) where {U<:AbstractFloat,E<:Edge}
3884
wnew = Dict{E,Int32}()
3985
cmax = maximum(values(w))
@@ -44,7 +90,7 @@ function minimum_weight_perfect_matching(
4490
for (e, c) in w
4591
wnew[e] = round(Int32, (c - cmin) / max(cmax - cmin, 1) * tmax)
4692
end
47-
match = minimum_weight_perfect_matching(g, wnew)
93+
match = minimum_weight_perfect_matching(g, wnew, algorithm)
4894
weight = zero(U)
4995
for i in 1:nv(g)
5096
j = match.mate[i]
@@ -55,7 +101,7 @@ function minimum_weight_perfect_matching(
55101
return MatchingResult(weight, match.mate)
56102
end
57103

58-
function minimum_weight_perfect_matching(g::Graph, w::Dict{E,U}) where {U<:Integer,E<:Edge}
104+
function minimum_weight_perfect_matching(g::Graph, w::Dict{E,U}, ::BlossomVAlgorithm) where {U<:Integer,E<:Edge}
59105
m = BlossomV.Matching(nv(g))
60106
for (e, c) in w
61107
BlossomV.add_edge(m, src(e) - 1, dst(e) - 1, c)

0 commit comments

Comments
 (0)