C++初学者指南-5.标准库(第二部分)–随机数生成

news2024/10/4 4:47:42

C++初学者指南-5.标准库(第二部分)–随机数生成

文章目录

  • C++初学者指南-5.标准库(第二部分)–随机数生成
    • 基本概念
    • 例子
      • 统一随机数
      • 布尔值(“抛硬币”)
      • 正态分布
      • 具有独立概率的整数
    • 怎么做
      • 种子引擎
      • 使用自定义生成器
    • shuffle算法
    • 分布类型概述
      • 通用接口
      • 均匀分布
      • 采样分布
      • 伯努利分布
      • 正态分布
      • 泊松分布
      • 概览表
    • 引擎类型概述
      • 通用引擎接口
    • 相关内容

基本概念

#include <random>
random_engine_type engine {seed};
distribution_type distribution {parameters,…};
auto random_value = distribution(engine);

随机性的来源与分布是解耦的。

  • 随机数是由分布产生的
  • 分布使用均匀随机位引擎作为随机性源

此设计的优点

  • 没有单个全局状态,可以使用多个独立的随机引擎
  • 新的分发类型可以使用现有引擎
  • 可以更改随机性源,同时保持分布类型 (例如,将确定性引擎更改为使用硬件熵的引擎)

例子

统一随机数

#include <random>
// fixed seed(固定种子)
auto const seed = 123;
// Mersenne Twister random engine(梅森旋转随机引擎):
std::mt19937 urbg {seed};  
// generate random ints ∈ [1,6](生成1-6之间的随机整数)
std::uniform_int_distribution<int> distr1 {1, 6};
auto const value1 = distr1(urbg);
auto const value2 = distr1(urbg);
// generate random floats ∈ [-1.2,6.25)(生成-1.2到6.25之间的随机浮点数)
std::uniform_real_distribution<float> distr2 {-1.2f, 6.25f};
auto const value3 = distr2(urbg);

运行示例代码

布尔值(“抛硬币”)

#include <random>
auto const seed = 123;
auto urbg = std::mt19937 {seed};  
// unfair coin (40% 'true'):
double const p = 0.4;  
auto flip = std::bernoulli_distribution{p};
if (flip(urbg))  // 40% chance
  cout << "heads\n";
else  // 60% chance
  cout << "tails\n";

在这里插入图片描述
运行示例代码

正态分布

#include <random>
auto const seed = 123;
auto urbg = std::mt19937 {seed};  
double const mu = 4.0; 
double const sigma = 0.7; 
auto norm = std::normal_distribution<double>{mu,sigma};
auto value = norm(urbg);

在这里插入图片描述
运行示例程序

具有独立概率的整数

#include <random>
auto const seed = std::random_device{}();
auto urbg = std::mt19937{seed};  
std::vector<double> ws {1.0, 1.5, 0.5, 2.0};
std::discrete_distribution<int> distr {begin(ws), end(ws)};
std::vector<int> histo (ws.size(), 0);
int const N = 100000;
for (int k = 0; k < N; ++k) {
  auto const i = distr(urbg);
  ++histo[i];
}
std::cout << "Histogram:\n";
for (auto x : histo) {
  auto const size = int(30 * x/double(N));
  cout << std::string(size,'-') << "o\n";
}

在这里插入图片描述
运行示例程序

怎么做

种子引擎

  • 使用一个整数类型的 engine_type::result_type
  • 或使用种子序列
  • 在构造函数中: engine_type { seed }
  • 或者使用成员函数  .seed( seed };
#include <random>
#include <chrono>  // clocks
auto e = std::mt19937{};
// seed engine with a constant
e.seed(123);
// … or with system clock ticks
auto const ticks = std::chrono::system_clock::now().time_since_epoch().count();
e.seed(ticks);
// … or with hardware entropy
auto const hes = std::random_device{}();
e.seed(hes);
// … or with a seed sequence
std::seed_seq s {1,5,3,7,0,9};
e.seed(s);
auto distr = std::uniform_real_distribution{-11.0, 15.3};
cout << distr(e) << '\n';

运行示例代码

使用自定义生成器

Lambda生成器

  • 在 lambda 捕获中初始化引擎和分发
  • 重要:lambda 必须标记为 mutable 因为内部状态 引擎和分配需要随着每次调用而改变
#include <random>
auto const seed = std::random_device{}();
auto coin_flip = [
  // init-capture engine + distribution:
  urbg = std::mt19937{seed},
  distr = std::bernoulli_distribution{0.5}
]() mutable -> bool { return distr(urbg); };
// use generator:
cout << coin_flip() << '\n';
auto roll = [
  urbg = std::mt19937{seed},
  distr = std::uniform_int_distribution<int>{1,6}
]() mutable -> int { return distr(urbg); };
cout << roll() << '\n';

运行示例程序

自定义生成器类
如果需要对参数进行更多控制

#include <random>
class DiceRoll {
  using engine_type = std::mt19937;
  // engine + distribution as members:
  engine_type urbg_;
  std::uniform_int_distribution<int> distr_;
public:
  using seed_type = engine_type::result_type;
  // constructor:
  explicit 
  DiceRoll (int sides, seed_type seed = 0) noexcept: 
    urbg_{seed}, distr_{1,sides} {}
  // allows to re-seed
  void seed (seed_type s) noexcept { urbg_.seed(s); }
  // call operator:
  int operator () () noexcept { return distr_(urbg_); }
};

int main () {
  auto const seed = std::random_device{}();
  DiceRoll roll_d20 {20, seed};
  std::cout << roll_d20() << '\n';
}

运行示例程序

shuffle算法

在这里插入图片描述
cppreference

#include <algorithm>
#include <random>
// 32 bit mersenne twister engine
auto const seed = std::random_device{}();
auto reng = std::mt19937{seed};
std::vector<int> v {0,1,2,3,4,5,6,7,8};
shuffle(begin(v)+2, begin(v)+7, reng);  
for (int x : v) { cout << x <<' '; }  // 0 1 … 7 8

运行示例代码
在这里插入图片描述

分布类型概述

通用接口

构造

  • distribution_type distr; // with default params
  • distribution_type distr { parameter_object };
  • distribution_type distr { parameter1, parameter2,… parameterN };

生成值
auto random_value = distribution_object(engine_object);

常见访问器

  • distr.min() → smallest obtainable value(可获得的最小值)
  • distr.max() → largest obtainable value(可获得的最大值)
  • distr.param() → parameter object(参数对象)
  • distr.reset() : reset internal state(复位内部状态)

参数对象

  • distribution_type::param_type pars { parameter1, parameter2,… parameterN };
  • distribution_type distr1 { pars };
  • distribution_type distr2 { pars };
  • distribution_type distr3 { distr1.param() };

分布-特定参数访问器
distr.a() .b()  .m() .n() .s()  .alpha() .beta()  .lambda() .mean() .stddev() …

均匀分布

在这里插入图片描述

采样分布

在这里插入图片描述

伯努利分布

在这里插入图片描述

正态分布

在这里插入图片描述

泊松分布

在这里插入图片描述

概览表

在这里插入图片描述
在这里插入图片描述

引擎类型概述

通用引擎接口

在这里插入图片描述

线性同余引擎
std::minstd_rand0 // 1969 by Lewis, Goodman, Miller
std::minstd_rand // 1993 by Park, Miller, Stockmeyer
std::linear_congruential_engine

梅森旋转引擎
std::mt19937 // 32-bit, Matsumoto and Nishimura, 1998
std::mt19937_64 // 64-bit, Matsumoto and Nishimura, 2000
std::mersenne_twister_engine

带进位的减法引擎
std::ranlux24_base
std::ranlux48_base
std::subtract_with_carry_engine

引擎适配器
std::discard_block_engine
std::independent_bits_engine
std::shuffle_order_engine
基于适配器的引擎:
std::ranlux24 // discard_block_engine
std::ranlux48 // discard_block_engine
std::knuth_b // shuffle_order_engine

std::default_random_engine
取决于编译器/平台;通常是线性同余生成器。

非确定性熵源
std::random_device
表示一个非确定性随机数生成器,例如,使用硬件熵源。
如果没有可用的非确定性熵源,标准库的实现可以使用伪随机数引擎作为random_device。
测试设备是否真正是非确定性的:

std::random_device rd;
bool non_deterministic = rd.entropy() >  0;
bool deterministic     = rd.entropy() == 0;
auto distr = std::uniform_real_distribution{-1.0,1.0};
auto num = distr(rd);

注意:一些(较旧的)标准库实现尽管其随机设备是非确定性的,但仍然返回0。

相关内容

Random Generator: Combining Engine + Distribution
Random Number Sequences: Control Reproducibility
cppreference: Pseudo-Random Number Generation
cppreference: std::generate_canonical
What C++ Programmers Need to Know about Header  (Walter E. Brown, 2016)

附上原文链接
如果文章对您有用,请随手点个赞,谢谢!^_^

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2187363.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

虚拟机 VMware 安装 macOS

macOS 界面 MAC OS IOS下载&#xff1a; amacOS Monterey by Techrechard.comwmacOS Monterey by Techrechard.com 下载&#xff1a;Unlocker-v2.0.1-x64 Mac OS X 虚拟机中更改屏幕分辨率 终端输入命令&#xff1a; sudo defaults write /Library/Preferences/com.apple.w…

C++11bind、function、lambda详细讲解

一.lambda表达式 关于lambda表达式&#xff0c;我之前是详细讲过的&#xff0c;现在我们只来做重点讲解&#xff08;如果存在疑问可以回看我之前的作品&#xff09;。 固定格式&#xff1a; []()->返回值{};([capture-list] (parameters) mutable -> return-type { state…

UE行为树编辑器图文笔记

对UE的编辑器实现有点好奇&#xff0c;于是从比较熟悉的行为树编辑器着手分析。以下为阅读UE源码后的个人理解&#xff0c;如有错误请指正。 编辑器基础 扩展编辑器的几种方式 MenuBar 菜单栏ToolBar 工具栏DetailCustomization 自定义细节面板&#xff0c;支持两种方式&…

西安做网站如何打造出色的企业网站

西安做网站如何打造出色的企业网站 随着数字化时代的到来&#xff0c;企业网站已成为展示企业形象、传播品牌价值的重要平台。在西安&#xff0c;如何打造出色的企业网站呢&#xff1f;以下几点建议可以帮助企业在激烈的竞争中脱颖而出。 **1. 清晰的网站定位** 首先&#xff…

【Godot4.3】匀速和匀变速直线运动粒子

概述 本篇论述&#xff0c;如何用加速度在Godot中控制粒子运动。 匀速和匀变速直线运动的统一 以下是匀变速运动的速度和位移公式&#xff1a; v t v 0 a t x t v 0 t 1 2 a t 2 v_tv_0 at \\ x_tv_0t \frac{1}{2}at^2 vt​v0​atxt​v0​t21​at2 当a 0 时&#xf…

计算机科学英语词汇汇总(下)Computer Science English Complete Vocabulary )

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…

0基础学习QT——配置开发环境

大纲 安装Qt配置Visual Studio 2022安装插件配置 测试 Qt框架&#xff0c;以其跨平台、高性能以及丰富的UI组件库而著称&#xff0c;是开发图形用户界面应用程序的理想选择。Visual Studio 2022提供了对Qt项目的深度支持&#xff0c;包括智能代码提示、代码导航、调试工具等&am…

(14)MATLAB莱斯(Rician)衰落信道仿真4

文章目录 前言一、改写莱斯分布概率密度函数的理论值二、仿真代码三、仿真结果总结 前言 本文通过将接收信号总功率设置为1&#xff0c;重写了莱斯衰落信道上接收信号幅度的理论PDF式。然后用MATLAB代码生成了在具有不同莱斯因子K的Ricean平坦衰落信道下接收到的信号样本&…

容器适配器-stack、queue、priority_queue和仿函数

目录 1.什么是适配器 2.deque 1.简单了解结构 2.deque的缺陷 3.为什么选择deque作为stack和queue的底层默认容器 3.stack&#xff08;栈&#xff09; 4.queue&#xff08;队列&#xff09; 5.仿函数 6.priority_queue&#xff08;优先级队列&#xff09;&#xff08;堆…

PlantUML中的实体关系图

概述 实体关系图&#xff08;Entity Relationship Diagrams&#xff0c;ERD&#xff09;是一种被广泛用于数据库建模的图。 1976年美籍华裔计算机科学家陈品山&#xff08;Peter Chen&#xff09;首次提出了Entity Relationship Modeling&#xff08;实体关系建模&#xff09…

数据结构-单链表的反转

一直在路上 目录 前言一、普通方法二、头插法三、递归法总结 前言 本篇文章介绍反转单链表的三种方法&#xff0c;分别为普通方法、头插法、递归法。 一、普通方法 普通方法是从第一个结点开始反转&#xff0c;然后反转剩余的结点。 普通方法需要保存当前结点的前驱和后继&a…

DevExpress WinForms v24.1新版亮点:富文本编辑器、电子表格组件功能升级

DevExpress WinForms拥有180组件和UI库&#xff0c;能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForms能完美构建流畅、美观且易于使用的应用程序&#xff0c;无论是Office风格的界面&#xff0c;还是分析处理大批量的业务数据&#xff0c;它都能轻松胜…

自动驾驶-轨迹拼接

在进行自动驾驶的规划之前&#xff0c;要确定当前帧轨迹规划的起点&#xff0c;这个起点常被误认为是当前车辆的位置&#xff0c;即每次以车辆的当前位置进行轨迹规划&#xff1b;其实不是这样的&#xff0c;直观上&#xff0c;这会导致本次次规划的轨迹同上次规划的轨迹之间是…

如何计算服务需要部署多少台机器?

写在前面 遇到流量激增的性能问题&#xff0c;相信绝大多数人的第一反应不是优化代码而是加机器&#xff01;比如隔壁微博一旦出现爆炸性吃瓜&#xff0c;就会紧急扩机器&#xff0c;防止自己服务被打挂&#xff08;虽然经常被打挂 这篇文章我们就来讲一下如何 计算出一个服务…

项目配置说明

文章目录 一、下载 vscode 并安装相应扩展1.1 下载 vscode1.2 安装扩展 二、git 项目三、git 提交流程3.1 确定要提交的代码 四、git 拉新流程 一、下载 vscode 并安装相应扩展 1.1 下载 vscode vscode 我已经发群里了&#xff0c;或者自己去官网下载也行 1.2 安装扩展 打开…

四舵轮车辆中的舵轮角度计算

对于四舵轮车辆&#xff0c;或者对角线安装的双舵轮车辆来说&#xff0c;当同时存在线速度与角速度的时候&#xff0c;它的两个轮子的角度值是不一样的&#xff0c;而它的角度值与其当时的瞬心相关&#xff08;机器人模型与ICR(Instantaneous Center of Rotation)&#xff09;。…

IP6537_C_30W20V--移动设备快充的得力助手,集成 14 种快充协议的降压 SoC

IP6537_C_30W20V是一款集成同步开关的降压转换器、支 持 14 种输出快充协议、支持 Type-C 输出和 USB PD2.0/PD3.0(PPS)协议的 SoC&#xff0c;为车载充电器、 快充适配器、智能排插提供完整的解决方案。 IP6537_C_30W20V支持 USB Type-C 或者 USB A 输出&#xff0c; 5V 输出功…

火语言RPA流程组件介绍--模拟键盘输入

&#x1f6a9;【组件功能】&#xff1a;在浏览器网页中使用键盘操作模拟输入值 配置预览 配置说明 按键间隔(ms) 支持T或# 输入仅支持整型 两次输入按键的间隔,单位毫秒 输入内容 支持T或# 默认FLOW输入项 需要输入的内容 超时时间 支持T或# 输入仅支持整型 输入的超时时…

我们的赞赏码

每一位粉丝的认可&#xff0c;都是我们前进的动力。欢迎为我们点赞、转发和分享&#xff0c;让我们一起传递美好与快乐&#xff01; 我们真诚地邀请您来赞赏我们&#xff0c;您的认可是我们前进的动力&#xff01; 赞赏我们只要0.99&#xff0c;让我们一起在CSDN增长知识&…

OpenAI 开发者大会!实时语音功能有API了,GPT-4o支持多模态微调,上下文cache功能上线

家人们&#xff01;十一假期第1天&#xff0c; OpenAI一年一度的开发者大会又来了惹&#xff01;今年的开发者大会分成三部分分别在美国、英国、新加坡三个地点举办&#xff0c;刚刚结束的是第一场。 去年的OpenAI开发者大会公布了GPT-4 Turbo和GPTs&#xff0c;今年没有大更新…