その他:古典的なアルゴリズムの乱数生成

0まえがき

tkinterライブラリのブログ(python notes:ビジュアルインターフェイスの作成の試み)は本当に書かれています。私は疲れています。実際、物事は難しくありませんが、多すぎます。それから、信頼できる公式文書は見つかりませんでした。最初は気分が悪くなりました。コンポーネントアプリケーションを作成していない場合は、ソースコードを確認してから、自分でコードを作成する必要があり、半分疲れています。

残念ながら、休憩して短い記事を書いてみましょう。それは仕事と休息の組み合わせです。

そこで、ここで、もう1つの古典的なアルゴリズムの問​​題である乱数生成の問題を見てみましょう。

1.問題の説明

ほとんどの人、特に乱数生成の古典的なアルゴリズムの質問について知っていると思います。特に、リートコードをブラッシングしたり、インタビューの経験がある人は、乱数ジェネレーターを与えて、別の範囲内で乱数を生成するだけです。

典型的な例は、rand7世代の使用ですrand10

そこで、ここでは、rand7世代rand10を例にとり、実現のアイデアを議論し、ある程度拡大していきます。

2.ソリューション1

1.アルゴリズムのアイデア

明らかに、範囲の広い乱数ジェネレーターを使用して範囲の狭い乱数ジェネレーターを生成する場合、それは非常に簡単です。たとえば、次の方法を使用してrand7()生成rand5()できます

def rand5():
    while True:
        seed = rand7()
        if seed <= 5:
            return seed

このようにして、1から5までの乱数ジェネレーターが完成することは明らかです。もちろん、効率はわずかに低下します。各乱数生成に必要なrand7()予想実行回数は1.4倍です。その時点で、全体として、この値が2を超えることは決してないため、実際、小さな問題を生成することは常に簡単です。

そして、実際には、小世代と大世代の問題については、大世代と小世代の問題に分解して問題を解決することもできます。

10 = 2×510 = 2 \ times 5なので、より簡単な考え方は次のとおりです。1 0=2××したがって、 5を使用してrand7()2つのrand5()ジェネレーターを作成し、それらを1つのrand10()ジェネレーターにマージできます

2.コードの実装

Pythonコードは次のとおりです。

def rand2():
    while True:
        seed = rand7()
        if seed != 7:
            return seed % 2 + 1

def rand10():
    return 5 * (rand2()-1) + rand5()

その中で、rand5()すでに上記の内容で紹介しているので、ここでは詳しく説明しません。

3.アルゴリズム分析

全体としてrand7()各乱数生成に必要な予想呼び出し数は7/6 + 7 /5≃2.577/ 6 + 7/5 \ simeq2.57であることがわかります。7 / 6+7 / 52 5 7

ただし、上記のアルゴリズムの制限も非常に明白です。ターゲット範囲は小数点以下2桁の積に因数分解する必要があります。そうしないと、上記のアルゴリズムをそのままコピーできません。たとえばrand11()、分解によって解決することはできません。

ただし、この問題は解決できないわけではなく、少し調整するだけで上記と同じアイデアを解決できます。

3.ソリューション2

1.アルゴリズムのアイデア

上記のアルゴリズムで最も重要な点は、問題を大きな問題を生成する小さな問題から小さな問題を生成する大きな問題に変換することであることがわかります。

具体的な実装に関しては、上記のアイデアは大規模モデルと小規模モデルを採用しており、ターゲット範囲は同じ確率でいくつかのサブ範囲に分解され、現在の乱数生成でカバーして問題を解決できます。

ただし、上記の方法は、分割プロセスを等しい確率で複数のサブ範囲に分割する必要があるという事実によって制限されます。つまり、因数分解して分割可能である必要がありますが、ターゲット範囲が素数であるか、乱数がある場合現在の因子数ジェネレーターより大きい数の場合、上記のアイデアは無効になります。

ただし、ターゲット範囲を縮小する代わりに、上記の分割の考え方を逆にすることはできますが、現在の乱数ジェネレーターを同じ比率で拡大して、ターゲット範囲をカバーできるようにします。

拡大する方法は、k-aryメソッドを使用してk倍連続的に拡大することです。これにより、新しい範囲のすべての値を同じ確率でカバーできます。

2.コードの実装

Pythonコードは次のとおりです。

def rand10():
    while True:
        seed = (rand7()-1) * 7 + rand7()
        if seed <= 40:
            return seed % 10 + 1

3.アルゴリズム分析

同様に、同じ分析を得ることができます。上記のアルゴリズムの期待値2×(49/40)= 2.45 2 \ times(49/40)= 2.452××4 9 / 4 0 =2 4 5

このようにして、問題を制限なしにあらゆる状況に拡張できることがわかります。

4.まとめ

要約すると、古典的なアルゴリズムの問​​題、つまり乱数生成問題への答えを示し、それをある程度拡張して、任意の2つの乱数を相互に変換する問題に拡張します。具体的には、分解することができます。小さな問題の大きな問題と大きな問題の場合。

その中で、大きなものと小さなものについては、実際には非常に明白であるため、詳細には説明しませんでした。

小さな問題から大きな問題まで、コア処理のアイデアは実際にそれらを大きな問題から小さな問題に変換することです。具体的には、ターゲット範囲の分解と既存の世代の拡張という2つの一般的な実装方法を示します。方法の範囲。

おすすめ

転載: blog.csdn.net/codename_cys/article/details/112074196