Çalışan medyanı hesaplamam gerekiyor:
Giriş: , k , vektör ( x 1 , x 2 , … , x n ) .
Çıkış: vektörü , y i ortancasıdır ( x i , x i + 1 , ... , x i + k - 1 ) .
(Yaklaşımlarla aldatma yok; Kesin çözümlere sahip olmak istiyorum. Elements büyük tamsayılar.)
boyutunda bir arama ağacını koruyan önemsiz bir algoritma vardır ; toplam çalışma süresi O ( n log k ) ' dır . (Burada bir "arama ağacı", logaritmik zamandaki ekleme, silme ve ortanca sorguları destekleyen bazı verimli veri yapılarını ifade eder.)
Ancak, bu bana biraz aptal görünüyor. Sadece medyanayı değil, k boyutundaki tüm pencerelerde tüm sipariş istatistiklerini etkili bir şekilde öğreneceğiz . Ayrıca, bu pratikte çok çekici değildir, özellikle k büyükse (büyük arama ağaçları yavaş olma eğilimindedir, bellek tüketiminde ek yük önemsiz değildir, önbellek verimliliği genellikle düşüktür, vb.).
Daha iyi bir şey yapabilir miyiz?
Daha düşük sınırlar var mı (örneğin karşılaştırma modeli için önemsiz algoritma asimptotik olarak optimal mi?)?
Düzenleme: David Eppstein karşılaştırma modeli için güzel bir alt sınır verdi! Yine de önemsiz algoritmadan biraz daha akıllıca bir şey yapmanın mümkün olup olmadığını merak ediyorum?
Örneğin, bu satırlar boyunca bir şeyler yapabilir miyiz: giriş vektörünü boyutunda parçalara böler ; her bir parçayı sıralayın (her bir elemanın orijinal konumlarını takip ederek); ve daha sonra, yardımcı veri yapıları olmadan verimli çalışan ortancaları bulmak için parçalara ayrılmış vektörleri kullanın. Tabii ki bu hala O ( n log k ) olacaktır , ancak pratikte dizilerin sıralanması arama ağaçlarının korunmasından çok daha hızlı olma eğilimindedir.
Düzenleme 2: Saeed, sıralama işleminin arama ağacı işlemlerinden daha hızlı olduğunu düşündüğüm nedenleri görmek istedi. İşte , n = 10 8 için çok hızlı karşılaştırmalar :
- ≈ 8s: sıralama vektörleri ile k elemanları, her
- ≈ 10s: elemanlı bir vektörü sıralama
- ≈ 80'ler: boyutu bir karma tablo ekleme & silme k
- ≈ 390s: , k boyutunda dengeli bir arama ağacına yapılan yerleştirmeler ve silmeler
Karma tablo sadece karşılaştırma için var; Bu uygulamada doğrudan kullanım yok.
Özetle, sıralama ve dengeli arama ağacı işlemlerinin performansında neredeyse 50 faktör farkımız var. Ve arttıkça işler daha da kötüleşiyor .
(Teknik detaylar: Veriler = rastgele 32 bit tam sayılar. Bilgisayar = tipik bir modern dizüstü bilgisayar. Test kodu standart kütüphane yordamları (std :: sort) ve veri yapıları (std :: multiset, std ::) kullanılarak C ++ dilinde yazılmıştır. sıralanmamış_multiset) İki farklı C ++ derleyicisi (GCC ve Clang) ve standart kitaplığın iki farklı uygulamasını kullandım (libstdc ++ ve libc ++).