リストの反転数を数えるだけです。
反転
型の要素のシーケンスの反転はT
、いくつかの順序に従った順序で表示されて配列要素のペアで<
のセットでT
の。
ウィキペディアから:
正式にはA(1), A(2), ..., A(n)
、一連のn
数値とします。
場合i < j
とA(i) > A(j)
、そのペアが(i,j)
呼び出された反転のA
。
シーケンスの反転番号は、その並べ替えの一般的な指標の1つです。
正式には、反転数は反転数として定義されます。つまり、
これらの定義をより明確にするために、シーケンスの例を検討してください9, 5, 7, 6
。このシーケンスには、反転 (0,1), (0,2), (0,3), (2,3)
と反転番号があり 4
ます。
0
との間の値が必要な場合は1
、反転数をで除算できますN choose 2
。
リストがどのようにソートされているかについてこのスコアを計算するアルゴリズムを実際に作成するには、2つの方法があります。
アプローチ1(確定的)
実行中に修正する反転の数を追跡するために、お気に入りのソートアルゴリズムを変更します。これは重要なことではなく、選択した並べ替えアルゴリズムに応じて実装が異なりますが、最初に行った並べ替えアルゴリズムよりも(複雑さの点で)費用がかからないアルゴリズムになります。
この方法をとる場合は、「スワップ」を数えるほど簡単ではないことに注意してください。たとえば、Mergesortは最悪のケースですがO(N log N)
、降順で並べ替えられたリストで実行すると、すべてのN choose 2
反転が修正されます。それO(N^2)
はO(N log N)
操作で修正された反転です。したがって、一部の操作では、必然的に一度に複数の反転を修正する必要があります。実装には注意が必要です。注:これはO(N log N)
複雑な方法でも実行できますが、注意が必要です。
関連:順列の「反転」数の計算
アプローチ2(確率的)
- ランダムにサンプルのペア
(i,j)
、ここでi != j
- 各ペアについて、
list[min(i,j)] < list[max(i,j)]
(0または1)かどうかを決定します
- これらの比較の平均を計算し、次に正規化します
N choose 2
正確さの要件がない限り、私は個人的に確率論的アプローチを採用します。
(降順で並べ替え)から(昇順で並べ替えz'
)の間の値()が本当に必要な場合は、この数式を使用して、(昇順で並べ替え)と(降順で並べ替え)の間の()の上にある値をこの範囲に簡単にマッピングできます:-1
1
z
0
1
z' = -2 * z + 1