Menu
Coddy logo textTech

Algorytm Prima

Ostatnia aktualizacja

Algorytm Prima buduje minimalne drzewo rozpinające (MST), czyli najtańszy zbiór krawędzi łączący wszystkie węzły bez cykli, rozbudowując jedno drzewo od węzła startowego. W każdym kroku sprawdza każdą krawędź prowadzącą z drzewa do węzła spoza niego i dodaje najtańszą. Kliknij odtwarzanie powyżej i zobacz, jak drzewo się rozrasta, zawsze biorąc krawędź o najmniejszej wadze, która prowadzi do nowego węzła.

Ponieważ algorytm zawsze wybiera najtańszą krawędź przekroju, każde dodanie jest bezpieczne (na pewno należy do jakiegoś MST). Z kolejką priorytetową opartą na kopcu binarnym, w której kluczem jest najtańsza krawędź do każdego zewnętrznego węzła, algorytm Prima działa w O(E log V). Różni się od algorytmu Kruskala, który sortuje globalnie wszystkie krawędzie, zamiast rozbudowywać jedno spójne drzewo.

Złożoność czasowa i pamięciowa

ImplementacjaZłożonośćUwagi
Kopiec binarnyO(E log V)Kolejka priorytetowa krawędzi przekroju
Macierz sąsiedztwaO(V²)Prostsza; dobra dla gęstych grafów
PamięćO(V + E)Przynależność do drzewa + kolejka priorytetowa
Najlepszy dlaGrafów gęstychRośnie od jednego węzła startowego

Krok po kroku

KrokCo się dzieje
1Zacznij drzewo od dowolnego pojedynczego węzła.
2Sprawdź wszystkie krawędzie prowadzące z drzewa do węzła spoza niego.
3Wybierz krawędź przekroju o najmniejszej wadze.
4Dodaj tę krawędź i jej nowy węzeł do drzewa.
5Powtarzaj, aż każdy węzeł będzie w drzewie.

Przykład krok po kroku

Budowanie MST grafu z 4 węzłami i krawędziami A-B=1, A-C=3, B-C=2, B-D=4, C-D=5, zaczynając od A:

KrokDrzewoKrawędzie przekrojuWybrana krawędź
1{A}A-B=1, A-C=3A-B (waga 1)
2{A, B}A-C=3, B-C=2, B-D=4B-C (waga 2)
3{A, B, C}B-D=4, C-D=5B-D (waga 4)
4{A, B, C, D}brak: wszystkie węzły w drzewiekoniec: waga MST 1+2+4 = 7

Kiedy używać algorytmu Prima

Używaj, gdyUnikaj, gdy
Potrzebujesz minimalnego drzewa rozpinającego spójnego, nieskierowanego grafu ważonego.Graf jest skierowany albo potrzebujesz najkrótszych ścieżek: użyj algorytmu Dijkstry lub Bellmana-Forda.
Graf jest gęsty (E bliskie V²); wersja macierzowa O(V²) jest prosta i szybka.Graf jest rzadki, a krawędzie są już posortowane lub łatwo je posortować: algorytm Kruskala jest często prostszy.
Chcesz, aby drzewo rosło od jednego obszaru na zewnątrz (np. przyrostowy układ sieci).Graf jest niespójny: algorytm Prima obejmuje tylko jedną składową, a potrzebujesz minimalnego lasu rozpinającego.
Masz już strukturę sąsiedztwa i kolejkę priorytetową.Musisz wykrywać cykle w globalnym zbiorze krawędzi: union-find (Kruskal) lepiej do tego pasuje.

Prim's Algorithm: kod

Przejrzysta, gotowa do uruchomienia implementacja algorytmu Prim's Algorithm w językach: Python, JavaScript, Java, C++, C. Wybierz język, skopiuj kod albo otwórz go od razu w edytorze online Coddy.

Prim's Algorithm: kod (Python)

Python
1import heapq2
3
4def prim(graph, start):5    visited = {start}6    heap = [(w, start, v) for v, w in graph[start]]7    heapq.heapify(heap)8    mst, total = [], 09    while heap and len(visited) < len(graph):10        w, u, v = heapq.heappop(heap)11        if v in visited:12            continue13        visited.add(v)14        mst.append((u, v, w))15        total += w16        # Offer the new node's edges to the frontier17        for neighbor, weight in graph[v]:18            if neighbor not in visited:19                heapq.heappush(heap, (weight, v, neighbor))20    return mst, total21
22
23graph = {24    "A": [("B", 4), ("C", 1)],25    "B": [("A", 4), ("C", 3), ("D", 2)],26    "C": [("A", 1), ("B", 3), ("D", 5)],27    "D": [("B", 2), ("C", 5), ("E", 7)],28    "E": [("D", 7)],29}30
31mst, total = prim(graph, "A")32for u, v, w in mst:33    print(f"{u} - {v} (weight {w})")34print("Total MST weight:", total)
Uruchom ten kod w edytorze Python online

Algorytm Prima: najczęstsze pytania

Jaka jest złożoność czasowa algorytmu Prima?
Z kolejką priorytetową opartą na kopcu binarnym algorytm Prima działa w O(E log V). Prostsza wersja z macierzą sąsiedztwa, która w każdym kroku szuka najtańszej krawędzi przekroju, ma złożoność O(V²) i w gęstych grafach może być szybsza. Obie zużywają O(V + E) pamięci.
Czym różni się algorytm Prima od algorytmu Kruskala?
Oba zachłannie znajdują minimalne drzewo rozpinające. Algorytm Prima rozbudowuje jedno spójne drzewo od węzła startowego, wielokrotnie dodając najtańszą krawędź wychodzącą z drzewa (z użyciem kolejki priorytetowej). Algorytm Kruskala rozważa wszystkie krawędzie posortowane według wagi i dodaje najtańszą, która nie tworzy cyklu (z użyciem union-find). Prim jest często preferowany w grafach gęstych, a Kruskal w rzadkich.
Czy algorytm Prima zawsze znajduje optymalne MST?
Tak. W każdym kroku najtańsza krawędź przekroju bieżącego drzewa jest bezpieczna do dodania: należy do jakiegoś minimalnego drzewa rozpinającego (własność przekroju). Wielokrotne dodawanie bezpiecznych krawędzi daje prawdziwe minimalne drzewo rozpinające, o ile graf jest spójny.
Kiedy użyć algorytmu Prima zamiast algorytmu Kruskala?
Sięgnij po algorytm Prima, gdy graf jest gęsty, bo jego wersja z macierzą sąsiedztwa O(V²) nie sortuje wszystkich E krawędzi i rozbudowuje jedno drzewo od węzła startowego. Kruskal błyszczy w grafach rzadkich, gdzie sortowanie listy krawędzi jest tanie, a union-find przyspiesza sprawdzanie cykli. Oba dają poprawne MST, więc wybór zależy głównie od gęstości krawędzi i struktur danych, które już masz.
Czy węzeł startowy wpływa na wynikowe MST?
Nie. Łączna waga MST jest taka sama niezależnie od węzła startowego, bo waga minimalnego drzewa rozpinającego spójnego grafu jest jednoznaczna. Konkretne krawędzie mogą się różnić tylko wtedy, gdy kilka krawędzi ma tę samą wagę i istnieje wiele MST. W przeciwnym razie algorytm Prima dochodzi do dokładnie tego samego drzewa bez względu na węzeł startowy.
Czy algorytm Prima obsługuje grafy niespójne?
Nie bezpośrednio. Algorytm Prima rozbudowuje jedno drzewo, więc obejmuje tylko spójną składową zawierającą węzeł startowy, a resztę pomija. Aby objąć każdą składową, trzeba wielokrotnie uruchamiać go od nieodwiedzonego węzła, co daje minimalny las rozpinający zamiast jednego drzewa.
Ilustracja języków programowania w Coddy

Opanuj algorytmy z Coddy

ZACZNIJ