我正在尝试编写一个脚本来计算从给定列表中选择随机元素的概率。这是我到目前为止所拥有的:
import random
a = [11, 12, 13, 14]
b = [21, 22, 23, 24, 25]
c = [31, 32, 33, 34, 35, 36]
total = a+b+c
print ("Choosing 3 random items from any list")
sampled_list = random.sample(total, 3)
print(sampled_list)
使用此脚本,我可以选择三个随机元素而无需替换。现在我想计算生成的随机列表将包含列表 b 中的两个元素或每个列表中的一个元素的概率。我该怎么办?我在列表中选择数字不是最有效的方法吗?
这是您如何为您的第一个任务进行蒙特卡洛采样(恰好包含 B 中的两个元素)。
大致的想法是检查特定样本是否满足您所拥有的任何条件,并在此处增加变量 (
counter
)。则近似概率为 counter / N
。
import random
a = [11, 12, 13, 14]
b = [21, 22, 23, 24, 25]
c = [31, 32, 33, 34, 35, 36]
total = a+b+c
N = 1000
counter = 0
for _ in range(N):
sampled_list = random.sample(total, 3)
els_in_b = 0
for el in sampled_list:
if el in b:
els_in_b += 1
if els_in_b == 2:
counter += 1
print(counter / N)
这只是概率论。 您只需计算有效可能性的数量并将其除以可能性的总数。
所以,我们需要一个方程来计算可能的组合数量,或者
nCr
:
from math import factorial
def nCr(n, r):
return(factorial(n)//(factorial(r)*factorial(n-r)))
现在我们有了这个,我们可以轻松计算以特定方式选择数字的概率是多少。 假设我们有一个包含 3 个值的列表,每个值表示从特定列表中获取了多少个值。 因此,举例来说,如果我们想从列表 1 中获取 2 个,从列表 2 中获取 1 个,我们可以计算当我们从一组所有列表中随机选择 3 个时发生这种情况的概率,其中:
from functools import reduce
import operator
# Define product function
def prod(iterable):
return(reduce(operator.mul, iterable, 1))
# Define lists
numbers = [
[11, 12, 13, 14],
[21, 22, 23, 24, 25],
[31, 32, 33, 34, 35, 36]
]
# Define how many are taken from each
n_taken = [2, 1, 0]
# Calculate number of values in each list
n_values = list(map(len, numbers))
# Calculate total number of values
n_total = sum(n_values)
# Calculate number of ways numbers can be taken this way
N1 = prod(map(nCr, n_values, n_taken))
# Calculate total number of possibilities
N2 = nCr(n_total, sum(n_taken))
# Divide the two
print(N1/N2)
输出:
0.06593406593406594
或约6.6%。
您可以修改
numbers
和 n_taken
列表以添加更多列表或向列表中添加更多数字。
它可能不是最优雅的解决方案,但至少它提供了一个可以轻松阅读和扩展的简单解决方案。
import random
a = [11, 12, 13, 14]
b = [21, 22, 23, 24, 25]
c = [31, 32, 33, 34, 35, 36]
total = a+b+c
# Decide how many samples you want.
samples = 100
# Define an empty vector.
combs = []
# Get the possible outcomes of number of elements per list.
for i in range(0,4):
for j in range(0,4):
for k in range(0,4):
if(i + j + k == 3):
combs = combs + [[i,j,k]]
# Count of how many elements per group
accum = [0 for x in combs]
# Perform the experiment a number of times given the sample.
for i in range(samples):
# Auxiliary variables.
totalEnt = [0,0,0]
sampled_list = random.sample(total, 3)
# Store the number of elements that belong to each list.
totalEnt[0] = [x in a for x in sampled_list].count(True)
totalEnt[1] = [x in b for x in sampled_list].count(True)
totalEnt[2] = [x in c for x in sampled_list].count(True)
# According to the result add to the proper counter.
idx = combs.index(totalEnt)
accum[idx] += 1
# Print the probabilities.
print("[elements in a, elements in b, elements in c]: Probability")
for i, elem in enumerate(accum):
print(str(combs[i]) + ": " + str(elem/samples))