【发布时间】:2015-08-11 09:27:42
【问题描述】:
用n个骰子找到滚动和的概率的最佳解决方案是什么? 我正在通过查找来解决它
- 意思。
- 标准偏差。
- z_score 下面的数字
x - 上述数字的z_score
x - 将两者都转换为概率
- 从另一个中减去一个
这是我到目前为止所做的。
# sides - number of sides on one die
def get_mean(sides)
(1..sides).inject(:+) / sides.to_f
end
def get_variance(sides)
mean_of_squares = ((1..sides).inject {|sum, side| sum + side ** 2}) / sides.to_f
square_mean = get_mean(sides) ** 2
mean_of_squares - square_mean
end
def get_sigma(variance)
variance ** 0.5
end
# x - the number of points in question
def get_z_score(x, mean, sigma)
(x - mean) / sigma.to_f
end
# Converts z_score to probability
def z_to_probability(z)
return 0 if z < -6.5
return 1 if z > 6.5
fact_k = 1
sum = 0
term = 1
k = 0
loop_stop = Math.exp(-23)
while term.abs > loop_stop do
term = 0.3989422804 * ((-1)**k) * (z**k) / (2*k+1) / (2**k) * (z**(k+1)) / fact_k
sum += term
k += 1
fact_k *= k
end
sum += 0.5
1 - sum
end
# Calculate probability of getting 'х' total points by rolling 'n' dice with 'sides' number of sides.
def probability_of_sum(x, n, sides=6)
mean = n * get_mean(sides)
variance = get_variance(sides)
sigma = get_sigma(n * variance)
# Rolling below the sum
z1 = get_z_score(x, mean, sigma)
prob_1 = z_to_probability(z1)
# Rolling above the sum
z2 = get_z_score(x+1, mean, sigma)
prob_2 = z_to_probability(z2)
prob_1 - prob_2
end
# Run probability for 100 dice
puts probability_of_sum(400, 100)
我担心的是,当我选择x = 200时,概率为0。
这是正确的解决方案吗?
【问题讨论】:
-
如果我理解正确.. 不。如果您将所有 2 掷 100 次,总数将是 200。所以它有一定的可能性发生。
-
我也是这么想的。但是,根据68-95-99.7 (empirical) rule 或 3-sigma 规则“大约 68% 从正态分布中提取的值在 1 标准偏差 σ i> 偏离平均值;大约 95% 的值在 2 个标准差范围内;大约 99.7% 在 3 个范围内 标准差。”在这种情况下,使用 100 6 面骰子
mean = 350和σ = 17。这意味着,99.7% 的值将落在 299 到 401 的范围内。 (350 +/- 17 * 3) -
另外请注意,算法存在根本问题,运行非常简单的东西,例如 x=12 和 n=2(应该是 1/36)不起作用。我认为@NeilSlater 可能对离散性有所了解。
-
在简单的情况下,比如滚动 2 个骰子
Monte Carlo模拟是更好的解决方案。这种情况不同。 -
如果您关心结果的准确性,Monte Carlo 并不是一个好的解决方案。对于一个简单的分布,例如相同骰子的总和,可以以完美的精度和比蒙特卡洛更快的任何合理误差进行计算。
标签: ruby math probability standard-deviation