繰り返しの中で乱数を発生させたいのですが、その乱数を重複しないようにするためにはどうすればよいのでしょうか?以下にコードを示します。
lang
1for (int i =0 ; i < 5 ; i++) 2 { 3 Random r = new Random(); 4 int lots = r.Next(10); //5回の繰り返しで乱数を重複させないようにしたい 5 }
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答7件
0
参考情報:
- 重複しないランダムな数値リストの生成 http://www.programming-magic.com/20080824234424/
- 配列から重複なくランダムに複数の値を得る方法 http://am-yu.net/2014/05/11/random-plural-number/
投稿2015/03/23 21:43
総合スコア22324
0
>繰り返しの中で乱数を発生させたいのですが、
>その乱数を重複しないようにするためにはどうすればよいのでしょうか?
トランプのシャッフル、の方法で検索されると事例が見つかると思います。
(ゲームとしての、トランプのシャッフルでは、
意図して、片寄のあるシャッフルを行う事が普通です。
完全に混ぜてしまうと、ゲームになりません。)
簡単に、今回は、1~10迄の数値とします。
1.10個の配列を用意します。
2.1~10の値を、順に、各要素とします。
3.配列の要素を入れ替える為の、配列番号に相当する乱数を発生させます。
4.発生させた乱数で、配列同志の内容を入れ替えます。
5.入替終了後、配列を、昇順でも、降順でも良いので、
順番にアクセスすれば、重複しない値が取得できます。
’
コンピュータ系の、乱数と呼ばれている機能は、
正規乱数ではないので、片寄が発生します。
これを避けるようにする、乱数ジェネレータの為のコードが、
検索で見つかりますので、工夫してみてください。
⇒全うな、乱数発生機器は高いので、正規乱数でないのが解っていながら、
プログラムでは、正規乱数でない乱数を、工夫して使っています。
’
乱数の片寄を、視覚化する方法として、
8ビットパソコンの時代から行われている方法は、
100×100~ 位の範囲に
乱数値をプロットしていく方法があります。
ドット1回目は、最暗色、同じ処に、ドットを描画する度に
明るい色になるようにして、描画します。
(1600万色表示できる現在では、色変化は大きくしないと、
色変化が解らないかも。)
投稿2015/03/24 01:36
総合スコア2030
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
どのような物が必要か にもよりますね。
例えばトランプや麻雀のような資源が限られてるような乱数であればその分を配列等に用意しシャッフルします。
C#カテゴリですので、C# シャッフル とかで検索すれば例はたくさん出てくると思いますよ。
RPGのようなものでユーザーに気遣って、2回連続で攻撃が外れることは絶対に無いのようなものであれば、攻撃が外れたらフラグを立てて、次の回では乱数処理をせずに確実に当たるのようにしたり(乱数ではないですね)
1/256がたまたま◯回中に同じのは出ないようにしたいのであれば、出た乱数を保持し比較してすでに出たのが含まれていたらもう一度乱数を回すのようにしたりも考えられます。(この手段は「最悪」無限ループします。◯回が少なくなったり母数が大きくなったりするとその可能性は下がります。)
必要とされるのは一般的にはシャッフルによる手法かと思われます。
母数があまりにも大きくなると処理速度やリソースの問題出てきてしまうかと思いますが。
投稿2016/03/01 06:53
総合スコア17
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
Random 限定でやる場合だとシードにループ値を含めるだけでもずいぶん結果が異なります。
既に体験済みだと思いますがRandomは時間をデフォルトシードにしているのでごく短い間隔で乱数を生成すると値が重複しちゃいます。(こういう厳密な乱数とは異なるものを擬似乱数といういうそうですが)
コードは省略しますが、前回生成した乱数+実行回数 (intのオーバーフロー対策込み)をシード値にすると今のところ連続生成しても同じ値が連続で出現し続けるのを回避できています。
あとはループ回数が事前にわかっている(forで実現できる)場合は暗号化やハッシュに用いる為の、より「乱数」に近い擬似乱数を生成するアルゴリズムも利用できると思います。
→ System.Security.Cryptography.Rfc2898DeriveBytes
→ System.Security.Cryptography.RNGCryptoServiceProvider
Randomと使い方が異なるのでご参考までにどうぞ
投稿2015/03/24 01:07
総合スコア85
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/03/24 01:24
2015/03/24 04:31
0
これは一つの考えであって、最適解ではないとは思いますが、
int length = 5;
int[] array = new int[length];
for (int i = 0; i < length; i++ )
array[i] = i;
for( int i = 0; i < randomCount; i++ ){
int num1 = rand(0, length);
int num2 = rand(0, length);
int temp = array[num1];
array[num1] = array[num2];
array[num2] = temp;
}
for(int i = 0; i < length; i++){
int num = array[i];
System.out.println(num);
}
投稿2015/03/23 21:03
総合スコア31
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
0~9までの数が入った配列を用意し、そこからランダムな場所を抜き取ってつかったらどうですか?
投稿2015/03/23 20:55
総合スコア973
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/03/24 01:10
2015/03/24 01:29
2015/03/24 02:10
2015/03/24 02:13
2015/03/24 03:54
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。