logo
down
shadow

Haskell - Calculating the shortest path using trees


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]


Share : facebook icon twitter icon
Dissimilarity between shortest path trees

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

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

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

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"
shpData <- readshpnw(myShapefile, ELComputed=TRUE)
igraphShpObject <- nel2igraph(shpData[[2]], shpData[[3]], weight=shpData[[4]])
testPath <- get.shortest.paths(igraphShpObject, from=42, to=52) # arbitrary nodes
testPath[1] # print the node IDs to the console
C++ Calculating Shortest Path in a Directed Graph

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);
Related Posts Related Posts :
  • Haskell Shelly sample code
  • Finding type signatures in Haskell that are too specific
  • haskell - will pattern matching work faster for non-specific form of an algebraic data type?
  • Cannot enter multiline statements in GHCi
  • Using Gloss to run a simulation while using SDL to play a sound
  • Beginner: Converting Types in Haskell
  • G-machine, (non-)strict contexts - why case expressions need special treatment
  • Indentation with Let Statements
  • Haskell parse list of integers with Attoparsec
  • Change (0, 1] to (0, 1) without branching
  • Haskell equivalent to contains
  • Is there a way to unmap in Haskell?
  • Using HLint.hs file in EclipseFP
  • Don't know how to use . and $ operator in Haskell
  • Why is my haskell code so slow
  • How is FRP handled in terms of memory?
  • Generalizing traversal of expressions with changes on specific nodes
  • Why does pattern matching on this GADT seem to introduce ambiguity in the type checker?
  • How to detect end of input with pipes
  • Basic Haskell IO Monad FilePath join
  • shadow
    Privacy Policy - Terms - Contact Us © ourworld-yourmove.org