小さいウィンドウサイズでは、n log n
ソートが機能する場合があります。これを達成するためのより良いアルゴリズムはありますか?
小さいウィンドウサイズでは、n log n
ソートが機能する場合があります。これを達成するためのより良いアルゴリズムはありますか?
回答:
ここでは一つの可能なアルゴリズムを説明した記事です。ソースコードが含まれており、非常に深刻なアプリケーション(レーザー干渉法に基づく重力波検出)であるため、十分にテストされることが期待できます。
近似値を許容する場合は、他の方法があります。たとえば、1つの近似値は、ランクが真の中央値から(ユーザー指定の)距離内にある値です。たとえば、中央値のランクは(正規化された)ランク0.5であり、10%のエラー項を指定した場合、ランクが0.45〜0.55の回答が必要になります。
そのような答えが適切な場合、データのスライディングウィンドウで機能する多くのソリューションがあります。基本的な考え方は、特定のサイズ(ほぼ1 /エラー項)のデータのサンプルを維持し、このサンプルの中央値を計算することです。入力の性質に関係なく、高い確率で、結果の中央値が上記の特性を満たすことが示されます。
したがって、主な問題は、特定のサイズのデータの実行中のサンプルをどのように維持するかということであり、そのための多くのアプローチがあります。たとえば、このペーパー:http : //citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.24.7136
データの長さkのウィンドウをソートされた二重リンクリストとして維持する場合、バイナリ検索(ウィンドウにシフトされるたびに新しい要素を挿入する)とポインターの循環配列(すぐに要素を見つける削除する必要があります)、ウィンドウの各シフトには、1つの要素を挿入するためのO(log(k))努力、ウィンドウからシフトした要素を削除するためのO(1)努力、および見つけるためのO(1)努力のみが必要です中央値(1つの要素がリストに挿入または削除されるたびに、O(1)時間で中央値へのポインタを更新できます)。したがって、長さNの配列を処理するための総労力はO((nk)log(k))<= O(n log(k))です。これはこれまでに提案された他のどの方法よりも優れており、近似ではなく、正確です。
あなたが述べたように、ソートはO(n·log n)
長さのウィンドウのためのものn
です。この移動をするl=vectorlength
ことは、総費用を作る別を追加しますO(l·n·log n)
。
これをプッシュする最も簡単な方法は、あるウィンドウから次のウィンドウに移動するときに、メモリ内の最後のn個の要素の順序付きリストを保持することです。1つの要素を順序付きリストから削除したり、リストに挿入したりすると、両方のO(n)
コストが発生しますO(l·n)
。
擬似コード:
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)
現在の中央値を見つけるためのソリューションO(1)と、新しい番号を追加するためのO(log n) http://www.dsalgo.com/RunningMedian.php
真の中央値の代わりに推定値で生きることができる場合、Remedian Algorithm(PDF)は、ストレージ要件が低く、正確に定義されたワンパスです。
基数bのレメディアンは、b個の観測値のグループの中央値を計算し、次にこれらの中央値の中央値を、単一の推定値のみが残るまで計算します。このメソッドは、サイズbのk個の配列(n = b ^ k)を必要とします...
このRunningStats C ++ライブラリを組み込みアプリケーションで使用しました。これは、私がこれまでに見つけた中で最も単純な実行統計ライブラリです。
リンクから:
このコードは、データの1回のパスで標準偏差を計算するためのKnuth and Welfordのメソッドの拡張です。同様のインターフェースで歪度と尖度も計算します。データを1回だけ通過するだけでなく、アルゴリズムは数値的に安定しており、正確です。