Heutiges Thema, ui. Alle da, eins, zwei, drei.
Gut, heutiges Thema, die weiten Cocker-Verfahren, das ist eine Algorithmentechnik.
Bisher hatten wir ja irgendwie sowas wie linear was zu durchsuchen,
wie näheres Suchen hatten wir,
also so die beim linearen Suchen so die Idee,
ich gucke mir alles einmal an, beim Binären suchen,
ich halbiere und schmeiße immer die Hälfte von der Eingabe quasi weg.
Was hatten wir noch so,
den Suchraum komplett zu durchsuchen
Und das ist alles so ein bisschen Brootforce, ne?
Also außer lineare Suche ist ja im Grunde genommen ein Bootforce-Ansatz.
Ich gucke mir jedes Ding einmal an und gucke,
ob es meine Eigenschaften hat, die mich interessieren oder nicht.
Und falls ja, ist gut, falls nein, ist doof.
Da sind ja insofern alles noch nicht so richtige Techniken.
Die weiten Kongress, jetzt die erste wirklich Algorithmentechnik.
Und damit wollen wir uns heute beschäftigen.
Und wir wollen uns zwei ganz klassische Beispiele angucken.
Einmal das Merch-Sort und einmal das Quick-Sort.
Und zwischendrin machen wir nochmal eine Vertiefung zur Master-Theorie.
Das ist so der Plan für heute.
Erstmal noch zwei organisatorische Anmerkungen. Erstens die Gruppe 15,
die bisher Donnerstag 10 bis 12 in F2, 3,
5 war bei Felix Wiedemann.
Die haben wir verlegt in
Das ist dieses neu renovierte Gebäude auf der rechten Seite des Informatikampuses.
Da ist das jetzt immer aber zur gleichen Uhrzeit.
Das nur so ganz kurz organisatorisch. Und das zweite spannender,
unsere neue Professorin für Computer Science Education, die Frau Maria Knobelsdorf.
Die hatte mich angesprochen, dass sie eine Studie machen wollte.
Mit einer Masterstudentin von ihr zum,
ich habe es da jetzt Arbeitsverhalten von Studierenden genannt,
das klingt ein bisschen harsch.
Also gemeint ist,
die Studentin will sich mit Kleingruppen
quasi treffen
Die ähm Übungsaufgaben gerade bearbeiten. Also wenn ihr jetzt hier kriegt,
die neuen Übungszettel und ihr trefft euch jetzt irgendwie in eurer
Zwei- oder Dreiergruppe und bearbeitet den Übungszettel.
So, und was sie jetzt interessiert ist, wie geht ihr da eigentlich vor?
Also insbesondere, wie geht ihr bei mathematischen Inhalten vor?
Wir haben ja demnächst nochmal so dieses Thema PNP,
wo man dann vielleicht mal so eine Transitivitätsrelation zeigen soll oder sowas.
Und dann ist die Frage halt, wie geht ihr da so ran?
Wie gehen vielleicht die Gruppen ran, die schon eher von sich sagen,
naja, wir haben den Stoff eigentlich ziemlich gut verstanden,
wie gehen die Gruppen da ran, die von sich vielleicht bald Selbsteinschätzung sagen,
uh, ist mir alles noch ein bisschen unheimlich gerade.
Und das Ziel der Untersuchung soll dann sein,
dass man da eben irgendwie was rauszieht,
womit man den Unterricht quasi verbessern kann,
sodass man irgendwie weiß, okay, das sind so irgendwie,
so wird da rangegangen und das ist vielleicht gerade gar nicht so zielführend oder so.
Und genau, das ist so das Ziel, diese Untersuchung. Das ist auch freiwillig,
also sie wird da irgendwie dann demnächst mal die Übungsgruppenleiter ansprechen
und die werden dann vielleicht die Leute in den einzelnen Gruppen ansprechen,
dass wir so ein paar Kleingruppen haben, die Lust haben,
daran mitzuarbeiten und dann setzt sie sich halt einfach dazu und beobachtet,
wie gearbeitet wird und führt noch irgendwie Interviews mit euch.
Und wie gesagt, das Ziel ist dann eben letztendlich da irgendwie was rauszuziehen,
dass man das eben verbessern kann, weil das ja so
ein Ding ist, was eben vielen irgendwie Probleme macht.
Also ich merke das jetzt auch gerade wieder,
in der Masterveranstaltung hier FGI 3,
dass so dieses Ding irgendwie, wie man Beweis führt,
alleine schon so eine genau dann Van-Beziehung oder so,
dass das da immer noch da Probleme macht.
Und da soll es eben in der Untersuchung darum gehen,
warum eigentlich und wie die Leute da so rangehen.
Und wie man das dann unterstützen kann. Genau,
das einmal kurz, damit ihr das schon wisst,
dass das so die nächste Zeit nochmal auf euch zukommt.
Das wird so ungefähr Mitte November,
wird das passieren Mitte, Ende November.
Genau. Ja, gut.
Fragen? Kurz zum organisatorischen
Dann, die weite in Cocker-Verfahren,
die weiten in Conka oder eben Teile und Beherrsche auf Deutsch,
das ist ein Algorithmentechnik, arbeitet im Allgemeinen rekursiv.
Und hatten wir ja schon, wenn ich ein rekursives Verfahren habe,
brauche ich diese Rekurrenzgleichung, um irgendwie zu analysieren, welche Laufzeit die haben.
Also da fließt jetzt das, was wir vom letzten Mal hatten,
wieder mit rein. Also dieses ganze Vorgeplänkel mit der U-Notation,
eine Rekurrenzgleichung und so, jetzt wird das mir mit Inhalten gefüllt.
Also da eine grobe Beschreibung der Technik,
ich habe ein größeres Problem, eben beispielsweise,
ich will in Arry von ganz vielen Zahlen sortieren und dann überlege ich mir halt,
vielleicht kann ich dieses größere Problem, irgendwie ein Tai-Problem zerlegen.
Ich sollte hier erst einen Teil und einen anderen Teil und dann habe ich
zwei sortierte Teile irgendwie muss ich jetzt diese Teilergebnisse wieder zu einer richtigen Lösung zusammenführen.
Und das, wo eben Arbeit passiert ist, beim,
gegebenenfalls beim Zerlegen oder und beim Zusammenfügen,
weil die Idee bei dem Teilen ist, naja,
ich habe ein großes Area und jetzt teile ich das vielleicht
in der Mitte oder beim Drittel oder beim Viertel oder so,
also das Teilen ist meistens nicht so das Problem,
dass sie dann rekursiv nach der gleichen Methode gelöst werden.
Das ist auch nicht so das Problem. Ich rufe halt einfach die Methode auf,
aber das wurde dann eben viel Arbeit drin steckt üblicherweise,
ist da, wo ich das Problem teile,
also wo ich mir überhaupt überlege,
was kommt in welches Teilproblem rein und da,
wo ich die Teilprobleme wieder zusammenfüge.
Da muss ich meistens Gehirnschmalz reinstecken.
Unter Umständen auch schon beim, wenn ich mir überlege,
wie ich das in kleinere zerlege,
aber das sehe ich mir dann gleich noch
Genau. Ja. Der Livestream hat keinen Tun.
Hallo Internet, Kim sagt dazu.
Wer kann schnell schreiben, dann machen wir irgendwie hier...
Ja, äh, Texte mal zurück.
Keine Ahnung. Soll sich ein Bus setzen und schnell herkommen
So, genau, da jetzt auf kleineren Instanzen rekursiv gearbeitet wird,
genau, du nutzt mir diese Rekurrenzgleichung und ein Nahverwandter,
den wir später haben, werden das dynamische Programmierung,
da macht man noch so Sachen wie irgendwie diese einzelnen Teilprobleme,
die man jetzt hat, quasi irgendwie noch zu bewerten,
also dann auch irgendwie was auszurechnen und die zu bewerten und dann mit dieser zusätzlichen Zahl noch irgendwie zu arbeiten,
das ist also, das liest da so rein,
das machen wir später, jetzt ist erstmal so unser Anliegen,
okay, ich habe ein Problem,
ich zerlege das und löst das dann rekursiv.
Und was man so erfahrungsmäßig sagen kann, ist,
wenn ich ein Problem habe,
das für die Weite und Konka zugänglich ist,
oder für so ein devialen Konka-Verfahren,
dann hat das Problem meistens schon Unbein erbrut Force-Attacke irgendwie eine polymnielle Laufzeit und keine so eine exponentielle, typisches Beispiel sortieren.
Wenn ich beim Sortieren sage, um zu sortieren,
ich vergleiche einfach jedes Element mit jedem anderen,
so wie bei Max Hort oder Bubbles Hort auch oder sowas,
da ist es ja eine ziemliche Berut-Force-Attacke.
Die läuft dann ja schon im polymnialen Laufzeit, die ist schon ein O von Endquadrat.
So, und das kann man aber dieses Sortieren,
kann man mit einer devidenden Honka-Technik noch schneller machen.
Wie gesagt, so die Brut-Force ging schon vorher. Und dann kam vorher im Polymnialzeitung,
kann man sich fragen, ob überhaupt,
wenn ich jetzt was in den ON-Quadrat habe,
so wie dieses Max Hort, oder wenn ich was habe,
was in ON mal Login läuft, wie Merch Sword,
wie wir nachher sehen werden, wenn wir sich fragen,
lohnt sich das überhaupt?
Ist jetzt vielleicht nicht so der Unterschied? Und dann kann man
sich mal irgendwie so ein Zahlenbeispiel machen, dann sagt man,
hier als Eingabe nehme ich grob 1000, also zwei hoch zehn.
Und dann brauchst du ein ON-Quadrat eben, Algorithmus eben,
zehnmal zwei hoch zwanzig, viele Operationen.
Das C ist die Konstante, die in der ON-Notation verschluckt wird.
Und zwei hoch zwanzig ist irgendwie eine Million. Das heißt,
ich brauche hier irgendwie eine Konstante, mal eine Million Schritte,
wohingegen dieser N-Malok-In-Algorithmus eben irgendwie nur C, vielleicht sinnvollerweise C-Strich,
dann kann das irgendwie eine andere Konstante sein.
Und dann eben zieh Strich mal dieses zwei hoch zehnmal Lugerithmus von 2 hoch 10 ist eben nur 10,
deswegen habe ich dann nur 10.000 Schritte,
also habe ich ja schon so einen Unterschied zwischen 10.000 oder einer Millionen Schritte,
jeweils noch mit so einer Konstanten oder wenn man jetzt mal so annimmt,
dass die Konstanten bei beiden vielleicht ungefähr ähnlich ist, dann sieht man da schon einen ziemlich deutlichen Unterschied.
Und wenn man eben Eingabegrößen dieser Art hat,
also ungefähr eine Million Elemente, dann wird das eben noch deutlicher.
Also bei eine Million Elemente zu sortieren,
wäre jetzt nicht so ungewöhnlich, wenn man jetzt mal beim Sortieren bleibt,
so auch andere Eingaben mit einem Millionen Elementen sind nicht ungewöhnlich.
Und wenn man dann hier bei dem Endquadratalgorithmus so eine Million,
mal eine Million, da hat man dann schon eine Billion Schritte,
also zehnmal eine Billion,
während man hier dann irgendwie nur 20 Millionen Schritte hat
Da sieht man jetzt sehr deutlich, dass das irgendwie einen krassen Unterschied macht,
ob ich 20 Millionen Schritte habe oder eine Billion.
Ergo lohnt sich. Also so eine Verbesserung,
wenn ich bisher einen Algorithmus habe, ja ein ON-Quadrat abläuft,
zu einem der ein ON-Malogin abläuft, das lohnt sich.
Und deswegen wollen wir uns das heute angucken, wie solche,
die weit im Konka-Verfahren funktionieren. Wir werden das einmal illustrieren
in diesem Merch-Sort-Algorithmus. Dann machen wir einen kleinen Einschub,
um das Mastertheorium nochmal zu vertiefen,
dass wir uns nochmal für jeden Fall, den es da so gab,
ein Beispiel angucken und für diese Regularitätsbedingungen und sowas,
dass wir da nochmal kurz vertiefen.
Und dann gucken wir uns nochmal Quick-Sort an als weiteres
klassisches Verfahren
Bei Merchshot ist es so, dass ich nachher beim Zusammenfügen
quasi die Arbeit habe. Beim Quicksort ist es so,
dass ich beim Teilen die Arbeit habe. Also Arbeit soll bedeuten,
dass ich da so das habe, wo ich meinen Gehirnschmalz reinstecken muss.
Beides soll eben dazu dienen, dass er sagt,
ah ja, okay, mir ist prinzipiell klar,
wie ich so ein Devite-and-Konka-Ansatz machen kann.
Und dann sollte das eben in den Übungszetteln noch mal an
so einem anderen Beispiel probieren. Gut, da das typische Sortierproblem so,
die Folie haben wir jetzt schon x-mal gesehen.
Und was wir bisher hatten, so Max-Sort,
Insearch and Sword, ON-Quadrat, Und jetzt behaupte ich einfach mal,
das kriegen wir besser hin, das kriegen wir schneller hin.
Und die Idee, bei dem Merch Sword ist eben,
ich kriege die Eingabe, ich kriege ein Elemente,
ich teile die, in dem Fall in zwei gleichgroße Teile.
Und jetzt steht hier circa, weil wenn ich irgendwie sieben Elemente habe,
dann kann ich das eine, drei Elemente, das andere vier,
das ist ungefähr gleich, dann löse ich die zwei Teilprobleme,
unabhängig und rekursiv voneinander.
Also das erste Teilproblem hat nichts mehr mit dem Zweiten zu tun,
deswegen unabhängig und rekursiv, weil ich quasi einfach die Methode nochmal aufrufe.
Und dann, und da kommt jetzt diese Arbeit,
wo wirklich was passiert, dann kombiniere ich diese zwei Teilergebnisse
zu einer Gesamtlösung
Und unser Anliegen ist jetzt,
dass wir hier bei diesem Zusammenfügen nur linear viel Zeit brauchen.
Für die anfängliche Teilung auch, aber Teile,
die Eingabe in zwei Teile, da kann man sich schon vorstellen,
dass aus null Linear viel Zeit braucht.
Aber beim Zusammenfügen dann eben. Kann man sich schon überlegen,
wenn ich irgendwie die Rekurrenzgleichung nachher aufstelle,
warum ich hier nur linear viel Zeit verbringen möchte.
Werden wir auch gleich nochmal sehen. So sehe ich das
dann aus. Also ich kriege ganz oben dieses Array aus,
fünf, sechs, sieben, aus neun Zahlen unsortiert.
Und entteile ich das einmal in der Mitte durch.
Also ungefähr in der Mitte
Auf einem linken Strang ist quasi immer das,
wenn es nicht gerade ist, dann ist links immer ein Element mehr.
Dann habe ich das geteilt und jetzt mache ich rekursiv weiter.
Jetzt habe ich irgendwie auf der linken Seite dieses Arry
91372. Dann teile ich wieder in der Mitte, dann habe ich 91372,
teile wieder irgendwie in der Mitte und so weiter,
bis ich überall nur noch ein Elementige Arrays habe.
Also hier ist Arry, das 9 enthält Arry,
das 1 enthält Arridas 3 enthält, die sind alle einelementig.
Und jetzt habe ich quasi meinen Rekursionsabbruch, weil an
der Stelle kann ich sagen, dass einelementige Areas sortiert.
So ein Element ist immer sortiert. Und jetzt kommt
das Zusammenfügen und da ist jetzt eben die Idee,
dass ich sage, wenn ich zwei sortierte Areas habe,
wie füge ich die zusammen zu einem sortierten Arry
Und hier ist es jetzt erstmal nur grafisch dargestellt,
da kann man jetzt irgendwie nicht draus lesen,
wie das gemacht wird, aber hier sieht man irgendwie,
ich habe das Area, das Siemensheld,
dass Area das 2 enthält und kommt aus Ellen raus,
was 2 und 7 enthält und hier irgendwie vielleicht ein bisschen spannender 1,
3,
9 und 2,
7. Die werden dann auch irgendwie zu diesem sortierten Arry zusammengefügt und
immer so weiter, bis die eben vollständig sortiert sind.
Und so sehe das dann eben als Hauskot aus,
irgendwie kriegt dieses Area mit den Grenzen links und rechts
Und dann gucke ich immer,
wenn links tatsächlich noch links ist vorm Recht,
also wenn der Index,
wenn sich das jetzt nicht irgendwie überlappt, sondern wenn links,
wenn das immer noch ein wirkliches Area ist von AL bis AR,
dann bestimme ich eben die Mitte davon,
diesen Index Kuh und dann sortiere ich einmal die linke Seite und einmal die rechte Seite,
einfach durch einen rekursiven Aufruf.
Also hier geht das jetzt so lange weiter runter,
bis ich nur noch ein elementige Aris habe und dann merke ich die halt hier.
Na und jetzt ist es quasi fast fertig,
jetzt müssen wir aber noch diese Merch-Routine implementieren.
Und man sieht auch, da geht die Arbeit rein,
weil beim Aufteilen, das Outteilen passiert quasi hier,
wo der Index Kuh bestimmt wird.
Dadurch habe ich die ganze Aufteilung gemacht bei Merry
Dann sage ich, das ist der Index, jetzt will ich
nur noch von Elvis Kuh gehen und von Kuplus 1 bis R.
Aber das Merch wäre jetzt so die Herausforderung. Ich glaube,
das Merch-Shot dürften einige von euch schon gehabt haben.
Wir hatten Merch-Shot schon gehabt, so DM oder so.
DM, SE, echt Gegenprobe, wer hat das noch
nicht gehabt? Das ist immer spannend bei solchen Fragen,
so 80 Prozent haben keine Meinung zu dem Thema.
Was? Ob du die Auswahl nochmal hören kannst, ja,
wer hat Merch-Shot schon gehabt und wer hat es noch nicht gehabt?
Eins davon ist. Okay,
wie würdet ihr denn jetzt mal unabhängig davon,
ob ihr schon gehabt habt oder nicht,
wenn man es gehabt hat,
hat man es ja vielleicht vergessen.
Aber ich gebe euch
zwei sortierte Arrays
Und ich möchte die sortieren. Also ich gebe euch zweite TDS,
ich möchte die zusammenfügen, sodass ein sortiertes Array rauskommt.
So, jetzt habe ich es. Wie? Also ihr kriegt jetzt hier irgendwie,
da bleiben wir mal hier, ihr kriegt das Array 1,
3, 9, das ist eure eine Eingabe.
Ihr kriegt das Array 2 und 7, das ist eure
andere Eingabe und ihr wollt ein Array rauskriegen, das hier sortiert ist.
Und jetzt, ne, doof wäre jetzt,
wenn ich sage, ich mache mir ein neues Array,
packt da alles rein und führe Maxsort aus oder so.
Das ist irgendwie blöd, das führt zu nichts. Es ist zwar richtig,
so ist korrekt, aber dann haben wir da irgendwie keine Verbesserung.
Wie merge ich schnell? Die Idee war ja,
dass ich in Linearzeit das jetzt machen muss,
weil die Teilung kriege ich schon eine Linearzeit hin,
die kriege ich sogar in konstanter Zeit hin,
weil ich einfach diese Konstante Kuh berechne, diese Zahl Kuh, Entschuldigung.
Und jetzt muss ich aber das Mergin in linearer Zeit hinkriegen.
Das heißt, wenn ich da irgendwie 1, 3,
9, 2 und 7 habe,
dann darf ich jetzt nur irgendwie ein konstantes Vielfaches von fünf als Schritten irgendwie brauchen,
irgendwie O von N.
Wie kann man
das machen
Genau. Ich fange neben mir einen Pointer jeweils an den Anfang der beiden Arrays,
dann gucke ich, welches Element ist kleiner,
ist eins kleiner oder ist zwei kleiner, dann weiß ich,
eins ist kleiner, das mache ich mit dem Ergebnis Array,
da tue ich jetzt die einzelnen.
Und dann schiebe ich bei dem Array, wo ich jetzt gerade die Zahl rausgenommen habe,
schiebe ich den Pointer ein, weiter nach vorne.
Dann gucke ich jetzt drei Kleider oder ist zwei kleiner,
zwei kleiner, also nehme ich das,
schiebe das ins Ergebnis Array, schiebe da den Pointer ein weiter vor,
dann sind die Pointer auf drei und sieben,
dann gucke ich wieder, was ist da, kleiner,
Drei ist kleiner,
also kommt das als nächstes ins Ergebnis Array und immer so weiter.
Und wenn, naja,
jetzt kann man sich noch so Gedanken machen,
so über Abbruch und solche Geschichten,
wenn ich eins der Arrays komplett abgearbeitet habe und dem
anderen sind noch fünf Zahlen oder so,
dann kann ich die halt komplett nehmen und da hintun dann
das Ende
Sowas kann ich da noch machen. Also gegeben zwei sortierte Listen A und B,
dann mache ich mir so zwei solche Zeiger,
also im Grunde genommen einfach Intüter-Variablen,
die eben den Wert haben, den Index des Elements,
auf das ich gerade ein A beziehungsweise B zeige,
also das Current-Element in A und das Current-Element in B.
Und am Anfang zeigen sie jeweils auf das erste und jetzt mache ich folgendes,
solange beide Listen nicht leer sind,
also wohlgemerkt beide Listen nicht leer sind, mache ich folgendes,
nehmen wir mal ein AI und BJ, sind eben diese Elemente,
auf die die beiden Zeiger gerade zeigen.
Also Current A ist der Index so,
dass A von Current A
eben AI ist
Und dann füge ich das Kleinere von beiden der Ausgabeliste hinzu,
erhöhe den Zeiger der Liste, dessen Element gewählt wurde.
Und das mache ich immer weiter. So lange,
bis eben eine der Listen leer ist oder sogar beide Lehrer,
ja, beide können gar nicht leer sein.
Eine von beiden ist zuerst leer. Wobei Lea hier eben bedeutet,
dass einer dieser Zeiger quasi über den Arry-Rand hinausgeht.
Dann weiß ich, oh, ich habe die abgearbeitet.
Und sobald eine leer ist, füge ich die andere
eben komplett noch an. Also lass da quasi den Zeiger
nochmal zu Ende drüber laufen und füge alle Elemente an.
Warum? Weil alles, was da jetzt kommt,
größer ist als das größte Element im ersten Arry,
also kann ich die
da alle anfügen
Und dann ist das fertig. Klar. So, was müsste man jetzt noch machen?
Man müsste jetzt dieses für Merch, also für die Routine,
die da eben quasi so irgendwie halbnatürlich sprachlich stand,
jetzt müsste man die einmal als Pseudo-Code angeben,
um irgendwie sowas hier ein bisschen zu formulisieren,
dass man sagt, hier,
das sollen einfach Zeiger auf Elemente da drin sein und dann muss man die irgendwie auf eins setzen.
Da muss man sich hier überlegen,
erhöhen, vergleichen und so weiter, also das einmal irgendwie
als Pseudo-Code angeben
Und dann müsste man die als korrekt nachweisen, diese Variante dann.
Und da kann man wieder mit einer schleifenden Variante arbeiten.
Man hat hier irgendwie eine Schleife bei diesem so lange und
den ganzen Unterpunkten. Und da kann man sich überlegen,
was kann ich da für eine sinnvolle Schleifen in Variante benutzen?
Und kann dann irgendwie zeigen, dass die eben,
ne, Initialisierung, nächster Schritt und Termination.
Und dann kommt da hoffentlich irgendwas raus, sodass man daraus die Korrektheit von diesem Merch schlussfolgern kann.
Und wenn man das hat, dann weiß ich erstmal nur,
Merch ist korrekt, dann muss ich als nächstes noch zeigen,
dass damit dann tatsächlich auch dieses Merch-Sort korrekt ist.
Das kann man dann wahrscheinlich irgendwie über eine Induktion machen,
dass man sagt, naja,
wenn ich nach so und so viel Schritten Muss ich irgendwie argumentieren,
dass ich erst in ihre Kursion ganz nach unten gehe und dann sage ich,
okay, jetzt habe ich noch ein Element,
die Elemente, die sind sortiert und dann neben,
dann mache ich irgendwie eine Option darüber,
was beim Aufstieg passiert.
Da kriege ich dann ja immer sortierte Arrays und kommt da
immer wieder das Sortierte raus und dann weiß ich von dem korrekten Merch,
dass das irgendwie passiert.
Das zur Übung, das mal dann irgendwie im Detail auszuführen.
Und was wir jetzt noch machen wollen, so Korrektheit ist,
ich mache das jetzt nur gerade hier nicht.
Normalerweise müsste man das machen, dass man diese Korrektheit auch zeigt.
Bei dem Trickstort machen wir das gleich auch.
Hier sollt ihr das einmal selbst machen.
Was wir jetzt aber noch brauchen,
ist diese Laufzeitanalyse
Ah, wir können für Merchs heute nun die folgende Rekurrenzgleichung aufstellen.
Großer weißer Fleck. Wie sieht denn die Rekurrenzgleichung aus?
Für Merchsort. Also wenn ihr euch das da anguckt.
Wie sieht die Rekurrenzgleichung aus
Ich sehe ja Leute, die haben Laptop und Handy offen.
Googelt ihr das zweimal? Genau,
und Abbruch irgendwie bei 1, ne?
Abbruch bei N gleich
Um eigene konstante N. AD, Entschuldigung. Wenn N1 ist,
also wenn quasi R-Minus L nur noch eins ist,
also wenn die Arry Länge dann nur noch eins ist,
dann bricht er halt ab.
Wenn es null ist, Entschuldigung, dann bricht er ab.
Und ansonsten rufe ich ja zweimal Merchsort auf,
jeweils mit der Hälfte des Arrays.
Naja,
also so
Plus minus eins, also da muss man ja wieder ab- oder aufrunden,
aber für die Rekurrenzgleichung Analyse gleich ist das nicht so wichtig.
Und dann haben wir ja gesagt,
Merch braucht linear viele Schritte,
also zumindest haben wir gerade noch nicht gesagt,
aber kann man sich ja schnell überlegen,
dass man über beide Aris ja irgendwie,
ich kriege zwei Eingabe, Aris,
die haben zusammen die Länge N und ich erhöhe ja jeweils den Zeiger irgendwie um eins bei jedem Schritt,
das brauche ich irgendwie auch von N viele Schritte.
Das heißt, ich habe hier noch irgendwie so
eine konstante C.
So sieht das aus
Falls ein gleich eins und falls ein größerer 2. Und entweder kann man
das jetzt wieder abwickeln oder man kann das Mastertheorien benutzen.
Und das Mastertheorien, jetzt kommt diese Vertiefung zum Mastertheorien,
dass wir das, da sehen wir nochmal das Mastertheorium,
das passt auch sehr gut damit der Rekurrenzgleichung gerade.
Das A ist dann eine 2,
das B ist ein 2, das F von NSC mal N.
Und jetzt gab es eben diese drei Fälle,
dass man eben quasi das F von N,
das F von N verglichen hat mit N
hoch LogBA
Und Tefon ändert sich dann im Grunde genommen immer so verhalten,
wie das Größere von beiden. Der erste Fall war,
wenn F von N kleiner ist als N-Log BR, in Hochlog BR,
dann verhält sich Tee von denen ebenso wie das Größere, also so wie N-Hochlog BR.
Der zweite Fall ist, wenn die genau gleich sind,
also F von N ist gleich, Eno Log BR,
dann verhält sich Tee von N eben wie das Größere,
also dann ist es egal,
die sind ja beide gleich groß und in dem Fall kommt aber noch irgendwie dieser Faktor-Log 2-Ender dazu.
Leider, sonst wäre es irgendwie viel leichter,
sich das zu merken,
aber da gibt es so einen Spezialfall, dass man sagt,
hier ist dann Log 2-N noch als Faktor drin und wenn sich F von N,
wenn er von End größer ist,
als End hoch Log BR,
dann verhält sich Tee von End ebenso wie das Größere
wieder,
also wie das F von
Wobei dann hier eben auch wieder so eine Zusatzbedingung ist,
zusätzlich muss ja irgendwie diese sogenannte Regularitätsbedingung gelten.
Die sehen wir auch gleich nochmal ein Beispiel. Aber das war halt dieses Mastertheorie,
dass man immer einfach nur immer guckt sich dann an,
wenn man so eine Rekurrenzgleichung hat,
wie sieht das F von N aus?
Was ist B und A? Und da hat man halt
F von N und N und Log B A und dann guckt man,
ob man entweder das hier sicherstellen kann.
Im ersten Fall, ob man das im zweiten Fall sicherstellen
kann oder ob man das im dritten Fall sicherstellen kann.
Und je nachdem, welcher davon zutrifft,
kann man dann eben T von N-Element aus Täter von Punkt, Punkt, Punkt.
Schlussfolgern. Dann gibt es halt noch so diese Geschichte,
dass man dann eben beim dritten Fall noch gucken muss,
ob der Unteil da auch zutrifft
Genau. So, und dann kann man sich,
also genau, einmal noch kurz zu dem Devide and Conquer,
wenn man jetzt so eine Gleichung hat,
also ich mache die weit in Conquer-Algorithmus,
komme irgendwie auf diese Gleichung, dann ist das A,
die Anzahl der Teilprobleme oder eben auch die Anzahl der rekursiven Aufrufe,
die ich da drin habe.
Das N durch B ist die Größe der Teilprobleme,
also durch das B primär ausgedrückt,
aber N durch B ist halt die Größe der Teilprobleme.
Und F von N, das ist der Zeitbedarf,
den ich beim Teilen des Problems und oder beim Zusammenfügen des Problems habe.
Beim Merchstod war es jetzt so, beim Teilen,
es ist nur ein Schritt, das ist da nicht so bedeutsam,
das Zusammenfügen braucht aber linear viel Zeit.
Beim Quickstore werden wir sehen,
ist genau andersrum
Und man kann sich auch Sachen vorstellen,
wo ich irgendwie beim Teilen des Problems vielleicht,
of und end viele Schritte brauche und beim Zusammenfügen
auch wieder of und end viele Schritte oder so.
Deswegen hier und, oder, oder.
Aber so hängt quasi der die weit,
oder so einen die weiten Konka-Ansatz mit den Mastertheorien zusammen.
Aber was habt, wo ihr Teilprobleme unterschiedlicher Größe habt?
Also wenn ihr sagt, ich teile das so auf,
dass ich einmal ein Problem habe, das ist die Hälfte
der Eric-Größe und dann nochmal zweimal ein Viertel oder irgendwie sowas.
Oder vielleicht interessiert euch das eine Viertel gar nicht und
ihr habt die Hälfte und ein Viertel,
dann wird der Ansatz da nicht zu benutzen.
Dann habt ihr irgendwie sowas wie Tee von N-Viertel plus Tee
von N-Halbe oder irgendwie sowas, dann kann man das
nicht benutzen
Dann müsste man das irgendwie mit Abwicklung machen oder so. Genau,
aber üblicherweise, wenn man jetzt in die weiten Konka-Verfahren hat,
bei sehr vielen Fällen hat man sowas halt nicht,
sondern teilt irgendwie quasi einheitlich auf.
Genau so, das war das Mastertheorie und das ist die Anmerkung dazu,
wie das sich auf die, die weiten Konka-Verfahren matcht.
Und jetzt eben dieser Fall vom Merch-Sort.
Oben drüber steht jetzt immer schon der Fall, der zutrifft,
aber das ist quasi im Grunde genommen nachher das Ergebnis.
Ich habe das nur darüber geschrieben, damit man als Erinnerung
sieht, was man jetzt irgendwie prüfen würde.
Man prüft jetzt den ersten Fall, merkt, oh,
der trifft nicht zu, als nächstes prüft man irgendwie den zweiten Fall.
Jetzt hatten wir diese Rekurrenzgleichung hier aufgestellt
Und dann sagt man, okay, was ist denn überhaupt Log BA,
B-S-2-A-S-2, also habe ich Log 2-2,
das ist eins, F von Ende ist gerade dieses Zema-N.
Und was mir jetzt also miteinander vergleicht,
ist C von N und N hoch 1. Naja,
und C von N-Elemente sind Täter aus N hoch 1,
C ist die verschluckte Konstante,
also haben wir F von N das Element aus Täter N1
und dann dürfen wir eben das hier Schluss folgern.
Das ist dann der zweite Fall vorliegt und dass also
TV N in Täter von N mal Log N ist.
Genau das gleiche Ergebnis würde man auch durch Abwicklung kriegen,
aber so geht es halt merklich schneller.
Ergo-Ergebnis, Merch-Sorts sortiert diese Sequenz von Endzahlen in Täter N
mal Login
Wenn man denn noch einen Zwischenschritt beweist, dass denn tatsächlich dieses Verfahren korrekt ist.
Also das, wo da stand so zur Übung.
Genau, das ist der Fall, Fragen. Genau,
und dann wollen wir jetzt nochmal kurz Beispiele für die anderen Fälle
uns angucken und dann noch so ein Hilfsmittel nehmen für die Benutzung,
weil man, es gibt so ein Hilfsmittel variablen Transformation,
dass man das Master-Theorium auch bei Fällen benutzen kann,
die eben nicht diese Form haben von so einer Rekurrenzgleichung,
sondern die anders aussehen.
Das werden wir uns dann auch gleich nochmal angucken.
Erstmal zu den anderen Fällen noch,
das kennen wir schon vom letzten Mal,
der erste Fall Wenn ich so eine Rekurrenzgleichung hier habe,
dann vergleiche ich das wieder mit der allgemeinen Form aus dem Mastertheorien.
Hier ist jetzt A3 und B3. Dann habe ich also auch wieder Lugarithmus,
BA, Lock 3,3. Das ist also wieder eins.
Und F von N ist hier hinten der Teil.
Das ist also eins durch N, also N hoch minus eins.
Und dann vergleiche ich also N hoch minus eins mit N hoch eins. Naja,
und dann ist halt die Frage, kriege ich das hin,
dass hier N hoch minus eins Element ist aus O von
N minus engen Apsilon und das kriege ich,
kriege ich gut hin.
Da kann ich entweder, da kann ich für Apsilon
irgendwas wählen zwischen 0 und
Ich habe in dem Fall zwei genommen,
dann steht da eben N hoch minus eins,
das Element in U von N hoch minus eins.
Das ist auf jeden Fall so. Und dann ist das fertig,
nämlich der erste Fall vor und dann darf man schlussfolgern,
dass eben diese Rekurrenzgleichung hier,
das also T von N in Täter von Ende ist.
Der ist auch noch relativ einfach, der Fall.
Und der dritte Fall ist halt ein bisschen knifflig wegen dieser Regularitätsbedingung.
Wenn ich diese Rekurrenzgleichung jetzt hier habe,
da ist jetzt das mit dem Logarithmus auch ein bisschen spannender,
jetzt muss ich Log BA, also Logarithmus zur Basis vier von drei,
das ist so ungefähr
Also, weiß ich nicht, im Kopf habe ich nachgeschlagen.
Oder gibt es einen Taschenrechner ein oder so, aber man weiß halt,
dass es irgendwas, was kleiner ist als eins.
Manchmal reicht das auch schon, das zu wissen,
aber jetzt hier genauer ist es so ungefähr 0,793.
Und das F von NSN mal Login. Nein,
jetzt kann man wieder gucken, ist das irgendwie,
ist das hier kleiner gleich N hoch 0,793,
dann weiß man gleich, nee, das ist es nicht.
Es ist irgendwie gleich, also im Täter,
dann weiß man auch, nee, das ist es nicht,
dann bleibt irgendwie der dritte Fall übrig.
Also ist das irgendwie in diesem,
kann ich so ein Epsilon finden,
so das N mal Login-Element ist aus N
hoch 0,793 plus irgendwie
so ein Epsilon
Ja, ja, und Enma Lock N
ist ja N-Hoch 1, mal genommen mit noch irgendwas.
Das heißt, solange ich das hinkriege, dass ich irgendwie
maximal bei diesem N-Hoch 1 bin, ist alles gut.
Ich will mir also als Epstilon irgendwie 0,2. Und dann muss
ich gucken, ob ich jetzt das hingekriegt habe,
dass N mal Lock N in Omega-Hoch 0,993 ist oder so.
Man will das mit dem Limes machen, dann sieht man
sehr schnell, dass das geht. Das heißt,
das hier gilt, ja, wir finden so ein Epstilon,
sodass N mal Lock N enthalten ist,
in Omega von N hoch 0,793 plus Epstilon.
Und der dritte Fall kommt also zur Anwendung.
Aber hier steht ja, was noch gelten muss,
das muss noch dieser Teil gelten
Das heißt, wir müssen jetzt gucken, ob diese Regularitätsbedingungen erfüllt ist.
Dann kann man auch erst mal wieder einsetzen. A ist 3,
BS4, F von N ist N mal Login.
Und das heißt, insgesamt muss N durch 4 steht hier.
Das heißt, wenn ich N mal Login habe und überall,
wo entsteht N durch 4 Einsätze, dann habe ich Endviertel,
mal Logerhythmus von Endviertel.
Und davor noch der Faktor 3 hier von dem A. Also ich muss gucken,
dass dreimal ein Viertel, mal Logerhythmus von Endvierteln,
das Gleiche ist,
wie das hier Delta mal N
mal Login
Also ich muss gucken, ob ich das hier und diese kleine Gleichbeziehung da,
ob ich das hinkriege für irgendeinen Data. Naja,
und dann kann man sich überlegen,
irgendwie hier steht drei Viertel N, hier steht Delta N,
hier Lugarithmus von ein Viertel, hier Lugarithmus von N,
der Lugarithmus steigt ja so schön monoton,
das heißt irgendwie bei genügend großen Ends kann ich das sicherstellen,
dass drei Viertel mal N,
Malugarithmus von End Vierteln eben kleiner gleich drei Viertel N,
Malog N ist
Ich habe jetzt hier nur für diese kleine Gleichbeziehung einfach aus dem Argument des Logarithmus,
da habe ich einfach nicht ein Viertel genommen, sondern N.
Das ist ein größeres Argument und dann ist der Logarithmus davon eben größer,
das ist schön. Und dann kann ich sagen,
naja, das ist das Gleiche wie Delta von FN,
wenn ich eben Delta auf drei Viertel setze.
Das heißt, ich kann tatsächlich so ein Delta finden, sodass diese Ungleichung hier gilt.
Und damit habe ich sowohl das Erste hier gezeigt,
dass F von Ende dem Omega ist,
als auch das Zweite, dass die Regularitätsbedingung gilt.
Also kann ich jetzt endlich schlussfolgern,
dass T von N in Täter von FN ist.
Und FN war N mal Login, also gilt das hier.
Was man so machen muss, ist,
man bestimmt dieses N-Hochlock BA und dann guckt man,
gibt es so ein Epsilon, sodass diese Omega-Gleichung da erfüllt ist.
Und als nächstes guckt man, gibt es so ein Delta,
sodass diese Regularitätsbedingung erfüllt ist
Muss man so an zwei, drei Stellen arbeiten.
Fragen. Gibt es denn natürliche zum Beispiel... Gibt es
schon, aber bei den Funktionen, die wir haben,
ist die meistens erfüllt.
Bei dem, was so eine Algorithmenanalyse auftritt, ist das meistens erfüllt.
Führt ein bisschen zu weit,
wenn man da jetzt
ein Gegenbeispiel konstruieren will
Ob es Techniken gibt, um sich ein gutes App-Senon oder Delta zu wählen.
Im Grunde genommen so Erfahrung. Also du weißt ja,
dass Polynome, dass das quasi die Polynome mit dem größeren Exponenten,
die sind dann irgendwie größer als die mit dem kleineren Exponenten.
Du weißt, wenn du gleiche Polynome hast,
aber bei dem einen multiplizierst du noch mit dem Logarithmus dran,
dass das dann auch irgendwie größer wird und sowas,
dann sehen wir auch gleich, gibt es noch so Grenzfälle,
dass halt N-Malock-End nicht für das Master-Theorie nicht wirklich größer ist als N,
weil man dann eben nicht diesen polemiellen Unterschied haben kann,
das sehen wir gleich.
Aber so, dass man das ungefähr weiß,
dass man ungefähr schon sehen kann,
was kleiner und was größer ist
Sonst einfach von der Idee, wenn du im Kopf kurz ein paar Zahlen einsetzt,
so grob, dass der irgendwie weiß, naja, Endquadrat und N hoch 1,
ich sag jetzt bei beiden mal 5 ein und dann sehe ich schon,
das Endquadrat ist irgendwie größer oder das N mal Login oder irgendwie sowas.
Und dann weiß man schon grob, welcher Fall zutreffen muss. Und für das App-Silon,
wenn du es dir jetzt aufschreibst hier,
und hier siehst du ja jetzt irgendwie,
du hast N mal Login,
also N hoch 1 und irgendwas kommt noch da dran,
halt nichts oben im Exponenten,
aber es wird noch was dran multipliziert und hier ist so N hoch 0,793. Naja,
dann weißt du schon, okay,
wenn ich meinen App-Silon jetzt so wähle,
dass ich nicht über die 1 rüber hüpfe,
also dass quasi 0,793 plus App-Silon nicht größer wird
als eins,
dann ist alles gut
Also so kann man das so grob machen, um so ein App-Zone rauszufinden.
Und wenn man dann eins hat, kann man natürlich zur Sicherheit,
also das fehlt hier jetzt so ein bisschen,
wenn man das hat und sich das noch ganz genau überlegen will,
dann nimmst du noch einmal diese Liebesnotation und zeigst, dass es tatsächlich gilt.
Und dann würdest du halt in dem Fall mit diesem N-Ma-Login und dem N
hoch 0,993 und dann durchkürzen, fliegt das eine halt weg und dann ist es fertig. Genau,
und bei der Regularitätsbedingung, wie gesagt,
die trifft eigentlich hier in den Fällen eigentlich immer zu bei den Funktionen,
die wir so haben, Aber auch da,
also meistens kann man irgendwie, das Delta,
du siehst ja, also du versuchst eigentlich den Teil hier,
dieses N mal Login und den Teil, der hier links steht,
den versuchst du halt grob so ein bisschen ähnlich zu machen.
Und du darfst halt hier mit dem Delta noch so rumspielen,
um einfach irgendwie das noch,
ein Vielfaches darfst du nicht nehmen,
du musst ja ein Delta kleiner als eins nehmen.
Ja, du guckst halt quasi, ob zwischen dem hier,
zwischen dem Faktor und eins,
ob da noch was dazwischen passt
Und dann kannst du halt vorher noch versuchen, hier dieses Endviertel und das N,
das irgendwie gleich zu machen, ob das okay ist oder nicht.
Also wenn hier jetzt nicht ein Viertel steht,
sondern viermal N, dann hast du ein Problem,
weil dann hast du auf der linken Seite etwas,
wo der Logarithmus größer ist als auf der rechten Seite und dafür
ist vielleicht auf der rechten Seite das N größer als auf der linken Seite,
weil du hast auf der einen Seite Ende und auf dem anderen Dreiviertelende wird es irgendwie so ein bisschen unangenehmer,
aber hier kannst du quasi faktorenweise vergleichen und mal gucken,
was größer ist und dann ist gut.
Sonst noch Fragen
Genau, und dann hier das Beispiel, wo man das Mastertheorie eben nicht benutzen kann.
Wir haben jetzt jede Menge Rekurrenzgleichung gesehen, wo das funktioniert.
Und das ist eben auch ziemlich mächtig. Aber wenn man
eben genau diesen Fall hat, dass ich jetzt sage,
Tee von NS2 mal Tee von den halbe plus N mal Login.
Jetzt habe ich nämlich dieses Problem,
dass ich N hoch 1 mal Logorithmus von N vergleichen will
mit N hoch 1. LogBR ist Log 22, also N hoch 1.
So, und die sind nicht ponioniell unterschiedlich, sondern nur mit so einem lugarithmischen Faktor. Bleibt man dann nämlich das Problem hier,
also ich vergleiche die beiden jetzt miteinander,
F von NSN mal Login und Logby A ist 1,
also gucke ich, ob N mal Login und N hoch 1,
ob ich irgendwie sowas machen kann,
das N hoch 1, plus Y oder Minus-Epsilon,
dass das dann echt größer oder kleiner irgendwie wird als dieses N mal Login.
Sieht zuerst so aus, als ob dieser dritte Fall zutrifft,
weil das F von N ja irgendwie größer ist als N hoch 1,
aber es ist eben nicht größer als N hoch 1 plus Äpsilon.
So ein Äpsilon größer Null findet man nämlich nicht.
Das hängt damit zusammen, dass dieses F von N nicht
Punimir größer ist, sondern nur diesen logarithmischen Faktor hat.
Das heißt, hier hat man ja den dritten Fall
des Mastertheoriens versucht anzuwenden
Und das ist quasi eine Funktion, dieses F&N und
dieses Addison 2 Funktionen, dieses F&N und dieses NO1,
die quasi zwischen dem zweiten und dritten Fall liegen.
Die sind nicht gleich, die eine ist zwar größer als
die andere, aber nicht dieses polynomiell größer.
Das heißt, ich falle genau zwischen diese beiden Fälle zwei
und drei des Mastertheoriens und kann das deswegen nicht anwenden.
Genauso gibt es Fälle, die zwischen eins und den ersten
und zweiten Fall des Mastertheoriens fallen, wo das quasi umgedreht ist.
Und bei denen ist, bei diesen beiden Fällen ist dann das Mastertheorie eben nicht anwendbar.
Da muss man das dann anders machen. Also bei der
hier könnte man ja mit Abwicklung irgendwie versuchen zu arbeiten.
Genau, aber eben nicht mit den Mastertheorien der dritte Fall,
wo man das Mastertheorien nicht benutzen kann, ist eben,
wenn die Regularitätsbedingung nicht zutrifft.
Mir geht das auch nicht. Das sind so die drei Fälle,
wo man eigentlich eine Rekurrenzgleichung hat, die zugänglich ist für das Mastertheorie,
wo man dann aber eben in Fälle reinrutscht,
die nicht mit dem Mastertheorien abgedeckt sind.
Die anderen Sachen sind ja sowas wie dieses Tee von Ende
ist gleich dreimal Tee von N minus 1 oder irgendwie sowas,
da hat man ja in den Übungszetteln gesehen,
dass da das Mastertheorie irgendwie auch nicht anwendbar ist.
Da steht es nochmal, das liegt zwischen Fällen 2 und 3
und dann gibt es mit Gleichargumentation etwas,
was zwischen den Fällen 1 und 2 liegt und bei all
denen ist irgendwie dieses Mastertheorie nicht anwendbar
Damit das mit dem Wort Fall und Fälle da nicht so irritierend ist,
habe ich immer Fälle des Master-Theoriens geschrieben, wenn das gemeint ist.
Also wenn dahinter steht, das Master-Theorien sind die Fälle des Master-Theoriens gemeint.
Und mit Fall sonst ist eben etwas gemeint,
zwei Funktionen, die man da vergleichen will.
Fragen, das waren die Fälle 1, 2,
3 aus dem Master-Theorien mit noch der Anmerkung,
wo man rausrutschen kann aus dem Master-Theorien.
Wieso bei dem vorherigen Beispiel
Ach, da? Weiß nicht, rechne doch aus.
Keine Ahnung. Wird ausrechnen. Fragen. Gut, dann
variablen Transformation. Spannendes Hilfsmittel. Das sieht auch aus erstmal
wie eine Rekurrenzgleichung, die für das Mastertheorie nicht bearbeitbar ist.
Warum, naja, der Tee von Wurzeln ändert irgendwie nicht
so viel zu tun mit Tee von Enhalbe oder so.
Auch wenn ich das Wurzel entschreibe als Enhocheinhalb,
sieht das immer noch nicht so gut aus
Also das ist irgendwie nicht zugänglich. Genauso wie eben,
wenn ich so einen Fall sehe wie Tee von dreimal Tee von denen,
gleich dreimal Tee von N-minus 1 oder so,
würde ich auch sagen, ist nicht zugänglich.
Nur hier kann man mit variablen Transformationen arbeiten und kann es noch hinkriegen,
dass man es bearbeiten kann. Wie geht das? Man überlegt sich,
dass es, hier steht irgendwie ein Logarithmus von N,
hier steht das N, das ist N-hocheinhalb,
und so ein Logarithmus hier, das bietet sich irgendwie an,
dass man dann sagt, okay,
für Logarithmus von N schreibe ich mir jetzt überall ein M hin.
Ich hätte mal einen K nehmen sollen,
dann ist das beim Sprechen nicht so.
Also für das Logarithmus von N schreibe ich jetzt einen M hin.
Und dann kann ich für zwei hoch
M, kann ich für N zwei
hoch M hinschreiben
Und für Wurzeln, also N-Hoch, ein halbe, kann ich zwei hoch M
halbe hinschreiben. Wenn man das alles substituiert,
dann steht da eben, das gleiche Rekurrenzgleich,
aber jetzt steht hier irgendwie Tee von zwei Hoch M,
also das Ende ist ja zwei Hoch M,
ist zweimal Tee von zwei Hoch M halbe,
wo zu Ende ist zwei Wochen halbe,
plus M, M ist Logothmusflatten.
Einfach eine Substitution benutzt. Das Problem ist halt nur,
man muss auf diese Substitution kommen. Jetzt weiß man auch immer noch nicht,
ob das weiterführt, also jetzt habe ich erstmal eine Substituierte,
das ist schön und gut, aber vielleicht führt das ja nirgendwo hin.
Aber was man jetzt machen kann, ist,
jetzt sage ich das hier,
zum Beispiel quasi eine neue Rekurrenzgleichung und sage,
S von M ist Tee hoch zwei
Wenn ich das mache, dann sieht das jetzt schon viel schöner aus,
wenn S von MT hoch 2M ist,
dann ist S von M halbe Tee von 2 hoch M halbe.
Ja, und dann habe ich erst von M diese Rekurrenzgleichung.
Das habe ich einfach, überall wo Tee auf 2M
steht, schreibe ich S auch M hin.
Hier steht Tee von 2 auf M halbe, das ist ein S hoch,
S von M halbe und dann sieht das so aus.
Und das sieht irgendwie, ne, das sieht bekannt aus,
das sieht genauso aus wie die Rekurrenzgleichung vom,
von Merch Sword, weil davon abgesehen,
dass da ein M steht, statt 10 mal M,
aber die Konstante ist ja nachher bei dem,
bei dem Benutzen des Rekurrenzgleichung
eh nicht so wichtig
Verstanden? Wenn man die jetzt hat, diese Rekurrenzgleichung SM,
dann kann man für die jetzt ganz normal das Mastertheorie anwenden,
dann kriegt man eine Lösung raus und dann muss man
die Lösung wieder zurückführen quasi mit diesen Gleichheiten,
die man hier hatte, auf eine Lösung für Tee von N.
Also das war das, was wir bisher hatten,
in der ersten, beim ersten Bullet ist die gegebene Rekurrenzgleichung,
beim zweiten ist die,
die man rauskriegt,
wenn man diese Substitution M
gleich Login benutzt
Und beim dritten ist dann das, was man rauskriegt,
wenn man sagt, S von M so gleich,
Tee von 2 Hoch M sein.
Jetzt kann man das Mastertheorien benutzen für die Rekurrenzgleichung hier
für die dritte Zeile, dann kriegt man eben raus,
dass S von M gleich Täter von M malock M ist, mit Mastertheorien.
Und jetzt muss man das noch zurückführen. Jetzt weiß ich,
Tee von N ist ja das Gleiche wie Tee von
2 Hoch M ist das Gleiche wie S von M.
Bei S von M weiß ich,
dass es in Täter M malock M drin und für M
kann ich ja nachdem hier überall,
wo M steht,
kann ich
Login schreiben
Also bin ich, ist mein Tee von N in Täter von Login, mal Log-Login.
Und dann hat man eine Abschätzung für T von N. Genau,
und hier habe ich jetzt mal diese Schreibweise mit dem Gleichheit statt mit dem Enthaltensein,
weil man das dann so ganz gut von nix nach rechts lesen kann.
Ja, und dann hat man diese Rekurrenzgleichung,
die eigentlich nicht zugänglich ist, wo man normalerweise sagen würde,
kann ich das Mastertheorie nicht für benutzen,
hat man die doch gelöst.
Mit diesem, ich mache erst eine Variablentransformation,
dann benutze ich das Mastertheorie und dann mache ich quasi die
Variablentransformation wieder rückgängig.
Und dann habe ich
die Rekurrenzgleichung eben doch gelöst
Also habt eine Abschätzung dafür. Giggy. Ersten, weitere Fragen?
Kurzer Einschub noch, wenn ich diese Rekurrenzgleichen von Merch Sword verallgemeinern will.
Jetzt habe ich hier nicht zwei stehen, sondern einen Q.
Da kann ich mir überlegen, was gibt es so für Fälle.
Wenn ich Q größer zwei wähle,
dann habe ich für meinen Enhoch Lock BA,
das B ist ja jetzt die ganze Zeit eine zwei,
aber das A wird jetzt irgendwie größer,
also die Anzahl der Teilprobleme,
die ich betrachte,
wird größer
Das hätte man, wenn man einige von den Teilproblemen irgendwie mehrmals betrachten muss.
Kann passieren. Und wenn man das hat, dann wird eben
dieses N-Hoch-Lock-BA, ist dann ja größer als das N-Hoch-1 hier.
Und dann verhält sich das TVN eben wie das Größere,
also wie das N-Hoch-Lock-BA, also in unserem Fall, ist A gleich Puh und B
gleich 2. Also verhält sich das so wie der hier.
Sprich, wenn ich mehr rekursive Aufrufe habe,
also bei diesem wachsenden Kuh, dann wird das quasi der ausschlaggebende Faktor.
Und wenn ich sowas habe wie Kuh gleich 1,
so wie beim binären Suchen oder sowas,
dass ich nur ein Teilproblem mir immer wieder betrachte,
dann wird eben dieses N-Hoch-Logryphmus über das 2 von 1,
das wird dann eben Kleiner als das C von N.
Also fällt sich meine Rekurrenzgleichung so wie das Größere hier, das C von N.
Und dann ist Tee von N in Täter von N. Das heißt,
die meiste Arbeit ist dann auf der obersten Ebene, nämlich da,
wo ich irgendwie zehnmal in viele Schritte brauche, um das zu lösen.
Also das ist eine Verallgemeinerung von Merchshot, dass man so weiß,
okay, Merchshot, wo ich mir zwei das angucke,
aber immer halbiere, da bin ich in N mal Login.
Wenn ich nicht halbiere,
sondern ich mir, also wenn ich auch halbiere,
habe ich mir immer nur eine Hälfte davon angucke,
dann bin ich in N, also besser.
Und wenn ich mir ein Teil Problem mehrfach angucken muss,
wenn das Kuh also wächst,
dann bin ich schlechter als N mal Login,
dann bin ich in N hoch im Log 2
zu Logrhythmus,
das war alles 2 von
Das als Einschub. Ja, und das zusammengefasst für
das Deviite in Konka-Verfahren. Also jetzt mal wieder weg von
den Rekurrenzgleichungen hin zu dem Deviite in Konka-Verfahren.
Das sind so die drei Schritte, dieses Deviite in Konka-Musters oder Paradigmas.
Zuerst teile ich das Problem auf. In Entteilprobleme oder in
der Notation des Master-Theoriums in Ahr-Teil-Probleme. Dann beherrsche ich die Teilprobleme,
deswegen teile und beherrsche die Viet in Konka,
beherrsche ich die durch rekursives Lösen.
Das heißt, ich teile das immer weiter.
Oder wenn ich bei so einem einfachen Fall bin,
wenn das Teilproblem hinreichend klein ist, dann löse ich das direkt.
Also bei Merch Sword,
wenn die Aris nur noch die Größe 1 haben,
bin ich fertig und löse das direkt
Und dann verbinde ich die Lösung zur Lösung des übergeordneten Problems.
Also die Idee ist ja, ich steige rekursiv ab,
dass Ary wird immer kleiner.
Und dann habe ich nachher zwei ganz kleine Arys, verbinde die.
Dann habe ich zwei immer noch kleine Arys,
aber schon ein bisschen größer, verbinde die und so weiter,
bis ich irgendwann zwei halbgroße Lösungen habe und die zur Lösung des ganzen Problems zusammenfüge.
Und das mache ich halt auf jede Rekursionsübene.
Gut, Fragen zum Merch Sword oder zu Rekorrenzgleichungen.
Das war die erste Hälfte gerade. Sonst kommt gleich noch
Quick Sword
Kriegst du Ort. Auch ein Deviiting Cocker-Algorithmus. Da kann
man schon mal als Vorausschau, im schlechtesten Fall ist da
ein Täter von Endquadrat, was ja eigentlich schlecht ist.
Da würde man normalerweise sagen, hey,
dann nehme ich doch Merchshot, der ist besser.
Die erwartete Laufzeit, also das, was der eigentlich meistens hat,
auch in der Praxis, ist Täter von N. Malogin.
Und weil der über dieses Täter eine kleinere Konstante versteckt als
eben Merchshot, ist der in der Praxis meistens überlegen.
Also meistens wählt man den in der Praxis. Aber da,
da tritt auch dieser Fall ein,
was irgendwie in der ersten Vorlesung mal so als Warnung war,
dass man immer dieser U-Notation immer so ein bisschen gucken muss,
ist das eigentlich auch okay mit den versteckten Konstanten oder nicht.
Normalerweise würde man sagen, ich nehme Merchshot,
der ist schneller
Und wenn man jetzt ganz genau hinguckt und irgendwie einen Fall hat,
wo das gerade besonders wichtig ist,
dann nimmt man vielleicht doch lieber den Quicksalt,
wobei man sich dann, wie gesagt,
im schlechtesten Fall hatte die Laufzeit,
da muss man sich vielleicht noch ein bisschen angucken,
wie denn die Eingabeinstanzen immer aussehen.
Also ob das wirklich okay ist, den zu nehmen.
Ja. Genau, und beim Quicksalt ist es jetzt so,
bei Merch-Salt war das Teilen einfach und das Zusammenfügen war der schwierige Teil.
Beim Quicksalt ist es genau andersrum. Man wählt zuerst ein
Element aus dem Array aus, das wird das sogenannte Pivo-Element,
wir nennen das mal X.
Und dann teile ich meinen Array, das ist im Moment
von PBSR geht,
oder so gefunden
Links bis rechts, ich weiß gar nicht, wo ich das P genannt habe,
von PBSR, das teile ich in zwei Teilfelder auf.
Einmal das Teilfeld, was nur Elemente enthält,
die kleiner sind als X und einmal das Teilfeld,
was nur Elemente enthält, die größer sind als X.
Und dann schiebe ich nochmal ein X an die richtige Stelle direkt dazwischen.
Also ich habe quasi mein ganzes Arry. Wir werden als Pivo-Element X
gleich das am weitesten rechts stehende Element im Arry nehmen.
Dann habe ich das, das halte ich fest.
Und jetzt sortiere ich alles andere Inplays um,
sodass die ersten Elemente des Arris hier von P bis Q minus 1,
dass die halt all die Elemente enthalten,
die kleiner sind als mein Pivo-Element.
Und das, was danach kommt, ist alles größer als
mein Pivo-Element. Und dann tausche ich noch einmal aus und
dann steht mein Pivo-Element an der richtigen Stelle
Da sieht man schon, beim Merch-Sort muss sich
nur irgendwie das Element Kubisch oder den Index Kuh bestimmen,
durch eine L plus R-Halbe, fertig.
Und hier habe ich jetzt viel mehr Arbeit beim Teilen.
Und danach habe ich gerade mal ein Element an der richtigen Stelle,
also nach dem ganzen Teilvorgaben steht das Pivo-Element an der richtigen Stelle.
Alles davor ist kleiner, alles danach ist größer,
aber die Sachen sind immer noch komplett unsortiert.
Ich weiß nur, es ist kleiner als das Pivo,
wenn du es größer als das Pivo-Element.
Und dann rufe ich aber rekursiv auf denen das wieder auf,
dann kommt wieder irgendwie ein Pivo-Element an die richtige Stelle und immer so weiter.
Bei jedem Rekursionsschritt kommt quasi ein Element an die richtige Stelle
und dann ist gut
Genau, verbinden. Hier ist beim Verbinden nichts zu tun. In der,
wenn man das jetzt implementiert, dann erst mal das Übergeordnete hier,
Quicksort, ich rufe, wir haben ja ein paar Tischen genannt,
also ich partitioniere quasi mein Feld in die Elemente,
die kleiner sind als mein,
ich glaube der Index AR und die Elemente, die größer sind.
Kuh ist dann der Index, wo das Pivo-Element hinkommt,
das liefert das zurück und dann rufe ich
halt links und rechts von diesem Kuh wieder Quicksort auf.
Und dann sieht man hier schon,
man hat irgendwie zwei rekursive Aufrufe,
die jeweils ungefähr mit der Hälfte des Aris arbeiten
Wenn er also das hier in Linearzeit ablaufen würde, dann wäre alles wieder gut.
Das Problem ist, das Element hier, dieses Kuh,
das muss nicht unbedingt die Mitte sein. Und dadurch habe ich das,
ich zwar hier, zwei rekursive Aufrufe habe,
aber nicht eventuell nicht so schön wie bei Merch Sword,
wo ich sage, ich habe zwei rekursive Aufrufe mit TN halbe,
sondern ich habe eventuell zwei rekursive Aufrufe,
irgendwie einer, der mir nichts bringt,
weil der nur die Länge 0 oder 1 hat.
Und einer, der die Länge N minus 1 hat.
Und wenn ich das dann so weitermache,
dann habe ich Enricossio aufrufen und alle haben die länger in minus 1,
in minus 2, in minus 3,
in minus 4, minus 5 und so weiter.
Und dann ist die Laufzeit eben nicht in mal Login,
sondern tatsächlich quadratisch
Ja. So wird er aufgerufen und jetzt halt der spannende Teil irgendwie dieses Partition, ne?
Also was passiert? Ich nehme mir als erstes Element X,
mein Pivo-Element, das am weitesten Rechtsstehenden im Arry.
Ich habe ja hier, ich habe das ja aufgerufen mit Arry R,
1, der am weitesten links stehende Index,
Länge A, der am weitesten rechts stehende Index.
Das heißt, wenn das R hier Länge A ist,
dann ist das das rechte Element in dem Arry, das ist mein Pivo-Element X.
Und dann passt eine i gleich P minus 1,
P minus 1 war ja gerade die Eins,
also dass am weitesten links stehende Elemente im Arry,
das heißt, E ist davon noch links,
also das zeigt gerade ins Leere.
Jetzt passieren hier
irgendwie komische Dinge in der Vorschleife
Und der Swap hier, der führt nachher dazu,
dass das Pivo-Element an die richtige Stelle kommt.
Das ist dann also an der Stelle A iPlus 1
und den Index liefere ich dann zurück.
Das ist dann hier dieses Kuh damit. Ich weiß,
oh, da ist mein Pivo-Element, das ist richtig.
Und ich muss nur noch das Links davon sortieren und das
rechts davon sortieren. So, und für die Vorschleife,
die gucken wir uns jetzt mal genauer an.
Die Zeilen 1, 2 und 10,
die spare ich mir gleich wegen Platzmangel.
Das hat dann nicht mehr raufgepasst. Aber ihr wisst,
X ist das Pivo-Element AR. I startet an der Stelle
P-1 und ganz zum Schluss
wird eben
IPlus 1 zurückgeliefert
Ohne die Zahlen sieht das so aus. Also hier sieht man es
auch in dem Beispiel, R ist das Element ganz rechts.
Also XSAR, R ist das hier, X ist das.
X ist, also die vier,
I startet an der Stelle und ganz zum Schluss,
wenn ich ganz durch bin, dann würde ich iPlus 1 zurückliefern.
Stimmt das? Ja. XSAR, iSP minus 1 sieht man,
ja, genau. Und jetzt kann man sich überlegen,
jetzt kann man sich mal angucken, was da so schrittweise passiert.
Also P zeigt hierhin, J zeigt hier, oder?
Am Anfang J ist gleich P, das heißt J zeigt auch hierhin.
Und ich lasse jetzt das J irgendwie von hier bis R
minus 1 durchlaufen. Also das J geht tatsächlich einmal über
dieses ganze Eric über
Das wird ja auch nirgendwo hier,
das kann man sich ja mit den Schleifenrumpf angucken,
ob J unvorsichtigerweise irgendwo mal neu gesetzt wird, wird es nicht.
Das heißt, das wandert einmal komplett über dieses Eric über.
So, was macht man? Man guckt, ist AJ,
kleiner gleich X. Also ist die zwei, kleiner gleich der vier.
Ja, also erhöhe ich I um eins. Wandert I
da um eins. Und ich swappe AI mit AJ,
da passiert jetzt aber nicht so viel. Also,
wenn ich I um eins erhöhe, dann ist I hier.
Und dann tausche ich also AI und AJ aus,
aber das ist beides das gleiche Element, also da passiert noch nichts.
Und dann wird hier im Schleifenkopf J um eins erhöht.
Das heißt, jetzt zeigt JJ hier hin
So, jetzt wird wieder geguckt, ist AJ, kleiner
gleich X. Also, kleiner gleich der Vier. Das ist nicht
der Fall. Das heißt, ich erhöhe ihn nicht.
Ich swappe auch nicht. Und das J wandert weiter.
Und mit der farblichen Markierung hier,
das Blaue und das Ruth, da könnt ihr schon sehen,
irgendwie blau wird nachher der Bereich sein.
Das ist alles kleiner als das Pivo-Element. Rot wird der
Bereich sein, das ist alles größer als das Pivo-Element.
Und dieses I, das versucht nachher genau die Grenze zu finden.
Also, dass das I quasi bis dahin läuft,
wo all die Elemente drin sind, die kleiner sind als das Pivo-Element.
Und alles, was dann nach dem I kommt,
das ist alles größer
Bist du den ja auch zumindest. So, jetzt wird wieder geguckt
, ist AJ. Hier ist das kleine gleiche X,
ist sieben Kleiderlei 4. Nee,
also passiert wieder nichts und ich erhöhe einfach nur,
dass J um 1 im nächsten Schleifen durchlaufen.
Geht er dahin. So, und jetzt kommt der spannende Teil jetzt,
sage ich, okay, ich vergleiche eins mit vier,
eins ist kleiner als vier, also muss irgendwas passieren.
Das I erhöht sich jetzt um eins, geht also an diese Stelle.
Und jetzt tausche ich AI und AJ aus. Also das
Element AJ zeige ich gerade auf ein Element, das kleiner ist.
Und AI zeigt auf ein Element, das größer ist.
Warum zeigt er ihr jetzt auf ein Element, was größer ist?
Bisher war ihr das letzte Element, das kleiner ist.
Also muss das nächste eins sein, was größer ist.
Wenn ich die beiden jetzt austausche, 1 und 8, dann stimmt das wieder.
Dann geht alles, was bis zum IndexI geht,
ist kleiner als das Pivot-Element und das danach ist größer.
Also hier, I wird um einen erhöht, 8 und 1 werden ausgetauscht.
Und J beim nächsten Schleifenrumschleifendurchlauf geht dann wieder ein weiter.
Jetzt habe ich wieder dieses, dass ich von A1 bis AI,
sind all die Elemente, die kleiner sind,
von der AI plus 1 bis AJ minus 1 ist alles,
was größer ist und alles, was noch zwischen AJ und AR ist,
da,
das ist noch nicht sortiert.
Aber so wird quasi dieses Arry jetzt Schritt für Schritt
für Schritt
weiter partitioniert
Es wird wieder geguckt, es ist drei kleiner als vier,
das ist auch der Fall. Dann wird I um eins erhöht,
Simon 3 werden ausgetauscht und J wird um eins erhöht.
Fünf kleiner als vier, nee, dann geht das I
einfach weiter. Sechs kleiner als vier, nee,
geht das J auf weiter, Entschuldigung, J geht weiter.
So, jetzt ist das J irgendwie hier angekommen.
J gleich R, also bricht diese Schleife hier ab,
die geht ja nur bis R minus eins.
Und jetzt weiß ich, dieser Bereich bis I ist kleiner,
der Bereich hier ist größer und jetzt swappe ich noch das Element,
die vier hier mit dem AI plus eins.
Und dann habe ich es erreicht, mein Pivo-Element an der
richtigen Stelle steht. Alles, was links davon ist,
ist kleiner und muss jetzt noch rekursiv sortiert werden.
Und alles, was rechts davon ist,
ist größer und muss auch noch rekursiv sortiert werden.
Kann man glauben, dass das funktioniert?
Müsste man jetzt noch als korrekt nachweisen. Wenn ihr euch
das hier so anseht. Also das ist ja,
der spannende Teil passiert ja irgendwie in der Vorschleife.
Wenn man uns jetzt irgendeinen Punkt hier ansehen,
den da hat, was wäre denn eine sinnvolle Schleifenden-Variante,
irgendwas,
womit man arbeiten kann
So grob. Die schleifenden Variante sollte irgendwas sein,
was eine Aussage macht über den Inhalt des Arrays,
der quasi bei jedem Anfang der Schleife wieder komplett richtig ist.
Also wenn ich jetzt als,
ich könnte als Schleifen in Variante nehmen,
die Summe da drin ist irgendwie, weiß ich nicht,
neunmal acht halber oder irgendwie sowas.
Das hilft mir aber wahrscheinlich nicht so.
Die Summe aller Elemente bleibt die ganze Zeit gleich.
Yay. Oder die Array-Elemente bleiben die ganze Zeit gleich.
Ja, okay, ist auch eine Schleifen in Variante,
bringt mir aber auch nichts
Was mir was bringt. Deswegen habe ich den Snapshot da genommen,
dass ich irgendwie was sage über die Aufteilung des Arrays und
das nachher sinnvoll benutzen kann, um Schluss zu folgern,
jetzt ist das Ganze Array irgendwie richtig sortiert.
Ja. Genau. Genau
Genau. Also es gilt nicht immer, aber es gilt halt immer,
wenn die Schleife neu angefangen wird. Und das reicht ja auch so. Genau,
und dann hast du, das sind zwei Bereiche,
dann hast du als dritten Bereich, wenn du so möchtest,
noch den unsortierten Bereich und als vierten Bereich das Pivo-Element.
Und die vier Bereiche, die sind immer richtig. Also die sind immer richtig,
die sind immer so wie gerade von dir angegeben,
dass man irgendwie sagt,
jetzt kann man es noch formal sagen, dass man sagt,
irgendwie von eins bis ihr ist immer kleiner,
von i plus eins bis J minus eins ist immer größer,
von J bis R minus eins ist undefiniert und er ist gerade das Pivo-Element.
Das sind die vier Bereiche. Also das Feld ist während
dieser Aufteilung in vier Teile zerlegt und die lassen sich dann
in einer schleifenden Variante formulieren
Für jeden Feld in XK gilt, zu Beginn der Iteration.
Wenn K eben zwischen diesem PBSI ist,
also P ist ja am Anfang eins, also den ganzen Bereich,
und nachher durch diese rekursiven Aufrufe ist das P ja immer an irgendeiner anderen Stelle.
Also wenn ich hier, wenn ich für den roten Bereich nachher rekursiv aufrufe,
dann ist mein P eben hier das fünfte Element in dem Erry.
Deswegen steht da jetzt nicht von eins bis irgendwas,
sondern halt von P bis irgendwas.
Also von P bis I sind genau die Elemente,
die kleiner gleich X sind,
von i plus eins bis J minus eins sind die Elemente,
die größer als X sind.
Und wenn K gleich R ist,
naja, dann ist es eben
das Pivo-Element
Das ist hier nochmal als drittes extra gemacht, weil man,
wie gesagt, da bei diesem Pivo-Element eine gewisse Wahlfreiheit hat.
Also hier ist es jetzt so, dass es immer das im weitesten Rechtsstehende ist.
Man kann das am altesten Linksstehende nehmen, man kann immer das nehmen,
was in der Mitte ist, irgendwie solche Sachen.
Aber so ist es, so sieht man ganz gut,
dass man einmal das ganze Ende rübergeht und das sortiert.
Genau, der vierte Teil sind eben dann
die Indizes zwischen diesem J und R minus 1,
die noch nicht klar definiert sind.
Genau. Ja, da kommen wir nochmal verifizieren,
dass das tatsächlich stimmt
Und jetzt geht man los und beweist diese Schleifminen-Variante. Man zeigt,
gilt das bei der Initialisierung, dann zeigt man, gilt das.
Wenn es gerade galt, gilt es auch nach dem nächsten
Durchlauf und dann zeigt man noch, terminiert das irgendwie.
Also Initialisierung, am Anfang sieht das ja so aus hier.
Ja, und dann ist I gleich P-minus 1 und JSP.
Das heißt, bei den ersten beiden Fällen ist nichts zu tun. Hier steht ja,
wenn das K irgendwie zwischen P und I liegt, naja,
und zwischen P und P minus 1 kann es irgendwie nicht liegen.
Und der zweite Fall, dass das K irgendwie
zwischen I plus 1 und J minus 1 liegt,
das kann auch nicht sein in diesem Setting.
Wenn EP minus 1 ist, dann steht hier ein P
und wenn JP steht hier P minus einzeln, kann das auch nicht sein.
Also den ersten, zweiten Bereich gibt es gerade gar nicht.
Also gelten die sofort. Und der dritte ist nach Initialisierung erfüllt.
Also ich gehe ja erst in die Schleife rein, wenn,
jetzt habe ich das Wort Initialisierung ein bisschen viel benutzt.
Ich gehe ja erst in die Schleife rein,
nachdem ich die erste Zeile im Source Code ausgeführt habe.
Und da weiß ich ja, dem X gerade dieses Element
AR hier zu.
Also gilt das auch.
Ja. Okay. Fortsetzung. Jetzt bei der Fortsetzung muss ich
jetzt zwei Fälle unterschreiben, weil ich ja in dem Schleifenrumpf
auch so ein Östern Elst drin habe.
Ist irgendwie das Element kleiner ist, dann tut das,
wenn es größer ist, tu das. Wenn das also,
wenn das AJ größer ist, dann haben wir ja nichts gemacht.
Dann wird der Zen-Teil bei dem FSN nicht ausgeführt,
also wird nur die Schleife erhöht,
wenn also AJ größer ist als X,
dann wird in der Schleife
nur J inkrementiert
Dann bleibt die erste Bedingung gehalten, die dritte auch.
Und nur bei der zweiten kann sich irgendwie was ändern,
weil nur bei der zweiten passiert ja irgendwas mit dem J. Und da muss man gucken,
ob für den neuen Index jetzt,
ob dafür das dann auch gilt,
aber ja, muss ja gelten,
weil AJ soll ja gerade größer sein als X, dann passt das.
Also wenn ich das J um einen erhöhe, dann muss ich gucken,
gilt jetzt weiterhin diese Eigenschaft hier und ja, die gilt.
Hier wurde das J erhöht,
dann gilt das da weiterhin
Und da passiert es, ne. Fünf ist wirklich größer,
das J wird erhöht und jetzt muss ich überprüfen,
gelten weiterhin alle drei Eigenschaften. Die erste gilt weiterhin,
weil nichts passiert ist in diesem blauen Bereich.
Die Rechte gilt weiterhin, weil hier nichts passiert ist.
Und die dritte. Und die zweite gilt eben,
weil ich ja explizit das J hier erhöhe,
weil das da ja größer ist.
Also gilt das auf jeden Fall da. Hast also geben
. Zweitens, wenn AJ kleiner ist als X,
so wie jetzt hier, dann, was passiert jetzt?
Jetzt wird das I imkrementiert. AI und AJ
werden ausgetauscht und dann wird J imkrementiert.
Jetzt muss ich wieder gucken,
gelten wieder
alle drei Eigenschaften
Gelten wieder alle drei Eigenschaften. Und da ich hier ja aber tausche, ich erhöhe I,
ich erhöhe I, ich tausche unter Höhe dein J,
habe ich hier wieder den Fall, dass das wieder kleiner sein muss.
Weil ich hatte ja vorher, ich habe ja getauscht,
weil das Element kleiner ist und dieses Element, was also kleiner ist,
kommt jetzt an die Stelle von dem neuen I,
also muss das hier wieder erfüllt sein für dieses neue I.
Genauso hatte ich hier vorher ein Element,
das größer ist, das ist jetzt an der Stelle,
also gilt auch hier im zweiten Fall für diesen neu hinzugekommenen Index,
dass es da wieder größer ist
Und der dritte bleibt sowieso erfüllt. Bei dem R habe
ich ja nichts gemacht. Ergo gelten beide Fortsetzungen. Frank
? Fragen? Fragen. Terminierung, wenn ich terminiere,
dann ist J gleich R. Und dann weiß ich,
jedes Element, das Aris gehört jetzt zu einer dieser drei Mengen
Und dann wird eben noch das Pivo-Element an seinen richtigen Platz im RRI gesetzt.
Dann sitzt das Pivo-Element hier, dann weiß ich,
dieses Partition tut das, was es tun soll,
nämlich, dass alles links von dem Element kleiner ist,
alles,
was Rechtselement größer ist und dann kann man damit eben relativ schnell die Korrektheit von Quick-Sort-Folge,
weil ich das jetzt rekursiv immer weiter aufrufe und immer das Pivo-Element an die richtige Stelle gesetzt wird und dann bin ich fertig.
Dann habe ich die Korrektheit gezeigt. Also die schleifende Variante
brauche ich um die Korrektheit von Quick-Sort zu zeigen und von Partition
und daraus folgt dann eben die Korrektheit von dem Quick-Sort-Algorithmus.
Genau. Fragen zur Korrektheit
Auf die Schleifen in Variante zu kommen, ist immer,
das ist halt Kreativität. Die fällt jetzt nicht irgendwie,
die kann man nicht ausrechnen oder so. Aber es gibt
halt so mit Erfahrung und man kann sich mal überlegen,
was versuche ich eigentlich zu erreichen mit meinem Algorithmus?
Und die Idee, die da dahinter steckte, war ja,
dass man irgendwie dieses Arry Partitioniert in bestimmte Bereiche.
Dann kann man sich überlegen, ob ich vielleicht das nicht
in einer schleifenden Variante ausdrücken kann.
Und wenn ich das ausdrücken kann in der Schleifenmelde,
dann kann ich die benutzen, um das zu beweisen,
was ich eben ja versuche zu erreichen mit meinem Algorithmus.
Ich will das ja gerade partitionieren. Also kann ich auch
genau versuchen, das zu beweisen
Genau, und bei Merch Sword könnt ihr euch ja mal
überlegen, was man da sinnvoll als Schleifenden-Variante benutzen kann.
Also bei diesem Merchant, dass man da irgendwie auch weiß,
ich habe zwei Eingabe-Aris, ich habe diese beiden Pointer,
ich habe eine Ausgabe-Arry, kann ich mir auch überlegen,
so naja, was gilt denn da irgendwie?
Ich habe gerade genau so viele Elemente in meinem Ausgabe-Arry V,
das hängt jetzt irgendwie von den beiden Pointern ab,
wie weit die halt gelaufen sind und all die Dinger sind
vielleicht richtig sortiert und vielleicht kommt in den Ausgabe,
in den Eingabe-Aris danach nur noch Elemente,
die größer sein können und so.
Sonst kann man irgendwie benutzen. Ja, Laufzeitanalyse
noch von Quickshot hier
Die hängt stark davon ab, ob diese Zerlegung balanciert.
Das habe ich ja vorhin einmal kurz angedeutet. Balanciert ist sie,
wenn die Tie Arris ungefähr die gleiche Größe haben,
so wie in dem Beispiel eben.
Unbalanciert ist sie, wenn die Tie Arris immer,
wenn das eine immer sehr viel größer ist als das andere.
Extrembeispiel, ich gebe euch ein sortiertes Arry und wir wenden da diesen Quicksout-Algorithmus drauf an.
Dann ist das Pivo-Element das erste, das größte.
Also kommt alles, was noch in dem Arry ist,
in meine linke Hälfte und nichts kommt in meine rechte Hälfte.
Das hilft ein bisschen, nicht so in meinen linken Teil,
in meinen rechten Teil.
Dann nehme ich mir als nächstes Pivo-Element wieder das ganz recht,
das ist mein zweitgrößtes Element, alles,
was also noch übrig ist,
ist im linken Teil
So weiter. Also der rote Teil ist immer komplett leer
und der linke Teil ist immer komplett voll.
Und dann brauche ich en rekursive Aufrufe und alle haben die Größe in minus 1,
in minus 2, in minus 3, in minus 4.
Das ist doof. Balanciertheit führt zu ON mal Login,
weil das dann ungefähr so aussieht wie da die Rekurrenzgleichung,
unbalanciertheit führt halt zu O von Endquadrat,
weil die Gleichung dann ist, T von N gleich,
T von N minus 1 plus 10 mal in.
Genau. Im schlechtesten Fall sieht die Rekurrenzgleichung so aus.
Ich glaube, sowas ähnliches haben wir auch schon mal abgewickelt,
das führt dann irgendwie zu diesem O von Endquadrat
Ich kann euch schnell überlegen,
da habt ihr irgendwie N plus N minus 1 plus N
minus 2 plus N minus 3 und so weiter und dann mit
einem kleinen Gaus ist das dann eben endquadratminus in halbe.
Genau. Das ist der Worst Case. Jetzt kann man sich natürlich fragen,
naja, wie oft kommt es in der Anwendung vor,
dass ich ein sortiertes Arry sortieren will?
Im Notfall kann man einmal drüber lesen und gucken,
ob es schon sortiert ist.
Das braucht nur linear viele Schritte. Wenn ich weiß,
es ist schon sortiert, dann mache ich gar nichts.
Und sobald es ein bisschen unsortiert, das reicht es meistens schon,
um die schicke Laufzeit zu kriegen und nicht diese ON-Quadratlaufzeit.
Wenn es gleichmäßig aufteilt, dann sehen wir mit Mastertheorien
sofort,
dass es so ist
Das ist ein Täter in mal Login ist.
Wenn es anders ist, also das Ziel ist ja jetzt
die schönste Abschätzung, die wir uns vorstellen können.
Und für andere Abschätzung bräuchte man eine dorastische Methoden.
Deswegen überspringen wir das jetzt hier. Aber das Ergebnis ist quasi,
es reicht schon, wenn es nur ein bisschen unbalanciert ist.
Also wenn es nicht ganz so schlimm ist,
dass es immer komplett alle Elemente in die eine Hälfte gehen,
in die eine teilen geht,
das reicht schon.
Da steht es nochmal
Genau, wer mag, kann das im Kormen nachlesen.
Aber Stochassi kommt ja hier eigentlich erst so im vierten Semester.
Deswegen fällt das mal aus. Ihr müsst übrigens mal googeln,
wie viele falsch implementierte, was war das? Es gab mal Untersuchungen dazu,
wie oft Merch, Sword, Quick Sword und ich glaube,
wie näheres Suchen oder so, wie oft das falsch sortiert ist.
Es ist unglaublich oft falsch sortiert, also falsch implementiert.
Es gibt unglaublich viele Anwendungen, wo das falsch implementiert ist,
weil man meistens irgendwie, ne,
die eine Grenze klappt nicht oder irgendwie sowas.
Und die Dinger laufen trotzdem in den Anwendungen,
weil die Fehler meistens nur dann auftreten,
wenn ihr sowas habt wie ein zweielementiges Arry zu sortieren oder
dass Ary schon komplett sortiert ist oder irgendwie sowas, so Grenzfälle.
Und dann klappt das immer nicht,
weil dann irgendwas mit den Grenzen da total schief läuft.
Deswegen fällt das dann meistens gar nicht auf,
dass das falsch implementiert ist, so an irgendeiner Stelle.
Aber ich habe irgendwelche Zahlen gelesen,
so 80 Prozent aller Implementierungen davon sind fehlerhaft oder so.
Gruselig. So, Zusammenfassung zu dem Quicksort.
Quicksort sortierten Arry von Zahlen
In dem rekursiv, das Arian 2 kleinere Ähres geteilt wird.
In dem Teil, irgendwie kommen die Kleineren in das andere Teil, kommen die Größeren.
Quicksort sortiert, das ist spannend, Quicksort sortiert Inplace.
Ihr könnt ja mal versuchen, als Herausforderung, Merch Thord Inplace hinzukriegen.
Also bei dem Merch, so wie wir das gemacht haben,
hatten wir ihr ein zusätzliches Ausgabe-Erry für das Merchant.
Man kriegt das auch in-place hin, das ist aber knifflig.
Aber wenn eine Herausforderung sucht, wen das bisher zu langweilig war heute,
der kann mal versuchen, das Inplace hinzukriegen,
könnt ihr mal ein Wochenende dran arbeiten und dann könnt ihr
eventuell einfach mal in die Literatur schauen und so.
Da findet man so einige Papers zu,
das ist
ganz schön knifflig
Worst-Case-Laufzeit von Quicksort in Täter-N-Quadrat, mittlerere Laufzeit in Emma-Login.
Und aber die bessere Grenze tritt sehr viel häufiger auf.
Aber wenn es einem um Worst-Case-Laufzeiten geht,
was man eben üblicherweise zunächst angibt, also wenn ich sage,
ein Algorithmus läuft in Täter von so und so,
dann meine ich zunächst eine Worst-Case-Laufzeit.
Sonst betone ich explizit, dass ich eine mittlere Laufzeit meine.
Ergo Quicksort gehört eigentlich zu den schlechteren Sortierverfahren,
aber weil die mittlere Laufzeit sehr häufig auftritt und weil die
hier versteckte Konstante klein ist, ist er eben doch ein sehr,
sehr schöner Sortieralgorithmus.
Ja, Abschluss.
Was haben wir gemacht
Wir haben diese neue Algorithmentechnik kennengelernt. Idee, wie gesagt,
größere Probleme in kleinere zu zerlegen, mit der gleichen Methode
zu lösen und diese Teilergebnisse dann wieder zur Lösung zusammenzusetzen.
Das war, wie die Weite in Konker so funktioniert,
Teil und Beherrsche, das sind so die drei Ideen.
Wie gesagt, bei Merch Sword ist das Teilen aufwendig beim,
äh Quatsch, das Verbinden beim Quick Sword, das Teilen.
Und wenn ihr jetzt irgendwie ein Problem habt,
wo ihr gucken wollt, ob ihr einen Algorithmus dafür finden könnt,
Dann kann man erst mal versuchen, Brutforce-Algorithmus zu entwickeln.
So vielleicht hilft das. Vielleicht kriegt man da eine ganz gute Idee,
was irgendwie ein Problem sein, also wo Probleme liegen könnten oder nicht.
Und vor allem hat man es dann erst mal gelöst,
oder das ist ja schon mal ganz gut.
Und dann kann man gucken, ist das,
wenn der Bootforce-Algorithmus eine pulliniumielle Laufzeit hat und einem auch irgendwie spontan nichts Cooleres einfällt,
dann ist das, je nachdem, wie viel Erfahrung man hat,
meistens schon so ein Indiz dafür,
dass das Problem vielleicht NPV ständig sein könnte.
Dann kann man schon mal nachgucken. Erstmal ist das überhaupt NPV ständig,
da muss man sich die ganze Arbeit nicht machen, schnelleren Algorithmus zu suchen.
Ich sage mal sehr viel Zeit, aber Genau,
da könnte man sonst aufhören. Wenn man aber so einen Algorithmus hat,
wo man weiß, oh,
Brutforce ist ein Endquadrat oder N-Hoch 3 oder irgendwie sowas,
dann kann man überlegen, kann ich da mit einem Greedy-Verfahren das besser machen?
Wie, die Verfahren machen wir nochmal, das sind so Verfahren,
die gucken sich jedes Element nur einmal an und basteln daraus die Lösung.
Es gibt tatsächlich eine Menge Probleme, die man gut damit lösen kann,
aber man merkt schon so an der Beschreibung eben,
dass das nicht so das cleverste Verfahren sein kann,
so sich jedes Element nur einmal anzugucken oder so.
Und gleich zu wissen, wo das in die Lösung gehört,
so eher unwahrscheinlich so,
dass man das für viele Probleme machen kann
Dann können wir gucken, geht das mit dem Devite in Conquer.
Weil die weit in Conquers ist halt die Idee,
kann ich irgendwie mein Problem zerlegen und Teilprobleme lösen?
Als erstes natürlich, ich meine,
natürlich kann ich mein Problem teilen und Teilprobleme betrachten.
Ich ignoriere einfach die Hälfte oder so. Schön,
aber dann ist halt die Aufgabe, okay,
wie kann ich es dann wieder verbinden?
Oder man kann eben gucken, ob man beim Teilen mehr
Zeit reinsteckt und dass man dann beim Verbinden schneller ist.
Das ist auch so,
wenn ihr versucht mit Devide in Conquer-Verfahren irgendwie ein Problem zu attackieren,
kannst du durchaus eine Menge unterschiedlicher,
die weit in Conquer-Algorithmen geben,
die das gleiche Problem lösen
Eine steckt vielleicht mehr Zeit in das Teilen,
das andere steckt mehr Zeit in das Verbinden und so weiter.
Und eben haben wir das ja quasi auch gesehen,
Merchstored und Quickstored lösen ja beide das gleiche Problem, in Zahlen zu sortieren.
Beides sind die weit in Konka-Verfahren und beide arbeiten aber sehr unterschiedlich. Genau,
und da nochmal, wie man,
also wie diese Rekurrenzgleichung dann mit dem Divide in Konka-Verfahren zusammenhängen,
wenn ich irgendwie A-Teilprobleme habe und alle haben die Größe N durch B,
dann kann ich das da benutzen und FVN ist eben die Zeit,
die ich für Teilen und Zusammenfügen brauche.
Genau, und was wir dann gemacht haben,
wir haben dieses Merch dort kennengelernt und wir haben das Quicksort kennengelernt, zwei ganz klassische Verfahren
Und da drunter steht nochmal so, dass wenn so die Fragen,
die man, wenn man die Vorlesung nachbereitet hat und so,
auf die sollte man eine Antwort haben.
So, was ist das Idee, was die Idee des Verfahrens,
also beim Merchshot, ich teile immer weiter beim Trickshot,
ich partitioniere das Arry in bestimmte Bereiche, abhängig irgendwie von dem Pivo-Element.
Wie ist der ungefähre Ablauf? Die beiden Sachen gehen so ineinander über,
die Idee kann irgendwie vielleicht in einem Satz dargestellt werden,
eine ungefähre Ablauf, da muss ich schon ein bisschen weiter ausholen.
Das ist erstmal so die Beschreibung des Algorithmuses und dann eben,
was ist die Idee beim Korrektheitsbeweis?
Was ist die Idee bei der Laufzeitanalyse? Und Laufzeit einfach zu wissen,
dass es einfach wieder dann Wissen, dass ich weiß,
die Laufzeit ist so und so, aber die anderen vier Sachen,
die haben eben irgendwie was damit zu tun,
dass ich das Verfahren irgendwie verstanden habe und dass ich es
einsortieren kann
Genau, und wie gesagt, für Interessierte als Herausforderung,
wie kann man denn ein In-Place-Merch dort realisieren?
Kann man sich mal angucken, aber das ist eine blaue Box,
das ist jetzt, wenn ihr noch unterfordert seid,
könnt ihr euch das mal angucken. Ja,
und da noch, wenn ich so ein Dividend Conk-Algorithmus entwerfen will,
dann aber die Tipps, die ich eben auch so hatte,
Problem verstehen,
eventuell hilft so ein Bootforce-Algorithmus und dann Aufteilen zusammenfügen,
wie kann ich
das machen
So, ich muss gestehen, ich weiß nicht,
was auf meiner letzten Folie steht.
Ah, der Ausblick, ja, ist klar.
Macht Sinn. Also, nächstes und übernächstes Mal.
Wollen wir uns Datenstrukturen angucken? Erstmal so ganz klassische.
Ich glaube, das kennt ihr alle, oder?
So Q-Stark-Stack-Bäume, also Heeps jetzt nicht unbedingt,
aber so Q-Stacks und Bäume kennt ihr wahrscheinlich alle, ne?
Wer kennt das nicht? Nee, bitte? Ja,
Bäume, ich meine gerade, wer kennt die Scheune und
wer kennt die nicht? Also Q-Stacks und Bäume,
wer das kennt und wer das nicht kennt
Also da gehe ich relativ zügig durch, denke ich.
Und dann werden wir uns auf den Heep und das Heepsword konzentrieren,
dass man einmal sehen kann, oh,
man kann auch irgendwie eine bisher, haben wir immer mit Aris gearbeitet.
Und die Idee bei Heepsword ist eben, sich zu überlegen,
wie kann ich denn eine Datenstruktur entwickeln,
mit der ich dann schnell sortieren kann?
Da fließt quasi die ganze Arbeit in die Entwicklung der Datenstruktur,
damit man dann irgendwie einen schicken Algorithmus haben kann.
Und ziel natürlich irgendwie unterhalb von O von Endquadrat zu bleiben,
sonst brauchen wir die Mühe nicht machen.
Genau, und immer die Frage, kann ich das für
schnelleres Sortieren benutzen
Und wir werden dann halt sehen,
Heep Sword geht auch wieder irgendwie in den O von N
mal Login und dann kann man abschließend sich mal fragen,
ob man irgendwie schneller sortieren kann als beim Earchford.
Also ob man auch irgendwie unter diese N mal Login-Schwelle kommen kann.
Weil wir haben angefangen, haben gesagt,
Blue Force Algorithmus dafür geht in Endquadrat,
dann haben wir gesagt, geht das schneller,
dann sind wir auf angekommen in N mal Login arbeitet.
Jetzt kann man sich als nächstes fragen, geht das noch schneller?
Und ich glaube, nächstes Mal werden wir uns mit den
ersten drei Punkten beschäftigen und übernächstes Mal mit dem Merch Sword.
Quatsch, mit dem schnelleren Sortieren, so.
Fragen. Im ersten zum zweiten dritten. Gut,
dann, ihr habt zu wenig Fragen gestellt. Na gut,
ich muss leider gleich los, das heißt,
wir sind jetzt schon komplett fertig für heute und ja,
nutzt die Zeit in der Mensa und so und wir sehen
uns nächste Woche