热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何用随机函数rand5来构造随机函数rand7

rand5()它能够等概率生成1-5之间的整数。所谓等概率就是1,2,3,4,5生产的概率均为0.2。现在利用rand5(),构造一个能够等概率生成1-7的方法。这里有两个特别重要的点,一是如果rand5()+rand5(),我们能够产生一个均匀分布的1-10吗?答案是否定的。比如对于6来讲(4+2,2+4,3+3),

试一下以对话的方式写博~如果看不到人物头像,请刷新页面获取最新的CSS。如果有建议或意见,欢迎到我的微博上跟帖~ 这里是腾讯微博这里是新浪微博

常规方法

  • 今天公司有一个面试题是这样的:假如有一个函数rand5能等概率生成1 - 5 之间的整数,如何利用rand5来实现rand7?rand7函数的要求是能够等概率生成1 - 7之间的整数。说实话我自己也不是很清楚。
  • 这个问题很经典的。carreercup那本书上有个常见的解法,我记得算法大概是这样的,用PHP写写吧:
echo 'rand7 = '.rand7();

function rand7()
{
	while (true)
	{
		//得出[0,24]的平均分布
		$i = 5 * (rand5() - 1) + (rand5() - 1);
		//只取前21个, 前21个也是平均分布,然后mod 7
		if( $i <21 )
		{
			return $i % 7 + 1;
		}
	}
}
  • 这么写是什么意思呢?
  • 两次使用rand5(),可以生成1-25的所有数。5 * (rand5() - 1) 可以生成 0 - 20,而后面的则可以生成0 - 4。用数学表达的话就是 [0, 24]。
  • [0, 24] 范围内生成的随机数$i如果大于21,就用 while (true) 重新生成。当$i <21的时候,就可以用模运算了。
  • 明白了。当 $i <21的时候,模 7 的结果是 0-6,加1就可以修正为 1-7,这样就可以通过rand5来实现rand7了。

算法的一些释疑

  • 话说得出[0,24]的平均分布的 $i = 5 * (rand5() - 1) + (rand5() - 1); 为什么要这么写呢?为什么不能直接 $i = 6 * (rand5() - 1) ?
  • rand5()产生的是[1,5]的均匀分布,但是有没有发现最后产生的rand7()却是[0,6]的,那么平均分布是如何实现的呢?
  • 5*(rand5()-1) 生成的是 0, 5,10,15,20各20%的概率,rand5()-1 是0,1,2,3,4各20%概率,两者相加,就是0-24各1/25的概率,这样就保证了平均分布的问题了。基本的概率和排列组合问题了。
  • 前21个也是平均分布,那么我取 $i <14 也可以么?这样也能保证平均分布吗?
  • 应该也可以,但是增加了可能的循环次数。你看到 while (true) 这行代码吗?当while里面的条件不满足,循环就会一直下去。所以从程序上考虑,就是用了21而非14吧。

晚些时候

  • 我Google了下,貌似还有其它思路。先用2个rand5产生rand10(注意,不是相加),然后从rand10产生rand7。
// Gen 0, 1 equal probability
int rand01()
{
    int i = rand5();
    while (i > 4) {i = rand5();}
    return i % 2;
}
 
// Gen 0, 1, 2, 3, 4, 5, 6, 7 equal probability
int rand07()
{
    return rand01() <<2 + rand01() <<1 + rand01();
}
 
// Gen 1, 2, 3, 4, 5, 6, 7 equal probability
int rand7()
{
    int i = rand07();
    while (i == 0) {i = rand07();}
    return i;
}
  • 还有一种方法,可以直接把概率问题转化到矩阵中解决。
int matrix[5][5];
 
memset(matrix, 0, sizeof(matrix));
 
// Set matrix with num 1-7, each num has the same count.
for (int i = 1; i <= 7; ++i)
{
    for (int j = 0; j <3; ++j)
    {
        *matrix++ = i;
    }
}
 
int rand7()
{
    int i;
 
    do
    { 
        i = matrix[rand5() - 1][rand5() - 1];
    } while (i == 0);
 
    return i;
}
  • 你还真好学。。

通过这个面试题学到了等概率问题的各种解法,可以从把数从二进制角度看,可以用公式拼接出更大的等概率值域空间,也可以直接把概率问题转化到矩阵中解决。

rand5() 它能够等概率生成 1-5 之间的整数。所谓等概率就是1,2,3,4,5 生产的概率均为 0.2 。现在利用rand5(), 构造一个能够等概率生成 1- 7 的方法。 这里有两个特别重要的点,一是 如果 rand5() + rand5(), 我们能够产生一个均匀分布的 1 - 10 吗? 答案是否定的。比如对于 6来讲(4+2, 2+4, 3+3),它被生成的生成的概率比1 (1+0,0+1)要大。

第二个点就是我们不可能用rand5()直接产生 1- 7 的数,不管你用加减乘除都不行。所以,我们要构造一个更大的范围,使得范围里每一个值被生成的概率是一样的,而且这个范围是7的倍数。

先产生一个均匀分布的 0, 5, 10, 15, 20的数,再产生一个均匀分布的 0, 1, 2, 3, 4 的数。相加以后,会产生一个 0到24的数,而且每个数(除0外)生成的概率是一样的。我们只取 1 - 21 这一段,和7 取余以后+1就能得到完全均匀分布的1-7的随机数了。

本文地址:http://www.nowamagic.net/librarys/veda/detail/2172,欢迎访问原出处。


推荐阅读
  • H5技术实现经典游戏《贪吃蛇》
    本文将分享一个使用HTML5技术实现的经典小游戏——《贪吃蛇》。通过H5技术,我们将探讨如何构建这款游戏的两种主要玩法:积分闯关和无尽模式。 ... [详细]
  • 在1995年,Simon Plouffe 发现了一种特殊的求和方法来表示某些常数。两年后,Bailey 和 Borwein 在他们的论文中发表了这一发现,这种方法被命名为 Bailey-Borwein-Plouffe (BBP) 公式。该问题要求计算圆周率 π 的第 n 个十六进制数字。 ... [详细]
  • 本文介绍了SIP(Session Initiation Protocol,会话发起协议)的基本概念、功能、消息格式及其实现机制。SIP是一种在IP网络上用于建立、管理和终止多媒体通信会话的应用层协议。 ... [详细]
  • 二维码的实现与应用
    本文介绍了二维码的基本概念、分类及其优缺点,并详细描述了如何使用Java编程语言结合第三方库(如ZXing和qrcode.jar)来实现二维码的生成与解析。 ... [详细]
  • 我的读书清单(持续更新)201705311.《一千零一夜》2006(四五年级)2.《中华上下五千年》2008(初一)3.《鲁滨孙漂流记》2008(初二)4.《钢铁是怎样炼成的》20 ... [详细]
  • Go从入门到精通系列视频之go编程语言密码学哈希算法(二) ... [详细]
  • TCP协议中的可靠传输机制分析
    本文深入探讨了TCP协议如何通过滑动窗口和超时重传来确保数据传输的可靠性,同时介绍了流量控制和拥塞控制的基本原理及其在实际网络通信中的应用。 ... [详细]
  • 2023年,Android开发前景如何?25岁还能转行吗?
    近期,关于Android开发行业的讨论在多个平台上热度不减,许多人担忧其未来发展。本文将探讨当前Android开发市场的现状、薪资水平及职业选择建议。 ... [详细]
  • 知识图谱与图神经网络在金融科技中的应用探讨
    本文详细介绍了融慧金科AI Lab负责人张凯博士在2020爱分析·中国人工智能高峰论坛上的演讲,探讨了知识图谱与图神经网络模型如何在金融科技领域发挥重要作用。 ... [详细]
  • CRZ.im:一款极简的网址缩短服务及其安装指南
    本文介绍了一款名为CRZ.im的极简网址缩短服务,该服务采用PHP和SQLite开发,体积小巧,约10KB。本文还提供了详细的安装步骤,包括环境配置、域名解析及Nginx伪静态设置。 ... [详细]
  • Python 领跑!2019年2月编程语言排名更新
    根据最新的编程语言流行指数(PYPL)排行榜,Python 在2019年2月的份额达到了26.42%,稳坐榜首位置。 ... [详细]
  • 理解浏览器历史记录(2)hashchange、pushState
    阅读目录1.hashchange2.pushState本文也是一篇基础文章。继上文之后,本打算去研究pushState,偶然在一些信息中发现了锚点变 ... [详细]
  • 从CodeIgniter中提取图像处理组件
    本指南旨在帮助开发者在未使用CodeIgniter框架的情况下,如何独立使用其强大的图像处理功能,包括图像尺寸调整、创建缩略图、裁剪、旋转及添加水印等。 ... [详细]
  • 探索AI智能机器人自动盈利系统的构建
    用户可通过支付198元押金及30元设备维护费租赁AI智能机器人,推荐他人加入可获得相应佣金。随着推荐人数的增加,用户将逐步解锁更高版本,享受更多收益。 ... [详细]
  • 本文将从基础概念入手,详细探讨SpringMVC框架中DispatcherServlet如何通过HandlerMapping进行请求分发,以及其背后的源码实现细节。 ... [详细]
author-avatar
黑旦儿
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有