2009-06-25 10 views
8

私が欲しいのは、です。 C#の乱数生成器です。C#で擬似乱数を生成する最も簡単な方法は何ですか?

int dummyAge = MathHelpers.GetRandomNumber(20,70); 

、それは例えば、疑似ランダムに見える持っていますダミーデータを生成する。

ほとんどのstack overflow questions on this topicとウェブで真のランダム性に関する哲学的議論に入ります。私は現時点で興味のあるものではありません。私はちょうど迅速C#でこれをやろうとしているミリ秒/スリープダミーデータの罰金ですを使用して、長い時間前にPHPに1をしました。

誰もが、それは常に行の同じ5番号を発生させないように、私は次のコードを変更することができますどのようにいくつかの時間の種子など、または、に基づいて迅速半まともなC#乱数ジェネレータを持っています?

using System; 

namespace TestRandom23874 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Console.WriteLine("the random number is: {0}", MathHelpers.GetRandomNumber(1, 10)); 
      Console.WriteLine("the random number is: {0}", MathHelpers.GetRandomNumber(1, 10)); 
      Console.WriteLine("the random number is: {0}", MathHelpers.GetRandomNumber(1, 10)); 
      Console.WriteLine("the random number is: {0}", MathHelpers.GetRandomNumber(1, 10)); 
      Console.WriteLine("the random number is: {0}", MathHelpers.GetRandomNumber(1, 10)); 
      Console.ReadLine(); 
     } 
    } 

    public class MathHelpers 
    { 
     public static int GetRandomNumber(int min, int max) 
     { 
      Random random = new Random(); 
      return random.Next(min, max); 
     } 
    } 
} 
+0

「疑似ランダム」を意味すると思います。準ランダムは他の何かを意味します。 –

+0

私は準疑問(「まるでそのような感じがあるかのように、ある程度似ている」と思う)は、擬似(「本物ではなく出現している」よりも)意味があります。正規の乱数を平均的なユーザーに返しますが、数学者にとっては乱数で「ある程度」のみです。 –

答えて

13
public class MathHelpers 
    { 
     private static Random random = new Random(); 
     public static int GetRandomNumber(int min, int max) 
     { 
      return random.Next(min, max); 
     } 
    } 

この方法で、あなたはむしろあなたは同じものを再利用している、新しいランダムオブジェクトを毎回作成していません。新しいものをすばやく再作成すると、同じ結果が得られます。しかし、既存のものを再利用すると、ランダム性が得られます。

+0

素晴らしい、それは私が必要としていたすべてのものです、ありがとう! –

+1

注:これはC#だけでなく、他の多くの言語(C、C++、Javaなど)でも当てはまります。あなたは通常、あなたのRNGを一度シードし、必要なだけRNGを再利用します。彼らがRNGを再播種し続けているので、人々が開発関連のフォーラムで何か助けを求めているのを何度も見たことがあります。 – Ksempac

+1

これはスレッドセーフではないと思います... –

2

BFreeの答えは良いですが、私はそれはまた、静的変数を介して常に単一のインスタンスを使用するよりも、それが必要なものにRandomインスタンスを渡すことは少し異なるパターンを言及する価値があると思います。後者のアプローチの欠点は、Randomがスレッドセーフではないことです。いくつかのロックまたはスレッドローカル変数が必要か、または複数のスレッドを使用しないで始めるかのどちらかです。だから私は、質問の元のコードを調整する:

using System; 

namespace TestRandom23874 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Random rng = new Random(); 
      Console.WriteLine("the random number is: {0}", 
       MathHelpers.GetRandomNumber(rng, 1, 10)); 
      Console.WriteLine("the random number is: {0}", 
       MathHelpers.GetRandomNumber(rng, 1, 10)); 
      Console.WriteLine("the random number is: {0}", 
       MathHelpers.GetRandomNumber(rng, 1, 10)); 
      Console.WriteLine("the random number is: {0}", 
       MathHelpers.GetRandomNumber(rng, 1, 10)); 
      Console.WriteLine("the random number is: {0}", 
       MathHelpers.GetRandomNumber(rng, 1, 10)); 
     } 
    } 

    public class MathHelpers 
    { 
     public static int GetRandomNumber(Random random, int min, int max) 
     { 
      return random.Next(min, max); 
     } 
    } 
} 

これは、コントロールの基本的な反転です。 1つのラウンドロック付きスタティックRNGを使用して、スレッドセーフな方法でRandomという新しいインスタンスを生成することができます(ランダムにシードを生成してからインスタンスを作成することによって)Random特定のシングルスレッド・セットの操作全体を通じて実行されます。

+0

スレッドセーフである必要がある場合は、うまく解決します。しかし、ヘルパーメソッドが既存のアイテムの1回の呼び出しに減らされるので、私はこの場合にヘルパーメソッドを完全に削除します。 – Ksempac

+0

ああ、絶対に。これはアプローチのほんの一例です。 –

+0

これは本当に23,874番目の "TestRandom"プログラムですか? :) –

1

問題は(同じ5つの番号の)タイミングの問題です、BFreeの答えはそれを解決します。 Randomクラスは、タイマーを使用して自己播種しています。あなたの呼び出しは、互いに密接に接しており、同じシードを使用しています。

関連する問題