diff --git a/doc/build.jl b/doc/build.jl index d89ce8974..8e08e10d4 100644 --- a/doc/build.jl +++ b/doc/build.jl @@ -354,7 +354,9 @@ Any graph traversal will traverse an edge only if it is present in the graph. W ## Connectivity / Bipartiteness `Graph connectivity` functions are defined on both undirected and directed graphs: -{{is_connected, is_strongly_connected, is_weakly_connected, connected_components, strongly_connected_components, weakly_connected_components, has_self_loop, attracting_components, is_bipartite, condensation, period}} +{{is_connected, is_strongly_connected, is_weakly_connected, connected_components, + strongly_connected_components, weakly_connected_components, has_self_loop, + attracting_components, is_bipartite, condensation, period, neighborhood}} ## Cycle Detection In graph theory, a cycle is defined to be a path that starts from some vertex diff --git a/doc/pathing.md b/doc/pathing.md index b9b556618..8c35ce6f8 100644 --- a/doc/pathing.md +++ b/doc/pathing.md @@ -131,6 +131,13 @@ period(g::LightGraphs.DiGraph) ``` Computes the (common) period for all nodes in a strongly connected graph. +### neighborhood +```julia +neighborhood(g, v::Int, d::Int; dir=:out) +``` + +Returns a vector of the vertices in `g` at distance less or equal to `d` from `v`. If `g` is a `DiGraph` the `dir` optional argument specifies the edge direction with respect to `v` (i.e. `:in` or `:out`) to be considered. + ## Cycle Detection In graph theory, a cycle is defined to be a path that starts from some vertex `v` and ends up at `v`. diff --git a/src/LightGraphs.jl b/src/LightGraphs.jl index 47a04724d..3eda359ef 100644 --- a/src/LightGraphs.jl +++ b/src/LightGraphs.jl @@ -62,7 +62,7 @@ randomwalk, saw, non_backtracking_randomwalk, # connectivity connected_components, strongly_connected_components, weakly_connected_components, is_connected, is_strongly_connected, is_weakly_connected, period, -condensation, attracting_components, +condensation, attracting_components, neighborhood, # cliques maximal_cliques, @@ -100,7 +100,7 @@ maximum_weight_maximal_matching, MatchingResult, # randgraphs erdos_renyi, watts_strogatz, random_regular_graph, random_regular_digraph, random_configuration_model, StochasticBlockModel, make_edgestream, nearbipartiteSBM, blockcounts, blockfractions, -stochastic_block_model, +stochastic_block_model, #community modularity, community_detection_nback, core_periphery_deg, diff --git a/src/connectivity.jl b/src/connectivity.jl index 8e2e7a653..2a7597006 100644 --- a/src/connectivity.jl +++ b/src/connectivity.jl @@ -227,3 +227,29 @@ function attracting_components(g::DiGraph) end return scc[attracting] end + +""" + neighborhood(g, v::Int, d::Int; dir=:out) + +Returns a vector of the vertices in `g` at distance less or equal to `d` +from `v`. If `g` is a `DiGraph` the `dir` optional argument specifies the edge direction +with respect to `v` (i.e. `:in` or `:out`) to be considered. +""" +function neighborhood(g::SimpleGraph, v::Int, d::Int; dir=:out) + neig = Set{Int}(v) + ∂neig = copy(neig) + fneig = dir == :out ? out_neighbors : in_neighbors + for l=1:d + newneigs = Set{Int}() + for i in ∂neig + for j in fneig(g, i) + if j ∉ neig + push!(newneigs, j) + push!(neig, j) + end + end + end + ∂neig = newneigs + end + return collect(neig) +end diff --git a/test/connectivity.jl b/test/connectivity.jl index d6a374be8..326f75b41 100644 --- a/test/connectivity.jl +++ b/test/connectivity.jl @@ -132,3 +132,22 @@ fig8 = DiGraph(fig8) @test attracting_components(fig1) == Vector[[2,5]] @test attracting_components(fig3) == Vector[[3,4],[8]] + +g10 = StarGraph(10) +@test neighborhood(g10, 1 , 0) == [1] +@test length(neighborhood(g10, 1, 1)) == 10 +@test length(neighborhood(g10, 2, 1)) == 2 +@test length(neighborhood(g10, 1, 2)) == 10 +@test length(neighborhood(g10, 2, 2)) == 10 + +g10 = StarDiGraph(10) +@test neighborhood(g10, 1 , 0, dir=:out) == [1] +@test length(neighborhood(g10, 1, 1, dir=:out)) == 10 +@test length(neighborhood(g10, 2, 1, dir=:out)) == 1 +@test length(neighborhood(g10, 1, 2, dir=:out)) == 10 +@test length(neighborhood(g10, 2, 2, dir=:out)) == 1 +@test neighborhood(g10, 1 , 0, dir=:in) == [1] +@test length(neighborhood(g10, 1, 1, dir=:in)) == 1 +@test length(neighborhood(g10, 2, 1, dir=:in)) == 2 +@test length(neighborhood(g10, 1, 2, dir=:in)) == 1 +@test length(neighborhood(g10, 2, 2, dir=:in)) == 2