[ Prostředí ] [ Jarníkův alg. ] [ Borůvkův alg. ] [ Topologické uspořádání ] [ Hledání komponent ] [ Nejkratší cesty ]

Algoritmus pro vyhledávání souvislých (silně souvislých) komponent za použití Floydova algoritmu
Michal Radecký, L97085

Princip algoritmu
     Algoritmus je založen na zpracování výsledků Floydova algoritmu. Tj. z matice dosažitelnosti určí jednotlivé komponenty.
     Nejprve je tedy nutné na zadaný graf aplikovat Floydův algoritmus, který z matice cen, vytvoří matici dosažitelnosti. V našem případě, je zbytečné pracovat s kompletní maticí cen, a je postačující pracovat s maticí, kde jsou ceny nahrazeny jedničkou.
     Po vytvoření této matice pak aplikujeme algoritmus zařazování vrcholů do komponent. Tento algoritmus je založen na zjišťování dosažitelných vrcholů z výchozího vrcholu a naopak, dosažitelnost z dosažených vrcholů zpět do výchozího vrcholu. Je-li tato podmínka splněna, je dosažený vrchol zařazen do stejné komponenty, jako byl vrchol výchozí. Algoritmus končí, jakmile jsou všechny vrcholy zařazeny do některé z komponent.

Implementace algoritmu
     Vlastní implementace je v jedné funkci, která jako vstupní parametr dostává celou strukturu grafu a alokovane pole, a jak výsledek vrací ukazatel na pole, které k jednotlivým vrcholům přiřazuje číslo příslušné komponenty. Vzhledem k předávání dat, jsou vráceny čísla komponent postupně, nikoliv podle čísla vrcholů
     Jako první krok je vytvoření matice A, jako dvojrozměrného dynamického pole o rozměrech [počet vrcholů][počet vrcholů]. Dále je toto pole inicializováno na počáteční hodnotu (všechny prvky jsou X, hlavní diagonála pak 0). Nakonec je podle struktury grafu jednotlivým prvkům přiřazena hodnota (viz.výše).
     Dalším krokem je vytvoření matice dosažitelnosti, to je provedeno pomocí tří vnořených cyklů a trojůhelníkové nerovnosti.
     Poslední část algoritmu potřebuje ke své činnosti ještě vytvořené pole K o velikosti [počet vrcholů]. Prvky tohoto pole se inicializují na hodnotu X. Dále se vybere první prvek, jehož hodnota v K je X. Pak se prochází řádek matice odpovídající vybranému vrcholu a kontroluje se, jestli jsou vrcholy dosažitelné z vybraného vrcholu a zpět. Platí-li to, je zkoumaný vrchol v poli K označen číslem komponenty. Tato část algoritmu je uzavřena v cyklu, který probíhá tak dlouho, dokud počítadlo zařazených vrcholů není rovno počtu vrcholů.

     Funkce se tedy volá:
                                                           ukazatel = Funkce(Graf);
    , kde ukazatel je ty pointer na int a Graf je ukazatel na strujturu grafu (TGraf).
     Po provedení funkce je tedy ukazatel nastaven na první prvek dynamicky vytvořeného pole K a je nutné ho po zpracovácní dealokovat příkazem
                                                           delete [počet vrcholů]ukazatel;

Zdrojový kód
#define X 10000 //nedosazitelny vrchol, zatim nezakomponentovany vrchol musi byt hodne velke int cislo

int *Funkce(TGraf *graf, int *K)
{
int i,j,k; //pomocne
int **A; //matice cen

//dynamicka inicializace matice
A = new int*[graf->nvrch];
for (i=0;i<(graf->nvrch);i++)
   A[i]= new int[graf->nvrch];

//naplneni matice
for(i=0;i<(graf->nvrch);i++)
   for(j=0;j<(graf->nvrch);j++)
      A[i][j]=X; //nejprve jsou vsechny vrcholy nedosazitelne
for(i=0;i<(graf->nvrch);i++)
   A[i][i]=0; //na diagonale nuly
for(i=0;i<(graf->nhran);i++)
   A[graf->phran[i].pv-1][graf->phran[i].kv-1]=1; //existujici hrany

//Floyduv algoritmus pro urceni dosazitelnosti
for(k=0;k<(graf->nvrch);k++)
   for(i=0;i<(graf->nvrch);i++)
      for(j=0;j<(graf->nvrch);j++)
         if(A[i][j]>(A[i][k]+A[k][j])) A[i][j]=A[i][k]+A[k][j];  //trojuhelnikova nerovnost

//algoritmus pro zarazovani vrcholu do komponentu
for(i=0;i<(graf->nvrch);i++) K[i]=X; //inicializace, vsechny vrcholy jsou nezarazene
int pocet_zakomp=0; //pocitadlo jiz zarazenych vrcholu, slouzi k urceni ukonceni cyklu
int cislo_komp=0; //pocitadlo aktualniho cisla komponenty
int vyb_vrch; //aktualni vrchol - vychozi

while(pocet_zakomp<(graf->nvrch)) //dokud nejsou zarazeny vsechny
{
   for(i=0;i<(graf->nvrch);i++) if (K[i]==X) {cislo_komp++;vyb_vrch=i;i=graf->nvrch;}
                                       //nalezeni prvniho nezarazeneho vrcholu
   K[vyb_vrch]=cislo_komp; //zarazeni vrcholu do komponenty
   pocet_zakomp++;
   for(i=0;i<(graf->nvrch);i++) //cyklus pro kontrolu dosazitelnosti z vybraneho
        //vrcholu a zpet
      if((A[vyb_vrch][i]!=0)&&(A[vyb_vrch][i]!=X)&&(A[i][vyb_vrch]!=0)&&(A[i][vyb_vrch]!=X))
      {
          K[i]=cislo_komp; //je-li vrchol dosazitelny z vybraneho a naopak,
                                      //je zarazen do komponenty vybraneho vrcholu
          pocet_zakomp++;
      }
}//konec while

return K;

//funkce vraci ukazatel na pole, jehoz velikost je pocet vrcholu v grafu
//a jednotlive hodnoty symbolizuji cislo komponenty tj. 1,1,2,3 atd.

}


[ Prostředí ] [ Jarníkův alg. ] [ Borůvkův alg. ] [ Topologické uspořádání ] [ Hledání komponent ] [ Nejkratší cesty ]