news 2026/4/30 22:12:26

用rand7()函数构造函数rand10()

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用rand7()函数构造函数rand10()

题目要求:用一个已知均匀随机的rand7()(生成1~7等概率)来构造rand10()(生成1~10等概率)。

思路:题目要求用均匀分布生成另一个均匀分布。

1.前提:rand7()可以均匀生成1,2,3,4,5,6,7,目标是rand10()均匀生成1 ~ 10。

2.不能用简单的(rand7() * 10 / 7)之类的方法,因为它们不是均匀的(会偏向某些数)。

举例:

rand7()取值:1,2,3,4,5,6,7

乘以10:10,20,30,40,50,60,70

除以7:1,2,4,5,7,8,10

目标应该是1~10每个数的概率都为1/10,结果1,2,4,5,7,8,10的概率为1/7,3,6,9的概率为0,不合题意。

3.拒绝采样法:利用(rand7() - 1) * 7 + rand7()可以生成1 ~ 49之间的等概率随机数。

证明:

(1)令a = rand7() - 1,取值:0,1,2,3,4,5,6(均匀)。

(2)令b = rand7(),取值:1,2,3,4,5,6,7(均匀)。

(3)公式变成了a * 7 + b。这实际上是在构造一个两位的7进制数。

当a固定时:

a = 0:0 * 7 + b = 1 ~ 7。

a = 1:1 * 7 + b = 8 ~ 14。

a = 2: 2 * 7 + b = 15 ~ 21。

a = 3: 3 * 7 + b = 22 ~ 28。

a = 4: 4 * 7 + b = 29 ~ 35。

a = 5: 5 * 7 + b = 36 ~ 42。

a = 6: 6 * 7 + b = 43 ~ 49。

完美覆盖了1 ~ 49的所有整数。

之所以a * 7 + b这样构造是均匀的,是因为a和b是独立的随机变量,也就是两次独立的rand7()调用。概率计算:P(得到某个特定数 x) = P(a = 某值) × P(b = 某值)。实际上是在做笛卡尔积。通过(a'-1)*7 + b映射到 1~49,这是一个双射(一一对应),所以分布保持均匀。

举例:

P(得到23) = P(a=3) × P(b=2) = (1/7) × (1/7) = 1/49

任何1 ~ 49的数都能唯一表示为a * 7 + b的形式,所以每个数的概率都是1/49。

4.(rand7() - 1) * 7 + rand7()生成等概率随机数的步骤。从1 ~ 49中只取1 ~ 40的数字(映射到1 ~ 10),遇到41 ~ 49则重试。这是因为转换为rand10()的话,最大概率是将1 ~ 49分成10组,每组4个数(但49不是10的倍数),因此必须让num落在1 ~ 40范围内才有用,否则丢弃重新生成,保证1 ~ 10均匀。

附代码:

class Solution { private Random random = new Random(); // 假设提供的 rand7() 是均匀的 private int rand7() { // random.nextInt(7)是生成一个0到6之间的随机整数(包含0,不包含7) //random.nextInt(7) + 1就是生成一个1到7之间的随机整数 return random.nextInt(7) + 1; } public int rand10() { while (true) { int num = (rand7() - 1) * 7 + rand7(); // 1 ~ 49 均匀 if (num <= 40) { // 将1 ~ 40的数映射到1 ~ 10 // 如果是num % 10,那么1 % 10 + 1 = 2,映射错误,所以是(num - 1) % 10 // 要求返回1 ~ 10,而不是0 ~ 9,所以应该 + 1,不加1的映射范围是0 ~ 9 return (num - 1) % 10 + 1; // 如果 num = 41~49,则丢弃,重新生成 } } } }

ACM模式:

import java.util.Random; import java.util.Scanner; class Solution { private Random random = new Random(); // 假设提供的 rand7() 是均匀的 private int rand7() { // random.nextInt(7)是生成一个0到6之间的随机整数(包含0,不包含7) //random.nextInt(7) + 1就是生成一个1到7之间的随机整数 return random.nextInt(7) + 1; } public int rand10() { while (true) { int num = (rand7() - 1) * 7 + rand7(); // 1 ~ 49 均匀 if (num <= 40) { // 将1 ~ 40的数映射到1 ~ 10 // 如果是num % 10,那么1 % 10 + 1 = 2,映射错误,所以是(num - 1) % 10 // 要求返回1 ~ 10,而不是0 ~ 9,所以应该 + 1,不加1的映射范围是0 ~ 9 return (num - 1) % 10 + 1; // 如果 num = 41~49,则丢弃,重新生成 } } } } public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); // 需要生成多少个随机数 Solution sol = new Solution(); for (int i = 0; i < n; i++) { System.out.print(sol.rand10()); if(i < n - 1){ System.out.print(" "); } } System.out.println(); scanner.close(); } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/30 22:10:46

别再复制粘贴了!手把手教你封装一个可复用的Vue2百度地图组件

从零构建高复用Vue2百度地图组件&#xff1a;工程化实践指南 每次新项目需要地图功能时&#xff0c;你是否还在重复复制粘贴那段熟悉的集成代码&#xff1f;当团队中不同成员各自实现的地图功能出现行为差异时&#xff0c;是否让项目维护变得棘手&#xff1f;本文将带你超越基础…

作者头像 李华
网站建设 2026/4/30 22:06:49

流匹配与扩散模型在机器人动作生成中的对比与应用

1. 流匹配与扩散模型的核心差异解析在机器人动作生成领域&#xff0c;流匹配(Flow Matching)和扩散模型(Diffusion Models)代表了两种截然不同的概率路径构建方法。理解它们的本质区别对于选择合适的技术方案至关重要。1.1 概率路径构建方式的对比扩散模型采用了一种"随机…

作者头像 李华
网站建设 2026/4/30 22:04:07

告别手动画图!用PostGIS+PostgreSQL自动生成城市路网(附巴黎实战案例)

基于PostGISPostgreSQL的城市路网自动化生成实战指南 从手工绘制到智能生成&#xff1a;城市路网建模的技术演进 城市规划师和GIS开发者们一定深有体会&#xff1a;传统手工绘制城市路网不仅耗时费力&#xff0c;而且难以保证数据的一致性和准确性。一个中等规模城市的路网可能…

作者头像 李华
网站建设 2026/4/30 21:56:59

Swoole 的onWorkerStart的生命周期的庖丁解牛

Swoole 的 onWorkerStart 是 Swoole 常驻内存架构中最关键、最复杂、也最容易踩坑的生命周期节点。 它的本质是&#xff1a;Worker 进程&#xff08;工作进程&#xff09;诞生后的“初始化入口”。在这个回调中&#xff0c;你完成所有 一次性加载 (One-time Loading) 、 资源预…

作者头像 李华
网站建设 2026/4/30 21:54:29

WebLaTeX零基础入门指南:5分钟搭建你的云端LaTeX写作环境

WebLaTeX零基础入门指南&#xff1a;5分钟搭建你的云端LaTeX写作环境 【免费下载链接】WebLaTex A complete alternative for Overleaf with VSCode Web Git Integration Copilot Grammar & Spell Checker Live Collaboration Support. Based on GitHub Codespace and…

作者头像 李华