日期:2014-05-17  浏览次数:20877 次

C# 伪随机数 随机数顺序排列 附带双色球机选程序

伪随机数是一个老生常谈的问题

因为貌似能一夜暴富的最稳定的办法就是买彩票了,当然我也抱有这个幻想。。。。。。我觉得彩票和魔方以及像数独其他什么的都可以看作是数组或者矩阵,特别是玩魔方的高手肯定都是一些数学比较优秀的人

彩票貌似看起来就是随机事件,开奖的时候也貌似很正规,抓哪个球就是哪个球,只不过是机器抓的,但是反过来想想,天朝都能把女航天员送上天、原子弹都能造出来,难道还不能控制彩票的结果?开个玩笑,貌似扯远了。。。。。。。。女人和政治不谈。。。。。。

因为我之前买彩票都是机选的,每期一注,攒够了10来张再兑奖,也并没在乎能不能中奖,碰运气呗,幻想还是有那么一点点的。后来由于辞职等一些原因在家闲了一段时间,就想研究研究彩票的号码关系。再扯一段,因为根据混沌理论,所有的事物都在沿着一定的秩序在进行,当然要找到这条秩序也不是简单的事情。虚无飘渺的事情总能勾起我的好奇心。。。。。。。。。。1/17721088的概率够虚无缥缈了吧。。。。。。。。。。

因此闲着没事就虚无缥缈了。。。。。。。。

之前也看到过一些关于“伪随机数”的文章,比如http://www.jb51.net/article/17406.htm,当时也没在意,今天闲着没事研究了一下,顺便写了一个双色球的机选代码,大家一起来讨论讨论。

有两种产生随机数的代码,先看写好的代码1:

    public List<int> GetSuiJiHaoMa()
    {
        List<int> SJHM = new List<int>();//return SJHM;
        List<int> sum = new List<int>();//临时取号

        int[] nobs = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33 };
        sum.AddRange(nobs);
        sum.Sort();

        Random rd = new Random(); *****注释1

        //获取红球号码的循环
        for (int i = 0; i < 6; i++)//共循环6次
        {
            int SumCount = sum.Count;//获取sum还有多少行,如果为15行,则数组随机取值范围 0-15
            //Random rd = new Random();  *****注释2
            //Random rd = new Random(GetRandomSeed());  *****注释3
            int temp1 = rd.Next(0, SumCount);//随机取得sum的列号
            int temp2 = sum[temp1];

            SJHM.Add(temp2);//加入到SJHM
            sum.Remove(temp2);//从sum中删除
            sum.Sort();//排序
        }

        SJHM.Sort();

        //获取蓝球号码
        Random rd1 = new Random();
        SJHM.Add(rd1.Next(1, 17));
        return SJHM;
    }


算法很简单,就是从泛型里删除随机的号码后再循环

既然说到Random就不得不多说点了,计算机上的随机数都是伪随机,因为算法中的随机数也是需要一定的种子的,而C#里的种子就是时间(我想知道为什么不用GUID作为种子),上面的程序中,如果我把注释1删掉,放在注释2的位置,就是for循环里面,会有两个结果:

1.如果是断点运行,比如一步步的断点测试什么的是没有问题的

2.一旦直接运行,前 六位都是连续的数字,比如:22 23 24 25 26 27 13      11 12 13 14 15 16 7      16 17 18 19 20 21 9  什么的

因此只能将Random rd = new Random();放在for循环的外面才可以得到“真正”的随机数

简单的说,如果Random rd = new Random();在for循环里面,你要想办法让每次循环的间隔时间在15毫秒之上,这样才能产生“像样”的随机数

 

但是如果说Random rd = new Random();在for循环里面就没办法了吗?也不是,参考注释3,GetRandomSeed()的代码如下:

 代码2

    static int GetRandomSeed()
    {
        byte[] bytes = new byte[4];
        System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
        rng.GetBytes(bytes);
        return BitConverter.ToInt32(bytes, 0);
    }


这样的话屏蔽掉注释1和注释2,保留注释3,也可以达到“真正”随机数的效果,RNGCryptoServiceProvider自己可以去查查

 

说到这大家应该能明白,电脑机选的随机和开奖的“随机”并不是一回事,电脑是伪随机,因为需要种子来生成随机的规则,只不过种子可以选择强度;电视开奖的随机。。。。。。我觉得也会有手脚