Vračanje

RAČUNALNIŠTVO IN INFORMACIJSKE TEHNOLOGIJE
OSNOVE ALGORITMOV
NIKOLA GUID
Fakulteta za elektrotehniko,
računalništvo in informatiko
Maribor, 2011
Kazalo
5 Vračanje (sestopanje)
5.1 Splošna metoda . . . . . . .
5.2 N kraljic na šahovsko desko
5.3 Vsota podmnožic . . . . . .
5.4 Barvanje grafov . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5-1
5-2
5-4
5-15
5-21
Poglavje
5
Vračanje (sestopanje)
Obstajajo problemi, ki imajo eksponentno časovno zahtevnost. Takim problemom
rečemo, da so težki (hard ). Če je eksponentni problem dokazano eksponentni,
mu rečemo, da je NP-polni (NP-complete). Mnogi od teh problemov so za
prakso pomembni, zato se ne moremo kar vdati in storiti ničesar. V tem poglavju
spoznamo en način obravnave teh težkih problemov, tj. vračanje ali sestopanje
(backtracking).
Z vračanjem je mogoče rešiti kar velike primerke eksponentnih problemov.
Vračanje je izboljšava grobega iskanja, ko nekatere naslednike, za katere vemo, da
ne pripeljejo do rešitve, zavrnemo. Čeprav problem še zmeraj ostane eksponentni,
lahko s to strategijo v splošnem rešimo največkrat dovolj velike primerke.
Vračanje temelji na konstrukciji drevesa prostora stanj (state-space tree),
katerih vozlišča pomenijo določene izbire. Dana morata biti začetno in končno
(ciljno) stanje. V trenutnem stanju uporabimo eno od možnih pravil, ki nas
pripelje v drugo stanje.
Če naletimo na stanje, iz katerega ni več mogoče tvoriti novih stanj, se vrnemo
na predhodno stanje, od koder poskušamo najti drugo novo stanje. Strategijo
prav zaradi te lastnosti imenujemo vračanje. Vračanje deluje podobno kot iskanje
z razvijanjem v globino, kot smo ga že obravnavali v poglavju Zmanjšaj in vladaj,
samo da tu na tekočem koraku ne poiščemo vseh stanj, ki izhajajo iz danega
stanja, temveč izberemo samo eno od izhajajočih stanj. V terminologiji teorije
grafov ustreza izbiri enega novega stanja tvorba (generation) vozlišča. Prav
zaradi takega napredovanja v globino drevesa Kozak [Kozak, 1997] in Vilfan [Vilfan, 1998] tej strategiji pravita sestopanje.
5-2
5.1 Splošna metoda
5.1
Splošna metoda
V tem poglavju se bomo omejili na probleme, katerih rešitev je mogoče zapisati kot
vektor x = [x[1] x[2] . . . x[n]]T , kjer izbiramo komponente x[i] (i = 1, 2, . . . , n)
iz končnih množic S[i] (x[i] ∈ S[i]). Velikost množice S[i] je m[i], pri čemer je
m[i] < ∞.
Problemi, ki jih rešujemo z vračanjem, zahtevajo, da vse rešitve izpolnjujejo
množico omejitev. Omejitve delimo v eksplicitne in implicitne.
Eksplicitne omejitve se kažejo v omejevanju števila vrednosti komponente x[i]
(i = 1, 2, . . . , n). Tako lahko x[i] zavzame le vrednosti iz dane množice S[i], torej
x[i] ∈ S[i]. Primer eksplicitne omejitve je:
x[i] = 0 ali 1,
če ima množica S[i] samo dva elementa (S[i] = {0, 1}). Vektor x, čigar komponente izpolnjujejo eksplicitne omejitve, definira prostor rešitve (solution space).
Velikost tega prostora določa naslednji zmnožek:
p(n) = m[1]m[2] . . . m[n].
Zgled 5.1. Vzemimo, da ima rešitev obliko x = [x[1] x[2]]T , pri čemer so x[1] ∈
S[1], x[2] ∈ S[2], S[1] = {0, 1, 2} in S[2] = {1, 0}. Torej velja m[1] = 3, m[2] = 2
in n = 2. Vseh rešitev je p(2) = m[1]m[2] = 3 · 2 = 6. Prostor rešitev lahko
prikažemo z drevesom z globino 2 (slika 5.1). Vsaki veji na globini i pripada ena
vrednost i-te komponente vektorja x. Vseh možnih stanj vektorja x je p(n), kar
je toliko, kot je listov drevesa. V našem primeru je p(2) = 6. Globina drevesa
ustreza številu komponent vektorja x, v našem primeru je to 2. ♦
globina
0
x[1]=1
x[1]=2
x[1]=3
1
x[2]=1
x[2]=0
x[2]=1
x[2]=0
x[2]=1
x[2]=0
2
Slika 5.1: Drevo prostora stanj.
Z implicitnimi omejitvami skušamo zmanjšati prostor rešitev. Pri tem si pomagamo s kriterijsko funkcijo f , ki nam že pri delnem vektorju [x[1] x[2] . . . x[i]]T ,
5.1 Splošna metoda
5-3
ugotovi, ali ima smisel z določanjem naslednje komponente vektorja x[i + 1].
Torej vrednost f ([x[1] x[2] . . . x[i]]) nam pove ali z iskanjem rešitve nadaljevati
ali nehati. Na ta način lahko pohitrimo reševanje. Čim ostrejše so implicitne
omejitve, tem več poti bomo krajšali in s tem bo pregledovanje hitrejše in algoritem učinkovitejši. Algoritem vračanja najde rešitev pri manj poskusih kot
p(n). Njegova osnovna ideja je v tem, da gradi vektor postopoma, komponento
za komponento.
Psevdokod strategije vračanja je:
VRACANJE(n, S,resitev)
1 k←1
2 while k > 0
3
do if obstaja nepregledan x[k] ∈ S[k] and
4
LAHKO-VODI-K-CILJU(n, x, k)
5
then if k = n
6
then resitev ← resitev ∪ x
7
else k ← k + 1 % Stopi v globino (sestopi).
% Od tod izvira ime sestopanje.
8
else k ← k − 1 % Vrni se. Od tod tudi ime vračanje.
Komponente x[k] zadoščajo eksplicitnim omejitvam (x[k] ∈ S[i]) in implicitnim omejitvam (LAHKO-VODI-K-CILJU(n, x, k)). Vse rešitve vektorja x shranimo
v množico rešitev, ki jo moramo pred klicem procedure izprazniti.
Časovna zahtevnost
Najslabša časovna zahtevnost je T (n) = O(p(n)) = O(Πni=1 m[i]). Implicitne omejitve v splošnem zmanjšajo časovno zahtevnost, za koliko pa je težko izračunati.
Pomagali si bomo z merjenimi časi.
5-4
5.2 N kraljic na šahovsko desko
5.2
N kraljic na šahovsko desko
Najznamenitejša uporaba strategije vračanja je postavitev osmih kraljic na šahovsko desko, tako da se med seboj ne napadajo. Procedura N-KRALJIC(n,
rešitev) poišče vse postavitve n kraljic na šahovsko desko n × n, da se med
seboj ne napadajo. Ko rešitev najde, jo shrani v množico rešitev. Množica rešitev
mora biti pred klicem prazna.
N-KRALJIC(n,resitev)
1 x[1] ← 0
2 k←1
% k je tekoča vrsta, x[k] je tekoči stolpec
3 while k > 0
4
do x[k] ← x[k] + 1 % premakni v naslednji stolpec
5
while x[k] ≤ n and NAPADENA(k, x)
6
do x[k] ← x[k] + 1 % kraljico moramo premakniti
7
if x[k] ≤ n
% položaj smo našli
8
then if k = n
% ali je rešitev kompletna?
9
then resitev←resitev ∪ x
10
else k ← k + 1 % pojdi v naslednjo vrsto
% ali sestopi
11
x[k] ← 0
% pripravi novo kraljico
12
else k ← k−1
% položaj nismo našli, zato se vrni
Preden se lotimo podrobne obravnave procedure N-KRALJIC(n,resitev) poskušajmo zgraditi Boolovo fukcijo NAPADENA(k, x). Vrstica i naj pripada i-ti
kraljici (i = 1, 2, . . . , n). Z x[k] (x[k] = 1, 2, . . . , n) označimo stolpec, v katerem
je i-ta kraljica (slika 5.2).
i
3
2
1
1 2 3 4
x[i]
Slika 5.2: Kraljice na šahovskem polju.
Predpostavimo, da je i-ta kraljica na položaju (x[i], i) in k-ta kraljica na
položaju (x[k], k) (slika 5.3).
Kraljici se napadata, če ležita na premici z naslednjimi naklonskimi koeficienti:
5-5
5.2 N kraljic na šahovsko desko
i
i
(x[i], i)
(x[k], k)
k
x[i] x[k]
x[i]
Slika 5.3: i-ta in k-ta kraljica na šahovskem polju.
∞, 0, 1 in −1. Če je naklon
i−k
= ∞,
x[i] − x[k]
velja x[i] = x[k].
(5.1)
Enačba 5.1 pove, da sta kraljici v istem stolpcu. Če je naklon
i−k
= 0,
x[i] − x[k]
velja i = k.
(5.2)
Enačba 5.2 trdi, da sta kraljici v isti vrstici. Če je naklon
i−k
= ±1,
x[i] − x[k]
velja |x[i] − x[k]| = |i − k|.
(5.3)
Enačba 5.3 pove, da sta kraljici na isti diagonali.
Zgradimo Boolovo funkcijo NAPADENA(k, x), ki nam vrne vrednost FALSE, če
k-to kraljico lahko postavimo na šahovsko desko, kar pomeni, da ni napadena od
že postavljenih kraljic. Kraljice postavljamo tako, da damo v i-to vrstico samo
i-to kraljico. Tako nam v funkcijo NAPADENA(k, x) ni treba neposredno vgraditi
pogoja iz enačbe 5.2.
NAPADENA(k, x)
1 i←1
2 while i < k
3
do if x[i] = x[k] or |x[i]-x[k]|=|i-k|
4
then NAPADENA←TRUE
% k-ta kraljica je napadena
% od i-te kraljice
5
exit(NAPADENA)
6
i ← i + 1 % k-ta kraljica ni napadena od i-te kraljice
7 NAPADENA←FALSE
% k-ta kraljica ni napadena od nobene kraljice
Funkcija NAPADENA pove, ali je k-ta kraljica, ki jo postavimo na šahovsko polje
v k-to vrstico in x[k]-ti stolpec, napadena ali ne od kraljic na poljih v i-ti vrsti in
5-6
5.2 N kraljic na šahovsko desko
x[i]-tem stolpcu (i = 1, 2, . . . , k − 1). Če je napadena, nam vrne vrednost TRUE,
če ni napadena, pa vrednost FALSE.
Zgled 5.2. Ponazorimo delovanje funkcije NAPADENA. Naj bo k = 2, x[1] = 1
in x[2] = 1. Položaj dveh kraljic kaže slika 5.4. Poženimo funkcijo:
i
2
1
1 2
x[i]
Slika 5.4: Postavitev prve in druge kraljice na šahovskem polju.
1. Vrstica 1: i = 1.
2. Vrstica 2: i = 1 < 2 = k.
3. Vrstici 3–4: Ker je x[1] = x[2], izstopimo z vrednostjo TRUE. To pomeni, da
je druga kraljica napadena. ♦
Zgled 5.3. Ponazorimo še enkrat delovanje funkcije NAPADENA. Naj bo k = 2,
x[1] = 1 in x[2] = 3. Položaj dveh kraljic kaže slika 5.5. Poženimo funkcijo:
i
2
1
1 2 3
x[i]
Slika 5.5: Postavitev prve in druge kraljice na šahovskem polju.
1. Vrstica 1: i = 1.
2. Vrstica 2: 1. iteracija zanke while: i = 1 < 2 = k.
3. Vrstica 3: Ker velja x[1] 6= x[2] (1 6= 3) in |x[1] − x[k]| 6= |i − k| (|1 − 3| 6=
|1 − 2|), gremo na vrstico 6.
4. Vrstica 6: i = 1 + 1 = 2.
5. Vrstica 2: 2. iteracija zanke while: ker i = k (2 = 2), ne izvedemo zanke.
5-7
5.2 N kraljic na šahovsko desko
6. Vrstica 7: NAPADENA dobi vrednost FALSE. To pomeni, da druga kraljica ni
napadena. ♦
Zgled 5.4. Zaradi preprostejše obravnave predpostavimo, da imamo šahovsko
polje 4 × 4 s štirimi kraljicami (n = 4). Poženimo proceduro N-KRALJIC(4,rešitev):
1. Vrstica 1: x[1] = 0.
2. Vrstica 2: k = 1
3. Vrstice 3–12: 1. iteracija 1. zanke while, k = 1 > 0
(a) Vrstica 4: x[1] = 0 + 1 = 1
(b) Vrstica 5: 2. while se ne izvrši, ker ni izpolnjen drugi pogoj, tj.
NAPADENA(1, x) = FALSE.
(c) Vrstica 7: Ker je 1 ≤ 4 (1. if) in ker 1 6= 4 (2. if), gremo v vrstico 10.
(d) Vrstici 10–11: k = 1 + 1 = 2 (sestopimo v globino) in x[2] = 0. Na
koncu 1. iteracije 1. zanke while smo postavili 1. kraljico v polje (1, 1).
4. Vrstice 3–12: 2. iteracija 1. zanke while, k = 2 > 0
(a) Vrstica 4: x[2] = 0 + 1 = 1
(b) Vrstici 5–6: 2. while: ker velja x[2] = 1 ≤ 4 in NAPADENA(2, x)=TRUE,
se 2. while izvrši: x[2] = 1 + 1 = 2.
(c) Vrstici 5–6: 2. while: ker velja x[2] = 2 ≤ 4 in NAPADENA(2, x)=TRUE,
se 2. while izvrši: x[2] = 2 + 1 = 3.
(d) Vrstica 5: 2. while: ker velja x[2] = 3 ≤ 4 in NAPADENA(2, x)=FALSE,
se 2. while ne izvrši.
(e) Vrstica 7: Ker je 3 ≤ 4 (1. if) in ker 2 6= 4 (2. if), gremo v vrstico 10.
(f) Vrstici 10–11: k = 2 + 1 = 3 (sestopimo v globino) in x[3] = 0. Na
koncu 2. iteracije 1. zanke while smo postavili 2. kraljico v polje (3, 2)
(slika 5.6).
k 4
3
2
1
1 2 3 4
x[k]
Slika 5.6: Postavitev prve in druge kraljice na šahovskem polju.
5-8
5.2 N kraljic na šahovsko desko
5. Vrstice 3–12: 3. iteracija 1. zanke while, k = 3 > 0
(a) Vrstica 4: x[3] = 0 + 1 = 1
(b) Vrstici 5–6: 2. while: ker velja x[3] = 1 ≤ 4 in NAPADENA(3, x)=TRUE,
se 2. while izvrši: x[3] = 1 + 1 = 2.
(c) Vrstici 5–6: 2. while: ker velja x[3] = 2 ≤ 4 in NAPADENA(3, x)=TRUE,
se 2. while izvrši: x[3] = 2 + 1 = 3.
(d) Vrstici 5–6: 2. while: ker velja x[3] = 3 ≤ 4 in NAPADENA(3, x)=TRUE,
se 2. while izvrši: x[3] = 3 + 1 = 4.
(e) Vrstici 5–6: 2. while: ker velja x[3] = 4 ≤ 4 in NAPADENA(3, x)=TRUE,
se 2. while izvrši: x[3] = 4 + 1 = 5.
(f) Vrstica 5: 2. while: ker ne velja x[3] = 5 ≤ 4, se 2. while ne izvrši.
(g) Vrstica 7: Ker ne velja 5 ≤ 4 (1. if), gremo v vrstico 12.
(h) Vrstica 12: k = 3 − 1 = 2. Vrnemo se na globino k = 2. Na koncu
3. iteracije 1. zanke while ugotovimo, da tretje kraljice ne moremo
postaviti.
6. Vrstice 3–12: 4. iteracija 1. zanke while, k = 2 > 0
(a) Vrstica 4: x[2] = 3 + 1 = 4
(b) Vrstica 5: 2. while: ker velja x[2] = 4 ≤ 4 in NAPADENA(2, x)=FALSE,
se 2. while ne izvrši.
(c) Vrstica 7: Ker velja 4 ≤ 4 (1. if) in ker 2 6= 4 (2. if), gremo v vrstico
10.
(d) Vrstici 10–11: k = 2 + 1 = 3 (sestopimo v globino) in x[3] = 0. Na
koncu 4. iteracije 1. zanke while smo postavili 2. kraljico v polje (4, 2)
(slika 5.7).
k
4
3
2
1
1 2 3 4
x[k]
Slika 5.7: Postavitev prve in druge kraljice na šahovskem polju.
5-9
5.2 N kraljic na šahovsko desko
7. Vrstice 3–12: 5. iteracija 1. zanke while, k = 3 > 0
(a) Vrstica 4: x[3] = 0 + 1 = 1
(b) Vrstici 5–6: 2. while: ker velja x[3] = 1 ≤ 4 in NAPADENA(3, x)=TRUE,
se 2. while izvrši: x[3] = 1 + 1 = 2.
(c) Vrstica 5: 2. while: ker velja x[3] = 2 ≤ 4 in NAPADENA(3, x)=FALSE,
se 2. while ne izvrši.
(d) Vrstica 7: Ker velja 2 ≤ 4 (1. if) in ker 3 6= 4 (2. if), gremo v vrstico
10.
(e) Vrstici 10–11: k = 3 + 1 = 4 (sestopimo v globino) in x[4] = 0. Na
koncu 5. iteracije 1. zanke while smo postavili 3. kraljico v polje (2, 3)
(slika 5.8).
k
4
3
2
1
1 2 3 4
x[k]
Slika 5.8: Postavitev prvih treh kraljic na šahovskem polju.
8. Vrstice 3–12: 6. iteracija 1. zanke while, k = 4 > 0
(a) Vrstica 4: x[4] = 0 + 1 = 1
(b) Vrstici 5–6: 2. while: ker velja x[4] = 1 ≤ 4 in NAPADENA(4, x)=TRUE,
se 2. while izvrši: x[4] = 1 + 1 = 2.
(c) Vrstici 5–6: 2. while: ker velja x[4] = 2 ≤ 4 in NAPADENA(4, x)=TRUE,
se 2. while izvrši: x[4] = 2 + 1 = 3.
(d) Vrstici 5–6: 2. while: ker velja x[4] = 3 ≤ 4 in NAPADENA(4, x)=TRUE,
se 2. while izvrši: x[4] = 3 + 1 = 4.
(e) Vrstici 5–6: 2. while: ker velja x[4] = 4 ≤ 4 in NAPADENA(4, x)=TRUE,
se 2. while izvrši: x[4] = 4 + 1 = 5.
(f) Vrstica 5: 2. while: ker ne velja x[4] = 5 ≤ 4, se 2. while ne izvrši.
(g) Vrstica 7: Ker ne velja 5 ≤ 4 (1. if), gremo v vrstico 12.
(h) Vrstica 12: k = 4 − 1 = 3. Vrnemo se na k = 3. Na koncu 6. iteracije
1. zanke while smo ugotovili, da 4. kraljice ne moremo postaviti na
desko.
5.2 N kraljic na šahovsko desko
5-10
9. Vrstice 3–12: 7. iteracija 1. zanke while, k = 3 > 0
(a) Vrstica 4: x[3] = 2 + 1 = 3
(b) Vrstici 5–6: 2. while: ker velja x[3] = 3 ≤ 4 in NAPADENA(3, x)=TRUE,
se 2. while izvrši: x[3] = 3 + 1 = 4.
(c) Vrstici 5–6: 2. while: ker velja x[3] = 4 ≤ 4 in NAPADENA(3, x)=TRUE,
se 2. while izvrši: x[3] = 4 + 1 = 5.
(d) Vrstica 5: 2. while: ker ne velja x[4] = 5 ≤ 4, se 2. while ne izvrši.
(e) Vrstica 7: Ker ne velja 5 ≤ 4 (1. if), gremo v vrstico 12.
(f) Vrstica 12: k = 3 − 1 = 2. Vrnemo se na k = 2. Na koncu 7. iteracije
1. zanke while smo ugotovili, da 3. kraljice ne moremo postaviti na
desko.
10. Vrstice 3–12: 8. iteracija 1. zanke while, k = 2 > 0
(a) Vrstica 4: x[2] = 4 + 1 = 5
(b) Vrstica 5: 2. while se ne izvrši, ker ne velja x[2] = 5 ≤ 4.
(c) Vrstica 7: Ker ne velja 5 ≤ 4 (1. if), gremo v vrstico 12.
(d) Vrstica 12: k = 2 − 1 = 1. Vrnemo se na k = 1. Na koncu 8. iteracije
1. zanke while smo ugotovili, da 2. kraljice ne moremo postaviti na
desko.
11. Vrstice 3–12: 9. iteracija 1. zanke while, k = 1 > 0
(a) Vrstica 4: x[1] = 1 + 1 = 2
(b) Vrstica 5: 2. while se ne izvrši, ker velja NAPADENA(4, x)=FALSE.
(c) Vrstica 7: Ker velja 2 ≤ 4 (1. if) in ker 2 6= 4 (2. if), gremo v vrstico
10.
(d) Vrstica 10–11: k = 1 + 1 = 2 (sestopimo v globino) in x[2] = 0. Na
koncu 9. iteracije 1. zanke while smo postavili 1. kraljico v polje (2, 1).
5-11
5.2 N kraljic na šahovsko desko
12. Na ta način pridemo kmalu do 1. rešitve (slika 5.9):
x[1] = 2, x[2] = 4, x[3] = 1, x[4] = 3.
k
4
3
2
1
1 2 3 4
x[k]
Slika 5.9: Prva postavitev vseh kraljic na šahovskem polju.
13. Kljub temu da smo našli rešitev, ponovno izvršimo 1. zanko while in premaknemo 4. kraljico v naslednji položaj:
x[4] = 3 + 1 = 4.
Ker je 4. kraljica nenapadena, jo moramo premakniti v naslednje polje
(x[4] = 5), kar ima za posledico vračanje (k = 4 − 1 = 3).
14. V naslednji izvršitvi 1. zanke while dosežemo že x[3] = 5 in vračanje do
k = 2.
15. Sledi ponovna izvršitev 1. zanke while, ko dobimo x[2] = 5 in vračanje do
k = 1.
16. V novi izvršitvi 1. zanke while premaknemo 1. kraljico v tretji stolpec
(x[1] = 2 + 1 = 3). Kmalu zatem najdemo še drugo rešitev:
x[1] = 3, x[2] = 1, x[3] = 4, x[4] = 2.
17. Procedura se zaključi, ko k postane 0.
Celoten postopek reševanja procedure N-KRALJIC podajamo v preglednici 5.1.
Delovanje procedure N-KRALJIC lahko opišemo z drevesom stanj (slika 5.10).
Vozlišča na sliki 5.10 predstavljajo tekočo podatkovno bazo, ki jo lahko vidimo
na sliki 5.11. ♦
5-12
5.2 N kraljic na šahovsko desko
Preglednica 5.1: Rezultat delovanja procedure N-KRALJIC.
k
0
1
2
3
2
3
4
3
2
1
2
3
4
4
3
2
1
2
3
4
4
3
2
1
2
3
4
3
2
3
2
1
0
x[1]
0
1
x[2]
x[3]
x[4]
opomba
začetni pogoji
3
>4
zmanjšamo k za 1
4
2
>4
zmanjšamo k za 1
zmanjšamo k za 1
zmanjšamo k za 1
3
>4
rešitev in vrnitev v 1. while
zmanjšamo k za 1
zmanjšamo k za 1
zmanjšamo k za 1
2
>4
rešitev in vrnitev v 1. while
zmanjšamo k za 1
zmanjšamo k za 1
zmanjšamo k za 1
>4
zmanjšamo k za 1
zmanjšamo k za 1
>4
>4
2
4
1
>4
>4
3
1
4
>4
>4
4
1
3
>4
2
>4
>4
>4
zmanjšamo k za 1
zmanjšamo k za 1
zmanjšamo k za 1
konec procedure
5-13
5.2 N kraljic na šahovsko desko
nivo
a
1
x[1]
b
x[2]
x[3]
2
0
4
3
1
f
3
4
4
c
d
g
2
1
e
h
3
x[4]
1
1
2
2
4
3
3
2
4
i
rešitev
rešitev
Slika 5.10: Drevo stanj kot rezultat reševanja problema nenapadanja 4 kraljic.
a
b
c
d
f
g
h
i
rešitev
Slika 5.11: Stanja v vozliščih drevesa na sliki 5.10.
e
5-14
5.2 N kraljic na šahovsko desko
Rešitve so le listi z nivojem 4. Če ne bi upoštevali omejitev, bi zgradili drevo
stanj s 44 = 256 listov (slika 5.12).
x[1]
1
1 ... 4
x[2]
x[3]
x[4]
1 ... 4
1 ... 4
1 ... 4
1.. 1..
1.. 1..
1.. 1..
1.. 1.. 1..
1.. 1..
1.. 1..
1 ... 4
1 ... 4
4
3
2
.. 4
.. 4
... 256
1 ... 4
Slika 5.12: Drevo stanj brez upoštevanja implicitnih omejitev.
Časovna zahtevnost procedure N-KRALJIC
Kozak je izmeril naslednjo časovno zahtevnost [Kozak, 1997]:
T (n) = O(22,5n ).
Ta vrednost je gotovo precej manjša od O(nn ), vendar je še vedno eksponentna.
5-15
5.3 Vsota podmnožic
5.3
Vsota podmnožic
Pozitivno število M želimo razstaviti na pozitivne sumande, ki jih izbiramo iz
množice znanih števil w[i], i = 1, 2, . . . , n. V literaturi je problem znan kot
problem vsote množic (subset-sum problem). Iskano rešitev predstavimo z
vektorjem x = [x[1] x[2] . . . x[n]], kjer komponento x[i] definiramo z:
½
0, ˇce w[i] ni v vsoti
x[i] =
(5.4)
1, ˇce je w[i] v vsoti
Vektor x je rešitev, če velja:
n
X
x[i]w[i] = M.
(5.5)
i=1
Iz enačbe 5.5 lahko sklepamo, da lahko vsak sumand sodeluje v vsoti samo enkrat.
Rešitev x gradimo postopoma in skušamo zavreči čimveč možnosti. Pri tem si
pomagamo z omejitvenimi funkcijami. Denimo, da smo x zgradili do (k − 1)-te
komponente, tj. x[k − 1]. Izbira naslednje komponente x[k] ne vodi k cilju, če M
ne moremo doseči s preostalimi sumandi:
k
X
x[i]w[i] +
i=1
n
X
w[i] < M.
(5.6)
i=k+1
Cilja ne bomo dosegli tudi v primeru, če vsoto v naslednjem koraku presežemo:
k
X
x[i]w[i] +
i=1
min {w[i]} > M.
k+1≤i≤n
(5.7)
Pogoj 5.7 pove, da je koristno, če sumande že na začetku uredimo v nepadajočem
vrstnem redu. V tem primeru je:
min {w[i]} = w[k + 1].
k+1≤i≤n
(5.8)
Pogoji, ki jih predstavljajo izrazi 5.5, 5.6 in 5.7, so tako imenovane implicitne
omejitve.
Preden zapišemo rekurzivni algoritem sestopanja za tvorbo vsote podmnožic
števil, uvedimo nekaj spremenljivk. Spremenljivka dok naj predstavlja vsoto
vključenih sumandov na tekočem koraku:
dok =
k−1
X
i=1
x[i]w[i],
(5.9)
5-16
5.3 Vsota podmnožic
medtem ko odk pomeni največjo možno vsoto iz preostalih sumandov:
odk =
n
X
w[i].
(5.10)
i=k
Obe spremenljivki potrebujemo v tekočih omejitvenih pogojih. Elementi w[i]
morajo biti razvrščeni v nepadajočem vrstnem redu. Da ima reševanje sploh
smisel, mora veljati:
w[1] ≤ M
(5.11)
in
n
X
w[i] ≥ M.
(5.12)
i=1
Psevdokod algoritma za tvorbo vsote množic števil je:
VSOTA-PODMNOZIC(n, w, M, k, dok, odk, resitev)
1 x[k] ← 1
% Predpostavimo, da je w[k] v rešitvi, tj. levi sin.
2 if dok + w[k] = M
3
then for i ← k + 1 to n
4
do x[i] ← 0 % Rešitev; preostale komponente so enake 0.
5
resitev ← [x[1] x[2] . . . x[n]] ∪ resitev
6
else if dok + w[k] + w[k + 1] ≤ M
% S preostalim sumandom še lahko pridemo do rešitve.
7
then VSOTA-PODMNOZIC(n, w, M, k+1, dok+w[k], odk−w[k], resitev)
% Sestopimo v levo, tj. generiramo levi sin.
8 if dok + odk − w[k] ≥ M and dok + w[k + 1] ≤ M
% S preostalimi sumandi še lahko dosežemo rešitev.
9
then x[k] ← 0
% Sestopimo v desno, tj. generiramo desni sin.
10
VSOTA-PODMNOZIC(n, w, M, k + 1, dok, odk − w[k], resitev)
Začetni klic danega algoritma mora imeti naslednje vrednosti parametrov:
k = 1,
dok = 0,
odk =
n
X
w[i],
i=1
resitev = {}.
Parameter k ustreza vrednosti globine, povečani za 1.
5-17
5.3 Vsota podmnožic
Zgled 5.5. Število 10 razstavi s pomočjo štirih števil w = [4, 5, 5, 6].
1. Proceduro pokličemo z naslednjimi vrednostmi:
k = 1, dok = 0, odk =
4
X
w[i] = 20, resitev = 0.
i=1
Predpostavimo levi sin: x[1] = 1. Pogoj pri 1. if ni izpolnjen (0 + 4 6= 10).
Pogoj pri 2. if je izpolnjen (0 + 4 + 5 ≤ 10), zato sestopimo v levo in
generiramo levi sin x[1] = 1.
2. Proceduro pokličemo z naslednjimi vrednostmi:
k = 2, dok = 4, odk = odk − w[1] = 16.
Sedaj smo na globini 1. Predpostavimo levi sin: x[2] = 1. Pogoj pri 1. if ni
izpolnjen (4 + 5 6= 10). Pogoj pri 2. if ni izpolnjen (4 + 5 + 5 ni manjše ali
enako 10), zato pogledamo pogoja pri 3. if (4 + 16 − 5 ≥ 10 in 4 + 5 ≤ 10).
Oba pogoja sta izpolnjena, zato generiramo x[2] = 0, tj. desni sin oziroma
sestopimo v desno v globino 2.
3. Proceduro pokličemo z naslednjimi vrednostmi:
k = 3, dok = 4, odk = odk − w[2] = 16 − 5 = 11.
Predpostavimo levi sin: x[3] = 1. Pogoj pri 1. if ni izpolnjen (4 + 5 6= 10).
Pogoj pri 2. if ni izpolnjen (4+5+6 ni manjše ali enako 10), zato pogledamo
pogoja pri 3. if (4 + 11 − 5 ≥ 10 in 4 + 6 ≤ 10). Oba pogoja sta izpolnjena,
zato generiramo x[3] = 0, tj. desni sin oziroma sestopimo v desno v globino
3.
4. Proceduro pokličemo z naslednjimi vrednostmi:
k = 4, dok = 4, odk = odk − w[3] = 11 − 5 = 6.
Sedaj smo na globini 3. Predpostavimo levi sin: x[4] = 1. Pogoj pri 1. if
je izpolnjen (4 + 6 = 10), zato zapišemo rešitev. Ker preostalih komponent
x[i] ni, se zanka for ne izvrši (i = 5 to 4). Rešitev je vektor x = [1 0 0 1].
Torej zadnji levi sin generiramo. Vstopimo v 3. if (4 + 6 − 6 ni večje ali
enako 10). S tem so zaključili proceduro na globini 3.
5. Ker smo sestopali v globino po desni strani (razen na globini 0), se vrnemo
na globino 0, ko smo poklicali VSOTA-PODMNOZIC v vrsti 7. Sledi izvršitev
3. if s starimi podatki: k = 1, dok = 0, odk = 20. Pogoja pri 3. if sta
izpolnjena (0 + 20 − 4 ≥ 10) in (0 + 5 ≤ 10), zato generiramo x[1] = 0,
tj. desni sin oziroma sestopimo v desno v globino 1.
5-18
5.3 Vsota podmnožic
6. Proceduro pokličemo z naslednjimi vrednostmi:
k = 2, dok = 0, odk = odk − w[1] = 16.
Predpostavimo levi sin: x[2] = 1. Pogoj pri 1. if ni izpolnjen (0 + 5 6=
10). Pogoj pri 2. if je izpolnjen (0 + 5 + 5 ≤ 10), zato sestopimo v levo,
tj. generiramo levi sin x[2] = 1. Sestopimo v globino 2.
7. Proceduro pokličemo z naslednjimi vrednostmi:
k = 3, dok = 5, odk = 11.
Predpostavimo levi sin: x[3] = 1. Pogoj pri 1. if je izpolnjen (5 + 5 = 10),
zato zapišemo rešitev. Preostale komponente x[i] dobijo vrednost 0. Zanka
for se izvrši samo enkrat (i = 4 to 4) ali x[4] = 0. Torej zadnji levi sin
generiramo (x[3] = 1). Rešitev je vektor x = [0 1 1 0]. Vstopimo v 3. if.
Prvi pogoj je izpolnjen (5 + 11 − 5 ≥ 10), drugi pa ne (5 + 6 ni manjše ali
enako 10), zato končamo s proceduro na globini 2.
8. Vrnemo se na globino 1, ko smo izvršili proceduro VSOTA-PODMNOZIC v vrsti
7. Sledi izvršitev 3. if s starimi podatki: k = 2, dok = 0, odk = 16. Pogoja
pri 3. if sta izpolnjena (0 + 16 − 5 ≥ 10) in (0 + 5 ≤ 10), zato generiramo
x[2] = 0, tj. desni sin oziroma sestopimo v desno v globino 2.
9. Proceduro pokličemo z naslednjimi vrednostmi:
k = 3, dok = 0, odk = 11.
Predpostavimo levi sin: x[3] = 1. Pogoj pri 1. if ni izpolnjen (0 + 5 6= 10).
Pogoj pri 2. if ni izpolnjen (0+5+6 ni manjše ali enako 10), zato pogledamo
prvi pogoj pri 3. if. Ta ni izpolnjen, saj (0 + 11 − 5 ni večje ali enako 10).
Zaključimo proceduro na globini 2, ne da bi generirali levega sina x[3] = 1.
Dani postopek reševanja lahko ponazorimo s preglednico 5.2.
5-19
5.3 Vsota podmnožic
Preglednica 5.2: Rezultati delovanja procedure VSOTA-PODMNOZIC.
k=1
dok
0
odk
20
k=2
dok
odk
4
16
k=3
dok
odk
4
11
k=4
dok
x[1]
1
x[2]
x[3]
x[4]
0
0
4
0
odk
20
6
1!
0
0
16
1
5
0
11
16
1
0!
0
0
11
1?
Opomba: Klicaj označuje konec zaporedja vrednosti x, ki predstavlja rešitev.
Vprašaj pomeni, da končamo brez generacije levega sina x[3] = 1.
Naš primer ima dve rešitvi: x = [1 0 0 1] in x = [0 1 1 0].
Slika 5.13 prikazuje drevo stanj, ki ga tvori procedura VSOTA-PODMNOZIC. Vozlišča so označena s trojico (k, dok, odk). Vrednost za k je enaka globini drevesa
minus 1. V našem primeru smo poklicali proceduro VSOTA-PODMNOZIC sedemkrat.
Drevo stanj brez implicitnih omejitev ima 2n − 1 = 24 − 1 = 15 vozlišč. ♦
5.3 Vsota podmnožic
5-20
Slika 5.13: Drevo stanj procedure VSOTA-PODMNOZIC.
Časovna zahtevnost procedure VSOTA-PODMNOZIC
Iz meritev je Kozak [Kozak, 1997] določil, da je časovna zahtevnost algoritma
približno
3
T (n) = O(2 4 n ),
kar je nekaj bolje od direktnega pregledovanja, kjer bi bila zahtevnost O(2n ).
5-21
5.4 Barvanje grafov
5.4
Barvanje grafov
Definicija 5.1. Graf G je m-barvljiv (m-colourable), če obstaja prireditev celih
števil 1, 2, . . . , m, imenovanih barve, k vozliščem iz G, tako da nobeni sosedni
vozlišči nimata enakih barv.
Problem barvanja grafov imenujemo odločitveni problem m-barvljivosti
(m-colourability decision problem). Zanimiv je optimizacijski problem m-barvljivosti, ki išče najmanjše celo število barv m, s katerim lahko še pobarvamo graf
G.
Definicija 5.2. Kromatično število ( chromatic number) v G je najmanjše
celo število k, tako da se graf G da pobarvati s k barvami (ali z drugimi besedami
povedano, tako da je graf G k-barvljiv).
Zgled 5.6. Graf na sliki 5.14 je 2-barvljiv, če vozliščem 1, 3 in 5 priredimo barvo
1, vozliščema 2 in 4 pa barvo 2. Ta graf seveda ni 1-barvljiv. To pomeni, da je
kromatično število enako 2. ♦
1
2
3
5
4
Slika 5.14: Graf s 5 vozlišči.
5.4 Barvanje grafov
5-22
Definicija 5.3. Graf je ravninski ( planar), če in samo če ga lahko narišemo v
eni ravnini, tako da se nobeni dve povezavi ne sekata.
Vsak zemljevid je mogoče pobarvati s 4-barvami, tako da nobeni sosednji
regiji nimata iste barve. Zemljevid transformiramo v graf, pri čemer vsaki regiji
priredimo vozlišče, vsaki meji med regijami pa povezavo. Slika 5.15 kaže zemljevid
s 5 regijami, tvorbo grafa v zemljevidu in posebej narisan graf. Dani zemljevid
zahteva 4 barve.
Slika 5.15: a) Zemljevid s 5 regijami, b) Tvorba grafa v zemljevidu, c) Samostojno
narisan graf istega zemljevida.
Velja naslednji teorem:
Izrek 5.1. Vsak ravninski graf lahko pobarvamo z največ 4 barvami, tako da noben
sosed nima enake barve.
5-23
5.4 Barvanje grafov
Slika 5.16 kaže primer neravninskega grafa s 5 vozlišči. To je tudi neravninski
graf z najmanj vozlišči. V osnovi je to polni graf. Polni graf s 4 vozlišči je ravninski
graf.
1
3
2
4
5
Slika 5.16: Neravninski graf s 5 vozlišči.
Lotili se bomo problema, kako pobarvati dani graf z m barvami. Seveda
bomo poiskali vse možne načine barvanja. Graf G je podan z Boolovo matriko
povezav. Če med vozliščema i in j obstaja povezava, je c[i, j] = T , če med
njima povezave ni, je c[i, j] = F . Barve predstavimo s celimi števili 1, 2, . . . , m
in rešitev je v obliki vektorja x = [x[1] x[2] . . . x[n]], kjer je x[i] barva i-tega
vozlišča (x[i] ∈ {1, 2, . . . , m}).
5.4 Barvanje grafov
5-24
Uporabimo rekurzivno formulacijo sestopanja. Drevo prostora stanj je stopnje
m in višine n. Vsako vozlišče na nivoju i ima m sinov, kar ustreza m možnim dodelitvam k x[i] (i = 1, 2, . . . , n). Zapišimo psevdokod procedure BARVANJE-GRAFA
na globini k, ko predpostavljamo, da so barve vozliščem 1, 2, . . . , k −1 že določene.
BARVANJE-GRAFA(n, c, m, k, x,rešitev)
1 loop
% tvori vse legalne prireditve za x[k]
2
NOVA-BARVA(n, c, m, k, x)
% priredi x[k] legalno barvo
3
if x[k] = 0
4
then exit
% vozlišča k ni več mogoče pobarvati
5
if k = n
6
then rešitev ← rešitev ∪ x
% vključi tekočo rešitev x
% v množico rešitev
7
else BARVANJE-GRAFA(n, c, m, k + 1, x,rešitev)
% sestopimo
Procedura NOVA-BARVA določi novo barvo vozlišču k, tako da je ta različna od
barv že pobarvanih sosednjih vozlišč. Nova barva x[k] je lahko katerakoli barva
(število) v zaprtem intervalu [1, m]. Če vozlišču k ne moremo določiti barve,
postavimo 0 v x[k] .
NOVA-BARVA(n, c, m, k, x)
1 loop
2
x[k] ← (x[k] + 1) mod (m + 1)
% naslednja barva
3
if x[k] = 0
4
then exit
% izčrpali smo vse barve
% preverimo, če ima kateri od sosedov že barvo x[k]
5
j=1
6
while j ≤ n and not (c[k, j] and x[k] = x[j])
7
do j ← j + 1
8
if j = n + 1
9
then exit
% najdena nova barva
Proceduro BARVANJE-GRAFA pokličemo s:
for k ← 1 to n
do x[k] ← 0
BARVANJE-GRAFA(n, c, m, 1, x,0)
5-25
5.4 Barvanje grafov
Zgled 5.7. Slika 5.17 prikazuje preprosti graf s 4 vozlišči (n = 4). Dani graf
želimo pobarvati z največ 3 barvami (m = 3).
Slika 5.17: Graf s 4 vozlišči.
Za dani graf lahko napišemo naslednjo

F T
 T F
c=
 F T
T F
Boolovo matriko povezav:

F T
T F 

F T 
T F
1. Začetni pogoji so:
x[1] = x[2] = x[3] = x[4] = 0.
2. Prvi klic je BARVANJE-GRAFA(4, c, 3, 1, x,0) na globini 0.
3. Vstopimo v proceduro NOVA-BARVA(4, c, 3, 1, x). Najprej določimo:
x[1] = (0 + 1)
mod 4 = 1.
Pogoj pri 1. if (x[1] 6= 0) ni izpolnjen, zato postavimo j = 1. Zanka while
se izvede 4-krat, saj so izpolnjeni vsi pogoji:
1 ≤ 4 and not (F and x[1] = x[1]) = T ⇒ j = 2
2 ≤ 4 and not (T and x[1] 6= x[2]) = T ⇒ j = 3
3 ≤ 4 and not (F and x[1] 6= x[3]) = T ⇒ j = 4
4 ≤ 4 and not (T and x[1] 6= x[4]) = T ⇒ j = 5
Ker je pri 2. if izpolnjen pogoj (j = n + 1 ali 5=5), izstopimo iz procedure
NOVA-BARVA.
4. Smo ponovno v proceduri BARVANJE-GRAFA v vrstici 3 na globini 0. Ker nista
izpolnjena pogoja pri 1. if (x[1] 6= 0) in 2. if (k = 1 6= n = 4), sestopimo v
globino 1 s klicem BARVANJE-GRAFA(4, c, 3, 2, x,0).
5-26
5.4 Barvanje grafov
5. Vstopimo v proceduro NOVA-BARVA(4, c, 3, 2, x).
a) 1. iteracija zanke loop:
Najprej določimo:
x[2] = (0 + 1) mod 4 = 1.
Pogoj pri 1. if (x[2] 6= 0) ni izpolnjen, zato postavimo j = 1. Zanka while
se ne izvede niti enkrat, saj ni izpolnjen pogoj:
1 ≤ 4 and not (T and x[1] = x[1]) = F
Ker pri 2. if ni izpolnjen pogoj (j = n + 1 ali 1 6= 5), končamo iteracijo
zanke loop.
b) 2. iteracija zanke loop:
Najprej določimo:
x[2] = (1 + 1) mod 4 = 2.
Pogoj pri 1. if (x[2] 6= 0) ni izpolnjen, zato postavimo j = 1. Zanka while
se izvede 4-krat, saj so izpolnjeni vsi pogoji:
1 ≤ 4 and not (T and x[2] 6= x[1]) = T ⇒ j = 2
2 ≤ 4 and not (F and x[2] = x[2]) = T ⇒ j = 3
3 ≤ 4 and not (T and x[2] 6= x[3]) = T ⇒ j = 4
4 ≤ 4 and not (F and x[2] 6= x[4]) = T ⇒ j = 5
Ker je pri 2. if izpolnjen pogoj (j = n + 1 ali 5=5), izstopimo iz procedure
NOVA-BARVA.
6. Smo ponovno v proceduri BARVANJE-GRAFA v vrstici 3 na globini 1. Ker nista
izpolnjena pogoja pri 1. if (x[2] 6= 0) in 2. if (k = 2 6= n = 4), sestopimo v
globino 2 s klicem BARVANJE-GRAFA(4, c, 3, 3, x,0).
7. Vstopimo v proceduro NOVA-BARVA(4, c, 3, 3, x). Najprej določimo:
x[3] = (0 + 1)
mod 4 = 1.
Pogoj pri 1. if (x[3] 6= 0) ni izpolnjen, zato postavimo j = 1. Zanka while
se izvede 4-krat, saj so izpolnjeni vsi pogoji:
1 ≤ 4 and not (F and x[3] = x[1]) = T ⇒ j = 2
2 ≤ 4 and not (T and x[3] 6= x[2]) = T ⇒ j = 3
3 ≤ 4 and not (F and x[3] = x[3]) = T ⇒ j = 4
4 ≤ 4 and not (T and x[3] 6= x[4]) = T ⇒ j = 5
Ker je pri 2. if izpolnjen pogoj (j = n + 1 ali 5=5), izstopimo iz procedure
NOVA-BARVA.
5-27
5.4 Barvanje grafov
8. Smo ponovno v proceduri BARVANJE-GRAFA v vrstici 3 na globini 2. Ker nista
izpolnjena pogoja pri 1. if (x[1] 6= 0) in 2. if (k = 3 6= n = 4), sestopimo v
globino 3 s klicem BARVANJE-GRAFA(4, c, 3, 4, x,0).
9. Vstopimo v proceduro NOVA-BARVA(4, c, 3, 4, x).
a) 1. iteracija zanke loop:
Najprej določimo:
x[4] = (0 + 1) mod 4 = 1.
Pogoj pri 1. if (x[4] 6= 0) ni izpolnjen, zato postavimo j = 1. Zanka while
se ne izvede niti enkrat, saj ni izpolnjen pogoj:
1 ≤ 4 and not (T and x[4] = x[1]) = F
Ker pri 2. if ni izpolnjen pogoj (j = n + 1 ali 1 6= 5), končamo iteracijo
zanke loop.
b) 2. iteracija zanke loop:
Najprej določimo:
x[4] = (1 + 1) mod 4 = 2.
Pogoj pri 1. if (x[4] 6= 0) ni izpolnjen, zato postavimo j = 1. Zanka while
se izvede 4-krat, saj so izpolnjeni vsi pogoji:
1 ≤ 4 and not (T and x[4] 6= x[1]) = T ⇒ j = 2
2 ≤ 4 and not (F and x[4] = x[2]) = T ⇒ j = 3
3 ≤ 4 and not (T and x[4] 6= x[3]) = T ⇒ j = 4
4 ≤ 4 and not (F and x[4] = x[4]) = T ⇒ j = 5
Ker je pri 2. if izpolnjen pogoj (j = n + 1 ali 5=5), izstopimo iz procedure
NOVA-BARVA.
10. Smo ponovno v proceduri BARVANJE-GRAFA v vrstici 3 na globini 3. Ker ni
izpolnjen pogoj pri 1. if (x[4] 6= 0), gremo do 2. if, kjer je pogoj izpolnjen
(k = 4 6= n = 4), zato izpišemo prvo možno rešitev:
[x[1] x[2] x[3] x[4]] = [1 2 1 2].
11. Zopet se vrnemo na začetek procedure BARVANJE-GRAFA (naslednja iteracija
zanke loop) v globini 3. Vstopimo v proceduro NOVA-BARVA(4, c, 3, 4, x).
Najprej določimo:
x[4] = (2 + 1) mod 4 = 3.
Pogoj pri 1. if (x[4] 6= 0) ni izpolnjen, zato postavimo j = 1. Zanka while
se izvede 4-krat, saj so izpolnjeni vsi pogoji. Ker je pri 2. if izpolnjen pogoj
(j = n + 1 ali 5=5), izstopimo iz procedure NOVA-BARVA.
5-28
5.4 Barvanje grafov
12. Smo ponovno v proceduri BARVANJE-GRAFA v vrstici 3 na globini 3. Ker ni
izpolnjen pogoj pri 1. if (x[4] 6= 0), gremo do 2. if, kjer je pogoj izpolnjen
(k = 4 = n = 4), zato izpišemo drugo možno rešitev:
[x[1] x[2] x[3] x[4]] = [1 2 1 3].
13. Vrnemo se na začetek procedure BARVANJE-GRAFA (naslednja iteracija zanke
loop) v globini 3. Vstopimo v proceduro NOVA-BARVA(4, c, 3,4, x). Najprej
določimo:
x[4] = (3 + 1) mod 4 = 0.
Pogoj pri 1. if je izpolnjen (x[4] = 0), zato izstopimo iz procedure NOVABARVA, saj smo izčrpali vse barve.
14. Smo ponovno v proceduri BARVANJE-GRAFA v vrstici 3 na globini 3. Ker je
izpolnjen pogoj pri 1. if (x[4] = 0), izstopimo iz procedure in se vrnemo na
globino 2, da preiščemo še ostale možnosti za x[3].
Na ta način nadaljujemo, dokler ne poiščemo vseh možnih rešitev. Delovanje
procedure BARVANJE-GRAFA lahko opišemo z drevesom stanj na sliki 5.18. Rešitve
predstavljajo listi z najvišjim nivojem, tj. n. Vseh rešitev je 18, od tega je 6
rešitev z 2 barvama in 12 rešitev s 3 barvami. Rešitve z 2 barvama so označene s
puščico. Za dani graf velja, da ima kromatično število 2. ♦
Slika 5.18: Drevo prostora stanj in vse možnosti barvanja z največ 3 barvami.
5-29
5.4 Barvanje grafov
Časovna zahtevnost algoritma BARVANJE-GRAFA
Zgornja meja časovne zahtevnosti je:
T (n) = O(nmn ).
Literatura
Aho, A. V., Hopcroft, J. E., and Ullman, J. D. (1974). The Design and Analysis
of Computer Algorithms. Addison-Wesley, Reading.
Cormen, T. H., Leiserson, C. E., and Rivest, R. L. (2007). Introduction to Algorithms. Druga izdaja, MIT Press, Cambridge.
Horowitz, E., Sahni, S., and Rajasekaran, S. (1998). Computer Algorithms. Computer Science Press, New York.
Kleinberg, J. and Tardos, E. (2006). Algorithm Design. Parson Education, Inc.,
New York.
Kononenko, I. (1996). Načrtovanje podatkovnih struktur in algoritmov. Fakulteta
za računalništvo in informatiko, Ljubljana.
Kozak, J. (1997). Podatkovne strukture in algoritmi. Društvo matematikov, fizikov
in astronomov Slovenije, Ljubljana.
Levitin, A. (2007). The Design and Analysis of Algorithms. Druga izdaja, Pearson
Education, Inc., Boston.
Manber, U. (1989). Introduction to Algorithms. A Creative Approach. AddisonWesley, Reading.
Nilsson, N. J. (1980). Principles of Artificial Intelligence. Tioga.
Sedgewick, R. (2003).
Boston.
Algorithms in Java.
Third Edition. Addison-Wesley,
Vilfan, B. (1998). Osnovni algoritmi. Fakulteta za računalništvo in informatiko,
Ljubljana.