博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
证明洗牌问题
阅读量:5157 次
发布时间:2019-06-13

本文共 704 字,大约阅读时间需要 2 分钟。

问题背景:

有一副牌假设有N张,请设计一个随机洗牌算法。

解决方案:

这里只给出一个可以使用数学证明每张牌出现在任何位置概率为1/N的算法。

Poker[N]

for (i = 0; i < N; ++i)

{

k = rand() % ( i + 1)

if (i != k)

{

switch(Poker[k], Poker[i]);

}

}

 

分析:

第一次取第一张牌(i=0)保持位置不变。第二次取第二张牌(i=1),随机生成0-1的随机数k,如果随机生成数不为1,则交换下标为k和i的牌,否则不进行交换。

假设现在取第Z张牌(i = Z - 1), k= rand()%Z, 如果k!=i则交换下标为k和i的两张牌。

这个算法粗看起来有点像蓄水池抽样的操作方法。这样我们来看一下每张牌出现位置的概率。

 

第一次计算时第一张牌(i=0)出现在第一个位置的概率为1。

第二次计算时第二张牌(i=1)很明显出现在两个位置中的概率都是1/2。

我们就是要证明第Z(Z<=N)次计算时每张牌出位位置的概率为1/Z。

下面采用归纳法来证明。

1. 很明显Z=1时结论成立。

2. 假设当Z = K时结论也成立。

当Z=K+1时,易知第Z张牌出现在任意位置的概率为1/Z。

前K个数能够保留当前位置的概率为(1 - 1/(K+1)), 那么任意一张牌出现在任意位置的概率为(1/K) *(1 - 1/(K+1)) = 1/(K+1)。

3. 同样当Z=N时该算法也成立。

转载于:https://www.cnblogs.com/aiyelinglong/archive/2012/09/10/2679437.html

你可能感兴趣的文章
HDU1257
查看>>
初步了解HTTP
查看>>
unittest----assert断言的使用
查看>>
caffe+opencv3.3.1
查看>>
利用正则按固定长度分割字符串
查看>>
NGUI里的sprite和label有白色的边框
查看>>
python——进程基础
查看>>
CentOs6.6安装Python3
查看>>
PHP框架自动加载类文件原理
查看>>
深度链接对社会化营销有哪些价值和作用?
查看>>
【php数组函数序列】之sort() - 对数组的元素值进行升序排序
查看>>
文件锁
查看>>
使用mybatis插入数据(insert)时返回主键的问题
查看>>
[LinqPad妙用]-在Net MVC中反射调用LinqPad中的Dump函数
查看>>
ASP.NET前台代码绑定后台变量方法总结
查看>>
iOS开发富文本
查看>>
C++中的临时对象
查看>>
01_Android应用开发环境_01_android发展史及系统架构
查看>>
WCF元数据发布的2种方式:httpGetEnabled与mex
查看>>
值类型与引用类型传递的艺术
查看>>