随机数产生算法

合集下载

实验报告随机数

实验报告随机数

一、实验目的1. 理解随机数生成的原理和过程。

2. 掌握常见随机数生成算法。

3. 分析随机数生成的性能和特点。

二、实验原理随机数在计算机科学、密码学、统计学等领域有着广泛的应用。

随机数生成算法是指从某种随机过程中产生一系列看似随机数的算法。

本实验主要研究以下几种随机数生成算法:1. 线性同余法(Linear Congruential Generator,LCG)2. Xorshift算法3. Mersenne Twister算法三、实验环境1. 操作系统:Windows 102. 编程语言:Python3. 实验工具:Jupyter Notebook四、实验步骤1. 线性同余法(LCG)实验(1)编写LCG算法函数```pythondef lcg(seed, a, c, m, n):random_numbers = []x = seedfor _ in range(n):x = (a x + c) % mreturn random_numbers```(2)设定参数并生成随机数```pythonseed = 12345a = 1103515245c = 12345m = 231n = 1000random_numbers = lcg(seed, a, c, m, n) print(random_numbers)```2. Xorshift算法实验(1)编写Xorshift算法函数```pythondef xorshift(seed, n):random_numbers = []x = seedfor _ in range(n):x ^= (x << 13)x ^= (x >> 17)x ^= (x << 5)return random_numbers```(2)设定参数并生成随机数```pythonseed = 12345n = 1000random_numbers = xorshift(seed, n)print(random_numbers)```3. Mersenne Twister算法实验(1)安装Mersenne Twister算法库```shellpip install numpy```(2)编写Mersenne Twister算法函数```pythonimport numpy as npdef mt19937(seed):random_numbers = np.random.RandomState(seed) return random_numbers.rand(n)n = 1000random_numbers = mt19937(12345)print(random_numbers)```五、实验结果与分析1. 线性同余法(LCG)生成的随机数序列具有较好的随机性,但存在周期性,当n足够大时,周期将变得非常明显。

随机数算法原理

随机数算法原理

随机数算法原理
随机数算法是一种用于生成随机数序列的算法。

它的原理基于数学函数和随机化技术,以确保生成的序列是在一定范围内具有随机性的。

其中一种常用的随机数算法是线性同余法。

其原理是基于一个线性递推关系,通过对前一个随机数乘以一个常数,再加上另一个常数,最后对一个大整数取模,得到下一个随机数。

具体的公式为:
Xn+1 = (a * Xn + c) mod m
其中,Xn代表当前的随机数,Xn+1代表下一个随机数,a和c是常数,m是模数。

通过不同的常数选择,可以得到不同范围内的随机数。

同时,为了提高随机性,常数a和c需要是比较大的素数,模数m
需要是一个较大的整数。

此外,初始种子X0也需要是一个随机的整数,以确保生成的序列具有更好的随机性。

除了线性同余法,还有其他一些常见的随机数算法,例如乘积法、平方取中法、梅森旋转算法等。

每种算法都有其特定的原理和适用范围,选择适合的算法取决于具体的应用需求和随机性要求。

总之,随机数算法通过使用数学函数和随机化技术,生成具有随机性的数列。

选择合适的算法和参数可以得到不同范围内、
不同随机性要求的随机数序列。

这些随机数在计算机科学、密码学、模拟实验等领域有着广泛的应用。

随机数的算法分析

随机数的算法分析

随机数的算法分析随机数的算法分析1-0:Microsoft VC++产生随机数的原理:Srand ( )和Rand( )函数。

它本质上是利用线性同余法,y=ax+b(mod m)。

其中a,b,m 都是常数。

因此rand的产生决定于x,x被称为Seed。

Seed需要程序中设定,一般情况下取系统时间作为种子。

它产生的随机数之间的相关性很小,取值范围是0—32767(int),即双字节(16位数),若用unsigned int 双字节是65535,四字节是4294967295,一般可以满足要求。

1-1:线性同余法:/P>其中M是模数,A是乘数,C是增量,为初始值,当C=0时,称此算法为乘同余法;若C ≠0,则称算法为混合同余法,当C取不为零的适当数值时,有一些优点,但优点并不突出,故常取C=0。

模M大小是发生器周期长短的主要标志,常见有M为素数,取A为M的原根,则周期T=M-1。

例如:a=1220703125a=32719 (程序中用此组数)a=16807代码:void main( ){const int n=100;double a=32719,m=1,f[n+1],g[n],seed;m=pow(2,31);cout<<"设置m值为"<<m-1<<endl;< p="">cout<<"输入种子"<<="">cin>>seed;f[0]=seed;for(int i=1;i<=n;i++) //线性同余法生成随机数{f[i]=fmod((a*f[i-1]),(m-1));g[i-1]=f[i]/(m-1);cout.setf(ios::fixed);cout.precision(6); //设置输出精度cout<<i<<" "<<'\t'<<g[i-1]<<endl;<="" p="">}}结果分析:统计数据的平均值为:0.485653统计数据的方差为:0.3205761-2:人字映射递推公式/P>就是有名的混沌映射中的“人字映射”或称“帐篷映射”,它的非周期轨道点的分布密度函数:人字映射与线性同余法结合,可产生统计性质优良的均匀随机数。

随机数算法

随机数算法

随机数算法简介随机数在计算机科学和信息安全领域扮演着重要角色。

随机数算法用于生成一系列看似随机的数字,这些数字在统计上是均匀分布、不可预测的。

本文将介绍几种常见的随机数算法,包括伪随机数算法和真随机数算法,以及它们的优缺点和应用场景。

伪随机数算法伪随机数算法是一种基于确定性计算的生成随机数的方法。

通过一个初始种子(seed),该算法按照一定规则生成一系列数字。

由于算法的确定性,相同的初始种子将产生相同的随机数序列。

线性同余法线性同余法是最常见的伪随机数生成算法之一。

它通过以下公式计算随机数:X(n+1) = (a × X(n) + c) mod m其中,X(n)表示当前的随机数,X(n+1)表示下一个随机数,a、c、m是事先确定的常数。

这个算法的优点是简单、高效,也易于实现。

然而,如果选择的参数不当,可能产生周期较短或重复的随机数序列。

梅森旋转算法梅森旋转算法是一类伪随机数算法的统称,它们使用一个巨大的状态空间来生成随机数。

最著名的梅森旋转算法是梅森旋转发生器(Mersenne Twister)。

梅森旋转算法的优点是周期非常长,产生的随机数序列质量较高。

它的缺点是占用内存较大,生成随机数的速度相对较慢。

真随机数算法真随机数算法是通过物理过程来生成随机数,例如电子噪声、放射性衰变等。

相比于伪随机数算法,真随机数算法具有更高的随机性和不可预测性。

硬件随机数生成器硬件随机数生成器是一种基于物理过程的真随机数生成器。

它利用物理设备(如热噪声源、放射性衰变)产生的不可预测的随机事件来生成随机数。

由于依赖于硬件设备,硬件随机数生成器通常安全性较高,但成本也较高。

环境噪声环境噪声是通过采集环境中的噪声信号来生成随机数。

这些噪声信号可以是来自于温度、湿度、大气压力等方面的变化。

环境噪声具有很高的随机性,可以被用作真随机数的来源。

由于环境噪声易于采集和获取,这种方法相对来说比硬件随机数生成器更容易实现。

10以内随机数生成的算法

10以内随机数生成的算法

10以内随机数生成的算法引言:在计算机科学中,随机数生成是一个常见的需求。

对于某些应用程序和算法来说,需要生成一些随机数来模拟真实世界中的随机事件。

本文将介绍一种生成10以内随机数的算法,该算法能够生成不重复的随机数,并且符合要求的随机性。

算法原理:该算法的原理是通过调用计算机系统提供的随机数生成函数,生成一个范围在0到9之间的随机数。

然后通过一个数组来记录已经生成的随机数,以防止重复生成。

当需要生成下一个随机数时,先判断该数是否已经在数组中存在,如果存在,则重新生成一个随机数,直到生成一个不重复的随机数为止。

这样就能够确保生成的随机数在10以内并且不重复。

具体实现:我们需要定义一个数组来记录已经生成的随机数。

假设该数组名为"randomArray",长度为10,并且初始状态下所有元素都为false。

这样,当某个元素对应的值为true时,表示该随机数已经被生成过。

然后,我们需要调用计算机系统提供的随机数生成函数。

一般来说,可以使用rand()函数来生成一个伪随机数,该函数返回一个范围在0到RAND_MAX之间的整数。

为了将随机数限制在10以内,我们可以使用取余运算符%,将生成的随机数对10取余,得到一个范围在0到9之间的随机数。

接下来,我们需要判断生成的随机数是否已经存在于数组中。

我们可以使用一个循环来遍历数组,判断数组中是否存在与生成的随机数相等的元素。

如果存在,则重新生成一个随机数,直到生成一个不重复的随机数为止。

我们将生成的随机数存入数组中,并将对应的数组元素设置为true,表示该随机数已经被生成过。

这样,下次生成随机数时就可以通过查找数组来判断是否重复。

算法实例:下面是一个示例代码,演示了如何实现该算法:```pythonimport randomrandomArray = [False] * 10def generateRandomNumber():while True:randomNumber = random.randint(0, 9)if randomArray[randomNumber] == False:randomArray[randomNumber] = Truereturn randomNumber# 生成10个不重复的随机数for i in range(10):randomNumber = generateRandomNumber()print(randomNumber)```总结:通过上述算法,我们可以生成10以内不重复的随机数。

随机数讲解

随机数讲解

随机数讲解随机数是一种随机生成数字的算法,可以用于各种不同的应用中。

在现代科技中,随机数已经成为了许多应用不可或缺的一部分,例如密码学、数据加密、人工智能、金融等等。

本文将介绍随机数的生成原理、应用场景以及如何使用随机数。

一、随机数生成原理随机数生成算法最基本的原则是“生成一个序列唯一的数字”。

为了实现这个目标,随机数生成器会通过多种算法生成一个序列数字。

现在我们来介绍几种常见的随机数生成算法。

1.Pseudo Random Number Generator(PRNG)PRNG是一种基于伪随机数生成的随机数生成器。

它使用的是一个序列伪随机数种子,通过这个种子来计算出其他的伪随机数。

每次生成的随机数都应该是不同的,并且可以通过简单的加法、减法、乘法等操作与之前的随机数进行区分。

2.True Random Number Generator(TRNG)TRNG是一种真正的随机数生成器,它使用的是一个物理随机数种子。

这个种子可以随着时间的推移而改变,因此生成的随机数可以保证是不同的。

TRNG通过一系列的数学运算来生成真正的随机数,并且这些随机数可以精确地表示任何种子。

3.Secure Random Number Generator(SRNG)SRNG是一种安全的随机数生成器,主要用于金融和密码学等领域。

它使用的是一个安全的随机数种子,并且可以生成同时满足NIST GG 88-1和FIPS140-2标准的随机数。

为了保证随机性,SRNG在生成随机数之前会对种子进行一个非线性变换,以消除种子对随机性造成的微小影响。

二、随机数应用场景随机数在许多应用中都可以使用,下面列举了其中的一些应用场景。

1.密码学随机数在密码学中有着重要的应用,主要用于生成加密密钥、随机密码以及数字签名等。

这些数字都是基于随机数生成的,可以确保密码的复杂度和安全性。

2.数据加密随机数也可以用于数据加密中。

通过使用随机数作为密钥,数据加密算法可以确保密钥的复杂度和安全性,以保护数据的安全。

随机数生成公式

随机数生成公式

随机数生成公式随机数生成公式是一种计算机程序中常用的技术,可以生成随机的数字,用于模拟和实验等场景中。

本文将介绍几种常见的随机数生成公式及其应用场景。

一、线性同余法(Linear Congruential Method)线性同余法是一种简单而又高效的随机数生成方法,其公式为:Xn+1 = (aXn + c) mod m其中Xn为当前随机数,a、c、m为常数,mod为模运算符。

该公式的原理是通过不断迭代计算,每次得到一个新的随机数。

该方法的优点是计算速度快,缺点是会产生周期性重复的随机数序列。

该方法常用于模拟和实验场景中。

二、梅森旋转算法(Mersenne Twister)梅森旋转算法是一种广泛应用的随机数生成方法,其公式为:Xn+1 = Xn⊕(Xn >> u)其中Xn为当前随机数,⊕为异或运算符,>>为右移运算符,u为常数。

该公式的原理是通过对当前随机数进行位运算,得到一个新的随机数。

该方法的优点是生成的随机数序列较为均匀,缺点是计算速度较慢。

该方法常用于加密和安全场景中。

三、高斯分布随机数生成公式(Gaussian Distribution)高斯分布随机数生成公式是一种生成符合正态分布(高斯分布)的随机数的方法,其公式为:X = μ + σ * Z其中μ为均值,σ为标准差,Z为符合标准正态分布的随机数。

该公式的原理是通过对标准正态分布进行线性变换,得到符合正态分布的随机数。

该方法的优点是生成的随机数符合实际分布规律,缺点是计算量较大。

该方法常用于金融和统计场景中。

四、指数分布随机数生成公式(Exponential Distribution)指数分布随机数生成公式是一种生成符合指数分布的随机数的方法,其公式为:X = -ln(U) / λ其中U为符合均匀分布的随机数,ln为自然对数函数,λ为指数分布的参数。

该公式的原理是通过对均匀分布进行变换,得到符合指数分布的随机数。

正态分布随机数生成算法

正态分布随机数生成算法

正态分布随机数生成算法正态分布(也称为高斯分布)是统计学中非常重要的概率分布之一、生成服从正态分布的随机数是许多应用程序和模型的基本要求之一、下面将介绍几种常见的正态分布随机数生成算法。

1. Box-Muller算法:Box-Muller算法是最常见的生成服从标准正态分布(均值为0,标准差为1)的随机数的方法之一、它的基本思想是利用两个独立的、均匀分布的随机数生成一个标准正态分布的随机数对。

具体步骤如下:-生成两个独立的、均匀分布在(0,1)区间的随机数u1和u2- 计算z1 = sqrt(-2 * ln(u1)) * cos(2 * pi * u2)和z2 =sqrt(-2 * ln(u1)) * sin(2 * pi * u2)两个服从标准正态分布的随机数。

2. Marsaglia极坐标法:Marsaglia极坐标法也是一种生成服从标准正态分布随机数的方法。

它基于极坐标系的性质,即生成的随机数对所对应的点的距离(模长)服从Rayleigh分布,方向(角度)均匀分布。

具体步骤如下:-生成两个独立的、均匀分布在(-1,1)区间的随机数u1和u2-计算s=u1^2+u2^2,如果s>=1,则重新生成u1和u2- 计算f = sqrt(-2 * ln(s) / s)和z1 = f * u1,z2 = f * u2即为两个服从标准正态分布的随机数。

3. Box-Muller/Box-Muller Transformation组合方法:此方法是将两种算法结合起来,先用Box-Muller算法生成两个服从标准正态分布的随机数,然后进行线性变换得到多种均值和标准差的正态分布随机数。

4. Ziggurat算法:Ziggurat算法是一种近似生成服从标准正态分布随机数的算法,它基于分段线性逼近的思想。

Ziggurat算法将正态分布的概率密度函数拆分成多个长方形和一个截尾尾巴(tail)部分。

具体步骤如下:- 初始化一个包含n个长方形的Ziggurat结构,每个长方形包括一个x坐标、一个y坐标、一个面积。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

最近做了一些Tencent及几家公司的面试题,发现有一种关于产生随机数的类型的题目。

看到多有大牛们做出来,而且效率很高,也有不知道怎么做的,最近根据几个产生随机数的题目整理一下,发现所有的类似题目可以用一种万能钥匙解决。

故分享,欢迎发表不同看法,欢迎吐槽。

题目一:给定能随机生成整数1到5的函数,写出能随机生成整数1到7的函数。

利用随机函数rand()函数生成一个等概率随机生成整数1到5的函数Rand5(),然后根据Rand5()生成Rand7(),代码如下:
[cpp]view plaincopy
1.#include <iostream>
ing namespace std;
3.int Rand5()
4.{
5.int n =1 + rand()%5;
6.return n;
7.}
8.int Rand7()
9.{
10.int n ,tmp1 ,tmp2;
11.do
12. {
13. tmp1 = Rand5();
14. tmp2 = Rand5();
15. n = (tmp1-1)*5+tmp2;//n是可以取1~25的随机的数。

16. } while (n>21);//当n>21舍去,这样n只能取1~21,对7取模就能取1~7之间的随机

17.
18.return 1+n%7;
19. }
20.int main()
21.{
22.for (int i = 0 ; i < 100 ; i++)
23. {
24. cout<<Rand5()<<" ";
25. }
26. cout<<endl;
27.for (int j = 0 ; j < 100 ; j++)
28. {
29. cout<<Rand7()<<" ";
30. }
31. cout<<endl;
32.return 0;
33.}
生成结果如下:
算法的关键就是两次运用
Rand5(); tmp1 = Rand5();tmp2 = Rand5();n = (tmp1-1)*5+tmp2;n的最大值为25,为了满足产生的1到7等概率,所以n最大应该取7的倍数,所以当n>21时应舍去,为了测试是否概率真的相等,写一个测试函数:
[cpp]view plaincopy
1.int main()
2.{
3.const int Max = 10000000;
4.int a[7] = {0};
5.for (int ii = 0 ; ii < Max ; ++ii)
6. {
7.switch (Rand7())
8. {
9.case 1:a[0]++;break;
10.case 2:a[1]++;break;
11.case 3:a[2]++;break;
12.case 4:a[3]++;break;
13.case 5:a[4]++;break;
14.case 6:a[5]++;break;
15.case 7:a[6]++;break;
16.default:cerr<<"Error!"<<endl;exit(-1);
17. }
18. }
19.for (int r = 0 ; r<7 ; r++)
20. {
21. cout<< r+1<<":"<<setw(6)<<setiosflags(ios::fixed)<<setprecision(2)<<
double(a[r])/Max*100<<"%"<<endl;
22. }
23.return 0;
24.}
题目二:已知rand7() 可以产生 1~7 的7个数(均匀概率),利用rand7() 产生rand10() 1~10(均匀概率)
解法与上面类似,同样只用两个rand7()生成rand10()即可。

各位可以自己试试。

另外,看见一个大牛的方法,似乎比以上更为简单,现贴出代码,供各位欣赏:[cpp]view plaincopy
1.int rand10()
2.{
3.int temp1;
4.int temp2;
5.do
6. {
7. temp1 = rand7();
8. }while(temp1>5);
9.do
10. {
11. temp2 = rand7();
12. }while(temp2>2);
13.return temp1+5*(temp2-1);
14.}
temp1只取1到5,temp2只取1到2,即可等概率取到1到10。

个人觉得两种方法有异曲同工之妙,所以大多数利用一个等概率随机数构造另外一个等概率随机数,只需两次使用概率函数即可。

相关文档
最新文档