结果概率算法

发布于 2024-09-15 17:49:10 字数 241 浏览 6 评论 0原文

我有一个概率问题,我需要在合理的时间内模拟它。简单来说,我有 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

等待我真够勒 2024-09-22 17:49:10

您可以使用动态规划方法。

例如,要计算 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.

哑剧 2024-09-22 17:49:10

这实际上是一个有趣的问题。我受到启发写了一篇关于它的博客文章,详细介绍了公平与不公平的硬币抛掷,一直到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 代码片段如下:

private static void runDynamic() {
  long start = System.nanoTime();
  double[] probs = dynamic(0.2, 0.3, 0.4);
  long end = System.nanoTime();
  int total = 0;
  for (int i = 0; i < probs.length; i++) {
    System.out.printf("%d : %,.4f%n", i, probs[i]);
  }
  System.out.printf("%nDynamic ran for %d coinsin %,.3f ms%n%n",
      coins.length, (end - start) / 1000000d);
}

private static double[] dynamic(double... coins) {
  double[][] table = new double[coins.length + 2][];
  for (int i = 0; i < table.length; i++) {
    table[i] = new double[coins.length + 1];
  }
  table[1][coins.length] = 1.0d; // everything else is 0.0
  for (int i = 0; i <= coins.length; i++) {
    for (int j = coins.length - 1; j >= 0; j--) {
      table[i + 1][j] = coins[j] * table[i][j + 1] +
          (1 - coins[j]) * table[i + 1][j + 1];
    }
  }
  double[] ret = new double[coins.length + 1];
  for (int i = 0; i < ret.length; i++) {
    ret[i] = table[i + 1][0];
  }
  return ret;
}

这是构建一个表,显示从 pipi 的硬币序列的概率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:

private static void runDynamic() {
  long start = System.nanoTime();
  double[] probs = dynamic(0.2, 0.3, 0.4);
  long end = System.nanoTime();
  int total = 0;
  for (int i = 0; i < probs.length; i++) {
    System.out.printf("%d : %,.4f%n", i, probs[i]);
  }
  System.out.printf("%nDynamic ran for %d coinsin %,.3f ms%n%n",
      coins.length, (end - start) / 1000000d);
}

private static double[] dynamic(double... coins) {
  double[][] table = new double[coins.length + 2][];
  for (int i = 0; i < table.length; i++) {
    table[i] = new double[coins.length + 1];
  }
  table[1][coins.length] = 1.0d; // everything else is 0.0
  for (int i = 0; i <= coins.length; i++) {
    for (int j = coins.length - 1; j >= 0; j--) {
      table[i + 1][j] = coins[j] * table[i][j + 1] +
          (1 - coins[j]) * table[i + 1][j + 1];
    }
  }
  double[] ret = new double[coins.length + 1];
  for (int i = 0; i < ret.length; i++) {
    ret[i] = table[i + 1][0];
  }
  return ret;
}

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.

任性一次 2024-09-22 17:49:10

伪代码:

    procedure PROB(n,k,p)
/*
    input: n - number of coins flipped
           k - number of heads
           p - list of probabilities  for n-coins where p[i] is probability coin i will be heads
    output: probability k-heads in n-flips
    assumptions: 1 <= i <= n, i in [0,1], 0 <= k <= n, additions and multiplications of [0,1] numbers O(1)
*/

A = ()() //matrix
A[0][0] = 1 // probability no heads given no coins flipped = 100%

for i = 0  to  k                                                              //O(k)
    if  i != 0  then  A[i][i] = A[i-1][i-1] * p[i]
    for j = i + 1  to  n - k + i                                              //O( n - k + 1 - (i + 1)) = O(n - k) = O(n)
        if i != 0 then  A[i][j] = p[j] * A[i-1][j-1] + (1-p[j]) * A[i][j-1]
        otherwise       A[i][j] = (1 - p[j]) * A[i][j-1]
return A[k][n] //probability k-heads given n-flips

最坏情况 = O(kn)

Pseudocode:

    procedure PROB(n,k,p)
/*
    input: n - number of coins flipped
           k - number of heads
           p - list of probabilities  for n-coins where p[i] is probability coin i will be heads
    output: probability k-heads in n-flips
    assumptions: 1 <= i <= n, i in [0,1], 0 <= k <= n, additions and multiplications of [0,1] numbers O(1)
*/

A = ()() //matrix
A[0][0] = 1 // probability no heads given no coins flipped = 100%

for i = 0  to  k                                                              //O(k)
    if  i != 0  then  A[i][i] = A[i-1][i-1] * p[i]
    for j = i + 1  to  n - k + i                                              //O( n - k + 1 - (i + 1)) = O(n - k) = O(n)
        if i != 0 then  A[i][j] = p[j] * A[i-1][j-1] + (1-p[j]) * A[i][j-1]
        otherwise       A[i][j] = (1 - p[j]) * A[i][j-1]
return A[k][n] //probability k-heads given n-flips

Worst case = O(kn)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文