结果概率算法
我有一个概率问题,我需要在合理的时间内模拟它。简单来说,我有 30 个不公平的硬币,每个硬币都有不同的已知概率。然后我想问诸如“恰好 12 个正面朝上的概率是多少?”或“至少 5 个正面朝上的概率是多少?”。
我了解基本的概率论,所以我知道我可以枚举所有(30 个选择 x)的可能性,但这并不是特别可扩展。最坏的情况(30选15)有超过1.5亿种组合。从计算的角度来看,是否有更好的方法来解决这个问题?
非常感谢任何帮助,谢谢! :-)
I have a probability problem, which I need to simulate in a reasonable amount of time. In simplified form, I have 30 unfair coins each with a different known probability. I then want to ask things like "what is the probability that exactly 12 will be heads?", or "what is the probability that AT LEAST 5 will be tails?".
I know basic probability theory, so I know I can enumerate all (30 choose x) possibilities, but that's not particularly scalable. The worst case (30 choose 15) has over 150 million combinations. Is there a better way to approach this problem from a computational standpoint?
Any help is greatly appreciated, thanks! :-)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以使用动态规划方法。
例如,要计算 30 个硬币中有 12 个正面朝上的概率,令 P(n, k) 为前 n 个硬币中有 k 个正面朝上的概率。
那么 P(n, k) = p_n * P(n - 1, k - 1) + (1 - p_n) * P(n - 1, k)
(这里 p_i 是第 i 个硬币正面朝上的概率)。
您现在可以在动态规划算法中使用此关系。有一个包含 13 个概率的向量(表示 0..12 中 i 的 P(n - 1, i))。使用上述递推关系为 P(n, i) 构建一个新的 13 向量。重复直到 n = 30。当然,您从 n=0 的向量 (1, 0, 0, 0, ...) 开始(因为没有硬币,您肯定不会得到正面)。
使用此算法的最坏情况是 O(n^2) 而不是指数。
You can use a dynamic programming approach.
For example, to calculate the probability of 12 heads out of 30 coins, let P(n, k) be the probability that there's k heads from the first n coins.
Then P(n, k) = p_n * P(n - 1, k - 1) + (1 - p_n) * P(n - 1, k)
(here p_i is the probability the i'th coin is heads).
You can now use this relation in a dynamic programming algorithm. Have a vector of 13 probabilities (that represent P(n - 1, i) for i in 0..12). Build a new vector of 13 for P(n, i) using the above recurrence relation. Repeat until n = 30. Of course, you start with the vector (1, 0, 0, 0, ...) for n=0 (since with no coins, you're sure to get no heads).
The worst case using this algorithm is O(n^2) rather than exponential.
这实际上是一个有趣的问题。我受到启发写了一篇关于它的博客文章,详细介绍了公平与不公平的硬币抛掷,一直到OP的情况,即每种硬币具有不同的概率。您需要一种称为动态规划的技术来在多项式时间内解决这个问题。
一般问题:给定C,一系列n个硬币p1 > 到 pn,其中 pi< /sub> 表示第 i 个硬币正面朝上的概率,抛掷所有硬币后出现 k 个正面朝上的概率是多少?
这意味着求解以下递推关系:
P(n,k,C,i) = pi x P(n-1,k-1,C,i+1) + (1-pi) x P(n,k,C,i+1)
执行此操作的 Java 代码片段如下:
这是构建一个表,显示从 pi 到 pi 的硬币序列的概率em>pn 包含 k 个头。
有关二项式概率的更深入介绍以及如何应用动态规划的讨论,请查看 抛硬币、二项式和动态规划。
This is actually an interesting problem. I was inspired to write a blog post about it covering in detail fair vs unfair coin tosses all the way to the OP's situation of having a different probability for each coin. You need a technique called dynamic programming to solve this problem in polynomial time.
General Problem: Given C, a series of n coins p1 to pn where pi represents the probability of the i-th coin coming up heads, what is the probability of k heads coming up from tossing all the coins?
This means solving the following recurrence relation:
P(n,k,C,i) = pi x P(n-1,k-1,C,i+1) + (1-pi) x P(n,k,C,i+1)
A Java code snippet that does this is:
What this is doing is constructing a table that shows the probability that a sequence of coins from pi to pn contain k heads.
For a deeper introduction to binomial probability and a discussion on how to apply dynamic programming take a look at Coin Tosses, Binomials and Dynamic Programming.
伪代码:
最坏情况 = O(kn)
Pseudocode:
Worst case = O(kn)