官方释义:表示伪随机数生成器,这是一种能够产生满足某些随机性统计要求的数字序列的算法。
(1)为什么叫做“伪随机数生成器”?
Random本质上是利用一种算法,利用数学算法进行加密,从一组数中挑选出一个,但它们足够随机,可用于实际目的。(来自:微软)
实际上我们可以通过相同的数学算法对Random的结果进行预测,所以要进行加密安全,请不要使用!
1、Random下面的用法在数组当中添加随机数,只适用于byte和double两种类型(以下示例byte)
- byte[] bytes1 = new byte[100];
- byte[] bytes2 = new byte[100];
-
- for(int i = 0; i < bytes1.Length; i++)
- {
- Console.WriteLine(bytes1[i]);
- }
-
- Console.WriteLine();
-
- Random rnd1 = new Random();
- Random rnd2 = new Random();
-
- rnd1.NextBytes(bytes1);
-
- for(int i = 0; i < bytes1.Length; i++)
- {
- Console.WriteLine(bytes1[i]);
- }
-
-
- //输出结果
- /*
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
-
- 172
- 94
- 240
- 51
- 128
- 54
- 100
- 46
- 63
- 219
- 234
- 183
- 227
- 253
- 16
- 226
- 216
- 155
- 130
- 191
- 153
- 124
- 87
- 71
- 147
- 233
- 22
- 64
- 216
- 111
- 4
- 105
- 169
- 249
- 32
- 232
- 176
- 160
- 124
- 156
- 171
- 109
- 43
- 165
- 191
- 120
- 38
- 14
- 96
- 56
- 192
- 127
- 24
- 225
- 142
- 47
- 7
- 168
- 159
- 150
- 31
- 35
- 85
- 208
- 214
- 129
- 13
- 233
- 221
- 39
- 50
- 55
- 30
- 229
- 20
- 43
- 81
- 177
- 136
- 27
- 195
- 8
- 224
- 160
- 174
- 132
- 80
- 200
- 107
- 240
- 225
- 7
- 0
- 230
- 124
- 136
- 23
- 91
- 206
- 62
- */
-
-
2、也可用于从string[] 中随机挑选一个,返回的是他的下标值(int)
- Random rnd = new Random();
- string[] malePetNames = { "Rufus", "Bear", "Dakota", "Fido",
- "Vanya", "Samuel", "Koani", "Volodya",
- "Prince", "Yiska" };
- string[] femalePetNames = { "Maggie", "Penny", "Saya", "Princess",
- "Abby", "Laila", "Sadie", "Olivia",
- "Starlight", "Talla" };
-
- // Generate random indexes for pet names.
- int mIndex = rnd.Next(malePetNames.Length);
- int fIndex = rnd.Next(femalePetNames.Length);
-
- // Display the result.
- Console.WriteLine("Suggested pet name of the day: ");
- Console.WriteLine(" For a male: {0}", malePetNames[mIndex]);
- Console.WriteLine(" For a female: {0}", femalePetNames[fIndex]);
-
- // The example displays output similar to the following:
- // Suggested pet name of the day:
- // For a male: Koani
- // For a female: Maggie
-
- (来自:微软)
3、简单用法(比较常规的用法)
- Random rnd = new Random();
- int str=rnd.Next(1,6);//从1到5之间随机选择一个数字
- int nol=rnd.Next(6);//从0到5之间随机选择一个数字
上述我们向您讲述了三种用途,但这不是本文的重点,我们主要在这里是要讨论的是它的注意事项:(这非常重要)
详情参见:Random 类 (System) | Microsoft Docs
1、使用时请不要过多的实例化Random对象,像这样(这会消耗太多的计算)
- Random rnd = new Random();
- int str=rnd.Next(1,6);//从1到5之间随机选择一个数字
-
-
- Random nor = new Random();
- int nol=nor.Next(6);//从0到5之间随机选择一个数字
2、在线程当中注意保护Random
如果应用从多个线程调用方法,则必须使用同步对象来确保一次只有一个线程可以访问随机 Random 数生成器。 如果不确保以线程安全的方式访问对象,则对返回随机数的方法的调用 Random 将返回 0。(微软)
请确保在使用过程中不会有多个线程同时调用此方法,让他们有序调用。
在游戏当中应用:
有52张牌,需要抽取9张牌分发给三个人,使用随机数该如何制作?
- int[] Num = new int[52];
- Random rd = new Random();
- int num;
- bool flag;
-
- for (int i = 0; i < 52; i++)
- {
- do
- {
- flag = true;
- num = rd.Next(53);
- for (int j = 0; j < i; j++)
- {
- if (num == Num[j])
- {
- flag=false;
- break;
- }
- }
- }
- while (!flag);
- {
- Num[i] = num;
- }
-
- }
-
- //选择前9个
-
- for (int i = 0; i < 9; i++)
- {
- Console.WriteLine(Num[i]);
- }
-
-------------------------------------以下是更新内容-------------------------------------
c#的随机数种子
ok,先来简单的说下为什么要用随机数种子
主要的原因是希望我们随机出来的数字“尽可能的”不重复、
为什么是尽可能?
这是因为Random本质上是一种数字序列的算法,所以避免不了出现重复相同。
但为了尽量随机,让他不一致,因此使用随机数种子
random首先要考虑线程问题,因此需要使用lock锁
但如果你在unity中使用,也建议你为了线程安全使用,这并不强制,这需要您注意处理伪线程。
为了对新手友好,代码如下:
- Object game = new Object();//线程锁
-
- Random random = new Random((int)DateTime.Now.Ticks);//随机数
- //这里面是获取你当前的时间信息作为种子来进行随机的,要求是一个整数作为种子
- 注(1)
- List<int> ints = new List<int>();//将随机出来的数字保存到集合
-
- lock (game) //加线程锁,保护线程
- {
-
-
- for (int i = 0; i < 50; i++)//随机50个对象
- {
- int ran = random.Next(0, 100);//指定范围0——100
-
- if (!ints.Contains(ran)) //如果在集合中没有相同的数字添加到集合中
- {
- ints.Add(ran);
- }
- }
-
- }
-
- for (int i = 0; i < ints.Count; i++) //输出集合中的数字,如果你要使用的话,也可以选择前几个数字
- {
- Console.WriteLine(ints[i]);
- }
-
-
-
- Console.ReadKey();
注(1):
这里使用时间是为了让他足够随机,因为我们的时间是在不断变化的,这样确保了种子的随机性,但random选取种子会有15ms的一个随机序列生成,时间很短,这也就会导致会有一定重复的可能性
为了剔除这种随机出来相同的数字,我们将出来不同的数字添加到集合中,来以此确保它不会重复。