如何使用蒙特卡罗方法搜索极限概率

时间:2016-11-27 15:23:48

标签: c# algorithm statistics montecarlo

我想了解如何使用蒙特卡罗方法搜索某个系统S的极限概率。

例如:

    S0  S1  S2  S3
S0  0.1 0.9 0   0
S1  0   0.2 0.3 0.5
S2  0.2 0.1 0.5 0.2
S3  0.5 0   0.4 0.1

据我所知,我们需要生成一些数字(x),然后比较概率:

if x 
   0   <= x < 0.1 => S0 -> S0
   0.1 <= x < 0.9 => S0 -> S1
   0.9 <= x < 0.9 => S0 -> S2
   0.9 <= x < 0.9 => S0 -> S3
   0.9 <= x < 1   => S0 -> S4 

当S4 - 限制(边界)

与其他州类似。

按照这种方法,我可以计算过渡次数:

  static double[] SimpleMonte(double[][] a, int iter = 1)
    {
        var n = a.GetLength(0);

        var p =
            a
            .Select(x => x.Select((_, i) => x.Take(i + 1).Sum()).ToArray())
            .ToArray();

        Random rand = new Random();

        double[] X = new double[n];
        for (int x = 0; x < n; x++)
        {
            double count = 0;
            for (int i = 0; i < iter; i++)
            {
                int row = x;
                bool notG = true;
                Console.Write("{0} -> ", row);
                while (notG)
                {

                    var e = rand.NextDouble();
                    Console.Write("({0})", Math.Round(e, 2));
                    bool ch = false;
                    for (int j = 0; j < n - 1; j++)
                    {
                        if (p[row][j] <= e && e < p[row][j + 1])
                        {
                            row = j + 1;
                            ch = true;
                            break;
                        }
                    }
                    if (!ch)
                        notG = false;
                    else
                    {
                        Console.Write("{0} -> ", row);
                        count++;
                    }
                }
                Console.WriteLine();
            }
            X[x] = count / iter;
        }
        return X;
    }

https://dotnetfiddle.net/nJF5sm

我很高兴听到如何解决这个问题的提示。

1 个答案:

答案 0 :(得分:1)

在实际意义上,找到像这样的系统的极限的最好方法是重复矩阵的矩阵直到条目收敛。这是有效的,因为它是一个随机矩阵(每行的总和等于1)。当我尝试它时,我得到了答案:

S0        S1        S2        S3
0.1939252 0.2593458 0.3294393 0.2172897

,它给出了您将处于特定状态的平均概率。

要使用蒙特卡罗方法,您应该像您一样生成随机数并保持转换计数。那么你处于特定状态的平均概率是

(Amount of Transitions to State S)/(Total Transitions)

因为您的总转化次数足够大。

在您提供的代码中,如果您继续增加iter变量的大小(并且确实需要相对较大),则输出的最后四行应收敛到上面的数字。我希望有所帮助。

在原始代码中出现了一个错误,导致无法转换到初始状态。这是正确的版本:

static double[] SimpleMonte(double[][] a, int iter = 10000)
    {
        var n = a.GetLength(0);

        var p =
            a
            .Select(x => x.Select((_, i) => x.Take(i + 1).Sum()).ToArray())
            .ToArray();

        Random rand = new Random();
        double[] X = new double[n];
        int row = rand.Next(n);
        for (int i = 0; i < iter; i++)
        {
            var e = rand.NextDouble();
            X[row]++;
            if (e < p[row][0])
                row = 0;
            else
                for (int j = 0; j < n - 1; j++)
                {
                    if (p[row][j] <= e && e < p[row][j + 1])
                    {
                        row = j + 1;
                        break;
                    }
                }

        }
        return X.Select(x => x / iter).ToArray();
    }