我正在编写一个程序,该程序使用户能够在给定的最大“跳跃距离”的情况下搜索任何两个机场之间的航线,但是我仍然在着手编写“ 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 >