Neden ikili arama üçlü aramadan daha hızlıdır?


49

İkili aramayı kullanarak bir öğesi dizisi aramak, en kötü durumda yinelemeleri gerçekleştirir, çünkü her adımda arama alanımızın yarısını . Bunun yerine, 'üçlü arama' kullanırsak, her yinelemede arama alanımızın üçte ikisini , en kötü durum yinelemeyi ...Nlog2Nlog3N<log2N

Üçlü aramanın daha hızlı olduğu anlaşılıyor, peki neden ikili aramayı kullanıyoruz?


3
Kişi, Kuaterner araması için aynı akıl yürütmeyi kullanamaz mıydı? Veya hatta ondalık arama ... ya da 2'den büyük bir şey
d'alar'cop

4
lütfen B + Ağaçları hakkında okuyun
arunmoezhi

5
Lineer arama genellikle modern donanımdaki küçük ila orta büyüklükteki problemlerde ikili aramadan daha hızlıdır, çünkü önbellek uyumludur ve neredeyse tüm dallar doğru tahmin edilmektedir.
Sahte

2
Ayrıca 2 * log_3 (N) = log_3 (N ^ 2) sezginize uygunsa.
PawelP

6
Bunu sezgisel terimlere koyalım. Her bir yinelemede arama alanını daha fazla azalttığı için 3 tabanlı bir arama kullanmak daha hızlıysa, milyon tabanlı bir arama daha hızlı kullanılmıyor mu? Ancak, hedefi içeren 1 milyonuncu dilimi belirlemek için ortalama olarak her yinelemede 500.000 kontrol yapmanız gerektiğini kolayca görebilirsiniz. Açıkçası, arama alanını her yinelemenin yarısında kesmek ve daha fazlasını kesmek, size en fazla bilgiyi güvenilir bir şekilde tek bir adımda verir .
ErikE

Yanıtlar:


76

İkili arama yaparsanız, birçok karşılaştırmanız var. Üçlü arama uygularsanız , her adımda olduğu gibi birçok karşılaştırmaya sahipsiniz, arama alanını üç parçaya ayırmak için 2 karşılaştırma yapmanız gerekir. Şimdi hesaplamayı yaparsanız şunu gözlemleyebilirsiniz: bildiğimiz yana olduğunu , aslında almak daha üçlü arama ile karşılaştırmalar.

log2(n)+O(1)
2log3(n)+O(1)
2log3(n)+O(1)=2log(2)log(3)log2(n)+O(1)
2log(2)log(3)>1

Bu arada: -ary search, kıyaslamaların oldukça maliyetli olması ve paralelleştirilebilmesi durumunda çok anlamlı olabilir, paralel bilgisayarlar uygulanabilir.n

Argümanın, -ary aramaya oldukça kolay şekilde genelleştirilebileceğini unutmayın . Sadece fonksiyonunun kesinlikle tamsayı değerleri için artan monoton olduğunu göstermeniz gerekir .nf(k)=(k1)log(2)log(k)k


1
Ve LHS doğrusaldır ve RHS logaritmiktir, bu yüzden herhangi bir dördüncüye veya bundan daha fazlasına yardımcı olmaz .... Güzel Açıklamalar .... Teşekkürler
Ortalama Meydan

3
Sadece tamlık adına: eleman karşılaştırmaları gibi soyut bir önlemin gerçek çalışma zamanını etkileyebileceğini veya etkilemeyebileceğini unutmayın. Özellikle, ne kadar önbellek özlüyor olabileceğini düşünmek zorunda kalabilirsiniz. (Burada çakışıyorlar. Sadece şunu fark ediyorum çünkü OP “neden daha hızlı?” Diye soruyor ve soyut bir önlemle cevap vermek bazı algoritmalar için yanıltıcı olabilir.)
Raphael

10
Üçlü bir aramada, zamanın 1 / 3'ünde sadece 1 karşılaştırmaya ihtiyacınız olacak (daha düşük karşılaştırmayı yapın: daha düşük üçüncüde ise, ikinci karşılaştırmaya ihtiyacınız olmaz). Bu, üçlüyü% 25 yerine sadece% 5 kadar yavaşlatıyor (sadece karşılaştırma sayısını önemsiyoruz bu dünyada). N-ary için nasıl genelleştirileceğinden emin değilim, ancak hiçbir zaman ikiliden daha hızlı olmadığından şüpheleniyorum.
Aaron Dufour

2
@AaronDufour: İlk önce ortadaki maddeye göre bir kuaterner arama yapıp, diğer karşılaştırmaların sonucunu göz ardı ederek yapabileceği için, kuaterner araştırmanın daha hızlı olması, üç karşılaştırmanın iki karşılaştırmadan daha ucuza paralel olarak daha ucuz bir şekilde yapılabilmesidir. sırayla gerçekleştirilebilir.
supercat,

1
@AaronDufour Ama aramak için elementler üzerinden amorti ediyorsunuz ve bunun neden tamam olduğu bana belli değil. En kötü durumda, her adımda her iki karşılaştırma da yapılabilir.
Sasho Nikolov

26

DCTLib haklı, ama bir saniye için matematiği unut.

O zaman mantığınızla, n -ary en hızlı olmalı. Ancak, eğer bunu düşünürseniz, n -ary normal bir yineleme aramasına tamamen eşittir (sadece listeyi 1'e 1 yineleyen, ancak ters sırada). Öncelikle listedeki son (veya sondan sonraki) öğeyi seçip bu değeri karşılaştırma değerinizle karşılaştırın. Sonra o öğeyi listenizden kaldırırsınız ve yeni listedeki son öğeyi seçersiniz; bu, dizideki son değerin hemen yanındadır. Her seferinde, değerinizi bulana kadar bir seferde yalnızca 1 değeri elemediniz.

Bunun yerine, böyle düşünmelisin - her yinelemede listedeki en fazla değeri nasıl eleyebilirim? İkili bir aramada, listenin yarısını her zaman kaldırırsınız. Üçlü bir aramada, listenin 2 / 3'ünü elimine etme olasılığınız (aslında% 33,33 şansı), ancak listenin sadece 1 / 3'ünü elimine alma şansınız daha da yüksektir (% 66,66). O (n) 'yi hesaplamak için, 1/3 olan 1/2 en küçük senaryoya bakmanız gerekir. N'ye yaklaştıkça, daha da kötüye gider.

İkili arama ile yalnızca en kötü durum senaryosu iyileştirilmeyecek, aynı zamanda ortalama süreniz de artacaktır. Beklenen değere bakarak (listenin hangi kısmını ortalama olarak kaldırabiliriz), şu formülü kullanırız:

(P_lower) x (daha düşükse çıkarabileceğimiz kısım) + (P_higher) x (daha yüksekse çıkarabileceğimiz kısım) = E

İkili arama için, bu .5x.5 + .5x.5 = .5'tir (listenin yarısını daima kaldırırız). Üçlü aramalar için bu değer .666x.333 + .333x.666 = 0.44 veya her adımda, listenin yalnızca% 44'ünü kaldıracağız, bu sayede ikili aramadan ortalama olarak daha az verimli hale getireceğiz. Bu değer 1/2 olarak (listenin yarısı) doruk noktasına çıkar ve n (ters yineleme) ve 0 (normal yineleme) değerlerine yaklaştıkça düşer.

Tamam, yalan söyledim ... biraz matematik işin içinde, ama umarım bu yardımcı olur!


1
Bu harika bir cevap.
The_Sympathizer,

Ya sınır analizi zor matematiği anlamaya yardımcı olur! n ary ardışık arama aynı doğrusal arama O (n) maliyetine sahiptir.
shuva

-2

Lütfen log (N) - 2 log (N) karşılaştırma argümanının algoritmanın saf bir yorumuna dayandığını unutmayın. Aslında bunu x86 düzeneğine yazıp yazacak olsaydım sonuçlar tersine çevrilirdi. Sorun, gereksiz karşılaştırmaları kaldıramayan yeterince akıllı bir derleyici ile birleştirilen test durumları için tamsayıların kullanılmasıdır. Dizeleri ve uygun bir dize karşılaştırma işlevini yeniden deneyin ve karşılaştırma işlevini döngü başına bir kez çağırmak için kodlayın; üçlü aramanın tekrar daha hızlı olduğunu göreceksiniz.


2
Elbette üçlü arama, her yineleme için yalnızca bir karşılaştırmayla yapılabilseydi daha hızlı olurdu. Ancak, dizeleri veya tamsayıları olursa olsun, yapamazsınız.
FrankW

Karşılaştırmalar gereksiz olmaz ve sorunun derleyici ile ilgisi yoktur. Arama alanını üç bölüme ayırmak için 2 karşılaştırmaya ihtiyacınız var. İkili bir aramada, yalnızca ortadaki öğeyle karşılaştırmanız gerekir ve daha sonra sonucun hangi yarısında yer alacağını bilirsiniz. Üçlü aramayla, yolun 1 / 3'ünün elemanı ile karşılaştırmanız gerekir. liste VE liste içinde yolun 2 / 3'ü. Ne tür veriler karşılaştırıyorsunuz veya hangi dili kullanıyorsunuz önemli değil. Verilmiş, madde 1. 3 ise, 1 karşılaştırmanın ardından durabilirsiniz.
reirab

2
Bazı platformlarda, CPU'nun karşılaştırmak için ihtiyaç duymadan önce işlenenleri RAM'den almak için daha fazla zamana izin vermesi nedeniyle üçlü arama daha hızlı olabilir. Ancak bu tamamen kullanılan platforma ve gecikmelerine ve önbelleklerine bağlıdır.
jpa

1
Kahretsin - üçlü aramanın yanlış tanımı.
Joshua,
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.