Bu önceki soru , bir algoritmanın O (log n) karmaşıklığına sahip olmasına neden olabilecek bazı faktörlere yöneliktir.
Bir algoritmanın zaman karmaşıklığına O (log log n) sahip olmasına ne sebep olur?
Bu önceki soru , bir algoritmanın O (log n) karmaşıklığına sahip olmasına neden olabilecek bazı faktörlere yöneliktir.
Bir algoritmanın zaman karmaşıklığına O (log log n) sahip olmasına ne sebep olur?
Yanıtlar:
O (log log n) terimleri çeşitli farklı yerlerde görünebilir, ancak genellikle bu çalışma zamanına ulaşacak iki ana yol vardır.
Bağlantılı sorunun cevabında belirtildiği gibi, bir algoritmanın zaman karmaşıklığına O (log n) sahip olmasının yaygın bir yolu, bu algoritmanın, her yinelemede girdinin boyutunu tekrar tekrar sabit bir faktörle azaltarak çalışmasıdır. Bu durumda, algoritma O (log n) yinelemelerinden sonra sonlandırılmalıdır, çünkü bir sabite göre O (log n) bölmelerini yaptıktan sonra, algoritma problem boyutunu 0 veya 1'e düşürmelidir. ikili aramanın karmaşıklığı O (log n).
İlginç bir şekilde, O formunun çalışma zamanlarını (log log n) veren bir problemin boyutunu küçültmenin benzer bir yolu vardır. Her katmanda girdiyi ikiye bölmek yerine, her katmanda boyutun karekökünü alırsak ne olur ?
Örneğin 65.536 sayısını alalım. Bunu 1'e inene kadar kaç defa 2'ye bölmeliyiz? Bunu yaparsak, alırız
Bu süreç 16 adım sürer ve 65.536 = 2 16 da söz konusudur .
Ancak, her seviyede karekök alırsak, şunu elde ederiz:
2'ye inmek için sadece dört adım gerektiğine dikkat edin. Bu neden?
İlk olarak, sezgisel bir açıklama. N ve √n sayılarında kaç basamak vardır? N sayısında yaklaşık olarak log n basamak vardır ve √n cinsinden yaklaşık olarak log (√n) = log (n 1/2 ) = (1/2) log n basamak vardır. Bu, her karekök aldığınızda, sayıdaki basamak sayısını kabaca yarıya indirdiğiniz anlamına gelir. Bir k O (log k) miktarını bir sabite (örneğin, 2) düşmeden önce yarıya indirebileceğiniz için, bu, sayıyı düşürmeden önce sadece O (log log n) kez karekök alabileceğiniz anlamına gelir. sabit (diyelim, 2).
Şimdi, bunu titizleştirmek için biraz matematik yapalım. Le'ts, yukarıdaki diziyi ikinin kuvvetleri açısından yeniden yazar:
2 16 → 2 8 → 2 4 → 2 2 → 2 1 sırasını izlediğimize dikkat edin . Her yinelemede, ikinin üssünü ikiye böldük. Bu ilginç, çünkü bu zaten bildiğimiz şeye geri dönüyor - k sayısını sıfıra düşmeden önce yalnızca O (log k) kez ikiye bölebilirsiniz.
Yani herhangi bir n sayısını alın ve bunu n = 2 k olarak yazın . N'nin karekökünü her aldığınızda, bu denklemdeki üssü yarıya indirirsiniz. Bu nedenle, k 1 veya altına düşmeden önce sadece O (log k) karekökleri uygulanabilir (bu durumda n 2 veya altına düşer). N = 2 k olduğundan , bu k = log 2 n olduğu anlamına gelir ve bu nedenle alınan karekök sayısı O (log k) = O (log log n) olur. Bu nedenle, problemi tekrar tekrar orijinal problem boyutunun karekökü olan bir boyut alt problemine indirgeyerek çalışan bir algoritma varsa, bu algoritma O (log log n) adımlarından sonra sona erecektir.
Bunun gerçek hayattan bir örneği van Emde Boas ağacıdır.(vEB-ağacı) veri yapısı. Bir vEB ağacı, 0 ... N - 1 aralığındaki tam sayıları depolamak için özel bir veri yapısıdır. Aşağıdaki şekilde çalışır: ağacın kök düğümü, 0 ... N - aralığını bölerek, içinde √N işaretçiye sahiptir. 1 ila rangeN kova, her biri kabaca √N tam sayı aralığı içerir. Bu kovaların her biri daha sonra dahili olarak her biri kabaca √ (√ N) eleman tutan √ (√ N) kovalara bölünür. Ağaçta gezinmek için, kökten başlarsınız, hangi gruba ait olduğunuzu belirlersiniz ve ardından uygun alt ağaçta yinelemeli olarak devam edersiniz. VEB ağacının yapılandırılma şekline bağlı olarak, O (1) zamanda hangi alt ağacın alçalacağını belirleyebilirsiniz ve böylece O (log log N) adımlarından sonra ağacın dibine ulaşırsınız. Buna göre, bir vEB ağacındaki aramalar yalnızca O zaman alır (günlük günlüğü N).
Başka bir örnek, Hopcroft-Fortune en yakın nokta çifti algoritmasıdır . Bu algoritma, bir 2B nokta koleksiyonunda en yakın iki noktayı bulmaya çalışır. Bir kova ızgarası oluşturarak ve noktaları bu kovalara dağıtarak çalışır. Algoritmanın herhangi bir noktasında, içinde √N'den fazla noktaya sahip bir kova bulunursa, algoritma o grubu yinelemeli olarak işler. Özyinelemenin maksimum derinliği bu nedenle O (log log n) 'dir ve özyineleme ağacının bir analizi kullanılarak ağaçtaki her katmanın O (n) çalıştığı gösterilebilir. Bu nedenle, algoritmanın toplam çalışma süresi O (n log log n) 'dir.
O (log n) boyutundaki nesneler üzerinde ikili arama gibi algoritmaları kullanarak O (log log n) çalışma zamanlarına ulaşan başka algoritmalar da vardır. Örneğin, x-fast trie veri yapısı, ağaç yüksekliğindeki (log U) katmanlar üzerinde ikili bir arama gerçekleştirir, bu nedenle bazı işlemlerinin çalışma zamanı O olur (log log U). İlgili y-hızlı üçlü , O (log U) düğümlerinin her birinin dengeli BST'lerini koruyarak, O (log log U) çalışma zamanlarından bazılarını alır ve bu ağaçlardaki aramaların O zamanında çalışmasına izin verir (log log U). Tango ağaç ve ilgili multisplay ağacı da O (log n) ürün her içeren ağaçları korumak için veri yapılarının analizlerde, bir O (log n) terimi ile sonuna kadar.
Diğer algoritmalar, başka yollarla çalışma zamanı O (log log n) elde eder. Enterpolasyon araması , sıralı bir dizide bir sayı bulması için çalışma zamanı O'nun (log log n) bekledi, ancak analiz oldukça dahil. Son olarak, adım sayısının sayısı k burada n eşittir göstererek analiz çalışmaları 2 -k ≤ 2 için, günlük log n, doğru bir çözümdür. Cheriton-Tarjan MST algoritması gibi bazı algoritmalar, karmaşık bir kısıtlı optimizasyon problemini çözerek O (log log n) içeren bir çalışma zamanına ulaşır.
Bu yardımcı olur umarım!
Zaman karmaşıklığındaki O faktörünü (log log n) görmenin bir yolu, diğer cevapta açıklanan şeyler gibi bölünmedir, ancak bu faktörü görmenin başka bir yolu vardır, zaman ve mekan / zaman arasında bir ticaret yapmak istediğimizde ve algoritmaların yaklaşımı / süresi ve sertliği / ... ve bizim algoritmamızda bazı yapay yinelemeler var.
Örneğin SSSP (Tek kaynak en kısa yol) düzlemsel grafiklerde O (n) algoritmasına sahiptir, ancak bu karmaşık algoritmadan önce çalışma süresi O (n log log n) ile çok daha kolay bir algoritma (ama yine de oldukça zor) vardı. algoritmanın temeli aşağıdaki gibidir (çok kaba bir açıklama ve bu bölümü anlamayı ve cevabın diğer bölümünü okumayı öneriyorum):
Ama benim açımdan, burada bölünmeyi O büyüklüğünde seçiyoruz (log n / (log log n)). O (log n / (log log n) ^ 2) gibi diğer bölümleri seçersek, bu daha hızlı çalışabilir ve başka bir sonuç getirebilir. Demek istediğim, birçok durumda (yaklaşım algoritmaları veya rastgele algoritmalar veya yukarıdaki gibi SSSP gibi algoritmalar gibi), bir şeyi yinelediğimizde (alt problemler, olası çözümler, ...), bunun ticaretine karşılık gelen yineleme sayısını seçeriz. Elimizde (zaman / mekan / algoritmanın karmaşıklığı / algoritmanın sabit faktörü, ...). Gerçek çalışan algoritmalarda "log log n" den daha karmaşık şeyler görüyor olabiliriz.