algorytmy grafowe 2 - politechnika gdańskakaims.eti.pg.gda.pl/~jendrek/aketi/wyklad06.pdf ·...
TRANSCRIPT
Algorytmy grafowe 2
Andrzej Jastrz¦bski
Akademia ETI
Politechnika Gda«ska Algorytmy grafowe 2
Minimalne drzewo spinaj¡ce
Drzewem nazywamy spójny graf nie posiadaj¡cy cyklu. Liczbawierzchoªków drzewa jest o jeden wi¦ksza od liczby jego kraw¦dzi.Drzewem spinaj¡cym nazywamy podgraf grafu G , który jestdrzewem i zawiera wszystkie wierzchoªki grafu G .Je±li dany jest graf z wagami, to drzewo spinaj¡ce o najmniejszejsumie wag na kraw¦dziach b¦dziemy nazywali minimalnym drzewem
spinaj¡cym.
Politechnika Gda«ska Algorytmy grafowe 2
Algorytm Prima
minDrzewoPrim(Graf G) {
T - graf bez kraw¦dzi i wierzchoªków
Dodajemy do T dowolny wierzchoªek z G
while(|V(T)|<|V(G)|) {
szukamy najl»ejszej kraw¦dzi
pomi¦dzy wierzchoªkami z V(T) i V(G)/V(T)
dodajemy wyszukan¡ kraw¦d¹ wraz z incydentnym
wierzchoªkiem z V(G)/V(T) do grafu T
}
return T;
}
Politechnika Gda«ska Algorytmy grafowe 2
Alorytm Prima - szczegóªy implementacyjne
Najwa»niejsz¡ cz¦±ci¡, jest algorytm wyznaczania kolejnej -najl»ejszej kraw¦dzi pomi¦dzy wierzchoªkami z V(T) i V(G)/V(T).Mo»emy stworzy¢ kolejk¦ priorytetow¡ maj¡c¡ jako elementy: wag¦najl»ejszej kraw¦dzi do T oraz s¡siada (wierzchoªek) z T
poª¡czonego najl»ejsz¡ kraw¦dzi¡.
Stworzymy kolejk¦ priorytetow¡ na podstawie kopca.
Politechnika Gda«ska Algorytmy grafowe 2
Kolejka priorytetowa
struct Sasiad {
int idKolejka, prevWierz, waga;
Sasiad(): idKolejka(-1), prevWierz(0), waga(0) {}
};
B¦dziemy rozpatrywali tablic¦ struktur Sasiad.
idKolejka � wskazuje na miejsce w kopcu, gdzie znajduje si¦wierzchoªek;je±li idKolejka jest równa -1, to wierzchoªek jeszcze nieprzebywaª w kolejce priorytetowej;je±li idKolejka jest równa -2, to wierzchoªek byª ju» w kolejcepriorytetowej;
waga � waga najl»ejszej kraw¦dzi, która ª¡czy wierzchoªekopisany przez struktur¦ Sasiad z wierzchoªkiem z grafu T;
prevWierz � wskazuje na wierzchoªek z grafu T, którys¡siaduje z wierzchoªkiem opisanym przez struktur¦ Sasiad
najl»ejsz¡ kraw¦dzi¡.
Politechnika Gda«ska Algorytmy grafowe 2
Kolejka priorytetowa
void fixHeapUp(int id, vector<int> &kopiec,
vector<Sasiad> &sasiad) {
while(id>0) {
int uid = (id-1)>>1;
if( sasiad[ kopiec[id] ].waga
>=sasiad[ kopiec[uid] ].waga )
return;
int tmp = kopiec[id];
kopiec[id] = kopiec[uid];
kopiec[uid] = tmp;
sasiad[kopiec[id]].idKolejka = id;
sasiad[kopiec[uid]].idKolejka = uid;
id = uid;
}
}
Politechnika Gda«ska Algorytmy grafowe 2
Kolejka priorytetowa
void fixHeapDown(vector<int> &kopiec,
vector< Sasiad > &sasiad) {
int id = 0, uid = 1;
while(uid<kopiec.size()) {
int minid = id;
if(kopiec[minid].waga > kopiec[uid].waga)
minid = uid;
uid++;
if(uid<kopiec.size()
&& kopiec[minid].waga > kopiec[uid].waga)
minid = uid;
if(minid==id) return;
int tmp = kopiec[id]; kopiec[id] = kopiec[minid];
kopiec[minid] = tmp;
sasiad[kopiec[id]].idKolejka = id;
sasiad[kopiec[minid]].idKolejka = minid;
id = minid; uid = (minid<<1)+1;
}
}
Politechnika Gda«ska Algorytmy grafowe 2
Kolejka priorytetowa
int getMinVal(vector<int> &kopiec,
vector< Sasiad > &sasiad) {
int odp = kopiec[0];
sasiad[ odp ].idKolejka = -2;
if(kopiec.size()==1)
return odp;
kopiec[0] = kopiec.back();
kopiec.pop_back();
sasiad[ kopiec[0] ].idKolejka = 0;
fixHeapDown(kopiec, sasiad);
return odp;
}
Politechnika Gda«ska Algorytmy grafowe 2
Algorytm Prima
struct Krawedz {
int sasiad, waga;
};
int minDrzewoPrim(vector< list<Krawedz> > G) {
vector<Sasiad> sasiad;
sasiad.resize(G.size());
//ustawiamy 0 wierzchoªek jako korze«
sasiad[0].idKolejka = -2;
list<Krawedz>::iterator beg, end=G[0].end();
for(beg=G[0].begin(); beg!=end; beg++) {
int pos = kopiec.size();
sasiad[ beg->sasiad ].waga = beg->waga;
sasiad[ beg->sasiad ].prevWierz = 0;
sasiad[ beg->sasiad ].idKolejka = pos;
kopiec.push_back( beg->sasiad );
fixHeapUp(pos, kopiec, sasiad);
}...
Politechnika Gda«ska Algorytmy grafowe 2
Algorytm Prima cd.
while(kopiec.size()>0) {
int minWierz = getMinVal(kopiec, sasiad);
end = G[minWierz].end();
for(beg=G[minWierz].begin(); beg!=end; beg++) {
if( sasiad[beg->sasiad].idWierz == -2 )
continue;
int pos;
if( sasiad[beg->sasiad].idWierz == -1 ) {
pos = kopiec.size();
sasiad[ beg->sasiad ].idWierz = pos;
kopiec.push_back( beg->sasiad );
} else if(sasiad[beg->sasiad].waga>beg->waga)
pos = sasiad[beg->sasiad].idKolejka;
else continue;
sasiad[ beg->sasiad ].waga = beg->waga;
sasiad[ beg->sasiad ].prevWierz = minWierz;
fixHeapUp(pos, kolejka, sasiad);
}
}
}
Politechnika Gda«ska Algorytmy grafowe 2
Dyskusja o algorytmie Prima
Powy»szy algorytm nic nie zwraca, ale w zale»no±ci od potrzebymo»emy otrzyma¢ wag¦ najl»ejszego drzewa:
int suma = 0;
for(i=1; i<sasiad.size(); i++) //sic!
suma += sasiad[i].waga;
albo drzewo.Zªo»ono±¢ obliczeniowa tego algorytmu to O(m ∗ log n), gdzien=|V(G)|, m=|E(G)|.Je±li u»yliby±my kopca Fibonacciego jako kolejki priorytetowejzªo»ono±¢ wyniosªaby O(m + n log n).
Politechnika Gda«ska Algorytmy grafowe 2
Algorytm Kruskala
minDrzewoKruskal(Graf G) {
sortujemy kraw¦dzie grafu G ze wzgl¦du na wag¦
T - graf bez kraw¦dzi z |V(G)| wierzchoªkami
foreach(e in posortowane kraw¦dzie) {
je±li dodanie e do T nie tworzy cyklu w grafie T,
to dodajemy kraw¦d¹ e do T }
return T;
}
Politechnika Gda«ska Algorytmy grafowe 2
Algorytm Kruskala
Sprawdzenie, czy dodanie kraw¦dzi doprowadzi do powstania cyklu,mo»na realizowa¢ przez lasy zbiorów rozª¡cznych.
Politechnika Gda«ska Algorytmy grafowe 2
Lasy zbiorów rozª¡cznych
Lasy zbiorów rozª¡cznych mo»na zaimplementowa¢ za pomoc¡tablicy. Podstawow¡ operacj¡ b¦dzie wyszukiwanie korzenia zkompresj¡ ±cie»ki.
int znajdzKorzen(int v, vector<int> &las) {
if(las[v]==v) return v;
return las[v] = znajdzKorzen(las[v], las);
}
Tablica las przechowuje odniesienie do ojca w¦zªa. OperacjaznajdzKorzen powoduje spªaszczenie drzewa przy ka»dymwywoªaniu.
Politechnika Gda«ska Algorytmy grafowe 2
Dziaªanie lasów zbiorów rozª¡cznych
TAblica
Politechnika Gda«ska Algorytmy grafowe 2
Algorytm Kruskala
struct KrawedzKruskal {
int u, v, waga;
KrawedzKruskal(int tu, int tv, int tw):
u(tu), v(tv), waga(tw)
friend bool operator<(const KrawedzKruskal &a,
const KrawedzKruskal &b) {
return a.waga<b.waga;
}
}
int minDrzewoKruskal(vector< list<Krawedz> > G) {
list<Krawedz>::iterator beg, end;
vector<KrawedzKruskal> sortKraw;
for(int i=0; i<G.size(); i++) {
beg = G[i].begin(); end = G[i].end();
for(; beg!=end; beg++)
sortKraw.push_back(
KrawedzKruskal(i,beg->sasiad,beg->waga) );
}
sort(sortKraw.begin(), sortKraw.end());...
Politechnika Gda«ska Algorytmy grafowe 2
Algorytm Kruskala
...
vector<int> las;
las.resize(G.size());
for(int i=0; i<las.size(); i++) las[i]=i;
int sumaWag=0;
for(int i=0; i<sortKraw.size(); i++) {
int korzenU = znajdzKorzen(sortKraw[i].u, las);
int korzenV = znajdzKorzen(sortKraw[i].v, las);
if(korzenU==korzenV) continue;
sumaWag += sortKraw[i].waga;
las[korzenU] = korzenV;
}
return sumaWag;
}
Politechnika Gda«ska Algorytmy grafowe 2
Przepªywy w sieciach
Mamy dany graf skierowany G z dodatnimi wagami(przepustowo±¢). Wyró»nijmy dwa wierzchoªki s i t. Przepustowo±¢b¦dziemy oznaczali przez c(·, ·). Je±li pomi¦dzy wierzchoªkami u, vnie ma kraw¦dzi, to c(u, v) = 0.Tak graf b¦dziemy nazywali sieci¡.Przepªywem nazywamy funkcj¦ f : V × V ⇒ R speªniaj¡c¡:
warunek przepustowo±ci: dla ka»dych u, v ∈ V
f (u, v) ≤ c(u, v)
warunek sko±nej symetryczno±ci: dla ka»dych u, v ∈ V
f (u, v) = −f (v , u)warunek zachowania przepªywu: dla ka»dego u ∈ V \{s, t}∑
v∈V f (u, v) = 0
Politechnika Gda«ska Algorytmy grafowe 2
s t
4
9
2 4
1
4
8
1
2 3
4
8
Politechnika Gda«ska Algorytmy grafowe 2
Warto±¢ przepªywu, maksymalny przepªyw
Warto±ci¡ przepªywu jest liczba∑
v∈V f (s, v).Maksymalnym przepªywem sieci G jest przepªyw o maksymalnejwarto±ci przepªywu.
Politechnika Gda«ska Algorytmy grafowe 2
Sie¢ residualna
Dla danej sieci G = (V ,E ) oraz przepªywu f (·, ·) mo»na stworzy¢przepustowo±ci residualne równe cf (u, v) = c(u, v)− f (u, v) orazsie¢ residualn¡ H = (V ,E ′), gdzieE ′ = {(u, v) ∈ V 2 : cf (u, v) > 0}.
s t
4
9
2 4
1
4
8
1
2 3
4
8
s t
2
2
9
4 2
3
2
8
1
5
2
2
8
Politechnika Gda«ska Algorytmy grafowe 2
�cie»ka powi¦kszaj¡ca
�cie»k¡ powi¦kszaj¡c¡ sieci G jest droga (prosta) pomi¦dzywierzchoªkami s oraz t.
s t
4
9
2 4
1
4
8
1
2 3
4
8
s t
2
2
9
4 2
3
2
8
1
5
2
2
8
Politechnika Gda«ska Algorytmy grafowe 2
Metoda Fulkersona�Forda
FulkFordMetod(G, s, t) {
foreach (u,v) in E(G)
f(u,v)=f(v,u)=0;
while( istnieje ±cie»ka powi¦kszaj¡ca
pomi¦dzy s i t w sieci residualnej Gf )
{
p = ±cie»ka powi¦kszaj¡ca;
c - minimalna warto±¢ cf na ±cie»ce p;
foreach (u,v) in p {
f(u,v) += c;
f(v,u) -= c;
}
}
}
Politechnika Gda«ska Algorytmy grafowe 2
Algorytm Edmondsa-Karpa
Algorytm Edmondsa-Karpa jest realizacj¡ metodyFulkersona-Forda. Algorytm znajduje najkrótsz¡ ±cie»k¦powi¦kszaj¡c¡ (pod wzgl¦dem liczby wierzchoªków).
Politechnika Gda«ska Algorytmy grafowe 2
s t
4
9
2 4
1
4
8
1
2 3
4
8
Politechnika Gda«ska Algorytmy grafowe 2
s t
4
9
2 4
1
4
8
1
2 3
4
8
Politechnika Gda«ska Algorytmy grafowe 2
s t
4
9
2 4
1
4
4
5
2 3
4
8
Politechnika Gda«ska Algorytmy grafowe 2
s t
4
9
2 4
1
4
4
5
2 3
4
8
Politechnika Gda«ska Algorytmy grafowe 2
s t
4
4
5
2 4
5
4
5
2 3
4
4
4
Politechnika Gda«ska Algorytmy grafowe 2
s t
4
4
5
2 4
5
4
5
2 3
4
4
4
Politechnika Gda«ska Algorytmy grafowe 2
s t
4
6
3
6
5
2
7
4 1
4
2
6
Politechnika Gda«ska Algorytmy grafowe 2