8

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

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

それで、お茶で水をやった後、頭を悩ませて、次のことを思いついたのですが、あなたの考えがあればいいのかと思っていました。

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

すなわち

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

でも、考えずにはいられなかったのですが、時間を無駄にしていたのでしょうか?私はそれを何度も繰り返して実行し、いつでも倒れるかどうかなどを確認しました。

これで時間を無駄にしていたと思いますか?または私は逃げることができたかもしれません:

素晴らしい乱数ジェネレーター

GateKillerの答えは私にこれを思い出させました:

ディルバートランダム

Clarifyに更新

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

19 に答える 19

6

要件からテストします:「同じ画像があまり頻繁に表示されないようにするため」

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

于 2008-09-23T18:49:18.397 に答える
6

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

于 2008-09-23T19:01:44.263 に答える
5

アイテムの固定セットがあり、あまり頻繁に繰り返したくない場合は、コレクションをランダムにシャッフルします。そうすれば、同じ画像を 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すでにキューに入っているかどうかをテストし、そうであれば、合格するものが見つかるまで別の画像をランダムに選択します。

乱数ジェネレーターの品質をテストすることについて本当に質問している場合は、統計の本を開く必要があります。

于 2008-09-23T18:31:46.333 に答える
4

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

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

于 2008-09-23T18:20:43.113 に答える
2

乱数の生成は、偶然に任せるにはあまりにも重要です。-- ロバート・R・コヴェユー

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

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

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

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

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

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

于 2008-09-23T18:38:16.817 に答える
2

ランダム性と何かがランダムに見えるかどうかの評価について書ける本はたくさんありますが、数学のページは割愛します。つまり、カイ二乗検定を使用して、明らかに「ランダムな」分布が期待どおりにどの程度適合するかを判断できます。

Perl を使用している場合は、Statistics::ChiSquareモジュールを使用して面倒な作業を行うことができます。

ただし、画像が均等に分散されていることを確認したい場合は、完全にランダムにしたくないでしょう。代わりに、画像のリスト全体を取得し、そのリストをシャッフルして、「ランダムな」画像が必要なときはいつでもアイテムを削除することをお勧めします. リストが空の場合は、リストを再構築し、再シャッフルして繰り返します。

この手法は、一連の画像が与えられた場合、個々の画像がリストの反復ごとに 1 回しか表示されないことを意味します。画像を均等に配置せざるを得ません。

ではごきげんよう、

ポール

于 2008-09-24T06:59:14.913 に答える
1

ランダム関数と同様の関数が提供するのは、疑似乱数、つまり関数を通じて生成される一連の数値です。通常、その関数には、最初の「乱数」を生成するために使用される最初の入力パラメーター(別名「シード」)を指定します。その後、最後の各値は、サイクルの次の反復の入力パラメーターとして使用されます。「擬似乱数生成器」に関するウィキペディアの記事を確認できます。そこにある説明は非常に優れています。

これらのアルゴリズムにはすべて共通点があります。一連の反復は、何度も繰り返された後に繰り返されます。これらは真の乱数ではなく、ランダムに見える一連の数字であることを忘れないでください。あるジェネレーターを別のジェネレーターから選択するには、次のことを自問する必要があります。

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

2つ目は、その時点でどのくらいの乱数を使用していますか。2、3?それらをペア(またはトリプレット)にして、前の実験を繰り返します。非常に長い反復回数の後、期待される各結果が少なくとも1回表示されるはずです。また、各結果が表示される回数は、それほど遠くないはずです。期待される。一度に1つまたは2つを服用するのに問題なく機能するジェネレーターがいくつかありますが、3つ以上を服用すると見事に失敗します(RANDUは誰ですか?)。

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

于 2008-09-23T19:09:47.023 に答える
0

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

于 2008-09-23T18:19:36.737 に答える
0

私の意見では、ランダムなものは適切にテストできません。

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

于 2008-09-23T18:22:13.533 に答える
0

一連の繰り返されない乱数を取得するには:

  1. 乱数のリストを作成します。
  2. 各乱数にシーケンス番号を追加します
  3. シーケンスされたリストを元の乱数で並べ替えます
  4. シーケンス番号を新しい乱数として使用します。
于 2008-09-23T19:06:34.610 に答える
0

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

YサイズのプールをN個取得して、X回を超えて表示される結果を確認するか、N * Yサイズのプールを1つ取得して、Yサイズのすべてのグループを取得してX回を超えて表示される結果を確認します(1 Yへ、2からY + 1、3からY + 2など)。Nが何であるかは、テストの信頼性によって異なります。

于 2008-09-23T19:09:07.663 に答える
0

優れた擬似乱数ジェネレーターを使用すると、ジェネレーターをシードできます。ジェネレーターに同じ数をシードすると、生成される乱数のストリームは同じになります。では、乱数ジェネレーターをシードしてから、その特定の数値ストリームに基づいて単体テストを作成してみませんか?

于 2008-09-23T18:40:43.067 に答える
0

乱数は分布から生成されます。この場合、すべての値の出現確率は同じでなければなりません。無限の乱数を計算すると、正確な分布が得られます。

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

現在使用しているジェネレーターが不十分であることがわかった場合は、簡単に何かを見つけることができます。Google で「Mersenne Twister」を検索します。これは、必要以上にランダムです。

画像が再表示されるのを避けるには、ランダム性の低いものが必要です。簡単なアプローチは、許可されていない値を確認し、その値の 1 つである場合は再計算することです。

于 2008-09-23T19:25:16.110 に答える
0

問題は、定義上、乱数が繰り返される可能性があることです (それらは... 待ってください: ランダムだからです)。たぶん、あなたがしたいことは、最新の乱数を保存して、計算されたものと比較し、等しい場合は別のものを計算することです.ランダム性ですが、今回だけこの用語を使用させてください)、それらは繰り返されないことが保証されているためです。

とにかく、乱数をあまり考えるべきではありません。:)

于 2008-09-23T18:25:46.770 に答える
0

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

私が通常遭遇する状況は、お気に入りの言語の 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";

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

繰り返しになりますが、生成する数値が多いほど、結果はより有効になります。私は小さく始めて、自分のマシンが妥当な時間 (たとえば 5 分) で処理できるようになるまで作業を進める傾向があります。

于 2008-09-23T19:57:43.240 に答える
0

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

于 2008-09-23T18:27:37.623 に答える
0

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

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

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

于 2008-09-23T19:31:52.587 に答える
0

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

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

上記は、「相対的に」正規分布を示しています。

次のように、より歪んで見える場合:

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

次に、ランダム性が少ないことがわかります。他の人が述べたように、繰り返しの問題もあります。

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

なぜこれが機能するのか

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

于 2008-09-23T20:57:05.627 に答える
0

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

于 2008-09-23T18:35:16.543 に答える