Skip to content

Commit f9461bc

Browse files
Wikuniamatbesancon
authored andcommitted
JuMP/MOI to new version v0.20/0.9 (#16)
* JuMP/MOI to new version v0.20/0.9 * removed julia 0.7 added 1.2 and changed readme * require julia 1 * Require -> Project.toml * added/removed spaces based on review
1 parent 946a7ff commit f9461bc

File tree

7 files changed

+55
-52
lines changed

7 files changed

+55
-52
lines changed

Project.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@ Hungarian = "e91730f6-4275-51fb-a7a0-7064cfbd3b39"
99
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
1010
LightGraphs = "093fc24a-ae57-5d10-9952-331d41423f4d"
1111
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
12-
MathProgBase = "fdba3010-5040-5b88-9595-932c9decdf73"
12+
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
1313
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
1414

1515
[compat]
1616
BlossomV = "0.4"
1717
Hungarian = "0.4"
18-
JuMP = "0.18"
18+
JuMP = "0.20"
1919
LightGraphs = "1.2"
20+
MathOptInterface = "0.9"
2021
julia = "1"
2122

2223
[extras]

README.md

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ containing the `mate` and `weight` fields.
1616
### Perfect matching
1717

1818
```julia
19-
g =CompleteGraph(4)
20-
w =Dict{Edge,Float64}()
19+
g = complete_graph(4)
20+
w = Dict{Edge,Float64}()
2121
w[Edge(1,3)] = 10
2222
w[Edge(1,4)] = 0.5
2323
w[Edge(2,3)] = 11
@@ -36,17 +36,15 @@ match = minimum_weight_perfect_matching(g, w, 50)
3636
### Maximum weight matching
3737

3838
A maximum weight matching is solved as a Linear Programming
39-
problem and requires a LP solver respecting the [MathProgBase](https://github.com/JuliaOpt/MathProgBase.jl) solver
40-
interface. See MathProgBase
41-
[documentation](http://mathprogbasejl.readthedocs.io/en/latest/solvers.html) for more details.
39+
problem and requires an LP optimizer for bipartite graphs and a MILP solver for general graphs respecting the [MathOptInterface](https://github.com/JuliaOpt/MathOptInterface.jl) optimizer interface. A list of solvers can be found in the [JuMP documentation](http://www.juliaopt.org/JuMP.jl/v0.19.0/installation/#Getting-Solvers-1).
4240

4341
```julia
44-
using Cbc: CbcSolver #import a LP solver
45-
g = CompleteGraph(3)
42+
using JuMP, Cbc #import a MILP solver
43+
g = complete_graph(3)
4644
w = zeros(3,3)
4745
w[1,2] = 1
4846
w[3,2] = 1
4947
w[1,3] = 1
50-
match = maximum_weight_matching(g,CbcSolver(),w)
48+
match = maximum_weight_matching(g,with_optimizer(Cbc.Optimizer, logLevel=0),w)
5149
# match.weight ≈ 1
5250
```

src/LightGraphsMatching.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ using LightGraphs
55
using SparseArrays: spzeros
66

77
using JuMP
8-
using MathProgBase: AbstractMathProgSolver
8+
using MathOptInterface
9+
const MOI = MathOptInterface
910
import BlossomV # 'using BlossomV' leads to naming conflicts with JuMP
1011
using Hungarian
1112

src/lp.jl

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
function maximum_weight_maximal_matching_lp(g::Graph, solver::AbstractMathProgSolver, w::AbstractMatrix{T}, cutoff::R) where {T<:Real, R<:Real}
1+
function maximum_weight_maximal_matching_lp(g::Graph, solver::JuMP.OptimizerFactory, w::AbstractMatrix{T}, cutoff::R) where {T<:Real, R<:Real}
22
return maximum_weight_maximal_matching_lp(g, solver, cutoff_weights(w, cutoff))
33
end
44

5-
function maximum_weight_maximal_matching_lp(g::Graph, solver::AbstractMathProgSolver, w::AbstractMatrix{T}) where {T<:Real}
5+
function maximum_weight_maximal_matching_lp(g::Graph, solver::JuMP.OptimizerFactory, w::AbstractMatrix{T}) where {T<:Real}
66
# TODO support for graphs with zero degree nodes
77
# TODO apply separately on each connected component
88
bpmap = bipartite_map(g)
@@ -26,7 +26,7 @@ function maximum_weight_maximal_matching_lp(g::Graph, solver::AbstractMathProgSo
2626
end
2727
end
2828

29-
model = Model(solver=solver)
29+
model = Model(solver)
3030
@variable(model, x[1:length(w)] >= 0)
3131

3232
for i in v1
@@ -56,13 +56,14 @@ function maximum_weight_maximal_matching_lp(g::Graph, solver::AbstractMathProgSo
5656

5757
@objective(model, Max, sum(w[src(e),dst(e)] * x[edgemap[e]] for e in keys(edgemap)))
5858

59-
status = solve(model)
60-
status != :Optimal && error("JuMP solver failed to find optimal solution.")
61-
sol = getvalue(x)
59+
optimize!(model)
60+
status = JuMP.termination_status(model)
61+
status != MOI.OPTIMAL && error("JuMP solver failed to find optimal solution.")
62+
sol = JuMP.value.(x)
6263

6364
all(Bool[s == 1 || s == 0 for s in sol]) || error("Found non-integer solution.")
6465

65-
cost = getobjectivevalue(model)
66+
cost = JuMP.objective_value(model)
6667

6768
mate = fill(-1, nv(g))
6869
for e in edges(g)

src/maximum_weight_matching.jl

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ Returns MatchingResult containing:
2222
function maximum_weight_matching end
2323

2424
function maximum_weight_matching(g::Graph,
25-
solver::AbstractMathProgSolver,
25+
solver::JuMP.OptimizerFactory,
2626
w::AbstractMatrix{U} = default_weights(g)) where {U <:Real}
2727

28-
model = Model(solver = solver)
28+
model = Model(with_optimizer(solver))
2929
n = nv(g)
3030
edge_list = collect(edges(g))
3131

@@ -49,15 +49,16 @@ function maximum_weight_matching(g::Graph,
4949
@objective(model, Max, sum(x[e]*w[src(e),dst(e)] for e in edge_list))
5050

5151
@constraint(model, c1[i=1:n], sum(x[Edge(minmax(i,j))] for j in neighbors(g,i)) <= 1)
52-
status = solve(model)
53-
solution = getvalue(x)
54-
cost = getobjectivevalue(model)
55-
## TODO: add the option of returning the solve status as part of the MatchingResult type.
52+
optimize!(model)
53+
status = JuMP.termination_status(model)
54+
status != MOI.OPTIMAL && error("JuMP solver failed to find optimal solution.")
55+
solution = value.(x)
56+
cost = objective_value(model)
5657
return MatchingResult(cost, dict_to_arr(n, solution, edge_list))
5758
end
5859

5960
""" Returns an array of mates from a dictionary that maps edges to {0,1} """
60-
function dict_to_arr(n::Int64, solution::JuMP.JuMPArray{U,1,Tuple{Array{E,1}}}, edge_list::AbstractVector{E}) where {U<: Real, E<: Edge}
61+
function dict_to_arr(n::Int64, solution::JuMP.Containers.DenseAxisArray{U,1,Tuple{Array{E,1}}}, edge_list::AbstractVector{E}) where {U<: Real, E<: Edge}
6162
mate = fill(-1,n)
6263
for e in edge_list
6364
if solution[e] >= 1 - 1e-5 # Some tolerance to numerical approximations by the solver.

src/maximum_weight_maximal_matching.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ function maximum_weight_maximal_matching(
1616
algorithm::LPAlgorithm,
1717
solver = nothing
1818
) where {T<:Real}
19-
if ! isa(solver, AbstractMathProgSolver)
20-
error("The keyword argument solver must be an AbstractMathProgSolver, as accepted by JuMP.")
19+
if ! isa(solver, JuMP.OptimizerFactory)
20+
error("The keyword argument solver must be an JuMP.OptimizerFactory, as accepted by JuMP.")
2121
end
2222

2323
return maximum_weight_maximal_matching_lp(g, solver, w)
@@ -96,4 +96,4 @@ function cutoff_weights(w::AbstractMatrix{T}, cutoff::R) where {T<:Real, R<:Real
9696
wnew
9797
end
9898

99-
@deprecate maximum_weight_maximal_matching(g::Graph, solver::AbstractMathProgSolver, w::AbstractMatrix{T}, cutoff::R) where {T<:Real, R<:Real} maximum_weight_maximal_matching(g, w, algorithm=LPAlgorithm(), cutoff=cutoff, solver=solver)
99+
@deprecate maximum_weight_maximal_matching(g::Graph, solver::JuMP.OptimizerFactory, w::AbstractMatrix{T}, cutoff::R) where {T<:Real, R<:Real} maximum_weight_maximal_matching(g, w, algorithm=LPAlgorithm(), cutoff=cutoff, solver=solver)

test/runtests.jl

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,29 @@
11
using LightGraphs
22
using LightGraphsMatching
33
using Test
4-
using Cbc: CbcSolver
4+
using Cbc
5+
using JuMP
56
using LinearAlgebra: I
67

78
@testset "LightGraphsMatching" begin
89

910
@testset "maximum_weight_matching" begin
10-
g = CompleteGraph(3)
11+
g = complete_graph(3)
1112
w = [
1213
1 2 1
1314
1 1 1
1415
3 1 1
1516
]
16-
match = maximum_weight_matching(g, CbcSolver(), w)
17+
match = maximum_weight_matching(g, with_optimizer(Cbc.Optimizer, logLevel=0), w)
1718
@test match.mate[1] == 3
1819
@test match.weight 3
1920

20-
g = CompleteGraph(3)
21+
g = complete_graph(3)
2122
w = zeros(3,3)
2223
w[1,2] = 1
2324
w[3,2] = 1
2425
w[1,3] = 1
25-
match = maximum_weight_matching(g,CbcSolver(),w)
26+
match = maximum_weight_matching(g,with_optimizer(Cbc.Optimizer, logLevel=0),w)
2627
@test match.weight 1
2728

2829

@@ -36,7 +37,7 @@ using LinearAlgebra: I
3637
w[1,4] = 3
3738
w[2,4] = 1
3839

39-
match = maximum_weight_matching(g,CbcSolver(),w)
40+
match = maximum_weight_matching(g,with_optimizer(Cbc.Optimizer, logLevel=0),w)
4041
@test match.weight 3
4142
@test match.mate[1] == 4
4243
@test match.mate[2] == -1
@@ -48,7 +49,7 @@ using LinearAlgebra: I
4849
add_edge!(g, 2,3)
4950
add_edge!(g, 3,1)
5051
add_edge!(g, 3,4)
51-
match = maximum_weight_matching(g,CbcSolver())
52+
match = maximum_weight_matching(g,with_optimizer(Cbc.Optimizer, logLevel=0))
5253
@test match.weight 2
5354
@test match.mate[1] == 2
5455
@test match.mate[2] == 1
@@ -61,7 +62,7 @@ using LinearAlgebra: I
6162
w[1,3] = 1
6263
w[3,4] = 1
6364

64-
match = maximum_weight_matching(g,CbcSolver(), w)
65+
match = maximum_weight_matching(g,with_optimizer(Cbc.Optimizer, logLevel=0), w)
6566
@test match.weight 2
6667
@test match.mate[1] == 2
6768
@test match.mate[2] == 1
@@ -74,7 +75,7 @@ using LinearAlgebra: I
7475
w[1,3] = 5
7576
w[3,4] = 1
7677

77-
match = maximum_weight_matching(g,CbcSolver(),w)
78+
match = maximum_weight_matching(g,with_optimizer(Cbc.Optimizer, logLevel=0),w)
7879
@test match.weight 5
7980
@test match.mate[1] == 3
8081
@test match.mate[2] == -1
@@ -85,56 +86,56 @@ end
8586

8687
@testset "maximum_weight_maximal_matching" begin
8788

88-
g = CompleteBipartiteGraph(2,2)
89+
g = complete_bipartite_graph(2,2)
8990
w = zeros(4,4)
9091
w[1,3] = 10.
9192
w[1,4] = 1.
9293
w[2,3] = 2.
9394
w[2,4] = 11.
94-
match = maximum_weight_maximal_matching(g, w, algorithm=LPAlgorithm(), solver=CbcSolver())
95+
match = maximum_weight_maximal_matching(g, w, algorithm=LPAlgorithm(), solver=with_optimizer(Cbc.Optimizer, logLevel=0))
9596
@test match.weight 21
9697
@test match.mate[1] == 3
9798
@test match.mate[3] == 1
9899
@test match.mate[2] == 4
99100
@test match.mate[4] == 2
100101

101-
g =CompleteBipartiteGraph(2,4)
102+
g =complete_bipartite_graph(2,4)
102103
w =zeros(6,6)
103104
w[1,3] = 10
104105
w[1,4] = 0.5
105106
w[2,3] = 11
106107
w[2,4] = 1
107-
match = maximum_weight_maximal_matching(g, w, algorithm=LPAlgorithm(), solver=CbcSolver())
108+
match = maximum_weight_maximal_matching(g, w, algorithm=LPAlgorithm(), solver=with_optimizer(Cbc.Optimizer, logLevel=0))
108109
@test match.weight 11.5
109110
@test match.mate[1] == 4
110111
@test match.mate[4] == 1
111112
@test match.mate[2] == 3
112113
@test match.mate[3] == 2
113114

114-
g =CompleteBipartiteGraph(2,6)
115+
g =complete_bipartite_graph(2,6)
115116
w =zeros(8,8)
116117
w[1,3] = 10
117118
w[1,4] = 0.5
118119
w[2,3] = 11
119120
w[2,4] = 1
120121
w[2,5] = -1
121122
w[2,6] = -1
122-
match = maximum_weight_maximal_matching(g, w, algorithm=LPAlgorithm(), solver=CbcSolver(), cutoff=0)
123+
match = maximum_weight_maximal_matching(g, w, algorithm=LPAlgorithm(), solver=with_optimizer(Cbc.Optimizer, logLevel=0), cutoff=0)
123124
@test match.weight 11.5
124125
@test match.mate[1] == 4
125126
@test match.mate[4] == 1
126127
@test match.mate[2] == 3
127128
@test match.mate[3] == 2
128129

129-
g =CompleteBipartiteGraph(4,2)
130+
g =complete_bipartite_graph(4,2)
130131
w = zeros(6,6)
131132
w[3,5] = 10
132133
w[3,6] = 0.5
133134
w[2,5] = 11
134135
w[1,6] = 1
135136
w[1,5] = -1
136137

137-
match = maximum_weight_maximal_matching(g, w, algorithm=LPAlgorithm(), solver=CbcSolver(), cutoff=0)
138+
match = maximum_weight_maximal_matching(g, w, algorithm=LPAlgorithm(), solver=with_optimizer(Cbc.Optimizer, logLevel=0), cutoff=0)
138139
@test match.weight 12
139140
@test match.mate[1] == 6
140141
@test match.mate[2] == 5
@@ -144,7 +145,7 @@ end
144145
@test match.mate[6] == 1
145146

146147

147-
g = CompleteBipartiteGraph(2, 2)
148+
g = complete_bipartite_graph(2, 2)
148149
w = zeros(4, 4)
149150
w[1, 3] = 10.
150151
w[1, 4] = 1.
@@ -157,12 +158,12 @@ end
157158
@test match.mate[2] == 4
158159
@test match.mate[4] == 2
159160

160-
g = CompleteGraph(3)
161+
g = complete_graph(3)
161162
w = zeros(3, 3)
162163
@test ! is_bipartite(g)
163164
@test_throws ErrorException maximum_weight_maximal_matching(g, w, algorithm=HungarianAlgorithm())
164165

165-
g = CompleteBipartiteGraph(2, 4)
166+
g = complete_bipartite_graph(2, 4)
166167
w = zeros(6, 6)
167168
w[1, 3] = 10
168169
w[1, 4] = 0.5
@@ -201,7 +202,7 @@ end
201202
Edge(3,4)=>100,
202203
Edge(2,4)=>1000)
203204

204-
g = CompleteGraph(4)
205+
g = complete_graph(4)
205206
match = minimum_weight_perfect_matching(g, w)
206207
@test match.mate[1] == 2
207208
@test match.mate[2] == 1
@@ -216,15 +217,15 @@ end
216217
Edge(3, 4) => 1000,
217218
Edge(2, 4) => 1000
218219
)
219-
g = CompleteGraph(4)
220+
g = complete_graph(4)
220221
match = minimum_weight_perfect_matching(g, w)
221222
@test match.mate[1] == 3
222223
@test match.mate[2] == 4
223224
@test match.mate[3] == 1
224225
@test match.mate[4] == 2
225226
@test match.weight 1400
226227

227-
g =CompleteBipartiteGraph(2,2)
228+
g =complete_bipartite_graph(2,2)
228229
w =Dict{Edge,Float64}()
229230
w[Edge(1,3)] = -10
230231
w[Edge(1,4)] = -0.5
@@ -239,7 +240,7 @@ end
239240
@test match.weight -11.5
240241

241242

242-
g = CompleteGraph(4)
243+
g = complete_graph(4)
243244
w = Dict{Edge,Float64}()
244245
w[Edge(1,3)] = 10
245246
w[Edge(1,4)] = 0.5

0 commit comments

Comments
 (0)