• Sonuç bulunamadı

Veri Yapıları. Algoritma Karmaşıklığı Analizi. İTÜ, BLG221 Veri Yapıları

N/A
N/A
Protected

Academic year: 2022

Share "Veri Yapıları. Algoritma Karmaşıklığı Analizi. İTÜ, BLG221 Veri Yapıları"

Copied!
47
0
0

Yükleniyor.... (view fulltext now)

Tam metin

(1)

Algoritma Karmaşıklığı Analizi

Veri Yapıları

İTÜ, BLG221 Veri Yapıları

(2)

Veri Yapıları ve Algoritma Analizi

• Veri Yapıları:

– Verinin bellekte en etkin nasıl depolanacağı, erişileceği ve yönetileceği konularını inceler.

– Hangi veri yapısının kullanılacağı, bir algoritmanın performansını etkiler.

• Algoritma Analizi:

– Bir algoritmanın performansını tahmin eder.

– Bir problem için farklı algoritmaların nasıl karşılaştırılacağı konularını inceler.

2

(3)

Algoritma Performansı

• Performans değerlendirme metrikleri:

– Gerekli bellek alanı – Çalışma süresi

• Çalışma süresi en çok kullanılan standartdır.

– Ölçülebilir ve karşılaştırması kolay

– Genellikle performans, girdi sayısının bir fonksiyonudur:

• Örnek: Veri elemanı sayısı

3

(4)

Çalışma Süresi Karmaşıklığının Ölçülmesi

• Genellikle çalışma süresi tahmini, tam olarak zaman birimi cinsinden yapılmaz.

(örn. Bir algoritmanın toplam kaç mili saniyede tamamlanacağı)

• Bunun yerine, bir algoritmanın hızının problemin girdi sayısına göre değişimi tahmin edilir.

(örn. İşlem sayısı).

• Problemin boyutuna (N) bağlı olan bir f(N) fonksiyonu

tanımlanır, bu fonksiyon algoritmanın çalışma süresi ile doğru orantılıdır.

4

(5)

• Aşağıdaki üç algoritmanın (pseudo code) her biri için, toplam işlem sayılarını, N’in bir fonksiyonu olarak hesaplayalım.

Örnek : T(N) hesaplanması

(6)

• Toplam işlem sayılarının grafikleri:

B Algoritması, çalışma süresi açısından en fazla zamanı harcar.

Algoritma T(N) O( f(N) )

A 2N+1 O(N)

B N2+N+1 O(N2)

C 4 O(1)

•T(N) algoritma Çalışma Süresi’dir.

•O(f(N)) ise, Asimptotik Algoritma Karmaşıklığıdır.

(7)

• Aşağıdaki C fonksiyonu için toplam işlem sayısını hesaplayalım.

Örnek : C kodunundan T(N) hesaplanması

float Avg(int A[], int N) {

float ort, tot=0;

int i;

for (i=0; i < N; i++) tot = tot + A[i];

if (N > 0)

ort = (float)tot/N;

return ort;

} 1

2 3 4 5 6

Satır İşlem Maliyet Tekrarlar

1 tot=0 1 1

2 i=0 1 1

2 i < N 1 N+1

2 i++ 1 N

3 tot = tot + A[i] 1 N

4 N > 0 1 1

5 (float) tot 1 1

5 … / N 1 1

6 return ort 1 1

Toplam T(N) = 3N+7

(8)

Algoritma Karmaşıklığı:

Büyük-O Notasyonu

• Bir algoritmanın karmaşıklığı (Asimptotik Karmaşıklık) genellikle, bir fonksiyonun icrası için gerekli işlem

sayısının çarpanlarından oluşan terimler halinde ifade edilir.

– Büyük O harfi ile gösterilir (Order of )

– Parantez içinde ise problem boyutu N’a bağlı bir ifade yazılır.

• Büyük-O bir algoritmanın nümerik olarak kaç mili saniye süreceğini göstermez.

– Girdi sayısı (N)’ e bağlı olarak değişim oranını gösterir.

(9)

T(N) ve O(f(N)) Örnekleri

Çalışma süresi T(N)

Asimptotik Karmaşıklık O(f(N))

4 N log N O(N log N)

7N2 log N + 5N2 + N O(N2 log N) 10 N3 + N2 + 40N + 800 O(N3)

2N + 1000N O(2N)

9

(10)

Analiz Kuralları

• Aşağıdaki işlemler sabit çalışma süresine sahiptir O(1):

– Aritmetik (topla, çıkar, çarp, vb.) – Veri hareketi (oku, yaz, ata)

– Kontrol (dallanma, alt program çağrısı, return)

• Döngüler sabit olmayan çalışma süresine sahiptir, O(N), O(N2), vb.

– Döngü sayısı ile, döngü içindeki işlemlerin toplam çalışma süresi çarpılır.

• Ardışık komutlar

– Ardışık olarak birçok komut varsa, çalışma süresi en yüksek maliyete sahip olan komutlar O()’yu belirler.

(11)

Sadeleştirme Kuralları

• Mümkünse sadece bir terime indirgeyin.

– En hızlı büyüyen terim, toplam çalışma süresini belirleyicidir.

– N sayısı arttıkça, asimptotik sonuç tamamen derecesi en büyük olan terim tarafından belirlenir.

• Sabit katsayılar atılır.

O(aNk + bNk-1 + … + yN + z) ≈ O(Nk) O(N) + O (N) = 2 O(N) ≈ O(N) O(N) + O (M) ≈ O(N) Eğer N > M

O(N) * O (N) = O(N2)

O(N) + O (logN) ≈ O(N) Çünkü O(N) > O(logN)

O(N) * O (logN) ≈ O(N logN)

11

(12)

Matematik İfadeler (1)

• Üsler

XA XB = XA+B XA / XB = XA-B (XA)B = XAB

XN+XN = 2XN 2N+2N = 2N+1

• Logaritmalar

Tanım: XA = B ise logX B = A log AB = log A + log B

log A/B = log A – log B log (AB) = B log A

(13)

Matematik İfadeler(2)

• Seriler

1 2

2

1

0

N N i

i

2 2

) 1

(

2

1

N N

i N

N

i

 

 

1

1

1

0

N

a a a

N i

i

3 6

) 1 2

)(

1

(

3

1

2

N N N N

i

N

i

 

 

13

(14)

Karmaşıklık Sıralaması

Sabit O(1)

Logaritmik O(log N) Doğrusal O(N)

Kare O(N2)

Küp O(N3)

Polinom O(Na)

Üslü O(aN)

Faktoriyel O(N!)

• Bir algoritma aşağıdaki kategorilerden birine girebilir.

Hızlıdan yavaşa

doğru sıralı.

(15)

1 10 100 1000 10000 100000

n

n2

n log n

n

log n n3

2n

Karmaşıklık Sıralaması

Çalışma süresi (saniye)

Girdi boyutu (N)

15

(16)

Çalışma süresi örnekleri

N Sabit

O(1)

Logaritmik O(logN)

Doğrusal O(N)

Kare O(N2)

1000 10 ns 100 ns 10 μs 10 ms

1 milyon 10 ns 200 ns 10 ms 3 saat

1 milyar 10 ns 300 ns 10 sec 300 yıl

1 saniye = 103 mili san = 106 mikro san = 109 nano san

(17)

Bazı Veri Yapısı İşlemlerinin Algoritma Karmaşıklığı

Ekleme Silme Arama

Sırasız dizi O(1) O(n) O(n)

Sıralı dizi O(log2n + n) O(log2n+ n) O(log2n) Bağlantılı

Liste O(n) O(n) O(n)

İkili Arama

Ağacı O(log2n) O(log2n) O(log2n)

17

(18)

Örnek1: Tek döngü

for (i = 1; i <= N; i++) {

myfunc( );

}

N

i

N

1

1

Karmaşıklık O(N)

• myfunc() fonksiyonu kaç defa çağrılır?

(19)

Örnek2: Tek döngü

for (i = 1; i <= N; i *= 2) {

myfunc( );

}

N

i

N

,..

16 , 8 , 4 , 2 , 1

log

2

1

Karmaşıklık O(log2N)

19

(20)

Örnek3: İç içe iki döngü

for (i = 1; i <= N; i++) {

for (j = 1; j <= M; j++) {

myfunc( );

} }

  

N

i

N

i M

j

NM M

1 1 1

1

Karmaşıklık O(NM) ≈ O(N2)

(21)

Örnek4: İç içe iki döngü

for (i = 1; i <= N; i++) {

for (j = 1; j <= i; j++) {

myfunc( );

} }

  

 

N

i

N

i i

j

N N N

i

1 1 1

2

) 1 ... (

3 2

1 1

Karmaşıklık O(N2/2 + N/2) ≈ O(N2)

21

(22)

Örnek5: İç içe üç döngü

for (i = 1; i <= N; i++) {

for (j = 1; j <= M; j++) {

for (k = 1; k <= L; k++) { myfunc( );

} }

}

   

N

i

N

i N

i

M

j M

j

L

k

NML L

M L

1 1 1 1 1 1

1

Karmaşıklık O(NML) ≈ O(N3)

(23)

Örnek6: Ard arda iki döngü

for (i = 1; i <= N; i++) {

myfunc( );

}

for (i = 1; i <= N; i *= 2) {

myfunc( );

}

N

log

2

N

Karmaşıklık O(N + log2N) ≈ O(N)

23

(24)

Örnek7: Ard arda ve iç içe döngüler

for (i = 1; i <= N; i++) {

for (j = 1; j <= i; j++) {

myfunc( );

} }

for (i = 1; i <= N; i++) {

for (j = 1; j <= M; j++) {

myfunc( );

} }

N(N + 1)/2

NM

Karmaşıklık O(N2/2 + N/2) + O(N2) ≈ 2 O(N2) ≈ O(N2)

(25)

Örnek8: İç içe iki döngü

for (i = 1; i <= N; i++) {

for (j = 1; j <= M; j *= 2) {

myfunc( );

} }

  

N

i

N

i M

j

M N

M

1

2 1

2 ,...

4 , 2 , 1

log log

1

Karmaşıklık O(N log2M) ≈ N O(logN)

log

2

N N

25

(26)

Örnek9: İç içe iki döngü

for (i = 1; i <= N * N; i++) {

for (j = 1; j <= N * N * N; j++) {

myfunc( );

} }

  

2 3 2

1

5 1

3 2

3 1

1

N

i

N

i N

j

N N

N N

Karmaşıklık O(N5)

N

3

N

2

(27)

Örnek10: Faktoriyel

// Rekürsif çözüm int factorial (int n) {

if (n<=1) return 1;

else

return n * factorial(n-1);

}

Her ikisi için karmaşıklık O(N) // İteratif çözüm

int factorial(int n) {

int i, fact;

if (n<=1) return 1;

else {

fact = 1;

for (i=2;i<=n;i++) fact *= i;

return fact;

}

27 }

(28)

Rekürsif Faktoriyel

factorial (n)

n * factorial(n-1)

n-1 * factorial(n-2)

n-2 * factorial(n-3)

… …

2 *factorial(1)

(29)

Rekürsif Faktoriyel

• T(n) rekürsif olarak T(k) cinsinden tanımlanır, k < n

• Rekürsiyon, T(n)’nin temel durumlara (T(0) veya T(1)) biriktirilmesini sağlar.

• T(n) = T(n-1) + d

= T(n-2) + d + d

= T(n-3) + d + d + d = . . .

= T(1) + (n-1)*d = c + (n-1)*d

= c + nd - d ≈ O(n)

29

(30)

Örnek11: Rekürsif bölme

void divide(int N) {

if (N <= 2) return;

divide(N / 2);

}

T(0) = T(1) = T(2) = 1 T(n) = 1 + T(n/2) if n > 2 T(n) = 1 + (1 + T(n/4))

= 2 + T(n/4)

= 2 + (1 + T(n/8))

= 3 + T(n/8)

= 3 + (1 + T(n/16))

= 4 + T(n/16)

≈ O(log2 n) Karmaşıklık O(logN)

(31)

• Amaç: N adet diski A kulesinden C kulesine taşımak.

• Kurallar:

Bir defada tek bir disk taşınır

Büyük bir disk, küçük bir diskin üzerine gelemez

• Rekürsif çözüm:

 N - 1 diski A’dan B’ye taşı

A’daki en büyük diski (tek) C’ye taşı

 N - 1 diski B’den C’ye taşı

• Toplam hareket sayısı:

 O(2N)

Örnek12: Hanoi Kuleleri

31

(32)

Rekürsif

çözüm

(33)

Rekürsif Hanoi Kuleleri

void hanoi(int N, char source, char target, char tmp) {

if (N == 1)

printf("Move disk from %c to %c \n", source, target);

else {

hanoi(N-1, source, tmp, target);

printf("Move disk from %c to %c \n", source, target);

hanoi(N-1, tmp, target, source);

} }

int main() {

move(4, 'A', 'B', 'C');

return 0;

} Karmaşıklık O(2N)

33

(34)

Hanoi(n,A,B,C)

Hanoi(n-1,A,C,B) Hanoi(n-1,C,B,A)

Hanoi(n-2,A,B,C) Hanoi(n-2,B,C,A) Hanoi(n-2,C,A,B) Hanoi(n-2,A,B,C)

Rekürsif Hanoi Kuleleri

T(N) = 2 * T(N-1)

= 2 * (2 * T(N-2) )

= 2 * (2 * (2 * T(N-3) )) = . . .

= 2N-1 * T(1) ≈ O(2N)

34

(35)

Rekürsif Hanoi Kuleleri

• Rekürsiyon bağıntısı:

T(n) = 2 T(n - 1) + 1 T(1) = 1

• Bağıntıyı açarak çözüm:

T(n) = 2 (2 T(n - 2) + 1) + 1 = = 4 T(n - 2) + 2 + 1 =

= 4 (2 T(n - 3) + 1) + 2 + 1 = = 8 T(n - 3) + 4 + 2 + 1 = ...

= 2i T(n - i) + 2i-1 +2i-2 +...+21 +20

• i = n – 1 olduğunda açılım sonlanır.

T(n) = 2n – 1 + 2n – 2 + 2n – 3 + ... + 21 + 20

• Sonuç geometrik toplamdır.

– T(N) = 2N - 1 = O(2N) – Bu algoritma üslüdür.

35

(36)

Örnek13: Dizi sıralama

/* Sort an array in ascending order */

void BubbleSort(int a[ ], int N) { int pass, i, hold;

/* loop to control number of passes */

for ( pass = 1; pass < N; pass++ ) {

/* loop to control number of comparisons per pass */

for ( i = 0; i < N - 1; i++ ) {

/* compare adjacent elements and swap them if first element is greater than second element */

if ( a[ i ] > a[ i + 1 ] ) { hold = a[ i ];

a[ i ] = a[ i + 1 ];

a[ i + 1 ] = hold;

} /* end if */

} /* end inner for */

} /* end outer for */

}

40 10 90 30 20 60

Başlangıç

10 20 30 40 60 90

Sıralı dizi

Karmaşıklık O(N2)

(37)

Dizi sıralama

• En iyi durum: Sıralama öncesi elemanlar zaten sıralı ise.

Çalışma süresi doğrusaldır. O(N)

• En kötü durum: Sıralama öncesi tüm elemanlar tamamen ters sıralı ise.

Çalışma süresi kareseldir. O(N2)

• Ortalama durum: Sıralama öncesi elemanlar kısmen sıralı, kısmen sırasız iseise.

Çalışma süresi kareseldir. O(N2/2) ≈ O(N2)

37

(38)

Program çalışma süresinin C’de ölçülmesi

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

int main() {

clock_t baslama;

double sure, i;

baslama = clock(); // Capture the start time

for (i=1; i <= 1E5; i++)

printf("Sayac = %g \r", i);

sure = (clock() - baslama) / (double) CLOCKS_PER_SEC;

printf(“Geçen süre : %g saniye \n", sure);

system(“pause");

return 0;

(39)

Örnek14: Dizide İkili Arama

• İkili arama

– Sadece sıralı bir dizide uygulanabilir.

– Bu nedenle, dizi arama işlemi öncesinde sıralı hale getirilmelidir.

– Ortadaki elemanı arama anahtarı ile karşılaştır

• Eşitseler, aranan bulundu

• Eğer key < middle ise, dizinin ilk yarısında aramaya devam et.

• Eğer key > middle ise, dizinin ikinci yarısında aramaya devam et.

• Yeni middle’ı hesapla ve üstteki adımları tekrarla.

– Çok hızlı; en fazla x adımda çözüm bulunur. ( 2x > Eleman sayısı )

• Örnek: 30 elemanlı dizide arama işlemi en fazla 5 adımda biter.

( 25 > 30 )

Karmaşıklık O(log2N)

39

(40)

İkili Arama örneği:

Aranan hedef = 22

2 4 5 7 8 9 12 14 17 19 22 25 27 28 33 37

2 4 5 7 8 9 12 14 17 19 22 25 27 28 33 37

2 4 5 7 8 9 12 14 17 19 22 25 27 28 33 37

2 4 5 7 8 9 12 14 17 19 22 25 27 28 33 37

low mid high

low mid high

low mid high

low=mid=high Hedef bulundu!

40

(41)

1 /* Fig. 6.19: fig06_19.c

2 Binary search of an array */

3 #include <stdio.h>

4 #define SIZE 15 5

6 /* function prototypes */

7 int binarySearch( const int b[ ], int searchKey, int low, int high );

8 void printHeader( void );

9 void printRow( const int b[ ], int low, int mid, int high );

10

11 /* function main begins program execution */

12 int main() 13 {

14 int a[ SIZE ]; /* create array a */

15 int i; /* counter */

16 int key; /* value to locate in array a */

17 int result; /* variable to hold location of key or -1 */

18

19 /* create data */

20 for ( i = 0; i < SIZE; i++ ) { 21 a[ i ] = 2 * i;

22 } /* end for */

23

24 printf( "Enter a number between 0 and 28: " );

25 scanf( "%d", &key );

26

Örnek: Dizide ikili arama

41

(42)

fig06_19.c (Part 2 of 5)

27 printHeader();

28

29 /* search for key in array a */

30 result = binarySearch( a, key, 0, SIZE - 1 );

31

32 /* display results */

33 if ( result != -1 ) {

34 printf( "\n%d found in array element %d\n", key, result );

35 } /* end if */

36 else {

37 printf( "\n%d not found\n", key );

38 } /* end else */

39

40 return 0; /* indicates successful termination */

41

42 } /* end main */

43

44 /* function to perform binary search of an array */

45 int binarySearch( const int b[ ], int searchKey, int low, int high ) 46 {

47 int middle; /* variable to hold middle element of array */

48

(43)

49 /* loop until low subscript is greater than high subscript */

50 while ( low <= high ) { 51

52 /* determine middle element of subarray being searched */

53 middle = ( low + high ) / 2;

54

55 /* display subarray used in this loop iteration */

56 printRow( b, low, middle, high );

57

58 /* if searchKey matched middle element, return middle */

59 if ( searchKey == b[ middle ] ) { 60 return middle;

61 } /* end if */

62

63 /* if searchKey less than middle element, set new high */

64 else if ( searchKey < b[ middle ] ) {

65 high = middle - 1; /* search low end of array */

66 } /* end else if */

67

68 /* if searchKey greater than middle element, set new low */

69 else {

70 low = middle + 1; /* search high end of array */

71 } /* end else */

72

73 } /* end while */

74

43

(44)

fig06_19.c (Part 4 of 5)

75 return -1; /* searchKey not found */

76

77 } /* end function binarySearch */

78

79 /* Print a header for the output */

80 void printHeader( void ) 81 {

82 int i; /* counter */

83

84 printf( "\nSubscripts:\n" );

85

86 /* output column head */

87 for ( i = 0; i < SIZE; i++ ) { 88 printf( "%3d ", i );

89 } /* end for */

90

91 printf( "\n" ); /* start new line of output */

92

93 /* output line of - characters */

94 for ( i = 1; i <= 4 * SIZE; i++ ) { 95 printf( "-" );

96 } /* end for */

97

98 printf( "\n" ); /* start new line of output */

99 } /* end function printHeader */

100

(45)

fig06_19.c (Part 5 of 5)

101 /* Print one row of output showing the current 102 part of the array being processed. */

103 void printRow( const int b[ ], int low, int mid, int high ) 104 {

105 int i; /* counter */

106

107 /* loop through entire array */

108 for ( i = 0; i < SIZE; i++ ) { 109

110 /* display spaces if outside current subarray range */

111 if ( i < low || i > high ) { 112 printf( " " );

113 } /* end if */

114 else if ( i == mid ) { /* display middle element */

115 printf( "%3d*", b[ i ] ); /* mark middle value */

116 } /* end else if */

117 else { /* display other elements in subarray */

118 printf( "%3d ", b[ i ] );

119 } /* end else */

120

121 } /* end for */

122

123 printf( "\n" ); /* start new line of output */

124 } /* end function printRow */

45

(46)

Enter a number between 0 and 28: 25

Subscripts:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 --- 0 2 4 6 8 10 12 14* 16 18 20 22 24 26 28 16 18 20 22* 24 26 28 24 26* 28 24*

25 not found

Enter a number between 0 and 28: 8

Subscripts:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 --- 0 2 4 6 8 10 12 14* 16 18 20 22 24 26 28 0 2 4 6* 8 10 12

8 10* 12 8*

8 found in array element 4

Program çıktısı

(47)

SLAYTLARIN

SONU

Referanslar

Benzer Belgeler

– Dışarıdan girilen numara veya ad soyad bilgisine göre arama – Dışarıdan girilen numara veya ad soyad bilgisine göre bilgi değiştirme – Tüm öğrencilerin istenen bir

Çeş itli veri türlerine sahip değ iş kenleri yapı ile kontrol etme Yapı sal veri tanı mlanabilen bir dilde iş aretçi oluş turma Kayı t yapı sı nda bir değ iş ken tanı

Algoritma Akış Diyagramı Programlama Araçları, Değişkenler ve Sabit Giriş- Çıkış İşlemleri, Operatörler Karar Yapıları Döngü Kontrolleri Tek Boyutlu Diziler Çok

ì Algoritma; belli bir problemi çözmek veya belirli bir amaca ulaşmak için tasarlanan adımlar kümesidir3.

• Algoritma analizi, bir yazılım/programı çalıştırmadan, ne kadar sürede çalışacağını ve alternatif algoritmalara göre nasıl daha hızlı, daha yavaş, yakın hızlı,

diyagramlarının gösterimi için Bachman notasyonu, kavramsal veri modelleri ve veri tabanlarında Crow's Foot Spec dili gibi farklı yöntemler kullanılmaktadır.. Ayrıca,

 Kuyruk başı işaretçisi her zaman dizinin ilk elemanı olsun.  Yeni eleman eklemek için son işaretçisi bir arttırılır.  Eleman çıkarılırken ise hep ilk eleman

Programlama dilleri, donanıma ve kullanıcıya yakınlık durumuna göre düşük seviye diller ve yüksek seviye diller olarak iki sınıfta incelenir.. è Bir programlama dili aynı