@@ -124,37 +124,64 @@ function gdistances(graph::SimpleGraph, sources; defaultdist::Int=-1)
124124 gdistances! (graph, sources, dists)
125125end
126126
127+ # ##########################################
128+ # Constructing BFS trees #
129+ # ##########################################
130+
131+ # this type has been deprecated in favor of TreeBFSVisitorVector and the tree function.
132+ """ TreeBFSVisitor is a type for representing a BFS traversal of the graph as a DiGraph"""
127133type TreeBFSVisitor <: SimpleGraphVisitor
128134 tree:: DiGraph
129135end
130136
137+ TreeBFSVisitor (n:: Int ) = TreeBFSVisitor (DiGraph (n))
138+
139+ @deprecate TreeBFSVisitor (x) TreeBFSVisitorVector (x)
140+
141+ """ TreeBFSVisitorVector is a type for representing a BFS traversal
142+ of the graph as a parents array. This type allows for a more performant implementation.
143+ """
131144type TreeBFSVisitorVector <: SimpleGraphVisitor
132145 tree:: Vector{Int}
133146end
134147
135- type ComponentVisitorVector <: SimpleGraphVisitor
136- labels:: Vector{Int}
137- seed:: Int
148+ function TreeBFSVisitorVector (n:: Int )
149+ return TreeBFSVisitorVector (zeros (Int, n))
138150end
139- function examine_neighbor! (visitor:: TreeBFSVisitorVector , u:: Int , v:: Int , vcolor:: Int , ecolor:: Int )
140- # println("discovering $u -> $v, vcolor = $vcolor, ecolor = $ecolor")
141- if u != v && vcolor == 0
142- visitor. tree[v] = u
151+
152+ """ TreeBFSVisitor converts a parents array into a DiGraph"""
153+ function TreeBFSVisitor (tvv:: TreeBFSVisitorVector )
154+ n = length (tvv. tree)
155+ parents = tvv. tree
156+ g = tree (parents)
157+ return TreeBFSVisitor (g)
158+ end
159+
160+ """ tree converts a parents array into a DiGraph"""
161+ function tree (parents:: AbstractVector )
162+ n = length (parents)
163+ t = DiGraph (n)
164+ for i in 1 : n
165+ parent = parents[i]
166+ if parent > 0 && parent != i
167+ add_edge! (t, parent, i)
168+ end
143169 end
144- return true
170+ return t
145171end
146172
147- function examine_neighbor! (visitor:: ComponentVisitorVector , u:: Int , v:: Int , vcolor:: Int , ecolor:: Int )
173+ tree (parents:: TreeBFSVisitorVector ) = tree (parents. tree)
174+
175+ function examine_neighbor! (visitor:: TreeBFSVisitorVector , u:: Int , v:: Int , vcolor:: Int , ecolor:: Int )
148176 # println("discovering $u -> $v, vcolor = $vcolor, ecolor = $ecolor")
149177 if u != v && vcolor == 0
150- visitor. labels [v] = visitor . seed
178+ visitor. tree [v] = u
151179 end
152180 return true
153181end
154- # Return the DAG representing the traversal of a graph.
155182
156- TreeBFSVisitor (n:: Int ) = TreeBFSVisitor (DiGraph (n))
157183
184+ # Return the DAG representing the traversal of a graph.
158185function examine_neighbor! (visitor:: TreeBFSVisitor , u:: Int , v:: Int , vcolor:: Int , ecolor:: Int )
159186 # println("discovering $u -> $v, vcolor = $vcolor, ecolor = $ecolor")
160187 if u != v && vcolor == 0
@@ -163,34 +190,58 @@ function examine_neighbor!(visitor::TreeBFSVisitor, u::Int, v::Int, vcolor::Int,
163190 return true
164191end
165192
166- """ Provides a breadth-first traversal of the graph `g` starting with source vertex `s`,
167- and returns a directed acyclic graph of vertices in the order they were discovered.
168- """
169- function bfs_tree (g:: SimpleGraph , s:: Int )
170- nvg = nv (g)
171- visitor = TreeBFSVisitor (nvg)
172- traverse_graph (g, BreadthFirst (), s, visitor)
173- return visitor. tree
174- end
175193
176- function bfs_tree (visitor:: TreeBFSVisitorVector , g:: SimpleGraph , s:: Int )
177- nvg = nv (g)
178- visitor = TreeBFSVisitorVector (zeros (Int,nvg))
179- visitor. tree[s] = s
180- return bfs_tree! (visitor, g, s)
181- end
182194
183195function bfs_tree! (visitor:: TreeBFSVisitorVector ,
184196 g:: SimpleGraph ,
185197 s:: Int ;
186198 colormap= zeros (Int, nv (g)),
187199 que= Vector {Int} ())
200+ # this version of bfs_tree! allows one to reuse the memory necessary to compute the tree
201+ # the output is stored in the visitor.tree array whose entries are the vertex id of the
202+ # parent of the index. This function checks if the scratch space is too small for the graph.
203+ # and throws an error if it is too small.
204+ # the source is represented in the output by a fixed point v[root] == root.
205+ # this function is considered a performant version of bfs_tree for useful when the parent
206+ # array is more helpful than a DiGraph struct, or when performance is critical.
207+ nvg = nv (g)
208+ length (visitor. tree) >= nvg || error (" visitor.tree too small for graph" )
209+ visitor. tree[s] = s
188210 traverse_graph (g, BreadthFirst (), s, visitor; colormap= colormap, que= que)
189- return visitor. tree
190211end
191212
192- # Test graph for bipartiteness
213+ """ Provides a breadth-first traversal of the graph `g` starting with source vertex `s`,
214+ and returns a directed acyclic graph of vertices in the order they were discovered.
215+
216+ This function is a high level wrapper around bfs_tree!, use that function for more performance.
217+ """
218+ function bfs_tree (g:: SimpleGraph , s:: Int )
219+ nvg = nv (g)
220+ visitor = TreeBFSVisitorVector (nvg)
221+ bfs_tree! (visitor, g, s)
222+ return tree (visitor)
223+ end
224+
225+ # ###########################################
226+ # Connected Components with BFS #
227+ # ###########################################
228+ """ Performing connected components with BFS starting from seed"""
229+ type ComponentVisitorVector <: SimpleGraphVisitor
230+ labels:: Vector{Int}
231+ seed:: Int
232+ end
233+
234+ function examine_neighbor! (visitor:: ComponentVisitorVector , u:: Int , v:: Int , vcolor:: Int , ecolor:: Int )
235+ # println("discovering $u -> $v, vcolor = $vcolor, ecolor = $ecolor")
236+ if u != v && vcolor == 0
237+ visitor. labels[v] = visitor. seed
238+ end
239+ return true
240+ end
193241
242+ # ###########################################
243+ # Test graph for bipartiteness #
244+ # ###########################################
194245type BipartiteVisitor <: SimpleGraphVisitor
195246 bipartitemap:: Vector{UInt8}
196247 is_bipartite:: Bool
0 commit comments