diff --git a/src/graphs/BasicGraphs.jl b/src/graphs/BasicGraphs.jl index d2cea5c2b..dcaa579ce 100644 --- a/src/graphs/BasicGraphs.jl +++ b/src/graphs/BasicGraphs.jl @@ -198,11 +198,13 @@ multiplicity*. To get the unique neighbors, call `unique(neighbors(g))`. """ In-neighbors of vertex in a graph. """ -@inline inneighbors(g::AbstractGraph, v::Int) = @inbounds subpart(g, incident(g, v, :tgt), :src) +inneighbors(g::AbstractGraph, v::Int) = + (subpart(g, e, :src) for e in incident(g, v, :tgt)) """ Out-neighbors of vertex in a graph. """ -@inline outneighbors(g::AbstractGraph, v::Int) = @inbounds subpart(g, incident(g, v, :src), :tgt) +outneighbors(g::AbstractGraph, v::Int) = + (subpart(g, e, :tgt) for e in incident(g, v, :src)) """ Union of in-neighbors and out-neighbors in a graph. """ @@ -286,10 +288,10 @@ rem_edges!(g::AbstractSymmetricGraph, es) = rem_parts!(g, :E, unique!(sort!([es; inv(g, es)]))) neighbors(g::AbstractSymmetricGraph, v::Int) = - subpart(g, incident(g, v, :src), :tgt) -inneighbors(g::AbstractSymmetricGraph, v::Int) = neighbors(g, v) -outneighbors(g::AbstractSymmetricGraph, v::Int) = neighbors(g, v) -all_neighbors(g::AbstractSymmetricGraph, v::Int) = neighbors(g, v) + (subpart(g, e, :tgt) for e in incident(g, v, :src)) +@inline inneighbors(g::AbstractSymmetricGraph, v::Int) = neighbors(g, v) +@inline outneighbors(g::AbstractSymmetricGraph, v::Int) = neighbors(g, v) +@inline all_neighbors(g::AbstractSymmetricGraph, v::Int) = neighbors(g, v) # Reflexive graphs ################## diff --git a/src/graphs/GraphAlgorithms.jl b/src/graphs/GraphAlgorithms.jl index b2d3191bb..6674bf1ca 100644 --- a/src/graphs/GraphAlgorithms.jl +++ b/src/graphs/GraphAlgorithms.jl @@ -62,7 +62,7 @@ function topological_sort(g::ACSet, ::TopologicalSortByDFS) push!(stack, v) while !isempty(stack) u = first(stack) - u_out = outneighbors(g, u) + u_out = collect(outneighbors(g, u)) i = findfirst(u_out) do w marking[w] != TempMarked || error("Graph is not acyclic: $g") marking[w] == Unmarked diff --git a/src/graphs/Searching.jl b/src/graphs/Searching.jl index 216f6bef9..3b675cf3a 100644 --- a/src/graphs/Searching.jl +++ b/src/graphs/Searching.jl @@ -34,8 +34,9 @@ implementations which are marginally faster in practice for smaller graphs, but the performance improvements using this implementation on large graphs can be significant. """ -bfs_parents(g::ACSet, s::Int; dir = :out) = - (dir == :out) ? _bfs_parents(g, s, outneighbors) : _bfs_parents(g, s, inneighbors) +function bfs_parents(g::ACSet, s::Int; dir = :out) + _bfs_parents(g, s, dir == :out ? outneighbors : inneighbors) +end function _bfs_parents(g::ACSet, source, neighborfn::Function) n = nv(g) @@ -52,7 +53,7 @@ function _bfs_parents(g::ACSet, source, neighborfn::Function) end while !isempty(cur_level) @inbounds for v in cur_level - @inbounds @simd for i in neighborfn(g, v) + @inbounds for i in neighborfn(g, v) if !visited[i] push!(next_level, i) parents[i] = v @@ -86,8 +87,9 @@ use the corresponding edge direction (`:in` and `:out` are acceptable values). ### Implementation Notes This version of DFS is iterative. """ -dfs_parents(g::ACSet, s::Integer; dir=:out) = - (dir == :out) ? _dfs_parents(g, s, outneighbors) : _dfs_parents(g, s, inneighbors) +function dfs_parents(g::ACSet, s::Integer; dir=:out) + _dfs_parents(g, s, dir == :out ? outneighbors : inneighbors) +end function _dfs_parents(g::ACSet, s::Int, neighborfn::Function) parents = zeros(Int, nv(g)) diff --git a/test/graphs/BasicGraphs.jl b/test/graphs/BasicGraphs.jl index 98047e298..eae049553 100644 --- a/test/graphs/BasicGraphs.jl +++ b/test/graphs/BasicGraphs.jl @@ -21,8 +21,8 @@ add_edge!(g, 2, 3) @test ne(g, 1, 2) == 1 @test has_edge(g, 1, 2) @test !has_edge(g, 1, 3) -@test outneighbors(g, 2) == [3] -@test inneighbors(g, 2) == [1] +@test collect(outneighbors(g, 2)) == [3] +@test collect(inneighbors(g, 2)) == [1] @test degree(g, 2) == 2 @test collect(all_neighbors(g, 2)) == [1,3] @@ -30,8 +30,8 @@ add_edge!(g, 1, 2) @test ne(g) == 3 @test ne(g, 1, 2) == 2 @test collect(edges(g, 1, 2)) == [1,3] -@test outneighbors(g, 1) == [2,2] -@test inneighbors(g, 1) == [] +@test collect(outneighbors(g, 1)) == [2,2] +@test isempty(inneighbors(g, 1)) @test degree(g, 1) == 2 @test SimpleGraphs.DiGraph(g) == SimpleGraphs.path_digraph(3) @@ -76,9 +76,9 @@ add_edge!(g, 1, 2) add_edge!(g, 2, 3) @test ne(g) == 4 @test collect(edges(g, 1, 2)) == [1] -@test neighbors(g, 1) == [2] -@test neighbors(g, 2) == [1,3] -@test neighbors(g, 3) == [2] +@test collect(neighbors(g, 1)) == [2] +@test collect(neighbors(g, 2)) == [1,3] +@test collect(neighbors(g, 3)) == [2] @test SimpleGraphs.Graph(g) == SimpleGraphs.path_graph(3) @test SymmetricGraph(SimpleGraphs.path_graph(3)) == g @@ -89,8 +89,8 @@ lg = SimpleGraphs.DiGraph(map(SimpleGraphs.Edge, [1,2,3,2,3,4], [2,3,4,1,2,3])) rem_edge!(g, 3, 4) @test ne(g) == 4 -@test neighbors(g, 3) == [2] -@test neighbors(g, 4) == [] +@test collect(neighbors(g, 3)) == [2] +@test isempty(neighbors(g, 4)) rem_vertex!(g, 2) @test nv(g) == 3 @test ne(g) == 0