2017-03-16 21 views
1

generating random numbers without consecutive repetitionを参照して、非繰り返し乱数ジェネレータを2から9までの範囲で作成したい。範囲内の非繰り返し整数(除外0)繰り返し整数シーケンスを生成する

私は、上記のURLの回答からラッピングコードをよく使います。あなたがパターンのように、5と9を繰り返しを見ることができるように、別の順序であなたがすべて見ながら

2 
7 
4 
9 

2 
3 
4 
5 

2 
7 
4 
9 

5 
9 
5 
9 

8 
7 
6 
5 

3 
9 
7 
5 

2 
7 
4 
9 

5 
9 
5 
9 

5 
9 
5 
9 

9 
9 
9 
9 

5 
9 
5 
9 

7 
5 
3 
9 

8 
7 
6 
5 

3 
9 
7 
5 

9 
5 
9 
5 

4 
3 
2 
9 

6 
3 
8 
5 

2 
7 
4 
9 

6 
3 
8 
5 

9 
5 
9 
5 

int oldrand = <prior random number>; 
int adder = randomNumberGenerator() % 4; 
int newrand = (oldrand + adder + 1) % 5; 

私のコードは、しかし、

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text.RegularExpressions; 
using System.Threading; 

namespace Rextester 
{ 
    public class Program 
    { 
     public static void Main(string[] args) 
     { 
      Random Rand = new Random(); 
      int oldrand = Rand.Next(0,7); 
      //Console.WriteLine(oldrand); 
      for (int i=0; i<50;i++) { 

      int adder = Rand.Next(0,7) % 7; 
      int newrand = (oldrand + adder + 1) % 8+2; 
      int newrand2 = (newrand + adder + 1) % 8+2; 
      int newrand3 = (newrand2 + adder + 1) % 8+2; 
      int newrand4 = (newrand3 + adder + 1) % 8+2; 

      Console.WriteLine(newrand); 
      Console.WriteLine(newrand2); 
      Console.WriteLine(newrand3); 
      Console.WriteLine(newrand4); 
      oldrand = newrand4; 
      Console.WriteLine(); 
      } 
     } 
    } 

    public class Rand { 
     private static readonly Random globalRandom = new Random(); 
     private static readonly object globalLock = new object(); 

     private static readonly ThreadLocal<Random> threadRandom = new ThreadLocal<Random>(NewRandom); 

     public static Random NewRandom() 
     { 
      lock (globalLock) 
      { 
       return new Random(globalRandom.Next()); 
      } 
     } 

     public static Random Instance { get { return threadRandom.Value; } } 

     public static int Next(int minValue, int maxValue) 
     { 
      return Instance.Next(minValue, maxValue); 
     } 

    } 
} 

は奇妙な結果を生成し、 4つの9。

+1

ないあなたがやっている理由を確認してくださいループごとに4つの 'newrand'がありますが、ループごとに4つのサンプルを実際に作成したい場合は、それぞれの間に' adder 'を再生成する必要があります。そうでなければ、正しくパターンに従っていません。 –

+0

この結果はどのくらいの頻度で生成されますか? –

答えて

0

コードの問題は、新しい乱数ごとに新しい乱数を選択する必要があることです。あなたのコードは単一の乱数を何度も何度も再利用するので、数学的に予測可能なシーケンスを得るだけで、どこから始めるのかによって重複が発生します。

ここで動作するコードのバージョンだ(と結果&hellipをテストし、それはまた私が考える方法で書かれてはるかに読みやすい、再利用可能な、と理解している):

static void Main(string[] args) 
    { 
     Random random = new Random(); 
     const int max = 8; 

     for (int i = 0; i < 50; i++) 
     { 
      int[] sequence = 
       GetRandomNonConsecutiveSequence(random, max, 4) 
       .Select(j => j + 2) 
       .ToArray(); 

      if (!CheckSequence(sequence)) 
      { 
       Console.WriteLine("Sequence failed: " + string.Join(", ", sequence)); 
      } 
     } 
    } 

    private static bool CheckSequence(int[] sequence) 
    { 
     int previous = sequence[0]; 

     for (int i = 1; i < sequence.Length; i++) 
     { 
      if (previous == sequence[i]) 
      { 
       return false; 
      } 

      previous = sequence[i]; 
     } 

     return true; 
    } 

    private static IEnumerable<int> GetRandomNonConsecutiveSequence(
     Random random, int max, int count) 
    { 
     int previous = random.Next(max); 

     yield return previous; 

     while (--count > 0) 
     { 
      yield return previous = Next(previous, max, random); 
     } 
    } 

    static int Next(int previous, int max, Random random) 
    { 
     return (previous + random.Next(max - 1) + 1) % max; 
    } 
+0

私はまだ自己学習しているので、私はIEnumerableの部分を得ていません。あなたはコードを詳しく教えていただけますか?ありがとう! –

+0

@MatthewTang:https://msdn.microsoft.com/en-us/library/65zzykke(v=vs.100).aspx –

関連する問題