ikili arama karmaşıklığı nasıl hesaplanır


144

Birinin, ikili arama arama için gerekli girdiyi yarıya indirdiği için log (n) algoritması olduğunu söylediğini duydum. Matematik geçmişinden olmadığım için onunla ilişki kuramıyorum. Biri bunu biraz daha detaylı açıklayabilir mi? logaritmik serilerle bir şey yapmak zorunda mı?


1
bu size yardımcı olabilir: stackoverflow.com/a/13093274/550393
2cupsOfTech

Yanıtlar:


395

Burada, gerçekten karmaşık olmasa da, daha matematiksel bir bakış açısı. IMO, gayri resmi olanlar kadar daha net:

Soru şu ki, 1 elde edene kadar N'yi 2'ye kaç kez bölebilirsiniz? Bu aslında şunu söyler, bulana kadar ikili arama yapın (elemanların yarısı). Bir formülde bu şöyle olacaktır:

1 = N / 2 x

2 x ile çarpın :

2 x = N

şimdi günlük 2'yi yapın :

log 2 (2 x ) = log 2 N
x * log 2 (2) = log 2 N
x * 1 = log 2 N

bu, her şey bölünene kadar log N kez bölebileceğiniz anlamına gelir. Bu, elemanınızı bulana kadar log N'yi ("ikili arama adımını yapın") bölmeniz gerektiği anlamına gelir.


t (n) = (2 ^ 2) * K olarak hesapladım. log formuna nasıl yapılır?
Shan Khan

2
aynı kavram grafik olarak açıklanmıştır: stackoverflow.com/a/13093274/550393
2cupsOfTech

Eksik olduğum kısım, 7 girişli bir BST'niz varsa, formülü nedir? log2 (7)? Olası her sonuç için kaba kuvvet hesaplaması yaptım ve log2 (7) 'ye eşit olmayan bir cevaba geldim, öyleyse neyi yanlış yapıyorum?
Perry Monschau

1
İkili ağaç açıklamasından çok daha kolay.
NoName

1
Çok güzel cevap
VHS

23

İkili Arama için, T (N) = T (N / 2) + O (1) // tekrarlama ilişkisi

Tekrarlama ilişkilerinin çalışma zamanı karmaşıklığını hesaplamak için Masters Teoremini uygulayın: T (N) = aT (N / b) + f (N)

Burada a = 1, b = 2 => log (a taban b) = 1

ayrıca burada f (N) = n ^ c log ^ k (n) // k = 0 & c = log (a tabanı b)

O halde, T (N) = O (N ^ c log ^ (k + 1) N) = O (log (N))

Kaynak: http://en.wikipedia.org/wiki/Master_theorem


1
a = 1 ve b = 2 iken neden log (a tabanı b) 1, 0 olması gerekmiyor mu?
GAURANG VYAS

16

T (n) = T (n / 2) +1

T (n / 2) = T (n / 4) + 1 + 1

The (n / 2) değerini yukarıya koyun, böylece T (n) = T (n / 4) + 1 + 1. . . . T (n / 2 ^ k) + 1 + 1 + 1 ..... + 1

= T (2 ^ k / 2 ^ k) + 1 + 1 .... + 1 k'ye kadar

= T (1) + k

2 ^ k = n aldığımız gibi

K = log n

Yani Zaman karmaşıklığı O (log n)


10

Arama süresinin yarısı değildir, bu onu log yapmaz (n). Logaritmik olarak azaltır. Bunu bir an düşünün. Bir tabloda 128 girişiniz varsa ve değerinizi doğrusal olarak aramak zorunda kaldıysanız, değerinizi bulmak muhtemelen ortalama 64 giriş alacaktır. Bu n / 2 veya doğrusal zamandır. İkili arama ile, her bir yinelemede olası girdilerin 1 / 2'sini ortadan kaldırırsınız, öyle ki, değerinizi bulmak için en fazla 7 karşılaştırma yapılır (128'in 2 tabanının 2'si 7 veya 2'nin 7'nin üssü 128'dir.) ikili aramanın gücü.


Necropost için özür dilerim ama 128 eşit doldurulmuş bir ağaç değil. Bunu aşmak için basit bir örnek kullandım ve 7 girişin bir ağacı 3 katmanla eşit şekilde doldurduğunu buldum. Karmaşıklığın 2,43 olan 17/7 (karşılaştırmaların toplamının ortalaması) olması gerektiğini hesapladım. Ancak log2 (7) 2,81'dir. Peki burada neyi özlüyorum?
Perry Monschau

İki cevap - Birincisi burada: Matematikte hata olmasa bile, 2,43 ortalamanın lineer için 3,5 ortalamadan daha iyi olduğunu görebiliriz ve bu düşük bir değerde. Yüzlerce girişe girdiğinizde, log2 () doğrusaldan çok daha iyidir. Sanırım bunu bir sonrakinde de görüyorsunuz.
Michael Dorgan

1
İkinci cevap: 7'nin her şeyi doldurduğu ne tür bir ağacın olduğundan emin değilim. 8 girişten oluşan mükemmel bir ağaç düşündüğümde, toplamda 8 yapraklı 3 seviyeli derin bir ağaç görüyorum. Bu ağaçta hangi numarayı ararsanız arayın, kökten yaprağa ulaşmak için toplam 3 karşılaştırma gerekir. 7 giriş için, yollardan birinin karşılaştırması bir eksiktir, bu nedenle 20/7 (3 karşılaştırmanın 6 düğüm, 2 karşılaştırmanın 1 düğümü) ~ 2,85 olur. Log2 (7) ~ 2.81'dir. .04 farkını açıklayacak matematik geçmişim yok, ancak bunun kesirli bitlerin mevcut olmaması veya başka bir sihir olmamasıyla ilgisi var sanırım :)
Michael Dorgan

sayı yaprak sayısıdır !? Düğüm sayısı değil mi? Bu, kaçırdığım büyük bir bilgiydi .. Her dallanma düğümü aynı zamanda potansiyel bir durma noktası olduğunda, fonksiyonun yapraklara dayalı olması bana garip geliyor. Her neyse, bunu benim için düzelttiğin için teşekkürler!
Perry Monschau

5

İkili arama algoritmasının zaman karmaşıklığı O (log n) sınıfına aittir. Buna büyük O notasyonu denir . Bunu yorumlamanız gereken yol, n boyutunda bir girdi kümesinin aşılmayacağı göz önüne alındığında, işlevin çalışması için gereken sürenin asimtotik büyümesinin olmasıdır log n.

Bu, ifadeleri vb. İspatlayabilmek için sadece resmi matematiksel bir dildir. Çok basit bir açıklaması vardır. N çok büyüdüğünde, log n işlevi, işlevi yürütmek için geçen süreyi aşar. "Girdi kümesi" nin boyutu, n, sadece listenin uzunluğudur.

Basitçe ifade etmek gerekirse, ikili aramanın O (log n) konumunda olmasının nedeni, her yinelemede giriş kümesini yarıya indirmesidir. Tersi durumda düşünmek daha kolay. X yinelemede, ikili arama algoritması maksimumda ne kadar uzun listeyi inceleyebilir? Cevap 2 ^ x. Buradan, bunun tersinin, ortalama olarak ikili arama algoritmasının, n uzunluğunun bir listesi için log2 n yinelemeye ihtiyaç duyduğunu görebiliriz.

Eğer neden O (log n) ise ve O (log2 n) değil ise, bunun nedeni basitçe tekrar söyleyelim - Büyük O notasyon sabitlerini kullanmak sayılmaz.


4

İşte wikipedia girişi

Basit yinelemeli yaklaşıma bakarsanız. İhtiyacınız olan öğeyi bulana kadar aranacak öğelerin yarısını ortadan kaldırmış olursunuz.

Formülü nasıl ortaya çıkardığımızın açıklaması burada.

Diyelim ki başlangıçta N sayıda elementiniz var ve sonra yaptığınız şey ilk deneme olarak ⌊N / 2⌋. N, alt sınır ve üst sınırın toplamıdır. N'nin ilk zaman değeri (L + H) 'ye eşit olacaktır; burada L, ilk dizin (0) ve H, aradığınız listenin son dizinidir. Şanslıysanız, bulmaya çalıştığınız öğe ortada olacaktır [ör. Listede {16, 17, 18, 19, 20} 18'i arıyorsun, ardından 0'ın alt sınır olduğu ⌊ (0 + 4) / 2 = 2'yi hesaplarsın (dizinin ilk elemanının L - indeksi) ve 4, üst sınırdır (dizinin son elemanının H-indeksi). Yukarıdaki durumda L = 0 ve H = 4. Şimdi 2, aradığınız element 18'in indeksidir. Bingo! Buldun.

Vaka farklı bir dizi olsaydı {15,16,17,18,19} ama hala 18'i arıyor olsaydın, o zaman şanslı olmazdın ve ilk N / 2'yi yapıyor olurdun (yani ⌊ (0 + 4) / 2⌋ = 2 ve sonra 2. dizideki 17. öğenin aradığınız sayı olmadığını anlayın. Artık yinelemeli arama için bir sonraki denemenizde dizinin en az yarısını aramanız gerekmediğini biliyorsunuz. Arama çabası yarı yarıya azalır.Yani temel olarak, önceki denemenizde bulamadığınız öğeyi her bulmaya çalıştığınızda, daha önce aradığınız öğe listesinin yarısını aramıyorsunuz.

Yani en kötü durum

[N] / 2 + [(N / 2)] / 2 + [((N / 2) / 2)] / 2 .....
yani:
N / 2 1 + N / 2 2 + N / 2 3 + ..... + N / 2 x … ..

ta ki… aramayı bitirdiğinize kadar, bulmaya çalıştığınız öğenin neresi listenin sonundadır.

Bu, en kötü durumun N / 2 x'e ulaştığınız zamandır, burada x, 2 x = N

Diğer durumlarda N / 2 x burada x, 2 x <N olacak şekildedir Minimum x değeri 1 olabilir, bu en iyi durumdur.

Şimdi matematiksel olarak en kötü durum,
2 x = N
=> log 2 (2 x ) = log 2 (N)
=> x * log 2 (2) = log 2 (N)
=> x * 1 = log 2 (N)
=> Daha resmi olarak ⌊log 2 (N) + 1⌋


1
Daha resmi versiyonu tam olarak nasıl elde edersiniz?
Kalle

Zemin işlevi kullanılır. Ayrıntılar , yanıtta verilen wiki bağlantısının ( en.wikipedia.org/wiki/Binary_search_algorithm ) performans bölümündedir .
RajKon


2

İkili Arama'daki yinelemenin k yinelemeden sonra sona erdiğini varsayalım. Her yinelemede dizi ikiye bölünür. Diyelim ki herhangi bir yinelemede dizinin uzunluğu n 1. Yinelemede,

Length of array = n

Yineleme 2'de,

Length of array = n⁄2

3. yinelemede,

Length of array = (n⁄2)⁄2 = n⁄22

Bu nedenle, k yinelemesinden sonra,

Length of array = n⁄2k

Ayrıca, K bölünme sonra sonra biliyoruz dizisinin uzunluğu 1 olur Bu nedenle

Length of array = n⁄2k = 1
=> n = 2k

Her iki tarafa da günlük işlevi uygulamak:

=> log2 (n) = log2 (2k)
=> log2 (n) = k log2 (2)
As (loga (a) = 1)

Bu nedenle,

As (loga (a) = 1)
k = log2 (n)

Dolayısıyla İkili Aramanın zaman karmaşıklığı

log2 (n)

1

İkili arama, problemi tekrar tekrar ikiye bölerek çalışır, buna benzer bir şey (ayrıntılar atlanmıştır):

[4,1,3,8,5] 'de 3'ü arayan örnek

  1. Öğe listenizi sipariş edin [1,3,4,5,8]
  2. Ortadaki öğeye (4) bakın,
    • Eğer aradığın buysa, dur
    • Daha büyükse, ilk yarısına bakın
    • Daha azsa, ikinci yarıya bakın
  3. 2. adımı yeni liste [1, 3] ile tekrarlayın, 3'ü bulun ve durdurun

Bu bir olan bi sen 2'de sorunu bölmek zaman -nary arama.

Arama, doğru değeri bulmak için yalnızca log2 (n) adımlarını gerektirir.

Algoritmik karmaşıklık hakkında bilgi edinmek istiyorsanız, Algorithms'e Giriş'i tavsiye ederim .


1

Her seferinde bir listeyi yarıya indirdiğimizden, bu nedenle bir listeyi ikiye bölerek kaç adımda 1 elde ettiğimizi bilmemiz gerekiyor. Aşağıda verilen hesaplamada x, bir öğe elde edene kadar (En Kötü Durumda) bir listeyi böldüğümüz süreyi gösterir.

1 = N / 2x

2x = N

Log2 alınıyor

log2 (2x) = log2 (N)

x * log2 (2) = log2 (N)

x = log2 (N)


1

T (N) = T (N / 2) + 1

T (N) = T (N / 2) + 1 = (T (N / 4) + 1) + 1

...

T (N) = T (N / N) + (1 + 1 + 1 + ... + 1) = 1 + logN (2 tabanında günlük) = 1 + logN

Yani ikili aramanın zaman karmaşıklığı O (logN)


0
ok see this
for(i=0;i<n;n=n/2)
{
i++;
}
1. Suppose at i=k the loop terminate. i.e. the loop execute k times.

2. at each iteration n is divided by half.

2.a n=n/2                   .... AT I=1
2.b n=(n/2)/2=n/(2^2)
2.c n=((n/2)/2)/2=n/(2^3)....... aT I=3
2.d n=(((n/2)/2)/2)/2=n/(2^4)

So at i=k , n=1 which is obtain by dividing n  2^k times
n=2^k
1=n/2^k 
k=log(N)  //base 2

0

Bir örnekle bunu hepiniz için kolaylaştırmama izin verin.

Basitlik amacıyla, ikili aramayı kullanarak bir elemanı aradığımız sıralı düzende bir dizide 32 eleman olduğunu varsayalım.

1 2 3 4 5 6 ... 32

32'yi aradığımızı varsayalım. İlk yinelemeden sonra,

17 18 19 20 .... 32

ikinci yinelemeden sonra,

25 26 27 28 .... 32

üçüncü yinelemeden sonra,

29 30 31 32

dördüncü yinelemeden sonra,

31 32

Beşinci yinelemede 32 değerini bulacağız.

Yani, bunu matematiksel bir denkleme dönüştürürsek, şunu elde ederiz:

(32 X (1/2 5 )) = 1

=> n X (2- k ) = 1

=> (2 k ) = n

=> k log 2 2 = log 2 n

=> k = günlük 2 n

Dolayısıyla kanıt.


0

Okunabilir LaTeX ile ana teoremi kullanan çözüm burada.

İkili arama için yineleme ilişkisindeki her yineleme için, sorunu çalışma zamanı T (N / 2) ile tek bir alt probleme dönüştürüyoruz. Bu nedenle:

T (n) = T (n / 2) +1

Ana teoremi değiştirerek şunu elde ederiz:

T (n) = aT (n / b) + f (n)

Şimdi, logba0 olduğundan ve f (n) 1 olduğundan, ana teoremin ikinci durumunu kullanabiliriz çünkü:

f (n) = O (1) = O (n0) = O (nlogba)

Bunun anlamı şudur ki:

T (n) = O (nlogbalogn) = O (n0logn) = O (logn)

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.