Asimptotik fonksiyonlar nelerdir? Zaten asimptot nedir?
Bir fonksiyon verilen f (n) boyutunun bir girişine uygulandığı zaman bir algoritma tarafından tüketilen kaynak (CPU süresi, RAM, disk alanı, vs) miktarını tarif n , üç tanımlayabilir asimptotik için performansını tanımlayan gösterimler büyük n .
Bir asimptot (veya asimptotik fonksiyonu) basitçe başka fonksiyonu (veya ilişki) g (n) o f (n) olarak yakın giderek alır n büyür de büyür, ama asla tamamen ulaşır. Asimptotik fonksiyonlardan bahsetmenin avantajı, f (n) ifadesi aşırı derecede karmaşık olsa bile, konuşmaları genellikle daha kolay olmalarıdır . Asimptotik fonksiyonlarının bir parçası olarak kullanılan sınırlayıcı gösterimler sınırlamak f (n) üstünde ya da altında.
(Not: burada kullanılan anlamda, asimptotik fonksiyonlar, sadece üç sabit-0 / Θ / Ω notasyonu bu sabit faktörleri göz önüne almadıklarından, bazı sabit olmayan sıfır faktörü düzelttikten sonra sadece orijinal fonksiyona yakındır.)
Üç asimptotik sınırlayıcı gösterim nedir ve bunlar nasıl farklıdır?
Üç gösterim de bu şekilde kullanılır:
f (n) = 0 (g (n))
burada f (n) ilgilenilen fonksiyondur ve g (n) , f (n) ile yaklaştırmaya çalıştığınız başka bir asimptotik fonksiyondur . Bu titiz anlamda bir eşitlik olarak alınan, ancak edilmemelidir hızlı nasıl arasında resmi açıklamada f (n) göre büyür n kıyasla gr (n) olarak, n büyük hale gelir. Titiz genellikle alternatif notasyonu kullanacağız (n) ∈ O (g (n)) f sembolü vurgulamak için O (g (n)) bir bütün gerçekten aile ortak bir büyüme oranını paylaşan fonksiyonları.
Big ϴ (Theta) notasyonu , f (n) ' nin büyümesinde sabit bir faktöre kadar olan eşitliği belirtir (bu konuda daha sonra). Büyüme oranları için bir operatöre benzer şekilde davranır .=
Big-O notasyonu f (n) ' nin büyümesiyle ilgili bir üst sınırı tanımlar . Büyüme oranları için bir operatöre benzer şekilde davranır .≤
Big Ω (Omega) notasyonu , f (n) 'nin büyümesinde bir alt sınır tanımlamaktadır . Büyüme oranları için bir operatöre benzer şekilde davranır .≥
Orada diğer birçok asimtotik gösterimler , ancak bilgisayar bilimi literatüründe neredeyse sıklıkta meydana gelmez.
Big-O notasyonları ve ilkleri genellikle zaman karmaşıklığını karşılaştırmanın bir yoludur .
Zaman karmaşıklığı nedir?
Zaman karmaşıklığı zaman miktarı için süslü bir terimdir , T (n) bir algoritma, giriş boyutunun bir fonksiyonu olarak çalıştırmak için gereken n . Bu, gerçek zamanlı (örn. Saniye), CPU talimatlarının sayısı, vb. İle ölçülebilir. Genellikle, algoritmanın her gün von Neumann mimari bilgisayarınızda çalışacağı varsayılır . Ama elbette, zamanın karmaşıklığını, olayların farklı olabileceği daha egzotik bilgi işlem sistemleri hakkında konuşmak için kullanabilirsiniz!
Big-O notasyonu kullanarak uzay karmaşıklığı hakkında konuşmak da yaygındır . Alan karmaşıklığı, RAM, disk vb. Olabilen algoritmayı tamamlamak için gereken bellek (depolama) miktarıdır.
Bir algoritmanın daha yavaş olması ancak daha az hafıza kullanılması, diğerinin daha hızlı olması ve daha fazla hafıza kullanılması durumunda olabilir. Kaynaklar farklı şekilde kısıtlanırsa, her biri farklı durumlarda daha uygun olabilir. Örneğin, gömülü bir işlemci sınırlı belleğe sahip olabilir ve yavaş algoritmayı destekleyebilir, veri merkezindeki bir sunucuda büyük miktarda bellek bulunabilir ve daha hızlı algoritmayı tercih edebilir.
Büyük-ϴ Hesabı
Bir algoritmanın Big-ϴ'inin hesaplanması, küçük bir ders kitabını doldurabilen veya yaklaşık bir yarıyıl lisans sınıfının yarıyılını doldurabilecek bir konudur: bu bölüm temelleri kapsayacaktır.
Sözde kodda f (n) işlevi verilen :
int f(n) {
int x = 0;
for (int i = 1 to n) {
for (int j = 1 to n) {
++x;
}
}
return x;
}
Zamanın karmaşıklığı nedir?
Dış döngü n kere çalışır . Dış döngü her çalıştığında, iç döngü n kere çalışır . Bu, çalışma süresini T (n) = n 2 olarak gösterir .
İkinci bir fonksiyon düşünün:
int g(n) {
int x = 0;
for (int k = 1 to 2) {
for (int i = 1 to n) {
for (int j = 1 to n) {
++x;
}
}
}
return x;
}
Dış döngü iki kez çalışır. Orta döngü n kere çalışır . Orta döngü her çalıştığında, iç döngü n kere çalışır . Bu, çalışma süresini T (n) = 2n 2 olarak belirler .
Şimdi soru şu ki, her iki fonksiyonun asimptotik çalışma süresi nedir?
Bunu hesaplamak için iki adım uygularız:
- Sabitleri kaldırın. Girdilerden dolayı algoritmalar zamanla arttıkça, diğer terimler de çalışma süresine hakim olur ve onları önemsiz kılar.
- En büyük terimi hariç hepsini kaldırın. As n sonsuza gider, n 2 hızla outpaces n .
Burada anahtar , baskın terimlere odaklanmak ve bu terimleri basitleştirmek .
T (n) = n- 2 ∈ Θ (n 2 )
T (n) = 2n 2 ∈ Θ (n = 2 )
Birden fazla terime sahip başka bir algoritmamız varsa, aynı kuralları kullanarak sadeleştiririz:
T (n) = 2n 2 + 4n + 7 ∈ ϴ (n 2 )
Tüm bu algoritmaların anahtarı , en büyük terimlere odaklanmak ve sabitleri kaldırmak . Gerçek çalışma süresine değil göreceli karmaşıklığa bakıyoruz .
Big-Ω ve Big-O Hesaplamaları
Öncelikle, gayriresmi literatürde , “Büyük-O” nun genellikle Büyük- a ile eşanlamlı olarak kullanıldığı , belki de Yunanca harflerin yazması zor olduğu konusunda uyarılırsınız . Öyleyse mavi olmayan biri bir algoritmanın Big-O'sunu isterse, muhtemelen Big- probably'sini ister.
Şimdi , daha önce tanımlanan biçimsel duyularda Big-Ω ve Big-O'yu gerçekten hesaplamak istiyorsanız, büyük bir probleminiz var: Herhangi bir işlev için sonsuz sayıda Big-Ω ve Big-O açıklaması var! 42'ye eşit ya da daha küçük sayıların ne olduğunu sormak gibi. Pek çok olasılık var.
T (n) ∈ ϴ (n 2 ) içeren bir algoritma için aşağıdakilerden herhangi biri resmi olarak geçerli ifadelerdir:
- T (n) ∈ O (n 2 )
- T (n) ∈ O (n 3 )
- T (n) ∈ O (n 5 )
- T (n) ∈ O (n 12345 × e n )
- T (n) ∈ Ω (n 2 )
- T (n) ∈ Ω (n)
- T (n) ∈ Ω (log (n))
- T (n) ∈ Ω (log (log (n)))
- T (n) ∈ Ω (1)
Ancak, T (n) ∈ O (n) veya T (n) ∈ Ω (n 3 ) belirtmek yanlıştır .
Bağıl karmaşıklık nedir? Hangi algoritma sınıfları var?
İki farklı algoritmayı karşılaştırırsak, giriş sonsuzluğa giderken karmaşıklığı normalde artacaktır. Farklı algoritma türlerine bakarsak, göreceli olarak aynı kalabilir (örneğin, sabit bir faktöre göre farklılık gösterebilir) veya büyük ölçüde farklılık gösterebilir. Big-O analizi yapmanın nedeni budur: bir algoritmanın büyük girdilerle makul bir şekilde çalışıp çalışmayacağını belirlemek.
Algoritma sınıfları aşağıdaki gibi dağılır:
Θ (1) - sabit. Örneğin, listedeki ilk numarayı seçmek her zaman aynı miktarda zaman alacaktır.
Θ (n) - doğrusal. Örneğin, bir listeyi yineleme her zaman liste boyutuna orantılı olarak zaman alır, n .
Log (log (n)) - logaritmik (normalde baz önemli değildir). İkili arama gibi her adımda giriş alanını bölen algoritmalar örneklerdir.
Θ (n × log (n)) - logaritmik doğrusal zamanlar (“linearitmik”). Bu algoritmalar tipik olarak girişin tamamını yineleyerek ( n ) bölüştürür ve alır ( log (n) ) . Birçok popüler sıralama algoritması (birleştirme sıralama, Timsort) bu kategoriye girer.
Θ (n m ) - polinom ( n herhangi bir sabit m'ye yükseltilmiş ). Bu, genellikle iç içe döngülerde bulunan çok yaygın bir karmaşıklık sınıfıdır.
Θ (m , n ) - Üstel (herhangi bir sabit m yükseltilmiştir n ). Birçok özyinelemeli ve grafik algoritmaları bu kategoriye girer.
Θ (n!) - faktörlü. Bazı grafik ve birleşimsel algoritmalar faktoring karmaşıklığıdır.
Bunun en iyi / ortalama / en kötü durumla ilgisi var mı?
Hayır. Big-O ve notasyonları ailesi belirli bir matematiksel fonksiyondan bahseder . Algoritmaların verimliliğini karakterize etmek için kullanılan matematiksel araçlardır, ancak en iyi / ortalama / en kötü durum kavramı burada açıklanan büyüme hızları teorisi ile ilişkili değildir.
Algoritmanın Big-O'undan bahsetmek için , ne kadar yararlı olursa olsun, girişin “boyutunu” tanımlaması gereken tam olarak bir parametreli bir algoritmanın spesifik bir matematiksel modeline bağlı kalmak gerekir n
. Fakat gerçek dünyada, girdiler sadece uzunluklarından çok daha fazla bir yapıya sahip. Bu bir sıralama algoritması olsaydı, ben dizeleri yem olabilir "abcdef"
, "fedcba"
ya da "dbafce"
. Bunların hepsi 6 uzunluğundadır, ancak bunlardan biri zaten sıralanmış, biri tersine çevrilmiş ve sonuncusu rastgele bir karmakarışık. Girdi sıralanmışsa, bazı sıralama algoritmaları (Timsort gibi) daha iyi çalışır. Ancak bu homojen olmayanlığı matematiksel bir modele nasıl dahil eder?
Tipik yaklaşım, girdilerin rasgele, olasılıksal bir dağılımdan geldiğini varsaymaktır. Ardından, algoritmanın karmaşıklığı tüm girişler boyunca olan uzunluğu ile ortalarsınız n
. Bu , algoritmanın ortalama bir durum karmaşıklık modelini verir . Burada, ortalama vaka davranışını tanımlamak için her zamanki gibi Big-O / Θ / Ω gösterimlerini kullanabilirsiniz.
Ancak hizmet reddi saldırılarıyla ilgileniyorsanız, daha karamsar olmanız gerekebilir. Bu durumda, yalnızca girdilerin algoritmanız için en fazla kedere neden olanlar olduğunu varsaymak daha güvenlidir . Bu size algoritmanın en kötü durum karmaşıklık modelini verir . Daha sonra, en kötü durum modelinin Big-O / Θ / Ω vb. Hakkında konuşabilirsiniz .
Benzer şekilde, ilginizi yalnızca en iyi durumda olan bir modele ulaşmak için algoritmanızın en az sorun yaşadığı girdilere odaklayabilir , daha sonra Big-O / Θ / Ω vb.