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