IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++随机数速成 -> 正文阅读

[C++知识库]C++随机数速成

C风格的随机数

srand和rand

srand——产生随机数种子
rand()%n——产生0~n随机数
rand()%n+1 产生1~n随机数

/* rand example: guess the number */
#include <stdio.h>      /* printf, scanf, puts, NULL */
#include <stdlib.h>     /* srand, rand */
#include <time.h>       /* time */

int main ()
{
  int iSecret, iGuess;

  /* initialize random seed: */
  srand (time(NULL));

  /* generate secret number between 1 and 10: */
  iSecret = rand() % 10 + 1;

  do {
    printf ("Guess the number (1 to 10): ");
    scanf ("%d",&iGuess);
    if (iSecret<iGuess) puts ("The secret number is lower");
    else if (iSecret>iGuess) puts ("The secret number is higher");
  } while (iSecret!=iGuess);

  puts ("Congratulations!");
  return 0;
}

全局随机数种子——避免多次调用 srand 引起 rand 产生同一随机数

这套伪随机有个问题,如果调用的时间间隔不是以秒为数量级 每次出来的随机数都相同。调用速度太快,使得每次srand初始化随机数种子。

 auto rdm = [](){
        srand(time(0));
        for(int i = 0;i<5;++i){
        cout << rand()%10<< '\t';}
        cout<<'\n';};
  for(int j = 0;j<5;++j)
        rdm();
      
    /*输出举例
    9       0       1       6       7
    9       0       1       6       7
    9       0       1       6       7
    9       0       1       6       7
    9       0       1       6       7
    */

全局的随机数种子,可以把srand()放到函数外,全局初始化随机数种子一次,解决这一问题
???不理解,我浅薄的理解随机数有周期(65536),如果每次在lambda表达式里初始化,就从头开始走,如果全局初始化,就不会走上一次走过的路径,所以一样。详见参考文献。

这样写

 srand(time(0));
   auto rdm = [&](){
        for(int i = 0;i<5;++i){
        cout << rand()%10<< '\t';
    }
    cout<<'\n';
   };
    for(int j = 0;j<5;++j)
        rdm();
    /*输出距离
    3       4       8       4       1
    2       2       6       6       9
    8       9       6       7       6
    9       8       2       1       0
    8       5       2       0       7
    */

出来结果就随机了,即使多次运行程序每次出来的 5 × 5 5\times5 5×5矩阵也是不同的。

参考文献

C++ rand 与 srand 的用法

C++随机数

<random>引入下面两类随机数库

  • random-number engines 随机数引擎,生成随机unsigned整数序列
  • random-number distribution 随机数分布,使用引擎返回特定概率分布的随机函数

C++ 程序不应该使用库函数rand,而应使用default_random_engine类和恰当的分布类对象。

random-number engines 随机数引擎

产生原始随机数,基本用法如下

  std::default_random_engine e;
  for(int i = 0;i<10; ++i)
    cout << e() << " ";
  //示例输出 16807 282475249 1622650073 984943658 1144108930 470211272 101027544 1457850878 1458777923 2007237709

static 避免随机数序列不变

和刚才rand一样。

    auto rdm = [&](){
        default_random_engine e;
        for(int j =0;j<5;++j)
            cout << e() <<'\t';
        cout <<'\n'; 
    };
    for(int i = 0;i<5;++i)
        rdm();
    /*示例输出
    16807   282475249       1622650073      984943658       1144108930
    16807   282475249       1622650073      984943658       1144108930
    16807   282475249       1622650073      984943658       1144108930
    16807   282475249       1622650073      984943658       1144108930
    16807   282475249       1622650073      984943658       1144108930
    */

为了避免这一问题只要用static使得随机数引擎全局化即可

  static std::default_random_engine e;

random-number engines vs random_device

random device 用法详见std::random_device

starkflow 上的说法

std::random_device conceptually produces true random numbers. Some implementations will stall if you exhaust the system’s source of entropy so this version may not perform as well.

std::default_random_engine is a pseudo-random engine. Once seeded, with an random number it would be extremely difficult (but not impossible) to predict the next number.

There is another subtle difference. std::random_device::operator() will throw an exception if it fails to come up with a random number.

Question 2: Which is better?

It depends. For most cases, you probably want the performance and temporal-determinism of the pseudorandom engine seeded with a random number, so that would be the second option.

关于这个问题的讨论详见random_device vs default_random_engine

random-number distribution 随机数分布

uniform_int_distribution基本用法

static default_random_engine e;
static uniform_int_distribution<unsigned> u(0,10);//[0,10]
for(int i = 0;i<10;++i)
    cout << u(e) <<' ';//产生0——10 下闭 上闭 伪随机

注意

  • static使得伪随机引擎全局化,避免产生重复序列
  • u 接受参数 为 e而非e()

正态分布 normal distribution

std::default_random_engine e;
std::normal_distribution<double> n(4.0,1.5);
vector<unsigned> vals(9);
for(size_t i =0;i<200;++i)
{
  unsigned v = lround(n(e));//四舍五入
  if(v<vals.size())//统计分布
      ++vals[v];
}
for(size_t i =0;i<vals.size();++i)
  cout <<i <<':' << string(vals[i],'*')<<'\n';
/*
示例输出
0:***
1:********
2:********************
3:**************************************
4:**********************************************************
5:******************************************
6:***********************
7:*******
8:*
*/

详见normal distribtion

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-19 07:48:45  更:2021-09-19 07:49:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:32:06-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码