Advertisement
Guest User

Untitled

a guest
Dec 10th, 2016
223
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- Data types
  2.  
  3. -------------
  4.  
  5. data Edge = Ed String Double
  6.  
  7. data Vertex = Vt String Double Double [Edge]
  8.  
  9. data Path = Pt [String] Double
  10.  
  11. data Vertexa = Vtx Vertex Path Bool
  12.  
  13. data Nodelist = Nls [Vertex]
  14.  
  15. data Mainlist = Mls [Vertexa] Bool
  16.  
  17. -- Graph definitions
  18.  
  19. --------------------
  20.  
  21. graph1 = (Nls [
  22.  
  23.                 (Vt "A" 0 0 [(Ed "B" 2), (Ed "C" 4)]),
  24.  
  25.                 (Vt "B" 1 1 [(Ed "A" 2), (Ed "C" 2), (Ed "D" 3)]),
  26.  
  27.                 (Vt "C" 2 2 [(Ed "A" 4), (Ed "B" 2), (Ed "D" 2)]),
  28.  
  29.                 (Vt "D" 1 3 [(Ed "B" 3), (Ed "C" 2)]),
  30.  
  31.                 (Vt "E" 0 0 [])
  32.  
  33.                 ])
  34.  
  35. -- Main function
  36.  
  37. ----------------
  38.  
  39. -- Returns a path
  40.  
  41. astar :: Nodelist -> String -> String -> Double -> [String]
  42.  
  43. astar (Nls nodes) start _ _ | (null(filter (samename start) nodes))  = ["Wrong start vertex!"]
  44.  
  45. astar (Nls nodes) _ goal _ | (null(filter (samename goal) nodes)) = ["Wrong goal vertex!"]
  46.  
  47. astar (Nls nodes) start goal maxcost = reverse (printpath (expansionblock (Nls nodes)
  48.  
  49.                 (Mls [(Vtx (getvert nodes start) (Pt [start] 0) False)] True) (Vtx (getvert nodes goal) (Pt [] 0) False) maxcost) (getvert nodes goal))
  50.  
  51. -- Print functions
  52.  
  53. ------------------
  54.  
  55. -- Turns a list into a path of vertices as a string
  56.  
  57. printvertlist :: [Vertexa] -> [String]
  58.  
  59. printvertlist [] = []
  60.  
  61. printvertlist (v:vs) = (printvert v : printvertlist vs)
  62.  
  63. -- Prints a vertex name (ToString())
  64.  
  65. printvert :: Vertexa -> String
  66.  
  67. printvert (Vtx (Vt n _ _ _) _ _) = n
  68.  
  69. -- Prints a path
  70.  
  71. printpath :: Mainlist -> Vertex -> [String]
  72.  
  73. printpath m goal | notreached (Vtx goal (Pt [] 0) False) m = ["No path available!"]
  74.  
  75. printpath (Mls vs _) goal = getpath (getverta vs (printvert (Vtx goal (Pt [] 0) False)))
  76.  
  77. getpath :: Vertexa -> [String]
  78.  
  79. getpath (Vtx _ (Pt p _) _) = p
  80.  
  81. -- Block function
  82.  
  83. -----------------
  84.  
  85. -- Block for expanding nodes, verifies against matches and updates as needed
  86.  
  87. expansionblock :: Nodelist -> Mainlist -> Vertexa -> Double -> Mainlist
  88.  
  89. expansionblock (Nls nodes) (Mls open changed) goal cost =
  90.  
  91.                 let minv = (getminvert open goal cost)
  92.  
  93.                 in if (isworthexpanding minv goal cost) && changed
  94.  
  95.                                 then (expansionblock (Nls nodes) (addexpanded (Mls (markexpanded open minv) False) (expandall nodes minv)) goal (getnewcost open (printvert goal) cost))
  96.  
  97.                                 else (Mls open False)
  98.  
  99. -- Main list related functions
  100.  
  101. ------------------------------
  102.  
  103. -- Returns a vertex by its name
  104.  
  105. getvert :: [Vertex] -> String -> Vertex
  106.  
  107. getvert ((Vt name x y e) : vs) name1 | name1 == name = (Vt name x y e)
  108.  
  109. getvert (_ : vs) name = getvert vs name
  110.  
  111. getverta :: [Vertexa] -> String -> Vertexa
  112.  
  113. getverta (v : vs) name | (printvert v) == name = v
  114.  
  115. getverta (_ : vs) name = getverta vs name
  116.  
  117. -- Removes a vertex by its name, returns a new list
  118.  
  119. remvert :: [Vertexa] -> String -> [Vertexa]
  120.  
  121. remvert vx s = filter (diffnamea s) vx
  122.  
  123. -- Returns a vertex with minimal g + h
  124.  
  125. getminvert :: [Vertexa] -> Vertexa -> Double -> Vertexa
  126.  
  127. getminvert (v:vs) ve vx | not(notexpanded v) = getminvert vs ve vx
  128.  
  129. getminvert (v:vs) ve vx = foldl (\acc cur -> if (totalcost cur ve) < (totalcost acc ve) && (notexpanded cur)
  130.  
  131. then cur else acc) v vs
  132.  
  133. -- Expand nodes, returns a list of new nodes
  134.  
  135. expandall :: [Vertex] -> Vertexa -> [Vertexa]
  136.  
  137. expandall vs (Vtx (Vt a b c e) p r) = map (expandone vs (Vtx (Vt a b c e) p r)) e
  138.  
  139. expandone :: [Vertex] -> Vertexa -> Edge -> Vertexa
  140.  
  141. expandone vs (Vtx _ (Pt p x) _) (Ed n c) = (Vtx (getvert vs n) (Pt (n:p) (c + x)) False)
  142.  
  143. -- Udates list, setting present node to expanded
  144.  
  145. markexpanded :: [Vertexa] -> Vertexa -> [Vertexa]
  146.  
  147. markexpanded (v:exp) v1 | (printvert v) == (printvert v1) = ((setexpanded v):exp)
  148.  
  149. markexpanded (e:exp) v = (e:(markexpanded exp v))
  150.  
  151. setexpanded :: Vertexa -> Vertexa
  152.  
  153. setexpanded (Vtx v p r) = (Vtx v p True)
  154.  
  155. -- Udates list, adding expanded nodes and checking distances
  156.  
  157. addexpanded :: Mainlist -> [Vertexa] -> Mainlist
  158.  
  159. addexpanded m [] = m
  160.  
  161. addexpanded m (e:exp) = addexpanded (cheaperpath m e) exp
  162.  
  163. -- Replace a vertex path by a cheaper path if available
  164.  
  165. cheaperpath ::  Mainlist -> Vertexa ->  Mainlist
  166.  
  167. cheaperpath (Mls [] _) e = (Mls [e] True)
  168.  
  169. cheaperpath (Mls (v:vx) b) e | (printvert e) == (printvert v) =
  170.  
  171.                 if (getcheapest e v) then (Mls (e:vx) True) else (Mls (v:vx) b)
  172.  
  173. cheaperpath (Mls (v:vx) b) e = addtomainlist (cheaperpath (Mls vx b) e) v
  174.  
  175. -- Returns a Vertexa list from a Mainlist
  176.  
  177. addtomainlist :: Mainlist -> Vertexa ->  Mainlist
  178.  
  179. addtomainlist (Mls vs b) v = (Mls (v:vs) b)
  180.  
  181. prn :: Mainlist -> Bool
  182.  
  183. prn (Mls m b) = b
  184.  
  185. -- Name filter predicates
  186.  
  187. -------------------------
  188.  
  189. -- Returns True if string matches the Vertexa name
  190.  
  191. samename :: String -> Vertex -> Bool
  192.  
  193. samename n (Vt name _ _ _) = if (n == name) then True else False
  194.  
  195. -- Returns True if string matches the Vertexa name
  196.  
  197. samenamea :: String -> Vertexa -> Bool
  198.  
  199. samenamea n1 n = if (n1 == (printvert n)) then True else False
  200.  
  201. -- Returns True if string does not match the Vertex name
  202.  
  203. diffnamea :: String -> Vertexa -> Bool
  204.  
  205. diffnamea a b = not (samenamea a b)
  206.  
  207. -- Returns True if node has not been reached yet
  208.  
  209. notreached :: Vertexa -> Mainlist -> Bool
  210.  
  211. notreached v (Mls open _) = (null(filter (samenamea (printvert v)) open))
  212.  
  213. -- Returns True if node has not been expanded yet
  214.  
  215. notexpanded :: Vertexa -> Bool
  216.  
  217. notexpanded (Vtx _ (Pt p _) b) = (not b)
  218.  
  219. -- Cost-related functions
  220.  
  221. -------------------------
  222.  
  223. -- Returns the value of g(current)
  224.  
  225. cost :: Vertexa -> Double
  226.  
  227. cost (Vtx _ (Pt _ x) _) = x
  228.  
  229. -- Returns the value of h(current, goal)
  230.  
  231. heuri :: Vertexa -> Vertexa -> Double
  232.  
  233. heuri (Vtx (Vt _ x1 y1 _) _ _) (Vtx (Vt _ x2 y2 _) _ _) = sqrt ((x1 - x2)^2 + (y1 - y2)^2)
  234.  
  235. -- Returns g(current) + h(current, goal)
  236.  
  237. totalcost :: Vertexa -> Vertexa -> Double
  238.  
  239. totalcost a b = (cost a) + (heuri a b)
  240.  
  241. -- Returns true if the first vertex is cheaper than the second
  242.  
  243. getcheapest :: Vertexa -> Vertexa -> Bool
  244.  
  245. getcheapest (Vtx _ (Pt _ x) _) (Vtx _ (Pt _ y) _) = if x < y then True else False
  246.  
  247. -- Tests if the vertex is potentially worth expanding
  248.  
  249. isworthexpanding :: Vertexa -> Vertexa -> Double -> Bool
  250.  
  251. isworthexpanding a b c = if (totalcost a b) < c then True else False
  252.  
  253. -- Returns new cost after a cycle, leaves intact if no path found
  254.  
  255. getnewcost :: [Vertexa] -> String -> Double -> Double
  256.  
  257. getnewcost [] _ x = x
  258.  
  259. getnewcost ((Vtx (Vt name _ _ _) (Pt p x) _): vs) name1 oldcost | name1 == name && x < oldcost = getnewcost vs name1 x
  260.  
  261. getnewcost (_ : vs) vert oldcost = getnewcost vs vert oldcost
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement