Nasıl çalıştığına bağlı olarak dört ortak büyük O zaman karmaşıklığı gösteren bir program (veya işlev) yazın . Her halükarda, 2 31'den küçük olduğunu varsayabileceğiniz pozitif bir tamsayı N alır .
Program orjinal haliyle çalıştırıldığında sürekli karmaşıklığa sahip olması gerekir . Yani, karmaşıklık Θ (1) veya eşit olarak ently (1 ^ N) olmalıdır .
Program tersine çevrildiğinde ve çalıştırıldığında doğrusal karmaşıklığa sahip olması gerekir . Yani, karmaşıklık Θ (N) veya eşdeğerde Θ (N ^ 1) olmalıdır .
(Bu normaldiN^1
edilir1^N
tersine çevirdi.)Program iki katına çıktığında , yani kendi kendine birleştirildiğinde ve çalıştırıldığında, üstel karmaşıklığa, özellikle 2 N'ye sahip olması gerekir . Yani, karmaşıklık Θ (2 ^ N) olmalıdır .
(Bu normaldi2
de2^N
çift1
içinde1^N
.)Program olduğunda iki ve ters ve olması gereken çalıştırmak polinom özellikle karmaşıklığı, N 2 . Yani, karmaşıklık Θ (N ^ 2) olmalıdır .
(Bu normaldiN^2
edilir2^N
tersine çevirdi.)
Bu dört vaka, üstesinden gelmen gereken tek şey.
Kesinliği için , büyük O yerine büyük teta (Θ) gösterimini kullanıyorum, çünkü programlarınızın çalışma sürelerinin gerekli karmaşıklıklarla hem yukarıda hem de altında tutulması gerektiğine dikkat edin. Aksi takdirde sadece O (1) 'de bir fonksiyon yazmak dört noktayı da tatmin eder. Buradaki nüansı anlamak çok önemli değil. Temel olarak, eğer programınız k * f (N) işlemlerini bazı sabit k için yapıyorsa, muhtemelen Θ (f (N)) 'dedir.
Örnek
Orijinal program olsaydı
ABCDE
sonra çalışan sabit zaman almalıdır. Yani, N girişinin 1 veya 2147483647 (2 31 -1) veya aradaki herhangi bir değer olup olmadığı, kabaca aynı sürede sona ermelidir.
Programın tersine çevrilmiş versiyonu
EDCBA
N cinsinden doğrusal zaman almalıdır, yani, sona erme süresi kabaca N ile orantılı olmalıdır, N = 1 en az zaman alır ve N = 2147483647 en fazla zaman alır.
Programın iki katına çıktı
ABCDEABCDE
N cinsinden iki'ye bir zaman almalıdır, yani, sonlandırması için geçen süre kabaca 2 N ile orantılı olmalıdır . N = 1 yaklaşık bir saniye içinde sona ererse, N = 60'ın sona ermesi, evrenin yaşından daha uzun sürer. (Hayır, test etmeniz gerekmez.)
Programın iki katına ve tersine çevrilmiş hali
EDCBAEDCBA
N cinsinden kare zaman almalıdır, yani, sonlandırılması için geçen süre kabaca N * N ile orantılı olmalıdır. N = 1 yaklaşık bir saniye içinde sona ererse, N = 60'ın sonlandırılması yaklaşık bir saat sürer.
ayrıntılar
Programlarınızın, söylediğiniz karmaşıklıklarda çalıştığını göstermeniz veya tartışmanız gerekir. Bazı zamanlama verilerinin verilmesi iyi bir fikir ancak aynı zamanda karmaşıklığın neden doğru olduğunu teorik olarak açıklamaya çalışın.
Uygulamada programlarınızın geçen zamanlarının karmaşıklıklarını (veya hatta deterministlerini) mükemmel şekilde temsil etmemesi halinde sorun yoktur. örneğin N + 1 girişi bazen N'den daha hızlı çalışabilir.
İçinde programlarınızı çalıştırdığınız çevre yapar olsun. Popüler dillerin kasıtlı olarak asla algoritmalarda zaman kaybetmediği konusunda temel varsayımlarda bulunabilirsiniz, ancak örneğin, Java'nın kendi sürümünüzün daha hızlı bir sıralama algoritması yerine kabarcık sıralaması uyguladığını biliyorsanız, herhangi bir sıralama yaparsanız bunu hesaba katmalısınız. .
Buradaki tüm karmaşıklıklar için , en iyi durumdan veya ortalama durumdan değil, en kötü durum senaryolarından bahsettiğimizi varsayın .
Programların uzay karmaşıklığı önemli değil, sadece zaman karmaşıklığı.
Programlar herhangi bir şey verebilir. Yalnızca pozitif tamsayı N'yi almaları ve doğru zaman karmaşıklıklarına sahip olmaları önemlidir.
Yorumlar ve çok satırlı programlara izin verilir. (
\r\n
Tersine çevrildiğini,\r\n
Windows uyumluluğu içindir.)
Büyük O Hatırlatıcılar
En hızlıdan en yavaşına kadar O(1), O(N), O(N^2), O(2^N)
(yukarıda sipariş 1, 2, 4, 3).
Daha yavaş terimler daima egemendir, örneğin O(2^N + N^2 + N) = O(2^N)
.
O(k*f(N)) = O(f(N))
sabiti için k. Öyleyse O(2) = O(30) = O(1)
ve O(2*N) = O(0.1*N) = O(N)
.
Unutmayın O(N^2) != O(N^3)
ve O(2^N) != O(3^N)
.
puanlama
Bu normal kod golfü. Bayt cinsinden en kısa orijinal program (sabit süre bir) kazanır.
n = input(); for i in xrange(n): pass
üstel bir karmaşıklığı var, çünkü 2 ** k
adım atıyor, k = log_2(n)
girdi boyutu nerede . Gereklilikleri önemli ölçüde değiştirdiği için durumun böyle olup olmadığını netleştirmelisiniz.