2 Haziran 2016 Perşembe

Algoritma Nedir ?Algoritma Türleri Nelerdir ?

Algoritma, belli bir problemi çözmek veya belirli bir amaca ulaşmak için tasarlanan yol. Matematikte ve bilgisayar biliminde bir işi yapmak için tanımlanan, bir başlangıç durumundan başladığında, açıkça belirlenmiş bir son durumunda sonlanan, sonlu işlemler kümesidir. Genellikle bilgisayar programlamada kullanılır ve tüm programlama dillerinin temeli algoritmaya dayanır. Aynı zamanda algoritma tek bir problemi çözecek davranışın, temel işleri yapan komutların veya deyimlerin adım adım ortaya konulmasıdır ve bu adımların sıralamasına dikkat edilmelidir. Bir problem çözülürken algoritmik ve sezgisel (herustic) olmak üzere iki yaklaşım vardır. Algoritmik yaklaşımda da çözüm için olası yöntemlerden en uygun olan seçilir ve yapılması gerekenler adım adım ortaya konulur. Algoritmayı belirtmek için ; metinsel olarak düz ifade ve akış diyagramı olmak üzere 2 yöntem kullanılır. Algoritmalar bir programlama dili vasıtasıyla bilgisayarlar tarafından işletilebilirler.



Algoritma Örnek;

 A0 --> Başla
 A1 --> Sayaç=0 (Sayaç'ın ilk sayısı 0 olarak başlar.)
 A2 --> Sayı=? : T=T+Sayı (Sayıyı giriniz. T'ye sayıyı ekle ve T'yi göster.)
 A3 --> Sayaç=Sayaç+1 (Sayaç'a 1 ekle ve sayacı göster.)
 A4 --> Sayaç<4 ise A2'ye git. (Eğer sayaç 4'ten küçükse Adım 2'ye git.)
 A5 --> O=T/4 (Ortalama için T değerini 4'e böl)
 A6 --> O'yu göster. (Ortalamayı göster.)
 A7 --> Dur

Algoritma Türleri Nelerdir ?

  • Arama algoritmaları
  • Bellek yönetimi algoritmaları
  • Bilgisayar grafiği algoritmaları
  • Birleşimsel algoritmalar
  • Çizge algoritmaları
  • Evrimsel algoritmalar
  • Genetik algoritmalar
  • Kripto algoritmaları veya kriptografik algoritmalar
  • Kök bulma algoritmaları
  • Optimizasyon algoritmaları
  • Sıralama algoritmaları
  • Veri sıkıştırma algoritmaları






Karmaşıklık Giriş

Neden Algoritmayı Analiz Ederiz ?

- Algoritmanın Performansını Ölçmek için
- Farklı Algoritmalarla Karşılaştırmak için
- Daha iyisi mümkün mü ?

Özelliklerinin Analizi

- Algoritmanın Çalışma Zamanı
- Hafızada Kapladığı Alan


Bir algoritmanın performansı iç ve dış faktörlere bağlıdır

İç Faktörler

- Çalıştırmak için gereken zaman
-Çalıştırmak için gereken yer (bellek)

Dış Faktörler

-Girdi verisinin büyüklüğü
-Bilgisayarın Hızı
-Derleyici Kalitesi






















Büyüme Hızı ve Büyük-O(big-O)notasyonu

  1. Büyüme hız bir algoritmanın performansını yansıtan en iyi göstergedir.
  2. Büyük-O notasyonu büyüme hızını gösterir. Bir algoritmanın performansını en iyi tanımlayan matematiksel bir formüldür ve algoritmanın iç detaylarına bakılarak elde edilir.
  3. Büyük-O girdi verisinin büyüklüğünü gösteren bir N parametresine dayanan bir fonksiyondur.
  4. Örneğin n değerine bağlı olarak performansı (sabit a, b, c değerleri için) an2 + bn + c olan bir algoritmanın performansı O(N2)’dir
  5. N değeri arttıkça N2 terimi baskın olacağı için büyük-O notasyonunda sadece baskın olan terim kullanılır

 

O Notasyonu- Asimtotik Üst Limit 

Bir algoritmanın çalışma süresi
   T(N)=O(f(n))

  • T(N)  c f(n)  ve N  n0 koşullarını sağlayan c ve n0 değerleri varsa T(N)  c f(n)  ifadesi doğrudur.
  • f(n), T(N)’in asimtotik üst limiti olarak adlandırılır.
  • T(N)=O(f(n))

    O Notasyonu

     O notasyonunda yazarken en basit şekilde yazarız.
    Örneğin
    3n2+2n+5 = O(n2)
    Aşağıdaki gösterimlerde doğrudur fakat kullanılmaz.
    3n2+2n+5 = O(3n2+2n+5)
    3n2+2n+5 = O(n2+n)
    3n2+2n+5 = O(3n2)

    Bir programın asıl çalışma zamanını hesaplama (örnek)
    Bir işlem için harcanan zaman 10ms olsun(bir veri üzerinde yapılan tek bir işlem)
    1000 veriyi işlemek için programın ne kadar çalışması gerekir? Programın çalışma zamanı aşağıdaki gibi verilmişse bu değer nasıl hesaplanır?
    log10 N
    N
    N log10 N
    N2
    N3

    (1 veri için zaman) x (N veri için verilen büyük-O( ) zaman karmaşıklığı)






     


Büyük -O Nasıl Hesaplanır ?

Bir program kodunun zaman karmaşıklığını hesaplamak için 5 kural

1    Döngüler
2    İç içe Döngüler
3    Ardışık deyimler
4    If-then-else deyimleri
5    Logaritmik karmaşıklık






KURAL 1: DÖNGÜLER




Bir döngünün çalışma zamanı en çok döngü içindeki deyimlerin çalışma zamanının iterasyon sayısıyla çarpılması kadardır.



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

{

     m = m + 2;

}
Toplam zaman = sabit c * n = cn = O(N)

KURAL 2: İÇ İÇE DÖNGÜLER 

İçteki analiz yapılır. Toplam zaman bütün döngülerin çalışma sayılarının çarpımına eşittir



for (i=1; i<=n; i++) {
    for (j=1; j<=n; j++) {
        k = k+1;
    }
}

Toplam zaman = c * n * n * = cn2 = O(N2)


KURAL 3: ARDIŞIK DEYİMLER


Her deyimin zamanı birbirine eklenir



x = x +1;
for (i=1; i<=n; i++) {
     m = m + 2;
}
for (i=1; i<=n; i++)  {
    for (j=1; j<=n; j++) {
        k = k+1;
    }
}   

toplam zaman = c0 + c1n + c2n2 = O(N2)

KURAL 4:  IF-THEN-ELSE DEYİMLERİEn kötü çalışma zamanı:test zamanına then veya else kısmındaki çalışma zamanının hangisi büyükse o kısım eklenir.

if (depth( ) != otherStack.depth( ) ) {
   return false;
}
else {
   for (int n = 0; n < depth( ); n++) {
   if (!list[n].equals(otherStack.list[n]))
      return false;
   }
}


Toplam zaman = c0 + c1 + (c2 + c3) * n = O(N)


KURAL 5: LOGARİTMİK KARMAŞIKLIK


Problemin büyüklüğünü belli oranda(genelde  ½)
 azaltmak için sabit bir zaman harcanıyorsa bu algoritma O(log N)’dir.
Örnek algoritma (binary search):
N sayfalı bir sözlükten bir sözcük arama

  Sözlüğün orta kısmına bakılır
  Sözcük ortaya göre sağda mı solda mı kaldığı bulunur?
  Bu işlem sağ veya solda sözcük bulunana kadar tekrarlanır




O Notasyonu - Örnek 13n2+2n+5 = O(n2) ifadesinin doğru olup olmadığını ispatlayınız.

10 n2  = 3n2 + 2n2 + 5n2
        3n2 + 2n + 5 for n  1

c = 10, n0 = 1


O Notasyonu - Örnek 2T(N)=O(7n2+5n+4) olarak ifade edilebiliyorsa, T(N) fonksiyonu aşağıdakilerden herhangi biri olabilir.
T(N)=n2
T(N)=1000n2+2n+300
T(N)= O(7n2+5n+4) =O(n2)

O Notasyonu - Örnek 3
Fonksiyonların harcadıkları zamanları O notasyonuna göre yazınız.

f1(n) = 10 n + 25 n2
f2(n) = 20 n log n + 5 n
f3(n) = 12 n log n + 0.05 n2
f4(n) = n1/2 + 3 n log n








 






En iyi, ortalama, en kötü durum karmaşıklığı

Bazı durumlarda en iyi, ortalama, en kötü durum karmaşıklığı gözönüne almak gerekir
  En kötü, O(N) veya o(N):  veya > asıl fonksiyon   *
  Genel, Θ(N):  asıl fonksiyon                                   *
  En iyi, Ω(N):  asıl fonksiyon                                  *

Örnek: Liste sıralarken eğer liste zaten sıralıya yakınsa yapılacak iş azdır.
En kötü durum muhtemel bütün girdiler için bir sınır çizer ve genelde ortalamadan daha kolay bulunur

Ω Notasyonu- Asimtotik Alt Limit

 O notasyonun tam tersidir.
 Her durumda T(N) Ωc f(n) ve N Ω n0 koşullarını      sağlayan  pozitif, sabit c ve n0 değerleri bulunabiliyorsa T(N)=Ω(f(n))  ifadesi doğrudur.

 f(n), T(N)’in asimtotik alt limiti olarak
adlandırılır.


Ω Notasyonu Örnek 1

7n2+3n+5 = O(n4)
7n2+3n+5 = O(n3)
7n2+3n+5 = O(n2)
7n2+3n+5 = Ω(n2)
7n2+3n+5 = Ω(n)
7n2+3n+5 = Ω(1)


Algoritma 1




   int  Sum (int N)
   {
     int i, PartialSum;
     PartialSum=0;
   for(i=1  ;i<=N ; i++)
      PartialSum+=i*i*i;
   return PartialSum;
   }

Çalışma zamanı 6N+4=O(N)

Performans her şey demek değildir!

Bazen aşağıdaki iki durum birbiriyle çelişebilir:
Anlama, yazma ve hata ayıklama kolaylığı
Zaman ve yerin verimli kullanılmasıEfficient use of time and space
Bu nedenle maksimum performans her zaman tercih edilmeyebilir
Ancak yine de en uygun algoritmayı kullanmak mümkün olmasa da farklı yöntemleri karşılaştırmak yararlıdır.

 


Algoritmalar ve Karmaşıklıkları

Binary Search

  İkili arama algoritması sıralı dizimizi ortadan ikiye bölerek aranılan değerin bulunup bulunmadığını; eğer bulunmadı ise arananın orta elemandan büyük mü küçük mü olduğunu kontrol eder. Diyelim ki aranan orta değerden küçüktür. Bu sefer arama algoritmamız orta elemandan büyük olan kısmı tamamen yok sayarak orta elemandan küçük olan kısmıyeni diziymiş gibi kabul eder. Böylelikle dizimiz yarıya indirgenmiş olmuştur. Sonrasında tekrardan orta değerden küçük kısmı ikiye bölerek, aranılan değerin bulunup bulunmadığını kontrol eder. Yeni orta değer aranan eleman değilse, küçük mü büyük mü diye yeniden kontrol edilir. Ve bu işlem aranan değer bulununcaya yada tamamen dizi taranıncaya kadar devam eder. Bu yüzden algoritmamızın karmaşıklığı O(logN) olur.

Binary search karmaşıklık: Worst case = O(log n) Average case = O(log n)

 

 

 

 

 

 

 

 

Binary Search Github

Bubble Sort

 Bubble sortun çalışma mantığı şöyledir: dizinin başından başlanarak ikişerli kıyaslama yapılarak dizinin sonuna kadar gidilir. İlgili sıralama şekline göre kıyaslanan elemanlar yer degiştirir. Hiç bir yer degiştiren eleman kalmadıgında sıralama işlemi sonlanır. Bu işlemin maliyeti O(N^2) dir.

Buble sort karmaşıklık: Worst case = O(n^2) Average case = O(n^2)








https://gist.github.com/yasko45/ee8c6d5bec8cc45cba6a

 

Hash Tablosu

 

 Hash tablosu, veriye bir anahtar (key) yardımı ile erişilen basit bir dizi üzerine bina edilmiştir.Anahtar kullanılarak bir indeks üretilir ve bu indeks ile dizideki istenen veriye ulaşılır.Anahtar tekildir yani bir başka kayıtta aynı anahtar olamaz. Ancak veri aynı olabilir. Bir sınıftaki öğrenciler buna çok iyi bir örnektir. Her öğrencinin sadece kendine ait bir numarası vardır. Ancak aynı isme sahip iki öğrenci olması muhtemeldir. Burada öğrenci numarası anahtardır; öğrenci ismi ise, bu anahtara ait veridir.

Ders kapsamında yazmış olduğum quick sort kodunu algoritma analiz yazarak github hesabıma koydum aşağıdaki linkten ulaşabilirsiniz.

 

https://gist.github.com/yasko45/093810359ea7a037143a5d3657ec47bd 

 

Selection Sort

 Selection Sort, bilgisayar bilimlerinde kullanılan bir sıralama algoritmasıdır. Karmaşıklığı   olduğu için büyük listeler üzerinde kullanıldığında verim sağlamaz ve genel olarak benzeri olan eklemeli sıralamadan daha başarısızdır. Seçmeli sıralama yalın olduğu ve bazı durumlarda daha karmaşık olan algoritmalardan daha iyi sonuç verdiği için tercih edilebilir.

Selection sort karmaşıklık:
Best case= O(n^2) Worst case = O(n^2) Average case = O(n^2)

https://gist.github.com/yasko45/ee8c6d5bec8cc45cba6a

 

Insertıon Sort
 Insertion Sort, bilgisayar bilimlerinde kullanılan ve sıralı diziyi her adımda öge öge oluşturan bir sıralama algoritmasıdır. Insertion Sort Algoritması, düzensiz dizi elemanlarını tek tek ele alarak her birini dizinin sıralanmış kısmındaki uygun yerine yerleştirme esasına dayanır. Genelllikle günlük hayatımızda farketmeden kullandığımız bir çözüm yöntemidir. Küçük boyutlu dizileri sıralamada hızlı olsa da çok sayıda veriyi sıralarken Insertion Sort diğer sıralama yöntemlerine göre çok yavaş kalmaktadır.

 İnsertion sort karmaşıklık:
Best case= O(n) Worst case = O(n^2) Average case = O(n^2)

https://gist.github.com/yasko45/ee8c6d5bec8cc45cba6a