Example #1
0
        public static void calcProbility(double[] ee, double[] dd, int PLC_CNT, out double[] p1, out double[] p3)
        {
            int CNT = ee.Length;

            p1 = new double[CNT];
            p3 = new double[CNT];

            for (int i = 0; i < CNT; i++)
            {
                common.Math.Calculus.MultiFunc f_top_3 = new common.Math.Calculus.MultiFunc(delegate(double x)
                {
                    double gx = exp(-(x - ee[i]) * (x - ee[i]) / (2 * dd[i] * dd[i])) / (SQRT_2_PI * dd[i]);

                    double[] ret = new double[2];     // 前两个为WIN和PLC的概率

                    double[] V, T;

                    calcFx(CNT, PLC_CNT, i, x, ee, dd, out V, out T);

                    ret[0] = T[0];
                    ret[1] = T.Sum();

                    return(new common.Math.vector(ret) * gx);
                });

                common.Math.vector pv = common.Math.Calculus.integrate(f_top_3, ee[i] - dd[i] * 7, ee[i] + dd[i] * 7, Math.Pow(10, -PRECISION), 5);
                p1[i] = pv[0];
                p3[i] = pv[1];
            }
        }
Example #2
0
        public static void calcProbility(double[] ee, double[] dd, int PLC_CNT, out double[] p1, out double[] p3, out double[] pq_win, out double[] pq_plc)
        {
            int CNT = ee.Length;

            p1 = new double[CNT];
            p3 = new double[CNT];

            // 需要计算各种组合细节
            common.Math.Combination combq = new common.Math.Combination(CNT, 2);
            pq_win = new double[combq.Length];
            pq_plc = new double[combq.Length];

            common.Math.Combination comb_plc = new common.Math.Combination(CNT - 1, PLC_CNT - 1);
            int[][] _plc_combinations        = comb_plc.GetCombinations();
            common.Math.Combination comb2    = null;
            int[][] _2_combinations          = null;
            if (PLC_CNT > 3)
            {
                comb2           = new common.Math.Combination(PLC_CNT - 1, 2);
                _2_combinations = comb2.GetCombinations();
            }

            for (int i = 0; i < CNT; i++)
            {
                common.Math.Calculus.MultiFunc f_top_3 = new common.Math.Calculus.MultiFunc(delegate(double x)
                {
                    double gx = exp(-(x - ee[i]) * (x - ee[i]) / (2 * dd[i] * dd[i])) / (SQRT_2_PI * dd[i]);

                    double[] ret;     // 前两个为WIN和PLC的概率

                    if (PLC_CNT <= 3)
                    {
                        ret = new double[comb_plc.Length + 2];
                    }
                    else
                    {
                        // 如果PLC_CNT超过3,为了计算前两名的概率,还必须计算我第二名时,其他马第一名的概率
                        ret = new double[comb_plc.Length + CNT - 1 + 2];
                    }

                    double[] V, T;

                    calcFx(CNT, PLC_CNT, i, x, ee, dd, out V, out T);

                    ret[0] = T[0];
                    ret[1] = T.Sum();

                    // 计算我跑第三(PLC_CNT)时,前两(PLC_CNT-1)名各种组合的概率
                    double tmp  = 1; // 去掉不可能赢之后的概率连乘
                    int v0count = 0, // 我赢概率为0的数量,即肯定超过我的数量
                    v1count     = 0; // 不可能超过我的数量
                    for (int j = 0; j < CNT - 1; j++)
                    {
                        if (V[j] == 0)
                        {
                            v0count++;
                        }
                        else if (V[j] == 1)
                        {
                            v1count++;
                        }
                        else
                        {
                            tmp *= V[j];
                        }
                    }
                    // 肯定超过我的数量v0count大于PLC_CNT-1,我的名次肯定低于PLC_CNT,我跑第PLC_CNT的概率为0
                    // 不可能超过的数量v1count大于CNT-PLC_CNT,我的名次肯定高于PLC_CNT
                    if (v0count < PLC_CNT && v1count <= CNT - PLC_CNT)
                    {
                        for (int j = 0, j2 = 2; j < comb_plc.Length; j++, j2++)
                        {
                            int[] c      = _plc_combinations[j];
                            int cv0count = 0;
                            ret[j2]      = tmp;
                            for (int k = 0; k < PLC_CNT - 1; k++)
                            {
                                if (V[c[k]] == 0)
                                {
                                    cv0count++;
                                }
                                else if (V[c[k]] == 1)  // 我肯定赢的人在我前面,这个组合不可能存在
                                {
                                    ret[j2] = 0;
                                    break;
                                }
                                else
                                {
                                    ret[j2] /= V[c[k]];
                                    ret[j2] *= (1 - V[c[k]]);
                                }
                            }

                            if (cv0count < v0count)  // 如果组合中没有包含全部肯定赢我的人,这个组合不可能存在
                            {
                                ret[j2] = 0;
                            }
                        }
                    }
                    // 计算我第二名时各个人第一名的概率
                    if (PLC_CNT > 3 && v0count < 2 && v1count <= CNT - 2)
                    {
                        for (int j = 0, j2 = 2 + (int)comb_plc.Length; j < CNT - 1; j++, j2++)
                        {
                            if (v0count == 1)
                            {
                                if (V[j] == 0)
                                {
                                    ret[j2] = tmp;
                                }
                                else
                                {
                                    ret[j2] = 0;
                                }
                            }
                            else
                            {
                                if (V[j] == 1)
                                {
                                    ret[j2] = 0;
                                }
                                else
                                {
                                    ret[j2] = tmp / V[j] * (1 - V[j]);
                                }
                            }
                        }
                    }

                    return(new common.Math.vector(ret) * gx);
                });

                common.Math.vector pv = common.Math.Calculus.integrate(f_top_3, ee[i] - dd[i] * 7, ee[i] + dd[i] * 7, Math.Pow(10, -PRECISION), 5);
                p1[i] = pv[0];
                p3[i] = pv[1];

                if (PLC_CNT > 3)
                {
                    // PLC_CNT大于3,Q的概率需要通过我第二名时,其他各马第一名的概率计算

                    int[] c = new int[2];
                    c[0] = i;

                    // Q的概率
                    for (int j = 0, j2 = 2 + (int)comb_plc.Length; j < PLC_CNT - 1; j++, j2++)
                    {
                        for (int k = 0; k < PLC_CNT - 1; k++)
                        {
                            if (k < i)
                            {
                                c[1] = k;
                            }
                            else
                            {
                                c[1] = k + 1;
                            }

                            pq_win[combq.Index(c)] += pv[j2];
                        }
                    }

                    // QP的概率
                    for (int j = 0, j2 = 2; j < comb_plc.Length; j++, j2++)
                    {
                        // 和我的组合
                        c[0] = i;
                        for (int k = 0; k < PLC_CNT - 1; k++)
                        {
                            if (_plc_combinations[j][k] < i)
                            {
                                c[1] = _plc_combinations[j][k];
                            }
                            else
                            {
                                c[1] = _plc_combinations[j][k] + 1;
                            }

                            pq_plc[combq.Index(c)] += pv[j2];
                        }

                        // 没有我的组合
                        for (int k = 0; k < _2_combinations.Length; k++)
                        {
                            if (_plc_combinations[j][_2_combinations[k][0]] < i)
                            {
                                c[0] = _plc_combinations[j][_2_combinations[k][0]];
                            }
                            else
                            {
                                c[0] = _plc_combinations[j][_2_combinations[k][0]] + 1;
                            }

                            if (_plc_combinations[j][_2_combinations[k][1]] < i)
                            {
                                c[1] = _plc_combinations[j][_2_combinations[k][1]];
                            }
                            else
                            {
                                c[1] = _plc_combinations[j][_2_combinations[k][1]] + 1;
                            }

                            pq_plc[combq.Index(c)] += pv[j2];
                        }
                    }
                }
                else if (PLC_CNT == 3)
                {
                    // PLC_CNT等于3,Q的概率根据我第三名时,前两名的概率计算

                    int[] c = new int[2];

                    for (int j = 0, j2 = 2; j < comb_plc.Length; j++, j2++)
                    {
                        // 和我的组合
                        c[0] = i;
                        for (int k = 0; k < PLC_CNT - 1; k++)
                        {
                            if (_plc_combinations[j][k] < i)
                            {
                                c[1] = _plc_combinations[j][k];
                            }
                            else
                            {
                                c[1] = _plc_combinations[j][k] + 1;
                            }

                            pq_plc[combq.Index(c)] += pv[j2];
                        }

                        // 没有我的组合
                        if (_plc_combinations[j][0] < i)
                        {
                            c[0] = _plc_combinations[j][0];
                        }
                        else
                        {
                            c[0] = _plc_combinations[j][0] + 1;
                        }

                        if (_plc_combinations[j][1] < i)
                        {
                            c[1] = _plc_combinations[j][1];
                        }
                        else
                        {
                            c[1] = _plc_combinations[j][1] + 1;
                        }

                        pq_win[combq.Index(c)] += pv[j2];
                        pq_plc[combq.Index(c)] += pv[j2];
                    }
                }
                else if (PLC_CNT == 2)
                {
                    // PLC_CNT等于2,Q/QP是一样的

                    int[] c = new int[2];
                    c[0] = i;

                    for (int j = 0, j2 = 2; j < comb_plc.Length; j++, j2++)
                    {
                        // 只有和我的组合
                        if (_plc_combinations[j][0] < i)
                        {
                            c[1] = _plc_combinations[j][0];
                        }
                        else
                        {
                            c[1] = _plc_combinations[j][0] + 1;
                        }

                        pq_win[combq.Index(c)] += pv[j2];
                    }
                }
            }
        }
Example #3
0
        private static void calcProbilityForFitting(double[] ee, double[] dd, out double[] p1, out double[] pq)
        {
            int CNT = ee.Length;

            p1 = new double[CNT];

            common.Math.Combination combq = new common.Math.Combination(CNT, 2);
            pq = new double[combq.Length];

            for (int i = 0; i < CNT; i++)
            {
                common.Math.Calculus.MultiFunc f_top_3 = new common.Math.Calculus.MultiFunc(delegate(double x)
                {
                    double gx = exp(-(x - ee[i]) * (x - ee[i]) / (2 * dd[i] * dd[i])) / (SQRT_2_PI * dd[i]);

                    double[] ret = new double[CNT];     // 第一个为WIN的概率,后面CNT-1个是我第二名时第一名的是各匹马的概率

                    double[] V, T;

                    calcFx(CNT, 2, i, x, ee, dd, out V, out T);

                    ret[0] = T[0];

                    // 计算我跑第二时,第一名各马的概率
                    double tmp  = 1; // 去掉不可能赢之后的概率连乘
                    int v0count = 0, // 我赢概率为0的数量,即肯定超过我的数量
                    v1count     = 0; // 不可能超过我的数量
                    for (int j = 0; j < CNT - 1; j++)
                    {
                        if (V[j] == 0)
                        {
                            v0count++;
                        }
                        else if (V[j] == 1)
                        {
                            v1count++;
                        }
                        else
                        {
                            tmp *= V[j];
                        }
                    }
                    // 肯定超过我的数量v0count大于1,我的名次肯定低于2,我跑第2的概率为0
                    // 不可能超过的数量v1count大于CNT-2,我的名次肯定高于2
                    if (v0count <= 1 && v1count <= CNT - 2)
                    {
                        for (int j = 0, j2 = 1; j < CNT - 1; j++, j2++)
                        {
                            if (v0count == 1)
                            {
                                if (V[j] == 0)
                                {
                                    ret[j2] = tmp;
                                }
                                else
                                {
                                    ret[j2] = 0;
                                }
                            }
                            else
                            {
                                if (V[j] == 1)
                                {
                                    ret[j2] = 0;
                                }
                                else
                                {
                                    ret[j2] = tmp / V[j] * (1 - V[j]);
                                }
                            }
                        }
                    }

                    return(new common.Math.vector(ret) * gx);
                });

                common.Math.vector pv = common.Math.Calculus.integrate(f_top_3, ee[i] - dd[i] * 7, ee[i] + dd[i] * 7, Math.Pow(10, -PRECISION), 5);
                p1[i] = pv[0];

                int[] c = new int[2];
                c[0] = i;

                for (int j = 0, j2 = 1; j < CNT - 1; j++, j2++)
                {
                    // 只有和我的组合
                    if (j < i)
                    {
                        c[1] = j;
                    }
                    else
                    {
                        c[1] = j + 1;
                    }

                    pq[combq.Index(c)] += pv[j2];
                }
            }
        }
Example #4
0
        private void calc(double[] ee, double[] dd, out double[] p1, out double[] p3, out double[] p3detail)
        {
            p1 = new double[CNT];
            p3 = new double[CNT];
            common.Math.Combination comb3 = new common.Math.Combination(CNT, PLC_CNT);
            p3detail = new double[comb3.Length];

            common.Math.Combination comb2 = new common.Math.Combination(CNT - 1, PLC_CNT - 1);
            int[][] _2_combinations       = comb2.GetCombinations();

            for (int i = 0; i < CNT; i++)
            {
                common.Math.Calculus.Func r = new common.Math.Calculus.Func(delegate(double x)
                {
                    double ret = 1;
                    for (int j = 0; j < CNT; j++)
                    {
                        if (j == i)
                        {
                            continue;
                        }
                        ret += this.gauss(ee[j], dd[j], x);
                    }
                    return(ret);
                });

                // @deprecated f_top1没用了,在f_top3中计算了
                common.Math.Calculus.Func f_top1 = new common.Math.Calculus.Func(delegate(double x)
                {
                    double gx = this.exp(-(x - ee[i]) * (x - ee[i]) / (2 * dd[i] * dd[i])) / (SQRT_2_PI * dd[i]);
                    double rx = 1;
                    for (int j = 0; j < CNT; j++)
                    {
                        if (j == i)
                        {
                            continue;
                        }
                        rx *= 1 - this.gauss(ee[j], dd[j], x);
                    }
                    return(gx * rx);

                    // 这里应该是将我跑x的成绩时,赢每个人的概率连乘,转换为其中0个人赢我的泊松分布概率  2017-3-7
                    // 这样子不行的,比如假设A赢我概率0.5,B赢我概率0.5,没有人能赢我的概率是0.5*0.5 = 0.25
                    // 转换后,A赢我的期望0.5+B赢我的期望0.5=1,泊松分布概率P(0)=0.368,差蛮远
                    //double rv = Math.Exp(-r(x));

                    //return gx * rv;
                });

                common.Math.Calculus.MultiFunc f_top_3 = new common.Math.Calculus.MultiFunc(delegate(double x)
                {
                    double gx = this.exp(-(x - ee[i]) * (x - ee[i]) / (2 * dd[i] * dd[i])) / (SQRT_2_PI * dd[i]);

                    double[] ret = new double[comb2.Length + 2];     // 前两个为WIN和PLC的概率

                    // 选2 Tree最后的结果就是有两个人赢我的概率
                    // 选1 Tree最后的结果是有一个人赢我的概率
                    // LS最后结果是没人赢我的概率
                    //
                    //          不选A  - “选2 Tree”   V(A)*2T
                    //       /
                    //  root                              +                  不选B - “选1 Tree”
                    //       \                                            /
                    //          选A  -  “选1 Tree”  (1-V(A))*1T    ---
                    //                                                    \ 
                    //                                                       选B - 连乘
                    //2T(n-2) = (1-V(n-1)) * (1-V(n-2))
                    //2T(d) = V(d)*2T(d+1)+(1-V(d))*1T(d+1)
                    //1T(n-1) = (1-V(n-1))
                    //1T(d) = V(d)*1T(d+1)+(1-V(d))*LS(d+1)
                    //LS(n-1) = V(n-1)
                    //LS(d) = V(d)*LS(d+1)
                    // 目标计算2T(0)
                    //
                    // 扩展3T、4T、jT
                    // jT(n-j) = (1-V(n-1))*...*(1-V(n-j))
                    // jT(d) = V(d)*jT(d+1)+(1-V(d))*(j-1)T(d+1)

                    double[] V = new double[CNT - 1];   // 我赢i的概率
                    for (int j = 0; j < CNT; j++)
                    {
                        if (j < i)
                        {
                            V[j] = 1 - this.gauss(ee[j], dd[j], x);
                        }
                        else if (j > i)
                        {
                            V[j - 1] = 1 - this.gauss(ee[j], dd[j], x);
                        }
                        else // if (j == i)
                        {
                            continue;
                        }
                    }

                    int n      = CNT - 1;
                    double[] T = new double[PLC_CNT];
                    for (int j = 0; j < PLC_CNT; j++)
                    {
                        T[j] = 1;
                        for (int k = 1; k <= j; k++)
                        {
                            T[j] *= 1 - V[n - k];
                        }
                    }
                    for (int j = n - 1; j >= 0; j--)
                    {
                        for (int k = 0; k < PLC_CNT; k++)
                        {
                            if (k == 0)
                            {
                                T[k] *= V[j];
                            }
                            else if (j - k >= 0)
                            {
                                T[k] = V[j - k] * T[k] + (1 - V[j - k]) * T[k - 1];
                            }
                        }
                    }

                    ret[0] = T[0];
                    ret[1] = T.Sum();

                    // 计算我跑第三(PLC_CNT)时,前两(PLC_CNT-1)名各种组合的概率
                    double tmp      = 1;
                    int[] v0indices = new int[CNT - 1];
                    int v0count     = 0, // 我赢概率为0的数量,即肯定超过我的数量
                    v1count         = 0; // 不可能超过我的数量
                    for (int j = 0; j < CNT - 1; j++)
                    {
                        if (V[j] == 0)
                        {
                            v0indices[v0count++] = j;
                        }
                        else if (V[j] == 1)
                        {
                            v1count++;
                        }
                        else
                        {
                            tmp *= V[j];
                        }
                    }
                    // 肯定超过我的数量v0count大于PLC_CNT-1,我的名次肯定低于PLC_CNT,我跑第PLC_CNT的概率为0
                    // 不可能超过的数量v1count大于CNT-PLC_CNT,我的名次肯定高于PLC_CNT
                    if (v0count < PLC_CNT && v1count <= CNT - PLC_CNT)
                    {
                        for (int j = 0; j < comb2.Length; j++)
                        {
                            int[] c      = _2_combinations[j];
                            int cv0count = 0;
                            ret[j + 2]   = tmp;
                            for (int k = 0; k < PLC_CNT - 1; k++)
                            {
                                if (V[c[k]] == 0)
                                {
                                    cv0count++;
                                }
                                else if (V[c[k]] == 1)
                                {
                                    ret[j + 2] = 0;
                                    break;
                                }
                                else
                                {
                                    ret[j + 2] /= V[c[k]];
                                    ret[j + 2] *= (1 - V[c[k]]);
                                }
                            }

                            if (cv0count < v0count)
                            {
                                ret[j + 2] = 0;
                            }
                        }
                    }

                    return(new common.Math.vector(ret) * gx);
                });

                //p1[i] = common.Math.Calculus.integrate(f_top1, ee[i] - dd[i] * 8, ee[i] + dd[i] * 8, Math.Pow(10, -PRECISION), 5);
                //p3[i] = common.Math.Calculus.integrate(f_top3, ee[i] - dd[i] * 8, ee[i] + dd[i] * 8, Math.Pow(10, -PRECISION), 5);

                common.Math.vector pv = common.Math.Calculus.integrate(f_top_3, ee[i] - dd[i] * 7, ee[i] + dd[i] * 7, Math.Pow(10, -PRECISION), 5);
                p1[i] = pv[0];
                p3[i] = pv[1];

                for (int j = 0; j < comb2.Length; j++)
                {
                    int[] c = new int[PLC_CNT];
                    c[0] = i;
                    for (int k = 0; k < PLC_CNT - 1; k++)
                    {
                        if (_2_combinations[j][k] < i)
                        {
                            c[k + 1] = _2_combinations[j][k];
                        }
                        else
                        {
                            c[k + 1] = _2_combinations[j][k] + 1;
                        }
                    }

                    p3detail[comb3.Index(c)] += pv[j + 2];
                }
            }
        }