对双胞胎团聚的概率进行编程

etn*_*clp 6 python algorithm hash

我有如下问题,我尝试过但找不到正确的结果。我想以简单的方式解决它,而不使用额外的库。我没有任何数据可以分享,因为我无法建立正确的逻辑。

4对双胞胎(共8个孩子)闭着眼睛玩耍。当某个时刻到来时,随机分布的小组中的孩子们会成对地握住彼此的手。如何编写一个python脚本,列出所有可能性并标记兄弟姐妹握住对方手的概率?

list = ['a1', 'a2', 'b1', 'b2', 'c1', 'c2', 'd1', 'd2']
Run Code Online (Sandbox Code Playgroud)

我想得到这样的结果:

[a1a2, b1b2, c1c2, d1d2] - Found
[a1a2, b1b2, c1d1, c2d2] - Not found
[a1a2, b1b2, c1d2, c2d1] - Not found
[a1a2, b1b2, c1d1, c2d2] - Not found
[a1a2, b2b1, c1d1, c2d2] - Not found
...
all possible matches
...
Run Code Online (Sandbox Code Playgroud)

感谢帮助。

Ste*_*tef 3

创建所有配对并与正确配对进行比较

\n

首先,定义一个函数来生成所有配对,以及一个函数来生成正确的配对:

\n
def all_pairings(l):\n  if len(l) == 0:\n    return [[]]\n  else:\n    return [[(l[0],l[i])] + p for i in range(1,len(l)) for p in all_pairings(l[1:i]+l[i+1:])]\n\ndef adjacent_pairing(l):\n    it = iter(l)\n    return zip(it, it)\n
Run Code Online (Sandbox Code Playgroud)\n

那么它只是一个 for 循环:

\n
\nchildren = [\'a1\', \'a2\', \'b1\', \'b2\', \'c1\', \'c2\', \'d1\', \'d2\']\n\ncorrect_pairing = set(adjacent_pairing(children))\n\nfor pairing in all_pairings(children):\n    sentence = \'Found\' if set(pairing) == correct_pairing else \'Not found\'\n    print(\', \'.join(\'\'.join(pair) for pair in pairing), \' -- \', sentence)\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
a1a2, b1b2, c1c2, d1d2  --  Found\na1a2, b1b2, c1d1, c2d2  --  Not found\na1a2, b1b2, c1d2, c2d1  --  Not found\na1a2, b1c1, b2c2, d1d2  --  Not found\n...\na1d2, a2d1, b1b2, c1c2  --  Not found\na1d2, a2d1, b1c1, b2c2  --  Not found\na1d2, a2d1, b1c2, b2c1  --  Not found\n
Run Code Online (Sandbox Code Playgroud)\n

打乱配对

\n

我建议random.shuffle在迭代之前对可能的配对进行打乱(否则,正确的配对始终是生成的第一个配对,这有点无聊)。

\n
a1a2, b1b2, c1c2, d1d2  --  Found\na1a2, b1b2, c1d1, c2d2  --  Not found\na1a2, b1b2, c1d2, c2d1  --  Not found\na1a2, b1c1, b2c2, d1d2  --  Not found\n...\na1d2, a2d1, b1b2, c1c2  --  Not found\na1d2, a2d1, b1c1, b2c2  --  Not found\na1d2, a2d1, b1c2, b2c1  --  Not found\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
a1a2, b1d2, b2d1, c1c2  --  Not found\na1d1, a2d2, b1c2, b2c1  --  Not found\na1b2, a2c2, b1c1, d1d2  --  Not found\n...\na1b1, a2c2, b2d1, c1d2  --  Not found\na1a2, b1b2, c1c2, d1d2  --  Found\na1b2, a2c2, b1d2, c1d1  --  Not found\n...\na1c2, a2d2, b1b2, c1d1  --  Not found\na1c2, a2d2, b1c1, b2d1  --  Not found\na1b1, a2b2, c1c2, d1d2  --  Not found\n
Run Code Online (Sandbox Code Playgroud)\n

找到正确配对的概率

\n

假设所有配对都是等概率的,则随机挑选一对时找到正确配对的概率为 1 除以不同可能配对的总数。

\n

有多少种不同的可能配对?

\n

选择有序配对(其中配对的顺序很重要,并且每对中两个子项的顺序也很重要)与选择排列相同。众所周知,孩子N!可能存在排列N

\n

每个无序配对对应有多少个有序配对?

\n

有 2 种可能的方式对每对中的 2 个孩子进行排序;因此有一些2 ** (N / 2)方法可以对所有对中的 2 个孩子进行排序。

\n

有多种(N / 2)!可能的方法来对这些对进行N / 2排序。

\n

因此,每个配对对应于(N / 2)! * 2 ** (N / 2)有序配对。

\n

因此,孩子们必须有N! / ( (N / 2)! * 2 ** (N / 2) )不同的可能配对N

\n

对于您的 8 个孩子来说,这就是8! / (4! * 2**4) == 105

\n

当在所有不同的可能配对中均匀随机挑选时,挑选正确配对的概率是该数字的 1:

\n

8 个孩子的比例略低于 1%

\n

随机配对中正确配对的预期数量

\n

让我们从所有不同的可能配对中随机选择一个配对。该配对中平均有多少对是正确的?

\n

我们可以在 python 程序中计算每个配对中正确配对的数量:

\n
import random\n\nl = list(all_pairings(children))\nrandom.shuffle(l)\nfor pairing in l:\n    sentence = \'Found\' if set(pairing) == correct_pairing else \'Not found\'\n    print(\', \'.join(\'\'.join(pair) for pair in pairing), \' -- \', sentence)\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
a1a2, b1b2, c1c2, d1d2  --  4\na1a2, b1b2, c1d1, c2d2  --  2\na1a2, b1b2, c1d2, c2d1  --  2\na1a2, b1c1, b2c2, d1d2  --  2\na1a2, b1c1, b2d1, c2d2  --  1\na1a2, b1c1, b2d2, c2d1  --  1\na1a2, b1c2, b2c1, d1d2  --  2\na1a2, b1c2, b2d1, c1d2  --  1\n...\na1d2, a2c1, b1d1, b2c2  --  0\na1d2, a2c2, b1b2, c1d1  --  1\na1d2, a2c2, b1c1, b2d1  --  0\na1d2, a2c2, b1d1, b2c1  --  0\na1d2, a2d1, b1b2, c1c2  --  2\na1d2, a2d1, b1c1, b2c2  --  0\na1d2, a2d1, b1c2, b2c1  --  0\n
Run Code Online (Sandbox Code Playgroud)\n

平均数其实很容易用数学计算出来。

\n

让我们考虑随机配对中的一个特定孩子,例如 child a1a1孩子握住双胞胎的手的概率是多少?由于还有其他孩子,并且通过对称性,所有孩子的可能性相同,因此孩子握住双胞胎的手的N-1概率为。a11/(N-1)

\n

当然,这适用于所有孩子,而不仅仅是a1。因此,平均而言,1/(N-1)孩子们会握住自己双胞胎的手。既然有N孩子,那么平均来说,N/(N-1) == 1 + 1/(N-1)孩子们都会牵着自己双胞胎的手。N / (2(N-1)) == (1 + 1/(N-1)) / 2由于每对有 2 个孩子,这意味着随机配对中平均会有正确的配对。

\n

在 的情况下N == 8,这意味着4/7 \xe2\x89\x88 0.571每次配对都是正确的。

\n

我们通过实验来验证一下:

\n
a1a2, b1d2, b2d1, c1c2  --  Not found\na1d1, a2d2, b1c2, b2c1  --  Not found\na1b2, a2c2, b1c1, d1d2  --  Not found\n...\na1b1, a2c2, b2d1, c1d2  --  Not found\na1a2, b1b2, c1c2, d1d2  --  Found\na1b2, a2c2, b1d2, c1d1  --  Not found\n...\na1c2, a2d2, b1b2, c1d1  --  Not found\na1c2, a2d2, b1c1, b2d1  --  Not found\na1b1, a2b2, c1c2, d1d2  --  Not found\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
Expected number of correct pairs:  0.5714285714285714\n
Run Code Online (Sandbox Code Playgroud)\n