Skip to content

Commit 0445886

Browse files
etiennedeggdalle
andauthored
fix merge_vertices (#369)
* fix merge_vertices * fix tests * Apply formatter --------- Co-authored-by: Guillaume Dalle <[email protected]>
1 parent 94b84be commit 0445886

File tree

2 files changed

+89
-76
lines changed

2 files changed

+89
-76
lines changed

src/operators.jl

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# as they require cloning and modifying graphs.
33

44
"""
5-
complement(g)
5+
complement(g)
66
77
Return the [graph complement](https://en.wikipedia.org/wiki/Complement_graph)
88
of a graph
@@ -58,7 +58,7 @@ function complement(g::DiGraph)
5858
end
5959

6060
"""
61-
reverse(g)
61+
reverse(g)
6262
6363
Return a directed graph where all edges are reversed from the
6464
original directed graph.
@@ -93,7 +93,7 @@ function reverse end
9393
end
9494

9595
"""
96-
reverse!(g)
96+
reverse!(g)
9797
9898
In-place reverse of a directed graph (modifies the original graph).
9999
See [`reverse`](@ref) for a non-modifying version.
@@ -105,7 +105,7 @@ function reverse! end
105105
end
106106

107107
"""
108-
blockdiag(g, h)
108+
blockdiag(g, h)
109109
110110
Return a graph with ``|V(g)| + |V(h)|`` vertices and ``|E(g)| + |E(h)|``
111111
edges where the vertices and edges from graph `h` are appended to graph `g`.
@@ -150,7 +150,7 @@ function blockdiag(g::T, h::T) where {T<:AbstractGraph}
150150
end
151151

152152
"""
153-
intersect(g, h)
153+
intersect(g, h)
154154
155155
Return a graph with edges that are only in both graph `g` and graph `h`.
156156
@@ -184,7 +184,7 @@ function intersect(g::T, h::T) where {T<:AbstractGraph}
184184
end
185185

186186
"""
187-
difference(g, h)
187+
difference(g, h)
188188
189189
Return a graph with edges in graph `g` that are not in graph `h`.
190190
@@ -218,7 +218,7 @@ function difference(g::T, h::T) where {T<:AbstractGraph}
218218
end
219219

220220
"""
221-
symmetric_difference(g, h)
221+
symmetric_difference(g, h)
222222
223223
Return a graph with edges from graph `g` that do not exist in graph `h`,
224224
and vice versa.
@@ -264,7 +264,7 @@ function symmetric_difference(g::T, h::T) where {T<:AbstractGraph}
264264
end
265265

266266
"""
267-
union(g, h)
267+
union(g, h)
268268
269269
Return a graph that combines graphs `g` and `h` by taking the set union
270270
of all vertices and edges.
@@ -319,7 +319,7 @@ function union(g::T, h::T) where {T<:AbstractSimpleGraph}
319319
end
320320

321321
"""
322-
join(g, h)
322+
join(g, h)
323323
324324
Return a graph that combines graphs `g` and `h` using `blockdiag` and then
325325
adds all the edges between the vertices in `g` and those in `h`.
@@ -359,7 +359,7 @@ function join(g::T, h::T) where {T<:AbstractGraph}
359359
end
360360

361361
"""
362-
crosspath(len::Integer, g::Graph)
362+
crosspath(len::Integer, g::Graph)
363363
364364
Return a graph that duplicates `g` `len` times and connects each vertex
365365
with its copies in a path.
@@ -420,7 +420,7 @@ function *(g::AbstractGraph, v::Vector{T}) where {T<:Real}
420420
end
421421

422422
"""
423-
sum(g, i)
423+
sum(g, i)
424424
425425
Return a vector of indegree (`i`=1) or outdegree (`i`=2) values for graph `g`.
426426
@@ -455,7 +455,7 @@ end
455455

456456
size(g::AbstractGraph) = (nv(g), nv(g))
457457
"""
458-
size(g, i)
458+
size(g, i)
459459
460460
Return the number of vertices in `g` if `i`=1 or `i`=2, or `1` otherwise.
461461
@@ -478,7 +478,7 @@ julia> size(g, 3)
478478
size(g::AbstractGraph, dim::Int) = (dim == 1 || dim == 2) ? nv(g) : 1
479479

480480
"""
481-
sum(g)
481+
sum(g)
482482
483483
Return the number of edges in `g`.
484484
@@ -495,7 +495,7 @@ julia> sum(g)
495495
sum(g::AbstractGraph) = ne(g)
496496

497497
"""
498-
sparse(g)
498+
sparse(g)
499499
500500
Return the default adjacency matrix of `g`.
501501
"""
@@ -518,7 +518,7 @@ end
518518
end
519519

520520
"""
521-
cartesian_product(g, h)
521+
cartesian_product(g, h)
522522
523523
Return the [cartesian product](https://en.wikipedia.org/wiki/Cartesian_product_of_graphs)
524524
of `g` and `h`.
@@ -570,7 +570,7 @@ function cartesian_product(g::G, h::G) where {G<:AbstractGraph}
570570
end
571571

572572
"""
573-
tensor_product(g, h)
573+
tensor_product(g, h)
574574
575575
Return the [tensor product](https://en.wikipedia.org/wiki/Tensor_product_of_graphs)
576576
of `g` and `h`.
@@ -618,8 +618,8 @@ end
618618
## subgraphs ###
619619

620620
"""
621-
induced_subgraph(g, vlist)
622-
induced_subgraph(g, elist)
621+
induced_subgraph(g, vlist)
622+
induced_subgraph(g, elist)
623623
624624
Return the subgraph of `g` induced by the vertices in `vlist` or edges in `elist`
625625
along with a vector mapping the new vertices to the old ones
@@ -706,15 +706,15 @@ function induced_subgraph(
706706
end
707707

708708
"""
709-
g[iter]
709+
g[iter]
710710
711711
Return the subgraph induced by `iter`.
712712
Equivalent to [`induced_subgraph`](@ref)`(g, iter)[1]`.
713713
"""
714714
getindex(g::AbstractGraph, iter) = induced_subgraph(g, iter)[1]
715715

716716
"""
717-
egonet(g, v, d, distmx=weights(g))
717+
egonet(g, v, d, distmx=weights(g))
718718
719719
Return the subgraph of `g` induced by the neighbors of `v` up to distance
720720
`d`, using weights (optionally) provided by `distmx`.
@@ -735,7 +735,7 @@ function egonet(
735735
end
736736

737737
"""
738-
compute_shifts(n::Int, x::AbstractArray)
738+
compute_shifts(n::Int, x::AbstractArray)
739739
740740
Determine how many elements of `x` are less than `i` for all `i` in `1:n`.
741741
"""
@@ -746,7 +746,7 @@ function compute_shifts(n::Integer, x::AbstractArray)
746746
end
747747

748748
"""
749-
merge_vertices(g::AbstractGraph, vs)
749+
merge_vertices(g::AbstractGraph, vs)
750750
751751
Create a new graph where all vertices in `vs` have been aliased to the same vertex `minimum(vs)`.
752752
@@ -772,7 +772,7 @@ julia> collect(edges(h))
772772
Edge 3 => 4
773773
```
774774
"""
775-
function merge_vertices(g::AbstractSimpleGraph, vs)
775+
function merge_vertices(g::G, vs) where {G<:AbstractSimpleGraph}
776776
# Use lowest value as new vertex id.
777777
vs = unique!(sort(vs))
778778
merged_vertex = popfirst!(vs)
@@ -788,7 +788,7 @@ function merge_vertices(g::AbstractSimpleGraph, vs)
788788
new_vertex_ids[vs] .= merged_vertex
789789

790790
# if v in vs then labels[v] == v0 else labels[v] == v
791-
newg = SimpleGraph(nvnew)
791+
newg = G(nvnew)
792792
for e in edges(g)
793793
u, w = src(e), dst(e)
794794
if new_vertex_ids[u] != new_vertex_ids[w] # not a new self loop
@@ -799,7 +799,7 @@ function merge_vertices(g::AbstractSimpleGraph, vs)
799799
end
800800

801801
"""
802-
merge_vertices!(g, vs)
802+
merge_vertices!(g, vs)
803803
804804
Combine vertices specified in `vs` into single vertex whose
805805
index will be the lowest value in `vs`. All edges connected to vertices in `vs`

test/operators.jl

Lines changed: 64 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -56,66 +56,79 @@
5656

5757
@testset "merge vertices" begin
5858
# Check merge_vertices function.
59-
h = Graph{T}(7)
60-
add_edge!(h, 2, 5)
61-
add_edge!(h, 3, 6)
62-
add_edge!(h, 1, 7)
63-
add_edge!(h, 6, 5)
64-
59+
h1 = Graph{T}(7)
60+
add_edge!(h1, 2, 5)
61+
add_edge!(h1, 3, 6)
62+
add_edge!(h1, 1, 7)
63+
add_edge!(h1, 6, 5)
6564
vs = [2, 3, 7, 3, 3, 2]
66-
hmerged = merge_vertices(h, vs)
65+
hmerged = @inferred merge_vertices(h1, vs)
6766
@test neighbors(hmerged, 1) == [2]
6867
@test neighbors(hmerged, 2) == [1, 4, 5]
6968
@test neighbors(hmerged, 3) == []
7069
@test neighbors(hmerged, 4) == [2, 5]
70+
@test eltype(hmerged) == eltype(g)
7171

72-
new_map = @inferred(merge_vertices!(h, vs))
72+
new_map = @inferred(merge_vertices!(h1, vs))
7373
@test new_map == [1, 2, 2, 3, 4, 5, 2]
74-
@test neighbors(h, 1) == [2]
75-
@test neighbors(h, 2) == [1, 4, 5]
76-
@test neighbors(h, 3) == []
77-
@test neighbors(hmerged, 4) == [2, 5]
78-
@test hmerged == h
79-
80-
h = Graph{T}(7)
81-
add_edge!(h, 1, 2)
82-
add_edge!(h, 2, 3)
83-
add_edge!(h, 2, 4)
84-
add_edge!(h, 3, 4)
85-
add_edge!(h, 3, 7)
86-
new_map = @inferred(merge_vertices!(h, [2, 3, 2, 2]))
74+
@test neighbors(h1, 1) == [2]
75+
@test neighbors(h1, 2) == [1, 4, 5]
76+
@test neighbors(h1, 3) == []
77+
@test neighbors(h1, 4) == [2, 5]
78+
@test hmerged == h1
79+
80+
h2 = path_digraph(4)
81+
h2 = DiGraph{T}(h2)
82+
hmerged = @inferred merge_vertices(h2, [2, 3])
83+
@test is_directed(hmerged)
84+
@test inneighbors(hmerged, 1) == []
85+
@test inneighbors(hmerged, 2) == [1]
86+
@test inneighbors(hmerged, 3) == [2]
87+
@test outneighbors(hmerged, 1) == [2]
88+
@test outneighbors(hmerged, 2) == [3]
89+
@test outneighbors(hmerged, 3) == []
90+
@test eltype(hmerged) == eltype(h2)
91+
92+
h3 = Graph{T}(7)
93+
add_edge!(h3, 1, 2)
94+
add_edge!(h3, 2, 3)
95+
add_edge!(h3, 2, 4)
96+
add_edge!(h3, 3, 4)
97+
add_edge!(h3, 3, 7)
98+
new_map = @inferred(merge_vertices!(h3, [2, 3, 2, 2]))
8799
@test new_map == [1, 2, 2, 3, 4, 5, 6]
88-
@test neighbors(h, 2) == [1, 3, 6]
89-
@test neighbors(h, 1) == [2]
90-
@test neighbors(h, 3) == [2]
91-
@test neighbors(h, 4) == Int[]
92-
@test neighbors(h, 6) == [2]
93-
@test ne(h) == 3
94-
@test nv(h) == 6
95-
96-
h2 = Graph{T}(7)
97-
add_edge!(h2, 1, 2)
98-
add_edge!(h2, 2, 3)
99-
add_edge!(h2, 2, 4)
100-
add_edge!(h2, 3, 4)
101-
add_edge!(h2, 3, 7)
102-
add_edge!(h2, 6, 7)
103-
new_map = @inferred(merge_vertices!(h2, [2, 7, 3, 2]))
100+
@test neighbors(h3, 2) == [1, 3, 6]
101+
@test neighbors(h3, 1) == [2]
102+
@test neighbors(h3, 3) == [2]
103+
@test neighbors(h3, 4) == Int[]
104+
@test neighbors(h3, 6) == [2]
105+
@test ne(h3) == 3
106+
@test nv(h3) == 6
107+
108+
h4 = Graph{T}(7)
109+
add_edge!(h4, 1, 2)
110+
add_edge!(h4, 2, 3)
111+
add_edge!(h4, 2, 4)
112+
add_edge!(h4, 3, 4)
113+
add_edge!(h4, 3, 7)
114+
add_edge!(h4, 6, 7)
115+
new_map = @inferred(merge_vertices!(h4, [2, 7, 3, 2]))
104116
@test new_map == [1, 2, 2, 3, 4, 5, 2]
105-
@test neighbors(h2, 2) == [1, 3, 5]
106-
@test neighbors(h2, 1) == [2]
107-
@test neighbors(h2, 3) == [2]
108-
@test neighbors(h2, 4) == Int[]
109-
@test neighbors(h2, 5) == [2]
110-
@test ne(h2) == 3
111-
@test nv(h2) == 5
112-
113-
h3 = star_graph(5)
114-
h3merged = merge_vertices(h3, [1, 2])
115-
@test neighbors(h3merged, 1) == [2, 3, 4]
116-
@test neighbors(h3merged, 2) == [1]
117-
@test neighbors(h3merged, 3) == [1]
118-
@test neighbors(h3merged, 4) == [1]
117+
@test neighbors(h4, 2) == [1, 3, 5]
118+
@test neighbors(h4, 1) == [2]
119+
@test neighbors(h4, 3) == [2]
120+
@test neighbors(h4, 4) == Int[]
121+
@test neighbors(h4, 5) == [2]
122+
@test ne(h4) == 3
123+
@test nv(h4) == 5
124+
125+
h5 = star_graph(5)
126+
h5 = Graph{T}(h5)
127+
h5merged = merge_vertices(h5, [1, 2])
128+
@test neighbors(h5merged, 1) == [2, 3, 4]
129+
@test neighbors(h5merged, 2) == [1]
130+
@test neighbors(h5merged, 3) == [1]
131+
@test neighbors(h5merged, 4) == [1]
119132
end
120133
end
121134

0 commit comments

Comments
 (0)