我正在撰写一些文章,旨在通过使用与扑克相关的主题来教授初学编程概念。目前,我正在研究洗牌问题。
作为Jeff Atwood points out on CodingHorror.com,一个简单的改组方法(遍历数组并使用随机卡在阵列中的其他位置交换每个卡)会产生不均匀的排列分布。在实际应用中,我只使用Knuth Fisher-Yates shuffle来获得更均匀的随机性。但是,我不想用编程器友好的算法来解释编程概念。
这导致了一个问题:如果黑帽子知道你正在使用52张牌的天真洗牌,那么黑帽会有多大的优势?它似乎无限小。
答案 0 :(得分:13)
与天真的洗牌相比,knuth shuffle是一个微不足道的变化:只需更换甲板上剩余(未洗过的)部分中的任何牌,而不是整个牌组中的任何位置。如果您认为它是从剩余的未选择卡片中按顺序重复选择下一张卡片,那么它也非常直观。
就我个人而言,我认为如果正确的算法不再复杂(并且更容易想象!),教会学生的算法很差。
答案 1 :(得分:6)
事实证明,优势非常显着。 Check out this article
问题的一部分是有缺陷的算法,但另一部分假设您可以从计算机获得“随机”数字。
答案 2 :(得分:3)
一个简单的&用于混洗的公平算法是为甲板中的每张卡分配随机浮点数(例如,在0和1之间),然后按指定的数字对甲板进行排序。
这实际上是一个完美的例子,让学生意识到只是因为某些东西是直观的,在我们的情况下天真的洗牌,并不意味着它是正确的。
答案 3 :(得分:1)
主观。
似乎它会无限小。
同意。
答案 4 :(得分:1)
这不像是你正在编写一个用于实际在线赌博网站的扑克计划。当你教人们如何编程时,某人欺骗该计划的能力并不是什么大事。
留下一张纸条说这是现实世界的一个糟糕模型(并将其称为可能的安全漏洞),并继续教学。
答案 5 :(得分:1)
顺便说一下,在模拟洗牌时,有一个关于洗牌的blog post over on ITtoolbox可能会引起人们的兴趣。
关于你的问题,请考虑有52个!可以从那里开始的甲板配置可能在杰夫的3张牌组的例子中起到了作用的作用,注意过度代表中的1出现在每个槽中一次。另外请注意,他说你必须有几千个例子,才能明显看出优势在哪里,但是你可以用一副套牌来重新开始使用相同的初始套牌,是吗?你拿着已经发出的牌并将它们放在底部并将它们洗牌,这是我认为不可能重复的。