algorithm engineering „symbolische suche“

Post on 02-Feb-2016

46 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Algorithm Engineering „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: ≈ 10 13 - PowerPoint PPT Presentation

TRANSCRIPT

Algorithm Engineering „Symbolische Suche“

Peter Kissmann

Spiele

Einpersonenspiele(n² - 1)-PuzzleSolitär

ZweipersonenspieleTic-Tac-ToeClobberVier 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 Zustandsmengensparen 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-SenkeZustand 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 x1

x2 x3 x3x2

BDDs für logische Operatoren

x1

x2

0 1

21 xx

x1

x2

0 1

21 xx

x1

0 1

1x

x1

x2 x2

0 1

21 xx

ROBDDs (Beispiele)column-x

row-x

diagonal-x

Ü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 ∈ Gberechne alle erreichbaren Zustände

2 Variablensätze:x für Vorgängervariablenx‘ für Nachfolgervariablen

in Variablenordnung xi und xi‘ abwechselnd (interleaved)

BDD-basierte Suche

Finden von Nachfolgern (image)Relationales Produkt:

Finden von Vorgängern (pre-image) analog:

zusätzlich: nach jedem (pre-)image:Verschieben der Variablen

xsxxTxsimage ',.

'','. xsxxTxspreimage

BDD-basierte Suche

Partitionierte Berechnung:T = VaTa für alle Aktionen a

∃ und ∨ kommutieren

(entsprechend auch für pre-image)Vorteil: Berechnung monolithischer Transitionsrelation teuer (Zeit und

Speicher)

xsxxTxsimage aa ',.

BDD-basierte Suche Finden der Vorgänger, deren Nachfolger alle in s liegen (strong pre-image):

strong pre-image auf pre-image zurückführbar → Übungsaufgabe '','._ xsxxTxspreimagestrong

BDD-basierte Suche

image pre-image strong 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 berechnenreach ← Iwiederhole

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-BDDfront ← Iwiederhole

closed ← closed ∨ front front ← image(front) ∧ ⌐closed

solange Abbruchkriterium nicht erfüllt

Bestimmung erreichbarer Zustände mittels SBFS

v: Anzahl Variablen für einen Zustandn: Anzahl BDD-Knoten zur Repräsentation aller

Zuständes: Anzahl aller erreichbarer Zustände

Bestimmung erreichbarer Zustände in „Vier Gewinnt“ (SBFS)

Bestimmung erreichbarer Zustände in „Vier Gewinnt“ (SBFS)

1E+00

1E+01

1E+02

1E+03

1E+04

1E+05

1E+06

1E+07

1E+08

1E+09

1E+10

1E+11

1E+12

1E+13

0 5 10 15 20 25 30 35 40

Knoten (BDD)Zustände (BDD)

Zustände (Allis-Schätzung)

Bidirektionale Breitensuche (SBBFS)

I

G

Schnittgefunden

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 IterationVerwendung von closed-BDDs möglich

Symbolischer Dijkstra

BFS nur bei uniformen Kosten Gewichtete Transitionsrelation → „Single Source Shortest

Path“→ DijkstraKosten 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:

Verwendung einer Heuristikz.B. aus Musterdatenbank (pattern database (PDB))Heuristik h darf nicht überschätzen (zulässig)

h = 0 → Dijkstra

vhvgvf

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-NullsummenspieleZweipersonenspiele mit allgemeinen Gewinnen

Überblick 2 (Lösen allgemeiner Spiele) General Game Playing Einpersonenspiele Zweipersonenspiele

Zweipersonen-NullsummenspieleZweipersonenspiele mit allgemeinen Gewinnen

General Game Playing

Beschreibung für Spiele mit folgenden Eigenschaften:endlichdiskretdeterministischvollständige Information

Spiele könnenEin- oder Mehr-Personenspiele seingleichzeitige oder abwechselnde Züge ermöglichen

General Game Playing „Game Description Language“ (GDL) Gegeben:

InitialzustandBestimmung legaler ZügeEffekt eines ZugesTerminierungsbedingungenVerteilung der Gewinne {0, …, 100} darin

Gesucht:Lösung erreichbarer ZuständeBestimmung 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.dehttp://euklid.inf.tu-dresden.de:8180/ggpserver (aktuelle Spiele etc.)

Überblick 2 (Lösen allgemeiner Spiele) General Game Playing Einpersonenspiele Zweipersonenspiele

Zweipersonen-NullsummenspieleZweipersonenspiele 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

75 100 90 80

99

75

80100

100

100

100

90

90

80

80

75

Ergebnisse für Solitär

Erreichbar: 375 110 246 Zustände

Überblick 2 (Lösen allgemeiner Spiele) General Game Playing Einpersonenspiele Zweipersonenspiele

Zweipersonen-NullsummenspieleZweipersonenspiele mit allgemeinen Gewinnen

Lösen von Zweipersonen-Nullsummenspielen 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 Zweipersonen-Nullsummenspielen 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 Zweipersonen-Nullsummenspielen

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-NullsummenspieleZweipersonenspiele 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 pre-image)

finde optimales Bucket für diese (pre-image)füge sie einiteriere, bis alle Zustände gelöst

Einschub: Reihenfolge beim Lösen

schwierig im allgemeinen Fall

eigenen Gewinn maximieren

(und gegnerischen minimieren)?

oder Differenz zum gegnerischen

Gewinn maximieren?

Hier: 2. Fall

own

100

0

opponent

0 100

own

100

0

opponent

0 100

Beispielplayer 0

play

er 1

0

0

1

1

2

2

3

3

player 0‘s turn

player 1‘s turn 0/1

0/1

0/3

2/0

3/1

2/0

2/0

3/1

3/1

0/1 3/13/1

0/10/1

0/3

0/3

0/1 3/1 0/1 2/0

0/10/1

0/1

Lösen allgemeiner Zweipersonenspiele

reach ← berechneErreichbareZustände()init matrix; solved ← alle Zustände in Matrixunsolved ← reach ∧ ⌐solvedsolange 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) ← 1für Knoten v aus Schicht i mit 0-Nachfolger u in Schicht j > i und 1-

Nachfolger 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)

0 1

1

1

1

30

1614

4

3522

2

abgedeckte Zustände:000001 000111 001011 001101 010011 010100 010101 010110 010111 011011

011100 011101 011110 011111 100011 100100 100101 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 Knotenspeichere 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ückfalls 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)

s ← 011101rank(G,s) ← [()2 + 1] * lc(G,s,v0) - 1

lc(G,s,v0) ← ()2 * sc(v1) + lc(G,s,v1)

lc(G,s,v1) ← 23-2-1 * sc(v3) + (1)2 * sc(v6) + lc(G,s,v6)

lc(G,s,v6) ← 25-4-1 * sc(v9) + (01)2 * sc(v13) + lc(G,s,v13)

v13 ist 1-Senke → lc(G,s,v13) ← 1

lc(G,s,v6) ← 20 * sc(v9) + 1 * sc(v13) + lc(G,s,v13)

= 1 * 1 + 1 * 1 + 1 = 3lc(G,s,v1) ← 20 * sc(v3) + 1 * sc(v6) + lc(G,s,v6)

= 1 * 4 + 1 * 5 + 3 = 12lc(G,s,v0) ← 0 * sc(v1) + lc(G,s,v1) = 12

rank(G,s) ← 1 * lc(G,s,v0) - 1 = 110 1

1

1

1

30

1614

4

3522

2

v0

v1 v2

v3

v4 v5 v6 v7

v8 v9 v10

v11

v12 v13

Unranking

Gegeben: BDD G, Hash-Wert r Gesucht: zugehöriger Zustand

Unranking

unrank(G,r)starte an der Wurzelfalls 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 ← lwiederhole, 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)

r ← 19i ← 1; r ≥ 22-1-1 * sc(v1) = 1 * 14 = 14

s1 ← 1; r ← r - 22-1-1 * sc(v1) = 19 - 1 * 14 = 5

r ← r mod sc(v2) = 5 mod 16 = 5

i ← 2; r < 24-2-1 * sc(v6) = 2 * 5 = 10 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 s5 ← 1; r ← r - 27-5-1 * sc(v12) = 0 - 2 * 0 = 0

r ← r mod sc(v11) = 0 mod 1 = 0

i ← 6; r ≥ 27-6-1 * sc(v12) = 1 * 0 = 0 s6 ← 1; r ← r - 27-6-1 * sc(v12) = 0 - 1 * 0 = 0

r ← r mod sc(v13) = 0 mod 1 = 0

0 1

1

1

1

30

1614

4

3522

2

v0

v1 v2

v3

v4 v5 v6 v7

v8 v9 v10

v11

v12 v13

s ← s ← 1 s ← 101 s ← 1010 s ← 10101 s ← 101011

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 Speicherlastspeichern 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

top related