置換をその場で適用する複雑さ


27

驚いたことに、私はこれに関する論文を見つけることができませんでした-おそらく間違ったキーワードを検索しました。

それで、私たちは何かの配列とそのインデックスに関数を持っています。は順列です。fff

可能な限りと近いメモリとランタイムでに従って配列を並べ替えるにはどうすればよいですか?O 1 O n fO(1)O(n)

このタスクが簡単になった場合、追加の条件はありますか?たとえば、関数がの逆関数であることを明示的に知っているは?fgf

私はサイクルに続き、各インデックスのサイクルを横断してそのサイクルで最小かどうかをチェックするアルゴリズムを知っていますが、再び、最悪の場合の実行時間を持っていますが、平均的にはより良く動作するようです...O(n2)


簡単な観察:アイテムの配列だけでなく、関数fを含む配列も書き込み可能な場合、O(1)整数レジスタ(長さO( log n)ビット)と、各サイクルをたどるだけで1つのアイテムの追加スペース。しかし、関数fが読み取り専用ストレージで指定されている場合(またはfがオラクルとしてのみ指定されている場合)、これは機能しません。これはこの質問の前提だと思います。
伊藤剛

23
フィッチ等。1995:時間、スペース。また、いくつかの特殊なケースについても説明します。O log n O(nlogn)O(logn)
ユッカスオメラ

はい、私たちはオラクルとしてfを持っていると仮定しています。
jkff

3
@JukkaSuomela、あなたはそれを答えにするべきです。また、が任意の順列であることを考慮すると、単純なエントロピー引数は空間および/または時間を生成するため、時間空間でよりもうまくやれるとしたら驚くでしょう。O n log n O n log n fO(nlogn)O(nlogn)
user834

回答:


4

オプション0:インプレース順列(1995)by Faith E. Fich、J. Ian Munro、Patricio V. Poblete time spaceO log 2 n O(nlogn)O(log2n)

オプション1:順列を簡潔なデータ構造に圧縮してチートします。Munrohttp://www.itu.dk/people/ssrao/icalp03-a.pdfを参照して ください

オプション2:素数サイクル分解を使用してpermを簡潔に保存し、その余分なスペースを使用してチートするhttp://oeis.org/A186202

オプション3:操作された各サイクルの最大インデックスを追跡します。反復ごとに、最大の非表示インデックスを使用して、サイクル内のすべてを1つずつ移動します。表示されたインデックスにヒットした場合、サイクルは既に操作されているため、すべての作業を取り消します。時間、スペース。O サイクルlog n O(n2)O(#cycleslogn)

オプション4:操作された各サイクルの最大インデックスを追跡しますが、異なるサイクル長のバッチでのみ実行します。反復ごとに、最大の非表示インデックスを使用して、そのサイクル内のすべてを1つずつ移動します。見かけのインデックスにヒットした場合、サイクルは既に操作されているため、すべての作業を取り消します。時間、スペース。O サイクル_ with _ 同じ_ サイズlog n O(n2distinct_cycle_lengths)O((#cycles_with_same_size)logn)

オプション5:Munroによるオプション0と同じ用紙から、場合、がそのサイクルの最大インデックスである場合、サイクルを回転します。時間とスペース。p i i O n 2O log n i=1..np(i)iO(n2)O(logn)


圧縮方法は一般にスペースを節約しない可能性があり。順列を格納する最悪の場合のスペースはです。3、4、5は一般に、OPがすでに知っているソリューション、またはFich、Munro、Pobleteによるソリューションと同じくらい悪いように見えます。そして、その解決策はすでに@Jukkaによって指摘されていますnlogn
Sasho Nikolov

#5は、log(n)係数により#0より少ないスペースを使用します。
チャドブリューベーカー14年

1

順列のサイクル表現を使用する場合、現在順列されている項目を格納するために1つの追加の配列要素が必要であり、より悪いO(N)操作でサイクルを実行できます。


2
jkffは既にサイクル追従アルゴリズムを知っていると述べたため、順列自体をブラックボックス(に近い)として扱うことを明確に望んでいます。彼が質問で指摘しているように、(ほぼ)ブラックボックスからサイクル表現への変換にはO(n ^ 2)時間かかる可能性があります。
ジョシュアグロチョウ

ブラックボックスp(i)は問題ありません。iに戻るまで、サイクルを繰り返します。問題は、更新されたアイテムのリストを保存するコロモゴロフの複雑さの1つであるため、それらを複数回循環させません。マンロはそれに限界があります。itu.dk/people/ssrao/icalp03-a.pdf
チャドブリューベーカー14年

-2

N個のアイテムの順列は、N-1個以下の交換を使用して他の順列に変換できます。このメソッドの最悪の場合、オラクルF()へのO(n ^ 2)呼び出しが必要になる場合があります。最小の位置から開始します。現在スワップしている位置をxとします。

F(x)> = xの場合、位置xとF(x)を交換します。それ以外の場合、位置F(x)にあったアイテムが現在リスト内のどこにあるかを見つけなければなりません。次の反復でこれを行うことができます。y = F(x)としましょう。y> = x:y = F(y):End Doまで実行します。次に、位置xとyを交換します。


3
OPはすでに、時間でそれを行う方法を知っていると述べました。O(n2)
ユッカスオメラ

ごめんなさい。このグループは初めてです。私はこの方法がシンプルだから気に入っています。効率よりも単純さのほうが速い場合があります。O(n)ステップを必要とする別の方法を知っていますが、O(nlogn)スペースが必要です。
ラッセルイースターリー

1
ラッセル、O(n log n)空間の割り当てとゼロ化もすでにO(n log n)ですが、他の方向を意味していましたか?
jkff

あなたは実際に割り当てられたスペースがありません。基本的な考え方は、F(x)> xの場合、アイテムをxの位置に置いた場所を覚えておく必要があるということです。本当に大きなnの場合、データベースを使用し、アイテムxが移動した場所の記録を保持します。xは最終的な場所に到達したときにレコードを削除できます。
ラッセルイースターリー

1
しかし、なぜあなたはO(n log n)スペースが必要だと言っているのですか?
-jkff

-2

この方法はFの逆を使用し、nビットのストレージを必要とします。xが元の配列内のアイテムの位置である場合、G(x)をソートされた配列内のアイテムの位置とします。Bをnビット配列とします。Bのnビットすべてを0に設定します。

FOR x = 1 to n-1:IF B(x)== 0 THEN:y = G(x):DO UNTIL x == y:Swap position x and y:B(y)= 1:y = G( y):ループ:ENDIF:次のX

このメソッドは、現在位置xにあるアイテムをアイテムの最終位置にスワップし続けます。正しいアイテムが位置xにスワップされると、内側のループが終了します。各スワップは少なくとも1つのアイテムをアイテムの最終位置に移動するため、内側のDoループは実行中にn-1回を超えて実行できません。この方法はO(n)時間と空間だと思います。


2
論文を見ましたか?ここにリストする2つのアルゴリズムは、2つの「明白な」アルゴリズムです。この論文には、時空間のトレードオフが異なる明確なものはなく、特にスペースがはるかに少ない。
ユヴァルフィルマス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.