Entwurfstechniken für Algorithmen II

Werbung
Entwurfstechniken für Algorithmen II
Entwurfstechniken für Algorithmen II
Gliederung
Algorithmen und Datenstrukturen II
1
Entwurfstechniken für Algorithmen
Einführung
Vorgehen
Anwendung Schiebe-Puzzle
D. Rösner
Gierige Suche
Institut für Wissens- und Sprachverarbeitung
Fakultät für Informatik
Otto-von-Guericke Universität Magdeburg
Einführung
Implementation
Beispiel: Geldwechsel-Problem
Beispiel: Prim’ MST-Algorithmus
c
Sommer 2009, 21. Juni 2009, 2009
D.Rösner
D. Rösner AuD II 2009 . . .
Entwurfstechniken für Algorithmen II
Entwurfstechniken für Algorithmen II
Diskussion
Prioritätsgesteuerte Suche
1
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
D. Rösner AuD II 2009 . . .
Entwurfstechniken für Algorithmen II
Entwurfstechniken für Algorithmen
2
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Prioritätsgesteuerte Suche
Suche mit Backtracking
besonders gut für Spielstrategien
aber: aufwändig, besonders bei grossen Suchräumen
daher: Varianten, bei denen versucht wird, Aufwand zu
verringern
Entwurfstechnik ’Prioritätsgesteuerte Suche’
einfache Suche mit Backtracking wird auch bezeichnet als
uninformierte Suche ( engl. unguided search) oder
blinde Suche ( engl. blind search)
Prioritätsgesteuerte Suche (engl. priority-first search):
Kandidaten werden danach geordnet, wie vielversprechend
sie für mögliche Lösung sind
Gierige Suche (engl. greedy search): aus den unmittelbaren
Nachfolgern eines Knotens wird nur die lokal beste
Alternative verfolgt
Grund: es wird keine Information über Unterschiede
zwischen Kandidatenknoten ausgenutzt
s.a. [RL99], Ch. 8.2
s.a. [RL99], Ch. 8.2.6, 8.3, 8.4
D. Rösner AuD II 2009 . . .
4
D. Rösner AuD II 2009 . . .
6
Entwurfstechniken für Algorithmen II
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Entwurfstechniken für Algorithmen II
Prioritätsgesteuerte Suche
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Prioritätsgesteuerte Suche
um aus der Funktion höherer Ordnung für Suche mit
Backtracking eine allgemeine Lösung für
Prioritätsgesteuerte Suche zu machen, müssen lediglich
Operationen aus dem ADT Stack gegen entsprechende
aus dem ADT für Prioritätswarteschlangen ausgetauscht
werden
bei ’Prioritätsgesteuerter Suche’ wird eine
Bewertungsfunktion für Kandidatenknoten definiert
eine solche Vergleichsfunktion erlaubt es,
Kandidatenknoten in einer Prioritätswarteschlange nach
höchster Priorität (oder niedrigsten Kosten) zu organisieren
searchPfs succ goal x = search’ (enPQ x emptyPQ) 0
where
search’ q t
| (pqEmpty q)
= []
| goal (frontPQ q) = ((frontPQ q),t+1):(search’ (dePQ q)(t+1))
| otherwise = let x = frontPQ q
in search’ (foldr enPQ (dePQ q) (succ x)) (t+1)
da immer der vielversprechendste Kandidat zuerst
untersucht wird, wird diese Form der Suche auch best-first
search genannt
s.a. [RL99], Ch. 8.2
s.a. [RL99], Ch. 8.3.1
D. Rösner AuD II 2009 . . .
Entwurfstechniken für Algorithmen II
7
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
D. Rösner AuD II 2009 . . .
Entwurfstechniken für Algorithmen II
Prioritätsgesteuerte Suche
8
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Prioritätsgesteuerte Suche
wenn bei Vergleichsoperation keine exakte Bewertung,
sondern nur eine Schätzung möglich, spricht man von
einer Heuristik
um den vielversprechendsten (also ’kleinsten’) Knoten an
die Spitze der Prioritätswarteschlange platzieren zu
können
Suche mit Prioritätswarteschlange unter Verwendung einer
Heuristik wird auch als heuristische Suche (engl. heuristic
search) bezeichnet
muss eine überladene Vergleichsoperation (typischerweise
<=) für Knoten definiert werden
Vergleichen aller Kandidatenknoten bezüglich einer
(heuristischen) Bewertungsfunktion führt zu zusätzlichem
Speicher- und Zeitaufwand
s.a. [RL99], Ch. 8.3.1
s.a. [RL99], Ch. 8.3.1
D. Rösner AuD II 2009 . . .
9
D. Rösner AuD II 2009 . . .
10
Entwurfstechniken für Algorithmen II
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Entwurfstechniken für Algorithmen II
Prioritätsgesteuerte Suche
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Prioritätsgesteuerte Suche
Schiebe-Puzzle mit acht Kacheln (eight-puzzle):
um zu bewerten, wie nah oder fern eine
Kandidatenkonfiguration vom Zielzustand ist, wird
für jede Kachel die Manhattan-Distanz zwischen aktueller
und Zielposition bestimmt
und über diese Werte summiert
in Haskell:
Schiebe-Puzzle mit acht Kacheln (eight-puzzle):
Überladene Gleichheits- bzw. Ordnungsbeziehungen für
Anordnungen des Schebepuzzle:
instance Eq Boards
where BDS(b1:_) == BDS(b2:_) = heur1 b1 == heur1 b2
heur1
:: Board -> Int
heur1 b = sum [ mandist (b!i) (g8T!i) | i<-[0..8]]
instance Ord Boards
where BDS (b1:_) <= BDS (b2:_) = heur1 b1 <= heur1 b2
Frage: welche Verallgemeinerung ist naheliegend?
............................................
............................................
............................................
s.a. [RL99], Ch. 8.3.2
s.a. [RL99], Ch. 8.3.2
D. Rösner AuD II 2009 . . .
Entwurfstechniken für Algorithmen II
11
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
D. Rösner AuD II 2009 . . .
Entwurfstechniken für Algorithmen II
Prioritätsgesteuerte Suche
12
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Prioritätsgesteuerte Suche
Schiebe-Puzzle mit acht Kacheln (eight-puzzle):
Aufwandsangaben für Bestimmung einer Lösung:
Schiebe-Puzzle mit acht Kacheln (eight-puzzle):
Variante der Heuristik:
bisher wird nur die Summe der Manhattan-Abstände zur
Zielposition berücksichtigt,
relevant ist aber auch, ob Kacheln zwar nicht an der
Endposition, aber bereits relativ zueinander in der richtigen
Reihung sind.
stats = (length ls , t)
where
(((BDS ls),t):_) = searchPfs succ8Tile goal8Tile (BDS [s8T])
Ergebnis:
Main> stats
(25,36)
Heuristik 2 kombiniert dann beide Informationen
s.a. [RL99], Ch. 8.3.2
s.a. [RL99], Ch. 8.3.2
D. Rösner AuD II 2009 . . .
13
D. Rösner AuD II 2009 . . .
14
Entwurfstechniken für Algorithmen II
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Entwurfstechniken für Algorithmen II
Prioritätsgesteuerte Suche
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Prioritätsgesteuerte Suche
Schiebe-Puzzle mit acht Kacheln (eight-puzzle):
spezielle Bewertungsfunktion:
Schiebe-Puzzle mit acht Kacheln (eight-puzzle):
Bewertung (score) für relative Abweichung von Endreihung
score :: Position -> Position -> Int
score (2,2) _
= 1
Kachel im Zentrum erhält Gewicht 1
Kachel nicht im Zentrum führt zu Gewicht 0, wenn der
gemäss Zielvorgabe erwartete Nachfolger (bei Zählung im
Uhrzeigersinn) unmittelbar folgt
in allen anderen Fällen führt Kachel zu Gewicht 2.
score
score
score
score
score
score
score
score
wichtig: diese Gewichte rechtfertigen sich aus der
speziellen Zielkonstellation und sind für andere
Konfigurationen anzupassen
(1,3)
(2,3)
(3,3)
(3,2)
(3,1)
(2,1)
(1,1)
(1,2)
score _ _
(2,3)
(3,3)
(3,2)
(3,1)
(2,1)
(1,1)
(1,2)
(1,3)
=
=
=
=
=
=
=
=
0
0
0
0
0
0
0
0
= 2
s.a. [RL99], Ch. 8.3.2
s.a. [RL99], Ch. 8.3.2
D. Rösner AuD II 2009 . . .
Entwurfstechniken für Algorithmen II
15
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
D. Rösner AuD II 2009 . . .
Entwurfstechniken für Algorithmen II
Prioritätsgesteuerte Suche
16
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Prioritätsgesteuerte Suche
Schiebe-Puzzle mit acht Kacheln (eight-puzzle):
Schiebe-Puzzle mit acht Kacheln (eight-puzzle):
Überladen von Gleichheit- bzw. Ordnungsbeziehung:
Summierung:
outseq
:: Board -> Int
outseq b = sum [score (b!i) ((b!(i+1)))|i<-[1..7]]
+score (b!8) (b!1)
instance Eq Boards
where BDS(b1:_) == BDS(b2:_) = heur2 b1 == heur2 b2
instance Ord Boards
where BDS (b1:_) < BDS (b2:_) = heur2 b1 < heur2 b2
BDS (b1:_) <= BDS (b2:_) = heur2 b1 <= heur2 b2
Heuristik 2:
heur2 :: Board -> Int
heur2 b = (heur1 b) + 3*(outseq b)
s.a. [RL99], Ch. 8.3.2
s.a. [RL99], Ch. 8.3.2
D. Rösner AuD II 2009 . . .
17
D. Rösner AuD II 2009 . . .
18
Entwurfstechniken für Algorithmen II
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Entwurfstechniken für Algorithmen II
Prioritätsgesteuerte Suche
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Gierige Suche
beim Ansatz der gierigen Suche (engl. greedy search) wird
Schiebe-Puzzle mit acht Kacheln (eight-puzzle):
nach Überladen von Gleichheit- bzw. Ordnungsbeziehung:
von den unmittelbaren Nachfolgern des aktuellen Knotens
immer der lokal beste gewählt und
alle anderen Alternativen werden aufgegeben
(m.a.W. keine Verwaltung von Alternativen, kein
Backtracking).
Lösung wird auf einem Pfad erreicht.
Main> stats
(19,68)
s.a. [RL99], Ch. 8.3.2
Problem: lokale Minima
s.a. [RL99], Ch. 8.4
D. Rösner AuD II 2009 . . .
Entwurfstechniken für Algorithmen II
D. Rösner AuD II 2009 . . .
19
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Entwurfstechniken für Algorithmen II
Gierige Suche
21
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Gierige Suche
als Funktion höherer Ordnung ergibt sich das
Greedy-Vorgehen durch eine leichte Modifikation der
Lösung für prioritätsgesteuerte Suche:
Funktion höherer Ordnung für das Greedy-Vorgehen
searchGreedy :: (Ord node) => (node -> [node])
-> (node -> Bool)
-> node -> [node]
searchGreedy succ goal x = (search’ (enPQ x emptyPQ))
where
search’ q
| (pqEmpty q)
= []
| goal (frontPQ q) = [frontPQ q]
| otherwise = let x = frontPQ q
in search’ (foldr enPQ emptyPQ (succ x))
wenn zu den Nachfolgerknoten übergegangen wird, wird
eine neue Prioritätswarteschlange angelegt ( emptyPQ)
und damit werden die verbliebenen Kandidaten aus dem
vorausgegangenen Schritt aufgegeben
ausserdem: keine Suche nach weiteren Lösungen, wenn
ein Knoten den Zieltest erfüllt
s.a. [RL99], Ch. 8.4
s.a. [RL99], Ch. 8.4.1
D. Rösner AuD II 2009 . . .
22
D. Rösner AuD II 2009 . . .
23
Entwurfstechniken für Algorithmen II
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Entwurfstechniken für Algorithmen II
Gierige Suche
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Geldwechsel-Problem
Ansatz:
in jedem Schritt wird diejenige Münze mit höchstem
Nennwert gewählt, deren Wert kleiner oder gleich dem
(noch) darzustellendem Betrag ist
Problem: ein Geldbetrag soll mit der kleinstmöglichen Zahl
von Münzen (aus einem vorgegebenen Münzsystem)
gegeben werden
für Münzsysteme wie beim Euro garantiert dieses ’gierige’
Vorgehen immer eine optimale Lösung
aber: es gab auch Münzsysteme, wo dies nicht der Fall ist:
Beispiel: 218 Cent mit den Münzen des Euro-Systems
darstellen
............................................
............................................
............................................
Beispiel: in England gab es Münzen der Nennwerte 30p,
24p, 12p, 6p, 3p und 1p
der Greedy-Ansatz würde 48p wechseln in die drei Münzen
30p, 12p und 6p
optimal wäre aber nur zwei Münzen mit 24p
s.a. [RL99], Ch. 8.4.2
s.a. [RL99], Ch. 8.4.2
D. Rösner AuD II 2009 . . .
Entwurfstechniken für Algorithmen II
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Entwurfstechniken für Algorithmen II
Geldwechsel-Problem
25
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Geldwechsel-Problem
Implementation einer Lösung mit Greedy Search
eine Lösung ist eine Liste von Nennwerten von Münzen
Implementation einer Lösung mit Greedy Search
das Münzsystem:
type Coin
D. Rösner AuD II 2009 . . .
24
type SolChange
= [Coin]
= Int
ein Knoten ist charakterisiert durch den verbliebenen
Betrag und die bisherige Liste von Nennwerten von
Münzen
coins :: [Coin]
coins = [1,2,5,10,20,50,100]
type NodeChange
= (Int , SolChange)
s.a. [RL99], Ch. 8.4.2
s.a. [RL99], Ch. 8.4.2
D. Rösner AuD II 2009 . . .
26
D. Rösner AuD II 2009 . . .
27
Entwurfstechniken für Algorithmen II
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Entwurfstechniken für Algorithmen II
Geldwechsel-Problem
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Geldwechsel-Problem
Implementation einer Lösung mit Greedy Search
die Nachfolger-Funktion produziert als mögliche neue
Knoten alle Beträge, bei denen eine Münze vom aktuellen
Betrag abgezogen werden konnte
Implementation einer Lösung mit Greedy Search
für Knoten vom Typ NodeChange existiert eine kanonische
Ordnung nach zunächst erster Komponente, dann
succCoins
:: NodeChange -> [NodeChange]
succCoins (r,p) = [ (r-c,c:p) | c <- coins , r - c >=0 ]
ggf. nach zweiter Komponente
damit Lösung:
ein Zielknoten liegt vor, wenn kein zu wechselnder Betrag
mehr vorliegt
change
:: Int -> SolChange
change amount =
snd(head(searchGreedy succCoins goalCoins (amount,[])))
goalCoins
:: NodeChange -> Bool
goalCoins (v,_) = v==0
s.a. [RL99], Ch. 8.4.2
s.a. [RL99], Ch. 8.4.2
D. Rösner AuD II 2009 . . .
Entwurfstechniken für Algorithmen II
28
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
D. Rösner AuD II 2009 . . .
Entwurfstechniken für Algorithmen II
Geldwechsel-Problem
29
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Gierige Suche
Implementation einer Lösung mit Greedy Search
naheliegende Verallgemeinerung:
succCoins’ :: [Coin] -> NodeChange -> [NodeChange]
succCoins’ coins (r,p)
= [(r-c,c:p)| c <- coins , r - c >=0 ]
oft lässt sich ein bekannter Algorithmus als Anwendung
des Greedy-Verfahrens interpretieren
change’ :: [Coin] -> Int -> SolChange
change’ coins amount
= snd(head(searchGreedy (succCoins’ coins)
goalCoins (amount,[])))
dies gilt z.B für Prim’s Algorithmus zur Bestimmung eines
minimalen aufspannenden Baumes (MST)
s.a. [RL99], Ch. 8.4.3
damit:
Main> change’ [1,3,6,12,24,30] 48
[6,12,30]
s.a. [RL99], Ch. 8.4.2
D. Rösner AuD II 2009 . . .
30
D. Rösner AuD II 2009 . . .
31
Entwurfstechniken für Algorithmen II
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Entwurfstechniken für Algorithmen II
Graphen
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Prim’ MST-Algorithmus
Zur Erinnerung: Algorithmus von Prim (publiziert 1957)
Grundidee:
Welche Information enthalten die Knoten im Suchbaum?
die Mengen T und R von Knoten (als Listen)
das Gewicht der gewählten Kante (u, v ) mit u ∈ T und
v ∈R
die partielle bisherige Lösung, dargestellt als Liste von
(gewichteten) Kanten
es wird mit den Knoten des Graphen gearbeitet
die Menge der Knoten wird dynamisch in zwei Mengen
geteilt:
T enthält diejenigen Knoten, die bereits im Baum sind, und
R enthält diejenigen , die (noch) nicht im Baum sind
als Typinfo:
Ausgangspunkt, d.h. erstes Element von T , ist ein
willkürlich gewählter Knoten
in jedem Schritt wird aus der Menge derjenigen Kanten
(u, v ) mit u ∈ T und v ∈ R die Kante mit den geringsten
Kosten ausgewählt
der Algorithmus endet, sobald R leer ist
type Edge a b
= (a,a,b)
type NodeMst a b = (b , [a] ,[a], [Edge a b])
s. u.a. [RL99], Ch. 8.4.3
s. u.a. [RL99], Ch. 7.5.2
D. Rösner AuD II 2009 . . .
Entwurfstechniken für Algorithmen II
32
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Entwurfstechniken für Algorithmen II
Prim’ MST-Algorithmus
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
das Ziel ist erreicht, wenn R leer ist
also:
goalMst (_,_,[],_) = True
goalMst _
= False
(NodeMst a b)
b)]
r, (x,y,weight x y g):mst)
(x,y)]
s. u.a. [RL99], Ch. 8.4.3
D. Rösner AuD II 2009 . . .
33
Prim’ MST-Algorithmus
die Bestimmung der Kandidatenknoten erfolgt unter
Verwendung des Graphen:
succMst :: (Ix a,Num b) => (Graph a b) ->
-> [(NodeMst a
succMst g (_,t,r,mst)
= [(weight x y g, (y:t), delete y
| x <- t , y <- r, edgeIn g
D. Rösner AuD II 2009 . . .
prim g = sol
where [(_,_,_,sol)] = searchGreedy (succMst g) goalMst
(0,[n],ns,[])
(n:ns) = nodes g
s. u.a. [RL99], Ch. 8.4.3
34
D. Rösner AuD II 2009 . . .
35
Entwurfstechniken für Algorithmen II
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Entwurfstechniken für Algorithmen II
Prim’ MST-Algorithmus
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Prim’ MST-Algorithmus
Beispiel:
graphEx::(Graph Int Int)
graphEx = mkGraph True (1,5)
[(1,2,12),(1,3,34),(1,5,78),(2,1,12),(2,5,32),(2,4,55),
(3,1,34),(3,5,44),(3,4,61),(4,2,55),(4,3,61),(4,5,93),
(5,1,78),(5,2,32),(5,3,44),(5,4,93)]
Ergebnis:
> prim graphEx
[(2, 4, 55), (1, 3, 34), (2, 5, 32), (1, 2, 12)]
s. u.a. [RL99], Ch. 8.4.3
s. u.a. [RL99], Ch. 8.4.3
D. Rösner AuD II 2009 . . .
Entwurfstechniken für Algorithmen II
36
Diskussion
Prioritätsgesteuerte Suche
Gierige Suche
Literatur: I
Fethi Rabhi and Guy Lapalme.
Algorithms – A Functional Programming Approach.
Pearson Education Ltd., Essex, 1999.
2nd edition, ISBN 0-201-59604-0.
D. Rösner AuD II 2009 . . .
38
D. Rösner AuD II 2009 . . .
37
Herunterladen