Ebooks, Audobooks and Classical Music from Liber Liber
a b c d e f g h i j k l m n o p q r s t u v w x y z





Web - Amazon

We provide Linux to the World


We support WINRAR [What is this] - [Download .exe file(s) for Windows]

CLASSICISTRANIERI HOME PAGE - YOUTUBE CHANNEL
SITEMAP
Audiobooks by Valerio Di Stefano: Single Download - Complete Download [TAR] [WIM] [ZIP] [RAR] - Alphabetical Download  [TAR] [WIM] [ZIP] [RAR] - Download Instructions

Make a donation: IBAN: IT36M0708677020000000008016 - BIC/SWIFT:  ICRAITRRU60 - VALERIO DI STEFANO or
Privacy Policy Cookie Policy Terms and Conditions
Algorytm Prima - Wikipedia, wolna encyklopedia

Algorytm Prima

Z Wikipedii

Algorytm Prima lub Algorytm Dijkstry-Prima wyznacza tzw. minimalne drzewo rozpinające. Mając do dyspozycji graf spójny i nieskierowany, tzn. taki w którym dla każdych dwóch wierzchołków grafu istnieje droga pomiędzy nimi oraz krawędzie grafu nie mają ustalonego kierunku, nasuwa się pytanie o podzbiór V' zbioru krawędzi V, dla którego graf nadal pozostaje spójny, ale suma kosztów wszystkich krawędzi zbioru V' ma najmniejszą możliwą wartość.

Grafy zawierające dużo krawędzi, w których dwa te same wierzchołki połączone są np. trzema krawędziami lub pomiędzy dwoma wierzchołkami istnieje np. 5 różnych dróg długości 2, raczej nie są "lubiane" przez algorytmy i często przekształcenie takiego skomplikowanego grafu w graf mu równoważny pod względem zachowania możliwych połączeń przynosi znaczące korzyści.

Algorytm Prima wygląda tak:

  • utwórz drzewo zawierające jeden wierzchołek, dowolnie wybrany z grafu
  • utwórz zbiór zawierający wszystkie krawędzie grafu
  • powtarzaj, aż każda z pozostałych w zbiorze krawędzi będzie łączyła dwa wierzchołki drzewa:
    • usuń ze zbioru krawędź o najmniejszej wadze, łączącą wierzchołek z drzewa z wierzchołkiem spoza drzewa
    • dodaj tę krawędź do drzewa

Złożoność obliczeniowa (m to liczba krawędzi a n to liczba wierzchołków):

  • przy użyciu kopca binarnego: O(m log(n))
  • przy użyciu kopca Fibonacciego O(m + n log(n)), co przy dużej gęstości grafu (takiej, że m jest ω(n log (n)) oznacza duże przyśpieszenie


[edytuj] Zobacz też


Przykładowa implementacja w Pascalu:

{
DANE:
 n - liczba wierzchołków grafu
 a - graf spójny i nieskierowany - tablica wskaźników na listy krawędzi incydentnych
 a[i] - adres pierwszej krawędzi incydentnej z wierzchołkiem grafu "i"
 elementem listy opisującym krawędź jest rekord zawierający trzy pola:
 wezel - numer wierzchołka grafu połączonego krawędzią
 koszt - koszt tej krawędzi
 nast  - adres następnego składnika listy
 wszystkie krawędzie grafu powinny mieć nieujemne koszty
 z - tablica, w której zapisano informację o zrobionych wierzchołkach grafu
 z[i]=prawda, gdy wierzchołek "i" został już dołączony do minimalnego drzewa rozpinającego

WYNIK:
 minimalne drzewo rozpinające "b" grafu "a"

Zaznacz wybrany wierzchołek - niech będzie to wierzchołek 1 - jako dołączony do minimalnego drzewa rozpinającego (zrobiony)
Dla wszystkich wierzchołków j incydentnych z wierzchołkiem 1:
jeżeli wierzchołek j nie został jeszcze zrobiony, to krawędź prowadzącą do tego wierzchołka dodaj do kopca
Dopóki kopiec nie jest pusty wykonuj następujące czynności:
Jeżeli krawędź o najmniejszym koszcie w kopcu prowadzi do wierzchołka jeszcze nie zrobionego, to wykonaj następujące czynności:
Dodaj tą krawędź do minimalnego drzewa rozpinającego
Zaznacz wierzchołek i, do którego prowadzi krawędź jako zrobiony
Usuń z kopca krawędź prowadzącą do wierzchołka i
Dla wszystkich wierzchołków j incydentnych z wierzchołkiem i:
 Jeżeli wierzchołek j nie został jeszcze dołączony do minimalnego drzewa rozpinającego, to dołącz krawędź [i, j] do kopca
 Jeżeli krawędź prowadzi do wierzchołka już dołączonego do minimalnego drzewa rozpinającego, to usuń ją z kopca
}

type
 WKrawedzGrafu = ^KrawedzGrafu;
 KrawedzGrafu = record
  wezel : integer;
  koszt : integer;
  nast : WKrawedzGrafu;
 end;

Graf = array[1..20] of WKrawedzGrafu;

WezelKopca = record
 odwezla : integer;
 dowezla : integer;
 koszt : integer;
end;

Kopiec = array[1..100] of WezelKopca;

Procedure Zamien(var a, b : WezelKopca);
 var
  tmp : WezelKopca;

 begin
  tmp := a;
  a := b;
  b := tmp;
 end;

{ n - rozmiar kopca }
{ k - numer węzła   }
procedure Przywroc(Var a : Kopiec; n, k : integer);
 var
  rodzic, potomek : integer;

 begin
  { Przywróć strukturę ku górze, do korzenia }
  potomek := k;
  rodzic := potomek div 2;
  while (rodzic > 0) and (a[rodzic].koszt > a[potomek].koszt) do
   begin
    zamien(a[rodzic], a[potomek]);
    potomek := rodzic;
    rodzic := potomek div 2;
   end;

  { Przywróć strukturę ku dołowi, od korzenia }
  rodzic := k;
  potomek := 2 * rodzic;

  while potomek <= n do
   begin
   if (potomek<n) And (a[potomek].koszt>a[potomek+1].koszt) then Inc(potomek);
   if a[potomek].koszt<a[rodzic].koszt then
    begin
     zamien(a[rodzic], a[potomek]);
     rodzic := potomek;
     potomek := 2 * rodzic;
    end
   else
    break;
  end;
 end;

{ Dodaj do kopca krawędź grafu }
{ n - rozmiar kopca            }
procedure DoKopca(var a : Kopiec; var n : integer; odwezla, dowezla, koszt : integer);
 begin
  inc(n);
  a[n].odwezla := odwezla;
  a[n].dowezla := dowezla;
  a[n].koszt := koszt;
  przywroc(a, n, n);
 end;

{ Usuń z kopca jego korzeń }
procedure ZKopca(var a : Kopiec; var n : integer);
 begin
  zamien(a[1], a[n]);
  dec(n);
  przywroc(a, n, 1);
 end;

Procedure DodajKrawedz(var a : Graf; odwezla, dowezla, koszt : integer);
 var
  tmp : WKrawedzGrafu;

 begin
  new(tmp);
  tmp^.wezel := dowezla;
  tmp^.koszt := koszt;
  tmp^.nast := a[odwezla];
  a[odwezla] := tmp;
  new(tmp);
  tmp^.wezel := odwezla;
  tmp^.koszt := koszt;
  tmp^.nast := a[dowezla];
  a[dowezla] := tmp;
 end;

{ Przekształć graf "a" w min. drzewo rozpinające "b" }
{ n - ilość wierzchołków grafu                       }
procedure GenerujGraf(var a, b : Graf; n : integer);
 var
  i : integer;
  k : Kopiec;
  ck : integer;
  ptr : WKrawedzGrafu;
  z : array[1..20] of boolean;

 begin
  ck := 0;
  for i := 1 to n do
   begin
    b[i] := nil;
    z[i] := false;
   end;

  ptr := a[1];
  z[1] := true;
  while ptr <> nil Do
   begin
    if not z[ptr^.wezel] then
     DoKopca(k, ck, 1, ptr^.wezel, ptr^.koszt);
    ptr := ptr^.nast;
   end;

  while ck > 0 Do
   begin
    if not z[k[1].dowezla] then
     begin
      i := k[1].dowezla;
      DodajKrawedz(b, k[1].odwezla, k[1].dowezla, k[1].koszt);
      ZKopca(k, ck);
      z[i] := true;
      ptr := a[i];

      while ptr <> nil do
       begin
        if not z[ptr^.wezel] then
         DoKopca(k, ck, i, ptr^.wezel, ptr^.koszt);
        ptr := ptr^.nast;
       end;
     end
    else
     ZKopca(k, ck);
  end;
 end;

var
 i, n : integer;
 a, b : Graf;
 ptr : WKrawedzGrafu;

 begin
  n := 6;
  for i := 1 to n do
  a[i] := nil;

  DodajKrawedz(a, 1, 2, 13);
  DodajKrawedz(a, 1, 3, 2);
  DodajKrawedz(a, 1, 4, 6);
  DodajKrawedz(a, 2, 4, 5);
  DodajKrawedz(a, 2, 5, 1);
  DodajKrawedz(a, 2, 6, 5);
  DodajKrawedz(a, 3, 4, 3);
  DodajKrawedz(a, 3, 5, 15);
  DodajKrawedz(a, 4, 2, 1);
  DodajKrawedz(a, 4, 5, 10);
  DodajKrawedz(a, 5, 2, 2);

  GenerujGraf(a, b, n);

  writeln('Minimalne drzewo rozpinające :');
  for i := 1 to n do
   begin
    ptr := b[i];
     while ptr <> nil do
      begin
       if i <= ptr^.wezel then
        writeln(i, ' -> ', ptr^.wezel, ' - ', ptr^.koszt);
       ptr := ptr^.nast;
      end;
   end;

  readln;
 end.
Our "Network":

Project Gutenberg
https://gutenberg.classicistranieri.com

Encyclopaedia Britannica 1911
https://encyclopaediabritannica.classicistranieri.com

Librivox Audiobooks
https://librivox.classicistranieri.com

Linux Distributions
https://old.classicistranieri.com

Magnatune (MP3 Music)
https://magnatune.classicistranieri.com

Static Wikipedia (June 2008)
https://wikipedia.classicistranieri.com

Static Wikipedia (March 2008)
https://wikipedia2007.classicistranieri.com/mar2008/

Static Wikipedia (2007)
https://wikipedia2007.classicistranieri.com

Static Wikipedia (2006)
https://wikipedia2006.classicistranieri.com

Liber Liber
https://liberliber.classicistranieri.com

ZIM Files for Kiwix
https://zim.classicistranieri.com


Other Websites:

Bach - Goldberg Variations
https://www.goldbergvariations.org

Lazarillo de Tormes
https://www.lazarillodetormes.org

Madame Bovary
https://www.madamebovary.org

Il Fu Mattia Pascal
https://www.mattiapascal.it

The Voice in the Desert
https://www.thevoiceinthedesert.org

Confessione d'un amore fascista
https://www.amorefascista.it

Malinverno
https://www.malinverno.org

Debito formativo
https://www.debitoformativo.it

Adina Spire
https://www.adinaspire.com