Teile und Herrsche (Divide and Conquer)

Werbung
Teile und Herrsche (Divide and Conquer)
Entwurfsmethode für Algorithmen
1.
2.
3.
Teile das Problem in kleinere Unterprobleme (Divide)
Löse rekursiv die entstehenden Unterprobleme (Conquer)
Setze die Lösungen zusammen.
Instanzen :
•
•
•
•
Mergesort
Quicksort
Intervallhalbierung (kein Zusammensetzen)
schnelle Berechnung ganzzahliger Potenzen
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 1
Divide-and-Conquer: Laufzeiten
Oft ergibt sich der Effekt:
O(n) Laufzeitanteil verbesserbar zu O(log(n))
Notwendig dazu:
Summe der Größen der Teilprobleme
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 2
≤ Größe des Problems
Beispiel: Türme von Hanoi
Gegeben
Stapel von verschieden großen Scheiben
von oben nach unten größer werdend
Aufgabe:
Umstapeln auf einen anderen Stapel.
Erlaubt ist ein weiterer Hilfsstapel
Bedingung: Es darf niemals eine Scheibe auf einer kleineren
liegen
Lösung: mittels Teile-und-Herrsche:
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 3
1
n-1
n
2
n
3
n-1
n
n-1
Beispiel: Türme von Hanoi (2)
Notwendige Bewegungen für n:
1. n − 1 Scheiben von 1 nach 3 mit 2 als Hilfsstapel
2. Scheibe n von 1 nach 2
3. n − 1 Scheiben von 3 nach 2 mit 1 als Hilfsstapel
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 5
Beispiel: Türme von Hanoi (2)
Haskell-Algorithmus zum Ermitteln der Bewegungen.
Die Nr. der Stapel wird als Argument mitübergeben.
-hanoi: Stapel, Stapelnr, Zielstapelnr Hilfstapelnr:
hanoi xs a b c = hanoiw (reverse xs) a b c
hanoiw [] _ _ _ = []
hanoiw
xa a b c =
(hanoiw
(tail xa) a c b)
++
((head xa ,(a,b)): (hanoiw
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 6
(tail xa) c b a))
Hanoi: Testaufruf
-- hanoi [1,2,3] 1 2 3
ergibt
-- [(1,(1,2)), (2,(1,3)), (1,(2,3)), (3,(1,2)), \\
--(1,(3,1)), (2,(3,2)), (1,(1,2))]
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 7
Beispiel: Türme von Hanoi (3)
hanoi-Resultat
Liste von Bewegungen:
Zum Beispiel eine Bewegung (2, (1, 3))
Scheibe 2 von Stapel 1 nach 3
Länge der Resultatliste = 2n − 1
wenn n die Anzahl der Scheiben ist.
Die Funktionen hanoiexec und hanoiexecl
interpretieren die Ausgabeliste und führen die Bewegungen aus.
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 8
Such-Algorithmen: Suche mit Backtracking
Beispiel Handlungsreisenden-Problem (travelling salesman problem)
Gegeben:
Landkarte, Städte, Wege und Entfernungen
Gesucht:
optimaler Weg durch alle Städte.
Weitere Beispiele:
•
•
optimaler Zug in Spielen (Dame, Schach, Tictactoe, Go)
erfüllende Belegung einer aussagenlogischen Formel
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 9
Suche
Abstrakte Sichtweise:
Suche
= Durchmusterung eines implizit gegebenen
Suchbaumes (Suchraumes)
geordnete Aufzählung der möglichen Lösungen
Suchstrategien:
Zurücksetzen bei Fehlschlag:
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
Tiefensuche (depth-first)
Breitensuche (breadth-first)
Backtracking
(4. F ebruar2005)
Seite 10
Beispiel: Zusammensetzen eines Wertes
Gegeben :
Gesucht :
Satz von (ganzzahligen, positiven ) Gewichten
Zielgewicht
Vereinfachtes Modell:
Gegeben :
Gesucht :
Multimenge von positiven ganzen Zahlen
Untermultimenge, deren Summe genau
das Zielgewicht (die gewünschte Zahl) ergibt.
P raktische Inf ormatik
2004/05, F olien Div+Conq−1,
1, W S
(4. F ebruar2005)
Seite 11
Gewichtsproblem (2)
Erste Methode
Konstruiere die Liste aller Unterlisten, berechne deren Summe und
vergleiche mit der gewünschten Zahl:
Funktion gewichtx:
Argument 1:
Argument 2:
P raktische Inf ormatik
1, W S
Liste der verfügbaren Gewichte
Zielzahl
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 12
Gewichtsproblem (3)
data Maybe a = Nothing | Just a
gewichtx xs ziel =
let ulisten = unterlisten xs
wertuliste = zip (map sum ulisten) ulisten
okliste = filter (\(w,xs) -> w == ziel) wertuliste
in head okliste
unterlisten [x] = [[x]]
unterlisten (x:xs) =
let unterl = unterlisten xs
in ([x]: (map (\ul -> x:ul) unterl)) ++ unterl
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 13
Methode 1: Eigenschaften
Die Funktion gewichtx ist ineffizient
Die Konstruktion aller Unterlisten erfordert exponentiellen Platz
lazy Auswertung ergibt: linearen Platzbedarf, exponentielle Zeit
gewichtx sucht weiter, auch wenn es keine Erfolgsaussichten mehr gibt
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 14
Suche mit Backtracking
Backtracking, wenn die Summe der Gewichte schon zu groß ist.
gewichtxbt xs ziel =
case gewichtxbtw xs ziel []
of Nothing -> Nothing
Just res -> Just (sum res, res)
gewichtxbtw xs 0 res = Just res
gewichtxbtw [] ziel res = Nothing
gewichtxbtw (x:xs) ziel res =
if ziel < 0 then Nothing
else
let versuch1 = gewichtxbtw
versuch2 = gewichtxbtw
in case versuch1 of
Just x -> Just x
Nothing -> versuch2
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
xs (ziel-x) (x:res)
xs ziel res
Seite 15
Testlauf Gewichtsproblem
Testeingabe = [5, 5, 3, 3, 3, 3], gewünschtes Ergebnis ist 12.
(Just (12,[3, 3, 3, 3]),
[[5], [5, 5], [5, 5, 3], [5, 5, 3], [5, 5, 3], [5, 5, 3],
[5, 3], [5, 3, 3], [5, 3, 3, 3], [5, 3, 3, 3], [5, 3, 3],
[5, 3, 3, 3], [5, 3, 3], [5, 3], [5, 3, 3], [5, 3, 3, 3],
[5, 3, 3], [5, 3], [5, 3, 3], [5, 3], [5], [5, 3], [5, 3, 3],
[5, 3, 3, 3], [5, 3, 3, 3], [5, 3, 3], [5, 3, 3, 3],
[5, 3, 3], [5, 3], [5, 3, 3], [5, 3, 3, 3], [5, 3, 3],
[5, 3], [5, 3, 3], [5, 3],
[3], [3, 3], [3, 3, 3], [3, 3, 3, 3]])
Weitere Verbesserungsmöglichkeiten: Symmetrien ausnutzen
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 16
Allgemeine Suchfunktion mit Tiefensuche und
Abschneiden
suchbtdf :: a -> (a->[a]) -> (a-> Bool) -> (a-> Bool) -> Maybe a
anf:
toechter:
ziel:
cut:
P raktische Inf ormatik
aktuelles Objekt (Zustand)
Direkte Nachfolgezustände
Prädikat: ist der aktuelle Zustand ein Zielzustand?
Wenn ja, dann keine Nachfolgezustände untersuchen
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 17
Allgemeine Suchfunktion mit Tiefensuche und
Abschneiden
suchbtdf anf toechter ziel cut =
if ziel anf then Just anf
else if cut anf
then Nothing
else let nexts = toechter anf
in suchbtdfl nexts toechter ziel cut
suchbtdfl [] toechter ziel cut = Nothing
suchbtdfl (x:xs) toechter ziel cut =
let result1 = suchbtdf x toechter ziel cut
result2 = suchbtdfl xs toechter ziel cut
in case result1 of
Nothing -> result2
Just x -> Just x
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 18
Anwendung und Testlauf
testgewicht_allgem = suchbtdftr ([],[5,5,3,3,3,3])
(\(xs,ys) -> if ys == [] then []
else [(head ys:xs,tail ys),(xs,tail ys)] )
(\(xs,_) -> (sum xs) == 12)
(\(xs,_) -> (sum xs) > 12)
--(75 Schritte)
testgewicht_allgemmv =
suchbtdftr ([],[(5,2),(3,4)])
(\(xs,ys) -> if ys == [] then []
else let (yh1,yh2):yr = ys
in if yh2 == 1
then [(yh1:xs,yr),(xs,yr)]
else [(yh1:xs,(yh1,yh2-1):yr),(xs,yr)])
(\(xs,_) -> (sum xs) == 12)
(\(xs,_) -> (sum xs) > 12)
--- ( 17 Schritte)
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 19
Greedy Algorithmen, lokal optimale Schritte
greedy == gierig, gefräßig
Idee der Suche
Bevorzuge den jeweils lokal optimalsten Schritt
Ergibt meist nur suboptimale Lösung
Bei manchen Problemklassen: optimale Lösung.
Paketproblem: Abwandlung des Gewichtsbeispiels
Gegeben
Gesucht
P raktische Inf ormatik
einige Teile, die in Pakete verpackt werden sollen
und eine Obergrenze des Paketgewichts.
optimale Zusammenstellung der Teile für das erste Paket
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 20
Greedy Algorithmen, lokal optimale Schritte
Vereinfachung: Liste von Zahlen.
lokal optimal: Immer das jeweils schwerste übrige Teil nehmen
Ergibt suboptimale Werte, aber nicht optimale.
postgreedy xs max = postgreedyw xs max []
postgreedyw [] max res = (sum res,res)
postgreedyw _ 0 res = (sum res,res)
postgreedyw xs max res =
let ls = filter (<= max) xs
m = maximum ls
in case ls of
[] -> (sum res,res)
_ -> postgreedyw (delete m xs) (max - m) (m:res)
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 21
Greedy Algorithmus: Testläufe
-- Beispiele:
--- postgreedy [1,2,3,4,5] 12
------
--->
(12,[3, 4, 5])
nicht optimal, aber nahe dran:
postgreedy [5,5,3,3,3,3] 12 --->
postmin1 [5,5,3,3,3,3] 12
--->
postgreedy [5,5,3,3,3,3] 14 --->
postmin1 [5,5,3,3,3,3] 14
--->
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 22
(10,[5,
(12,[3,
(13,[3,
(14,[5,
5])
3, 3, 3])
5, 5])
3, 3, 3])
Huffman-Kodierung von Nachrichten
Nachrichtenübertragung, Kompression von Dateien
Analog zum Morsecode:
Gegeben: lange Nachricht über Alphabet A,
die relativen Häufigkeiten p(a) der einzelnen Zeichen sind bekannt
Übertragung der Nachricht mit anderem Alphabet B
Gesucht: Kodierungsfunktion c so dass:
Übermittlungsaufwand der kodierten Nachricht minimal
Länge der kodierten Nachricht
Länge der Original-Nachricht
≈ mittlere Länge des Kodes C := {c(a) | a ∈ A},
= Σ{a∈A}p(a) ∗ c(a)
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 23
Huffman-Kodierung von Nachrichten
Wir nehmen B = {0, 1}.
Kodierung c so, dass C := {c(a) | a ∈ A} präfixfrei ist,
d.h. kein Wort in C ist Präfix eines anderen in C.
Zur präfixfreien Kodierung kann ein binärer Baum aufgebaut werden,
der die Dekodierung sehr einfach macht:
Die Kodeworte sind die Adressen der Blätter
(0: nach links, 1: nach rechts),
die Markierungen der Blätter sind die gesuchten Kode-Buchstaben.
Dekodierung ist eindeutig und schnell
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 24
Morse-Kode
a
ch
g
...
·−
− − −−
−−·
ä
d
h
· − ·−
−··
· · ··
b
e
i
− · ··
·
··
c
f
j
− · −·
· · −·
· − −−
ist kein Huffman-Kode, denn nicht präfixfrei
Nimmt man die Pause dazu, dann präfixfrei.
Die Länge der Kodierungen der Buchstaben beim Morsekode
entspricht der relativen Häufigkeit der Buchstaben in englischen Texten
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 25
Erzeugung eines Huffman-Kodes
Seien a1, . . . , an die zu kodierenden Zeichen
n
P
und p1, . . . , pn die relativen Häufigkeiten (u.a.
pi = 1)
i=1
Gesucht: Kode c über {0, 1}
n
P
i=1
|c(ai)| ∗ pi, die mittlere Kodewortlänge, soll minimal werden.
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 26
Algorithmus zur Erzeugung eines
Huffman-Kodes
Greedy-Algorithmus zum Aufbau eines Code-Baumes:
Start mit Liste von Bäumen, die nur aus einem Blatt bestehen.
Schritt des Algorithmus:
Nehme die beiden Bäume mit der geringsten Häufigkeit
Erzeuge neuen Baum (Knoten B1 B2) zu 0, 1
Am Ende ergibt sich der gesuchte Kode-Baum.
Dieser Greedy-Algorithmus erzeugt immer einen optimalen HuffmanKode !
Der Baum ist nicht eindeutig
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 27
Huffman in Haskell
data Hufftree a = Hleaf a Float
| Hnode (Hufftree a) (Hufftree a) Float
huffle :: Hufftree a -> Hufftree a -> Bool
huffle htr1 htr2 = (huffrh htr1) <= (huffrh htr2)
huffrh (Hleaf _ x) = x
huffrh (Hnode _ _ x) = x
huffgreedy xs = huffgreedyw (map (\(x,p)->(Hleaf x p)) xs)
huffgreedyw [x] = x
huffgreedyw xs@(_:_) =
let
y1:(y2:yr) = mischsortg xs huffle
in huffgreedyw ((Hnode y1 y2 ((huffrh y1) + (huffrh y2))):yr)
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 28
Huffman in Haskell
huffextractcode ht =
mischsortg (map (\(x,y) -> (x,reverse y)) (huffxcw "" ht))
(\(x1,_) (x2,_) -> x1 <= x2)
huffxcw prefix (Hleaf x _) = [(x,prefix)]
huffxcw prefix (Hnode tl tr _) =
(huffxcw (’0’:prefix) tl) ++ (huffxcw (’1’:prefix) tr)
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 29
Huffman in Haskell
testhuffgreedy =
let
probs =
[(’a’,0.45),(’b’, 0.13),(’c’,0.12),
(’d’,0.16),(’e’,0.09),(’f’,0.05)]
tr = huffgreedy probs
in (mittlere_codewortlaenge tr, huffextractcode tr)
mittlere_codewortlaenge tr = mitt_cwl tr 0.0
mitt_cwl (Hleaf _ x) tiefe = x*tiefe
mitt_cwl (Hnode tl tr x) tiefe =
(mitt_cwl tl (tiefe + 1.0)) + (mitt_cwl tr (tiefe + 1.0))
> testhuffgreedy
> (2.24,[(’a’,"0"), (’b’,"101"), (’c’,"100"),
(’d’,"111"), (’e’,"1101"), (’f’,"1100")])
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 30
Huffman in Haskell
0
1
a
1
0
0
0
1
1
c
b
0
f
P raktische Inf ormatik
1, W S
1
e
2004/05, F olien Div+Conq−1,
d
(4. F ebruar2005)
Seite 31
Huffman: Kodieren und Dekodieren
huffkodiere xs tr = huffcode xs (huffextractcode tr)
huffcode [] tr
= []
huffcode (x:xs) tr = (kodiere x tr) ++ huffcode xs tr
kodiere x ((a,ca):xs) = if x == a then ca else kodiere x
xs
huffdekodiere xs tr = huffdecode xs tr tr
huffdecode [] (Hleaf a _) _ = [a]
huffdecode xs (Hleaf a _) tr = a : (huffdecode xs tr tr)
huffdecode (’0’:xs) (Hnode trl trr _) tr = huffdecode xs
huffdecode (’1’:xs) (Hnode trl trr _) tr = huffdecode xs
trl tr
trr tr
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 32
Huffman: Kodieren und Dekodieren
testkodiere =
let wort = "badfadcade"
tr = huffgreedy hufftestprobs
kodiertes_wort = huffkodiere wort tr
dekodiertes_wort = huffdekodiere kodiertes_wort tr
in (kodiertes_wort, dekodiertes_wort,wort, dekodiertes_wort == wort)
>
>
testkodiere
("10101111100011110001111101","badfadcade","badfadcade",True)
Kompressionsverfahren: Kodieren (kurze) Worte statt Zeichen.
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 33
Scan: lineare Algorithmen
Ziel: Konstruktion von linearen Algorithmen (d.h. O(n))
Verfahren:
Durchlaufen (Scan) einer Folge / Liste
Verwendung von O(1)- Zeit und Speicher
pro Folgenelement.
Auch mehrfaches Scannen ist erlaubt.
Wesentlich:
Minimierung der Anzahl der Durchläufe.
Bester Fall:
1 Durchlauf
File-, Stream-Verarbeitung
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 34
Scan in Haskell
Beispiele
P raktische Inf ormatik
filter p (map q xs))
ein Durchlauf
map q (reverse xs)
ungünstig,
da ganze Liste gleichzeitig im Speicher
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 35
Beispiel
Maximum einer Liste von Zahlen:
Verfahren 1:
Verfahren 2:
sortieren, dann erstes Element auswählen
O(n ∗ log(n))
Scannen der Liste mit aktuellem maximalen Element
O(n)
minim (x:xs) = minimr x xs
minimu x [] = x
minimr x (y:ys) = if x <= y then minimr x ys
else minimr y ys
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 36
Minimum mit Verfahren 2
Minimumberechnung:
minim_sort xs = head (mischsort xs)
naive Analyse:
genauere Analyse in Haskell:
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
O(n ∗ log(n))
Aufwand: O(n)
(4. F ebruar2005)
Seite 37
Beispiele für Scan-Algorithmen
Suche eines gegebenen Wortes in einem Textfile
Erzeugung eines optimalen Huffman-Kodes:
1. Scan zur Ermittlung der Häufigkeiten der Zeichen
2. Erzeugung des Huffman Baumes
3. Kodierung: Scan
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 38
Beispiel für lineare Algorithmen
Finden des Medians einer Liste:
Median:
Element, so dass die Anzahl der kleineren
und die Anzahl der größeren
möglichst nah an der Hälfte liegt.
Es gibt O(n)-Algorithmus
vermutlich gibt es keinen Scan- Algorithmus!
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 39
Beispiel: Summe von Teilfolgen
Aufgabe:
Finde die maximale Summe einer zusammenhängenden
Teilfolge einer endlichen Folge von ganzen Zahlen.
bei der alle Elemente nichtnegativ sind
(mcv: maximal contiguous subvector).
Beispiel
Bei [1, 2, −5, 3, 4, −1, 1, 2, 5, −10] ergibt sich 8.
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 40
Beispiel: mcv: verschiedenen Methoden
direktes Verfahren
Bestimme alle Teilfolgen (ohne Lücken),
wähle die aus, die nur nichtnegative Elemente haben,
bilde die Summe und
bestimme das Maximum.
Dieses Verfahren ist kubisch O(n3):
i.
ii.
iii.
iv.
Es gibt quadratisch viele dieser Teillisten,
Auswahl hat Zeitbedarf O(n3),
Summenbildung ist linear in einer Teilliste, also auch O(n ∗ n2)
Maximumsberechnung linear (d.h. quadratisch).
Zusammen O(n3).
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 41
Beispiel: mcv: naives Verfahren
startsublists [] = []
startsublists [x] = [[x]]
startsublists (x:t) = [x] : (map (\y->(x:y)) (startsublists t))
nesublists [] = []
nesublists (x:t) = (startsublists (x:t)) ++ (nesublists t)
mcv_quadrat [] = 0
mcv_quadrat (x:xs) =
maximum (map sum
(filter (\ys -> all (>= 0) ys) (nesublists (x:xs))))
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 42
Beispiel: mcv: Divide and Conquer
Halbiere die Liste in der Mitte, bestimme die mcv-Zahlen ml , mr rekursiv
berechne zusätzlich die rechte mcv-Zahl mlr der linken Teilliste
die linke mcv-Zahl mrl der rechten Teilliste.
Bilde das Maximum der Zahlen ml , mr , mrl + mlr .
Zeitbedarf ist O(n ∗ log(n))
mcv_dq [x] = if x <= 0 then 0 else x
mcv_dq (x:xs) = let len =length (x:xs)
xa = take (len ‘div‘ 2) (x:xs)
xb = drop (len ‘div‘ 2) (x:xs)
mca = mcv_dq xa
mcb = mcv_dq xb
mca_r = sum (takeWhile (>= 0) (reverse xa))
mcb_l = sum (takeWhile (>= 0) xb)
in maximum [mca,mcb,mca_r+mcb_l]
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 43
Beispiel: mcv: Scan-Verfahren
Der Scan benötigt zum Durchlauf der Liste eine Umgebung:
• das bisher gefundene Maximum,
• die Summe der aktuellen Teilliste
• die Restliste.
Zeitbedarf ist O(n)
mcv_scan xs
= mcv_scanr 0 0
mcv_scanr gm lm []
= max gm lm
mcv_scanr gm lm (x:xs) =
if x < 0
then mcv_scanr (max gm lm) 0
xs
else mcv_scanr gm
(lm+x) xs
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 44
xs
Algorithmen für mcv-Variante
Finde die maximale Summe einer zusammenhängenden Teilfolge
einer gegebenen endlichen Folge von ganzen Zahlen.
MNaiver Algorithmus:
startsublists [] = []
startsublists [x] = [[x]]
startsublists (x:t) = [x] : (map (\y->(x:y)) (startsublists t))
nesublists [] = []
nesublists (x:t) = (startsublists (x:t)) ++ (nesublists t)
mcv2_quadrat [] = 0
mcv2_quadrat (x:xs) =
maximum (map sum (nesublists (x:xs)))
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 45
Scan-Algorithmus für mcv-Variante
Umgebung:
•
•
•
maximale Summe bisher
verwendbare Restsumme
Restfolge
mcv2_scan xs
= mcv2_scanr 0 0 xs
mcv2_scanr gm lsum []
= max gm lsum
mcv2_scanr gm lsum (x:xs) =
if lsum < 0
then mcv2_scanr
gm
x
xs
else mcv2_scanr (max gm lsum) (lsum+x) xs
P raktische Inf ormatik
1, W S
2004/05, F olien Div+Conq−1,
(4. F ebruar2005)
Seite 46
Herunterladen