偽隨機數是一個老生常談的問題
因為貌似能一夜暴富的最穩定的辦法就是買彩票了,當然我也抱有這個幻想。。。。。。我覺得彩票和魔方以及像數獨其他什麼的都可以看作是數組或者矩陣,特別是玩魔方的高手肯定都是一些數學比較優秀的人
彩票貌似看起來就是隨機事件,開獎的時候也貌似很正規,抓哪個球就是哪個球,只不過是機器抓的,但是反過來想想,天朝都能把女航天員送上天、原子彈都能造出來,難道還不能控制彩票的結果?開個玩笑,貌似扯遠了。。。。。。。。女人和政治不談。。。。。。
因為我之前買彩票都是機選的,每期一注,攢夠了10來張再兌獎,也並沒在乎能不能中獎,碰運氣呗,幻想還是有那麼一點點的。後來由於辭職等一些原因在家閒了一段時間,就想研究研究彩票的號碼關系。再扯一段,因為根據混沌理論,所有的事物都在沿著一定的秩序在進行,當然要找到這條秩序也不是簡單的事情。虛無飄渺的事情總能勾起我的好奇心。。。。。。。。。。1/17721088的概率夠虛無缥缈了吧。。。。。。。。。。
因此閒著沒事就虛無缥缈了。。。。。。。。
之前也看到過一些關於“偽隨機數”的文章,比如http://www.jb51.net/article/17406.htm,當時也沒在意,今天閒著沒事研究了一下,順便寫了一個雙色球的機選代碼,大家一起來討論討論。
有兩種產生隨機數的代碼,先看寫好的代碼1:
[csharp]
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
[csharp]
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);
}