Graph Algorithms for FII Gamedev
-
Upload
vlad-manea -
Category
Education
-
view
965 -
download
8
Transcript of Graph Algorithms for FII Gamedev
graf?gamedev:null
Vlad Manea, Radu Vasile Gagos {vlad.manea, radu.gagos}@info.uaic.ro
Clubul dezvoltatorilor de jocuri «FII Gamedev» Microsoft Student Partners
Salut
Arbori parțiali de cost minim Kruskal • Prim Drum minim de sursă multiplă Floyd Warshall = Roy Floyd Drum (minim) de sursă unică Bellman Ford • Dijkstra • A* Search
Cuprins
Mulțimea (setul) de vârfuri V pot fi etichetate de la 1 la N. Mulțimea de arce E inclusă în mulțimea ordonată V2
,
pot fi etichetate de la 1 la M. Funcția de cost are forma f: E → ℝ.
Graful G = (V, E)
7.3
Graf orientat ordinea vârfurilor din (i, j) ∊ E contează. Graf neorientat arc = muchie și dacă (i, j) ∊ E, atunci (j, i) ∊ E. Componentă conexă subset maximal al lui V cu vârfuri conectate, G conex dacă are o singură componentă.
Tipuri de grafuri
Exemplu de graf
Graf neorientat conex aciclic are M = N – 1 muchii. Arbore parțial al unui graf conex G = (V, E) arbore care conține toată mulțimea V.
Arbore parțial de cost minim (APM) are suma costurilor muchiilor minimă
în raport cu cei MN−1
arbori parțiali.
Arbore
Arbore parțial
Arbore parțial
Arbore parțial
APM-Generic(G, f) 1. A ⟵ ∅ 2. cât timp A nu este APM execută 3. găsește (u, v) ∊ E sigură pentru A 4. A ⟵ A ∪ {(u, v)} 5. întoarce A
Pasul 3 este cel mai dificil algoritmii Kruskal și Prim îl implementează.
Arbore parțial de cost minim
APM-Kruskal(G, f) 1. A ⟵ ∅ 2. pentru v ∊ V execută 3. Formează-Set(v) 3. Sortează muchiile din E după costurile f 4. pentru (u, v) ∊ E execută 5. dacă Găsește-Set(u) ≠ Găsește-Set(v) atunci 6. A ⟵ A ∪ {(u, v)} 7. Unește(u, v) 8. întoarce A
Demonstrații de corectitudine în [1][2]
APM-Kruskal
Se sortează E cu un algoritm rapid în complexitatea timp O(M × log(M)). Operațiile de Uniune-Găsire se realizează cu păduri de mulțimi disjuncte Iar complexitatea timp este O(M × α(M, N)). Întreg algoritmul are complexitatea timp O(M × log(M)).
APM-Kruskal
Exemple preluate din [2]
APM-Kruskal
1
2 3 5 6
4
9 5 3 1
2
7 3 1
1 43 6
5
2
3 4
5
56 81
80
44
62
APM-Prim(G, f , r) 1. Q ⟵ V 2. pentru u ∊ Q execută 3. distanță[u] ⟵ ∞ 4. distanță[r] ⟵ 0 5. tată[r] ⟵ NIL 6. cât timp Q ≠ ∅ execută 7. u ⟵ Extrage-Min(Q) 8. pentru v ∊ {w | (u, w) ∊ E} execută 9. dacă v ∊ Q și f(u, v) < distanță[v] atunci 7. tată[v] ⟵ u 8. distanță[v] ⟵ f(u, v) 9. Actualizează-Min(Q, v, distanță[v])
APM-Prim
Operațiile Extrage-Min și Actualizează-Min sunt implementate cu ajutorul unui heap/set, complexitatea timp totală e O(M × log(N)). Întreg algoritmul are complexitatea timp O(M × log(N)), aceeași cu cea Kruskal deoarece M < N2.
Demonstrație de corectitudine în [1]
APM-Prim
APM-Prim
Exemple preluate din [2]
1
2 3 5 6
4
9 5 3 1
2
7 3 1
1 43 6
5
2
3 4
5
56 81
80
44
62
Drum Secvență de arce din E. Costul unui drum este suma costurilor arcelor lui.
Drum (de cost) minim de la u la v orice alt drum de la u la v are un cost mai mare sau egal cu costul lui.
Drum de cost minim
Enunțarea problemei Să se găsească drumul de cost minim între oricare două vârfuri din V. Soluția prin programare dinamică Se poate demonstra [3] că un drum de cost minim de la u la w este concatenarea a două drumuri de cost minim: un drum de cost minim de la u la v și unul de la v la w.
Drum minim de sursă multiplă
DM-Floyd-Warshall
DM-Floyd-Warshall(A) 1. D ⟵ A 2. pentru k ⟵ 1, N execută 3. pentru i ⟵ 1, N execută 4. pentru j ⟵ 1, N execută 5. Dij = min(Dij, Dik + Dkj) 6. întoarce D
Demonstrații de corectitudine în [1][3]
Ordinea <k, i, j> este importantă Între i și j apar intermediari doar din {1, …, k}. Întreg algoritmul are complexitatea timp O(N3).
Algoritmul poate fi modificat pentru a calcula și un drum de cost minim, pentru a calcula închiderea tranzitivă a lui G.
DM-Floyd-Warshall
Enunțarea problemei Să se găsească drumul de cost minim între un vârf sursă u și oricare vârf din V. Soluția prin greedy Vom presupune pentru simplitate că funcția f: E → ℝ₊. Fiecare vârf este apropiat cât mai mult de sursă în unul sau mai mulți pași. Vârful cel mai apropiat este ales greedy.
Drum minim de sursă unică
DM-Bellman-Ford(G, f , s) 01. pentru u ∊ V execută 02. distanță[u] ⟵ ∞ 03. distanță[s] ⟵ 0 04. tată[s] ⟵ NIL 05. Q ⟵ s 06. cât timp Q ≠ ∅ execută 07. u ⟵ Pop-Coadă(Q) 08. pentru v ∊ {w | (u, w) ∊ E} execută 09. dacă distanță[v] > distanță[u] + f(u, v) atunci 10. distanță[v] ⟵ distanță[u] + f(u, v) 11. tată[v] ⟵ u 12. Push-Coadă(Q, v)
DM-Bellman-Ford
Operațiile Pop-Coadă și Push-Coadă necesită timp constant, deci au complexitatea timp constant O(1). Întreg algoritmul are complexitatea timp O(M × N), dar în practică se comportă foarte bine.
Demonstrație de corectitudine în [1]
DM-Bellman-Ford
DM-Bellman-Ford
Exemple preluate din [2]
1 2
1 43 6
5
2
3 4
5
56 81
80
44
62
4 5
3 6 7
2
3
8
10
2
4 7
1
20 2
3 1
2 3 5 6
4
9 5 3 1
2
7 3 1
DM-Dijkstra
DM-Dijkstra(G, f , s) 01. pentru u ∊ V execută 02. distanță[u] ⟵ ∞ 03. distanță[s] ⟵ 0 04. tată[s] ⟵ NIL 05. S ⟵ ∅ 06. Q ⟵ V 07. cât timp Q ≠ ∅ execută 08. u ⟵ Extrage-Min(Q) 09. S ⟵ S ∪ {u} 10. pentru v ∊ {w | (u, w) ∊ E} execută 11. dacă distanță[v] > distanță[u] + f(u, v) atunci 12. distanță[v] ⟵ distanță[u] + f(u, v) 13. Actualizează-Distanță(Q, v, distanță[v]) 14. tată[v] ⟵ u
Actualizează-Distanță și Extrage-Min sunt implementate cu ajutorul unui heap/set; complexitatea timp totală e O(N × log(N)). Algoritmul Dijkstra are complexitatea timp O((M + N) × log(N)), deoarece fiecare muchie poate actualiza Q.
Demonstrație de corectitudine în [1]
DM-Dijkstra
DM-Dijkstra
Exemple preluate din [2]
1 2
1 43 6
5
2
3 4
5
56 81
80
44
62
4 5
3 6 7
2
3
8
10
2
4 7
1
20 2
3 1
2 3 5 6
4
9 5 3 1
2
7 3 1
Enunțarea problemei Găsiți rapid un drum de cost aproape minim între un vârf sursă u și un vârf v. Soluția prin euristică Dacă estimăm drumul spre destinație, atunci vârfurile mai apropiate au șanse mai mari. Fie estimatorul e: V → ℝ₊, care se adaugă la distanță, obținându-se criteriul distanță*.
Drum minim de sursă unică
DM-A*-Search
DM-A*-Search (G, f , e, s) 01. pentru u ∊ V execută 02. distanță[u] ⟵ ∞ 03. distanță[s] ⟵ 0 04. tată[s] ⟵ NIL 05. S ⟵ ∅ 06. Q ⟵ V 07. cât timp Q ≠ ∅ execută 08. u ⟵ Extrage-Min*(Q) 09. S ⟵ S ∪ {u} 10. pentru v ∊ {w | (u, w) ∊ E} execută 11. dacă distanță[v] > distanță[u] + f(u, v) atunci 12. tată[v] ⟵ u
13. distanță[v] ⟵ distanță[u] + f(u, v) 14. Actualizează-Min*(Q, v, distanță*[v])
Operațiile Extrage-Min* și Actualizează-Min* sunt implementate cu ajutorul unui heap/set, deci complexitatea timp a uneia e O(log(N)). Întreg algoritmul poate avea complexitate exponențială, dar în practică se comportă excelent! Exemple pe internet
DM-A*-Search
Lecții http://en.wikipedia.org/wiki/Pathfinding http://www.policyalmanac.org/games/aStarTutorial.htm http://theory.stanford.edu/~amitp/GameProgramming/
Demo http://links.math.rpi.edu/applets/appindex/graphtheory.html http://www.unf.edu/~wkloster/foundations/DijkstraApplet/DijkstraApplet.htm http://jung.sourceforge.net/applet/shortestpath.html
Cărți [1] Thomas Cormen, Charles Leiserson, Ronald Rivest, Introducere în algoritmi, Agora 2000 [2] Emanuela Cerchez, Marinel Șerban, Programarea în limbajul C/C++ pentru liceu •••, Polirom 2006 [3] Dorel Lucanu, Mitică Craus, Proiectarea algoritmilor, Polirom 2008
Referințe
Mulțumim:)
Vlad Manea, Radu Vasile Gagos {vlad.manea, radu.gagos}@info.uaic.ro