大量のデータを処理できる、つまりデータセット全体をメインメモリに一度に保持できない場合でも機能する並べ替えアルゴリズムを探しています。
これまでに見つけた唯一の候補はマージソートです。すべてのデータをメインメモリに一度に保持せずに、各マージでデータセットをスキャンするようにアルゴリズムを実装できます。私が念頭に置いているマージソートのバリエーションは、セクションの この記事 で説明されています。テープドライブでの使用。
これは良い解決策だと思います(複雑度O(n x log(n)を使用)。しかし、メインメモリに収まらない大規模なデータセットで機能する他の(おそらくより高速な)ソートアルゴリズムがあるかどうか知りたいです。
[〜#〜]編集[〜#〜]
回答に必要な詳細を以下に示します。
私が考えていた改善の1つは、ファイルをメモリ内でソートするのに十分小さいファイルに分割し、最後に上記のアルゴリズムを使用してこれらすべてのファイルをマージすることでした。
ソートと検索に関する正規のリファレンスは Knuth、Vol。 です。そこから始めましょう。
この本は元々、コンピュータが現在よりもはるかに小さくて遅いときに書き直されたため、現在のメモリよりもメモリ不足のソート手法が重要になっています。
外部Rウェイマージ UNIXの場合と同様に、sort
コマンドを使用することをお勧めします。あなたの定式化から、それが「マージソート」で意図したアルゴリズムであるかどうかはわかりません。それがわからない場合は、見てください。
詳細な説明がなければ、「マージソート」がおそらく最良の答えになりますが、要件に応じて、よりスマートなものを実装できます。
たとえば、単にファイルのメモリ内インデックスを作成し、すべての値を一度にコピーして、さまざまなキー値の場所をキャッシュできますか? 1/2は一度にメモリに収まりますか、それとも1/1000000ですか?それが2番目の場合は、インデックスをメモリに収めることができない場合があり、最初の場合は両方の半分をより効率的に並べ替え、最後の1つの手順でそれらをマージできます。
地獄、それを指定しなかったので、データがすべてデータベースにある可能性があります。そうであれば、インデックステーブルを作成してそれを適切に呼び出すことができます(これは当てはまらないと思いますが、このような複雑な問題を解決するには、状況が重要です)。
あなたが一度だけそれをやりたいと思っていて、非常に迅速なハックを探しているなら、あなたがunixを実行しているならば、外部マージソートが良いスタートになるように思えます(それは明らかに組み込まれているので)
順序を保つ必要があり、常に単一のレコードを追加する場合は、挿入ソートが必要になります(ソートされたデータに単一のレコードを追加することは常に挿入ソートです)。
データを「読み取る」コードを制御できますか?その場合、(ディスク上でデータを移動して並べ替えるのではなく)インデックス付けの多くの形式が、LOTに役立ちます(実際には絶対要件です)。
そう:
スケーラブルなソリューションが本当に必要な場合は、map-reduceを使用した標準のソート実装であるTeraSortを検討する必要があります。 StackOverflowの詳細 。
バケットソート に興味があるかもしれません。平均的なケースのパフォーマンスは線形時間です。
= O(n + d)n:要素の数、d =データについて直感がある場合の最大数の長さ、つまりあなたはあなたの最大の数字が何桁あるか知っているなら。したがって、200万の6桁の数値がある場合=> 0(n)したがって線形です。
外部マージソートアルゴリズム(データが連続している場合)、または バケットソート と カウントソート をバケットのソートの実装として使用(データが離散的で均一に分散している場合) )。
おそらく、最善の方法は、増分が小さい場合に独自のインデックス/マッピングファイルを作成することです。
ビッグキューとビッグアレイと呼ばれる抽象的な構造を構築して、メモリが限られた単一のマシンでビッグデータのソートと検索タスクを簡素化しました。基本的に、使用されるアルゴリズムは、前述のアルゴリズム(外部マージソート)に似ています。
1台のマシンで128GBのデータ(各アイテム100バイト)を9時間で並べ替えることができ、並べ替えたデータをほとんど時間なくバイナリ検索できます。
ここ は、私のオープンソースの大きなキューと大きな配列構造を使用してビッグデータを検索する方法についての投稿です。