关于C++,Java和Python中的随机数生成法
来源:互联网 发布:python 改变工作路径 编辑:程序博客网 时间:2024/05/22 12:39
首先我们来说说C++中的随机数生成:
我们知道在C++用函数rand()获取的是一个0 ~ RAND_MAX之间的一个随机数。其中RAND_MAX的值为32767。
首先我们来分析两个程序:
#include <iostream>#include <string.h>#include <stdlib.h>#include <time.h>#include <stdio.h>using namespace std;int main(){ srand(time(0)); for(int i=0;i<10;i++) { int t = rand(); cout<<t<<endl; } return 0;}
#include <iostream>#include <string.h>#include <stdlib.h>#include <time.h>#include <stdio.h>using namespace std;int main(){ for(int i=0;i<10;i++) { srand(time(0)); int t = rand(); cout<<t<<endl; } return 0;}
我们分别输出这两个程序的结果会发现,第一个程序结果为:
而第二个程序的结果是:
很明显,我们希望得到第一种结果。那么把srand(time(0))放到循环体内和放到循环体外有什么不同?
现在我来详细解释上面的结果。
我们首先要明确,对于函数srand(int num)和函数rand()它们是定义在头文件<stdlib.h>里的。
而srand(int num)函数的作用是散布num个随机数,当用rand()时,获取的是散布的这num个数中的任意一个。
rand()函数返回随机数序列中的下一个数,实际上srand(int num)函数是一个伪随机数序列,序列中的每一个数是由对其前面的数字进行复杂变换得到的。为了模仿真正的随机性,首先要调用srand()函数给序列设置一个种子。为了更好地满足随机性,使用了时间函数time(),以便取到一个随时间变化的值,使每次运行rand()函数时从srand()函数所得到的种子值不相同。伪随机数生成器将作为 "种子 "的数当作初始整数传给函数。这粒种子会使这个球(生成伪随机数)一直滚下去。
time(0)返回的是一个整数,这个整数的值等于1970年1月1日0时0分0秒至现在的秒数。所以这样随着时间的不同,生成的随机数的个数也不同。
至于第二个程序中所有的数字都相同,那是因为本身循环并不多,每个循环时间间隔很近,所以实际上time(0)的值都一样。这样相当于每次都是取随机序列中的第一个元素,那当然就一样了。
上面提到了生成的随机序列实际上是一个伪随机序列,其实后面的数是根据前面的数经过复杂的变换得到的。我们可以来看看srand(int num)函数的大体实现原理。
#include <iostream>#include <string.h>#include <time.h>#include <stdio.h>#define RANDOM_MAX 0x7FFFFFFFusing namespace std;static long do_rand(unsigned long *value){ /* 这个算法保证所产生的值不会超过(2^31 - 1) 这里(2^31 - 1)就是 0x7FFFFFFF。而 0x7FFFFFFF 等于127773 * (7^5) + 2836,7^5 = 16807。 整个算法是通过:t = (7^5 * t) mod (2^31 - 1) 这个公式来计算随机值,并且把这次得到的值,作为 下次计算的随机种子值。 */ long quotient, remainder, t; quotient = *value / 127773L; remainder = *value % 127773L; t = 16807L * remainder - 2836L * quotient; if (t <= 0) t += 0x7FFFFFFFL; return ((*value = t) % ((unsigned long)RANDOM_MAX + 1));}static unsigned long next = 1;int rand(void){ return do_rand(&next);}void srand(unsigned int seed){ next = seed;}int main(){ srand((unsigned)(time(NULL))); for(int i=0;i<100; i++) { if(i % 10 == 0) puts(""); printf("%d\t",rand()%99+1); } return 0;}
经过上面的分析,就很容易获取一个0 ~ 1之间的一个随机小数。因为随机数中RAND_MAX最大,那么就很容易了:
double get_rand(){ return (double)rand() / (double)RAND_MAX;}
在很多重要的算法中,我们没有用srand(int num)函数而直接用rand()来获取随机数,比如Miller素数测试,大数分解等等。这时实际上有一个默认的随机种子,这个随机序列是固定的。
那么,Java中的随机数又是怎么样的呢?
在java语言中生成随机数的方法有三种:
1.通过System.currentTimeMillis()方法获取当前时间的毫秒数(long);
2.通过Math.random()方法获取一个介于0到1之间的伪随机数;
3.通过Random类获取随机数;
在Random类中,使用了一个48位的种子数,并通过线性同于公式进行随机数的生成(参考《The Art of Computer Programming, Volume 2》书的3.2.1节。
Random rand = new Random(System.currentTimeMillis());
在Java 中我们可以使用java.util.Random类来产生一个随机数发生器。它有两种形式的构造函数,分别是Random()和Random(long seed)。Random()使用当前时间即System.currentTimeMillis()作为发生器的种子,Random(long seed)使用指定的seed作为发生器的种子。
随机数发生器(Random)对象产生以后,
通过调用不同的method:nextInt(),nextLong(),nextFloat(),nextDouble()等获得不同类型随机数。
生成随机数
Random random = new Random();
Random random = new Random(100);//指定种子数100
random调用不同的方法,获得随机数。
import java.util.Random;public class Srand {public static void main(String[] args){Random random = new Random(100);System.out.println(random.nextInt());System.out.println(random.nextFloat());System.out.println(random.nextBoolean());}}
注意Java的Math类中也有一个random()方法,即Math.random()返回的是一个范围为[0.0,1.0)之间的小数。
在Java中,下面的代码表示生成10个0到49之间的随机数。
import java.util.Random;public class Srand {public static void main(String[] args){Random random = new Random();for(int i=0;i<10;i++){System.out.println(random.nextInt(50));}}}
在Python中,随机数的生成需要先导入random模块。
1.random.random()用于生成一个0到1的随机符小数: 0 <= n < 1.0
>>> import random>>> random.random()0.9658869832707923>>>
2.random.uniform的函数原型为:random.uniform(a, b),用于生成一个指定范围内的随机符点数,两个参数一个是上限,一个是下限。如果a > b,则生成的随机数n: a <= n <= b。如果 a<b, 则 b <= n <= a。
>>> random.uniform(1,10)8.241539762435707>>> random.uniform(10,1)5.2752945576846075>>>
3.random.randint()的函数原型为:random.randint(a, b),用于生成一个指定范围内的整数。其中参数a是下限,参数b是上限,生成的随机数n: a <= n <= b
>>> random.randint(1,10)8
>>> random.randrange(0,100,2)20
>>> random.choice('ACdreamers')'e'
6.random.shuffle的函数原型为:random.shuffle(x[, random]),用于将一个列表中的元素打乱。
>>> p = ['ACdreamers','Hello','World','NiHao']>>> random.shuffle(p)>>> print p['World', 'Hello', 'ACdreamers', 'NiHao']>>>
7.random.sample的函数原型为:random.sample(sequence, k),从指定序列中随机获取指定长度的片断。sample函数不会修改原有序列。 如果k大于sequence元素个数的话会报错。
>>> random.sample('ACdreamers',2)['s', 'a']>>>
- 关于C++,Java和Python中的随机数生成法
- python中的随机数生成
- Java和JS中的随机数生成办法
- python,c++,C#随机数生成
- Python 中的random模块用于生成随机数
- Python生成指定区间中的随机数
- Python中的random模块用于生成随机数
- 利用Python中的random模块生成随机数
- 关于c中的随机数的设定
- C/C++:随机数生成
- 关于随机数生成的一些代码(C/C++)
- C语言和java中生成随机数的原理和方法
- 关于JAVA中的Random()获取随机数
- 关于C++和CMD中的随机数
- Python生成随机数
- python 随机数生成
- python随机数生成
- Python生成随机数
- 结构体与共用体
- 入职第一天
- 零基础GitHub入门教程
- NYOJ 65 另一种阶乘问题
- J2EE入门必备
- 关于C++,Java和Python中的随机数生成法
- div+css学习笔记7
- 日记
- 湖南省桃江县灰山港中国邮政储蓄银行 属于哪个支行
- Perl 模块安装方式一览
- Phone Number
- WebService学习笔记系列之二----通过wsimport的方式调用WebService
- 您的鼓励,我的动力!(CSDN 2013年度博客之星评选)
- Shopping