Præsentation er lastning. Vent venligst

Præsentation er lastning. Vent venligst

GP 11, 14/11 20011 Grundlæggende programmering Efterår 2001 Forelæsning 11 onsdag 14/11 2001 kl. 9:15 – 12:00.

Lignende præsentationer


Præsentationer af emnet: "GP 11, 14/11 20011 Grundlæggende programmering Efterår 2001 Forelæsning 11 onsdag 14/11 2001 kl. 9:15 – 12:00."— Præsentationens transcript:

1 GP 11, 14/11 20011 Grundlæggende programmering Efterår 2001 Forelæsning 11 onsdag 14/11 2001 kl. 9:15 – 12:00

2 GP 11, 14/11 20012 Dagens program Søgning og sortering

3 GP 11, 14/11 20013 Søgning og sortering Motivation –Anvendelser –Hvorfor er et ok at kun kikke på heltal? Algoritmer vs. programmer Effektivitet af programmer –måles i forhold til antal elementer der skal søges iblandt, eller som skal sorteres. –Effektivitet af algoritmer: et mål som er relativt til andre algoritmer, og ikke i forhold til antal sekunder i den virkelige verden. –Hvis vi skal søge i en mængde på 1.000.000 tal, kan der være en faktor 25.000 til forskel mellem en simpel løsning og den bedste løsning.

4 GP 11, 14/11 20014 Simpel lineær søgning Hvis vi har følgende tabel: og ønsker at finde ud af om 62 er med, og på hvilken position det så i givet fald er, må man starte i den ene ende og lede. Når vi er et stykke inde i søgningen, kunne situationen beskrives som: 2215443397237255347194511623927359138150 2215443397237255347194511623927359138150 Dette er gennemsøgt Dette er ikke gennemsøgt index

5 GP 11, 14/11 20015 Bedste, gennemsnits og værste tilfælde I gennemsnit skal vi lede halvdelen af tabellen igennem for at finde elementet, og hele tabellen hvis det ikke er med. Hvis tabellen er n elementer stor, så siger vi at vi i værste tilfælde skal foretage n sammenligninger, mens vi i bedste tilfælde skal foretage 1 sammenligning, og i gennemsnit n/2 sammenligninger. 2215443397237255347194511623927359138150 Dette er gennemsøgt Dette er ikke gennemsøgt index

6 GP 11, 14/11 20016 En bedre måde. Hvis tallene stod i rækkefølge. 2215443397237255347194511623927359138150 Så kunne vi starte med at sammeligne 62 med det tal i midten af tabellen (position 11, tallet 33). 62 er større end 37, hvorfor det må være til højre for 37. Vi vælger så det midterste mellem index 11 og 21 = 16. 62 er større end 50, og vi vælger det midterste mellem 16 og 21 = 18. 62 er større end 59, og vi vælger det midterste mellem 18 og 21, som er 19. Og 62 står netop på plads 19. Denne gang brugte sammenlignede vi med 37, 50, 59 og 62. Altså 4 gange. Metoden kaldes binær søgning fordi man bisekterer tabellen hver gang. Den er god fordi man ved hver sammenligning undgår at lede i den ene halvdel af elementerne. Så der er mange man slet ikke behøver at sammenligne med. 12345678910111213141516171819 20 21

7 GP 11, 14/11 20017 Hvor god er binær søgning Hvis vi ved hver sammenligning kan smide halvdelen af elementerne fra, hvor mange gange skal vi så halvere før man kun har et element tilbage? Altså, hvis man har n, hvor mange gange kan man halvere n før man er nede på 1. Man kan sørge omvendt, hvor mange gange skal vi fordoble 1 før vi kommer op på mindst n? (1) 1*2 = 2(9) 256*2=512 (2) 2*2 = 4(10) 512*2=1024 (3) 4*2 = 8(11) 1024*2=2048 (4) 8*2 = 16... (5) 16*2 = 32(20)...= 1.048.576 (6) 32*2 = 64(23)... = 8.388.608 (større end antal danskere) (7) 64*2 = 128(30)... = 1.073.741.824 (8) 128*2= 256(33)... = 8.589.934.592 (større end antal mennesker)

8 GP 11, 14/11 20018 Lidt logaritme gejl Antal gange vi skal sammenligne k i en tabel med n elementer er altså givet ved at være det mindste heltal k sådan at: 2 k >= n Og det finder man altså ved: k = log 2 (n)(sådan er logaritmer defineret!) På en lommeregner er der ikke en log 2 funktion, men den kan udregnes med en almindelig logaritme som: k = log(n)/log(2) I vores eksempel var der 21 elementer. log(21)/log(2) = 4.39232 Det vil sige at vi i værste tilfælde skal halvere 5 gange, d.v.s. sammenligne med 5 tal.

9 GP 11, 14/11 20019 Sortering God søgning kræver at tabellen er sorteret. Derfor er sortering vigtig. Ofte vil man nemlig søge mange gange i samme tabel, og det er derfor vigtigt at kunne søge effektivt.

10 GP 11, 14/11 200110 Udvælgelses sortering 2215443397237255347194511623927359138150 2215443397237255347194511623927359138150 Find mindste element, og flyt det forrest. usorteret sorteret 2215443397237255347194511623927359138150 Find mindste element i den usorterede, og flyt det forrest i den usorterede del. usorteret sorteret

11 GP 11, 14/11 200111 Udvælgelses sortering er håbløs For at sortere n elementer, skal vi i værste tilfælde bruge følgende antal sammenligninger og ombytninger. Første gang skal vi sammenligne med (n-1) elementer, og 1 byt. Anden gang skal vi sammenligne med (n-2) elementer og 1 byt. Tredje gang skal vi sammenligne med (n-3) elementer og 1 byt.... I alt: n+(n-1)+(n-2)+...3+2. Hvis vi stiller det første og sidste led sammen, det andet og andet sidste osv, får vi følgende: (n+2) + ((n-1)+3) + ((n-2)+4)... = (n+2) + (n+2) + (n+2)... ialt n/2 led på formen (n+2). Dvs summen er i alt n(n+2)/2 = n 2 /2 + n. For store n er det lidt ligegyldigt med n, og man siger derfor at udvælgelses sortering er n 2. For n = 1000 giver den rigtige formel 501000, mens den skønsmæssige giver 1000000.

12 GP 11, 14/11 200112 Den er rigtig håbløs Hvis man kan sammenligne 1.000.000 elementer på et sekund, hvor lang tid tager det så at sortere alle danskere efter personnummer? Der er godt 5.000.000 danskere. 5.000.000 2 = 25.000.000.000.000, som divideret med 1.000.000 pr sekund giver 25.000.000 sekunder. Som er cirka 9 måneder og 20 dage.

13 GP 11, 14/11 200113 En bedre måde: Quicksort Dette er en utrolig god ide, som er fundet på af en af de helt store inden for datalogi (C.A.R. Hoare, 1959) 2215443397237255347194511623927359138150 usorteret Vi vælger et tilfældigt element i tabellen – f.eks. det midterste (19), og om ordner tabellen i to dele, en del som indeholder alle tal der er mindre end eller lig 19, og en del er er større end 19. Dette kaldes opdelingsfasen i quicksort. 123456789101112131415161718192021 2215443725534733945116239273597219138150 <= 19>= 19 4425911393337222731915135359817262454750 Sorter hver del for sig selv. Dette kan gøres rekursivt.

14 GP 11, 14/11 200114 Quicksort: 2 pegere 1533972372553471945116239274435922138150 123456789101112131415161718192021

15 GP 11, 14/11 200115 Opdelingsfasen i quicksort 224437255347334539275972816250 pivottal=62 while (lilleIndex <= storIndex) { while (tabel[lilleIndex]<pivotTal) lilleIndex++; while (tabel[storIndex]>pivotTal) storIndex++; if (lilleIndex <= storIndex) { swap(tabel, lilleIndex, storIndex); lilleIndex++; storIndex--; } 1591131913

16 GP 11, 14/11 200116 Quicksort videre 2215443725534733919451162392735972138150 4437252253331591162453947273597219138150 <= 11>11, <= 19>19, <= 44>44 4425223315911393727319135345475972816250 4425331591139372227319135347598172624550

17 GP 11, 14/11 200117 Hvor god/dårlig er quicksort I bedste tilfælde. I hver opdelingsfase løbes tabellen igennem en gang, og hvert element sammenlignes med pivottallet en gang. Hvis vi er mega heldige finder vi et pivottal der opdeler i to lige store dele. Man kan som sagt dele op i halvdele i alt log 2 (n) gange før man står tilbage med enkelt elementer. Dvs. at vi kan dele op log 2 (n), og hver gang skal vi igennem en opdelingsfase der koster n sammenligninger. I alt n log 2 (n). Hvis vi har vores 5.000.000 Danskere, så bliver det cirka 5.000.000*24 = 120.000.000 sammenligninger som med 1.000.000 pr. sekund giver 120 sekunder = 2 minutter. I værste tilfælde Så opdeler vi i del med et element, og en med n-1 elementer = som den dårlige.

18 GP 11, 14/11 200118 Gennemsnits quicksort Quicksort er i gennemsnit ret god. I en tilfældig opdeling vil man dele op i to dele, hvor man deler op i en ¼ og en på ¾ af den oprindelige længde. Hvor mange gange skal man dele en op i ¾ før man når ned på et element? Ja, man kan dele op i ¾ i alt log 4/3 (n) gange. Så hvis vi har vores 5.000.000 danskere, så er log 4/3 (5.000.000) = log(5.000.000)/log(4/3) = 53,6 eller cirka 54 gange. I gennemsnit er quicksort altså cirka halvt så god som i bedste tilfælde.

19 GP 11, 14/11 200119 Hele quicksort public int[] quicksort(int[] tabel){ return quicksort(tabel,0, tabel.length-1); } private int[] quicksort(int[] tabel, int startIndex, int slutIndex){ if (startIndex<slutIndex){ int lilleIndex=startIndex; int storIndex=slutIndex; int pivotTal= tabel[(startIndex+slutIndex)/2]; while (lilleIndex <= storIndex) { while (tabel[lilleIndex]<pivotTal) lilleIndex++; while (tabel[storIndex]>pivotTal) storIndex--; if (lilleIndex <= storIndex) { swap(tabel, lilleIndex, storIndex); lilleIndex++; storIndex--; } quicksort(tabel,startIndex,storIndex); quicksort(tabel,lilleIndex,slutIndex); } return tabel; } private void swap(int[] tabel, int a, int b){int t=tabel[a]; tabel[a]=tabel[b]; tabel[b]=t;} Det er denne metode vi kalder. Den kalder så den rekursive udgave, idet den skal have nogle index som parameter.

20 GP 11, 14/11 200120 Fletningsbaseret sortering (mergesort) 2215443397237255347194511623927359138150 sorter hver halvdel for sig 2215443397237255347194511623927359138150 flet de to halvdele 2215443397237255347194511623927359138150

21 GP 11, 14/11 200121 Sorter en halvdel, kvarte,... 2215443397237255347 sorter hver kvart for sig 7237255347 2215443397237255347 flet de to kvarte 221544339 915223344 221544339 915223344 339 44339 44339 sorter hver kvart for sig flet de to kvarte sorter to tal flet

22 GP 11, 14/11 200122 Divide-and-conquer Grundideen bag mergesort (del-og-hersk, divide-and-conquer): For at sortere en tabel med n tal i, gør følgende: –del tabellen i to halvdele; –sorter begge halvdele hver for sig; –flet de to halvdele sammen som et (“skævt”) lynlås. –(Se efterfølgende – mere om søgning og sortering næste gang).


Download ppt "GP 11, 14/11 20011 Grundlæggende programmering Efterår 2001 Forelæsning 11 onsdag 14/11 2001 kl. 9:15 – 12:00."

Lignende præsentationer


Annoncer fra Google