2013年11月16日 星期六

使用C# 產生亂數

在dotNET環境下要產生隨機亂數可以使用簡單的方法,但是當你在多執行緒環境時,產生出來的亂數始終不會很亂,似乎在同一個時間裏面所產生出來的亂數都是一樣的。
在網路上找了些解決方法,然後經過實做的改進,演變出一個可以重複使用的亂數產生器,這個原理是利用Guid.NewGuid()每一次所產生出來的結果都是不同的,在用它產生雜湊碼來當成亂數產生器的種子,這樣所產生出來的亂數就真的很亂了。
再加上一些我自己用得到的變形,這樣一個真的亂的亂數產生器誕生。
   1: public class RealRandom {
   2:  
   3:     /// <summary>
   4:     /// 產生0-1之間的實數亂數,由Random.NextDouble()實做
   5:     /// </summary>
   6:     /// <returns>0-1之間的亂數</returns>
   7:     public double NextDouble() {
   8:         Random rnd = new Random(Guid.NewGuid().GetHashCode());
   9:         return rnd.NextDouble();
  10:     }
  11:  
  12:     /// <summary>
  13:     /// 產生指定範圍內的亂數,由Random.NextDouble()實做
  14:     /// </summary>
  15:     /// <param name="minValue">開始值</param>
  16:     /// <param name="maxValue">結束值</param>
  17:     /// <returns>亂數</returns>
  18:     public double NextDouble(double minValue, double maxValue) {
  19:         Random rnd = new Random(Guid.NewGuid().GetHashCode());
  20:         return minValue + rnd.NextDouble() * (maxValue - minValue);
  21:     }
  22:  
  23:     /// <summary>
  24:     /// 產生指定範圍內的整數亂數,由Random.Next()實做
  25:     /// </summary>
  26:     /// <param name="minValue">開始值</param>
  27:     /// <param name="maxValue">結束值</param>
  28:     /// <returns>整數亂數</returns>
  29:     public int Next(int minValue, int maxValue) {
  30:         Random rnd = new Random(Guid.NewGuid().GetHashCode());
  31:         return rnd.Next(minValue, maxValue);
  32:     }
  33:  
  34:     /// <summary>
  35:     /// 產生正負一的亂數
  36:     /// </summary>
  37:     /// <returns>隨機的0或1</returns>
  38:     public int NextPNOne() {
  39:         Random rnd = new Random(Guid.NewGuid().GetHashCode());
  40:         return rnd.NextDouble() < 0.5 ? -1 : 1;
  41:     }
  42: }
在進行實際測試的時候,發現一個詭異的現象,我的環境是Win7+VS2008,rnd.Next()居然不會達到maxValue,寫程式的時候一定要小心呀!

沒有留言: