none
如何让产生的随机数不重复,且在一个区间范围内,非常散乱? RRS feed

  • 问题

  • 我用WPF在一个全屏(结果应该跟全屏与否,没有因果关系)界面下产生随机布局的窗口。
            private void CreateRectangle()
            {
                //绘制矩形
                Rectangle drawRectangle = new Rectangle();

                drawRectangle.Stroke = randBrushColor();
                drawRectangle.Fill = randBrushColor();
                //drawRectangle.HorizontalAlignment = randomInt(Convert.ToInt32(this.Width));
                //drawRectangle.VerticalAlignment = randomInt(Convert.ToInt32(this.Height));
                drawRectangle.Width = randomInt(Convert.ToInt32(canvas1.ActualWidth));
                drawRectangle.Height = randomInt(Convert.ToInt32(canvas1.ActualHeight));
                Canvas.SetTop(drawRectangle, randomInt(Convert.ToInt32(canvas1.ActualHeight )));
                Canvas.SetLeft(drawRectangle, randomInt(Convert.ToInt32(canvas1.ActualWidth)));
                canvas1.Children.Add(drawRectangle);
               
            }   //  end private void CreateRectangle()

            private int randomInt(int value)
            {
                Random rand = new Random();
                int randInt = rand.Next(value);

                sw.WriteLine("RandomInt(int {0}) = {1}", value, randInt);
                return randInt;
            }
           
            private byte randomColor()
            {
                Random rand = new Random();
                byte randByte = Convert.ToByte(rand.Next(255));

                sw.WriteLine("RandomColor(): ColorByte = {0}", randByte.ToString());
                return randByte;
            }

            private Brush randBrushColor()
            {
                //产生随机颜色
                SolidColorBrush brushColor = new SolidColorBrush();
                brushColor.Color = Color.FromArgb(255, randomColor(), randomColor(), randomColor());

                sw.WriteLine("RandomBrushColor() Color is {0}", brushColor.Color.ToString());
                return brushColor;
            }
    我在每次调用随机产生函数时,都把随机结果记录到一个文件,下面是这个文件的记录(部分能说明问题的):
    RandomBrushColor() Color is #FF8D8D8D
    RandomInt(int 1258) = 700
    RandomInt(int 993) = 552
    RandomInt(int 993) = 552
    RandomInt(int 1258) = 700
    RandomColor(): ColorByte = 28
    RandomColor(): ColorByte = 28
    RandomColor(): ColorByte = 28
    RandomBrushColor() Color is #FF1C1C1C
    RandomColor(): ColorByte = 28
    RandomColor(): ColorByte = 28
    RandomColor(): ColorByte = 28
    RandomBrushColor() Color is #FF1C1C1C
    RandomInt(int 1258) = 139
    RandomInt(int 993) = 109
    RandomInt(int 993) = 109
    RandomInt(int 1258) = 139
    RandomColor(): ColorByte = 169
    RandomColor(): ColorByte = 169
    RandomColor(): ColorByte = 169
    RandomBrushColor() Color is #FFA9A9A9
    RandomColor(): ColorByte = 169
    RandomColor(): ColorByte = 169
    RandomColor(): ColorByte = 169
    RandomBrushColor() Color is #FFA9A9A9
    RandomInt(int 1258) = 836
    RandomInt(int 993) = 659
    RandomInt(int 993) = 23
    RandomInt(int 1258) = 29
    RandomColor(): ColorByte = 147
    RandomColor(): ColorByte = 147
    RandomColor(): ColorByte = 147
    RandomBrushColor() Color is #FF939393
    RandomColor(): ColorByte = 147
    RandomColor(): ColorByte = 147
    RandomColor(): ColorByte = 147
    RandomBrushColor() Color is #FF939393
    RandomInt(int 1258) = 726
    RandomInt(int 993) = 573
    RandomInt(int 993) = 573
    RandomInt(int 1258) = 726
    RandomColor(): ColorByte = 33
    RandomColor(): ColorByte = 33
    RandomColor(): ColorByte = 33
    RandomBrushColor() Color is #FF212121
    RandomColor(): ColorByte = 33
    RandomColor(): ColorByte = 33
    RandomColor(): ColorByte = 33
    由于是各自调用,因此我认为,应该产生不同的值,那为什么,其中会有些值是连续相等的?由于rgb三色值相当,产生的矩形大多数是灰的,只是明暗各不相同。且打印结果始终是一个由远至近的方块串(因为我不清空之前打印的结果,所有的矩形都被反复叠加在原来的上面)。这些方块不会出现在屏幕的其它位置。

    这台奇怪了,取随机数,就是要它的结果凌乱;如果如此有秩序,那实在令我怀疑这是不是随机数;或有什么别的方法可以试它们凌乱(越乱越好)。谢谢!

    2009年11月18日 14:48

答案

  • 你好!

    使用一个 List<T> 记录已生成的随机数,如果当前生成的随机数在集合中存在就重新生成。
    知识改变命运,奋斗成就人生!
    • 已标记为答案 OpenNovo 2009年11月21日 7:29
    2009年11月19日 1:26
    版主
  • 你好!
         一般用一个集合或数组保存已经生成的随机数,写一个while循环,如果和保存的某个随机数一样就继续产生,直到产生一个和保存的所有数都不一致的数!
    周雪峰
    • 已标记为答案 OpenNovo 2009年11月21日 7:29
    2009年11月19日 3:44
    版主
  • 这个更好解决了,记录上一次产生的随机数。下次产生数据数时判断前后是否一样,如一样就重新产生。
    知识改变命运,奋斗成就人生!
    • 已标记为答案 OpenNovo 2009年11月21日 7:29
    2009年11月20日 2:46
    版主
  • 基本都是看上去随机而已,并不是真正的随机!都是基于一些数学上的随机算法来实现的,既然是算法,就不可能真的有随机性啊!
    实际上Random的随机算法已经相当的优秀!
    周雪峰
    • 已标记为答案 OpenNovo 2009年11月24日 2:07
    2009年11月22日 8:21
    版主

全部回复

  • 更糟糕的是,我通过在按键变化的事件中增加一个TempInt = Convert.ToInt32(e.Key.GetHashCode());来取得我按键的数值,结合:int randInt = rand.Next(TempInt) % value;和byte randByte = Convert.ToByte(rand.Next(TempInt) % 255);

    但最后得出来的结果却是:
    RandomBrushColor() Color is #FF3E3E3E
    RandomInt(int 1258) = 62
    RandomInt(int 993) = 62
    RandomInt(int 993) = 62
    RandomInt(int 1258) = 62
    RandomColor(): ColorByte = 27
    RandomColor(): ColorByte = 27
    RandomColor(): ColorByte = 27
    RandomBrushColor() Color is #FF1B1B1B
    RandomColor(): ColorByte = 27
    RandomColor(): ColorByte = 27
    RandomColor(): ColorByte = 27
    很明显:有几个int的范围已经修改了,但产生的随机结果还是62;这还是随机数吗?实在不理解。
    注int 1258和int 993 的值是固定的,因为是当前绘图区域的宽度和高度。
    2009年11月18日 15:12
  • 你好!

    使用一个 List<T> 记录已生成的随机数,如果当前生成的随机数在集合中存在就重新生成。
    知识改变命运,奋斗成就人生!
    • 已标记为答案 OpenNovo 2009年11月21日 7:29
    2009年11月19日 1:26
    版主
  • 你好!
         一般用一个集合或数组保存已经生成的随机数,写一个while循环,如果和保存的某个随机数一样就继续产生,直到产生一个和保存的所有数都不一致的数!
    周雪峰
    • 已标记为答案 OpenNovo 2009年11月21日 7:29
    2009年11月19日 3:44
    版主
  • 我允许重复,但不允许连续重复。
    2009年11月20日 2:24
  • 这个更好解决了,记录上一次产生的随机数。下次产生数据数时判断前后是否一样,如一样就重新产生。
    知识改变命运,奋斗成就人生!
    • 已标记为答案 OpenNovo 2009年11月21日 7:29
    2009年11月20日 2:46
    版主
  • 这方法可行!写个全局变量来记录就可以了,可是我有点懒,这个问题进一级问:c#的random函数,实际上是某个并不标准的随机数产生函数,也就是问:。net库有没有更真实的随机数?或者如何产生纯天然的随机数?

    2009年11月21日 7:32
  • 你好!
         很不幸,目前计算机无法生成真正意义上的随机数,不只是.NET 下做不到,其他框架或语言也做不到!都是根据某些随机算法生成的,所以都是伪随机的!
         如果真正实现了随机,那计算机也就具有自主思考的能力了!
    周雪峰
    2009年11月21日 10:55
    版主
  • 原来是这样,但是我觉得dos下的tubro c产生的随机数没有这样的情况,产生的结果蛮散乱的。所以我从来没想过随机数的产生居然如此难。

    2009年11月22日 1:42
  • 看了百度的一段说明,我明白是怎么回事了;怪不得msdn的sample用了开机后经历的时间数来作为随机种子。

    2009年11月22日 5:36
  • 基本都是看上去随机而已,并不是真正的随机!都是基于一些数学上的随机算法来实现的,既然是算法,就不可能真的有随机性啊!
    实际上Random的随机算法已经相当的优秀!
    周雪峰
    • 已标记为答案 OpenNovo 2009年11月24日 2:07
    2009年11月22日 8:21
    版主