C++ rand() 、srand() 和 蒙克卡罗方法

C++ rand() 和 srand()

1、rand()不需要传入参数,使用该函数能够返回一个从0到最大随机数的任意整数,最大随机数的大小通常是固定的一个大整数。

2、在0 ~ 99 这100个整数中随机取一个整数
可以表示为:int num = rand() % 100;

3、如果下界不为零,例如要产生 1 ~ 100的数字
可以表示为:int num = rand() % 100 + 1;

4、一般表示为:int num = rand() % n +a;
其中的 a 是起始值,n - 1 + a 是终止值,n 是整数的范围。

5、若要产生0 ~ 1之间的小数,则可以先取得0~10的整数,然后均除以10即可得到“随机到十分位”的10个随机小数。
若要得到“随机到百分位”的随机小数,则需要先得到0~100的10个整数,然后均除以100(即取出的小数的精度由mod的值所决定)

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
	//取任意数,数的范围在0到一个比较大的数字之间 
	for(int i = 1; i <= 1e2; i++)
		printf("%d\n", rand()); 
	
	//在0到99中随机取一个数字 
	for(int i = 1; i <= 1e2; i++)
		printf("%d\n", rand() % 100); 
	
	//在10到109中随机取一个数字
	for(int i = 1; i <= 1e2; i++)
		printf("%d\n", rand() %100 + 10); 
	
	//产生0 ~ 1之间的小数,具体的精度由mod决定 
	for(int i = 1; i <= 1e2; i++)
		printf("%lf\n", (rand() % 10) * 1.0 / 10 );
		
	return 0; 
} 

我们会发现,上面这段代码进行多次编译,结果都是一样的。

虽然rand()产生的数是随机数,但是这些是输出的结果在定义之后是不会再变化了(也就是编译器重新编译后输出的结果是相同的)。

如果这时候我们希望每次编译后输出的结果不相同,那么我们就需要用到srand() 和 time() 函数了。

time(0)可以输出一个与时间有关的数,再结合srand()函数即可产生真正的随机数.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
	srand(int(time(0)));
	//取任意数,数的范围在0到一个比较大的数字之间 
	for(int i = 1; i <= 1e2; i++)
		printf("%d\n", rand()); 
	
	//在0到99中随机取一个数字 
	for(int i = 1; i <= 1e2; i++)
		printf("%d\n", rand() % 100); 
	
	//在10到109中随机取一个数字
	for(int i = 1; i <= 1e2; i++)
		printf("%d\n", rand() %100 + 10); 
	
	//产生0 ~ 1之间的小数,具体的精度由mod决定 
	for(int i = 1; i <= 1e2; i++)
		printf("%lf\n", (rand() % 10) * 1.0 / 10 );
	return 0; 
} 

蒙特卡罗方法

蒙特卡罗方法,也称统计模拟方法,是一种以概率统计理论为指导的数值计算方法。是指使用随机数(或更常见的伪随机数)来解决很多计算问题的方法。

计算圆周率
用蒙特卡罗方法,让计算机每次随机生成两个0到1之间的数,看以这两个实数为横纵坐标的点是否在单位圆内。
生成一系列随机点,统计单位圆内的点数与总点数,当随机点获取越多时,其结果越接近于圆周率。

不过准确度还是不高:
首先,计算机产生的随机数是受到存储格式的限制的,是离散的,并不能产生连续的任意实数;
其次,上述做法将平面分割成一个个网格,在空间也不是连续的,由此计算出来的面积当然与圆或多或少有差距。

个人理解
就是先进行随机的操作,然后对这些操作记录进行统计,根据这些数据推测/获取答案的近似值。

我们用C中的rand()函数实现模拟。

参考来源

wiki百科
https://zh.wikipedia.org/wiki/蒙地卡羅方法

博客
https://www.cnblogs.com/yuehouse/p/10116691.html

博客
https://blog.csdn.net/zhuangjinhua/article/details/79940123

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值