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]; } }
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]; } } } }
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]; } } }
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]; } } }