Random 類 命名空間:System 表示偽隨機數產生器,一種能夠產生滿足某些隨機性統計要求的數字序列的裝置。 偽隨機數是以相同的機率從一組有限的數字中選取的。所選數字並不具有完全的隨機性,因為它們是用一種確定的數學演算法選擇的,但是從實用的角度而言,其隨機程度已足夠了。 偽隨機數的產生是從種子值開始。如果反覆使用同一個種子,就會產生相同的數字系列。產生不同序列的一種方法是使種子值與時間相關,從而對於 Random 的每個新執行個體,都會產生不同的系列。預設情況下,Random 類的無參數建構函式使用系統時鐘產生其種子值,而參數化建構函式可根據目前時間的計時周期數採用 Int32 值。但是,因為時鐘的解析度有限,所以,如果使用無參數建構函式連續建立不同的 Random 對象,就會建立產生相同隨機數序列的隨機數產生器。 通過建立單個而不是多個 Random 對象可以避免此問題。 若要提高效能,請建立一個隨時間推移能產生多個隨機數的 Random 對象,而不要反覆建立會產生同一個隨機數的 Random 對象。 Random 成員 名稱 ● 說明 Equals ● 確定指定的 Object 是否等於當前的 Object。(繼承自 Object。) Finalize ● 允許 Object 在“記憶體回收”回收 Object 之前嘗試釋放資源並執行其他清理操作。(繼承自 Object。) GetHashCode ● 用作特定類型的雜湊函數。(繼承自 Object。) GetType ● 擷取當前執行個體的 Type。(繼承自 Object。) MemberwiseClone ● 建立當前 Object 的淺表副本。(繼承自 Object。) Next ● 已重載。 返回隨機數。 NextBytes ● 用隨機數填充指定位元組數組的元素。 NextDouble ● 返回一個介於 0.0 和 1.0 之間的隨機數。 Sample ● 返回一個介於 0.0 和 1.0 之間的隨機數。 ToString ● 返回表示當前 Object 的 String。(繼承自 Object。) 用 C# 產生不重複的隨機數 我們可以使用兩種方式初始化一個隨機數發生器: 第一種方法不指定隨機種子,系統自動選取目前時間作為隨機種子: Random ro = new Random(); 第二種方法可以指定一個int型參數作為隨機種子: int iSeed=10; Random ro = new Random(10); long tick = DateTime.Now.Ticks; Random ran = new Random((int)(tick & 0xffffffffL) | (int) (tick >> 32)); 這樣可以保證99%不是一樣。 之後,我們就可以使用這個Random類的對象來產生隨機數,這時候要用到Random.Next()方法。這個方法使用相當靈活,你甚至可以指定產生的隨機數的上下限。 不指定上下限的使用如下: int iResult; iResult=ro.Next(); 下面的代碼指定返回小於100的隨機數: int iResult; int iUp=100; iResult=ro.Next(iUp); 而下面這段代碼則指定傳回值必須在50-100的範圍之內: int iResult; int iUp=100; int iDown=50; iResult=ro.Next(iDown,iUp); 除了Random.Next()方法之外,Random類還提供了Random.NextDouble()方法產生一個範圍在0.0-1.0之間的隨機的雙精確度浮點數: double dResult; dResult=ro.NextDouble(); 但是用Random類產生題號,會出現重複,特別是在數量較小的題目中要產生不重複的的題目是很難的。 參考了網上的一些方法,找到兩類解決方案,一類是通過隨機種子入手,使每一次的隨機種子不同,來保證不重複;第二類是使用一些資料結構和演算法。 下面主要就第二類介紹幾個方法: 方法1:思想是用一個數組來儲存索引號,先隨機產生一個數組位置,然後把隨機抽取到的位置的索引號取出來,並把最後一個索引號複製到當前的數組位置,然後使隨機數的上限減一,具體如:先把這100個數放在一個數組內,每次隨機取一個位置(第一次是1-100,第二次是1-99,...),將該位置的數用最後的數代替。
int[] index = new int[15]; for (int i = 0; i < 15; i++) index = i; Random r = new Random(); //用來儲存隨機產生的不重複的10個數 int[] result = new int[10]; int site = 15;//設定上限 int id; for (int j = 0; j < 10; j++) { id = r.Next(1, site - 1); //在隨機位置取出一個數,儲存到結果數組 result[j] = index[id]; //最後一個數複製到當前位置 index[id] = index[site - 1]; //位置的上限減少一 site--; } |
方法2:利用Hashtable。
Hashtable hashtable = new Hashtable(); Random rm = new Random(); int RmNum = 10; for (int i = 0; hashtable.Count < RmNum; i++) { int nValue = rm.Next(100); if (!hashtable.ContainsValue(nValue) && nValue != 0) { hashtable.Add(nValue, nValue); Console.WriteLine(nValue.ToString()); } } |
方法3:遞迴,用它來檢測產生的隨機數是否有重複,如果取出來的數字和已取得的數字有重複就重新隨機擷取。
Random ra=new Random(unchecked((int)DateTime.Now.Ticks)); int[] arrNum=new int[10]; int tmp=0; int minValue=1; int maxValue=10; for (int i=0;i<10;i++) { tmp=ra.Next(minValue,maxValue); //隨機取數 arrNum=getNum(arrNum,tmp,minValue,maxValue,ra); //取出值賦到數組中 } ......... ......... public int getNum(int[] arrNum,int tmp,int minValue,int maxValue,Random ra) { int n=0; while (n<=arrNum.Length-1) { if (arrNum[n]==tmp) //利用迴圈判斷是否有重複 { tmp=ra.Next(minValue,maxValue); //重新隨機擷取。 getNum(arrNum,tmp,minValue,maxValue,ra);//遞迴:如果取出來的數字和已取得的數字有重複就重新隨機擷取。 } n++; } return tmp; } |
silverlight 2 Random 隨機數解決方案 來源:我和未來有約會 2008-06-17 01:21 by nasa using System; using System.Security.Cryptography; public class RNG { private static RNGCryptoServiceProvider rngp = new RNGCryptoServiceProvider(); private static byte[] rb = new byte[4]; /// <summary> /// 產生一個非負數的亂數 /// </summary> public static int Next() { rngp.GetBytes(rb); int value = BitConverter.ToInt32(rb, 0); if (value < 0) value = -value; return value; } /// <summary> /// 產生一個非負數且最大值在 max 以下的亂數 /// </summary> /// <param name="max">最大值</param> public static int Next(int max) { rngp.GetBytes(rb); int value = BitConverter.ToInt32(rb, 0); value = value % (max + 1); if (value < 0) value = -value; return value; } /// <summary> /// 產生一個非負數且最小值在 min 以上最大值在 max 以下的亂數 /// </summary> /// <param name="min">最小值</param> /// <param name="max">最大值</param> public static int Next(int min, int max) { int value = Next(max - min) + min; return value; } } |