それはあなたのデータに依存します。最悪のシナリオは、それが一様に分布した数になることです。
この場合、次の例のように O(N) 時間で中央値を見つけることができます。
数値が 2,7,5,10,1,6,4,4,6,10,4,7,1,8,4,9,9,3,4,3 (範囲は 1 ~ 10) であるとします。 .
1-3、4-7、8-10 の 3 つのバケットを作成します。上と下のサイズが同じであることに注意してください。
バケツに数字を入れて、最大値と最小値のそれぞれにいくつ入るかを数えます
- 低 (5): 2,1,1,3,3、最小 1、最大 3
- 中間 (10): 7,5,6,4,4,6,4,7,4,4、最小 4、最大 7
- 高 (5): 10、10、8、9、9、最小 8、最大 10
平均は真ん中のバケツに入り、残りは無視します
3 つのバケットを作成します: 4、5-6、7。Low はカウント 5 で始まり、最大 3 で、High は最小 8 でカウント 5 です。
数値ごとに、低バケットと高バケット、最大バケットと最小バケットに該当する数をカウントし、中間バケットを保持します。
- 古い安値 (5)
- 低 (5): 4、4、4、4、4、最大 4
- 真ん中 (3): 5,6,6
- 高 (2): 7、7、最小 7
- 古い高値 (5)
これで、中央値を直接計算できます。次のような状況があります。
old low low middle high old high
x x x x x 4 4 4 4 4 4 5 6 6 7 7 x x x x x
したがって、中央値は 4.5 です。
分布について少し知っていると仮定すると、範囲を定義して速度を最適化する方法を微調整できます。いずれにせよ、1 + 1/3 + 1/9... = 1.5 であるため、パフォーマンスは O(N) と一致するはずです。
エッジケースのため、最小値と最大値が必要です (たとえば、中央値が古い安値の最大値と次の要素の間の平均である場合)。
これらの操作はすべて並列化できます。各コンピューターに 1/100 のデータを与え、各ノードで 3 つのバケットを計算し、保持しているバケットを分散できます。これにより、各数値が平均で 1.5 回 (O(N)) 渡されるため、ネットワークを効率的に使用できます。ノード間で最小数のみを渡す場合でも、それを打ち負かすことができます (たとえば、ノード 1 に 100 個の数があり、ノード 2 に 150 個の数がある場合、ノード 2 はノード 1 に 25 個の数を与えることができます)。
分布について詳しく知らない限り、実際には要素を少なくとも 1 回カウントする必要があるため、ここで O(N) よりもうまくできるとは思えません。