O (…) nedir ve nasıl hesaplarım?


31

Yardım et! Bir algoritmanın Big-O'sunu veya bazı kodları analiz etmem gereken bir sorum var.

  • Büyük-O'nun tam olarak ne olduğundan ya da Büyük-Theta'yla ya da bir algoritmanın karmaşıklığını analiz etmenin diğer yöntemleriyle ne olduğundan emin değilim.

  • Big-O'nun kodu çalıştırma zamanı mı, yoksa harcadığı hafıza miktarını mı ifade ettiğinden emin değilim (boşluk / zaman değişmesi).

  • Bilgisayar döngüsüne sahibim, belki bir özyinelemeli bir algoritma ve bazı döngüler almalı ve bunun için Big-O ile gelmeliyim.

  • Bilinen bir Big-O ile iki veri yapısı veya algoritma arasında seçim yapabildiğim ve hangisini seçeceğimi bilmediğim bir program üzerinde çalışıyorum.

Big-O'yu programıma, ödevime veya Genel Bilgisayar Bilimleri bilgisine nasıl hesaplayacağımı ve uygulayacağımı nasıl anlarım?

Not: Bu soru, topluluk tarafından belirlenen diğer Big-O soruları için kanuni bir dupe hedefidir . Birçok Big-O sorusu için büyük miktarda yararlı bilgi içerebilmeyi kasıtlı olarak geniştir. Lütfen bu kadar geniş olduğu gerçeğini, benzer soruların kabul edilebilir olduğunun bir göstergesi olarak kullanmayın.


1
Sadece bir not, bu soru burada meta üzerinde tartışılmaktadır .
enderland

2
Başlamak için harika bir kaynak, Han akademi kursu olacaktır (CLRS'den Thomas Cormen, yazarlardan biridir). Bu da benim için CS mezunu olarak harika bir kaynaktı. khanacademy.org/computing/computer-science/algorithms
Sudip Bhandari

3
Bu soruyu işaretleyen kişilere: lütfen sorunun altındaki alt metni okuyun ve işaretlemek veya kapatmak için oy vermeden önce bu bağlantıyı izleyin.

Yanıtlar:


22

O (...), bir algoritmanın bir şeyi yapması için kaç işlem yapılacağını açıklamanın basit bir yolu olan Big-O gösterimini ifade eder. Bu zaman karmaşıklığı olarak bilinir .

Big-O notasyonunda, bir algoritmanın maliyeti, çok pahalı olan en pahalı işlemiyle temsil edilir. Bir algoritma aldıysa adımları, bu (n-O temsil edilen 3 ). Bir listedeki her öğeyi sayan bir algoritma, doğrusal zaman olarak adlandırılan O (n) zamanda çalışır.n3 + n2 + n

Wikipedia'daki isimlerin ve klasik örneklerin bir listesi için: Genel fonksiyonların siparişleri

İlgili materyal:


6
Not: büyük O, doğası gereği zamanı veya boşluğu veya belirli bir şeyi ölçmez. Bu sadece bir fonksiyonun asimptotik büyümesini üste bağlar (bir sabite kadar). Bu işlev, giriş uzunluğunun bir işlevi olarak bir algoritmanın zamanı, boşluğu, vb. Olabilir ve en çok CS bağlamında zamandır, ancak zorunlu değildir.
Monica'yı

23

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.


Bu iyi bir cevap, ancak Big-O ve Big-worst'nin en kötü ve en iyi vakalarla ilgisi yok. Bunlar üst ve alt sınırlardır, ancak her ikisi için de geçerli olabilir; örneğin, yerleştirme sıralama en iyi durumda, ϴ(n)en kötü durumda iken (hem Big-O hem Big-Ω) zaman karmaşıklığına sahiptir. bir zaman karmaşıklığı ϴ(n²)(hem Big-O hem de Big-Ω).
Paul

Ayrıca, boş algoritmayı hariç tutan herhangi bir algoritma, Ω(1)en iyi, en kötü ve ortalama durumlardadır, ancak bunun nedeni, daha düşük bir sınırdır ve algoritmanın gerçek en iyi durumuyla ilgisi olmamasıdır.
Paul

Büyük-her ne olursa olsun en iyi veya en kötü durumla ilgisi yok - bu yaygın bir yanılgıdır. Bunlar sadece deterministik bir fonksiyonun diğerine kıyasla daha hızlı, daha yavaş veya aynı oranda büyüyüp büyümediğini belirlemenin bir yoludur. En iyi / en kötü durum kavramı, yalnızca gerçek algoritmaların zaman / mekan karmaşıklığı hakkında konuşmaya başladığınızda var olur; bu durumda belirleyici olmayan faktörler ortaya çıkar ve girdilerinizin olasılık dağılımını göz önünde bulundurmanız gerekir. O zaman bile, en iyi / en kötü durum büyük-O / Omega'ya dik bir eksende yatıyor .
17'de

@ Daha iyi tarif edebileceğinizi düşünüyorsanız, devam edin. Bunun bir topluluk wiki cevabı olduğunun farkındasın, değil mi?

"Öncelikle, gayriresmi literatürde," Big-O "'nun genellikle Big-a ile eşanlamlı olarak değerlendirildiği konusunda uyarılmalıdır. Karmaşıklık konusundaki ilk dönemim, üniversiteye döndüğümde bize Büyük-O'nun Büyük-definition gibi tanımını öğretti. (Ders kitabımız bu tanımı kullandı!) Karmaşıklık II'ye gittiğimde beynimin kafasını karıştırdı ve ikisinin de aynı olmadığını öğrendim.
T. Sar - Monica,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.