Skip to content

Commit 9883489

Browse files
simonschoellymatbesancon
authored andcommitted
Fixes for julia v1.0 (#12)
* fixes for julia v1.0 * updated travis and appveyor scripts * Update REQUIRE Co-Authored-By: simonschoelly <[email protected]> * Update test/REQUIRE Co-Authored-By: simonschoelly <[email protected]> * changed required versions
1 parent 50edcb4 commit 9883489

File tree

9 files changed

+296
-293
lines changed

9 files changed

+296
-293
lines changed

.travis.yml

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
## Documentation: http://docs.travis-ci.com/user/languages/julia/
1+
# Documentation: http://docs.travis-ci.com/user/languages/julia/
22
language: julia
33
os:
44
- linux
5+
- osx
56
julia:
6-
- 0.6
7-
- nightly
7+
- 0.7
8+
- 1.0
9+
- nightly
810

911
matrix:
1012
allow_failures:
@@ -15,12 +17,6 @@ notifications:
1517
git:
1618
depth: 99999999
1719

18-
## uncomment the following lines to allow failures on nightly julia
19-
## (tests will run but not make your overall status red)
20-
#matrix:
21-
# allow_failures:
22-
# - julia: nightly
23-
2420
## uncomment and modify the following lines to manually install system packages
2521
#addons:
2622
# apt: # apt-get for linux

REQUIRE

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
julia 0.6
2-
LightGraphs 0.12
3-
JuMP 0.13
4-
MatrixDepot
5-
BlossomV 0.3
1+
julia 0.7
2+
LightGraphs 1.2
3+
JuMP 0.18
4+
MathProgBase 0.7
5+
BlossomV 0.4

appveyor.yml

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
1-
environment:
2-
matrix:
3-
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe"
4-
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe"
5-
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
6-
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"
1+
platform:
2+
- x86 # 32-bit
3+
- x64 # 64-bit
74

8-
## uncomment the following lines to allow failures on nightly julia
9-
## (tests will run but not make your overall status red)
10-
#matrix:
11-
# allow_failures:
12-
# - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
13-
# - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"
5+
# # Uncomment the following lines to allow failures on nightly julia
6+
# # (tests will run but not make your overall status red)
7+
matrix:
8+
allow_failures:
9+
- julia_version: nightly
1410

1511
branches:
1612
only:
@@ -24,24 +20,19 @@ notifications:
2420
on_build_status_changed: false
2521

2622
install:
27-
- ps: "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12"
28-
# If there's a newer build queued for the same PR, cancel this one
29-
- ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod `
30-
https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | `
31-
Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { `
32-
throw "There are newer queued builds for this pull request, failing early." }
33-
# Download most recent Julia Windows binary
34-
- ps: (new-object net.webclient).DownloadFile(
35-
$env:JULIA_URL,
36-
"C:\projects\julia-binary.exe")
37-
# Run installer silently, output to C:\projects\julia
38-
- C:\projects\julia-binary.exe /S /D=C:\projects\julia
23+
- ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/JuliaCI/Appveyor.jl/version-1/bin/install.ps1"))
3924

4025
build_script:
4126
# Need to convert from shallow to complete for Pkg.clone to work
4227
- IF EXIST .git\shallow (git fetch --unshallow)
43-
- C:\projects\julia\bin\julia -e "versioninfo();
44-
Pkg.clone(pwd(), \"LightGraphsMatching\"); Pkg.build(\"LightGraphsMatching\")"
28+
- C:\julia\bin\julia -e "using InteractiveUtils, Pkg; versioninfo();
29+
Pkg.clone(pwd(), \"LightGraphsMatching\"); Pkg.build(\"LightGraphsMatching\")"
4530

4631
test_script:
47-
- C:\projects\julia\bin\julia -e "Pkg.test(\"LightGraphsMatching\")"
32+
- C:\julia\bin\julia -e "using Pkg; Pkg.test(\"LightGraphsMatching\")"
33+
34+
# # Uncomment to support code coverage upload. Should only be enabled for packages
35+
# # which would have coverage gaps without running on Windows
36+
# on_success:
37+
# - echo "%JL_CODECOV_SCRIPT%"
38+
# - C:\julia\bin\julia -e "%JL_CODECOV_SCRIPT%"

src/LightGraphsMatching.jl

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
1-
__precompile__(true)
21
module LightGraphsMatching
2+
33
using LightGraphs
4+
5+
using SparseArrays: spzeros
6+
7+
using JuMP
8+
using MathProgBase: AbstractMathProgSolver
9+
import BlossomV # 'using BlossomV' leads to naming conflicts with JuMP
10+
411
export MatchingResult, maximum_weight_matching, maximum_weight_maximal_matching, minimum_weight_perfect_matching
512

613
"""
7-
type MatchingResult{T}
8-
weight::T
14+
struct MatchingResult{U}
15+
weight::U
916
mate::Vector{Int}
1017
end
1118
@@ -16,18 +23,14 @@ A type representing the result of a matching algorithm.
1623
mate: `mate[i] = j` if vertex `i` is matched to vertex `j`.
1724
`mate[i] = -1` for unmatched vertices.
1825
"""
19-
struct MatchingResult{T<:Real}
20-
weight::T
26+
struct MatchingResult{U<:Real}
27+
weight::U
2128
mate::Vector{Int}
2229
end
2330

24-
import BlossomV
25-
include("blossomv.jl")
26-
27-
using JuMP
28-
using MathProgBase: AbstractMathProgSolver
2931
include("lp.jl")
3032
include("maximum_weight_matching.jl")
33+
include("blossomv.jl")
3134

3235
end # module
3336

src/blossomv.jl

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""
2-
minimum_weight_perfect_matching{T<:Real}(g, w::Dict{Edge,T})
3-
minimum_weight_perfect_matching{T<:Real}(g, w::Dict{Edge,T}, cutoff)
2+
minimum_weight_perfect_matching(g, w::Dict{Edge,Real})
3+
minimum_weight_perfect_matching(g, w::Dict{Edge,Real}, cutoff)
44
55
Given a graph `g` and an edgemap `w` containing weights associated to edges,
66
returns a matching with the mimimum total weight among the ones containing
@@ -20,8 +20,8 @@ In case of error try to change the optional argument `tmaxscale` (default is `tm
2020
"""
2121
function minimum_weight_perfect_matching end
2222

23-
function minimum_weight_perfect_matching(g::Graph, w::Dict{E,T}, cutoff, kws...) where {T<:Real, E<:Edge}
24-
wnew = Dict{E, T}()
23+
function minimum_weight_perfect_matching(g::Graph, w::Dict{E,U}, cutoff, kws...) where {U<:Real, E<:Edge}
24+
wnew = Dict{E, U}()
2525
for (e, c) in w
2626
if c <= cutoff
2727
wnew[e] = c
@@ -30,17 +30,17 @@ function minimum_weight_perfect_matching(g::Graph, w::Dict{E,T}, cutoff, kws...)
3030
return minimum_weight_perfect_matching(g, wnew; kws...)
3131
end
3232

33-
function minimum_weight_perfect_matching(g::Graph, w::Dict{E,T}; tmaxscale=10.) where {T<:AbstractFloat, E<:Edge}
33+
function minimum_weight_perfect_matching(g::Graph, w::Dict{E,U}; tmaxscale=10.) where {U<:AbstractFloat, E<:Edge}
3434
wnew = Dict{E, Int32}()
3535
cmax = maximum(values(w))
3636
cmin = minimum(values(w))
3737
tmax = typemax(Int32) / tmaxscale # /10 is kinda arbitrary,
38-
# hopefully high enough to not incurr in overflow problems
38+
# hopefully high enough to not occur in overflow problems
3939
for (e, c) in w
4040
wnew[e] = round(Int32, (c-cmin) / (cmax-cmin) * tmax)
4141
end
4242
match = minimum_weight_perfect_matching(g, wnew)
43-
weight = T(0)
43+
weight = zero(U)
4444
for i=1:nv(g)
4545
j = match.mate[i]
4646
if j > i
@@ -50,15 +50,15 @@ function minimum_weight_perfect_matching(g::Graph, w::Dict{E,T}; tmaxscale=10.)
5050
return MatchingResult(weight, match.mate)
5151
end
5252

53-
function minimum_weight_perfect_matching(g::Graph, w::Dict{E,T}) where {T<:Integer, E<:Edge}
53+
function minimum_weight_perfect_matching(g::Graph, w::Dict{E,U}) where {U<:Integer, E<:Edge}
5454
m = BlossomV.Matching(nv(g))
5555
for (e, c) in w
5656
BlossomV.add_edge(m, src(e)-1, dst(e)-1, c)
5757
end
5858
BlossomV.solve(m)
5959

6060
mate = fill(-1, nv(g))
61-
totweight = T(0)
61+
totweight = zero(U)
6262
for i=1:nv(g)
6363
j = BlossomV.get_match(m, i-1) + 1
6464
mate[i] = j <= 0 ? -1 : j

src/lp.jl

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""
2-
maximum_weight_maximal_matching{T<:Real}(g, w::Dict{Edge,T})
3-
maximum_weight_maximal_matching{T<:Real}(g, w::Dict{Edge,T}, cutoff)
2+
maximum_weight_maximal_matching(g, w::Dict{Edge,Real})
3+
maximum_weight_maximal_matching(g, w::Dict{Edge,Real}, cutoff)
44
55
Given a bipartite graph `g` and an edgemap `w` containing weights associated to edges,
66
returns a matching with the maximum total weight among the ones containing the
@@ -20,17 +20,17 @@ The returned object is of type `MatchingResult`.
2020
"""
2121
function maximum_weight_maximal_matching end
2222

23-
function maximum_weight_maximal_matching(g::Graph, solver::AbstractMathProgSolver, w::AbstractMatrix{T}, cutoff::R) where {T<:Real, R<:Real}
23+
function maximum_weight_maximal_matching(g::Graph, solver::AbstractMathProgSolver, w::AbstractMatrix{U}, cutoff::R) where {U<:Real, R<:Real}
2424
return maximum_weight_maximal_matching(g, solver, cutoff_weights(w, cutoff))
2525
end
2626

27-
function maximum_weight_maximal_matching(g::Graph, solver::AbstractMathProgSolver, w::AbstractMatrix{T}) where {T<:Real}
27+
function maximum_weight_maximal_matching(g::Graph, solver::AbstractMathProgSolver, w::AbstractMatrix{U}) where {U<:Real}
2828
# TODO support for graphs with zero degree nodes
2929
# TODO apply separately on each connected component
3030
bpmap = bipartite_map(g)
3131
length(bpmap) != nv(g) && error("Graph is not bipartite")
32-
v1 = findin(bpmap, 1)
33-
v2 = findin(bpmap, 2)
32+
v1 = findall(isequal(1), bpmap)
33+
v2 = findall(isequal(2), bpmap)
3434
if length(v1) > length(v2)
3535
v1, v2 = v2, v1
3636
end
@@ -88,7 +88,7 @@ function maximum_weight_maximal_matching(g::Graph, solver::AbstractMathProgSolve
8888

8989
mate = fill(-1, nv(g))
9090
for e in edges(g)
91-
if w[src(e),dst(e)] > zero(T)
91+
if w[src(e),dst(e)] > zero(U)
9292
inmatch = convert(Bool, sol[edgemap[e]])
9393
if inmatch
9494
mate[src(e)] = dst(e)
@@ -103,14 +103,14 @@ end
103103
"""
104104
cutoff_weights copies the weight matrix with all elements below cutoff set to 0
105105
"""
106-
function cutoff_weights(w::AbstractMatrix{T}, cutoff::R) where {T<:Real, R<:Real}
106+
function cutoff_weights(w::AbstractMatrix{U}, cutoff::R) where {U<:Real, R<:Real}
107107
wnew = copy(w)
108108
for j in 1:size(w,2)
109109
for i in 1:size(w,1)
110110
if wnew[i,j] < cutoff
111-
wnew[i,j] = zero(T)
111+
wnew[i,j] = zero(U)
112112
end
113113
end
114114
end
115115
wnew
116-
end
116+
end

src/maximum_weight_matching.jl

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
maximum_weight_matching{T <:Real}(g::Graph, w::Dict{Edge,T} = Dict{Edge,Int64}())
2+
maximum_weight_matching(g::Graph, w::Dict{Edge,Real} -> Dict{Edge,Int64}
33
44
Given a graph `g` and an edgemap `w` containing weights associated to edges,
55
returns a matching with the maximum total weight.
@@ -23,7 +23,7 @@ function maximum_weight_matching end
2323

2424
function maximum_weight_matching(g::Graph,
2525
solver::AbstractMathProgSolver,
26-
w::AbstractMatrix{T} = default_weights(g)) where {T <:Real}
26+
w::AbstractMatrix{U} = default_weights(g)) where {U <:Real}
2727

2828
model = Model(solver = solver)
2929
n = nv(g)
@@ -32,11 +32,11 @@ function maximum_weight_matching(g::Graph,
3232
# put the edge weights in w in the right order to be compatible with edge_list
3333
for j in 1:n
3434
for i in 1:n
35-
if i > j && w[i,j] > zero(T) && w[j,i] < w[i,j]
35+
if i > j && w[i,j] > zero(U) && w[j,i] < w[i,j]
3636
w[j,i] = w[i,j]
3737
end
3838
if Edge(i,j) edge_list
39-
w[i,j] = zero(T)
39+
w[i,j] = zero(U)
4040
end
4141
end
4242
end
@@ -47,26 +47,22 @@ function maximum_weight_matching(g::Graph,
4747
@variable(model, x[edge_list] >= 0, Int) # requires MIP solver
4848
end
4949
@objective(model, Max, sum(x[e]*w[src(e),dst(e)] for e in edge_list))
50-
@constraint(model, c1[i=1:n],
51-
sum(x[Edge(i,j)] for j=filter(l -> l > i, neighbors(g,i))) +
52-
sum(x[Edge(j,i)] for j=filter(l -> l <= i, neighbors(g,i)))
53-
<= 1)
5450

51+
@constraint(model, c1[i=1:n], sum(x[Edge(minmax(i,j))] for j in neighbors(g,i)) <= 1)
5552
status = solve(model)
5653
solution = getvalue(x)
5754
cost = getobjectivevalue(model)
5855
## TODO: add the option of returning the solve status as part of the MatchingResult type.
59-
return MatchingResult(cost, dict_to_arr(n, solution))
56+
return MatchingResult(cost, dict_to_arr(n, solution, edge_list))
6057
end
6158

6259
""" Returns an array of mates from a dictionary that maps edges to {0,1} """
63-
function dict_to_arr(n::Int64, solution::JuMP.JuMPArray{T,1,Tuple{Array{E,1}}}) where {T<: Real, E<: Edge}
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}
6461
mate = fill(-1,n)
65-
for i in keys(solution)
66-
key = i[1] # i is a tuple with 1 element.
67-
if solution[key] >= 1 - 1e-5 # Some tolerance to numerical approximations by the solver.
68-
mate[src(key)] = dst(key)
69-
mate[dst(key)] = src(key)
62+
for e in edge_list
63+
if solution[e] >= 1 - 1e-5 # Some tolerance to numerical approximations by the solver.
64+
mate[src(e)] = dst(e)
65+
mate[dst(e)] = src(e)
7066
end
7167
end
7268
return mate
@@ -79,4 +75,4 @@ function default_weights(g::G) where {G<:AbstractGraph}
7975
m[src(e),dst(e)] = 1
8076
end
8177
return m
82-
end
78+
end

test/REQUIRE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Cbc
1+
Cbc 0.4

0 commit comments

Comments
 (0)