【问题标题】:A variant of Knuth shuffleKnuth shuffle 的一种变体
【发布时间】:2015-06-03 23:26:15
【问题描述】:

这是一个与 Knuth/Fisher-Yates shuffle 相关的非常困难但有趣的概率问题。

在循环每个元素时,将当前元素与整个数组中的任何随机元素(不在左边的元素内)进行交换,那么原始第 ith 的概率是多少元素结束在第 jth 位置?

【问题讨论】:

  • 这个问题是关于“一种特定的算法”,它在这个网站的 ToR 中。人们普遍认为,幼稚的洗牌只是“略微偏离”,寻求偏差的量化是完全合适的。
  • @rici 我在这里添加一个注释,即普遍的看法是错误的。对于n=10,模式2 3 4 5 1 7 8 9 10 6 出现的可能性是模式10 1 2 3 4 5 6 7 8 9 的50 倍以上。这可不是个小偏见!

标签: algorithm probability shuffle fisher-yates-shuffle


【解决方案1】:

Knuth shuffle 如下(在 Python 中,但可能是伪代码)

for i in range(len(v)):
  swap(v, i, randrange(i, len(v))

naïve shuffle 非常相似,但它不是 Knuth shuffle:

for i in range(len(v)):
  swap(v, i, randrange(0, len(v))

Knuth shuffle 产生均匀分布的排列。可以证明朴素 shuffle 不会,因为有 nn 个可能的随机数序列,每个序列具有相等的概率,并且n!可能的排列,这不是 nn 的因素。 (另一方面,Knuth shuffle 恰好涉及 n! 个可能的随机数序列,每个序列都可以被证明产生唯一的排列。)

上述证明并未表明朴素洗牌中的各个排列位置是否均匀分布。尽管如此,排列的非均匀分布仍有可能产生排列元素的均匀分布:例如,如果除了旋转之外的所有排列的概率为 0,并且旋转具有相等的概率,那么排列元素将是均匀分布的。 (这将是比天真的洗牌更糟糕的洗牌。)

事实证明,naïve shuffle 不会产生均匀分布的元素位置。有两点规律性:向量中第一个元素的最终位置是均匀分布的,最终到达最终位置的元素也是如此。

元素ii≠0)最有可能的最终位置是i-1。

这是 n=8 的转移概率表,计算为转移矩阵的乘积:

from/to     0       1       2       3       4       5       6       7
  0      .125    .125    .125    .125    .125    .125    .125    .125
  1      .158    .116    .117    .118    .119    .121    .123    .125
  2      .144    .151    .110    .112    .115    .118    .121    .125
  3      .132    .139    .147    .107    .111    .115    .119    .125
  4      .122    .129    .137    .146    .107    .112    .118    .125
  5      .113    .120    .128    .137    .147    .110    .117    .125
  6      .105    .112    .120    .129    .139    .151    .116    .125
  7      .098    .105    .113    .122    .132    .144    .158    .125

可以推导出 Pn(i, j) -- n 个元素的向量中的元素 i 将被打乱到位置 j 的概率。

在算法中,迭代i时的swap涉及到元素vi sub> 和其他一些元素 vj。 (有可能 i=j。)虽然 swap 是一种对称操作,但区分这两个元素是有用的;我们称之为元素 viout swapin swap em> 的 vj

注意在元素kin swap之后,k不能再out swapped,因为以下所有 out swaps 都位于 k 的新位置之后的位置。因此,如果 k 曾经交换出,则它必须在迭代 k交换出;换句话说,只有第一个涉及元素的交换可以在 out swap

现在,在洗牌的任何一次迭代中,即将换出的元素的最终目的地都是均匀分布的。 (最终目的地为 j 的概率是下一个位置为 i 的概率乘以所有 i 的概率之和下一个位置i的最终目的地为j。由于下一个位置是均匀分布的,因此可以将乘数因式分解,剩余的和为1,因为j 必须来自某个 i。)

另外,对于一个从不out swapped的元素,它的最终目的地是它最后一次in swap发生的迭代。 (一个元素不可能既不是out swapped也不是in swapped。如果元素在in swap发生>out swap 位置,它将被out swapped。)

有了这些,我们就可以推导出转移函数的公式了。

首先,元素 k 将被交换出 的概率正是它在任何迭代中不交换 的概率在k之前,即(n-1)k/nk。在 k交换的洗牌中,最终目的地是均匀分布的,所以这贡献了 (n−1)k/nk+1 到每个转移概率Pn(k, j).

现在让我们考虑最后一个in swap 是在迭代j 的情况(因此是位置j)。在每次迭代中,给定元素将以 1/n 的概率交换。因此,最后一个 in swap 在迭代 j 的概率是在 j 之后没有发生交换的概率乘以发生交换的概率在迭代j,即(n-1)n-j-1/nn-j.

如果jk,那么k不能换出,但是如果j≥k,我们只需要计算在迭代k之前有交换的情况。这导致了以下定义:

Pn(k, j) = ( n-1)k/nk+1 + (1−On(k, j))×(n-1)nj-1/nn-j支持>

在哪里

On(k, j) = 0 如果 jk,否则 (n-1)k/n k

【讨论】:

  • 我认为这个解释可以简化,并且可能对公式进行一些简化(尽管 Wolfram 对我帮助不大)。我明天再看一遍,也许吧。
【解决方案2】:

在适当的 Knuth shuffle 中,您循环遍历 i 元素,选择 52 个元素之一与元素 1 交换,然后选择剩余 51 个元素之一与元素 2 交换,剩余 50 个元素之一与元素 3 交换,等等。一旦一个元素被放入增长的集合 1,2,3... 它将永远不会再移动。所以元素i 出现在位置 1 的几率正好是 1/52——它只能发生在第一个循环中。它最终进入单元格 2 的几率是它不在单元格 1 中的几率 (51/52) 乘以它在第二次通过时被选中的几率 (1/51)。 51s 取消,留下 1/52。同样,元素i 出现在位置 3 的机会是 51/52 * 50/51 * 1/50,同样是 1/52。所以每个元素都有相同的机会出现在每个单元格中。

在你的洗牌中,可能会再次选择已经放置的元素以供以后切换,这使得计算几率非常困难。

【讨论】:

    【解决方案3】:

    This page 将您提到的算法与 Knuth 的算法进行比较,说明为什么 Knuth 的算法更好。

    注意:以下内容可能有误,请参阅 cmets。

    我不知道有一种简单的方法来计算您询问的概率,我似乎也找不到任何简单的解释,但这个想法是您的算法(通常称为 naive shuffle 算法)考虑n^n 数组的排列而不是 n!。这是因为元素i 可以在步骤i 中的每个n 位置结束。由于您在每个步骤中都有n 的可能性和n 步骤,因此加起来为n^n。由于n^n 并不总是能被n! 整除,因此并非所有排列都具有相同的概率,这就是为什么该算法被认为是糟糕的混洗算法。

    由于并非所有排列都具有相同的概率,因此您询问的概率对于 ij 的不同值是不同的,但我不知道计算它的公式。

    【讨论】:

    • 理论上,排列可能是非均匀分布的,而单个元素的位置仍然是均匀分布的。例如,假设算法产生的唯一排列是旋转。如果旋转是均匀分布的,那么元素位置也是均匀分布的。不同之处在于元素位置不是独立均匀分布的。 (我相信 OP 中提到的朴素算法不会均匀分布排列或元素位置,但我也不确定。)
    • @rici - 是的,但如果这里是这种情况,那么幼稚的洗牌在实践中不会很好用吗?
    • 洗牌的重点当然是洗牌。假设您正在与洗牌机玩纸牌游戏,洗牌机为您提供收到黑桃 A 的正确概率以及收到黑桃 K 的正确概率。但是,您总是要么都收到,要么都不收到。那是“在实践中运作良好”吗?我认为不会。
    • 好的,我算出一个封闭的形式,概率肯定不统一(除了边缘)。如果您有兴趣,请提供答案。
    猜你喜欢
    • 1970-01-01
    • 2021-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-11
    • 1970-01-01
    相关资源
    最近更新 更多