Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding shortest path with FGL

I'm using Martin Erwig's Functional Graph Library (FGL) to represent the following simple directed weighted graph.

graph

genLNodes :: [LNode String]
genLNodes = zip [1..5] ["A","B","C","D","E"]

genLEdges :: [LEdge Int]
genLEdges = [(1,2,4),(1,3,1),(2,4,2),(3,4,2),(2,5,1),(4,5,1),
             (2,1,4),(3,1,1),(4,2,2),(4,3,2),(5,2,1),(5,4,1)]

mygraph :: Gr String Int
mygraph = mkGraph genLNodes genLEdges

Now I want to find the shortest path from one node to another e.g. A to E using dijkstra's algorithm. There seems to be a function to do that in Data.Graph.Inductive.Query.SP:

dijkstra :: (Graph gr, Real b) => Heap b (LPath b) -> gr a b -> LRTree b

But I'm not able to figure out how to use it from the interface provided. Any help would be much appreciated. I would also like to hear any other suggestions, if I'm creating the directed weighted graph the right way, or if there's any other (better) package to do so?

like image 821
vis Avatar asked Oct 28 '12 23:10

vis


People also ask

How do I find shortest path with the ability to skip some edges?

First use Dijkstra to find the length S(v) of shortest path from s to v for every vertex v . Then use Dijkstra to find the length T(v) of shortest path from v to t for every vertex v . Then for every edge (v, w) find the sum S(v) + T(w) by using the rules above. Finally, choose the minimum path.

How do you find the shortest path in a weighted graph?

One common way to find the shortest path in a weighted graph is using Dijkstra's Algorithm. Dijkstra's algorithm finds the shortest path between two vertices in a graph. It can also be used to generate a Shortest Path Tree - which will be the shortest path to all vertices in the graph (from a given source vertex).


1 Answers

To get the shortest path between two nodes, the module provides a special function, sp (short for "shortest path", presumably), so the simplest way to get the shortest path is

sp 1 5 mygraph

sp uses dijkstra:

spTree :: (Graph gr, Real b) => Node -> gr a b -> LRTree b
spTree v = dijkstra (H.unit 0 (LP [(v,0)]))

sp :: (Graph gr, Real b) => Node -> Node -> gr a b -> Path
sp s t = getLPathNodes t . spTree s

and from that you can see how you could produce the spanning tree and get the shortest path from that yourself, but unless you have a very good reason to not use the provided function, you should stick with that.

like image 86
Daniel Fischer Avatar answered Sep 29 '22 18:09

Daniel Fischer