シャッフルアルゴリズムの正しさを証明する方法は?


24

アイテムのリストをランダムな順序で作成する方法は2つありますが、それらが同等に公平であるかどうかを判断したいです

私が使用する最初の方法は、要素のリスト全体を作成してから、シャッフルを実行することです(Fisher-Yatesシャッフルなど)。2番目の方法は、挿入のたびにリストをシャッフルする反復的な方法です。擬似コードでは、挿入関数は次のとおりです。

insert( list, item )
    list.append( item )
    swap( list.random_item, list.last_item )

この特定のシャッフルの公平性を示す方法に興味があります。このアルゴリズムが使用される場合、このアルゴリズムの利点は、わずかに不公平であっても大丈夫です。決定するには、その公平性を評価する方法が必要です。

私の最初のアイデアは、この方法で可能な合計順列と、最終的な長さのセットで可能な合計順列を計算する必要があるということです。ただし、このアルゴリズムから生じる順列の計算方法については少し迷っています。また、これが最良の、または最も簡単なアプローチであると確信することもできません。


アルゴリズムの多数の実行で統計サンプルを実行し、それを期待値と比較したり、何らかのランダム性テストを実行したりできます。
デイブクラーク

配布をテストします。均一に分布しているか、歪んでいますか。ただし、何度も何度も実行する必要があると思います。
デイブクラーク

私はそれをどうするか明確ではありません。それは私が求めているコンテンツのランダム性ではなく、順序のランダム性です。どのアプローチで注文の分布を測定できますか?
edA-qa mort-ora-y

ああ、馬鹿げた、固定入力セットを使用し、各要素の最終位置を使用して分布を取得することができます。それでも、私は実際にはシミュレーションよりも論理的な証明を好むでしょう。
edA-qa mort-ora-y

@ edA-qamort-ora-y:あなたの願いは私の命令です。;)
ラファエル

回答:


22

まず、2つの明白な、しかし重要な仮定を立てましょう。

  1. _.random_item 最後の位置を選択できます。
  2. _.random_item確率ですべての位置を選択します1n+1

アルゴリズムの正確性を証明するために、ここで使用されるものと同様の帰納的引数が必要です

  • シングルトンリストの場合、可能性は1つしかないため、一様に選択されます。
  • 要素を持つリストが(すべての順列から)一様に選択されたと仮定すると、手法によって得られたn + 1 個の要素を持つリストが一様に選択されることを示します。nn+1

これから、証明は間違っています。正しい証拠については、以下をご覧ください。間違いと次の手順(どちらも適切)の両方が教育的である可能性があるため、ここにこれを残します。

順列全体について議論するのは苦痛なので、保持しなければならないローカル(つまり要素ごとの)プロパティを導出すると便利です。すべての要素が各位置にある確率が等しい場合、順列が一様に選択されることに注意してください。

πPermnPr(L=π)=1n!i=1n j=1nPr(Li=j)=1n(1)

ここで、そして、表記上の単純さのために、リストに{ 1 n }を挿入すると仮定します。n=|L|{1,,n}

ここで、番目の要素を挿入するときのテクニックの動作を見てみましょう。スワップ後の3つのケースを考慮する必要があります。n+1

  1. スワップされていないリスト内の要素の一つ、すなわち、及びJ { 1 ... N }i{1,,n}j{1n}
  2. スワップリスト内の要素の一つ、すなわち、J { 1 ... N }=n+1j{1n}
  3. 新しい要素、すなわち及びJ = N + 1{1n+1}j=n+1

各ケースについて、要素が位置iにある確率を計算します。すべてが1であることが判明する必要がありますj1により十分です)。ましょう、Pnは=11n+11は、最初のn個の要素の1つが古いリストの任意の位置にある確率(帰納仮説)、およびps=1pn=1nn(仮定1、2)によって選択される任意の位置の確率。n個の要素を含むリストのスワップ位置とスワップ位置の選択は独立したイベントであることに注意してください。ps=1n+1random_itemn

Pr(Li=j,i swapped)=Pr(Li=j)Pr(i swapped)=pnps

。計算のために。i,j{1,,n}

  1. 古い要素のみを考慮します。そのような要素jは、最後の挿入の前に存在し、スワップ位置としてiが選択されていない場合にのみ、位置iにあります。 njii

    Pr(Li=j)=pn(1ps)=1nnn+1=1n+1

  2. ここでは、古い要素の1つが最後の位置にスワップされると考えます。要素は古い位置のいずれかにあった可能性があるため、jが位置iにあり、iがスワップ位置として選択されているすべての確率を合計します。jjii

    Pr(Ln+1=j)=i=1npnps=i=1n1n1n+1=1n+1

  3. 新しい要素は、iがスワップ位置として選択されている場合にのみ、位置で終了します。ii

    Pr(Li=j)=ps=1n+1

すべてうまくいきましたが、挿入戦略は確かに均一性を維持します。誘導の力により、それはあなたのアルゴリズムが均一に分散した順列を作成することを証明します。

警告の言葉:挿入された要素がペアごとに異なるものでない場合、この証明は破綻します。なぜなら、最初の方程式はもはや有効ではないからです。しかし、あなたのアルゴリズムはまだ有効です。重複するすべての順列は、同じ数のランダム実行によって生成されます。これを証明するには、重複をマーク(つまり、区別可能)し、上記の証明を実行して、マークを(実質的に)削除します。最後のステップは、同じサイズの順列のセットを同じものにまとめます。


スティーブンはコメントで正しく述べたように、上記証明は根本的に欠陥があるを保持しません。左側ではなく右側を満たしている順列のセットで分布を構築できます¹。(1)

したがって、順列の確率を処理する必要がありますが、結局はそれほど悪くないことがわかります。random_itemポストの冒頭で概説した仮定と帰納的構造はそのまま残り、そこから継続します。ましょう後に示すリスト{ 1 ... K }に挿入されているが。L(k){1,,k}

ましょうの任意の順列{ 1 ... N + 1 }。それは書くことができるユニークとしてπPermn+1{1,,n+1}

π=(π(1),π(2),,π(i1),n+1,π(i+1),,π(n),π(i))

以下のためのいくつかのI { 1 ... N + 1 }。帰納仮説により、Pr L n = π = 1πPermni{1,,n+1}。さらに、確率1で位置iを選択しますPr(L(n)=π)=1n!random_itemi仮定による n + 1πiのランダムな選択は(確率的に)独立しているため、1n+1πi

Pr(L(n+1)=π)=Pr(L(n)=π)Pr(i swapped)=1(n+1)!

見せなければなりませんでした。誘導の力により、それはあなたのアルゴリズムが均一に分散した順列を作成することを証明します。


  1. 例えば、内のすべての順列を割り当てる確率1{(1,2,3,4),(2,3,4,1),(3,4,1,2),(4,1,2,3)}および他のすべて0。すべての順列にゼロ以外の確率を割り当てる例もあります。140

4
「すべての要素が各位置にある確率が等しい場合、順列が一様に選択されることに注意してください」-これは真実ではありません。たとえば、4つの要素の4つの順列のセット{(1、2、3、4)、(2、3、4、1)、(3、4、1、2)、(4、1、2、3 )}は制約を満たしますが、明らかにすべての順列のセットではありません。残念ながら、均一性を決定するのに十分なローカル条件がないため、順列のグローバルプロパティを使用する必要があります。
スティーブンスタドニッキー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.