I will first explain what dfs
does. As you mentioned in your comments, you use buildG
function so I will also use it in my answer.
dfs
takes 2 arguments: graph and list of root nodes. And then dfs
runs depth-first search starting from each vertex number in list, returning Tree
of reachable vertices from those nodes in list. For example:
- You have graph of 1 vertex and you want find paths from 1. You will then have list with only one
Tree
where root label is 1
and subforest is empty.
- You have graph of 2 vertices and edge from 1 to 2 and you want find paths from 1. You will then have list with only one
Tree
where root label is 1
and subforest is list with 2 as root label.
- You have graph of 3 vertices and edges (1,2) and (1,3) and you want find paths from 1. You will then have list with only one
Tree
where root label is 1
and subforest is list with two trees with 2 and 3 as root labels correspondingly.
All these examples (and even some more) are demonstrated in next ghci session:
λ: let g = buildG (1,1) []
λ: dfs g [1]
[Node {rootLabel = 1, subForest = []}]
λ: dfs g [2]
*** Exception: Ix{Int}.index: Index (2) out of range ((1,1))
λ: let g = buildG (1,2) [(1,2)]
λ: dfs g [1]
[Node {rootLabel = 1, subForest = [Node {rootLabel = 2, subForest = []}]}]
λ: dfs g [2]
[Node {rootLabel = 2, subForest = []}]
λ: let g = buildG (1,3) [(1,2), (1,3)]
λ: dfs g [1]
[Node {rootLabel = 1, subForest = [Node {rootLabel = 3, subForest = []},Node {rootLabel = 2, subForest = []}]}]
But, unfortunately, dfs
can't help you with your task: finding furthest vertex from given one. In the way algorithm works it is just not capable to solve such problems. Suppose you have graph with 4 vertices and edges:
1 → 2, 2 → 3, 3 → 4, 1 → 4
Vertex that has longest path from 1 is 3 (this path has 2 edges). But dfs
will return you different results depending on order of edges you specified.
λ: let g = buildG (1,4) [(1,2), (1,4), (2,3), (3,4)]
λ: dfs g [1]
[Node {rootLabel = 1, subForest = [Node {rootLabel = 4, subForest = []},Node {rootLabel = 2, subForest = [Node {rootLabel = 3, subForest = []}]}]}]
λ: let g = buildG (1,4) [(1,4), (1,2), (2,3), (3,4)]
λ: dfs g [1]
[Node {rootLabel = 1, subForest = [Node {rootLabel = 2, subForest = [Node {rootLabel = 3, subForest = [Node {rootLabel = 4, subForest = []}]}]}]}]
It is not the problem of particular implementation. It is just how dfs
works. And you can't use dfs
in general case to solve your particular problem. Also, this problem can't be fixed with just rearranging edges in list because you don't know how to rearrange them in general.
What you really need to use is bfs
algorithm — breadth-first search. Unfortunately, it is not implemented in Data.Graph
library. So you need to implement whole algo from zero or find implementation somewhere (here some dicussions: Traversing a graph breadth first, marking visited nodes in Haskell).