随笔-102  评论-64  文章-0  trackbacks-0

Random类不能产生随机数的情况测试

   今天本想写段程序,产生一个1到100个随机数序列供使用,意外的发现一个问题,rd.Next产生全是

一样的数。就做了个测试,发出来给大家瞅瞅,也给自己留个记号~~
   一、背景:产生一个1到100个随机数序列供使用,通过Random类的Next(int minValue,int

maxValue)方法。
   二、系统环境:VS2008,FrameWork3.5
   三、操作过程:

3.1、产生同数字的情况:
  private void button4_Click(object sender, EventArgs e)
         {
              List<int> list = new List<int>();
              for (int i = 0; i < 31; i++)
              {
                  list.Add(GetRandom());
              }
              listBox1.DataSource = list;
         }
         private int GetRandom()
         {
              Random rd = new Random();
              return rd.Next(0, 101);
         }
       3.2、产生随机数字的情况:
  private void button4_Click(object sender, EventArgs e)
         {
              List<int> list = new List<int>();
              for (int i = 0; i < 31; i++)
              {
                  list.Add(GetRandom());
                  Thread.Sleep(20);
              }
              listBox1.DataSource = list;
         }
      3.3、另外我也直接用了rd.Next(),产生的同样结果。
  
      3.4、把Thread.Sleep(20);改成小于20毫秒的情况时,如(15,10),也会产生相似结果。

四、结论:
   Random类的Next方法连续执行的情况下,产生随机数相同;在执行间隔小于一定时间内,产生

的随机数相同。

作者:欣静赏悦
出处:http://www.cnblogs.com/windy2008
本文版权归作者和博客园共有,欢迎转载,请保留此段声明。

标签: Random
posted on 2010-03-19 13:04 欣静赏悦 阅读(1453) 评论(22) 编辑 收藏

评论:
#1楼 2010-03-19 13:09 | pboyin      
按你的代码应该各连续执行没多大关系吧,
 回复 引用 查看   
#2楼 2010-03-19 13:15 | 命运之子      
你可以试一下,把Random对象设为全局,而不是每次都创建新的。这个情况是和随机数产生的那块内存有关系吧(我猜的,原理不太清楚,呵呵)
 回复 引用 查看   
#3楼[楼主] 2010-03-19 13:15 | 欣静赏悦      
@pboyin
没找到答案呢,发上来,帮忙看看怎么这样呢

 回复 引用 查看   
#4楼 2010-03-19 13:17 | liy      
把随机函数声明成
public static Random rand = new Random();
再试一下,结果就不一样了

 回复 引用 查看   
#5楼[楼主] 2010-03-19 13:22 | 欣静赏悦      
@liy
刚才试了,可以的,为啥每次重新初始化一个咋不可以呢

 回复 引用 查看   
#6楼 2010-03-19 13:37 | 超级奶崽      
不使用静态的话加个 种子 也是可以产生不同随机数的
 回复 引用 查看   
#7楼 2010-03-19 13:41 | AutumnWinter      
不是不能产生,是你不会用。
 回复 引用 查看   
#8楼 2010-03-19 13:42 | sun672380679      
msdn:
"随机数的生成是从种子值开始。如果反复使用同一个种子,就会生成相同的数字系列。产生不同序列的一种方法是使种子值与时间相关,从而对于 Random 的每个新实例,都会产生不同的系列。默认情况下,Random 类的无参数构造函数使用系统时钟生成其种子值,而参数化构造函数可根据当前时间的刻度数采用 Int32 值。

"

 回复 引用 查看   
#9楼 2010-03-19 13:43 | 颜斌      
因为每次都初始化的话 random的随机种子是和时间相关的 由于循环很快 所以每次实例化的random 都具有相同的随机种子 所以得到的随机数也是一样的 简单的说random(x) = f(x, current_time)
 回复 引用 查看   
#10楼 2010-03-19 13:47 | 孙长宇      
Random是“伪随机数”生成器,可以做一个递增数字作为Seed。
for (int i = 0; i < 100; i++)
{
Console.WriteLine(new Random(i).Next(0, 100));
}

 回复 引用 查看   
#11楼[楼主] 2010-03-19 14:04 | 欣静赏悦      
TO ALL:
学习了

 回复 引用 查看   
#12楼 2010-03-19 14:13 | 王半仙      
为什么不用System.Security.Cryptography.RandomNumberGenerator?
随机性比较好。

 回复 引用 查看   
#13楼 2010-03-19 14:50 | 不若相忘于江湖      
这个问题.. 与时间的种子相关.


 回复 引用 查看   
#14楼 2010-03-19 15:21 | fzxu_05      
Random对象设为全局
谢谢~

 回复 引用 查看   
#15楼[楼主] 2010-03-19 15:49 | 欣静赏悦      
总结一下~~
原因:随机数的生成是从种子值开始。默认情况下,Random 类的无参数构造函数使用系统时钟生成其种子值;由于循环很快,所以每次实例化的Random 都具有相同的随机种子。
解决办法:Random对象设为全局;循环外初始化。

 回复 引用 查看   
#16楼 2010-03-19 16:40 | elite_lcf      
Random rand = new Random()

这时产生的随机值和当前系统时间有关,而你的代码执行的非常快,(电脑体质好)
就会出现,第一个随机数生成完成并输出之后,第二次重新生成的随机数和第一次生成的随机数使用了一样的随机种子。
输出当然一样。
random是伪随机输出的

 回复 引用 查看   
#17楼 2010-03-19 18:24 | Argo      
建议楼主查查资料自己理解一下再发帖子,这种低级问题也发首页,我无语了
 回复 引用 查看   
#18楼 2010-03-19 21:46 | 560889223      
我在猜是不是很多人下载的VS里是不包括MSDN的。不过即便如此,微软的网站上也有在线版的……
 回复 引用 查看   
#19楼[楼主] 2010-03-20 07:40 | 欣静赏悦      
@560889223
@Argo
嘿嘿,说中了,二位见笑了,不过我想这是解决办法的最全面的途径

 回复 引用 查看   
#20楼 2010-03-20 10:53 | 菜鸟吃虫,虫吃菜      
你可以两个方法改变每次出来的状态不一样
1:将Random r = new Random();放出循环体
2:将for循环的i作为种子new Random(i)

 回复 引用 查看   
#21楼 2010-03-20 17:23 | 随机      
友情回帖。。。。
 回复 引用 查看   
#22楼 2010-03-23 13:11 | 菩提小鸟      
楼主,似乎你没有好好研究MSDN,Random连续产生随机数是需要种子的。也就是说,每次随机数是以种子为参数而创建的。惯例是取当前时间的毫秒作为种子,即可连续产生随机数,因为CPU的晶振频率绝对大于1毫秒1次。若按楼主睡掉线程的做法,当然也可以实现(因为默认的种子也发生变化了,通过楼主的实验,可见默认的种子变化是大于20毫秒的),但是性能肯定不是最佳的。综上所诉,楼主因该这样写Random:
Random r = new Random(DateTime.Now.Millisecond); //现在不睡线程也能产生连续随机数了。

 回复 引用 查看