  C RUBY-ON-RAILS MYSQL ASP.NET DEVELOPMENT RUBY .NET LINUX SQL-SERVER REGEX WINDOWS ALGORITHM ECLIPSE VISUAL-STUDIO STRING SVN PERFORMANCE APACHE-FLEX UNIT-TESTING SECURITY LINQ UNIX MATH EMAIL OOP LANGUAGE-AGNOSTIC VB6 MSBUILD # Haskell - Calculating the shortest path using trees  » haskell » Haskell - Calculating the shortest path using trees

By : grostas
Date : November 22 2020, 10:54 AM
this will help We're going to solve this problem by searching a tree in three parts. First we will build a Tree representing the paths through the problem, with branches for each state. We'd like to find the shortest path to get to a state with a certain criteria, so we will write a breadth first search for searching any Tree. This won't be fast enough for the example problem you provided, so we will improve on the breadth first search with a transposition table which keeps track of states we have already explored to avoid exploring them again.
Building a Tree code :
``````import Data.Array

type Board = Array (Int, Int) Char

board :: Board
board = listArray ((1,1),(3,4)) ("AAAA" ++ "ACCB" ++ "ADEF")
``````
``````import Data.Maybe

(!?) :: Ix i => Array i a -> i -> Maybe a
a !? i = if inRange (bounds a) i then Just (a ! i) else Nothing
``````
``````data State = State {position :: (Int, Int), direction  :: (Int, Int)}
deriving (Eq, Ord, Show)
``````
``````right :: Num a => (a, a) -> (a, a)
right (down, across) = (across, -down)

left ::  Num a => (a, a) -> (a, a)
left (down, across) = (-across, down)

moveTowards :: (Num a, Num b) => (a, b) -> (a, b) -> (a, b)
moveTowards (x1, y1) (x2, y2) = (x1 + x2, y1 + y2)
``````
``````import Prelude hiding (Right, Left)

data Move = Left | Right | Forward | Jump
deriving (Show)
``````
``````moves :: Board -> State -> [(Move, State)]
moves board (State pos dir) =
(if inRange (bounds board) pos then [(Right,   State pos    (right dir)), (Left, State pos (left dir))] else []) ++
(if next == Just here          then [(Forward, State nextPos dir)] else []) ++
(if next == Just (succ here)   then [(Jump,    State nextPos dir)] else [])
where
here = fromMaybe 'A' (board !? pos)
nextPos = moveTowards dir pos
next = board !? nextPos
``````
``````data Tree a = Node {
rootLabel :: a,         -- ^ label value
subForest :: Forest a   -- ^ zero or more child trees
}

type Forest a = [Tree a]
``````
``````import Data.Tree

explore :: Board -> State -> [Tree (Move, State)]
explore board = map go . moves board
where
go (label, state) = Node (label, state) (explore board state)
``````
``````limit :: Int -> Tree a -> Tree a
limit n (Node a ts)
| n <= 0    = Node a []
| otherwise = Node a (map (limit (n-1)) ts)
``````
``````(putStrLn .
drawForest .
map (fmap (\(m, s) -> show (m, board ! position s)) . limit 2) .
explore board \$ State (4, 1) (-1, 0))

(Forward,'A')
|
+- (Right,'A')
|  |
|  +- (Right,'A')
|  |
|  `- (Left,'A')
|
+- (Left,'A')
|  |
|  +- (Right,'A')
|  |
|  `- (Left,'A')
|
`- (Forward,'A')
|
+- (Right,'A')
|
+- (Left,'A')
|
`- (Forward,'A')
``````
``````import Data.Sequence (viewl, ViewL (..), (><))
import qualified Data.Sequence as Seq
``````
``````breadthFirstSearch :: (a -> Bool) -> [Tree a] -> Maybe [a]
breadthFirstSearch p = combine Seq.empty []
where
combine queue ancestors branches =
go (queue >< (Seq.fromList . map ((,) ancestors) \$ branches))
go queue =
case viewl queue of
EmptyL -> Nothing
(ancestors, Node a bs) :< queued ->
if p a
then Just . reverse \$ a:ancestors
else combine queued (a:ancestors) bs
``````
``````solve :: Char -> Board -> State -> Maybe [Move]
solve goal board = fmap (map fst) . breadthFirstSearch ((== goal) . (board !) . position . snd) . explore board
``````
``````> solve 'F' board (State (4, 1) (-1, 0))
``````
``````AB
AC
*
``````
``````smallBoard :: Board
smallBoard = listArray ((1,1),(2,2)) ("AB" ++ "AC")
``````
``````> solve 'C' smallBoard (State (3, 1) (-1, 0))
Just [Forward,Forward,Right,Jump,Right,Jump]
``````
``````import qualified Data.Set as Set
``````
``````breadthFirstSearchUnseen:: Ord r => (a -> r) -> (a -> Bool) -> [Tree a] -> Maybe [a]
``````
``````breadthFirstSearchUnseen repr p = combine Set.empty Seq.empty []
where
combine seen queued ancestors unseen =
go
(seen  `Set.union` (Set.fromList . map (repr . rootLabel) \$ unseen))
(queued ><         (Seq.fromList . map ((,) ancestors   ) \$ unseen))
go seen queue =
case viewl queue of
EmptyL -> Nothing
(ancestors, Node a bs) :< queued ->
if p a
then Just . reverse \$ ancestors'
else combine seen queued ancestors' unseen
where
ancestors' = a:ancestors
unseen = filter (flip Set.notMember seen . repr . rootLabel) bs
``````
``````solve :: Char -> Board -> State -> Maybe [Move]
solve goal board = fmap (map fst) . breadthFirstSearchUnseen snd ((== goal) . (board !) . position . snd) . explore board
``````
``````> solve 'F' board (State (4, 1) (-1, 0))
Just [Forward,Forward,Forward,Right,Forward,Forward,Forward,Right,Jump,Right,Jump,Forward,Left,Jump,Left,Jump,Jump]
`````` ## Dissimilarity between shortest path trees

By : Pietro Rampazzo
Date : March 29 2020, 07:55 AM
Does that help Your vector T is a vector containing the parent labels of each node. For your sample, T1 would look like [0,0,0,2,0], indicating that, in order to get to 4, you have to follow the path to node 2 and then take a link to 4.
This is a rather simple way of representing your paths. If you need to find the differences between both vectors, you could compare them elementwise or do a xor between both vectors. If you take that difference, the differences you'll find are the nodes that have different parents. ## Calculating the shortest path between any two vertices u,v in G

By : user3448499
Date : March 29 2020, 07:55 AM
I hope this helps . The efficiency of your current code depends on the implementation of g.get_shortest_paths. Typically choices of g.get_shortest_paths include:
Bellman–Ford algorithm, which shall run at O(VE), Dijkstra's algorithm, which shall run at O(V^2) without optimization, O(Elog(v)) or even O(E+Vlog(E/V)log(V)) if well-optimized. ## How to use jsprit for calculating the shortest path

By : Karegyeya Marvin
Date : March 29 2020, 07:55 AM
fixed the issue. Will look into that further jsprit has no meaning of a network topology - you can use euclidean, real or manhatten distances or whatever. To calculate real distances or even time estimates you can use GraphHopper (as you've tagged you question with that) or other software for that purpose. Note: I'm the author of GraphHopper. Then feed the distance matrix you calculated into jsprit. See the documentation and examples of the projects on how to do this. ## R: calculating single shortest path between two vertices

By : Sara Scarazzolo
Date : March 29 2020, 07:55 AM
fixed the issue. Will look into that further I found my issue, which occurred before I called get.shortest.paths(). For those who are curious on how to read in an ESRI shapefile, and find a single shortest path between two points (which was my dilemma):
code :
``````myShapefile <- readOGR(dsn=".", layer="MyShapefileName") # i.e. "MyShapefileName.shp"
igraphShpObject <- nel2igraph(shpData[], shpData[], weight=shpData[])
testPath <- get.shortest.paths(igraphShpObject, from=42, to=52) # arbitrary nodes
testPath # print the node IDs to the console
`````` ## C++ Calculating Shortest Path in a Directed Graph

By : Saiful Islam
Date : March 29 2020, 07:55 AM
I think the issue was by ths following , I am tasked with writing a program to maintain the representation of a simple network(weighted directed graph) and compute the best path between two given nodes upon request. , You have invalid code at the beginning of your shortestPath function:
code :
``````bool known[openNode];
int distance[openNode];
GraphNode*  previous[openNode];
``````
``````std::vector<bool> known(openNode, false);
std::vector<int> distance(openNode, 999999);
std::vector<GraphNode*>  previous(openNode, nullptr);
`````` 