C++:随机数的使用

一、前言

在很多算法中需要用到随机数,如模拟退火算法,粒子群算法,遗传算法,蚁群算法等,这些算法对随机数的质量要求较高,必须是均匀分布或者高斯分布随机数,下面介绍几种方式,不深入,但是实用。

环境:windows10,Dev-C++6.5

二、实现方法

此文所用头文件如下

#include <iostream>
#include <random>
#include <ctime>
#include <cstdio>
#include <iomanip>

using namespace std;

方式一、rand

rand函数采用线性同余法产生0-RAND_MAX之间任意随机数,不同的系统可能RAND_MAX大小不同,先看下本系统及编译器RAND_MAX的大小。

int main(void)
{
    cout << RAND_MAX << endl;
	return 0;
}

结果:32767

①、产生整数随机数0-10

int main(void)
{	
    for(int i= 1;i < 21;i++){
		cout << setw(8) <<  rand() % 10;
		if(i%5 == 0)
		  cout << endl;
	}
	return 0;
}
结果:
       1       7       4       0       9
       4       8       8       2       4
       5       5       1       7       1
       1       5       2       7       6

②、产生小数随机数0 - 1,小数点后3位有效

int main(void)
{	
    for(int i= 1;i < 21;i++){
		cout << setw(15) <<  (rand() % 1000  / 1000.0);
		if(i%5 == 0)
		  cout << endl;
	}
	return 0;
}

结果:
          0.041          0.467          0.334            0.5          0.169
          0.724          0.478          0.358          0.962          0.464
          0.705          0.145          0.281          0.827          0.961
          0.491          0.995          0.942          0.827          0.436

在①、②中,每次运行,得到的随机数都是相同的,这时需要添加随机种子,这样每次的结果都会不同了。

int main(void)
{	
    srand(time(NULL));	
    for(int i= 1;i < 21;i++){
		cout << setw(15) <<  (rand() % 1000  / 1000.0);
		if(i%5 == 0)
		  cout << endl;
	}
	return 0;
}

方式一在多线程运行的时候会出现随机数相同的情况,同时由于不同环境RAND_MAX不同,会给软件带来风险,而且随机数的精度不够高,比如RAND_MAX=32767,则最多小数点后5位。

方式二、mt19937

mt19937中19937是指最多可以2^19937个数不重复,这个远远大于RAND_MAX,足够我们使用。

同样,未了保证每次运行,生产的随机数不同,这里使用

  random_device rnd; //操作系统,CPU硬件取的随机种子 

这个随机种子基本是真正的随机数,来源于系统硬件,可以保证多线程运行任务时产生的随机数不同。在本系统中,random_device可输出最大、最小值如下,可以到,是个很大的值。

int main(void)
{	
//mt19937
	random_device rnd;	
	cout << "  max:" << rnd.max() << "  min:" << rnd.min()  <<  endl;
	return 0;
}

结果:  max:4294967295  min:0

下面演示产生0-100均匀分布随机数,整数。每次运行,结果不同。

int main(void)
{	
    random_device rnd; //操作系统,CPU硬件取的随机种子 
	mt19937 rng(rnd());//rng(time(NULL))随机种子只能精确到S,速度快会有问题 
	uniform_int_distribution<int> uni(0,100);//均匀分布 
	
    for(int i= 1;i < 21;i++){
		cout << setw(15) << uni(rng);
		if(i%5 == 0)
		  cout << endl;
	}
}

结果:
             28             56             38             44             87
             60             60              4             81             43
             76             55             82             88             57
             77             77             11             95             67

下面演示产生0-1均匀分布随机数,小数。每次运行,结果不同。

int main(void)
{	
    random_device rnd; //操作系统,CPU硬件取的随机种子 
	mt19937 rng(rnd());//rng(time(NULL))随机种子只能精确到S,速度快会有问题 
	uniform_real_distribution<double> unf(0,1);//均匀分布 
	
    for(int i= 1;i < 21;i++){
		cout << setw(15) << unf(rng);
		if(i%5 == 0)
		  cout << endl;
	}
}

结果
       0.575425        0.42965       0.355835        0.40992       0.299113
       0.930875       0.228144       0.146019       0.797079       0.337539
       0.079242     0.00467716      0.0838207       0.968054       0.449575
       0.262218       0.633872       0.165048      0.0746444       0.237763

下面演示产生0-1高斯分布随机数,小数。每次运行,结果不同。

int main(void)
{	
    random_device rnd; //操作系统,CPU硬件取的随机种子 
	mt19937 rng(rnd());//rng(time(NULL))随机种子只能精确到S,速度快会有问题 
    normal_distribution<double> gaosi(0,1);//高斯分布 
	
    for(int i= 1;i < 21;i++){
		cout << setw(15) << gaosi(rng);
		if(i%5 == 0)
		  cout << endl;
	}
}
结果
      0.0837849       0.342529       0.357691       0.719499       0.717263
      -0.553213       0.657816      0.0511081       -1.07223       -1.53896
       -1.94554        0.96073       0.690613       -2.00728       0.708173
       0.658764       -0.78627        -0.8083       0.773783        2.01785

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式宇宙联盟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值