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