【问题标题】:What is the best algorithm to shuffle cards? [closed]洗牌的最佳算法是什么? [关闭]
【发布时间】:2016-10-15 10:02:37
【问题描述】:

给定一组有限的 N 张牌, 洗牌的最佳方法(算法)是什么,这样我就能以最少的步骤获得最好的洗牌包以获得最大的随机排列?

什么是最少步骤的最佳解决方案?

【问题讨论】:

  • 你如何定义"the best shuffled pack of cards"
  • 由于现实世界的洗牌方法与编程或计算机科学之间存在微弱的联系,我投票决定将此问题作为题外话结束。
  • 如果您正在寻找一种有效的随机化算法,这是最好的算法之一:https://en.wikipedia.org/wiki/Fisher–Yates_shuffle
  • @TalAvissar 因此,相邻牌之间的距离越远,步数越小,一个洗牌组合就比其他组合更好?

标签: algorithm language-agnostic shuffle


【解决方案1】:

使用Fisher Yates algorithm。许多编程语言使用该算法的变体来打乱有限集的元素。这是 Fisher Yates 算法的伪代码(Richard Durstenfeld 优化版):

-- To shuffle an array a of n elements (indices 0..N-1):
for i from N−1 downto 1 do
     j ← random integer such that 0 ≤ j ≤ i
     exchange a[j] and a[i]

此算法可确保均匀分布。对于N 卡片,有N! 个可能的洗牌组合。在这里,这些N! 排列中的任何一个都同样可能被返回。时间复杂度为O(N)

【讨论】:

    【解决方案2】:

    这是经典的(我相信它是最好的,使用 len(x) 阶乘排列所需的确切位数):

    def shuffle(x):
        """Shuffle list x in place, and return None."""
        for i in reversed(range(1, len(x))):
            # pick an element in x[:i+1] with which to exchange x[i]
            j = int(random() * (i+1))
            x[i], x[j] = x[j], x[i]
    

    【讨论】:

    • 看起来不错。重要的一点是你用 i 到 N 上的随机数交换,而不是你可能首先想到的 0 到 N。将 0 换成 N 会产生一种奇怪的、不均匀的分布。
    猜你喜欢
    • 2010-09-08
    • 1970-01-01
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    • 2011-06-22
    • 1970-01-01
    • 1970-01-01
    • 2011-10-09
    相关资源
    最近更新 更多