1
1
"""
2
- BFSIterator
2
+ BFSIterator(graph, source; depth_limit=nothing, neighbors_type=outneighbors)
3
3
4
- `BFSIterator` is used to iterate through graph vertices using a breadth-first search.
5
- A source node(s) is optionally supplied as an `Int` or an array-like type that can be
6
- indexed if supplying multiple sources.
4
+ `BFSIterator` is used to iterate through graph vertices using a breadth-first search.
5
+ A source node(s) must be supplied as an `Int` or an array-like type that can be
6
+ indexed if supplying multiple sources. It is also possible to specify a `depth_limit`
7
+ which will stop the search once all nodes at that depth are visited and a `neighbors_type`
8
+ which specifies what kind of neighbors of a node should be considered when exploring the graph.
7
9
8
10
# Examples
9
11
```julia-repl
@@ -20,14 +22,18 @@ julia> for node in BFSIterator(g,3)
20
22
2
21
23
```
22
24
"""
23
- struct BFSIterator{S,G<: AbstractGraph }
25
+ struct BFSIterator{S,G<: AbstractGraph ,F }
24
26
graph:: G
25
27
source:: S
26
- function BFSIterator (graph:: G , source:: S ) where {S,G}
28
+ depth_limit:: Int
29
+ neighbors_type:: F
30
+ function BFSIterator (
31
+ graph:: G , source:: S ; depth_limit= typemax (Int64), neighbors_type:: F = outneighbors
32
+ ) where {S,G,F}
27
33
if any (node -> ! has_vertex (graph, node), source)
28
34
error (" Some source nodes for the iterator are not in the graph" )
29
35
end
30
- return new {S,G} (graph, source)
36
+ return new {S,G,F } (graph, source, depth_limit, neighbors_type )
31
37
end
32
38
end
33
39
@@ -46,6 +52,7 @@ mutable struct BFSVertexIteratorState
46
52
next_level:: Vector{Int}
47
53
node_idx:: Int
48
54
n_visited:: Int
55
+ n_level:: Int
49
56
end
50
57
51
58
Base. IteratorSize (:: BFSIterator ) = Base. SizeUnknown ()
@@ -59,7 +66,7 @@ First iteration to visit vertices in a graph using breadth-first search.
59
66
function Base. iterate (t:: BFSIterator{<:Integer} )
60
67
visited = falses (nv (t. graph))
61
68
visited[t. source] = true
62
- state = BFSVertexIteratorState (visited, [t. source], Int[], 0 , 0 )
69
+ state = BFSVertexIteratorState (visited, [t. source], Int[], 0 , 0 , 0 )
63
70
return Base. iterate (t, state)
64
71
end
65
72
@@ -68,7 +75,7 @@ function Base.iterate(t::BFSIterator{<:AbstractArray})
68
75
curr_level = unique (s for s in t. source)
69
76
sort! (curr_level)
70
77
visited[curr_level] .= true
71
- state = BFSVertexIteratorState (visited, curr_level, Int[], 0 , 0 )
78
+ state = BFSVertexIteratorState (visited, curr_level, Int[], 0 , 0 , 0 )
72
79
return Base. iterate (t, state)
73
80
end
74
81
@@ -80,10 +87,13 @@ Iterator to visit vertices in a graph using breadth-first search.
80
87
function Base. iterate (t:: BFSIterator , state:: BFSVertexIteratorState )
81
88
# we fill nodes in this level
82
89
if state. node_idx == length (state. curr_level)
90
+ state. n_level == t. depth_limit && return nothing
91
+ state. n_level += 1
83
92
state. n_visited += length (state. curr_level)
84
93
state. n_visited == nv (t. graph) && return nothing
94
+ neighbors_type = t. neighbors_type
85
95
@inbounds for node in state. curr_level
86
- for adj_node in outneighbors (t. graph, node)
96
+ for adj_node in neighbors_type (t. graph, node)
87
97
if ! state. visited[adj_node]
88
98
push! (state. next_level, adj_node)
89
99
state. visited[adj_node] = true
0 commit comments