제 연구를 위해 저는 두 국가 간의 최단 경로를 얻는 다음 함수를 작성해야합니다. 이미 두 나라 간의 연결이 있는지를 확인하는 isRoute 함수와 두 나라 간의 연결을 반환하는 yieldRoute 함수를 이미 작성했습니다. 이제 두 나라 간의 최단 경로를 반환하는 함수를 작성해야합니다.하스켈에서 Dijkstra 알고리즘을 구현하는 방법
내 첫 번째 접근 방식은 양국 간의 모든 연결을 얻은 다음 가장 짧은 연결을 얻는 것이었지만, 모든 연결을 얻는 것은 제 생각에는 프로그래머에게는 성가신 일입니다. 이제 dijstra 알고리즘을 구현하는 아이디어를 생각해 냈습니다. 그러나 실제로는 너무 어렵습니다. 너희들이 나에게이 일을하는 법을 줄 수 있니? 우리는 이러한 유형을 사용할 필요가
type Country = String
type Countries = [Country]
type TravelTime = Integer -- Travel time in minutes
data Connection = Air Country Country TravelTime
| Sea Country Country TravelTime
| Rail Country Country TravelTime
| Road Country Country TravelTime deriving (Eq,Ord,Show)
type Connections = [Connection]
data Itinerary = NoRoute | Route (Connections,TravelTime) deriving (Eq,Ord,Show)
은 내 수율 경로 기능은 단순히 첫 번째 검색을 폭 (우리가 그들을 변경할 수 있지만, 우리는 새로운 유형을 추가 할 수 있습니다 OFC되지 않습니다.) : (SRY
yieldFastestRoute :: Connections -> Country -> Country -> Itinerary
Dijkst을 :
-- Liefert eine Route falls es eine gibt
yieldRoute :: Connections -> Country -> Country -> Connections
yieldRoute cons start goal
| isRoute cons start goal == False = []
| otherwise = getRoute cons start [] [start] goal
getRoute :: Connections -> Country -> Connections -> Countries -> Country -> Connections
getRoute cons c gone visited target
| (c == target) = gone
| otherwise = if (visit cons c visited) then (getRoute cons (deeper cons c visited) (gone ++ get_conn cons c (deeper cons c visited)) (visited ++ [(deeper cons c visited)]) target) else (getRoute cons (back (drop (length gone -1) gone)) (take (length gone -1) gone) visited target)
-- Geht ein Land zurück
back :: Connections -> Country
back ((Air c1 c2 _):xs) = c1
back ((Sea c1 c2 _):xs) = c1
back ((Rail c1 c2 _):xs) = c1
back ((Road c1 c2 _):xs) = c1
-- Liefert das nächste erreichbare Country
deeper :: Connections -> Country -> Countries -> Country
deeper ((Air c1 c2 _):xs) c visited
| (c1 == c) = if (c2 `elem` visited) then (deeper xs c visited) else c2
| (c2 == c) = if (c1 `elem` visited) then (deeper xs c visited) else c1
| otherwise = deeper xs c visited
deeper ((Sea c1 c2 _):xs) c visited
| (c1 == c) = if (c2 `elem` visited) then (deeper xs c visited) else c2
| (c2 == c) = if (c1 `elem` visited) then (deeper xs c visited) else c1
| otherwise = deeper xs c visited
deeper ((Rail c1 c2 _):xs) c visited
| (c1 == c) = if (c2 `elem` visited) then (deeper xs c visited) else c2
| (c2 == c) = if (c1 `elem` visited) then (deeper xs c visited) else c1
| otherwise = deeper xs c visited
deeper ((Road c1 c2 _):xs) c visited
| (c1 == c) = if (c2 `elem` visited) then (deeper xs c visited) else c2
| (c2 == c) = if (c1 `elem` visited) then (deeper xs c visited) else c1
| otherwise = deeper xs c visited
-- Liefert eine Connection zwischen zwei Countries
get_conn :: Connections -> Country -> Country -> Connections
get_conn [] _ _ = error "Something went terribly wrong"
get_conn ((Air c1 c2 t):xs) c3 c4
| (c1 == c3) && (c2 == c4) = [(Air c1 c2 t)]
| (c1 == c4) && (c2 == c3) = [(Air c1 c2 t)]
| otherwise = get_conn xs c3 c4
get_conn ((Sea c1 c2 t):xs) c3 c4
| (c1 == c3) && (c2 == c4) = [(Air c1 c2 t)]
| (c1 == c4) && (c2 == c3) = [(Air c1 c2 t)]
| otherwise = get_conn xs c3 c4
get_conn ((Road c1 c2 t):xs) c3 c4
| (c1 == c3) && (c2 == c4) = [(Air c1 c2 t)]
| (c1 == c4) && (c2 == c3) = [(Air c1 c2 t)]
| otherwise = get_conn xs c3 c4
get_conn ((Rail c1 c2 t):xs) c3 c4
| (c1 == c3) && (c2 == c4) = [(Air c1 c2 t)]
| (c1 == c4) && (c2 == c3) = [(Air c1 c2 t)]
| otherwise = get_conn xs c3 c4
-- Überprüft ob eine besuchbare Connection exestiert
visit :: Connections -> Country -> Countries -> Bool
visit [] _ _ = False
visit ((Air c1 c2 _):xs) c visited
| (c1 == c) = if (c2 `elem` visited) then (visit xs c visited) else True
| (c2 == c) = if (c1 `elem` visited) then (visit xs c visited) else True
| otherwise = visit xs c visited
visit ((Sea c1 c2 _):xs) c visited
| (c1 == c) = if (c2 `elem` visited) then (visit xs c visited) else True
| (c2 == c) = if (c1 `elem` visited) then (visit xs c visited) else True
| otherwise = visit xs c visited
visit ((Rail c1 c2 _):xs) c visited
| (c1 == c) = if (c2 `elem` visited) then (visit xs c visited) else True
| (c2 == c) = if (c1 `elem` visited) then (visit xs c visited) else True
| otherwise = visit xs c visited
visit ((Road c1 c2 _):xs) c visited
| (c1 == c) = if (c2 `elem` visited) then (visit xs c visited) else True
| (c2 == c) = if (c1 `elem` visited) then (visit xs c visited) else True
이 하나) 독일어 의견을 내가 지금 작성해야 라 알고리즘 : http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
내 첫 번째 방법이 있었다 : 나는 기본적으로 가장 좋은 방법은 하스켈에서 익스트라을 구현하기 위해 무슨 알고 싶어
yieldFastestRoute :: Connections -> Country -> Country -> Itinerary
yieldFastestRoute cons start targ
|(isRoute start targ == False) = NoRoute
|otherwise = (Route (getFastest (getAllRoutes cons start targ)) (sumTT (getFastest (getAllRoutes cons start targ))))
-- Liefert alle Routen zwischen zwei Ländern
getAllRoutes :: Connections -> Country -> Country -> [Connections]
-- Liefert aus einer Reihe von Connections die schnellste zurück
getFastest :: [Connections] -> Connections
getFastest (x:xs) = if ((sumTT x) < sumTT (getFastest xs) || null (getFastest xs)) then x else (getFastest xs)
sumTT :: Connections -> TravelTime
sumTT [] = 0
sumTT ((Air _ _ t): xs) = t ++ sumTT xs
sumTT ((Rail _ _ t): xs) = t ++ sumTT xs
sumTT ((Road _ _ t): xs) = t ++ sumTT xs
sumTT ((Sea _ _ t): xs) = t ++ sumTT xs
경우, 또는 (I 내가 getallRoutes 문제가 있었다 말했듯이) 내가 따를 수있는 또 다른 접근법이있다.
1. Dijkstra 알고리즘이란 무엇입니까? 2. 구현 시도를 보여주십시오. 3. 당신이 어려운 부분을 구현하는 부분을 명확히하십시오. – dave4420
나는 haskell에서 dijstra를 구현하는 데 극단적으로 어려운 방법이 없거나 문제를 해결하기 위해 좀 더 쉽게 접근 할 수 있기를 원한다면 : http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm –
나는이 질문을 적절한 그래프 데이터 구조를 만드는 방법을 묻는 데 중점을두면 더 잘 대답 할 수 있습니다. 그 후에, Dijkstra를 구현하는 것이 어렵지 않아야합니다. 또한 당신은 코드 톤을 가지고 있으며, 그것은 특히 독일어 의견과 함께 삼키는 것이 조금 어렵습니다 – hugomg