Symbolische Suche

Werbung
Algorithmische Intelligenz
„Symbolische Suche“
Peter Kissmann
Spiele
 Einpersonenspiele
(n² - 1)-Puzzle
Solitär
 Zweipersonenspiele
Tic-Tac-Toe
Clobber
Vier Gewinnt
Motivation
 Zustandsraumexplosion
#erreichbare Zustände:
 (n²-1)-Puzzle: (n²)!/2
• 15-Puzzle: ≈ 1013
• 24-Puzzle: ≈ 7,8 x 1024
• 35-Puzzle: ≈ 1,9 x 1041
 Solitär: 375 110 246
 Clobber (4x5): 26 787 440
 4 Gewinnt: ≤ 70 728 639 995 483 (≈ 7 x 1013) (Allis, 1988)
(tatsächlich: 4 531 985 219 092 (≈ 4,5 x 1012))
Motivation
 Speicher sparen z.B. mittels Binären
Entscheidungsdiagrammen (BDDs)
verwalten Zustandsmengen
sparen unnötige Knoten ein → teils exponentiell viele
 Beispiel: vollständiges Lösen von allgemeinen Spielen
(General Game Playing)
Überblick
 Wiederholung: BDDs
 BDD-basierte Suche
 BFS, Dijkstra, A*
 Anwendung auf allgemeine Spiele („General Game
Playing“)
 BDDs als perfekte Hash-Funktion
Überblick
 Wiederholung: BDDs
 BDD-basierte Suche
 BFS, Dijkstra, A*
 Anwendung auf allgemeine Spiele („General Game
Playing“)
 BDDs als perfekte Hash-Funktion
BDDs (Binary Decision Diagrams)
 Repräsentieren Zustandsmenge
 gerichteter azyklischer Graph von Wurzel zu 0- oder 1-
Senke
 Knoten für (binäre) Variablen
Zwei Ausgänge: low und high (auch 0 und 1)
 Pfad von Wurzel bis 1-Senke
Zustand entsprechender Variablenbelegung in repräsentierter Menge
enthalten
OBDDs (Ordered BDDs)
 Feste Variablenordnung π
Gute Variablenordnung → exponentiell weniger Knoten
(möglicherweise)
Finden guter Variablenordnung NP-schwer
 Graphisch: Schichten gleicher Variablen
ROBDDs (Reduced OBDDs)
 Zwei Vereinfachungsregeln:
 ROBDDs eindeutig
 Im Folgenden nur ROBDDs
x1
x1
x2
x3
x1
x2
x3
BDDs für logische Operatoren
x 1 ∧x 2
x 1 ∨x 2
x1
x1
0
x2
x2
1
0
x1 ⇔ x2
¬x 1
1
x1
0
x1
1
x2
x2
0
1
ROBDDs (Beispiele)
columnx
rowx
diagonalx
Überblick
 Wiederholung: BDDs
 BDD-basierte Suche
 BFS, Dijkstra, A*
 Anwendung auf allgemeine Spiele („General Game
Playing“)
 BDDs als perfekte Hash-Funktion
BDD-basierte Suche
(Voraussetzungen)
 S Menge aller Zustände
 Initialzustand I ∈ S
 Menge von Zielzuständen G ⊆ S
 Transitionsrelation T ⊆ S x S
beschreibt Zustandsübergänge durch Vorgänger und Nachfolger
 mögliche Ziele:
finde kürzesten Pfad von I nach g ∈ G
berechne alle erreichbaren Zustände
 2 Variablensätze:
x für Vorgängervariablen
x‘ für Nachfolgervariablen
 in Variablenordnung xi und xi‘ abwechselnd (interleaved)
BDD-basierte Suche
 Finden von Nachfolgern (image)
Relationales Produkt:
image ( s ) =∃ x . ( T ( x , x ' ) ∧s ( x ) )
 Finden von Vorgängern (pre-image) analog:
preimage ( s ) =∃ x ' . ( T ( x , x ' ) ∧s ( x ' ) )
 zusätzlich: nach jedem (pre-)image:
Verschieben der Variablen
BDD-basierte Suche
 Partitionierte Berechnung:
T = VaTa für alle Aktionen a
∃ und ∨ kommutieren
image ( s ) =¿ a ∃ x . ( T a ( x , x ' ) ∧s ( x ) )
(entsprechend auch für pre-image)
Vorteil: Berechnung monolithischer Transitionsrelation teuer (Zeit und
Speicher)
BDD-basierte Suche
 Finden der Vorgänger, deren Nachfolger alle in s liegen
(strong pre-image):
strong preimage ( s )=∀ x ' . ( T ( x , x ' ) ⇒ s ( x ' ) )
 strong pre-image auf pre-image zurückführbar →
Übungsaufgabe
BDD-basierte Suche
 strong
image pre-image
pre-image
Überblick
 Wiederholung: BDDs
 BDD-basierte Suche
 BFS, Dijkstra, A*
 Anwendung auf allgemeine Spiele („General Game
Playing“)
 BDDs als perfekte Hash-Funktion
Breitensuche (SBFS)
 iterativ images berechnen
reach ← I
wiederhole
 newBDD ← image(reach) ∧ ⌐reach
 reach ← reach ∨ newBDD
solange Abbruchkriterium nicht erfüllt
 mögliche Abbruchkriterien:
newBDD = ⊥ (alle Zustände bestimmt)
reach ∧ G ≠ ⊥ (kürzester Weg zum Ziel gefunden)
Mögliche Verbesserung
 Jeden Zustand nur einmal expandieren
(Duplikatserkennung)
 Dazu: Closed-BDD
front ← I
wiederhole
 closed ← closed ∨ front
 front ← image(front) ∧ ⌐closed
solange Abbruchkriterium nicht erfüllt
Bestimmung erreichbarer
Zustände
v: Anzahl Variablen für einen Zustand
mittels SBFS n: Anzahl BDD-Knoten zur Repräsentation aller
Zustände
s: Anzahl aller erreichbarer Zustände
Bestimmung erreichbarer Zustände in „Vier
Gewinnt“ (SBFS)
Bestimmung erreichbarer Zustände in „Vier
Gewinnt“ (SBFS)
1E+14
1E+12
1E+10
1E+08
1E+06
1E+04
Knoten (BDD)
Zustände (BDD)
Zustände (Allis-Schätzung)
1E+02
1E+00
0
5
10
15
20
25
30
35
40
Bidirektionale Breitensuche (SBBFS)
Schnitt
gefunden
I
G
Bidirektionale Breitensuche (SBBFS)
 BFS von Start und Ziel „gleichzeitig“
Ende, wenn Suchfronten überschneiden
 ffront ← I, bfront ← G
 wiederhole
• falls vorwärts
 ffront ← image(ffront)
• sonst
 bfront ← pre-image(bfront)
 solange ffront ∧ bfront = ⊥
Auswahlkriterium etwa Zeit der letzten Iteration
Verwendung von closed-BDDs möglich
Symbolischer Dijkstra
 BFS nur bei uniformen Kosten
 Gewichtete Transitionsrelation → „Single Source Shortest
Path“→ Dijkstra
Kosten c ∈ {1, …, C}
T = VcTc
Symbolischer Dijkstra
open0 ← I, closed ← ⊥, g ← 0
wiederhole
 falls (openg ∧ G ≠ ⊥) STOPP
 openg ← openg ∧ ⌐closed
 für c ← 1, …, C
• openg+c ← openg+c ∨ imagec(openg)
 closed ← closed ∨ openg
 g←g+1
Symbolisches A* (BDDA*)
 Ähnlich Dijkstra; Expansion nach f-Wert:
f ( v )=g ( v ) +h ( v )
 Verwendung einer Heuristik
z.B. aus Musterdatenbank (pattern database (PDB))
Heuristik h darf nicht überschätzen (zulässig)
 h = 0 → Dijkstra
Symbolisches A* (BDDA*)
h
g
Symbolisches A* (BDDA*)
 open(0,h(I)) ← I, closed(0, …, |h|) ← ⊥, f ← h(I)
 wiederhole
für g ← 0, …, f
h←f-g
falls (h = 0 & open(g, h) ∧ G ≠ ⊥) STOPP
open(g, h) ← open(g, h) ∧ ⌐ closed(h)
für c ← 1, …, C
• succc ← imagec(open(g, h))
• für hsucc ← 0, …, |h|
 open(g + c, hsucc) ← open(g + c, hsucc) ∨ (succc ∧ hsucc)
 closed(h) ← closed(h) ∨ open(g, h)




f ← f + 1
Überblick
 Wiederholung: BDDs
 BDD-basierte Suche
 BDD-BFS, BDD-Dijkstra, BDDA*
 Anwendung auf allgemeine Spiele („General Game
Playing“)
 BDDs als perfekte Hash-Funktion
Überblick 2 (Lösen allgemeiner
Spiele)
 General Game Playing
 Einpersonenspiele
 Zweipersonenspiele
Zweipersonen-Nullsummenspiele
Zweipersonenspiele mit allgemeinen Gewinnen
Überblick 2 (Lösen allgemeiner
Spiele)
 General Game Playing
 Einpersonenspiele
 Zweipersonenspiele
Zweipersonen-Nullsummenspiele
Zweipersonenspiele mit allgemeinen Gewinnen
General Game Playing
 Beschreibung für Spiele mit folgenden Eigenschaften:
endlich
diskret
deterministisch
vollständige Information
 Spiele können
Ein- oder Mehr-Personenspiele sein
gleichzeitige oder abwechselnde Züge ermöglichen
General Game Playing
 „Game Description Language“ (GDL)
 Gegeben:
Initialzustand
Bestimmung legaler Züge
Effekt eines Zuges
Terminierungsbedingungen
Verteilung der Gewinne {0, …, 100} darin
 Gesucht:
Lösung erreichbarer Zustände
Bestimmung optimaler Gewinn-Verteilung
General Game Playing
 Beispiele:
Blocksworld
 Original GDL-Datei: .kif
Tic-Tac-Toe
 Original GDL-Datei: .kif
 Mehr Informationen:
http://games.stanford.edu (dort entwickelt; leider veraltet)
http://www.general-game-playing.de
http://euklid.inf.tu-dresden.de:8180/ggpserver (aktuelle Spiele etc.)
Überblick 2 (Lösen allgemeiner
Spiele)
 General Game Playing
 Einpersonenspiele
 Zweipersonenspiele
Zweipersonen-Nullsummenspiele
Zweipersonenspiele mit allgemeinen Gewinnen
Lösen von Einpersonenspielen
 Erst: Erreichbare Zustände finden (BFS)
 Dann: Rückwärtssuche
Start: Zielzustände mit Gewinn 100
 BFS (rückwärts)
Weiter: Zielzustände mit Gewinn 99
 BFS (rückwärts)
 dabei: bereits gelöste Zustände auslassen
Weiter bis Gewinn 0
Lösen von Einpersonenspielen
100
100
100
99
100
75
100
90
80
90
80
90
80
80
75
75
Ergebnisse für Solitär
 Erreichbar: 375 110 246 Zustände
Überblick 2 (Lösen allgemeiner
Spiele)
 General Game Playing
 Einpersonenspiele
 Zweipersonenspiele
Zweipersonen-Nullsummenspiele
Zweipersonenspiele mit allgemeinen Gewinnen
Lösen von ZweipersonenNullsummenspielen
 Mögliche Gewinne: 0, 50, 100
 Jeder Spieler versucht, möglichst hohen Gewinn zu
erreichen
 Lösung liefert Verteilung der Gewinne (bei optimaler
Spielweise)
Lösen von ZweipersonenNullsummenspielen


BFS für Finden erreichbarer Zustände
Zwei Rückwärtssuchen (eine pro Spieler):


Start bei verlorenen Zielzuständen
Bestimmung verlorener Vorgänger (2 Schritte)


für alle Züge, die Spieler durchführen kann, kann Gegenspieler Zug zu verlorenem
Zustand wählen (pre-image und strong pre-image)
Iterieren, solange neue Zustände gefunden
player 0‘s turn
player 1‘s turn
lost for player 0
lost for player 1
Lösen von ZweipersonenNullsummenspielen
reach ← berechneErreichbareZustände()
für jeden Spieler p ∈ {0, 1}
 front ← verlorenp ← reach ∧ gewinn(p, 0) ∧ G ∧ zugp
 gewonnen1-p ← reach ∧ gewinn(p, 0) ∧ G ∧ zug1-p
 wiederhole
• pred ← pre-image(front) ∧ reach
• gewonnen1-p ← gewonnen1-p ∨ pred
• front ← strong-pre-image(gewonnen1-p) ∧ reach ∧ ⌐verlorenp
• verlorenp ← verlorenp ∨ front
 solange front ≠ ⊥
Überblick 2 (Lösen allgemeiner
Spiele)
 General Game Playing
 Einpersonenspiele
 Zweipersonenspiele
Zweipersonen-Nullsummenspiele
Zweipersonenspiele mit allgemeinen Gewinnen
Lösen allgemeiner
Zweipersonenspiele
 Mögliche Gewinne ∈ {0, …, 100}
 Verwendung von (101 x 101)-Matrix
Zustand an Position (i, j):
 i Punkte für Spieler 0
 j Punkte für Spieler 1
 falls unvollständig, Verwendung als Endspieldatenbank
Lösen allgemeiner
Zweipersonenspiele
 Eine Vorwärts- und eine Rückwärtssuche
finde alle Vorgänger, deren Nachfolger alle gelöst sind (strong preimage)
finde optimales Bucket für diese (pre-image)
füge sie ein
iteriere, bis alle Zustände gelöst
Einschub: Reihenfolge beim Lösen
 schwierig im allgemeinen Fall
(und gegnerischen minimieren)?
Gewinn maximieren?
 Hier: 2. Fall
0
own
…
100
…
100
0
opponent
 oder Differenz zum gegnerischen
100
0
opponent
 eigenen Gewinn maximieren
0
own
…
…
100
Beispiel
player 0
0
1
2
0/1
3
player 1
0
0/1
0/3
0/1
1
2
0/1
3/1
0/3
0/1
2/0
3
0/1
0/1
3/1
2/0
3/1
0/1
0/3
0/1
2/0
3/1
player 0‘s turn
player 1‘s turn
0/1
3/1
2/0
3/1
Lösen allgemeiner
Zweipersonenspiele
reach ← berechneErreichbareZustände()
init matrix; solved ← alle Zustände in Matrix
unsolved ← reach ∧ ⌐solved
solange unsolved ≠ ⊥
 für jeden Spieler p ∈ {0, 1}
• solvable ← strong-pre-image(solved) ∧ unsolved ∧ zugp
• falls solvable ≠ ⊥



matrix ← fügeZuständeEin(solvable, p, matrix)
solved ← solved ∨ solvable
unsolved ← unsolved ∧ ⌐solvable
Ergebnisse
Game
t0-sum
tnew
Clobber 3x4
1.1s
Clobber 3x4 0-sum
1.0s
1.4s
Clobber 4x5
- 2:14:20
Clobber 4x5 0-sum 0:54:35 1:22:09
Minichess
1.0s
0.7s
TicTacToe
0.1s
0.2s
Nim 40
0.0s
0.1s
Überblick
 Wiederholung: BDDs
 BDD-basierte Suche
 BDD-BFS, BDD-Dijkstra, BDDA*
 Anwendung auf allgemeine Spiele („General Game
Playing“)
 BDDs als perfekte Hash-Funktion
Hashing
 Gegeben: Menge von Zuständen S
 Gesucht: Abbildung S → R ⊆ ℕ
 Hashfunktion ordnet jedem Zustand einen Wert zu
 perfektes Hashing: Hashwert jedes Zustandes eindeutig
 minimales perfektes Hashing: |R| = |S|
Sat-Count
 Anzahl gespeicherter Zustände in BDD G
 mögliche Berechnung:
sat-count(0-Senke) ← 0, sat-count(1-Senke) ← 1
für Knoten v aus Schicht i mit 0-Nachfolger u in Schicht j > i und 1Nachfolger w in Schicht k > i
 sat-count(v) ← 2j-i-1 * sat-count(u) + 2k-i-1 * sat-count(w)
falls Wurzel in Schicht i:
 sat-count(G) ← 2i-1 * sat-count(Wurzel)
 Laufzeit- und Speicherbedarf: ≤ O(|G|)
Sat-Count (Beispiel)
30
 abgedeckte
Zustände:
14
4
2
1
000001
16
000111
001011
001101
010011
010100
2010101
5
010110
1
010111 2
011011
1
0
1
011100
011101
011110
011111
100011
100100
3100101
100110
100111
101011
101100
101101
101110
101111
110010
110011
110111
111010
111011
111111
Ranking
 Gegeben: BDD G, Zustand s
 Gesucht: Hash-Wert von s (in {0, …, sat-count(G) - 1})
 Vorverarbeitung:
Berechne Sat-Count aller Knoten
speichere diese Sat-Counts
Ranking
 rank(G,s)
falls Wurzel in Schicht i
 d ← Binärwert von (s1, …, si-1)
 gib (d+1) * lexicographic-count(G,s,Wurzel) - 1 zurück
Ranking
 lexicographic-count(G,s,v)
falls v 0-Senke, gib 0 zurück; falls v 1-Senke, gib 1 zurück
falls v in Schicht i mit 0-Nachf. u in j und 1-Nachf. w in k
 falls si = 0
• r0 ← lexicographic-count(G,s,u)
• d0 ← Binärwert von (si+1, …, sj-1)
• gib d0 * sat-count(u) + r0 zurück
 falls si = 1
• r1 ← lexicographic-count(G,s,w)
• d1 ← Binärwert von (si+1, …, sk-1)
• gib 2j-i-1 * sat-count(u) + d1 * sat-count(w) + r1 zurück
Ranking (Beispiel)
30 v
14 v
4
2
0
 s ← 011101
16 v
1
rank(G,s) ← [()2 + 1] * lc(G,s,v0) - 1
2
lc(G,s,v0) ← ()2 * sc(v1) + lc(G,s,v1)
v3
lc(G,s,v1) ← 23-2-1 * sc(v3) + (1)2 * sc(v6) + lc(G,s,v6)
2
v4
v5
5
v6
3
lc(G,s,v6) ← 25-4-1 * sc(v9) + (01)2 * sc(v13) + lc(G,s,v13)
vv
7
13 ist 1-Senke → lc(G,s,v13) ← 1
lc(G,s,v6) ← 20 * sc(v9) + 1 * sc(v13) + lc(G,s,v13)
1
v8
1
1
v11
0
v12
v9
2
v10
=1*1+1*1+1=3
lc(G,s,v1) ← 20 * sc(v3) + 1 * sc(v6) + lc(G,s,v6)
= 1 * 4 + 1 * 5 + 3 = 12
lc(G,s,v0) ← 0 * sc(v1) + lc(G,s,v1) = 12
1
v13
rank(G,s) ← 1 * lc(G,s,v0) - 1 = 11
Unranking
 Gegeben: BDD G, Hash-Wert r
 Gesucht: zugehöriger Zustand
Unranking
 unrank(G,r)
starte an der Wurzel
falls Wurzel in Schicht l
 (s1, …, sl-1) ← Binärrepräsentation von r div sat-count(Wurzel)
 r ← r mod sat-count(Wurzel)
v ← Wurzel; i ← l
wiederhole, bis v 0- oder 1-Senke
 falls v Knoten in Schicht i mit 0-Nachf. u in j 1-Nachf. w in k
• falls r < 2j-i-1 * sat-count(u)
 si ← 0; (si+1, …, sj-1) ← Binärrepräsentation von r div sat-count(u)
 r ← r mod sat-count(u)
 v ← u; i ← j
• falls r ≥ 2j-i-1 * sat-count(u)
 si ← 1; r ← r - 2j-i-1 * sat-count(u)
 (si+1, …, sk-1) ← Binärrepräsentation von r div sat-count(w)
 r ← r mod sat-count(w)
 v ← w; i ← k
Unranking (Beispiel)
30 v
14 v
0
 r ← 19
16 v
1
 s ← 101011
1
101
1010
10101
i ← 1; r ≥ 22-1-1 * sc(v1) = 1 * 14 = 14
2
 s1 ← 1; r ← r - 22-1-1 * sc(v1) = 19 - 1 * 14 = 5
4
2
 r ← r mod sc(v2) = 5 mod 16 = 5
v3
i ← 2; r < 24-2-1 * sc(v6) = 2 * 5 = 10
2
v4
1
v8
1
v5
1
5
v9
v6
2
3
v10
v7
 s2 ← 0; (s3) ← (r div sc(v6))2 = (5 div 5)2 = 12 = 1
 r ← r mod sc(v6) = 5 mod 5 = 0
i ← 4; r < 25-4-1 * sc(v9) = 1 * 1 = 1
 s4 ← 0; r ← r mod sc(v9) = 0 mod 1 = 0
i ← 5; r ≥ 26-5-1 * sc(v12) = 2 * 0 = 0
v11
 s5 ← 1; r ← r - 27-5-1 * sc(v12) = 0 - 2 * 0 = 0
 r ← r mod sc(v11) = 0 mod 1 = 0
0
v12
1
v13
i ← 6; r ≥ 27-6-1 * sc(v12) = 1 * 0 = 0
 s6 ← 1; r ← r - 27-6-1 * sc(v12) = 0 - 1 * 0 = 0
Ranking und Unranking (Analyse)
 Vorverarbeitung: O(|G|)
 Ranking pro Zustand: O(n)
 Unranking pro Zustand: O(n)
 Vorverarbeitung beschriftet jeden Knoten mit n-bit Zahl →
O(n|G|) extra Bits nötig
Zusammenfassung
 Symbolische Suche zur Verringerung der Speicherlast
speichern von Zustandsmengen (als BDDs) statt einzelner Zustände
 Vorgänger- und Nachfolgerberechnungen (image und pre-
image) liefern direkt SBFS und SBBFS
 Symbolische Formen von Dijkstra und A*
 Lösen von Spielen mittels symbolischer Suche
 BDDs als perfekte Hash-Funktion
Herunterladen