質問

OK、私はランダムな画像セレクターとキュー システムに取り組んできました (同じ画像が頻繁に表示されないようにするため)。

すべてが順調に進んでいた (私の下手なコードがそうする限り) それまで ランダムビットに到達しました。テストしてみたいと思ったのですが、どうやってテストするのですか?ありません Debug.Assert(i.IsRandom) (悲しいことに) :D

そこで、お茶で少し考えて考えた結果、次のようなことを思いつきました。皆さんのご意見を聞かせていただけますか?

  • 基本的には知っていましたが、 ランダム ビットが問題だったので、それをデリゲートに取り込みました(その後、オブジェクトのコンストラクターに渡されます)。
  • 次に、次のロジックとほぼ同じロジックを実行するクラスを作成しました。 ライブ コードは保存されますが、プライベート変数で選択された値は記憶されます。
  • 次に、そのデリゲートをライブクラスに投げて、それに対してテストしました。

つまり

Debug.Assert(myObj.RndVal == RndIntTester.ValuePassed);

しかし、私はこう思わずにはいられませんでした。 私は時間を無駄にしていたでしょうか? それを何度も繰り返し実行して、いつでも転倒するかどうかなどを確認しました。

私がこれで時間を無駄にしていたと思いますか?あるいは、次のようにすることもできたでしょうか。

Awesome Random Number Generator

ゲートキラーの答え これを思い出しました:

Dilbert Random

明確にするための更新

  • 基本的に、Y サイズのプールから X 回以上同じ結果を見たくないことを付け加えておきます。
  • テスト コンテナを追加すると、基本的に、以前に選択した画像のいずれかが「ランダムに」選択されたかどうかを確認できるようになりました。
  • 技術的には、ここでテストされているのはRNGではなく(そのコードを書いたことがないため)、私が期待しているという事実だと思います ランダム 限られたプールから得られた結果を追跡したいと考えています。
役に立ちましたか?

解決

要件からテストします。「同じ画像を頻繁に見ることがなくなります」

100枚の画像を要求します。画像を頻繁に見すぎましたか?

他のヒント

便利なリストがあります 統計的ランダム性 テストと 関連研究 ウィキペディアで。これらのほとんどについては、ソースが本当にランダムであるかどうかは確信が持てないことに注意してください。簡単に予測できる可能性のあるいくつかの方法を除外しただけです。

アイテムのセットが固定されており、それらをあまり頻繁に繰り返したくない場合は、コレクションをランダムにシャッフルします。そうすれば、同じ画像を 2 回続けて見ることがなくなり、トップ 20 のラジオを聞いているような気分になるでしょう。繰り返す前に、コレクションを完全に通過します。

Item[] foo = …
for (int idx = foo.size(); idx > 1; --idx) {
  /* Pick random number from half-open interval [0, idx) */
  int rnd = random(idx); 
  Item tmp = foo[idx - 1];
  foo[idx - 1] = foo[rnd];
  foo[rnd] = tmp;
}

一度に収集してシャッフルするにはアイテムが多すぎる場合 (リポジトリ内の数万のイメージ)、同じアプローチに分割統治を追加できます。画像のグループをシャッフルし、各グループをシャッフルします。

修正された問題ステートメントに適用できそうな少し異なるアプローチは、「イメージ セレクター」の実装で、最新の選択履歴を最大でもキューに保持することです。 Y 長さ。画像を返す前に、画像がキューにあるかどうかをテストします。 X すでに 1 回、合格した場合は、合格するものが見つかるまで、別の 1 つをランダムに選択します。

乱数発生器の品質のテストについて本当に知りたい場合は、統計の本を開く必要があります。

値が本当にランダムかどうかをテストすることは不可能です。できる限りのことは、テストを何度も実行して、適切な分布が得られたかどうかをテストすることですが、結果が本当にランダムである場合、これでも失敗する可能性が (非常に小さい) あります。

ホワイト ボックス テストを行っていて、ランダム シードがわかっている場合は、期待される結果を実際に計算できますが、RNG のランダム性をテストするには別のテストが必要になる場合があります。

乱数の生成は、偶然に残されるにはあまりにも重要です。-- ロバート R.ありがとう

心理的問題を解決するには:

明らかな繰り返しを防ぐ適切な方法は、完全なセットからランダムにいくつかのアイテムを選択し、重複を破棄することです。それらを再生してから、さらにいくつか選択してください。「いくつか」がどれくらいかは、演奏する速さとフルセットの大きさによって異なりますが、たとえば、「20」や「5 分」のうち大きい方の範囲内での繰り返しを避けるのは問題ないかもしれません。ユーザー テストを実行します。プログラマーとして、スライドショーにはうんざりするでしょう。あなたは良い被験者ではありません。

ランダム化コードをテストするには、次のように言います。

ステップ1:コードが生の乱数をドメイン内の選択肢にどのようにマッピングしなければならないかを指定し、コードが乱数生成器の出力を正しく使用していることを確認してください。ジェネレーターをモックしてこれをテストします (または、PRNG の場合は既知のテスト値をシードします)。

ステップ2:ジェネレーターが目的に対して十分にランダムであることを確認してください。ライブラリ関数を使用した場合は、ドキュメントを読んでこれを実行します。自分で書いた場合、その理由は何ですか?

ステップ 3 (上級統計学者のみ):ジェネレーターの出力のランダム性についていくつかの統計テストを実行します。テストで誤って失敗する確率がどのくらいかを必ず把握してください。

ランダム性と何かがあるかどうかの評価については書ける本が何冊もあります 表示されます ランダムになりますが、数学のページを保存しておきます。要するに、次を使用できます。 カイ二乗検定 一見「ランダム」な分布が期待どおりにどの程度適合しているかを判断する方法として。

Perl を使用している場合は、 統計::カイ二乗 大変な作業をしてくれるモジュールです。

ただし、画像が均一であることを確認したい場合は、 配布された, 、その場合、それらを本当にランダムにすることはおそらく望まないでしょう。代わりに、画像のリスト全体を取得し、そのリストをシャッフルし、「ランダムな」画像が必要なときはいつでもそこから項目を削除することをお勧めします。リストが空の場合は、リストを再構築し、再シャッフルし、繰り返します。

この手法は、一連の画像が与えられた場合、個々の画像はリストの繰り返しごとに複数回表示できないことを意味します。画像が均等に分散されることは避けられません。

ではごきげんよう、

ポール

なんと ランダム および同様の関数で得られるのは、関数を通じて生成された一連の数値である疑似乱数にすぎません。通常、その関数に最初の入力パラメータ (別名「入力パラメータ」) を与えます。「シード」)、最初の「乱数」を生成するために使用されます。その後、最後の各値がサイクルの次の反復の入力パラメーターとして使用されます。「擬似乱数発生器」に関する Wikipedia の記事を確認してください。そこには非常に優れた説明があります。

これらのアルゴリズムにはすべて次のような共通点があります。 何度か繰り返した後、シリーズが繰り返されます. 。これらは真の乱数ではなく、単に一連の数値であることに注意してください。 思われる ランダム。あるジェネレータを別のジェネレータよりも選択するには、次のことを自問する必要があります。何のためにそれが欲しいのですか?

ランダム性をどのようにテストしますか?確かにそれは可能です。そのためのテストはたくさんあります。最初の最も簡単な方法は、もちろん、擬似乱数ジェネレーターを膨大な回数実行し、各結果が表示される回数をコンパイルすることです。最終的には、各結果は (反復回数)/(考えられる結果の数) に非常に近い回数表示されるはずです。この標準偏差が大きいほど、ジェネレータの性能は悪くなります。

2 番目は次のとおりです。そのときどれくらいの乱数を使っていますか?2、3?それらをペア (または三つ子) にして、前の実験を繰り返します。非常に長い回数の反復の後、期待される各結果は少なくとも 1 回は表示されるはずです。また、各結果が表示される回数も期待値からそれほど離れていないはずです。一度に 1 つまたは 2 つを取得する場合は正常に機能するジェネレーターがいくつかありますが、3 つ以上取得すると見事に失敗します (RANDU はいますか?)。

他にも、より複雑なテストがあります。結果を対数スケールでプロットしたり、中央に円がある平面上にプロットして、プロットがどれだけその中に収まるかを数えたりするものもあります...ほとんどの場合、上記の 2 つで十分だと思います (気難しい数学者でない限り)。

ランダムはランダムです。同じ画像が 4 回連続して表示された場合でも、それはランダムであるとみなされる可能性があります。

私の意見は、ランダムなものは適切にテストできないということです。

確かにテストしてみることはできますが、試したい組み合わせが非常に多いため、RNG に頼って少数のケースをスポット チェックする方が賢明です。

さて、問題は乱数の定義上、 できる 繰り返される(なぜなら...それを待つ:ランダム)。おそらく、あなたがやりたいことは、最新の乱数を保存し、計算された乱数をそれと比較し、等しい場合は別の乱数を計算することです...でも今あなたの数字は ランダム性が低い (「多かれ少なかれ」ランダム性などというものがないことはわかっていますが、今回はこの言葉を使わせてください)、それらは繰り返されないことが保証されているからです。

とにかく、乱数についてあまり深く考えてはいけません。:)

他の人も指摘しているように、ランダム性を実際にテストすることは不可能です。1 つの特定のメソッドにランダム性を含めて、他のすべてのメソッドに対して単体テストを作成できます (またそうすべきです)。こうすることで、最後の部分から乱数を取得できると仮定して、他のすべての機能をテストできます。

乱数値を保存し、次に生成された乱数を使用する前に、保存された値と照合してください。

優れた擬似乱数ジェネレーターであれば、ジェネレーターにシードを与えることができます。ジェネレーターに同じ番号をシードすると、生成される乱数のストリームも同じになります。では、乱数ジェネレーターをシードして、その特定の数値ストリームに基づいて単体テストを作成してみてはいかがでしょうか。

一連の非反復乱数を取得するには:

  1. 乱数のリストを作成します。
  2. 各乱数にシーケンス番号を追加します
  3. 順序付きリストを元の乱数でソートする
  4. シーケンス番号を新しい乱数として使用します。

ランダム性をテストするのではなく、得られた結果が望ましいものであるかどうかをテストしてください (むしろ、おそらく望ましい結果になるだろうと受け入れる前に、望ましくない結果が得られることを数回試してください)。ランダムな出力をテストしている場合に、望ましくない結果が絶対に得られないことを保証することは不可能ですが、少なくとも、その結果が発生していることに気づく可能性を高めることはできます。

Y サイズの N 個のプールを取得して、X 回を超えて出現する結果がないかチェックするか、N*Y サイズの 1 つのプールを取得して、Y サイズのすべてのグループに対して X 回を超えて出現する結果がないかチェックします (1から Y、2 から Y + 1、3 から Y + 2 など)。N が何であるかは、テストの信頼性をどの程度高めたいかによって異なります。

乱数は分布から生成されます。この場合、すべての値の出現確率は同じである必要があります。無限量のランダムを計算すると、正確な分布が得られます。

実際には、関数を何度も呼び出して結果を確認します。N 個の画像があると予想される場合は、100*N のランダムを計算し、予想される各数値のうち何個が見つかったかを数えます。ほとんどは 70 ~ 130 回出現するはずです。異なるランダムシードを使用してテストを再実行し、結果が異なるかどうかを確認します。

今使っているジェネレーターが物足りないと思ったら、簡単に何かを見つけることができます。Google で「Mersenne Twister」を検索してください。これは必要以上にランダムです。

画像が再度表示されるのを避けるには、ランダム性の低いものが必要です。簡単な方法は、許可されていない値を確認し、その値が含まれている場合は再計算することです。

ランダム性をテストすることはできませんが、一連の数値の相関または分布をテストすることはできます。

テストするのが難しい目標:画像が必要になるたびに、4 つの画像のうち 1 つをランダムに選択します。

テストが簡単な目標:選択した画像 100 枚ごとに、4 つの画像がそれぞれ少なくとも 20 回表示される必要があります。

私はアダム・ローゼンフィールドの意見に同意します。あなたが話している状況では、有効にテストできる唯一のことは、範囲全体の分布です。

私がよく遭遇する状況は、お気に入りの言語の PRNG を使用して擬似乱数を生成し、それを目的の範囲に操作するというものです。自分の操作が分布に影響を与えているかどうかを確認するために、大量の数値を生成し、それらを操作して、結果の分布を確認します。

適切なテストを行うには、範囲より少なくとも数桁多い数値を生成する必要があります。使用する値が多いほど、テストの精度が向上します。明らかに、範囲が非常に広い場合は、生成する数値が多すぎるため、これは機能しません。しかし、あなたの状況では、それはうまく機能するはずです。

ここで私が言いたいことを説明する Perl の例を示します。

for (my $i=0; $i<=100000; $i++) {
   my $r = rand;        # Get the random number
   $r = int($r * 1000); # Move it into the desired range
   $dist{$r} ++;        # Count the occurrences of each number
}

print "Min occurrences: ", (sort { $a <=> $b } values %dist)[1], "\n";
print "Max occurrences: ", (sort { $b <=> $a } values %dist)[1], "\n";

最小値と最大値の間の広がりが小さい場合、分布は良好です。幅が広い場合は、分布が悪い可能性があります。この方法を使用して、範囲がカバーされているかどうか、値が欠落していないかどうかを確認することもできます。

繰り返しますが、生成する数値が多いほど、結果の有効性が高くなります。私は、小さなことから始めて、自分のマシンが適切な時間内に処理できるものまで徐々に進めていく傾向があります。五分。

整数内のランダム性の範囲をテストしていると仮定すると、これを検証する 1 つの方法は、数十億 (おそらく 10,000 個程度) の「乱数」を作成し、その発生をヒストグラム上にプロットすることです。

          ******    ******           ****
***********************************************
*************************************************
*************************************************
*************************************************
*************************************************
*************************************************
*************************************************
*************************************************
*************************************************
         1         2         3         4         5
12345678901234567890123456789012345678901234567890

上記は「比較的」正規分布を示しています。

次のように、さらに歪んでいるように見える場合:

          ******    ******           ****
    ************  ************  ************
    ************  ************  ***************
    ************  ************  ****************
    ************  ************  *****************
    ************  ************  *****************
   ***************************  ******************
   **************************** ******************
******************************* ******************
**************************************************
         1         2         3         4         5
12345678901234567890123456789012345678901234567890

そうすれば、ランダム性が減少していることがわかります。他の人が述べたように、反復の問題にも対処する必要があります。

たとえば、1 から 1024 までの乱数を使用してジェネレーターから、たとえば 10,000 個の乱数を含むバイナリ ファイルを書き込み、何らかの圧縮 (zip、gzip など) を使用してそのファイルを圧縮しようとした場合、2 つのファイルを比較できます。サイズ。「大量の」圧縮がある場合、それは特にランダムではありません。サイズに大きな変化がない場合、それは「かなりランダム」です。

なぜこれが機能するのか

圧縮アルゴリズムはパターン (繰り返しなど) を探し、何らかの方法でパターンを削減します。これらの圧縮アルゴリズムを調べる 1 つの方法は、ファイル内の情報量を測定することです。高度に圧縮されたファイルにはほとんど情報がありません(例:ランダム性)、少し圧縮されたファイルには多くの情報が含まれます(ランダム性)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top