Tag: 混洗

什么,如果有的话,这个洗牌algorithm是错误的,我怎么知道?

就像背景一样,我知道Fisher-Yates完美的洗牌。 O(n)的复杂性和保证的一致性是一个很好的洗牌,我不会使用它…在允许数组就地更新的环境中(所以在大多数情况下,即使不是全部, 命令式编程环境)。 可悲的是function性编程世界并不能让你进入可变状态。 然而,由于Fisher-Yates,关于如何devise一个洗牌algorithm,并没有太多的文献可以find。 事实上,几乎没有一个地方可以这样说,“所以这里就是你需要知道的所有洗牌的费希尔 – 耶茨。 最后,我必须拿出我自己的解决scheme。 我想出了这样的解决scheme来洗牌任何数据列表: 如果列表为空,则返回空集。 如果列表中有单个项目,则返回该单个项目。 如果列表不是空的,则用随机数生成器对列表进行分区,并recursion地将algorithm应用于每个分区,然后组装结果。 在Erlang代码中,它看起来像这样: shuffle([]) -> []; shuffle([L]) -> [L]; shuffle(L) -> {Left, Right} = lists:partition(fun(_) -> random:uniform() < 0.5 end, L), shuffle(Left) ++ shuffle(Right). (如果这看起来像一个疯狂的快速sorting,那么基本上就是这样。) 所以这就是我的问题:寻找不是Fisher-Yates的混洗algorithm的相同情况使得寻找工具来分析洗牌algorithm同样困难。 在分析PRNG的一致性,周期性等方面,我可以find许多文献,但是关于如何分析洗牌的信息却并不多。 (事实上​​,我在分析洗牌时发现的一些信息显然是错误的 – 很容易通过简单的技术欺骗。) 所以我的问题是:我如何分析我的洗牌algorithm(假设random:uniform()调用那里有产生具有良好特性的适当随机数的任务)? 我可以用什么math工具来判断,在1..100的整数列表中,是否有100,000次洗牌机运行给了我合理的洗牌结果? 我已经做了一些我自己的testing(例如比较增量在shuffles中的递减),但我想知道更多。 如果有什么洞察到洗牌algorithm本身,也将不胜感激。

为什么这个简单的洗牌algorithm产生有偏见的结果? 什么是一个简单的原因?

看来这个简单的洗牌algorithm会产生有偏见的结果: # suppose $arr is filled with 1 to 52 for ($i < 0; $i < 52; $i++) { $j = rand(0, 51); # swap the items $tmp = $arr[j]; $arr[j] = $arr[i]; $arr[i] = $tmp; } 你可以试试它…而不是使用52,使用3(假设只有3张卡被使用),并运行10000次,并计算结果,你会看到结果是倾向于某些模式… 问题是…它会发生什么简单的解释? 正确的解决scheme是使用类似的东西 for ($i < 0; $i < 51; $i++) { # last card need not swap […]