Reputation: 4402
So the question is simple. Given a graph (I hope that the structure of the graph doesn't matter much in this problem), how do I go about doing a BFS on it?
I've recently asked a question about generating a list where each element appends many elements to the end of it. The answer should hopefully let me make a queue I need to do the BFS. But there's another key component that a search needs and it's marking the nodes as visited so we don't go over them again. This also needs to have no overhead on the execution of the algorithm. Neither marking or reading.
Since Haskell doesn't let me change state, how would I go about doing that?
(I'm not looking for a way to translate my imperative code to Haskell. An idiomatic Haskell solution would be great.)
Upvotes: 3
Views: 3659
Reputation: 1116
I think, the simplest way to look at this is to look at any level in the tree graph.
This is now easy to translate, (this code flattens the graph breadth first).
toBFSList :: [Graph a] -> [Graph a]
toBFSList [] = [] -- trivial case
toBFSList gs = ns ++ fs
where ns = map extract gs -- "extract" may extract a single node
cs = concat $ map children gs -- get all the child nodes for all above node
fs = toBFSList cs -- for all children, do traversal
Upvotes: 0
Reputation: 152997
The paper Inductive Graphs and Functional Graph Algorithms discusses such problems and is quite readable. It is the basis of the fgl package, which has an entire module for BFS-like queries. I highly recommend the paper -- it was an eye-opening read for me (namely, the underlying core idea of "give an inductive interface even if your data isn't inductive" was an awesome one) -- and further recommend that if you can use the fgl package you do. But if you can't, the paper will tell you enough to write an algorithm for your custom data type, I'm sure.
Upvotes: 6
Reputation: 63389
As mentioned in the comments, a proper approach is to separate your graph from marking its nodes. You need to use some kind of a set container. There are basically two approaches you can take:
Upvotes: 7