7

I've been banging my head over the wall for a few hours as I can't figure out how to write DFS in Haskell..

My graph is implemented as an adjacency list where the keys (or node name of the graph) are list indices:

0 -> 1
1 -> 0, 2
2 -> 1
As a Haskell list: [[1],[0,2],[1]]

Here's my code so far for DFS:

dfs graph visited node = helper graph visited (graph !! node) node
 where helper _ _ visited [] _ = visited
 helper graph visited (x:xs) currNode
 | elem x visited = helper graph visited xs currNode
 | otherwise = dfs graph (currNode:visited) x

I understand that the problem is that it doesn't backtrack and try another adjacent node once it reaches one end of the graph. I've been trying to modify the otherwise section of the guard in an attempt to fix it but can't seem to come up with something that works. What can I do to fix this?

asked Oct 5, 2012 at 3:20
3
  • Does that even compile ? Also the complexity of !! is O(n) in worst case, so the complexity of your dfs will be much larger. Commented Oct 5, 2012 at 3:49
  • If this isn't homework, you may want to use the Functional Graph Library (fgl). It looks daunting with tons of modules but it's actually easy to use. Commented Oct 5, 2012 at 3:54
  • This is too little for an answer but take a look at this paper: "Structuring Depth-First Search Algorithm in Haskell" www.researchgate.net/publication/2252048_Structuring_Depth-First_Search_Algorithms_in_Haskell/file/50463523c7a64b12d4.pdf – it's not the easiest to grasp but... Well, should perform well. I'll do testing a bit later. Commented Jul 28, 2014 at 11:09

2 Answers 2

3

What you are trying to do is still not very clear to me. I have written something similar to yours although it has the same problem that !! is not O(1), but it is still dfs.

mydfs graph visited [] = reverse visited
mydfs graph visited (x:xs) | elem x visited = mydfs graph visited xs
 | otherwise = mydfs graph (x:visited) ((graph !! x) ++ xs)

The idea for dfs to backtrack is to keep a list of tobevisited and just take out the first entry from it and visit it and whenever you find an entry that is not visited push its adjacent vertices on top of the tobevisited list.

You can use arrays or vectors for adjacency list to avoid O(n) lookup, but it is better to use graph libraries for what you are trying to do.

answered Oct 5, 2012 at 4:17
3

Shortest I could come up with

dfs current visited =
 foldl (\visited next -> if elem next visited then visited else dfs next visited)
 (visited ++ [current]) (graph !! current)

Compare with python:

def dfs(v, visited):
 visited.append(v)
 for u in graph[v]:
 if u not in visited:
 visited = dfs(u, visited)
 return visited
answered Nov 9, 2016 at 20:11

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.