随机数生成生成器和力扣按权重随机选择 528

在linux下内核有个专门内核模块进行生成随机数
/dev/random 不是很精准
/dev/urandom 更精准
原理 是内核的一个模块,专门产生的,根据cpu指令等等产生
读取随机数的话也可以读取这两个设备。
例如如下的代码:

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>int main()
{int fd1 = open("/dev/urandom", O_RDONLY);int fd2 = open("/dev/random", O_RDONLY);unsigned long u1 = 0, u2;read(fd1, &u1, sizeof(u1));read(fd2, &u2, sizeof(u2));printf("u1 = %lu\n", u1);printf("u2 = %lu\n", u2);return 0;
}

打印出来就是两个随机数。

std::random_device{}() // 生成真随机数,在linux中这个是通过读取 /dev/urandom 进行获取的, 一般用于做随机数种子
mt19937         // 用于生成伪随机数, 这个和rand()类似都是需要设置随机数种子。

真随机数一般为操作系统生成,根据当前操作系统的中断,键盘鼠标的输入,文件句柄等等一系列随机事件组成。伪随机数一般由算法组成,mt19937实际上就是一个算法的名称。

#include <iostream>
#include <random>
using namespace std;int main()
{int i ;for(i = 0; i < 10; i++){cout << std::random_device{}() <<endl;     //真随机数}mt19937 Rand;for(i = 0; i < 10; i++){cout << Rand() <<endl;    //假随机和rand() 一样}mt19937 s(std::random_device{}());    for(i = 0 ; i < 10; i++){cout << s() <<endl;         //通过真随机数播种,随后得到随机数质量更高}
}

如果要生成一个范围的随机数该怎么办呢,如果要生成一个类似于高斯分布形状的随机数该怎么办呢,其实在STL中已经为我们准备好了。

std::uniform_int_distribution 均匀分布器
std::normal_distribution 高斯分布器

均匀分布器可以通过构造函数设置随机值的上下范围
高斯分布器构造函数的两个参数用于设置均值和方差

#include <iostream>
#include <random>
using namespace std;int main()
{   mt19937 s(std::random_device{}());uniform_int_distribution<int> Rand(0, 10);vector<int> arr(11);for(int i = 0 ; i < 1000000; i++){arr[Rand(s)]++;}for(int i = 0 ; i < arr.size(); i++){cout << arr[i] << endl; }}

上代码是均匀分布,生成一百万次 0到10的随机数并统计每项出现的次数运行结果如下:

运行结果每个区间的值大致是均匀的。

#include <iostream>
#include <random>
using namespace std;int main()
{   mt19937 s(std::random_device{}());uniform_int_distribution<int> Rand(0, 10);std::normal_distribution<double> rands(100, 5);int size = 1000000; //一百万次int count_90_110 = 0;int count_95_105 = 0;for(int i = 0 ; i < size; i++){double a = rands(s);if(a >= 90 && a <= 110){count_90_110++;}if(a >= 95 && a <= 105){count_95_105++;}}cout << count_90_110 << "   90 - 100" <<endl;cout << count_95_105 << "   95 - 105" <<endl;
}


打印100万次发现在 一个 方差范围内概率大致为 68%, 两个 方差范围内概率大致为95% 符合正太分布。
正态分布如图所示:

http://c.biancheng.net/view/643.html
https://baike.baidu.com/item/%E6%AD%A3%E6%80%81%E5%88%86%E5%B8%83/829892?fr=aladdin

给定一个正整数数组 w ,其中 w[i] 代表下标 i 的权重(下标从 0 开始),请写一个函数 pickIndex ,它可以随机地获取下标 i,选取下标 i 的概率与 w[i] 成正比。

例如,对于 w = [1, 3],挑选下标 0 的概率为 1 / (1 + 3) = 0.25 (即,25%),而选取下标 1 的概率为 3 / (1 + 3) = 0.75(即,75%)。
也就是说,选取下标 i 的概率为 w[i] / sum(w)

class Solution{private:mt19937 gen;uniform_int_distribution<int> dis;vector<int> pre;public:Solution(vector<int>& w): gen(random_device{}()), dis(1, accumulate(w.begin(), w.end(), 0)) {partial_sum(w.begin(), w.end(), back_inserter(pre));}int pickIndex() {int x = dis(gen);return lower_bound(pre.begin(), pre.end(), x) - pre.begin();}
};/*
mt19937头文件是<random> 是伪随机数产生器,用于产生高性能的随机数
uniform_int_distribution 头文件在<random>中,是一个随机数分布类,参数为生成随机数的类型,构造函数接受两个值表示区间段
accumulate 头文件在<numeric>中,求特定范围内所有元素的和。
spartial_sum函数的头文件在<numeric>,对(first, last)内的元素逐个求累计和,放在result容器内
back_inserter函数头文件<iterator>,用于在末尾插入元素。
lower_bound头文件在<algorithm>,用于找出范围内不大于num的第一个元素
*/

该题的力扣链接:https://leetcode-cn.com/problems/random-pick-with-weight

随机数生成生成器和力扣按权重随机选择 528相关推荐

  1. 528. 按权重随机选择

    528. 按权重随机选择

  2. Java实现 LeetCode 528 按权重随机选择(TreeMap)

    528. 按权重随机选择 给定一个正整数数组 w ,其中 w[i] 代表位置 i 的权重,请写一个函数 pickIndex ,它可以随机地获取位置 i,选取位置 i 的概率与 w[i] 成正比. 说明 ...

  3. [528]. 按权重随机选择

    [528]. 按权重随机选择 题目 算法设计:加权随机取样 题目 传送门:528. 按权重随机选择 输入: ["Solution","pickIndex"] [ ...

  4. 【力扣】复制带随机指针的链表题解 C语言实现

    前言 这是力扣里的一道经典链表题,据说掌握此题你对链表的理解能力就是优秀水平了 题目 /*** Definition for a Node.* struct Node {* int val;* str ...

  5. LeetCode 528. 按权重随机选择(前缀和+二分查找)

    文章目录 1. 题目 2. 解题 1. 题目 给定一个正整数数组 w ,其中 w[i] 代表下标 i 的权重(下标从 0 开始),请写一个函数 pickIndex ,它可以随机地获取下标 i,选取下标 ...

  6. LeetCode力扣刷题——巧解数学问题

    数论 一.引言         对于 LeetCode 上数量不少的数学题,我们尽量将其按照类型划分讲解.然而很多数学题的解法并不通用,我们也很难在几道题里把所有的套路讲清楚,因此我们只选择了几道经典 ...

  7. 力扣随机数randX——透过现象看本质之二元独立随机分布

    用randX 实现 randY(X < Y) 其中,randN表示等概生成[1,N]的数 从一个力扣上的例子来引入吧 470. 用 Rand7() 实现 Rand10() 最直观的想法是用ran ...

  8. 力扣 O(1) 时间插入、删除和获取随机元素 - 允许重复

    力扣 O(1) 时间插入.删除和获取随机元素 - 允许重复 题目描述 设计一个支持在平均 时间复杂度 O(1) 下, 执行以下操作的数据结构. 注意: 允许出现重复元素. insert(val):向集 ...

  9. 力扣热门题目简单部分合集(共23道)

    文章目录 前言 1.两数之和(哈希表,双指针,数组) 2.有效的括号(栈,哈希表) 3.合并两个有序链表(递归,迭代) 4.最大子数组和(动态规划,分治,贪心) 5.爬楼梯(迭代,递归,动态规划,数学 ...

最新文章

  1. opencv imshow
  2. 《系统集成项目管理工程师》必背100个知识点-48质量控制的老七工具和新七工具...
  3. 解决NSData转NSString返回nil的问题
  4. 关于华为海思Hi35XX系列开发的思考与总结
  5. ORBSLAM2在Ubuntu14.04上详细配置流程
  6. 几道比较有意思的js面试题
  7. U盘基本处理,U盘与移动固态硬盘
  8. php mvc多态实例,asp.net mvc-多态模型绑定
  9. golang 泛型_Golang 1.x版本泛型编程
  10. AntDesignUI - V3.0 技术手册(资源篇)
  11. 复旦计算机转专业面试问题,转专业最容易的6所985大学,清华大学第4,复旦大学第3,这所第一...
  12. SpringCloud学习笔记(十)----服务熔断与限流 Sentinel
  13. 唯快不破:Web 应用的 13 个优化步骤
  14. 再谈js对象数据结构底层实现原理-object array map set
  15. Sql Server中清空所有数据表中的记录
  16. linux mysql 编译后的版本_LINUX下编译安装最新版本mysql_MySQL
  17. 简化企业CMMI5认证过程?
  18. Unity3D图像后处理特效——Crease
  19. 河南省第四届ACM程序设计大赛(共八道,目前只做两道。待续)
  20. 自动补全 (自定义)拼音分词器 搜索时注意事项

热门文章

  1. tomcat配置虚拟主机(Host)
  2. java闰年_java中求闰年的算法
  3. 安卓6.0运行时权限处理
  4. OBCA专员考试备考知识点(一) 已考过,不继续更新
  5. [前端笔记——HTML介绍] 2.开始学习HTML
  6. xssbypass_XSS Bypass
  7. Proteus元件库元件名称及中英对照表
  8. autodock tool文件_AutoDock PDBQT文件详解
  9. 孙溟㠭先生黄檗归来而篆刻“心”与“道”印章
  10. 微信小程序-会员卡组件(navigator)打开会员卡报参数错误