Præsentation er lastning. Vent venligst

Præsentation er lastning. Vent venligst

Grundlæggende programmering Forår 2002

Lignende præsentationer


Præsentationer af emnet: "Grundlæggende programmering Forår 2002"— Præsentationens transcript:

1 Grundlæggende programmering Forår 2002
Forelæsning 11 onsdag 24/4 2002 kl. 9:15 – 12:00 GP 11, 24/4 2002

2 Dagens program Søgning og sortering
4-uger projekter II: Søgemaskinprojekter (ca. 11:45) GP 11, 24/4 2002

3 Søgning og sortering Motivation Algoritmer vs. programmer
Anvendelser Hvorfor er et ok kun at 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å tal, kan der være en faktor til forskel mellem en simpel løsning og den bedste løsning. GP 11, 24/4 2002

4 Simpel lineær søgning Hvis vi har følgende tabel:
og ønsker at finde ud af om 45 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: 22 15 44 33 9 72 37 25 53 47 19 45 11 62 39 27 3 59 13 81 50 Dette er gennemsøgt Dette er ikke gennemsøgt 22 15 44 33 9 72 37 25 53 47 19 45 11 62 39 27 3 59 13 81 50 index GP 11, 24/4 2002

5 Bedste, gennemsnits og værste tilfælde
Dette er gennemsøgt Dette er ikke gennemsøgt 22 15 44 33 9 72 37 25 53 47 19 45 11 62 39 27 3 59 13 81 50 index 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. GP 11, 24/4 2002

6 En bedre måde. Hvis tallene stod i rækkefølge .
22 15 44 33 9 72 37 25 53 47 19 45 11 62 39 27 3 59 13 81 50 1 2 4 5 6 7 8 10 12 14 16 17 18 20 21 Så kunne vi starte med at sammeligne 45 med det tal i midten af tabellen (position 11, tallet 37). 45 er større end 37, hvorfor det må være til højre for 37. Vi vælger så det midterste mellem position 11 og 21 = er mindre end 50, og vi vælger så det midterste mellem 11 og 16 = 13 (eller 14, de er lige gode). 45 er større end 44, og vi vælger det midterste mellem 13 og 16, som er 14 (eller 15). Og 45 står netop på plads 14 og vi er færdige. Denne gang sammenlignede vi med 37, 50, 44 og 45. Altså 4 gange. Metoden kaldes binær søgning fordi man bisekterer (deler i 2) tabellen hver gang. Den er god fordi man ved hver sammenligning undgår at lede i den ene halvdel af de resterende elementer. Så der er mange man slet ikke behøver at sammenligne med. GP 11, 24/4 2002 20

7 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 = (5) 16*2 = 32 (20) ...= (6) 32*2 = 64 (23) ... = (større end antal danskere) (7) 64*2 = 128 (30) ... = (8) 128*2= 256 (33) ... = (større end antal mennesker) GP 11, 24/4 2002

8 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: 2k >= n Og det finder man altså ved: k = log2(n) (rundet opad) (hvis 2x = n, så er x = log2(n)) På en lommeregner er der ikke en log2 funktion, men den kan udregnes med en almindelig logaritme (base 10) som: k = lg(n)/lg(2) I vores eksempel var der 21 elementer. lg(21)/lg(2) = Det vil sige at vi i værste tilfælde skal halvere 5 gange, d.v.s. sammenligne med 5 tal, plus 1 sidste sammenligning for at se, om tallet i tabellen er den samme som vi leder efter . GP 11, 24/4 2002

9 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. GP 11, 24/4 2002

10 Udvælgelses sortering
22 15 44 33 9 72 37 25 53 47 19 45 11 62 39 27 3 59 13 81 50 usorteret Find mindste element, og flyt det forrest. 3 15 44 33 9 72 37 25 53 47 19 45 11 62 39 27 22 59 13 81 50 sorteret usorteret Find mindste element i den usorterede, og flyt det forrest i den usorterede del. 3 9 44 33 15 72 37 25 53 47 19 45 11 62 39 27 22 59 13 81 50 sorteret usorteret GP 11, 24/4 2002

11 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) 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 = n2/2 + n. For store n er det lidt ligegyldigt med n, fordi n2 dominerer (er meget større end) de andre termer og man siger derfor at udvælgelses sortering har kvadratisk kompleksitet, som også skrives som O(n2). For n = 1000 giver den rigtige formel , mens den skønsmæssige giver GP 11, 24/4 2002

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

13 En bedre måde: Quicksort
Quicksort er en gennemsnitlig (ikke altid) meget hurtig sorteringsalgoritme, som bruger meget lidt lagerplads (C.A.R. Hoare, 1959). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 15 44 33 9 72 37 25 53 47 19 45 11 62 39 27 3 59 13 81 50 usorteret Vi vælger et tilfældigt element i tabellen – f.eks. det midterste (19), og 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. 3 15 11 9 13 19 37 25 53 47 33 45 44 62 39 27 22 59 72 81 50 <= 19 >= 19 Sorter hver del for sig selv. Dette kan gøres rekursivt. 3 9 11 13 15 19 22 25 27 33 37 39 44 45 47 50 53 59 62 72 81 GP 11, 24/4 2002

14 Quicksort: 2 pegere 15 33 9 72 37 25 53 47 19 45 11 62 39 27 44 3 59 22 13 81 50 1 2 4 5 6 7 8 10 12 14 16 17 18 20 21 swap 1. tal >= pivot 1. tal <= pivot 15 11 9 72 37 25 53 47 19 45 33 62 39 27 44 3 59 22 13 81 50 1 2 4 5 6 7 8 10 12 14 16 17 18 20 21 GP 11, 24/4 2002

15 Opdelingsfasen i quicksort
do { /* pp2 */ while (arr[i] < x) i++; /* pp3 */ while (arr[j] > x) j--; /* pp4 */ if (i <= j) { swap(arr, i, j); i++; j--; } /* pp5 */ } while (i <= j); GP 11, 24/4 2002

16 Quicksort videre 3 15 11 9 13 19 37 25 53 47 33 45 44 62 39 27 22 59 72 81 50 3 9 11 15 13 19 37 25 22 27 33 39 44 62 45 47 53 59 72 81 50 <= 11 >11, <= 19 >19, <= 44 >44 3 9 11 15 13 19 27 25 22 37 33 39 44 50 45 47 53 59 72 81 62 3 9 11 15 13 19 22 25 27 37 33 39 44 45 50 47 53 59 62 81 72 GP 11, 24/4 2002

17 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 log2(n) gange før man står tilbage med enkelt elementer. Dvs. at vi kan dele op log2(n), og hver gang skal vi igennem en opdelingsfase der koster n sammenligninger. I alt n log2(n). Hvis vi har vores Danskere, så bliver det cirka *24 = sammenligninger som med 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. GP 11, 24/4 2002

18 quicksort i gennemsnit
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 log4/3(n) gange. Så hvis vi har vores danskere, så er log4/3( ) = log( )/log(4/3) = 53,6 eller cirka 54 gange. I gennemsnit er quicksort altså cirka halvt så god som i bedste tilfælde. GP 11, 24/4 2002

19 Hele quicksort private static void qsort(int[] arr, int a, int b) {
if (a < b) { int i = a, j = b; int x = arr[(i+j) / 2]; /* pp1 */ do { /* pp2 */ while (arr[i] < x) i++; /* pp3 */ while (arr[j] > x) j--; /* pp4 */ if (i <= j) { swap(arr, i, j); i++; j--; } /* pp5 */ } while (i <= j); /* pp6 */ qsort(arr, a, j); /* pp7 */ qsort(arr, i, b); /* pp8 */ } /* pp9 */ } public static void qsort(int[] arr) { qsort(arr, 0, n-1); private static void swap(int[] arr, int s, int t) { int tmp = arr[s]; arr[s] = arr[t]; arr[t] = tmp; Det er denne metode vi kalder. Den kalder så den rekursive udgave, idet den skal have nogle index som parameter. GP 11, 24/4 2002

20 Gentagelse fra sidste gang: Fletningsbaseret sortering (mergesort)
22 15 44 33 9 72 37 25 53 47 19 45 11 62 39 27 3 59 13 81 50 sorter hver halvdel for sig 9 15 22 25 33 37 44 47 53 72 3 11 13 19 27 39 45 50 59 62 81 flet de to halvdele 3 9 11 13 15 19 22 25 27 33 37 39 44 45 47 50 53 59 62 72 81 GP 11, 24/4 2002

21 Sorter en halvdel, kvarte, ...
22 15 44 33 9 72 37 25 53 47 22 15 44 33 9 sorter hver kvart for sig sorter hver kvart for sig 15 22 9 33 44 9 15 22 33 44 25 37 47 53 72 flet de to kvarte flet de to kvarte 9 15 22 33 44 9 15 22 25 33 37 44 47 53 72 44 33 9 sorter to tal 44 9 33 flet 9 33 44 GP 11, 24/4 2002

22 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). GP 11, 24/4 2002


Download ppt "Grundlæggende programmering Forår 2002"

Lignende præsentationer


Annoncer fra Google