/// <summary> /// 解析因子在记录中的连续次数 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="numbers">记录</param> /// <param name="factors"></param> /// <param name="predictiveFactor">反因子</param> /// <param name="numbersTailCutCount"></param> /// <param name="allowMinTimes">允许的最小连续数,大于等于此数才记录</param> /// <returns></returns> public static PermutationFactorTrendConsecutiveDetails <T> CountConsecutive <T>(IReadOnlyList <T> numbers, List <List <T> > factors, List <T> predictiveFactor, int numbersTailCutCount = 1, int allowMinTimes = 1) { var curResult = new PermutationFactorTrendConsecutiveDetails <T> { Factors = factors, PredictiveFactor = predictiveFactor, HistoricalConsecutiveTimes = new SortedDictionary <int, int>() }; var i = 0; //连续次数 var times = 0; //统计记录的长度 var length = numbers.Count - numbersTailCutCount; //遍历所有记录 while (i < length) { /* * 排列因子:{1,2}{3,4} * 号码索引位置:1 2 3 4 5 6 7 8 9 10 11 12 13 * 号码: 6 1 3 5 2 3 2 4 1 0 0 1 1 * 0 1 2 0 1 2 1 2 1 0 0 1 1 * (1命中第一个因子,2命中第二个因子,只有同时命中1、2才能算一次,并且索引位置跳到下一位置,比如索引位置2,3,同时命中1,2,连续次数递增1) * */ var n = 0; for (; n < factors.Count && n + i < length; n++) { if (!factors[n].Exists(m => m.Equals(numbers[n + i]))) { break; } } //排列因子全部相等 if (n >= factors.Count) { //连续次数递增 times++; //索引位置调整,指向下一索引位置的前一条记录 i = i + factors.Count - 1; } else { //是否有相同的连续次数,有则递增,否则新增一条连续次数记录 if (curResult.HistoricalConsecutiveTimes.ContainsKey(times)) { curResult.HistoricalConsecutiveTimes[times]++; } else if (times >= allowMinTimes) { curResult.HistoricalConsecutiveTimes.Add(times, 1); } //连续次数清零,下一次重新统计 times = 0; } i++; } //是否有相同的连续次数,有则递增,否则新增一条连续次数记录 if (curResult.HistoricalConsecutiveTimes.ContainsKey(times)) { curResult.HistoricalConsecutiveTimes[times]++; } else if (times >= allowMinTimes) { curResult.HistoricalConsecutiveTimes.Add(times, 1); } return(curResult); }
/// <summary> /// 分析因子的历史正确率分布等,(通过号码集合分析历史趋势) /// </summary> /// <param name="numbers">号码集合</param> /// <param name="trendResult">统计结果</param> /// <param name="endIndex">分析记录的最后索引位置</param> /// <param name="predictiveFactor">可能的因子</param> /// <returns></returns> public List <FactorTrendCorrectRate> GetCorrectRates <T>(List <T> numbers, PermutationFactorTrendConsecutiveDetails <T> trendResult, int endIndex, List <T> predictiveFactor) { var trends = new List <FactorTrendCorrectRate>(); if (endIndex <= 0) { throw new Exception("分析历史趋势时,分析记录数量不能小于等于0!"); } if (numbers == null || numbers.Count == 0) { throw new Exception("分析历史趋势时,记录不能为空!"); } var numberCount = numbers.Count; if (numberCount < endIndex) { throw new Exception("分析历史趋势时,分析记录数量不能大于记录数量!"); } var minConsecutiveTimes = trendResult.FactorDistributions.Where(n => n.ConsecutiveTimes != 0).Min(n => n.ConsecutiveTimes); var maxConsecutiveTimes = trendResult.FactorDistributions.Where(n => n.ConsecutiveTimes != 0).Max(n => n.ConsecutiveTimes); var minInterval = trendResult.FactorDistributions.Where(n => n.MaxConsecutiveTimesInterval != DisConsecutiveFlag).Min(n => n.MaxConsecutiveTimesInterval); var maxInterval = trendResult.FactorDistributions.Where(n => n.MaxConsecutiveTimesInterval != DisConsecutiveFlag).Max(n => n.MaxConsecutiveTimesInterval); //允许的连续次数,由小到大 for (var consecutiveTimes = minConsecutiveTimes; consecutiveTimes <= maxConsecutiveTimes; consecutiveTimes++) { //允许的间隔数,由大到小 for (var interval = maxInterval; interval >= minInterval; interval--) { var resultCount = 0; var successCount = 0; var trend = new FactorTrendCorrectRate { AllowConsecutiveTimes = consecutiveTimes, AllowInterval = interval, AnalyseNumberCount = endIndex }; trends.Add(trend); //行明细结果集 var distributions = trendResult.FactorDistributions; for (var i = numberCount - 1; i >= endIndex; i--) { var number = numbers[i]; //上一索引位置的分析结果,10个号码,分析第10位(索引位置9),取第9位(索引位置8) var distribution = distributions.FirstOrDefault(d => d.Index == i - 1);// distributions[i - 1]; if (distribution == null) { continue; } //对结果再分析 //1、按允许的最小因子当前连续次数和允许的最大间隔次数筛选 //2、先按最大连续次数然后按最小间隔次数排序 ////历史最大连续次数 //var historicalMaxConsecutiveTimes = curIndexResult.ConsecutiveTimes + interval; if (distribution.ConsecutiveTimes == consecutiveTimes && distribution.MaxConsecutiveTimesInterval == interval) { resultCount++; if (predictiveFactor.Contains(number)) { successCount++; } } } trend.AnalyticalCount = resultCount; trend.CorrectCount = successCount; trend.CorrectRate = trend.AnalyticalCount == 0 ? 0 : (double)trend.CorrectCount / trend.AnalyticalCount; } } return(trends); }