Büyük O, nasıl/yaklaşık hesaplamak mı?
CS mezunu olan çoğu kişi, kesinlikle Big O stands forbilir. Ölçmek için bir algoritma gerçekten ve eğer what category the problem you are trying to solve lays in Eğer hala mümkünse biraz daha fazla performans sıkmak için ise bir yolunu biliyorsan nasıl (verimli)için bize yardımcı olur.1
Ama merak ediyorum, nasılsanahesaplamak algoritmaların karmaşıklığını yaklaşık?
1
CEVAP
Bir profesör Yapıları ve Algoritmalar ders Veri benim yerel üniversitede asistan oldum. Benim en iyi burada basitçe açıklamak için elimden geleni yapacağım, ama bu konu benim öğrenci alır uyardı nihayet kavramak için bir kaç ay. Data Structures and Algorithms in Java kitabın Bölüm 2'de daha fazla bilgi bulabilirsiniz.
Bu BigOh almak için kullanılabilir mechanical procedure yoktur.
Bir "yemek kitabı", elde etmek için BigOh bir parça kod ilk ihtiyacı fark vardır oluşturarak bir matematik formülü kadar say kaç adım hesaplamaları olsun idam verilen bir giriş bazı boyutu.
Amaç basit: kodu çalıştırmak için gerek kalmadan bakış teorik açıdan bakıldığında,. algoritmaları karşılaştırmak için Adım sayısı, daha hızlı algoritma daha az.
Örneğin, bu kod parçası var:
int sum(int* data, int N) {
int result = 0; // 1
for (int i = 0; i < N; i ) { // 2
result = data[i]; // 3
}
return result; // 4
}
Bu işlev, dizinin tüm elemanlarının toplamını verir, ve bu işlevi computational complexity sayısı için bir formül yaratmak istiyoruz:
Number_Of_Steps = f(N)
f(N)
, hesaplama adımları saymak için bir işlevi var. Fonksiyonun giriş işlemi için yapı boyutudur. Bu işlev suchs olarak: denir anlamına gelir
Number_Of_Steps = f(data.length)
Parametre N
data.length
değerini alır. Şimdi işlevi gerçek tanımı f()
ihtiyacımız var. Bu 4'e 1 gelen her ilginç hat numaralı kaynak kodu, yapılır.
Bu BigOh hesaplamak için birçok yol vardır. Bu noktadan giriş verileri büyüklüğüne bağlı olmayan her cümle C
sabit bir sayı hesaplama adım atıyor varsayıyoruz.
Fonksiyonun adımları tek tek numara eklemek için gidiyoruz, ve ne yerel değişken bildirimi ne return ifadesi data
dizinin boyutu bağlıdır.
Bu hat 1 ve 4 C adımları her miktar alır, ve bu şekilde biraz anlamına gelir:
f(N) = C ??? C
Sonraki bölüm for
ifadesinin değeri tanımlamak için. Hesaplamalı adım sayısını ifade bedeni N kez idam alır, diğer bir deyişle sayma olduğunu unutmayın. *,* 27 ** 26 defa ekleme de aynen şu şekilde:
f(N) = C (C C ... C) C = C N * C C
for
vücut infaz ediliyor, bu kodu tam olarak ne yaptığını bakarak saymak gerekir nasıl saymak için mekanik bir kural yok. Hesaplamaları basitleştirmek için for
deyimi değişken başlatma, koşul ve artım parçaları göz ardı edilmektedir.
İşlevi Asymptotic analysis ihtiyacımız olan gerçek BigOh almak için. Bu böyle yapılır kabaca:
- Tüm sabitleri 31**.
f()
standard form
polynomium.- Bu polynomium şartları böl ve büyüme oranına göre sıralamak.
N
infinity
yaklaştığında daha büyük büyüyen bir tutmak.
f()
bizim iki dönem vardır:
f(N) = 2 * C * N ^ 0 1 * C * N ^ 1
C
sabitler ve yedek parçaları tüm götürüp:
f(N) = 1 N ^ 1
Son bir terim, büyüdükçe daha büyük olduğunda f()
yaklaşımlar sonsuz (sanırım limits) bu BigOh argüman, ve sum()
fonksiyona sahip bir BigOh:
O(N)
Bazı zor olanları çözmek için birkaç hile vardır: istediğiniz zaman kullanın. summations. summation identities bazı kullanışlı zaten doğru olduğu kanıtlanmıştır.
Başka bir örnek olarak, bu kod toplamları kullanılarak kolayca çözülebilir:
for (i = 0; i < 2*n; i = 2) { // 1
for (j=n; j > i; j--) { // 2
foo(); // 3
}
}
Sorulması için gerekli olan ilk şey foo()
yürütme sırası. Her zamanki gibi O(1)
olması ise bu konuda profesörler sormak gerekir. O(1)
(neredeyse çoğu) sabit 47 ** N
bağımsız anlamına gelir.
Bu cümle üzerinde for
deyimi numaralı zordur. Endeksi 2 * N
, biter ise artış iki tarafından yapılır. İlk for
N
adım idam olur, ve iki tarafından sayısını bölmek gerekir.
f(N) = Summation(i from 1 to 2 * N / 2)( ... ) =
= Summation(i from 1 to N)( ... )
Cümle sayısıikii
değeri bağlıdır beri. daha komplikedir Bak: dizin alır değerleri: 0, 2, 4, 6, 8, ..., 2 * N ve ikinci for
idam: N kez birinci, N - 2 İkinci, N - 4 üçüncü... N / 2 evre, ikinci for
asla idam alır.
Formül, anlamına gelir:
f(N) = Summation(i from 1 to N)( Summation(j = ???)( ) )
Yine, geri sayım devam ediyoradım sayısı. Ve tanımı gereği, her toplamı her zaman en başlatın ve bir numara daha büyük veya eşit en sonunda.
f(N) = Summation(i from 1 to N)( Summation(j = 1 to (N - (i - 1) * 2)( C ) )
(foo()
O(1)
C
adım atıyor varsayıyoruz.)
i
değer N / 2 1
Yukarı alır, iç Toplamı negatif bir sayı biter! bir sorunumuz var: Bu imkansız ve yanlış. Toplam bölünmüş iki, an N / 2 1
alır önemli nokta olmak istiyoruz.
f(N) = Summation(i from 1 to N / 2)( Summation(j = 1 to (N - (i - 1) * 2)) * ( C ) ) Summation(i from 1 to N / 2) * ( C )
Önemli anlardan beri i > N / 2
, iç infaz etmeyecek ve gövde üzerinde sabit C yürütme karmaşıklığı varsayıyoruz.
Şimdi özetler bazı kimlik kuralları kullanarak basitleştirilmiş olabilir:
- Toplamı(1 N w)( C ) = N * C
- Toplamı(w 1-N)( A ( /-) B ) = Toplamı(w 1-N)( A ) ( /-) Toplam(w 1-N)( B )
- Toplamı(1 N w)( w * C ) = C * Toplamı(1 N w)( w ) (C
w
sürekli, bağımsız) - Toplamı(1 N w)( w ) = (w * (g 1)) / 2
Bazı Cebir uygulanması
f(N) = Summation(i from 1 to N / 2)( (N - (i - 1) * 2) * ( C ) ) (N / 2)( C )
f(N) = C * Summation(i from 1 to N / 2)( (N - (i - 1) * 2)) (N / 2)( C )
f(N) = C * (Summation(i from 1 to N / 2)( N ) - Summation(i from 1 to N / 2)( (i - 1) * 2)) (N / 2)( C )
f(N) = C * (( N ^ 2 / 2 ) - 2 * Summation(i from 1 to N / 2)( i - 1 )) (N / 2)( C )
=> Summation(i from 1 to N / 2)( i - 1 ) = Summation(i from 1 to N / 2 - 1)( i )
f(N) = C * (( N ^ 2 / 2 ) - 2 * Summation(i from 1 to N / 2 - 1)( i )) (N / 2)( C )
f(N) = C * (( N ^ 2 / 2 ) - 2 * ( (N / 2 - 1) * (N / 2 - 1 1) / 2) ) (N / 2)( C )
=> (N / 2 - 1) * (N / 2 - 1 1) / 2 =
(N / 2 - 1) * (N / 2) / 2 =
((N ^ 2 / 4) - (N / 2)) / 2 =
(N ^ 2 / 8) - (N / 4)
f(N) = C * (( N ^ 2 / 2 ) - 2 * ( (N ^ 2 / 8) - (N / 4) )) (N / 2)( C )
f(N) = C * (( N ^ 2 / 2 ) - ( (N ^ 2 / 4) - (N / 2) )) (N / 2)( C )
f(N) = C * (( N ^ 2 / 2 ) - (N ^ 2 / 4) (N / 2)) (N / 2)( C )
f(N) = C * ( N ^ 2 / 4 ) C * (N / 2) C * (N / 2)
f(N) = C * ( N ^ 2 / 4 ) 2 * C * (N / 2)
f(N) = C * ( N ^ 2 / 4 ) C * N
f(N) = C * 1/4 * N ^ 2 C * N
Ve BigOh
O(N ^ 2)
Nasıl "mevcut çerçeveler" ekl...
Nasıl birisi hesaplamak'C s yaş m...
Nasıl div içeriğini daha büyük değil y...
Nasıl NSString için bilimsel deneyler ...
Nasıl böyle büyük mükafat 4 NSZombieEn...