Grafy
Grafy a jejich reprezentace
 Vytisknout studijní materiál

Grafy a jejich reprezentace

Stromy vyjadřují nějakou hierarchii vztahů. Velice obecným prostředkem pro modelování vztahů mezi prvky jsou grafy. Prvky jsou vrcholy grafu a vztahy mezi nimi vyjadřujeme jejich spojením - hranami. Příkladem může být graf počítačové sítě CESNET na obr.. Města jsou vrcholy a hrany znázorňují jejich spojení komunikačními linkami. Grafy nemusí znázorňovat jenom prostorové vztahy, ale například i časové, logické ap.

Formálně je graf dvojice G = (V, H), kde V je množina vrcholů (uzlů) a H je množina hran, přičemž hrana je dvojice (u,v) u,vÎV. Počet vrcholů grafu G pak je |V| a počet jeho hran je |H|. Množinu vrcholů grafu G budeme zapisovat V(G) a množinu jeho hran H(G).

Platí-li (u,v) ≠ (v,u) je hrana orientovaná, tj. má začáteční a koncový vrchol. Takový graf nazýváme orientovaný a jsou v nich možné hrany z vrcholu do téhož vrcholu. Příklad orientovaného grafu je na obr.. Pro tento graf je

V = { 1, 2, 3, 4, 5, 6 }                                     |V| = 6

H = { (1,2) (1,6) (2,5) (3,5) (4,4) (5,6) (6,2) }      |H| = 7

Stupeň vrcholu orientovaného grafu je dán součtem počtu hran do něj vstupujících a počtu hran z něj vystupujících. Například stupeň vrcholu 2 na obr. je 3.

V opačném případě (u,v) = (v,u) a graf se nazývá neorientovaný, přičemž budeme požadovat u ≠ v. Příklad neorientovaného grafu je na obr.. Pro tento graf je

V = { 1, 2, 3, 4, 5, 6 }                                          |V| = 6

H = { (1,2), (1,6), (2,3), (2,5), (2,6), (3,5), (5,6) }     |H| = 7

V neorientovaném grafu je stupeň vrcholu dán počtem incidentních hran, tj. hran, kterých je vrchol součástí. Například stupeň vrcholu 2 na obr. je 4.

Reprezentace grafu

Dva standardní způsoby v informatice pro reprezentaci grafu jsou

Oba způsoby jsou použitelné pro orientované i neorientované grafy.

Seznamy sousednosti

Pro každý vrchol grafu G = (V, H) je vytvořen seznam sousedů. Seznam sousedů pro vrchol u Î V obsahuje všechny vrcholy v, pro které je (u,v)ÎH. Sousedící vrcholy jsou obecně uloženy v seznamech v libovolném pořadí.

Příklad reprezentace orientovaného grafu z obr. seznamy sousednosti je na obr.. Celková délka seznamů sousednosti pro orientovaný graf je zřejmě |H|.

Příklad reprezentace neorientovaného grafu z obr. seznamy sousednosti je na obr.. Celková délka seznamů sousednosti pro orientovaný graf je zřejmě 2|H|, protože je-li hrana (u,v)Î H, potom v je v seznamu sousedů u a u je v seznamu sousedů v. Požadovaná velikost paměti tedy v obou případech je Θ(|V| + |H|).

Implementace reprezentace grafu seznamy sousednosti potom bude tvořena polem vrcholy, kterého prvky reprezentují vrcholy grafu.

Vrchol[ ] vrcholy = new Vrchol [|V|];

V objektech třídy Vrchol jsou uložena data vrcholu a ukazatel sousedi. Tento obsahuje odkaz na prvního souseda seznamu sousedů anebo null, když vrchol nemá sousedy.

class Vrchol {

...

Soused sousedi;

Vrchol ( ) {

...

sousedi = null;

}

}

Objekty třídy Soused obsahují číslo vrcholu, tj. jeho index v poli vrcholy, a ukazatel dalsi na dalšího souseda.

class Soused {

int vrchol;

Soused dalsi;

Soused (int v) {

    ...

    vrchol = v;

    dalsi = null;

}

}

Hrany grafu pak budou vytvářeny metodou hrana( ) tak, že vytvoříme objekt třídy Soused obsahující vrchol, do kterého hrana vede a vložíme ho do seznamu sousedů vrcholu, z kterého hrana vychází.

void hrana(int z, int kam) {

    Soused s = new Soused(kam);

    s.dalsi = vrcholy[z].sousedi;

    vrcholy[z].sousedi = s;

}

Poznamenejme, že vzhledem k tomu, že jsme řekli, že na pořadí sousedů v jejich seznamu nezáleží, sousedy vkládáme přímo na začátek jejich seznamu.

Reprezentace seznamem sousednosti je vhodná i pro ohodnocené grafy. Ohodnocením grafu G se nazývá funkce

w: H(G) -> R

Je-li (u,v)ÎH(G), w(u,v) se uloží ve vrcholu v seznamu sousedů vrcholu u. Příkladem může být ohodnocení hran reprezentujících počítačovou síť přenosovými rychlostmi.

Potenciální nevýhodou reprezentace grafu seznamy sousednosti je zjišťování existence hrany (u,v), což znamená hledat vrchol v v seznamu sousedů vrcholu u.

Matice sousednosti

Označme vrcholy čísly 1, …, |V|. Matice sousednosti je matice S = (sij ), i,j = 1, …, |V|, přičemž

je-li    (i,j)ÎH, sij = 1

jinak             sij = 0

Reprezentace orientovaného grafu z obr. maticí sousednosti je na obr. a reprezentace neorientovaného grafu z obr. maticí sousednosti je na obr.. Požadovaná paměť je Θ( |V |2), bez ohledu na počet hran. Pro neorientovaný graf je S = ST, kde ST je transponovaná matice, což umožňuje snížit nároky na paměť téměř na polovinu.

Další možností snížení nároků na paměť pro orientovaný i neorientovaný graf je uložení matice sousednosti v bitech, což však vyžaduje bitové operace.

Graf je při reprezentaci maticí sousednosti implementován dvourozměrným polem

int[ ][ ] s = new int [|V|] [|V|];

Maticí sousednosti lze implementovat i ohodnocený graf. Pro ohodnocený graf je

suv = w(u,v), je-li (u,v)ÎH(G),

suv   je hodnota mimo hodnot možných ohodnocení, není-li (u,v)ÎH(G).

Je-li   |H| << |V|2   graf se nazývá řídký a obvykle je vhodnější použít seznam sousednosti. Je-li   |H| ~ |V|2    graf se nazývá hustý a obvykle je vhodnější použít matici sousednosti. Matici sousednosti je vhodnější použít také, je-li nutno rychle zjistit existenci hrany.