Advertisement
Lucky_Dummy

Prim algorithm for MST

May 18th, 2023 (edited)
2,366
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Haskell 2.39 KB | Source Code | 0 0
  1. import Data.List
  2.  
  3. -- В graph на каждом шагу будем хранить ребра, у которых хотя бы одна вершина НЕ содержиться в текущем MST (Minimal Spanning Tree)
  4. -- Также будем поддерживать список ребёр в MST и список неприсоединённых к MST вершин
  5. -- На каждом шагу выбираем ребро минимального веса, среди смежных с текущим MST, за начальное ребро берём наименьшее среди всех
  6. prim :: (Ord c, Eq a) => [(a, a, c)] -> [(a, a, c)]
  7. prim [] = []
  8. prim graph = primH (tail sortedEdges) mst unvisited where -- Основная функция, подготавливает данные для вспомогательной
  9.   sortedEdges = nub $ sortBy (\(_, _, w1) (_, _, w2) -> compare w1 w2) graph -- Сортируем ребра по весу и удаляем дубликаты
  10.   mst = [head sortedEdges] -- Добавляем первое ребро в MST
  11.   unvisited = foldl (flip delete) (nub $ concatMap getVertices graph) (getVertices $ head mst) -- Создаем список неприсоединённых к MST вершин
  12.   primH graph mst unvisited -- Вспомогательная функция, рекурсивно выполняет шаги алгоритма
  13.       | null graph = mst
  14.       | null unvisited = mst
  15.       | otherwise = primH newGraph newMst newUnvisited where
  16.         (from, to, weight) = head (filter (\(x, y, _) -> notElem x unvisited || notElem y unvisited) graph) -- Берём ребро с наименьшим весом, соединённое с MST
  17.         newMst = (from, to, weight) : mst -- Добавляем это ребро в MST
  18.         newUnvisited = foldl (flip delete) unvisited [from, to] -- Удаляем вершину из непосещённых
  19.         newGraph = filter (\(x, y, _) -> elem x newUnvisited || elem y newUnvisited) graph -- Убираем из списка ребёр, те что соединяют вершины из MST
  20.   getVertices (x, y, _) = [x, y] -- Функция для получения списка вершин некоторого ребра  
  21.  
  22. graph :: [(Int, Int, Int)]
  23. graph = [(1, 2, 2), (1, 3, 5), (2, 3, 1), (2, 4, 6), (2, 5, 3), (3, 5, 1), (4, 5, 3)]
  24.  
  25. main :: IO ()
  26. main = print $ prim graph
Tags: Haskell
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement