W tym samouczku dowiesz się, jak działa algorytm Prim. Znajdziesz również działające przykłady algorytmu Prim w językach C, C ++, Java i Python.
Algorytm Prima to algorytm minimalnego drzewa rozpinającego, który przyjmuje graf jako dane wejściowe i znajduje podzbiór krawędzi tego grafu, który
- tworzą drzewo, które zawiera każdy wierzchołek
- ma minimalną sumę wag wszystkich drzew, które można utworzyć na podstawie wykresu
Jak działa algorytm Prim
Należy do klasy algorytmów zwanych algorytmami zachłannymi, które znajdują optimum lokalne w nadziei znalezienia optimum globalnego.
Zaczynamy od jednego wierzchołka i dodajemy krawędzie o najmniejszej wadze, aż osiągniemy nasz cel.
Kroki implementacji algorytmu Prim są następujące:
- Zainicjuj minimalne drzewo rozpinające z losowo wybranym wierzchołkiem.
- Znajdź wszystkie krawędzie łączące drzewo z nowymi wierzchołkami, znajdź minimum i dodaj je do drzewa
- Powtarzaj krok 2, aż uzyskamy minimalne drzewo opinające
Przykład algorytmu Prim






Pseudokod Algorytm Prima
Pseudokod algorytmu prim pokazuje, jak tworzymy dwa zbiory wierzchołków U i VU. U zawiera listę wierzchołków, które zostały odwiedzone, a VU listę wierzchołków, które ich nie miały. Jeden po drugim przenosimy wierzchołki z zestawu VU do zestawu U, łącząc krawędź o najmniejszej wadze.
T = ∅; U = ( 1 ); while (U ≠ V) let (u, v) be the lowest cost edge such that u ∈ U and v ∈ V - U; T = T ∪ ((u, v)) U = U ∪ (v)
Przykłady w Pythonie, Javie i C / C ++
Chociaż używana jest reprezentacja wykresów w postaci macierzy sąsiedztwa, algorytm ten można również zaimplementować za pomocą listy przyległości w celu poprawy jego wydajności.
Python Java C C ++ # Prim's Algorithm in Python INF = 9999999 # number of vertices in graph V = 5 # create a 2d array of size 5x5 # for adjacency matrix to represent graph G = ((0, 9, 75, 0, 0), (9, 0, 95, 19, 42), (75, 95, 0, 51, 66), (0, 19, 51, 0, 31), (0, 42, 66, 31, 0)) # create a array to track selected vertex # selected will become true otherwise false selected = (0, 0, 0, 0, 0) # set number of edge to 0 no_edge = 0 # the number of egde in minimum spanning tree will be # always less than(V - 1), where V is number of vertices in # graph # choose 0th vertex and make it true selected(0) = True # print for edge and weight print("Edge : Weight") while (no_edge G(i)(j): minimum = G(i)(j) x = i y = j print(str(x) + "-" + str(y) + ":" + str(G(x)(y))) selected(y) = True no_edge += 1
// Prim's Algorithm in Java import java.util.Arrays; class PGraph ( public void Prim(int G()(), int V) ( int INF = 9999999; int no_edge; // number of edge // create a array to track selected vertex // selected will become true otherwise false boolean() selected = new boolean(V); // set selected false initially Arrays.fill(selected, false); // set number of edge to 0 no_edge = 0; // the number of egde in minimum spanning tree will be // always less than (V -1), where V is number of vertices in // graph // choose 0th vertex and make it true selected(0) = true; // print for edge and weight System.out.println("Edge : Weight"); while (no_edge < V - 1) ( // For every vertex in the set S, find the all adjacent vertices // , calculate the distance from the vertex selected at step 1. // if the vertex is already in the set S, discard it otherwise // choose another vertex nearest to selected vertex at step 1. int min = INF; int x = 0; // row number int y = 0; // col number for (int i = 0; i < V; i++) ( if (selected(i) == true) ( for (int j = 0; j G(i)(j)) ( min = G(i)(j); x = i; y = j; ) ) ) ) ) System.out.println(x + " - " + y + " : " + G(x)(y)); selected(y) = true; no_edge++; ) ) public static void main(String() args) ( PGraph g = new PGraph(); // number of vertices in grapj int V = 5; // create a 2d array of size 5x5 // for adjacency matrix to represent graph int()() G = ( ( 0, 9, 75, 0, 0 ), ( 9, 0, 95, 19, 42 ), ( 75, 95, 0, 51, 66 ), ( 0, 19, 51, 0, 31 ), ( 0, 42, 66, 31, 0 ) ); g.Prim(G, V); ) )
// Prim's Algorithm in C #include #include #define INF 9999999 // number of vertices in graph #define V 5 // create a 2d array of size 5x5 //for adjacency matrix to represent graph int G(V)(V) = ( (0, 9, 75, 0, 0), (9, 0, 95, 19, 42), (75, 95, 0, 51, 66), (0, 19, 51, 0, 31), (0, 42, 66, 31, 0)); int main() ( int no_edge; // number of edge // create a array to track selected vertex // selected will become true otherwise false int selected(V); // set selected false initially memset(selected, false, sizeof(selected)); // set number of edge to 0 no_edge = 0; // the number of egde in minimum spanning tree will be // always less than (V -1), where V is number of vertices in //graph // choose 0th vertex and make it true selected(0) = true; int x; // row number int y; // col number // print for edge and weight printf("Edge : Weight"); while (no_edge < V - 1) ( //For every vertex in the set S, find the all adjacent vertices // , calculate the distance from the vertex selected at step 1. // if the vertex is already in the set S, discard it otherwise //choose another vertex nearest to selected vertex at step 1. int min = INF; x = 0; y = 0; for (int i = 0; i < V; i++) ( if (selected(i)) ( for (int j = 0; j G(i)(j)) ( min = G(i)(j); x = i; y = j; ) ) ) ) ) printf("%d - %d : %d", x, y, G(x)(y)); selected(y) = true; no_edge++; ) return 0; )
// Prim's Algorithm in C++ #include #include using namespace std; #define INF 9999999 // number of vertices in grapj #define V 5 // create a 2d array of size 5x5 //for adjacency matrix to represent graph int G(V)(V) = ( (0, 9, 75, 0, 0), (9, 0, 95, 19, 42), (75, 95, 0, 51, 66), (0, 19, 51, 0, 31), (0, 42, 66, 31, 0)); int main() ( int no_edge; // number of edge // create a array to track selected vertex // selected will become true otherwise false int selected(V); // set selected false initially memset(selected, false, sizeof(selected)); // set number of edge to 0 no_edge = 0; // the number of egde in minimum spanning tree will be // always less than (V -1), where V is number of vertices in //graph // choose 0th vertex and make it true selected(0) = true; int x; // row number int y; // col number // print for edge and weight cout << "Edge" << " : " << "Weight"; cout << endl; while (no_edge < V - 1) ( //For every vertex in the set S, find the all adjacent vertices // , calculate the distance from the vertex selected at step 1. // if the vertex is already in the set S, discard it otherwise //choose another vertex nearest to selected vertex at step 1. int min = INF; x = 0; y = 0; for (int i = 0; i < V; i++) ( if (selected(i)) ( for (int j = 0; j G(i)(j)) ( min = G(i)(j); x = i; y = j; ) ) ) ) ) cout << x << " - " << y << " : " << G(x)(y); cout << endl; selected(y) = true; no_edge++; ) return 0; )
Algorytm Prim kontra Kruskal
Algorytm Kruskala jest kolejnym popularnym algorytmem minimalnego drzewa rozpinającego, który wykorzystuje inną logikę do znalezienia MST grafu. Zamiast zaczynać od wierzchołka, algorytm Kruskala sortuje wszystkie krawędzie od małych do wysokich i dodaje najniższe krawędzie, ignorując te, które tworzą cykl.
Złożoność algorytmów Prima
Złożoność czasowa algorytmu Prim wynosi O(E log V)
.
Aplikacja algorytmu Prima
- Układanie kabli elektrycznych
- W zaprojektowanej sieci
- Tworzenie protokołów w cyklach sieciowych