Skip to content

Commit ab2056a

Browse files
Use GenericGraph for testing cycles algorithms (#274)
1 parent 2760c27 commit ab2056a

File tree

8 files changed

+37
-23
lines changed

8 files changed

+37
-23
lines changed

src/cycles/basis.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ julia> cycle_basis(g)
2929
### References
3030
* Paton, K. An algorithm for finding a fundamental set of cycles of a graph. Comm. ACM 12, 9 (Sept 1969), 514-518. [https://dl.acm.org/citation.cfm?id=363232]
3131
"""
32-
function cycle_basis(g::AbstractSimpleGraph, root=nothing)
32+
function cycle_basis(g::AbstractGraph, root=nothing)
3333
T = eltype(g)
3434
cycles = Vector{Vector{T}}()
3535

src/cycles/johnson.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# TODO most functions here do not work for general abstract graphs yet
2+
# as most of them relay on induced_subgraph, which expects the graph type
3+
# to be modifiable.
4+
15
abstract type Visitor{T<:Integer} end
26

37
"""

test/cycles/basis.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
# No Edges
99
ex = Graph(1)
1010
expected_cyclebasis = Array{Int64,1}[]
11-
@testset "no edges" for g in testgraphs(ex)
11+
@testset "no edges" for g in test_generic_graphs(ex)
1212
ex_cyclebasis = @inferred cycle_basis(g)
1313
@test isempty(ex_cyclebasis)
1414
end
@@ -17,7 +17,7 @@
1717
elist = [(1, 1)]
1818
ex = Graph(SimpleEdge.(elist))
1919
expected_cyclebasis = Array{Int64,1}[[1]]
20-
@testset "one self-edge" for g in testgraphs(ex)
20+
@testset "one self-edge" for g in test_generic_graphs(ex)
2121
ex_cyclebasis = cycle_basis(g)
2222
evaluate(ex_cyclebasis, expected_cyclebasis)
2323
end
@@ -26,7 +26,7 @@
2626
elist = [(1, 2), (2, 3), (3, 4), (4, 1), (1, 5)]
2727
ex = Graph(SimpleEdge.(elist))
2828
expected_cyclebasis = Array{Int64,1}[[1, 2, 3, 4]]
29-
@testset "one cycle" for g in testgraphs(ex)
29+
@testset "one cycle" for g in test_generic_graphs(ex)
3030
ex_cyclebasis = cycle_basis(g)
3131
evaluate(ex_cyclebasis, expected_cyclebasis)
3232
end
@@ -35,7 +35,7 @@
3535
elist = [(1, 2), (1, 3), (2, 3), (2, 4), (3, 4)]
3636
ex = Graph(SimpleEdge.(elist))
3737
expected_cyclebasis = Array{Int64,1}[[2, 3, 4], [2, 1, 3]]
38-
@testset "2 of 3 cycles w/ basis" for g in testgraphs(ex)
38+
@testset "2 of 3 cycles w/ basis" for g in test_generic_graphs(ex)
3939
ex_cyclebasis = cycle_basis(g)
4040
evaluate(ex_cyclebasis, expected_cyclebasis)
4141
end
@@ -44,15 +44,15 @@
4444
elist = [(1, 2), (1, 3), (2, 3), (2, 4), (3, 4), (1, 5), (5, 6), (6, 4)]
4545
ex = Graph(SimpleEdge.(elist))
4646
expected_cyclebasis = Array{Int64,1}[[2, 4, 3], [1, 5, 6, 4, 3], [1, 2, 3]]
47-
@testset "root argument" for g in testgraphs(ex)
47+
@testset "root argument" for g in test_generic_graphs(ex)
4848
ex_cyclebasis = @inferred cycle_basis(g, 3)
4949
evaluate(ex_cyclebasis, expected_cyclebasis)
5050
end
5151

5252
@testset "two isolated cycles" begin
5353
ex = blockdiag(cycle_graph(3), cycle_graph(4))
5454
expected_cyclebasis = [[1, 2, 3], [4, 5, 6, 7]]
55-
for g in testgraphs(ex)
55+
for g in test_generic_graphs(ex)
5656
found_cyclebasis = @inferred cycle_basis(g)
5757
evaluate(expected_cyclebasis, found_cyclebasis)
5858
end

test/cycles/hawick-james.jl

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
@testset "subset" for g in testgraphs(ex1)
1313
expected_circuits = Vector{Int}[[2, 3, 4, 5], [2, 3, 5]]
14-
ex1_circuits = simplecycles_hawick_james(g)
14+
ex1_circuits = simplecycles_hawick_james(GenericDiGraph(g))
1515

1616
@test issubset(expected_circuits, ex1_circuits)
1717
@test issubset(ex1_circuits, expected_circuits)
@@ -20,22 +20,22 @@
2020
add_edge!(g, 1, 1)
2121
add_edge!(g, 3, 3)
2222

23-
ex1_circuits_self = simplecycles_hawick_james(g)
23+
ex1_circuits_self = simplecycles_hawick_james(GenericDiGraph(g))
2424

2525
@test issubset(expected_circuits, ex1_circuits_self)
2626
@test [1] ex1_circuits_self && [3] ex1_circuits_self
2727
end
2828

2929
# Path DiGraph
3030
ex2_size = 10
31-
ex2 = testgraphs(path_digraph(ex2_size))
31+
ex2 = test_generic_graphs(path_digraph(ex2_size))
3232
@testset "empty" for g in ex2
3333
@test isempty(simplecycles_hawick_james(g))
3434
end
3535

3636
# Complete DiGraph
3737
ex3_size = 5
38-
ex3 = testgraphs(complete_digraph(ex3_size))
38+
ex3 = test_generic_graphs(complete_digraph(ex3_size))
3939
@testset "length" for g in ex3
4040
ex3_circuits = simplecycles_hawick_james(g)
4141
@test length(ex3_circuits) == length(unique(ex3_circuits))
@@ -62,7 +62,7 @@
6262
add_edge!(ex4, src, dest)
6363
add_edge!(ex4, dest, src)
6464
end
65-
@testset "membership" for g in testgraphs(ex4)
65+
@testset "membership" for g in test_generic_graphs(ex4)
6666
ex4_output = simplecycles_hawick_james(g)
6767
@test [1, 2] ex4_output && [8, 9] ex4_output
6868
end
@@ -72,8 +72,9 @@
7272
(n, k) in [(14, 18), (10, 22), (7, 16)]
7373

7474
g = erdos_renyi(n, k; is_directed=true, rng=StableRNG(seed))
75+
# TODO simplecycles(g) does not yet work with GenericDiGraph
7576
cycles1 = simplecycles(g)
76-
cycles2 = simplecycles_hawick_james(g)
77+
cycles2 = simplecycles_hawick_james(GenericDiGraph(g))
7778
foreach(sort!, cycles1)
7879
foreach(sort!, cycles2)
7980
sort!(cycles1)

test/cycles/incremental.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# The test here cannot be done with GenericDiGraph, as the functions under test
2+
# modify the graph. We probably need another generic graph type with more relaxed
3+
# constraints for modifying graphs.
4+
15
@testset "ICT" begin
26
Gempty = SimpleDiGraph(3)
37
Gsomedges = SimpleDiGraph(6)

test/cycles/johnson.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# TODO we cannot run the test here with GenericGraph yet,
2+
# as the functions don't work for arbitrary graphs yet.
3+
14
@testset "Cycles" begin
25
rng = StableRNG(1)
36
completedg = complete_digraph(4)

test/cycles/karp.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
add_edge!(g1, 11, 7)
4747
add_edge!(g1, 12, 9)
4848

49-
@testset "simple digraphs" for g in testgraphs(g1)
49+
@testset "simple digraphs" for g in test_generic_graphs(g1)
5050
c, λ = karp_minimum_cycle_mean(g, w)
5151
@test c == [9, 11, 7]
5252
@test λ == 0.9
@@ -78,7 +78,7 @@
7878
1.0 Inf 0.0 Inf
7979
]
8080

81-
@testset "tricky case" for g in testgraphs(tricky)
81+
@testset "tricky case" for g in test_generic_graphs(tricky)
8282
c, λ = karp_minimum_cycle_mean(g, distmx)
8383
@test λ == 0.0
8484
@test sort(c) == [3, 4]
@@ -97,7 +97,7 @@
9797
Inf -1
9898
]
9999

100-
@testset "multiple SCCs" for g in testgraphs(multi)
100+
@testset "multiple SCCs" for g in test_generic_graphs(multi)
101101
c, λ = karp_minimum_cycle_mean(g, distmx)
102102
@test λ == -1.0
103103
@test c == [2]

test/cycles/limited_length.jl

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
pathdg = path_digraph(5)
44
cycledg = cycle_digraph(5)
55

6-
@testset "complete digraph" for g in testgraphs(completedg)
6+
@testset "complete digraph" for g in test_generic_graphs(completedg)
77
@test length(simplecycles_limited_length(g, 0)) == 0
88
@test length(simplecycles_limited_length(g, 1)) == 0
99
@test length(simplecycles_limited_length(g, 2)) == 6
@@ -13,15 +13,15 @@
1313
@test length(simplecycles_limited_length(g, 4, typemax(Int))) == 20
1414
end
1515

16-
@testset "path digraph" for g in testgraphs(pathdg)
16+
@testset "path digraph" for g in test_generic_graphs(pathdg)
1717
@test length(simplecycles_limited_length(g, 1)) == 0
1818
@test length(simplecycles_limited_length(g, 2)) == 0
1919
@test length(simplecycles_limited_length(g, 3)) == 0
2020
@test length(simplecycles_limited_length(g, 4)) == 0
2121
@test length(simplecycles_limited_length(g, 5)) == 0
2222
end
2323

24-
@testset "cycle digraph" for g in testgraphs(cycledg)
24+
@testset "cycle digraph" for g in test_generic_graphs(cycledg)
2525
@test length(simplecycles_limited_length(g, 1)) == 0
2626
@test length(simplecycles_limited_length(g, 2)) == 0
2727
@test length(simplecycles_limited_length(g, 3)) == 0
@@ -30,12 +30,12 @@
3030
end
3131

3232
@testset "self loops" begin
33-
selfloopg = DiGraph([
33+
selfloopg = GenericDiGraph(DiGraph([
3434
0 1 0 0
3535
0 0 1 0
3636
1 0 1 0
3737
0 0 0 1
38-
])
38+
]))
3939
cycles = simplecycles_limited_length(selfloopg, nv(selfloopg))
4040
@test [3] in cycles
4141
@test [4] in cycles
@@ -46,10 +46,12 @@
4646
@testset "octahedral graph" begin
4747
octag = smallgraph(:octahedral)
4848
octadg = DiGraph(octag)
49+
# TODO simplecycleslength does currently not yet work with GenericDiGraph.
50+
# This is probably because it uses induced_subgraph which fails on that graph type.
4951
octalengths, _ = simplecycleslength(octadg)
5052
for k in 1:6
51-
@test sum(octalengths[1:k]) == length(simplecycles_limited_length(octag, k))
52-
@test sum(octalengths[1:k]) == length(simplecycles_limited_length(octadg, k))
53+
@test sum(octalengths[1:k]) == length(simplecycles_limited_length(GenericGraph(octag), k))
54+
@test sum(octalengths[1:k]) == length(simplecycles_limited_length(GenericDiGraph(octadg), k))
5355
end
5456
end
5557
end

0 commit comments

Comments
 (0)