计算机的运行过程是一个确定的过程,每一条指令都是确定,因此从根本上来讲,计算机产生不了真正意义上的随机数。
那么伪随机数怎么理解呢?举个最简单的例子,要随机产生0~9十个数,那么计算机可以循环快速的给出0、1、2、3、4、5、6、7、8、9、0、1……这样的一个数列,这个数列并不是随机的,而是有规律的(所以才叫做伪随机),当我们按下按钮,或者点下鼠标的瞬间,机器停止,并显示最后的一个数字(有点类似于玩老虎机),这个过程我们挑选出来的数字好像是随机的,但其实并不是100%随机,只有我们去触发机器的那个时间点是随机的,其他都是有规律的,所以就是伪随机。
rand()函数就是给出一列数值(这列数值是被事先打乱,但是是固定的数值),所以属于伪随机数。只是机器执行到rand()函数的时间点是随机的,才让我们感觉执行结果是随机的一样。
我们在做能自动生成试卷的考试系统时,常常需要随机生成一组不重复的题目,在net
Framework中提供了一个专门用来产生随机数的类SystemRandom。
对于随机数,大家都知道,计算机不可能产生完全随机的数字,所谓的随机数发生器都是通过
一定的算法对事先选定的随机种子做复杂的运算,用产生的结果来近似的模拟完全随机数,这
种随机数被称作伪随机数。伪随机数是以相同的概率从一组有限的数字中选取的。所选数字并
不具有完全的随机性,但是从实用的角度而言,其随机程度已足够了。伪随机数的选择是从随
机种子开始的,所以为了保证每次得到的伪随机数都足够地“随机”,随机种子的选择就显得
非常重要。如果随机种子一样,那么同一个随机数发生器产生的随机数也会一样。一般地,我
们使用同系统时间有关的参数作为随机种子,这也是net Framework中的随机数发生器默认采
用的方法。
我们可以使用两种方式初始化一个随机数发生器:
第一种方法不指定随机种子,系统自动选取当前时间作为随机种子:
Random ro = new Random();
第二种方法可以指定一个int型参数作为随机种子:
int iSeed=10;
Random ro = new Random(10);
long tick = DateTimeNowTicks;
Random ran = new Random((int)(tick & 0xffffffffL) | (int) (tick >> 32));
这样可以保证99%不是一样。
之后,我们就可以使用这个Random类的对象来产生随机数,这时候要用到RandomNext()方
法。这个方法使用相当灵活,你甚至可以指定产生的随机数的上下限。
不指定上下限的使用如下:
int iResult;
iResult=roNext();
下面的代码指定返回小于100的随机数:
int iResult;
int iUp=100;
iResult=roNext(iUp);
而下面这段代码则指定返回值必须在50-100的范围之内:
int iResult;
int iUp=100;
int iDown=50;
iResult=roNext(iDown,iUp);
除了RandomNext()方法之外,Random类还提供了RandomNextDouble()方法产生一个范
围在00-10之间的随机的双精度浮点数:
double dResult;
dResult=roNextDouble();
但是用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 = rNext(1, site - 1);
//在随机位置取出一个数,保存到结果数组
result[j] = index[id];
//最后一个数复制到当前位置
index[id] = index[site - 1];
//位置的下限减少一
site--;
}
方法2:利用Hashtable。[NextPage]
Hashtable hashtable = new Hashtable();
Random rm = new Random();
int RmNum = 10;
for (int i = 0; hashtableCount < RmNum; i++)
{
int nValue = rmNext(100);
if (!hashtableContainsValue(nValue) && nValue != 0)
{
hashtableAdd(nValue, nValue);
ConsoleWriteLine(nValueToString());
}
}
方法3:递归,用它来检测生成的随机数是否有重复,如果取出来的数字和已取得的数字有重复就重新随机获取。
Random ra=new Random(unchecked((int)DateTimeNowTicks));
int[] arrNum=new int[10];
int tmp=0;
int minValue=1;
int maxValue=10;
for (int i=0;i<10;i++)
{
tmp=raNext(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<=arrNumLength-1)
{
if (arrNum[n]==tmp) //利用循环判断是否有重复
{
tmp=raNext(minValue,maxValue); //重新随机获取。
getNum(arrNum,tmp,minValue,maxValue,ra);//递归:如果取出来的数字和已取得的数字有重复就重新随机获取。
}
n++;
}
return tmp;
}
编译环境为:vs2013
产生1到3的整型随机数的代码如下:
#include<stdioh>
#include<timeh>
#include<stdlibh>
#define max 3 //这个函数的意义为:随机生成最大的数为3
#define min 1 //这个函数的意义为:随机生成最小的数为1
int main()
{
int num;
srand(time(0));
num = rand() % (max - min) + min; // 这里的意义,“%”为模运算
printf("随机数为:%d\n", num);
system("pause"); //这个代码可以让弹出的黑框不会一下就消失
return 0;
}
扩展资料:
根据密码学原理,随机数的随机性检验可以分为三个标准:
条件一、统计学伪随机性。统计学伪随机性指的是在给定的随机比特流样本中,1的数量大致等于0的数量,同理,“10”“01”“00”“11”四者数量大致相等。类似的标准被称为统计学随机性。满足这类要求的数字在人类“一眼看上去”是随机的。
条件二、密码学安全伪随机性。其定义为,给定随机样本的一部分和随机算法,不能有效的演算出随机样本的剩余部分。
条件三、真随机性。其定义为随机样本不可重现。实际上只要给定边界条件,真随机数并不存在,可是如果产生一个真随机数样本的边界条件十分复杂且难以捕捉(比如计算机当地的本底辐射波动值),可以认为用这个方法演算出来了真随机数。
随机数分为三类:
①伪随机数:满足第一个条件的随机数。
②密码学安全的伪随机数:同时满足前两个条件的随机数。可以通过密码学安全伪随机数生成器
计算得出。
③真随机数:同时满足三个条件的随机数。
首先要说的是,什么叫伪随机数计算机不会产生绝对随机的随机数,计算机只能产生“伪随机数”。其实绝对随机的随机数只是一种理想的随机数,即使计算机怎样发展,它也不会产生一串绝对随机的随机数。计算机只能生成相对的随机数,即伪随机数。伪随机数并不是假随机数,这里的“伪”是有规律的意思,就是计算机产生的伪随机数既是随机的又是有规律的。
补:大哥这是原话但已经很白话了还要怎么样你才能听明白认识字的应该都能懂了意思就是:世界上没有绝对的事情什么事都是相对的OK
序列α= 0110100,其中0和1的个数相差1。把α看成周期为7的无限序列,左移1位得,α1 = 1101000,把α1也看成周期为7的无限序列。 α= 0110100α1=1101000在一个周期里,α和α1的对应位置元素相同的位置有3个,元素不同的位置有4个,它们的差等于-1,这个数称为α的自相关函数在1处的值,记作。类似地,把α左移2位,3位,…6位,可以求出α的自相关函数在2处,3处,…6处的值也等于-1。当0 < s <7时,称为α的自相关函数的旁瓣值。从刚才所求出的结果知道,α= 0110100的自相关函数的旁瓣值只有一个:-1。像这样的序列称为伪随机序列或拟完美序列。
即,一个周期为v的无限序列,如果在一个周期里,0和1的个数相差1,并且它的自相关函数的旁瓣值只有一个:-1,则称它为伪随机序列或拟完美序列。α的自相关函数的旁瓣值的绝对值越大,就表明(或把的0和1互换得到的序列)与α越像。因此如果周期为v的序列α是一个伪随机序列,那么α不管左移几位(只要不是v的倍数),得到的序列都和α很不像,这样就很难分辨出α是什么样子。好比川剧的变脸,由于每一次都变得和演员的脸很不一样,因此很难知道演员自己的脸是什么样子。反之如果演员每一次化装后都跟他自己的脸有许多相同之处,那么就容易辨认演员长得什么样。这说明了用伪随机序列作为密钥序列,是比较安全的。
伪随机序列是用函数生成随机数。它并不真正是随机的。只是比较近似随机。
一个简单的随机数产生方法如下:
X0=345
Xn=(Xn-1A+B)/C
其中A,B,C是常数,上式每执行一次就生成一个伪随机数
还可以在数组中填入若干个数然后顺序取出进行模拟。性能好,但是这种随机数就很不象随机数了。 还有就是根据当前系统时间,内存值等等用函数生成了。
以上就是关于rand()函数产生的随机数为什么是伪随机数全部的内容,包括:rand()函数产生的随机数为什么是伪随机数、.net 下用C#产生一个永不重复10位随机数、C语言怎样产生一定范围的随机数等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!