次の確定的(コンパレータなし)アルゴリズムは、入力タプルに対して機能します。(a1,…,an)
- コンパレーターを使用して、Fisher-Yatesのシャッフルを静的なペア(たとえば)とコインフリップ(受け入れ拒否のサンプリングを行う)で行います。コンパレータが最初に1を出力する場合は、それを反転して使用して、確定的なケースで無限の拒否ループを回避します。a1<a21
- (オプションのスピードアップ:シングルペアを回試行します。nは長さまたは入力です。出力のいずれか2つが異なる場合は、(1)で取得した順列を返します)nn
- マージソートを使用して配列をソートします。
決定論的順序関係をコンパレーターとして指定すると、Fisher-YatesシャッフルはO(n )で最大O(log n )非ランダム「ランダムビット」(例えば、コンパレーターへの呼び出し)を使用して実行されるため、このアルゴリズムは配列を時間でソートします。 )各ステップでマージソートは同じ漸近的な複雑さを持っています。この場合、(1)の結果はまったく役に立ちませんが、その後に実際の種類が続くため、害はありません。O(nlogn)O(n)O(logn)
コンパレータとして実際のコインフリップが与えられた場合(1)は各置換について等しい確率で配列を置換し、本当に(3)を実行する必要がある場合((2)を省略したか(2)ランダム性を決定できなかった)、これはノーです結果の分布は、(1)のためにすべての順列間で均一に分散される入力の順序にのみ依存するため、アルゴリズム全体の結果も均一に分散されるため、害があります。各受け入れ拒否サンプリングを繰り返す必要がある回数は、幾何学的に分布しています(確率< 1で拒否)したがって、期待値は2未満です。各繰り返しの使用高々ログのnビット、ランタイム分析は、決定論場合とほぼ同じですが、我々は唯一の取得ので、予想されるランタイムのOを(NログN)、nontermination(終了のみの可能性はほぼ確実に)。<12<2lognO(nlogn)
Joeが指摘したように:(1)の最初のビットのテストが気に入らない場合は、(3)を実行してから(1)を実行し常に0であるn < a 1を使用します。確定的なケース。さらに、乱数の上限が同じ順列を生成するため、ループの範囲の上限から乱数を減算する必要があります。ただし、身代金の場合は常にシャッフルする必要があるため、(2)は禁止されていることに注意してください。an<a10
(1)と(3)のコンパレータへの同じ呼び出しを使用することもできますが、結果が均一に分散されていることを証明することは、可能であれば、少なくともかなり困難です。
次のアルゴリズムには、シャッフルおよびソートする明確なフェーズはありませんが、漸近的に低速です。基本的には、
バイナリ検索を使用した挿入ソートです。私が使用する
= (1、... 、nで)入力と示すために
、B 、K = (BのK 、1、... 、bはK 、kは)後の結果を示すために
Kラウンド番目:
a=(a1,…,an)bk=(bk,1,…,bk,k)k
- 設定しb1,1=a1
- もし2 < 1、次いでB 2 = (2、1)および(C 、D ):= (2 、1 )他のB 2 = (1、2)及び(C 、D ):= (1 、2 )。どちらの場合でも、d <a2<a1b2=(a2,a1)(c,d):=(2,1)b2=(a1,a2)(c,d):=(1,2)は、ランダムでないコンパレーターでは常に 0(つまりfalse)になります。ad<ac0
- 得るためにためのK ≥ 3は得B K - 1最初に。bkk≥3bk−1
- ましょ及びK ' = 2 、L、すなわちkは'の最小パワーである2より小さくないK。l=⌈log2k⌉k′=2lk′2k
- してみましょう。すべてのためにJ ∈ { 1 、... 、L }せ
iはJ = { I 、J - 1 + 2 L - J I J - 1 + 2 L - J > K - 1 ∧ D < A 、C 、I 、J - 1 I J − 1 + 2 l −i0=0j∈{1,…,l}
ij=⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪ij−1+2l−jij−1ij−1+2l−jij−1ij−1+2l−j>k−1∧ad<acij−1+2l−j>k−1∧¬(ad<ac)ij−1+2l−j≤k−1∧bk−1,ij−1+2l−j<akij−1+2l−j≤k−1∧¬(bk−1,ij−1+2l−j<ak)
- il>kbk=(bk−1,1,…,bk−1,il−1,ak,bk−1,il,…,bk−1,k−1)
- bn
k−1k
配列を使用すると要素を任意の位置に挿入するとコストがかかり、リストを使用するとバイナリ検索に線形時間が必要になるため、このアルゴリズムは、Fisher-Yatesのシャッフルとマージソートに比べて両方のモードで非効率的です。しかし、おそらく、同様の方法でヒープソートまたはツリーソートを変更すると、アルゴリズムが高速になる可能性があります。