对双胞胎团聚的概率进行编程
Programming a probability of twins reunion
我有如下问题,我试过了,但找不到正确的结果。我想在不使用额外库的情况下以简单的方式解决它。我没有任何数据可以分享,因为我无法建立正确的逻辑。
4 对双胞胎(总共 8 children)闭着眼睛玩耍。关键时刻到来时,随机分配的 children 组中的 children 成对握住彼此的手。如何写一个python脚本,列出所有的可能性,并标出兄弟姐妹牵手的概率?
list = ['a1', 'a2', 'b1', 'b2', 'c1', 'c2', 'd1', 'd2']
我想得到这样的结果:
[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
...
感谢您的帮助。
如果包含的库适合您,您可以尝试使用 random.choice()。
我还添加了一小部分,估计找到正确双胞胎的概率。
尝试以下操作:
import random
twins= ['a1', 'a2', 'b1', 'b2', 'c1', 'c2', 'd1', 'd2']
twinsToFind= ['a1','a2', 'b1', 'b2', 'c1', 'c2', 'd1', 'd2']
# Loop over the list
for i in range(0, 4):
searcher = twins[0]
# remove the searching twin, since he shouldn't find "himself"
twinsToFind.remove(searcher)
# also remove him from the list, since he won't search again
twins.remove(searcher)
# variable for the probability of finding the right twin
prob = 0
# loop over to second list to check how possible it is to find the right twin
for y in twinsToFind:
if searcher[0] == y[0]:
prob =+1
# estimating the probability
prob = prob/len(twinsToFind)
# printing the probability
# casting it to inc gets rid of the digits behind the comma
# multiplying it with 100 gives the probability in percent
print("The probability to find the right twin is: "+str(int(prob*100))+"%")
# find a random twin
found = random.choice(twinsToFind)
# print a message if it's the right twin
if searcher[0] == found[0]:
print("==> Right twin found: "+searcher+found)
# remove the "found" twin from the list, because he won't search again
twins.remove(found)
# remove the found twin from the second list, because he shouldn't be found again
# (yeah, sounds a bit dark, but you get it, I guess)
twinsToFind.remove(found)
print("Found:"+searcher+"<->"+found)
创建所有配对并与正确的配对进行比较
首先,定义一个生成所有配对的函数,以及一个生成正确配对的函数:
def all_pairings(l):
if len(l) == 0:
return [[]]
else:
return [[(l[0],l[i])] + p for i in range(1,len(l)) for p in all_pairings(l[1:i]+l[i+1:])]
def adjacent_pairing(l):
it = iter(l)
return zip(it, it)
那就是for-loop:
children = ['a1', 'a2', 'b1', 'b2', 'c1', 'c2', 'd1', 'd2']
correct_pairing = set(adjacent_pairing(children))
for pairing in all_pairings(children):
sentence = 'Found' if set(pairing) == correct_pairing else 'Not found'
print(', '.join(''.join(pair) for pair in pairing), ' -- ', sentence)
输出:
a1a2, b1b2, c1c2, d1d2 -- Found
a1a2, b1b2, c1d1, c2d2 -- Not found
a1a2, b1b2, c1d2, c2d1 -- Not found
a1a2, b1c1, b2c2, d1d2 -- Not found
...
a1d2, a2d1, b1b2, c1c2 -- Not found
a1d2, a2d1, b1c1, b2c2 -- Not found
a1d2, a2d1, b1c2, b2c1 -- Not found
洗牌配对
我建议在迭代之前使用random.shuffle
打乱可能的配对(否则,正确的配对总是第一个生成的配对,这有点无聊)。
import random
l = list(all_pairings(children))
random.shuffle(l)
for pairing in l:
sentence = 'Found' if set(pairing) == correct_pairing else 'Not found'
print(', '.join(''.join(pair) for pair in pairing), ' -- ', sentence)
输出:
a1a2, b1d2, b2d1, c1c2 -- Not found
a1d1, a2d2, b1c2, b2c1 -- Not found
a1b2, a2c2, b1c1, d1d2 -- Not found
...
a1b1, a2c2, b2d1, c1d2 -- Not found
a1a2, b1b2, c1c2, d1d2 -- Found
a1b2, a2c2, b1d2, c1d1 -- Not found
...
a1c2, a2d2, b1b2, c1d1 -- Not found
a1c2, a2d2, b1c1, b2d1 -- Not found
a1b1, a2b2, c1c2, d1d2 -- Not found
找到正确配对的概率
假设所有配对都是等概率的,随机选择一对时找到正确配对的概率是 1 除以不同可能配对的总数。
有多少种不同的可能配对?
选择有序配对,其中配对的顺序很重要,每对中两个 children 的顺序很重要,与选择排列相同。众所周知,N
children.
有N!
种可能的排列
每个无序对对应多少个有序对?
每对 2 children 有 2 种可能的订购方式;因此有 2 ** (N / 2)
种方法来订购所有对中的 2 children。
有 (N / 2)!
种可能的方式来订购 N / 2
对。
因此,每个配对对应 (N / 2)! * 2 ** (N / 2)
个有序配对。
因此,N
children.
必须有 N! / ( (N / 2)! * 2 ** (N / 2) )
个不同的可能配对
你的 8 children,就是 8! / (4! * 2**4) == 105
。
在所有不同的可能配对中均匀随机选择时,选择正确配对的概率是该数字的 1:
在8 children.
的情况下略低于1%
随机配对中预期的正确对数
让我们在所有不同的可能配对中随机选择一个配对。该配对中平均有多少对是正确的?
我们可以在我们的 python 程序中计算每个配对中的正确对数:
for pairing in all_pairings(children):
nb_correct_pairs = len(set(pairing) & correct_pairing)
print(', '.join(''.join(pair) for pair in pairing), ' -- ', nb_correct_pairs)
输出:
a1a2, b1b2, c1c2, d1d2 -- 4
a1a2, b1b2, c1d1, c2d2 -- 2
a1a2, b1b2, c1d2, c2d1 -- 2
a1a2, b1c1, b2c2, d1d2 -- 2
a1a2, b1c1, b2d1, c2d2 -- 1
a1a2, b1c1, b2d2, c2d1 -- 1
a1a2, b1c2, b2c1, d1d2 -- 2
a1a2, b1c2, b2d1, c1d2 -- 1
...
a1d2, a2c1, b1d1, b2c2 -- 0
a1d2, a2c2, b1b2, c1d1 -- 1
a1d2, a2c2, b1c1, b2d1 -- 0
a1d2, a2c2, b1d1, b2c1 -- 0
a1d2, a2d1, b1b2, c1c2 -- 2
a1d2, a2d1, b1c1, b2c2 -- 0
a1d2, a2d1, b1c2, b2c1 -- 0
平均数其实用数学很容易算出来
让我们考虑随机配对中的一个特定 child,例如 child a1
。 child a1
握住双胞胎手的概率是多少?由于还有 N-1
个其他 children,并且根据对称性,所有 children 的可能性均等,因此 child a1
将握住双胞胎手的概率是 1/(N-1)
.
当然,这适用于所有child人,而不仅仅是a1
。因此,平均而言,child 人中的 1/(N-1)
人会握住自己双胞胎的手。既然有N
children,那么平均来说,N/(N-1) == 1 + 1/(N-1)
children会牵起自己双胞胎的手。由于每对有 2 children,这意味着在随机配对中平均会有 N / (2(N-1)) == (1 + 1/(N-1)) / 2
个正确的对。
在 N == 8
的情况下,这意味着每个配对 4/7 ≈ 0.571
对。
让我们通过实验验证一下:
l = list(all_pairings(children))
total_correct_pairs = sum(len(set(pairing) & correct_pairing) for pairing in l)
n_pairings = len(l)
expected_correct_pairs = total_correct_pairs / n_pairings
print('Expected number of correct pairs: ', expected_correct_pairs)
输出:
Expected number of correct pairs: 0.5714285714285714
我有如下问题,我试过了,但找不到正确的结果。我想在不使用额外库的情况下以简单的方式解决它。我没有任何数据可以分享,因为我无法建立正确的逻辑。
4 对双胞胎(总共 8 children)闭着眼睛玩耍。关键时刻到来时,随机分配的 children 组中的 children 成对握住彼此的手。如何写一个python脚本,列出所有的可能性,并标出兄弟姐妹牵手的概率?
list = ['a1', 'a2', 'b1', 'b2', 'c1', 'c2', 'd1', 'd2']
我想得到这样的结果:
[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
...
感谢您的帮助。
如果包含的库适合您,您可以尝试使用 random.choice()。
我还添加了一小部分,估计找到正确双胞胎的概率。
尝试以下操作:
import random
twins= ['a1', 'a2', 'b1', 'b2', 'c1', 'c2', 'd1', 'd2']
twinsToFind= ['a1','a2', 'b1', 'b2', 'c1', 'c2', 'd1', 'd2']
# Loop over the list
for i in range(0, 4):
searcher = twins[0]
# remove the searching twin, since he shouldn't find "himself"
twinsToFind.remove(searcher)
# also remove him from the list, since he won't search again
twins.remove(searcher)
# variable for the probability of finding the right twin
prob = 0
# loop over to second list to check how possible it is to find the right twin
for y in twinsToFind:
if searcher[0] == y[0]:
prob =+1
# estimating the probability
prob = prob/len(twinsToFind)
# printing the probability
# casting it to inc gets rid of the digits behind the comma
# multiplying it with 100 gives the probability in percent
print("The probability to find the right twin is: "+str(int(prob*100))+"%")
# find a random twin
found = random.choice(twinsToFind)
# print a message if it's the right twin
if searcher[0] == found[0]:
print("==> Right twin found: "+searcher+found)
# remove the "found" twin from the list, because he won't search again
twins.remove(found)
# remove the found twin from the second list, because he shouldn't be found again
# (yeah, sounds a bit dark, but you get it, I guess)
twinsToFind.remove(found)
print("Found:"+searcher+"<->"+found)
创建所有配对并与正确的配对进行比较
首先,定义一个生成所有配对的函数,以及一个生成正确配对的函数:
def all_pairings(l):
if len(l) == 0:
return [[]]
else:
return [[(l[0],l[i])] + p for i in range(1,len(l)) for p in all_pairings(l[1:i]+l[i+1:])]
def adjacent_pairing(l):
it = iter(l)
return zip(it, it)
那就是for-loop:
children = ['a1', 'a2', 'b1', 'b2', 'c1', 'c2', 'd1', 'd2']
correct_pairing = set(adjacent_pairing(children))
for pairing in all_pairings(children):
sentence = 'Found' if set(pairing) == correct_pairing else 'Not found'
print(', '.join(''.join(pair) for pair in pairing), ' -- ', sentence)
输出:
a1a2, b1b2, c1c2, d1d2 -- Found
a1a2, b1b2, c1d1, c2d2 -- Not found
a1a2, b1b2, c1d2, c2d1 -- Not found
a1a2, b1c1, b2c2, d1d2 -- Not found
...
a1d2, a2d1, b1b2, c1c2 -- Not found
a1d2, a2d1, b1c1, b2c2 -- Not found
a1d2, a2d1, b1c2, b2c1 -- Not found
洗牌配对
我建议在迭代之前使用random.shuffle
打乱可能的配对(否则,正确的配对总是第一个生成的配对,这有点无聊)。
import random
l = list(all_pairings(children))
random.shuffle(l)
for pairing in l:
sentence = 'Found' if set(pairing) == correct_pairing else 'Not found'
print(', '.join(''.join(pair) for pair in pairing), ' -- ', sentence)
输出:
a1a2, b1d2, b2d1, c1c2 -- Not found
a1d1, a2d2, b1c2, b2c1 -- Not found
a1b2, a2c2, b1c1, d1d2 -- Not found
...
a1b1, a2c2, b2d1, c1d2 -- Not found
a1a2, b1b2, c1c2, d1d2 -- Found
a1b2, a2c2, b1d2, c1d1 -- Not found
...
a1c2, a2d2, b1b2, c1d1 -- Not found
a1c2, a2d2, b1c1, b2d1 -- Not found
a1b1, a2b2, c1c2, d1d2 -- Not found
找到正确配对的概率
假设所有配对都是等概率的,随机选择一对时找到正确配对的概率是 1 除以不同可能配对的总数。
有多少种不同的可能配对?
选择有序配对,其中配对的顺序很重要,每对中两个 children 的顺序很重要,与选择排列相同。众所周知,N
children.
N!
种可能的排列
每个无序对对应多少个有序对?
每对 2 children 有 2 种可能的订购方式;因此有 2 ** (N / 2)
种方法来订购所有对中的 2 children。
有 (N / 2)!
种可能的方式来订购 N / 2
对。
因此,每个配对对应 (N / 2)! * 2 ** (N / 2)
个有序配对。
因此,N
children.
N! / ( (N / 2)! * 2 ** (N / 2) )
个不同的可能配对
你的 8 children,就是 8! / (4! * 2**4) == 105
。
在所有不同的可能配对中均匀随机选择时,选择正确配对的概率是该数字的 1:
在8 children.
的情况下略低于1%随机配对中预期的正确对数
让我们在所有不同的可能配对中随机选择一个配对。该配对中平均有多少对是正确的?
我们可以在我们的 python 程序中计算每个配对中的正确对数:
for pairing in all_pairings(children):
nb_correct_pairs = len(set(pairing) & correct_pairing)
print(', '.join(''.join(pair) for pair in pairing), ' -- ', nb_correct_pairs)
输出:
a1a2, b1b2, c1c2, d1d2 -- 4
a1a2, b1b2, c1d1, c2d2 -- 2
a1a2, b1b2, c1d2, c2d1 -- 2
a1a2, b1c1, b2c2, d1d2 -- 2
a1a2, b1c1, b2d1, c2d2 -- 1
a1a2, b1c1, b2d2, c2d1 -- 1
a1a2, b1c2, b2c1, d1d2 -- 2
a1a2, b1c2, b2d1, c1d2 -- 1
...
a1d2, a2c1, b1d1, b2c2 -- 0
a1d2, a2c2, b1b2, c1d1 -- 1
a1d2, a2c2, b1c1, b2d1 -- 0
a1d2, a2c2, b1d1, b2c1 -- 0
a1d2, a2d1, b1b2, c1c2 -- 2
a1d2, a2d1, b1c1, b2c2 -- 0
a1d2, a2d1, b1c2, b2c1 -- 0
平均数其实用数学很容易算出来
让我们考虑随机配对中的一个特定 child,例如 child a1
。 child a1
握住双胞胎手的概率是多少?由于还有 N-1
个其他 children,并且根据对称性,所有 children 的可能性均等,因此 child a1
将握住双胞胎手的概率是 1/(N-1)
.
当然,这适用于所有child人,而不仅仅是a1
。因此,平均而言,child 人中的 1/(N-1)
人会握住自己双胞胎的手。既然有N
children,那么平均来说,N/(N-1) == 1 + 1/(N-1)
children会牵起自己双胞胎的手。由于每对有 2 children,这意味着在随机配对中平均会有 N / (2(N-1)) == (1 + 1/(N-1)) / 2
个正确的对。
在 N == 8
的情况下,这意味着每个配对 4/7 ≈ 0.571
对。
让我们通过实验验证一下:
l = list(all_pairings(children))
total_correct_pairs = sum(len(set(pairing) & correct_pairing) for pairing in l)
n_pairings = len(l)
expected_correct_pairs = total_correct_pairs / n_pairings
print('Expected number of correct pairs: ', expected_correct_pairs)
输出:
Expected number of correct pairs: 0.5714285714285714