Java(或任何语言)概率中的随机混乱

时间:2015-03-20 18:12:37

标签: java algorithm random shuffle

所以,我正在观看Robert Sedgewick关于Coursera的视频,而我目前正在洗牌。他正在为在线扑克显示一个“写得不好”的洗牌代码(它还有一些其他错误,我已经将其删除,因为它们与我的问题无关)这就是算法的工作方式:

for(int i = 0; i < N; i++)
int r = new Random().nextInt(53);
swap(cardArray, i, r);

它迭代所有卡片一次。在每次迭代时,生成随机数,并且第i个卡与第r个卡交换。简单,对吧?

虽然我理解算法,但我不理解他的概率计算。他说,因为Random使用32位种子(或64,它似乎并不重要),这仅限于2 ^ 32种不同的排列。

他还说Knuth的算法更好(循环相同,但选择1和i之间的数字)因为它给你N!排列。

我同意Knuth的算法计算。但我认为在第一个(应该是错误的)上应该有N ^ N个不同的排列。

Sedgewick错了还是我错过了一个事实?

4 个答案:

答案 0 :(得分:4)

Sedgewick解释它的方式对我来说似乎很奇怪和迟钝。

想象一下,你只有3张牌,并应用了所示的算法。

交换第一张牌后,会有3种可能的结果。在第二次,然后,第三次交换之后,27。因此,我们知道使用交换算法我们将有27种不同的可能结果,其中一些将是其他结果的重复结果。

现在,我们知道3卡牌组有3 * 2 * 1 = 6种可能的安排。然而,27不能被6整除。因此,我们知道某些安排会比其他安排更常见,即使没有计算它们是什么。因此,交换算法不会在6种可能性中产生相等的概率,即,它将偏向某些安排。

同样的逻辑延伸到52张卡的情况。

我们可以通过查看三卡案件中的结果分布来调查哪些安排是首选的:

1 2 3 5次出现
1 3 2 5次出现
2 1 3 4次出现
2 3 1 4次出现
3 1 2 4次出现
3 2 1 5次出现

总计27

检查这些,我们注意到需要0或1次交换的组合比需要2次交换的组合具有更多的出现次数。通常,组合所需的交换次数越少,就越有可能。

答案 1 :(得分:2)

由于随机数生成器生成的数字序列由种子唯一确定,因此参数是正确的 - 但它也适用于Knuth的算法,以及任何其他混洗算法:如果 N! &GT; 2 ^ M (其中 N 是卡的数量,而 M 是种子中的位数),永远不会生成某些排列。但即使种子足够大,算法之间的实际差异在于概率分布:the first algorithm does not produce an uniform probability for the different permutations, while Knuth's does(假设随机生成器是&#34;随机&#34;足够)。请注意,Knuth的算法也称为Fisher-Yates shuffle

答案 2 :(得分:0)

当然,塞奇威克是对的。要获得卡的真正随机顺序,您必须首先使用在N中平均选择的算法!可能的排列,即选择N中的一个,N-1之一,N-2之一等,并为每个组合产生不同的结果,例如Fisher-Yates算法。

其次,必须使PRNG的内部状态大于log2(N!)位,否则它将在到达所有组合之前重复。对于52张牌,这是226位。 32甚至没有关闭。

答案 3 :(得分:0)

对不起,但我不同意Aasmund和Lee Daniel的答案。 N个元素的每个排列可以表示为1和1之间的一些指数i的3(N-1)个转置(这很容易通过N上的归纳证明 - 见下文)因此,为了产生随机排列它足以在1和N之间生成3(N-1)个随机整数。换句话说,随机生成器只需要能够生成3(N-1)个不同的整数。



<强>定理

{1,...,N}的每个排列都可以表示为N-1换位的组成

证明(通过对N的归纳)

案例N = 1。

{1}的唯一排列是(1)可以写成0个换位的组合(0个元素的组成是同一性)

案例N = 2.(仅适用于上述情况N = 1的人不相信)

有两个元素(1,2)和(2,1)的两种排列。置换(1,2)是1与1的转置。置换(2,1)是1和2的转置。

INDUCTION N - &gt;案例N + 1。

取{1,...,N,N + 1}的任何排列。如果s不移动N + 1,则s实际上是{1,...,N}的置换,并且可以写为索引i,j之间的N-1个转置的组合,其中1 <= i,j&lt; ; = N

因此,假设s将N + 1移动到K.设置N + 1和K之间的转置。然后ts不移动N + 1(N + 1 - > K - > N + 1)因此ts可以写成N-2转置的组成,即

ts = t 1 .. t N-1

因此,s = t 1 .. t N-1 t

由N个换位组成(一个小于N + 1)。


<强>推论

{1,...,N}的每个排列可以写为1和i之间(最多)3(N-1)个排列的组合,其中1 <= i <= N.

证明

根据该定理,足以证明两个索引i和j之间的任何转置都可以写成1和一些索引之间的3个转置的组合。但

swap(i,j)= swap(1,i)swap(1,j)swap(1,i)

其中交换的串联是这些转置的组合。