Fisher-Yates Shuffleアルゴリズムの複雑さ


15

この質問は、特定の配列のランダムシャッフルを返すFisher-Yatesアルゴリズムに関するものです。Wikipediaのページには、その複雑さはO(n)があると言うが、私はそれが(N Nログ)Oだと思います。

各反復iで、ランダムな整数が1〜iの間で選択されます。単純に整数をメモリに書き込むことはO(log i)であり、反復がn回あるため、合計は

O(log 1)+ O(log 2)+ ... + O(log n)= O(n log n)

ナイーブアルゴリズムの方が優れているわけではありません。ここに何かが足りませんか?

注:単純なアルゴリズムでは、各要素に間隔(0,1)の乱数を割り当て、割り当てられた番号に関して配列を並べ替えます。

回答:


24

ここでは、ほとんどのアルゴリズムの動作と同様に、ビット番号の読み取りと書き込みのコストは定数であると想定されていると思います。あなたが夢中になってPとPSPACEを誤って崩壊させない限り、それは小さな罪です。Oログn


4
それは確かに「小さな罪」ですが、これが明示的に言及されていないのはTCS教育学の大きな罪だと思います!すべてのCS学生は自分でこれを発見し、誰もがこれを知っているが誰もそれについて話さないと言われるまで、何か大きな問題があると考えます。また、誰かがO(log n)モデルを悪用してOmega(n ^ 3)と推測される有名な問題のサブキュービック時間アルゴリズムを提供したとき、数年前に大騒ぎはありませんでしたか?それは解決されましたか?
ランダムウォーカー

2
私はあなたが言及している大騒ぎを知りません。それに言及しないことに関しては、あなたは間違いなく正しい。ジェフ・エリクソンの投稿を最初に読んだ後、キックのためだけにジオメトリクラスでP = PSPACEを証明することをポイントにします:)
Suresh Venkat

1
答えてくれてありがとう。こんなに大したことだとは知らなかった。リンクは良い読み物を提供します。
Tomer Vromen

1
結論:モデルは常に明示的にしてください。
ユッカスオメラ

2
ビット操作を一定時間にする主な理由は、(多項式時間で)O log n )-ビットオペランドのすべてのペアに対して、ほとんどの場合、一定時間のアクセスルックアップテーブルをプログラムできるからだと思います「最新の」計算モデル。それについて「罪深い」ことは何もありません...私にとって、この特性は一般性を失うことなく単純に仮定できる特性であると思います。OログnOログn
ライアンウィリアムズ

17

計算の標準モデルでは、O(log n)ビット整数の算術演算は一定時間で実行できると想定しています。これらの演算は通常、ハードウェアで処理されるためです。したがって、Fisher-Yatesアルゴリズムでは、「整数iをメモリに書き込む」にはO(1)時間しかかかりません。

もちろん、ビット演算の観点からアルゴリズムを分析することは完全に意味がありますが、ビットコストモデルは実際の動作をあまり予測しません。単純なループでさえ、for i = 1 to n: print(i)O(n log n)ビット操作が必要です。


ループの良い点。それに気づいたことはありません...
トマーヴロメン

8

これは、「[Fisher-Yatesアルゴリズム]は単純なアルゴリズムよりも良くありません。ここに何か足りないのですか?」あなたは質問で尋ねました。

実数を使用する「単純な」アルゴリズムでは、何ビットの精度を使用しますか?(Fisher-Yatesで行っているように)ビットの複雑さをカウントしていて、アルゴリズムが実数にk個のランダムビットを使用している場合、2つのk-を比較するので、実行時間はΩ(kn log n)になります。ビット実数はΩ(k)時間かかります。ただし、2つの要素が同じ実数にマッピングされないように、kは少なくともΩ(log n)である必要があります。つまり、アルゴリズムはΩ(n log 2 n)時間かかります。これはFisher-Yatesシャッフルよりも遅いログnの係数。

算術演算と比較演算のを数えて、それらのビットの複雑さを無視している場合、Fisher-YatesはΘ(n)であり、アルゴリズムはΘ(n log n)であり、log nの係数はまだ離れています。


「ナイーブ」アルゴリズムには暗黙のkがあったと思われました。
TomerVromen

1
「単純な」アルゴリズムは、次のように線形時間できれいに実装できます。各要素に1〜n ^ 3のランダムな整数を割り当て、基数ソートを使用してO(n)時間で数値をソートします。(高い確率で、2つの要素が同じ乱数を取得することはありません。重複がある場合は、それらを再帰的にシャッフルします。)
ジェフ

@JeffE:ありがとう!それはとてもきれいで、Fisher-Yatesと同じ複雑さを持っています。これを投稿した後、私は実際に「単純な」アルゴリズムは悪くないはずだと感じていました... n kビットの数値はO(nklog n)を必要とせずにO(nk)でソートできるという事実を見逃しました。しかし、定数ではKnuth-Fisher-Yatesの方が優れていると思います。正確に(log n!)のランダムビット(1からn、次に1からn-1などのランダムな整数)が必要です。 3n log n)、一定の追加メモリのみでインプレースで実行できます。
シュリーバツァー

6

この問題の整数について特別なことはありません。

たとえば、ハッシュ関数がそのハッシュを計算するために値全体を読み取る必要がある場合、ハッシュテーブル(任意の種類の値を格納する)はアクセスするO(1)時間ではありません。n個の一意の要素は、表現がどれほど巧妙であっても、平均でそれぞれnビットの対数ログを必要とします。したがって、入力全体を読み取るハッシュ関数は、少なくとも計算に時間がかかります。実際には、赤黒木よりも高速ですが、漸近的には良くありません。

randomwalkerが参照した大騒ぎは、ここで説明されているPOPL 2008の論文(http://portal.acm.org/citation.cfm?doid=1328438.1328460)に関するものでした:http : //blog.computationalcomplexity.org/2009/05/shaving- logs-with-unit-cost.html

その投稿では、Lance Fortnowが学生として、2つの要素のすべてのlog nビットを読み取って比較する必要がある場合、並べ替えにn log ^ 2 n時間を要することを不満に思う方法について説明しています。


ブログ投稿の著者を取得しません。彼は、ソートは実際にはO(n log ^ 2 n)であると不満を述べていますが、その後、紙は堅固であると言いますか?
トマーヴロメン

この論文は、算術演算が単位時間を要するモデルがあり、そのモデルでは論文のアルゴリズムがo(n ^ 3)演算を達成する最初のモデルであるという点で堅実です(つまり、偽ではありません)。
デイブDoty

O(n log ^ 2 n)の異議はありません。ビットの観点からすると、入力自体のサイズはO(n log n)であるためです。ところで、サイドノートとして、複雑さのブログにコメントの品質レベルが....その後、そんなに高かった
arnab

4

ウィキペディアのページには、その複雑さはO(n)であると書かれていますが、O(n log n)であると思います。

実際、O(n log n)は、ソートがO(n log n)であるモデルのこの問題の下限です。すべての順列が等しく発生する可能性がある場合、ランダムストリームから順列への関数としてのアルゴリズムは全射でなければなりません。あります!順列なので、決定木モデルのようなものには、少なくともO(log n!)= O(n log n)の長さの分岐があります。

この最悪の場合の下限は、すべての順列にゼロ以外の確率がある限り、順列の不均一なランダム生成に対して引き続き機能します。変化するのは平均的な複雑さです。決定木モデルの平均複雑度の下限は、分布のエントロピーのようです。二分決定木では、この下限は、分布が二項の場合にのみ正確に達成できます。極端なケースは、1つの区別された順列が確率を持つ場合です。1ϵそして、他のすべては等しい確率を持っています。次に、平均複雑度の下限はOϵ


3

TCSでは、特に明記しない限り、チューリングマシンの複雑さを考慮します。これは理論的な目的には適していますが、異なるマシンモデル(つまり、有限近似)をハードウェアに実装するため、結果は実際にはあまり役に立ちません。したがって、これらのモデルの複雑さを尋ねるのは実行可能な質問です。たとえば、通常、レジスタマシン(実際のCPUと同様)は一定の時間で2つのレジスタでアトミック操作を実行できると想定しています。これがここで採用されている可能性があります。

要するに、あなたはTMの観点から、あなたはRMの観点から記事の著者を考えます。あなたは両方とも正しいです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.