Daha küçük pencere boyutlarında n log n
sıralama işe yarayabilir. Bunu başarmak için daha iyi algoritmalar var mı?
Daha küçük pencere boyutlarında n log n
sıralama işe yarayabilir. Bunu başarmak için daha iyi algoritmalar var mı?
Yanıtlar:
İşte olası bir algoritmayı açıklayan bir makale. Kaynak kodu dahil ve oldukça ciddi bir uygulama (lazer interferometrisine dayanan yerçekimi dalga tespiti), böylece iyi test edilmesini bekleyebilirsiniz.
Bir yaklaşıma tahammül etmek istiyorsanız, başka yöntemler de vardır. Örneğin, bir yaklaşım sıralaması gerçek ortancadan (kullanıcı tarafından belirtilen) bir mesafede olan bir değerdir. Örneğin, medyan 0,5 (normalleştirilmiş) sıralamaya sahiptir ve% 10'luk bir hata terimi belirtirseniz, 0,45 ile 0,55 arasında bir cevap istersiniz.
Böyle bir cevap uygunsa, sürgülü veri pencerelerinde çalışabilecek birçok çözüm vardır. Temel fikir, belirli bir boyuttaki verilerin bir örneğini (kabaca 1 / hata terimi) korumak ve bu örnek üzerindeki medyanı hesaplamaktır. Yüksek olasılıkla, girdinin doğasına bakılmaksızın, ortaya çıkan medyanın yukarıda bahsettiğim özellikleri karşıladığı gösterilebilir.
Bu nedenle, ana soru, belirli bir boyuttaki verilerin çalışan bir örneğinin nasıl korunacağıdır ve rezervuar örnekleme olarak bilinen teknik dahil olmak üzere birçok yaklaşım vardır. Örneğin, bu makale: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.24.7136
Bir uzunluk-k veri penceresini sıralanmış bir ikili bağlantı listesi olarak tutarsanız, ikili bir arama (her yeni öğeyi pencereye kaydırılırken eklemek için) ve dairesel bir işaretçi dizisi (hemen silinmesi gerekir), pencerenin her vardiyasında bir öğe eklemek için O (günlük (k)) çabası, pencereden dışarı kaydırılan öğeyi silmek için yalnızca O (1) çaba ve yalnızca O (1) bulma çabası gerekir ortanca (listeye her öğe eklendiğinde veya silindiğinde, bir işaretçiyi ortancaya O (1) zamanında güncelleyebilirsiniz). N uzunluğundaki bir diziyi işlemek için toplam çaba O ((nk) log (k)) <= O (n log (k)) şeklindedir. Bu, şimdiye kadar önerilen diğer yöntemlerden daha iyidir ve bir yaklaşım değildir, kesindir.
Bahsettiğiniz gibi, sıralama O(n·log n)
bir uzunluk penceresi için olacaktır n
. Bu hareketi l=vectorlength
yapmak, toplam maliyeti artıracak başka bir şey ekler O(l·n·log n)
.
Bunu itmenin en basit yolu, bir pencereden diğerine geçerken hafızadaki son n öğenin sıralı bir listesini tutmaktır. Bir öğeyi sıralı bir listeden / sıralı bir listeye çıkarmak / eklemek, her ikisinin de O(n)
maliyetiyle sonuçlanır O(l·n)
.
pseudocode:
l = length(input)
aidvector = sort(input(1:n))
output(i) = aid(n/2)
for i = n+1:l
remove input(i-n) from aidvector
sort aid(n) into aidvector
output(i) = aid(n/2)
İşte mevcut medyanı bulmak için bir O (1) ve yeni bir sayı eklemek için O (log n) http://www.dsalgo.com/RunningMedian.php
Gerçek medyan yerine bir tahminle yaşayabiliyorsanız, Remedian Algoritması (PDF) , düşük depolama gereksinimleri ve iyi tanımlanmış doğruluk ile tek geçiştir.
B bazlı ilaç, b gözlem gruplarının medyanlarını ve daha sonra bu medyanların medyanlarını sadece tek bir tahmin kalana kadar ilerletir. Bu yöntem yalnızca b boyutunda k dizilerine ihtiyaç duyar (burada n = b ^ k) ...
Bu RunningStats C ++ Kitaplığını kullandım gömülü bir uygulamada kullandım. Henüz bulduğum en basit koşu istatistikleri kütüphanesi.
Bağlantıdan:
Kod, verilerden bir geçişte standart sapmayı hesaplamak için Knuth ve Welford yönteminin bir uzantısıdır. Benzer bir arayüzle çarpıklık ve basıklık da hesaplar. Verilerden sadece bir geçiş yapılmasına gerek kalmasının yanı sıra, algoritma sayısal olarak kararlı ve doğrudur.