在图中搜索路径

时间:2019-05-07 16:24:04

标签: haskell

我正在编写一个程序,该程序使用户能够在给定的最大“跳跃距离”的情况下搜索任何两个机场之间的航线,但是我仍然在着手编写“ findPath”功能的代码。

findPath函数应该包含一个Locations列表,两个字符串是一个开始位置和一个结束位置,以及maxHop是一个飞机可以行进的最大距离。 到目前为止,我已经实现了以下功能,但是我仍然坚持如何在我的findPath函数中实现bestfirstsearch。

import Data.List
import Data.Ord
import Debug.Trace

search :: (Eq a, Show a) => (a -> Bool) -> (a -> [a]) -> ([a] -> [a] -> [a]) -> [a] -> [a] -> Maybe a
search goal succ combiner nodes oldNodes
  | null nodes = Nothing
  | goal (head nodes) = Just (head nodes)
  | otherwise = let (n:ns) = nodes
                in traceShow n $ search goal succ combiner
                   (combiner (removeDups (succ n)) ns)
                   (adjoin n oldNodes)
  where removeDups = filter (not . ((flip elem) (nodes ++ oldNodes)))
        adjoin x lst = if elem x lst then lst else x:lst

bestFirstSearch :: (Eq a, Show a, Ord b) => (a -> Bool) -> (a -> [a])                 -> (a -> b) -> a -> Maybe a

bestFirstSearch goal succ score start = search goal succ
                                        (\new old -> sortBy (comparing score)
                                          $ new ++ old)
                                        [start] []

data Location = Location { locName :: String
                         , latitude :: Double
                         , longitude :: Double
                         } deriving (Eq)

data Path = Path { route :: [Location]
                 , totalDist :: Double
                 } deriving (Eq)

geoDistance :: (Double,Double) -> (Double,Double) -> Double

geoDistance (lat1,lon1) (lat2,lon2) = 3959 * (acos (sindeg(lat1) * sindeg(lat2) + cosdeg(lat1) * cosdeg(lat2) * cosdeg(lon2-lon1)))
  where  sindeg = sin . toRadian
         cosdeg = cos . toRadian
         toRadian deg = pi/180.0 * deg


distanceBetween :: Location -> Location -> Double
distanceBetween (Location _ lat1 lon1) 
                (Location _ lat2 lon2) = geoDistance (lat1, lon1) 
                                                     (lat2, lon2)


findPath :: [Location] -> String -> String -> Double -> Maybe Path
findPath loc start goal maxHop = undefined



lat_long_data = [ ("Bangkok", 13.76, 100.5),
                  ("Beijing", 39.90, 116.41),
                  ("Buenos Aires", -34.6, -58.38),
                  ("Chicago", 41.87, -87.63),
                  ("Dallas", 32.77, -96.79),
                  ("Denver", 39.73, -104.99),
                  ("Dubai", 25.20, 55.27),
                  ("Honolulu", 21.30, -157.85),
                  ("London", 51.50, -0.12),
                  ("Los-Angeles", 34.05, -118.24),
                  ("New-York", 40.71, -74.00),
                  ("Paris", 48.85, 2.35) ]

testAirports :: [Location]
testAirports = map (\(n,lat,lon)->Location n lat lon) lat_long_data

预期输出应大致如下:

Input: findPath testAirports "Los-Angeles" "New-York" 1000

Output: Just <2459.3319233721513: Los-Angeles - Denver - Chicago - New-York >

0 个答案:

没有答案