この質問を読んだ後、私は疑問に思い始めました:元のリストを変更またはコピーしないシャッフルアルゴリズムを持つことは可能ですか?
明確にするために:
オブジェクトのリストが与えられたと想像してください。リストのサイズは任意ですが、かなり大きいと仮定します (たとえば、10,000,000 アイテム)。リストの項目をランダムな順序で印刷する必要があり、できるだけ速くそれを行う必要があります。ただし、次のことを行うべきではありません。
- 元のリストは非常に大きく、コピーすると大量のメモリが浪費されるため (おそらく使用可能な RAM の制限に達する)、元のリストをコピーします。
- 元のリストは何らかの方法でソートされており、後で他の部分がソートされることに依存するため、元のリストを変更します。
- 繰り返しになりますが、リストは非常に大きく、コピーには多くの時間とメモリが必要になるため、インデックス リストを作成します。(明確化: これは、元のリストと同じ数の要素を持つ他のリストを意味します)。
これは可能ですか?
追加:より明確化。
- すべての順列が同じ確率で真のランダムな方法でリストをシャッフルする必要があります (もちろん、最初に適切な Rand() 関数があると仮定します)。
- ポインターのリスト、インデックスのリスト、または元のリストと同じ数の要素を持つその他のリストを作成するという提案は、元の質問によって非効率的であると明示的に見なされます。必要に応じて追加のリストを作成できますが、元のリストよりも桁違いに小さいものにする必要があります。
- 元のリストは配列のようなもので、O(1) のインデックスによって任意の項目を取得できます。(したがって、目的のアイテムに到達するためにリストを反復処理する必要がある、二重にリンクされたリストのものはありません。)
追加 2 : OK、次のように言いましょう: 1 TB の HDD があり、それぞれ 512 バイト (単一セクター) のデータ項目でいっぱいです。すべてのアイテムをシャッフルしながら、このすべてのデータを別の 1TB HDD にコピーします。これをできるだけ速く実行したい (データの単一パスなど)。512MB の RAM が利用可能であり、スワップは必要ありません。(これは理論上のシナリオです。実際にはこのようなものはありません。完璧なアルゴリズムを見つけたいだけです。)