151
Programmering för språkteknologer II, HT2014 Avancerad programmering för språkteknologer, HT2014 [email protected] Rum 9-2035 http://stp.ling.uu.se/~evelina/uv/uv14/pst2/

Programmering för språkteknologer II, HT2014 …stp.lingfil.uu.se/~evelina/uv/uv14/pst2/F2/2014_sokning_sortering.pdf · Instruktioner som steg för steg beskriver hur man löser

  • Upload
    hadat

  • View
    214

  • Download
    0

Embed Size (px)

Citation preview

Programmering för språkteknologer II, HT2014

Avancerad programmering för språkteknologer, HT2014

[email protected] 9-2035http://stp.ling.uu.se/~evelina/uv/uv14/pst2/

2

Idag

- Sökalgoritmer

- Algoritmanalys

- Sorteringsalgoritmer

3

Sökalgoritmer

4

Sökalgoritmer – Vad är sökning?

- Hitta ett värde i en samling, till exempel i en array

- Returvärden: om värdet finns: det index värdet finns i om värdet inte finns: -1

- Algoritmer: om samling är osorterad: linjär sökning om samling är sorterad: binär sökning

5

Algoritm- och komplexitsteori

Algoritm Instruktioner som steg för steg beskriver hur man löser ett givet problem.

Pseudokod Beskrivning av en algoritm, påminner om kod som innehåller naturligt språk och/eller matematiska formler.

Tidskomplexitet Talar om hur lång tid algoritmen behöver för att lösa problemet

Minneskomplexitet Talar om hur mycket minne algoritmen behöver för för att lösa problemet.

6

Algoritm- och komplexitsteori

Algoritm Instruktioner som steg för steg beskriver hur man löser ett givet problem.

Pseudokod Beskrivning av en algoritm, påminner om kod som innehåller naturligt språk och/eller matematiska formler.

Exempel: linearSearch(array, target) FOR EACH i FROM 0 TO array.length - 1 IF(array[i] = target) THEN RETURN i;

RETURN -1;

7

Översätta pseudokod till JAVA

Exempel: linearSearch(array, target) FOR EACH i FROM 0 TO array.length - 1 IF(array[i] = target) THEN RETURN i;

RETURN -1;

int linearSearch(int array[], int target) {

}

8

Översätta pseudokod till JAVA

Exempel: linearSearch(array, target) FOR EACH i FROM 0 TO array.length - 1 IF(array[i] = target) THEN RETURN i;

RETURN -1;

int linearSearch(int array[], int array) { for(int i = 0; i < array.length; i++) { }

}

9

Översätta pseudokod till JAVA

Exempel: linearSearch(array, target) FOR EACH i FROM 0 TO array.length - 1 IF(array[i] = target) THEN RETURN i;

RETURN -1;

int linearSearch(int array[], int target) { for(int i = 0; i < array.length; i++) { if(array[i]== target) }

}

10

Översätta pseudokod till JAVA

Exempel: linearSearch(array, target) FOR EACH i FROM 0 TO array.length - 1 IF(array[i] = target) THEN RETURN i;

RETURN -1;

int linearSearch(int array[], int target) { for(int i = 0; i < array.length; i++) { if(array[i]== target) return i; }

}

11

Översätta pseudokod till JAVA

Exempel: linearSearch(array, target) FOR EACH i FROM 0 TO array.length - 1 IF(array[i] = target) THEN RETURN i;

RETURN -1;

int linearSearch(int array[], int target) { for(int i = 0; i < array.length; i++) { if(array[i]== target) return i; }

return -1;}

12

Översätta pseudokod till JAVA

Exempel: linearSearch(array, target) FOR EACH i FROM 0 TO array.length - 1 IF(array[i] = target) THEN RETURN i;

RETURN -1;

int linearSearch(int array[], int target) { for(int i = 0; i < array.length; i++) { if(array[i]== target) return i; }

return -1;}

13

Linjär sökning

Huvudidé: Gå igenom samlingen tills man gjort en träff ellersamlingen är slut.

Användning: Används på osorterade samlingar.

14

Linjär sökning

Sök efter siffra 5 i arrayen.

8 4 1 5 7 2 3 6

int linearSearch(int array[], int target) { for(int i = 0; i < array.length; i++) { if(array[i]== target) return i; }

return -1;}

15

Linjär sökning

Sök efter siffra 5 i arrayen.

8 4 1 5 7 2 3 6

int linearSearch(int array[], int target) { for(int i = 0; i < array.length; i++) { if(array[i]== target) return i; }

return -1;}

16

Linjär sökning

Sök efter siffra 5 i arrayen.

8 4 1 5 7 2 3 6

int linearSearch(int array[], int target) { for(int i = 0; i < array.length; i++) { if(array[i]== target) return i; }

return -1;}

17

Linjär sökning

Sök efter siffra 5 i arrayen.

8 4 1 5 7 2 3 6

8 == 5?

int linearSearch(int array[], int target) { for(int i = 0; i < array.length; i++) { if(array[i]== target) return i; }

return -1;}

18

Linjär sökning

Sök efter siffra 5 i arrayen.

8 4 1 5 7 2 3 6

8 == 5? Nej

int linearSearch(int array[], int target) { for(int i = 0; i < array.length; i++) { if(array[i]== target) return i; }

return -1;}

19

Linjär sökning

Sök efter siffra 5 i arrayen.

8 4 1 5 7 2 3 6

int linearSearch(int array[], int target) { for(int i = 0; i < array.length; i++) { if(array[i]== target) return i; }

return -1;}

20

Linjär sökning

Sök efter siffra 5 i arrayen.

8 4 1 5 7 2 3 6

4 == 5?

int linearSearch(int array[], int target) { for(int i = 0; i < array.length; i++) { if(array[i]== target) return i; }

return -1;}

21

Linjär sökning

Sök efter siffra 5 i arrayen.

8 4 1 5 7 2 3 6

4 == 5? Nej

int linearSearch(int array[], int target) { for(int i = 0; i < array.length; i++) { if(array[i]== target) return i; }

return -1;}

22

Linjär sökning

Sök efter siffra 5 i arrayen.

8 4 1 5 7 2 3 6

1 == 5?

int linearSearch(int array[], int target) { for(int i = 0; i < array.length; i++) { if(array[i]== target) return i; }

return -1;}

23

Linjär sökning

Sök efter siffra 5 i arrayen.

8 4 1 5 7 2 3 6

1 == 5? Nej

int linearSearch(int array[], int target) { for(int i = 0; i < array.length; i++) { if(array[i]== target) return i; }

return -1;}

24

Linjär sökning

Sök efter siffra 5 i arrayen.

8 4 1 5 7 2 3 6

5 == 5?

int linearSearch(int array[], int target) { for(int i = 0; i < array.length; i++) { if(array[i]== target) return i; }

return -1;}

25

Linjär sökning

Sök efter siffra 5 i arrayen.

8 4 1 5 7 2 3 6

5 == 5? Ja

int linearSearch(int array[], int target) { for(int i = 0; i < array.length; i++) { if(array[i]== target) return i; }

return -1;}

26

Tidskomplexitet

int linearSearch(int array[], int target) { for(int i = 0; i < array.length; i++) { if(array[i]== target) return i; }

return -1;}

- Varje jämförelse (array[i] == target) kostar 1

27

Tidskomplexitet

int linearSearch(int array[], int target) { for(int i = 0; i < array.length; i++) { if(array[i]== target) return i; }

return -1;}

- Varje jämförelse (array[i] == target) kostar 1

- I värsta fall behöver vi jämföra alla celler i array, dvs array.length = n gånger.

28

Tidskomplexitet – I värsta fall

1 – kostnad för en jämförelse (array[i] == target)

n – arrayens längd (array.length)

Tidskomplexitet i värsta fall:

Kallas för linjär komplexitet.

T=1⋅n≈O (n)

29

Linjär sökning – Tidskomplexitet

Fall Tidskomplexitet Kommentar

I värsta fall: Det sökta värdet finns inte i samlingen

I genomsnitt:

I bästa fall: Det sökta värdet finns i den första platsen I arrayen

O (n)

O (n)

O (1)

30

Binär sökning

31

Exempel:

Sök efter talet 2.

1 2 3 4 5 6 7 8 9

Binär sökning

32

Exempel:

Sök efter talet 2.

1 2 3 4 5 6 7 8 9

Binär sökning

2

5 == 2?

33

Exempel:

Sök efter talet 2.

1 2 3 4 5 6 7 8 9

Binär sökning

2

5 == 2? Nej

34

Exempel:

Sök efter talet 2.

1 2 3 4 5 6 7 8 9

Binär sökning

2

5 == 2? Nej

5 > 2?

35

Exempel:

Sök efter talet 2.

1 2 3 4 5 6 7 8 9

Binär sökning

2

5 == 2? Nej

5 > 2? Ja

36

Exempel:

Sök efter talet 2.

1 2 3 4 5 6 7 8 9

Binär sökning

2

(Array[(0+3+1)/2] =Array[2] = 3) == 2 ?

37

Exempel:

Sök efter talet 2.

1 2 3 4 5 6 7 8 9

Binär sökning

2

(Array[(0+3+1)/2] =Array[2] = 3) == 2 ? Nej

38

Exempel:

Sök efter talet 2.

1 2 3 4 5 6 7 8 9

Binär sökning

2

(Array[(0+3+1)/2] =Array[2] = 3) == 2 ? Nej

3 > 2 ?

39

Exempel:

Sök efter talet 2.

1 2 3 4 5 6 7 8 9

Binär sökning

2

(Array[(0+3+1)/2] =Array[2] = 3) == 2 ? Nej

3 > 2 ? Ja

40

Exempel:

Sök efter talet 2.

1 2 3 4 5 6 7 8 9

Binär sökning

2

(Array[(0+1+1)/2] =Array[1] =2) == 2 ?

41

Exempel:

Sök efter talet 2.

1 2 3 4 5 6 7 8 9

Binär sökning

2

(Array[(0+1+1)/2] =Arra[1] =2) == 2 ? Ja

Returnera index 1

42

Binär sökning

Huvudidé:- Titta på datan i den mittersta cellen. Om den är lika med den data vi letar efter → returnera positionen Om den är större än den data vi letar efter → leta i den vänstra halvan Om den är mindre än den data vi letar efter → leta i den högra halvan

Användning: Används på sorterade samlingar.

43

Binär sökning – Skapa pseudokod

Huvudidé:- Titta på datan i den mittersta cellen. Om den är lika med den data vi letar efter → returnera positionen Om den är större än den data vi letar efter → leta i den vänstra halvan Om den är mindre än den data vi letar efter → leta i den högra halvan Pseudokod:int binarySearch(array, target)

44

Binär sökning – Skapa pseudokod

Huvudidé:- Titta på datan i den mittersta cellen. Om den är större än den data vi letar efter → leta i den vänstra halvan

Om den är mindre än den data vi letar efter → leta i den högra halvan

Om den är lika med den data vi letar efter → returnera positionen Pseudokod:int binarySearch(array, target) low = 0 high = array.length - 1 mid = (low + high + 1) / 2

45

Binär sökning – Skapa pseudokod

Huvudidé: Om den är större än den data vi letar efter → leta i den vänstra halvan

Om den är mindre än den data vi letar efter → leta i den högra halvan

Om den är lika med den data vi letar efter → returnera positionen Pseudokod:int binarySearch(array, target) low = 0 high = array.length - 1 mid = (low + high + 1) / 2 IF array[mid] > target THEN high = mid – 1

46

Binär sökning – Skapa pseudokod

Huvudidé: Om den är mindre än den data vi letar efter → leta i den högra halvan Om den är lika med den data vi letar efter → returnera positionen Pseudokod:int binarySearch(array, target) low = 0 high = array.length - 1 mid = (low + high + 1) / 2 IF array[mid] > target THEN high = mid – 1 IF array[mid] < target THEN low = mid

47

Binär sökning – Skapa pseudokod

Huvudidé: Om den är lika med den data vi letar efter → returnera positionen Pseudokod:int binarySearch(array, target) low = 0 high = array.length mid = (low + high + 1) / 2 IF array[mid] > target THEN high = mid – 1 IF array[mid] < target THEN low = mid IF array[low] = target THEN RETURN low ELSE RETURN -1

48

Binär sökning – Skapa pseudokod

Detta fungerar för ett steg, vi behöver även loopa. Pseudokod:int binarySearch(array, target) low = 0 high = array.length WHILE(high – low > 0) mid = (low + high + 1) / 2 IF array[mid] > target THEN high = mid – 1 IF array[mid] < target THEN low = mid

IF array[low] = target THEN RETURN low ELSE RETURN -1

49

Binär sökning – Skapa pseudokod

Justera IF-satserna Pseudokod:int binarySearch(array, target) low = 0 high = array.length WHILE(high – low > 0) mid = (low + high + 1) / 2 IF array[mid] > target THEN high = mid – 1 ELSE low = mid IF array[low] = target THEN RETURN low ELSE RETURN -1

50

Binär sökning – Översätt till Java Pseudokod:int binarySearch(array, target) low = 0 high = array.length WHILE(high – low > 0) mid = (low + high + 1) / 2 IF array[mid] > target THEN high = mid – 1 ELSE low = mid IF array[low] = target THEN RETURN low ELSE RETURN -1

int binarySearch(int array[], int target)

51

Binär sökning – Översätt till Java Pseudokod:int binarySearch(array, target) low = 0 high = array.length - 1 WHILE (high – low > 0) mid = (low + high + 1) / 2 IF array[mid] > target THEN high = mid – 1 ELSE low = mid IF array[low] = target THEN RETURN low ELSE RETURN -1

int binarySearch(int array[], int target) int low = 0; int high = array.length - 1;

52

Binär sökning – Översätt till Java Pseudokod: WHILE (high – low > 0) mid = (low + high + 1) / 2 IF array[mid] > target THEN high = mid – 1 ELSE low = mid IF array[low] = target THEN RETURN low ELSE RETURN -1

int binarySearch(int array[], int target) { int low = 0; int high = array.length – 1; while (high – low > 0){

}}

53

Binär sökning – Översätt till Java Pseudokod: mid = (low + high + 1) / 2 IF array[mid] > target THEN high = mid – 1 ELSE low = mid IF array[low] = target THEN RETURN low ELSE RETURN -1

int binarySearch(int array[], int target) { int low = 0; int high = array.length – 1; while (high – low > 0){ int mid = (low + hight + 1)/ 2; }}

54

Binär sökning – Översätt till Java Pseudokod: IF array[mid] > target THEN high = mid – 1 ELSE low = mid IF array[low] = target THEN RETURN low ELSE RETURN -1

int binarySearch(int array[], int target) { int low = 0; int high = array.length – 1; while (high – low > 0){ int mid = (low + hight + 1)/ 2; if(array[mid] > target) high = mid–1; else low = mid; }}

55

Binär sökning – Översätt till Java Pseudokod: IF array[low] = target THEN RETURN low ELSE RETURN -1

int binarySearch(int array[], int target) { int low = 0; int high = array.length – 1; while (high – low > 0){ int mid = (low + hight + 1)/ 2; if(array[mid] > target) high = mid–1; else low = mid; }

if(array[low] = target) return low; else return -1; }

56

Binär sökning – koden i Java int binarySearch(int array[], int target) { int low = 0; int high = array.length – 1; while (high – low > 0){ int mid = (low + hight + 1)/ 2; if(array[mid] > target) high = mid–1; else low = mid; }

if(array[low] = target) return low; else return -1; }

57

Binär sökning – Rekursiv variant Pseudokoden innan loopen:int binarySearch(array, target) low = 0 high = array.length mid = (low + high + 1) / 2 IF array[mid] > target THEN high = mid – 1 IF array[mid] <= target THEN low = mid IF array[low] = target THEN RETURN low ELSE RETURN -1

58

Binär sökning – Rekursiv variant Börja med att hitta basfallet, dvs när lösningen är enkel och vi kan därför stanna.

Pseudokod:int binarySearch(array, target) low = 0 high = array.length mid = (low + high + 1) / 2 IF array[mid] > target THEN high = mid – 1 IF array[mid] <= target THEN low = mid // BASFALL IF array[low] = target THEN RETURN low ELSE RETURN -1

59

Binär sökning – Rekursiv variant Leta efter rekursionsstegen, dvs vad gör vi om vi inte är i basfallet.

Pseudokod:int binarySearch(array, target, low, high) low = 0 high = array.length mid = (low + high + 1) / 2 //REKURSIONSSTEG IF array[mid] > target THEN binarySearch(array, target, low, mid -1) IF array[mid] <= target THEN low = mid // BASFALL IF array[low] = target THEN RETURN low ELSE RETURN -1

60

Binär sökning – Rekursiv variant Leta efter rekursionsstegen, dvs vad gör vi om vi inte är i basfallet.

Pseudokod:int binarySearch(array, target, low, high) low = 0 high = array.length mid = (low + high + 1) / 2 //REKURSIONSSTEG IF array[mid] > target THEN binarySearch(array, target, low, mid -1)

//REKURSIONSSTEG IF array[mid] <= target THEN binarySearch(array, target, mid, high) // BASFALL IF array[low] = target THEN RETURN low ELSE RETURN -1

61

Binär sökning – Rekursiv variant Städa pseudokoden.

Pseudokod:int binarySearch(array, target, low, high) //REKURSIONSSTEG IF array[mid] > target THEN binarySearch(array, target, low, mid -1) //REKURSIONSSTEG IF array[mid] <= target THEN binarySearch(array, target, mid, high)

// BASFALL IF array[low] = target THEN RETURN low ELSE RETURN -1

62

Binär sökning – Rekursiv variant Lägg till if-sats så vi vet när vi ska använda basfall och rekursionssteg.Pseudokod:int binarySearch(array, target, low, high) IF (high – low > 0) THEN mid = (low + high +1) / 2 //REKURSIONSSTEG IF array[mid] > target THEN binarySearch(array, target, low, mid -1) //REKURSIONSSTEG IF array[mid] <= target THEN binarySearch(array, target, mid, high) ELSE // BASFALL IF array[low] = target THEN RETURN low ELSE RETURN -1

63

Binär sökning – Rekursiv variant Förfina if-satserna i pseudokoden.Pseudokod:int binarySearch(array, target, low, high) IF (high – low > 0) THEN mid = (low + high +1) / 2 //REKURSIONSSTEG IF array[mid] > target THEN binarySearch(array, target, low, mid -1) //REKURSIONSSTEG ELSE binarySearch(array, target, mid, high) ELSE // BASFALL IF array[low] = target THEN RETURN low ELSE RETURN -1

64

Rekursion

Metoden anropar anropar sig själv tills man kommitner till basfallet.

Skapas på följande sätt:- Basfall: – enkelt problem som kan lösas trivialt och resultatet returneras

- Rekursionssteget (kan finnas flera): – Metoden anropar sig själv med ett mindre problem.

65

Binär sökning – Översätt till Java Pseudokod:int binarySearch(array, target, low, high) IF (high – low > 0) THEN mid = (low + high +1) / 2 //REKURSIONSSTEG IF array[mid] > target THEN binarySearch(array, target, low, mid -1) //REKURSIONSSTEG ELSE binarySearch(array, target, mid, high) ELSE // BASFALL IF array[low] = target THEN RETURN low ELSE RETURN -1

int binSearch(int array[],int target, int low, int high)

66

Binär sökning – Översätt till Java Pseudokod: IF (high – low > 0) THEN mid = (low + high +1) / 2 //REKURSIONSSTEG IF array[mid] > target THEN binarySearch(array, target, low, mid -1) //REKURSIONSSTEG ELSE binarySearch(array, target, mid, high) ELSE // BASFALL IF array[low] = target THEN RETURN low ELSE RETURN -1

int binSearch(int array[],int target,int low, int high) if (high – low > 0) {}

67

Binär sökning – Översätt till Java Pseudokod: mid = (low + high +1) / 2 //REKURSIONSSTEG IF array[mid] > target THEN binarySearch(array, target, low, mid -1) //REKURSIONSSTEG ELSE binarySearch(array, target, mid, high) ELSE // BASFALL IF array[low] = target THEN RETURN low ELSE RETURN -1

int binSearch(int array[],int target,int low, int high) if (high – low > 0) { int mid = (low + high + 1)/2; }

68

Binär sökning – Översätt till Java Pseudokod: //REKURSIONSSTEG IF array[mid] > target THEN binarySearch(array, target, low, mid -1) //REKURSIONSSTEG ELSE binarySearch(array, target, mid, high) ELSE // BASFALL IF array[low] = target THEN RETURN low ELSE RETURN -1

int binSearch(int array[],int target,int low, int high) if (high – low > 0) { int mid = (low + high + 1)/2; if (array[mid] > target) binSearch(array, target, low, mid-1) }

69

Binär sökning – Översätt till Java Pseudokod: //REKURSIONSSTEG ELSE binarySearch(array, target, mid, high) ELSE // BASFALL IF array[low] = target THEN RETURN low ELSE RETURN -1

int binSearch(int array[],int target,int low, int high){ if (high – low > 0) { int mid = (low + high + 1)/2; if (array[mid] > target) binSearch(array, target, low, mid-1) else binSearch(array, target, mid, high) }}

70

Binär sökning – Översätt till Java Pseudokod: ELSE // BASFALL IF array[low] = target THEN RETURN low ELSE RETURN -1

int binSearch(int array[],int target,int low, int high){ if (high – low > 0) { int mid = (low + high + 1)/2; if (array[mid] > target) binSearch(array, target, low, mid-1) else binSearch(array, target, mid, high) } else {}}

71

Binär sökning – Översätt till Java Pseudokod: // BASFALL IF array[low] = target THEN RETURN low ELSE RETURN -1

int binSearch(int array[],int target,int low, int high){ if (high – low > 0) { int mid = (low + high + 1)/2; if (array[mid] > target) binSearch(array, target, low, mid-1) else binSearch(array, target, mid, high) } else { if (array[low] == target) return low; else return -1; }}

72

Binär sökning – rekursiv version i Java

int binSearch(int array[],int target,int low, int high){ if (high – low > 0) { int mid = (low + high + 1)/2; if (array[mid] > target) binSearch(array, target, low, mid-1) else binSearch(array, target, mid, high) } else { if (array[low] == target) return low; else return -1; }}

73

Binärsökning – Tidskomplexitet

int binSearch(int array[],int target,int low, int high){ if (high – low > 0) { int mid = (low + high + 1)/2; if (array[mid] > target) binSearch(array, target, low, mid-1) else binSearch(array, target, mid, high) } else { if (array[low] == target) return low; else return -1; }}

- Varje jämförelse kostar 1: - high - low > 0 - array[mid] > target - array[low] == target

74

Binärsökning – Tidskomplexitet

int binSearch(int array, int target, int low, int high){ if (high – low > 0) { int mid = (low + high + 1)/2; if (array[mid] > target) binSearch(array, target, low, mid-1) else binSearch(array, target, mid, high) } else { if (array[low] == target) return low; else return -1; }}

Hur många jämförelser gör algoritmen?

75

Binärsökning – Tidskomplexitet

Hur många jämförelser gör algoritmen?

Datamängden halveras i varje iteration:

1 2 3 4 5 6 7 8 9

1 2 3 4 5 6 7 8 9

1 2 3 4 5 6 7 8 9

1 2 3 4 5 6 7 8 9

76

Binärsökning – Tidskomplexitet

Hur många jämförelser gör algoritmen?

Datamängden halveras i varje iteration:

1 2 3 4 5 6 7 8 9

1 2 3 4 5 6 7 8 9

1 2 3 4 5 6 7 8 9

1 2 3 4 5 6 7 8 9 1=202=21

4=22

9=23+1

77

Binärsökning – Tidskomplexitet

Hur många jämförelser gör algoritmen?

Datamängden halveras i varje iteration:

1 2 3 4 5 6 7 8 9

1 2 3 4 5 6 7 8 9

1 2 3 4 5 6 7 8 9

1 2 3 4 5 6 7 8 9 1=202=21

4=22

9=23+1

Talet 2 kommer från att samlingen halveras

78

Binärsökning – Tidskomplexitet

Hur många jämförelser gör algoritmen?

Datamängden halveras i varje iteration:

1 2 3 4 5 6 7 8 9

1 2 3 4 5 6 7 8 9

1 2 3 4 5 6 7 8 9

1 2 3 4 5 6 7 8 9 1=202=21

4=22

9=23+1

Antalet halveringar

79

Binärsökning – Tidskomplexitet

Hur många jämförelser gör algoritmen?

I vårt exempel behövde vi göra 3 halveringar och varjejämförelse gjordes max 3 gånger.

I det allmänna fallet gör vi m jämförelser och vi kan därför skriva:

Tidskomplexiteten blir:

Men kan vi mäta tidskomplexiteten på antalet element i samlingen istället?

2m=n

T=O (2m)

80

Binärsökning – Tidskomplexitet

Hur många jämförelser gör algoritmen?

I vårt exempel behövde vi göra 3 halveringar och varjejämförelse gjordes max 3 gånger.

I det allmänna fallet gör vi m jämförelser och vi kan därför skriva:

Tidskomplexiteten blir:

Men kan vi mäta tidskomplexiteten på antalet element i samlingen istället?

Ja, det kan vi.

2m=n

T=O (2m)

81

Binärsökning – Tidskomplexitet

Så här kan vi räkna:

2m=n⇔

log(2m)=log(n)⇔

m⋅log (2)=log(n)⇔

m=log (n)log (2)

m=log2(n)

82

Binärsökning – Tidskomplexitet

Tidskomplexiteten blir nu så här:

Tidskomplexiteten kallas för logaritmisk komplexitet.

T=O (m)=O (log2(n))≈O (log n)

83

Binärsökning – Tidskomplexitet

I värsta fall:

I genomsnitt:

I bästa fall:

O (log n)

O (log n)

O (1)

84

Jämförelse mellan linjär och binär sökning

Linjär Binär

Kan användas Alltid Endast på sorterade samlingar

För länkad lista Ja Nej

Tid(Värsta) n log(n)

implementering Mycket lätt Lite svårare

85

Sökning – Andra alternativ

- Både linjär och binär sökning fungerar bra för arrayer

- Sökningen kan underlättas genom att använda andra datastrukturer:

– Binära sökträd - Ett alternativ till array

– Hashtabeller: --- Det går snabbt att slå upp vilket värdet som är kopplad till respektive nyckel

86

Algoritmer vs datastrukturer

Algoritm: - Instruktioner som steg för steg beskriver hur man löser ett givet problem.

Datastruktur: - Ordnad data så att datorn kan bearbeta datan på ett effektivt sätt Exempel: Länkad lista, Träd, Hashtabell, Array

Datastrukturen påverkar vilken algoritm som är lämplig att använda.

87

Algoritmanalys

Korrekthet Ger algoritmen alltid ett korrekt resultat

Lösning Får vi någon lösning eller fastnar algoritmen någonstans, till exempel i en loop?

Algoritmkomplexitet – Tidskomplexitet: Talar om hur lång tid en algoritm behöver för att lösa problemet

– Minneskomplexitet: Talar om hur mycket minne algoritmen behöver för att lösa problemet

88

Tidskomplexitet

- Hur kan man avgöra vilken algoritm är snabbast på att lösa ett givet problem?

89

Tidskomplexitet

- Hur kan man avgöra vilken algoritm är snabbast på att lösa ett givet problem?

- Mäta den tid det tar för en dator att exekvera algoritmen?

90

Tidskomplexitet

- Hur kan man avgöra vilken algoritm är snabbast på att lösa ett givet problem?

- Mäta den tid det tar för en dator att exekvera algoritmen? Problem: Man blir beroende av samma hårdvara om man vill jämföra olika algoritmer

91

Tidskomplexitet

- Hur kan man avgöra vilken algoritm är snabbast på att lösa ett givet problem?

- Mäta den tid det tar för en dator att exekvera algoritmen? Problem: Man blir beroende av samma hårdvara om man vill jämföra olika algoritmer

- Lösning: Använd asymptotisk analys istället. → Då blir analysen långsiktig

92

Asymptotisk analys

- Matematisk analys över hur lång tid en algoritm behöver när storleken på indatan växer.

Exempel på storlekar: Sträng : antal tecken Array : antal celler Allmänna fallet: antal byte

- Tre olika fall: – I värsta fall : Den längsta tiden som behövs – I genomsnitt fall: Den tid som behövs i genomsnitt – I bästa fall : Den minsta tiden som behövs

93

Asymptotisk analys

- Grundkrav: Algoritm behöver för indata av godtycklig storlek(n)

94

Asymptotisk analys

- Grundkrav: Algoritm behöver för indata av godtycklig storlek(n)

- Analys ska vara maskinoberoende -- Hastigheten ökar med en konstant om maskin är kraftfull

95

Asymptotisk analys

- Grundkrav: Algoritm behöver för indata av godtycklig storlek(n)

- Analys ska vara maskinoberoende -- Hastigheten ökar med en konstant om maskin är kraftfull

- Exekveringstiden beräknas som en funktion av indatans storlek T(n)

96

Asymptotisk analys

- Grundkrav: Algoritm behöver för indata av godtycklig storlek(n)

- Analys ska vara maskinoberoende -- Hastigheten ökar med en konstant om maskin är kraftfull

- Exekveringstiden beräknas som en funktion av indatans storlek T(n)

- Konstanta faktorer ignoreras

97

Asymptotisk analys

- Grundkrav: Algoritm behöver för indata av godtycklig storlek(n)

- Analys ska vara maskinoberoende -- Hastigheten ökar med en konstant om maskin är kraftfull

- Exekveringstiden beräknas som en funktion av indatans storlek T(n)

- Konstanta faktorer ignoreras

- Man fokuserar på dominerande faktorer

98

Asymptotisk analys

En algoritm komplexitet analyseras med hjälp av matematik i följande steg givet algoritmens pseudokod:

0. Räkna primitiva operationer och låt varje operation kosta 1: – aritmetiska operationer (+,-,*,/) – jämförelser (==, !=,<=,...) – referera till en variabel/objekt – indexera i en array – tilldelning – anropa en metod – returnera från en metod

1. Ställ upp ett uttryck T(n) för antalet primitiva operationer som

behövs relativt storleken på indatan (n) i bästa, värsta eller i genomsnitt.

2. Förenkla uttrycket T(n)

3. Hitta en funktion som begränsar T(n) uppifrån.

99

Asymptotisk analys – Exempel

0. Räkna primitiva operationer och låt varje operation kosta 1:

sumArray(array) sum = 0 FOR EACH i FROM 0 TO array.length - 1 sum = sum + array[i] RETURN sum;

(1+1)⋅n(1+1+1)⋅n

1

1

100

Asymptotisk analys - Exempel

1. Ställ upp ett uttryck T(n) för antalet primitiva operationer som

behövs relativt storleken på indatan (n) i bästa, värsta eller i genomsnitt.

2. Förenkla uttrycket T(n)

sumArray(array) sum = 0 FOR EACH i FROM 0 TO array.length - 1 sum = sum + array[i] RETURN sum;

1+(1+1)⋅n(1+1+1)⋅n

1

1

T (n)=5⋅n+3

101

Asymptotisk analys – Ordo (big-O)

- Övre gräns (upper bound) för hur tiden för en algoritm växer

Definition:

Givet funktionerna och säger vi att

Där och är positiva konstanter

T (n)⩽c⋅g (n)

n⩾n0

T (n)∈O (g (n))

T (n) g (n)

n0,c

102

Asymptotisk analys – Ordo (big-O)

- Övre gräns (upper bound) för hur tiden för en algoritm växer

Definition:

Givet funktionerna och säger vi att

Där och är positiva konstanter

T (n)⩽c⋅g (n)

n⩾n0

T (n)∈O (g (n))

T (n) g (n)

n0,c

Notera: är en mängd av funktioner som har den egenskap definitionen beskriver.

O (g (n))

103

Asymptotisk analys - Exempel

3. Hitta en funktion som begränsar T(n) uppifrån.

Det är uppenbart att det finns flera funktioner som begränsar T(n) men vi ska hitta den minsta.

Antag; g(n)=n

T (n)=5⋅n+3

5⋅n+3⩽cn (c−5)⋅n⩾3 n⩾ 3c−5

104

Asymptotisk analys - Exempel

3. Hitta en funktion som begränsar T(n) uppifrån.

Det är uppenbart att det finns flera funktioner som begränsar T(n) men vi ska hitta den minsta.

Antag; g(n)=n

Låt och för

T (n)=5⋅n+3

5⋅n+3⩽cn (c−5)⋅n⩾3 n⩾ 3c−5

c=6 n0=3

n⩾3⇒5n+3⩽6n

⇒T (n)∈O (n)

105

Tidskomplexitet – Linjär sökning

- Tidskomplexiteten för de olika fallen: – I värsta fallet:

– I bästa fallet: Om det tar konstant tid så används 1

– I genomsnitt: Antag att i genomsnitt tar algoritmen

Då är en konstant vi kan bortse ifrån och resultet blir

därför:

O (n)

O (1)

O (n)

T ( n2)=T (n⋅1

2)

12

106

Tidskomplexitet – Binär sökning

- Tidskomplexiteten för de olika fallen: – I värsta fallet:

– I bästa fallet: Om det tar konstant tid så används 1

– I genomsnitt:

O (log n)

O (1)

O (log n)

107

Tidskomplexitet – Beräkning

Vid beräkning av komplexitet bortser man ifrån termer av lägre ordning och konstanter:

Exempel:

T (5+n)∈O(n)T (5+10n)∈O(n)T (5000+10000n)∈O(n)

108

Tidskomplexitet – Beräkning

Vid beräkning av komplexitet bortser man ifrån termer av lägre ordning och konstanter:

Exempel:

T (5+n)∈O(n)T (5+10n)∈O(n)T (5000+10000n)∈O(n)

T (n2+n)∈O(n2)

T (15n2+58n)∈O(n2)

T (n+log n)∈O (n)T (25n log n+800)∈O(n log n)

109

Tidskomplexitet - Ordoklasser

Ordo Benämning

konstant

logaritmisk

linjär

kvadratisk

kubisk

polynomisk (för x > 1)

Exponentiell (för c > 1)

faktoriell

O (1)O (log n)O (n)O (n log n)O (n2)O (n3)O (nx)O (cn)O (n !)

110

Tidskomplexitet – asymtotisk storlek spelar roll

111

Tidskomplexitet – asymtotisk storlek spelar roll trots konstanter

112

Ordo( ) , Theta(Θ) och Omega (Ω)

- övre gräns(upper bound)

Θ - Θ och Ω

Ω - undre gräns(lower bound)

O

O

T (n)∈ (n)⇔T∈O (n) T (n)∈ (n)

113

Asymptotisk analys - diskussion

- Bra verktyg för att jämföra algoritmer

- stor indata → En algoritm med högre komplexitet är alltid långsammare

- liten indata → En algoritm med högre komplexitet kan vara Snabbare

Exempel:Om vi söker i en kort array så kan linjär sökning varasnabbare eftersom vi inte behöver beräkna medelvärden

114

Asymptotisk analys - diskussion

- Bra verktyg för att jämföra algoritmer

- stor indata → En algoritm med högre komplexitet är alltid långsammare

- liten indata → En algoritm med högre komplexitet kan vara Snabbare

Exempel:Om vi söker i en kort array så kan linjär sökning varasnabbare eftersom vi inte behöver beräkna medelvärden

Vi kan använda samma resonemang när vi diskuterarminneskomplexitet

115

Asymptotisk analys – Vad ska ni kunna?

- Utföra grundläggande resonemang angående tidskomplexiteten för en algoritm/program för den övre gränsen i olika fall (Ordo)

– Detta gäller speciellt med avseende på följande som tas upp i kursen: –- sök- och sorteringsalgoritmer –- vanliga operationer för datastrukturer

- Givet enkel kod så ska ni kunna resonera er fram till dess Tidskomplexitet

(Se exemplet med att summera innehållet I en array)

116

Sorteringsalgoritmer

117

Sorteringsalgoritmer – Vad är sortering?

- Objekten i en samling placeras i en viss ordning

- Vi kommer framförallt att arbeta med arrayer

- De viktigaste operationerna som används vid sortering är:

– jämföra två värden: compare(), ==, <, >, etc

– swap(i,j) – Byt plats på objekten vid indexarna i och j

118

Sorteringsalgoritmer – Algoritmer

- Enkla algoritmer som är mindre effektiva – Urvalssortering (Selection sort) – Bubbelsortering (Bubble sort) – Instickssortering (Insertion sort)

- Avancerade algoritmer som är mer effektiva – Merge sort – Quick sort – Shell sort

119

Urvalssortering – Algoritm

0. Dela upp arrayen i en sorterad del (tom från början) och en osorterad del (hela arrayen från början)

sorterad del osorterad del

4 5 2 1

120

Urvalssortering – Algoritm

0. Dela upp arrayen i en sorterad del (tom från början) och en osorterad del (hela arrayen från början)

sorterad del osorterad del

1. Leta efter det minsta element I den osorterade delen

sorterad del osorterad del

4 5 2 1

4 5 2 1

121

Urvalssortering – Algoritm

0. Dela upp arrayen i en sorterad del (tom från början) och en osorterad del (hela arrayen från början)

sorterad del osorterad del

1. Leta efter det minsta element i den osorterade delen

sorterad del osorterad del

2. Placera det sist i den sorterade delen

sorterad del osorterad del

4 5 2 1

4 5 2 1

1 5 2 4

122

Urvalssortering – Algoritm

3. Upprepa steg 1 och 2 tills hela arrayen är sorterad

sorterad del osorterad del

sorterad del osorterad del

sorterad del osorterad del

sorterad del osorterad del

1 5 2 4

1 2 5 4

1 2 4 5

1 2 4 5

123

Urvalssortering – Kod void selectionSort(int[] array) { for(int i = 0; i < array.length-1; i++){ int minIndex = i; for(int j = i+1; i < array.length; j++){ if(array[i] < array[minIndex]) { minIndex = j; } } swap(array,i,j); }}

void swap(int[] array, int x, int y){ int temp = array[x]; array[x] = array[y]; array[y] = temp;}

124

Urvalssortering – Tidskomplexitet void selectionSort(int[] array) { for(int i = 0; i < array.length-1; i++){ int minIndex = i; for(int j = i+1; i < array.length; j++){ if(array[i] < array[minIndex]) { minIndex = j; } } swap(array,i,j); }}

125

Urvalssortering – Tidskomplexitet void selectionSort(int[] array) { for(int i = 0; i < array.length-1; i++){ //n-1 int minIndex = i; for(int j = i+1; i < array.length; j++){ if(array[i] < array[minIndex]) { minIndex = j; } } swap(array,i,j); }}

126

Urvalssortering – Tidskomplexitet void selectionSort(int[] array) { for(int i = 0; i < array.length-1; i++){ //n-1 int minIndex = i; for(int j = i+1; i < array.length; j++){ // n-1+n-2+...+2+1 if(array[i] < array[minIndex]) { minIndex = j; } } swap(array,i,j); }}

127

Urvalssortering – Tidskomplexitet void selectionSort(int[] array) { for(int i = 0; i < array.length-1; i++){ //n-1 int minIndex = i; for(int j = i+1; i < array.length; j++){ // n-1+n-2+...+2+1 if(array[i] < array[minIndex]) { // konstant minIndex = j; } } swap(array,i,j); }}

128

Urvalssortering – Tidskomplexitet void selectionSort(int[] array) { for(int i = 0; i < array.length-1; i++){ //n-1 int minIndex = i; for(int j = i+1; i < array.length; j++){ // n-1+n-2+...+2+1 if(array[i] < array[minIndex]) { // konstant minIndex = j; // konstant } } swap(array,i,j); }}

129

Urvalssortering – Tidskomplexitet void selectionSort(int[] array) { for(int i = 0; i < array.length-1; i++){ //n-1 int minIndex = i; for(int j = i+1; i < array.length; j++){ // n-1+n-2+...+2+1 if(array[i] < array[minIndex]) { // konstant minIndex = j; // konstant } } swap(array,i,j); // konstant }}

130

Urvalssortering – Tidskomplexitet void selectionSort(int[] array) { for(int i = 0; i < array.length-1; i++){ //n-1 int minIndex = i; for(int j = i+1; i < array.length; j++){ // n-1+n-2+...+2+1 if(array[i] < array[minIndex]) { // konstant minIndex = j; // konstant } } swap(array,i,j); // konstant }}

= {Triangeltal} = =

=

Komplexiteten kallas för kvadratisk komplexitet.

(n−1)+2+1(n−1)2+n−1

2

n2−2n+1+n−12

n2−n2

∈O(n2)

131

Instickssortering – Algoritm

0. Dela upp arrayen i en sorterad del (tom från början) och en osorterad del (hela arrayen från början)

sorterad del osorterad del

4 5 2 1

132

Instickssortering – Algoritm

0. Dela upp arrayen i en sorterad del (tom från början) och en osorterad del (hela arrayen från början)

sorterad del osorterad del

4 5 2 1

1. Det första värdet i den osorterade delen flyttas till rätt plats i den sorterade delen.

sorterad del osorterad del

2. Upprepa tills hela arrayen är sorterad.

sorterad del osorterad del

4 5 2 1

4 5 2 1

133

Instickssortering – Algoritm

2. Upprepa tills hela arrayen är sorterad.

sorterad del osorterad del

sorterad del osorterad del

sorterad del osorterad del

4 5 2 1

2 4 5 1

1 2 4 5

134

Bubbelsortering – Algoritm

0. Dela upp arrayen i en sorterad del (tom från början) och en osorterad del (hela arrayen från början)

sorterad del osorterad del

4 5 2 1

135

Bubbelsortering – Algoritm

0. Dela upp arrayen i en sorterad del (tom från början) och en osorterad del (hela arrayen från början)

sorterad del osorterad del

4 5 2 1

1. Utför följande för varje par av värden från höger till vänster: – Byt plats om värdet till vänster är större än värdet till höger

4 5 2 1

4 5 1 2

4 1 5 2

136

Bubbelsortering – Algoritm

1. Utför följande för varje par av värden från höger till vänster: – Byt plats om värdet till vänster är större än värdet till höger

4 5 2 1

4 5 1 2

4 1 5 2

1 4 5 2

137

Bubbelsortering – Algoritm

1. Utför följande för varje par av värden från höger till vänster: – Byt plats om värdet till vänster är större än värdet till höger

2. Det minsta värdet bubblas upp till den sorterade arrayen och kan flyttas över till den

3. Upprepa tills arrayen är sorterad

1 4 5 2

138

Bubbelsortering – Algoritm

3. Upprepa tills arrayen är sorterad

1 4 5 2

1 4 2 5

1 2 4 5

1 2 4 5

139

Bubbelsortering – Algoritm

3. Upprepa tills arrayen är sorterad

1 2 4 5

1 2 4 5

140

Instickssortering och Bubbelsortering

Komplexitet:

Använd samma strategi som för urvalssortering

O (n2)

141

Sorteringsalgoritmer - Egenskaper

- Minneskomplexitet: Hur mycket minne behöver den?

De sorteringsalgoritmer vi tittat på hittills behöver:

Arrayen behöver:

Extraminne för swap:

O (n)

O (1)

142

Sorteringsalgoritmer - Egenskaper

- Stabilitet: Bevaras den relativa ordningen på element av samma nycklar?

Exempel: Antag att vi vill sortera följande tuplar enligt de vänstra siffrorna: (4,2); (1,6); (1,5); (2,8)

Om resultatet blir (1,6); (1,5); (2,8); (4,2) så är algoritmen stabil

Om resultatet blir (1,5); (1,6); (2,8); (4,2) så är algoritmen instabil

Det sorteringsalgoritmer vi tittat på hittills är stabila.

143

Sorteringsalgoritmer - Egenskaper

- Tidskomplexitet: Hur lång tid behöver algoritmen?

Det algoritmer vi tittat på har tidskomplexiteten

O (n2)

144

Avancerade sorteringsalgoritmer - Egenskaper

- Tidskomplexitet: som också är den gränsen för hur snabbt man kan sortera - Stabililitet: Olika

- Minneskomplexitet: Kan vara högre

O (n log n)

145

Avancerade sorteringsalgoritmer

146

Avancerade sorteringsalgoritmer

Namn Tidskomplexitet Stabil? MinnesåtgångMerge sort Ja Kan behöva mer

minne

Quick sort I medelfallet:

I värsta fallet:

Ja Kan behöva mer minne

Shell sort Svåranalyserad

I värsta fallet:

Nej Inget extra minne

O (n log n)

O (n log n)

O (n2)

O (n3 /2)

147

Ordnade klasser

Om en klass implementerar gränssnittet ComparableTo<T>får klassen en naturlig ordning.

Klassen behöver implementera metodenint compareTo(T t) som ska returnera följande: - 0 om t och objektet är lika - >0 om t är större än objektet - <0 om t är mindre än objektet

148

Lab 2, del 1

Sortering av heltal i ett grafi skt labskal

– Implementera två sorteringslagoritmer själva: Kandidat: insertion och shell sort Master : insertion och merge sort

– Jämför olika sorteringsalgoritmer under olika förutsättningar

– Koppla till teorin

149

Lab 2, del 1

Labskalet begränsat för att kunna synkronisera algoritmerna

- Tillhandahåller följande metoder: – cmp(i,j) – jämför värdena på plats i och j i arrayen (jfr compareTo) – swap(i,j) – byter plats på värdena på plats j och i

– elementCount() – hur många element fi nns det i arrayen (jfr length/size())

150

Mer om sorteringsalgoritmer

- Vi har bara gått igenom kod för en sorteringsalgoritm idag

- Ni ska kunna följande: – Beskriva alla de algoritmer som vi gått igenom

– Kunna visa hur de fungerar genom ett exempel för en array

– Kunna skriva (pseudo)kod för dem

– I labben får ni skriva egen kod för två algoritmer

– Labben innehåller även given kod för andra algoritmer –- studera den

– Läs i kursböckerna om sorteringsalgoritmer

– Även (engelska) Wikipedia har bra material om sortering

151

I veckan

Onsdag: - Deadline för lab 1! - Onsdag: -- Generiska algoritmer och klasser (behövs för lab 2, del 2) -- Länkade listor mm (behövs för lab 3) -- Mer om komplexitet

- Lab:-- Jobba själv innan onsdag-- Sätt igång med del1 i lab2– Läs på om sökning, sortering, komplexitet– Komplexitet: grundläggande Eck 8.5, mer avancerat Shaffer 3.1–3.7