public static void GenerateSituationsByEntropy(int seriesId) { var _context = DissertationDbList.getInstance(); { var needForecast = _context.SeriesDescriptions.SingleOrDefault(sd => sd.Id == seriesId).NeedForecast; var labels = EntropyByFT.Entropyes; var trends = (needForecast) ? EntropyByUX.Entropyes4Forecast : EntropyByUX.EntropyesNot4Forecast; int counter = 0; for (int i = 0; i < labels.Count; ++i) { for (int j = 0; j < trends.Count; ++j) { for (int t = 0; t < labels.Count; ++t) { for (int r = 0; r < trends.Count; ++r) { _context.StatisticsByEntropys.Add(new StatisticsByEntropy { NumberSituation = counter++, SeriesDiscriptionId = seriesId, StartStateLingvistUX = trends[j], StartStateLingvistFT = labels[i], EndStateLingvistUX = trends[r], EndStateLingvistFT = labels[t], CountMeet = 0 }); } } } } } }
public static void GenerateSituationsByFuzzy(int seriesId) { var _context = DissertationDbList.getInstance(); { var labels = _context.FuzzyLabels.Where(fl => fl.SeriesDiscriptionId == seriesId).ToList(); var trends = _context.FuzzyTrends.Where(ft => ft.SeriesDiscriptionId == seriesId).ToList(); int counter = 0; for (int i = 0; i < labels.Count; ++i) { for (int j = 0; j < trends.Count; ++j) { for (int t = 0; t < labels.Count; ++t) { for (int r = 0; r < trends.Count; ++r) { _context.StatisticsByFuzzys.Add(new StatisticsByFuzzy { NumberSituation = counter++, SeriesDiscriptionId = seriesId, StartStateFuzzyLabelId = labels[i].Id, StartStateFuzzyTrendId = trends[j].Id, EndStateFuzzyLabelId = labels[t].Id, EndStateFuzzyTrendId = trends[r].Id, CountMeet = 0 }); } } } } } }
/// <summary> /// Вычисляется точка по значении меры энтропии по нечеткой тенденции и точке фазовой плоскости по предыдущей тенденции (для прогнозирования) /// </summary> /// <param name="fft">значение меры энтропии</param> /// <param name="point">точка фазовой плоскости по предыдущей тенденции</param> /// <returns></returns> public static int CalcPointFromFFT(double fft, int point, int seriesId) { var _context = DissertationDbList.getInstance(); { var points = _context.PointTrends.Where(x => x.SeriesDiscriptionId == seriesId && x.StartPoint == point).ToList(); if (points != null && points.Count > 0) { var p = points.FirstOrDefault(x => x.Weight == fft); if (p != null) { return(p.FinishPoint); } if (fft == 0) { p = points.FirstOrDefault(x => x.Weight == 0.5); if (p != null) { return(p.FinishPoint); } p = points.FirstOrDefault(x => x.Weight == 1); if (p != null) { return(p.FinishPoint); } } else if (fft == 1) { p = points.FirstOrDefault(x => x.Weight == 0.5); if (p != null) { return(p.FinishPoint); } p = points.FirstOrDefault(x => x.Weight == 0); if (p != null) { return(p.FinishPoint); } } else if (fft == 0.5) { p = points.FirstOrDefault(x => x.Weight == 1); if (p != null) { return(p.FinishPoint); } p = points.FirstOrDefault(x => x.Weight == 0); if (p != null) { return(p.FinishPoint); } } throw new Exception(string.Format("CalcPointFromFFT({0}): Не нашли для точки {1} точку по весу {2}", seriesId, point, fft)); } else { throw new Exception(string.Format("CalcPointFromFFT({0}): Не найдены точки тенденция для ряда", seriesId)); } } }
public static string GetEndState(this StatisticsByFuzzyViewModel model) { var _context = DissertationDbList.getInstance(); { return(string.Format("{0} - {1}", _context.FuzzyLabels.SingleOrDefault(fl => fl.Id == model.EndStateFuzzyLabelId).FuzzyLabelName, _context.FuzzyTrends.SingleOrDefault(ft => ft.Id == model.EndStateFuzzyTrendId).TrendName)); } }
public static string GetDescription(this AnomalyInfo ai) { var _context = DissertationDbList.getInstance(); { var sb = new StringBuilder(); sb.AppendLine("Ситуации:"); var situations = ai.SetSituations.Split(','); BaseClassStatisticBy statistic = null; foreach (var sit in situations) { int number = Convert.ToInt32(sit); switch (ai.TypeSituation) { case TypeSituation.ПоНечеткости: statistic = _context.StatisticsByFuzzys //.Include(stf => stf.EndStateFuzzyLabel) //.Include(stf => stf.EndStateFuzzyTrend) //.Include(stf => stf.StartStateFuzzyLabel) //.Include(stf => stf.StartStateFuzzyTrend) .FirstOrDefault(stf => stf.NumberSituation == number && stf.SeriesDiscriptionId == ai.SeriesDiscriptionId); break; case TypeSituation.ПоЭнтропии: statistic = _context.StatisticsByEntropys.FirstOrDefault(ste => ste.NumberSituation == number && ste.SeriesDiscriptionId == ai.SeriesDiscriptionId); break; } sb.AppendLine(string.Format("{0} -> {1}", statistic.StartState, statistic.EndState)); } sb.AppendLine("Аномалия:"); switch (ai.TypeSituation) { case TypeSituation.ПоНечеткости: statistic = _context.StatisticsByFuzzys //.Include(stf => stf.EndStateFuzzyLabel) //.Include(stf => stf.EndStateFuzzyTrend) //.Include(stf => stf.StartStateFuzzyLabel) //.Include(stf => stf.StartStateFuzzyTrend) .FirstOrDefault(stf => stf.NumberSituation == ai.AnomalySituation && stf.SeriesDiscriptionId == ai.SeriesDiscriptionId); break; case TypeSituation.ПоЭнтропии: statistic = _context.StatisticsByEntropys.FirstOrDefault(stf => stf.NumberSituation == ai.AnomalySituation && stf.SeriesDiscriptionId == ai.SeriesDiscriptionId); break; } sb.AppendLine(string.Format("{0} -> {1}", statistic.StartState, statistic.EndState)); return(sb.ToString()); } }
/// <summary> /// Генерация нечетких тенденций /// </summary> /// <param name="seriesId"></param> public static void GenerateFuzzyTrends(int seriesId) { var _context = DissertationDbList.getInstance(); { foreach (FuzzyTrendLabel elem in Enum.GetValues(typeof(FuzzyTrendLabel))) { _context.FuzzyTrends.Add(ModelConvector.ToFuzzyTrend(new FuzzyTrendBindingModel { SeriesId = seriesId, TrendName = elem, Weight = Converter.ToFuzzyTrendLabelWeight(elem) })); } } }
/// <summary> /// Вычисление значения энтропии по нечеткой тенденции /// </summary> /// <param name="point"></param> /// <returns></returns> public static double CalcEntropyByFT(FuzzyTrendLabel lastPointFTN, FuzzyTrendLabel beforeLastPointFTN, FuzzyTrendLabel beforeBeforeLastPointFTN, int seriesId, out int pointNext) { var xNow = Converter.ToFuzzyTrendLabelWeight(lastPointFTN); if (xNow == Converter.TrendWeightNotFound) { throw new Exception(string.Format("Не найден вес для тенденции {0}", lastPointFTN)); } var xLast = Converter.ToFuzzyTrendLabelWeight(beforeLastPointFTN); if (xLast == Converter.TrendWeightNotFound) { throw new Exception(string.Format("Не найден вес для тенденции {0}", beforeLastPointFTN)); } var xLastLast = Converter.ToFuzzyTrendLabelWeight(beforeBeforeLastPointFTN); if (xLastLast == Converter.TrendWeightNotFound) { throw new Exception(string.Format("Не найден вес для тенденции {0}", beforeBeforeLastPointFTN)); } // точка на фазовой полскости для предыдущей точки ряда var beforePoint = CalcPointOnPhasePlane(beforeLastPointFTN, xLastLast - xLast); // точка на фазовой плоскости для текущей точки ряда var nextPoint = CalcPointOnPhasePlane(lastPointFTN, xLast - xNow); pointNext = nextPoint; // получаем энтропию var _context = DissertationDbList.getInstance(); { var point = _context.PointTrends.FirstOrDefault(rec => rec.StartPoint == beforePoint && rec.FinishPoint == nextPoint && rec.SeriesDiscriptionId == seriesId); if (point == null) { return(1); } else { point.Count++; return(1.0 - point.Weight); } } }
/// <summary> /// Вычисление значения функции принадлежности и определение нечеткой метки, к которой принадлежит точка /// </summary> public static PointInfo CalcFUX(PointInfo point, int?seriesId = null) { if (!seriesId.HasValue && point.SeriesDiscriptionId > 0) { seriesId = point.SeriesDiscriptionId; } if ((point.DiagnosticTest == null || point.DiagnosticTest.SeriesDiscriptionId == 0) && !seriesId.HasValue) { throw new Exception("Невозможно получить нечеткие метки"); } var _context = DissertationDbList.getInstance(); { // индекс нечеткой метки, к которой будет принадлежать точка var fuzzyLabels = (seriesId.HasValue) ? _context.FuzzyLabels.Where(fl => fl.SeriesDiscriptionId == seriesId.Value).ToList() : _context.FuzzyLabels.Where(fl => fl.SeriesDiscriptionId == point.DiagnosticTest.SeriesDiscriptionId).ToList(); var needForecast = _context.SeriesDescriptions.SingleOrDefault(sd => sd.Id == seriesId.Value)?.NeedForecast ?? false; switch (fuzzyLabels.First().FuzzyLabelType) { case FuzzyLabelType.FuzzyTriangle: //фаззификация // вычисляем функцию принадлежности к первой нечетой метке point.F*x = CalcNu(point.Value.Value, fuzzyLabels.First().FuzzyLabelMinVal, fuzzyLabels.First().FuzzyLabelCenter, fuzzyLabels.First().FuzzyLabelMaxVal); point.FuzzyLabel = fuzzyLabels.First(); point.FuzzyLabelId = fuzzyLabels.First().Id; // идем по остальным нечетким меткам foreach (var fuzzyLabel in fuzzyLabels) { if (point.F*x < CalcNu(point.Value.Value, fuzzyLabel.FuzzyLabelMinVal, fuzzyLabel.FuzzyLabelCenter, fuzzyLabel.FuzzyLabelMaxVal)) { point.FuzzyLabel = fuzzyLabel; point.FuzzyLabelId = fuzzyLabel.Id; point.F*x = CalcNu(point.Value.Value, fuzzyLabel.FuzzyLabelMinVal, fuzzyLabel.FuzzyLabelCenter, fuzzyLabel.FuzzyLabelMaxVal); } } break; case FuzzyLabelType.ClustFCM: double max = -1; foreach (var fuzzyLabel in fuzzyLabels) { double top = CalcDistanse(point.Value.Value, fuzzyLabel.FuzzyLabelCenter); if (top < 1.0) { top = Math.Pow(10, -5); } double sum = 0.0; foreach (var tempFuzzyLabel in fuzzyLabels) { double distance = CalcDistanse(point.Value.Value, tempFuzzyLabel.FuzzyLabelCenter); if (distance < 1.0) { distance = Math.Pow(10, -5); } sum += Math.Pow(top / distance, 2.0); } if (max < 1.0 / sum) { max = 1.0 / sum; point.FuzzyLabel = fuzzyLabel; point.FuzzyLabelId = fuzzyLabel.Id; point.F*x = CalcNu(point.Value.Value, fuzzyLabel.FuzzyLabelMinVal, fuzzyLabel.FuzzyLabelCenter, fuzzyLabel.FuzzyLabelMaxVal); } } break; } if (point.FuzzyLabel == null) { return(null); } if (needForecast) { // если значение функции энтропии меньше значения центра, то точка лежит левее центра if (point.Value.Value < point.FuzzyLabel.FuzzyLabelCenter) { point.PositionFUX = false; } // иначе - правее центра (центр не рассматриваем, нет нужды) else { point.PositionFUX = true; } } return(point); } }
/// <summary> /// Настройка весов для созданныых точек /// </summary> /// <param name="seriesId"></param> /// <returns></returns> private static bool SetWeightForPoint(int seriesId) { var _context = DissertationDbList.getInstance(); { try { var groupPoints = _context.PointTrends.Where(pt => pt.SeriesDiscriptionId == seriesId).GroupBy(pt => pt.StartPoint).ToList(); foreach (var groupPoint in groupPoints) { var points = groupPoint.OrderByDescending(pt => pt.Count).ToList(); List <int> deltas = new List <int>(); if (points.Count == 0) { } else if (points.Count == 1) { points[0].Weight = 1; continue; } else if (points.Count == 2) { var delta = Math.Abs(points[0].Count - points[1].Count); if (delta < 5) { points[0].Weight = 0.5; points[1].Weight = 0.5; } else { points[0].Weight = 1; points[1].Weight = 0.5; } } else if (points.Count == 3) { var delta1 = Math.Abs(points[0].Count - points[1].Count); var delta2 = Math.Abs(points[1].Count - points[2].Count); if (delta1 < delta2) { points[0].Weight = 0.5; points[1].Weight = 0.5; } else { points[0].Weight = 1; points[1].Weight = 0.5; points[2].Weight = 0.5; } } else { points[0].Weight = 1; for (int i = 1; i < points.Count; ++i) { points[i].Weight = 0.5; } } } return(true); } catch (Exception) { throw; } } }
/// <summary> /// Обработка новой точки /// </summary> /// <param name="point"></param> /// <param name="seriesId"></param> /// <returns></returns> private static bool AddNewPoint(PointInfo point, int seriesId) { var _context = DissertationDbList.getInstance(); { try { if (_points.Count > 0) {//если уже есть точки, получить тенденцию point = ModelCalculator.CalcFUX(point, seriesId); var fuzzyLabelId = _points[_points.Count - 1].FuzzyLabelId; var rule = _context.RuleTrends.SingleOrDefault(r => r.FuzzyLabelFromId == fuzzyLabelId && r.FuzzyLabelToId == point.FuzzyLabelId); if (rule == null) { throw new Exception(string.Format("Нет правила для такого сочитания нечетких меток: {0} и {1}", _points[_points.Count - 1].FuzzyLabel.FuzzyLabelName, point.FuzzyLabel.FuzzyLabelName)); } point.FuzzyTrendId = rule.FuzzyTrendId; point.FuzzyTrend = _context.FuzzyTrends.Single(ft => ft.Id == rule.FuzzyTrendId); if (_points.Count > 2) {//если есть возможность, получить энтропию по тенденции var xNow = Converter.ToFuzzyTrendLabelWeight(point.FuzzyTrend.TrendName); if (xNow == Converter.TrendWeightNotFound) { throw new Exception(string.Format("Не найден вес для тенденции {0}", point.FuzzyTrend.TrendName)); } var xLast = Converter.ToFuzzyTrendLabelWeight(_points[_points.Count - 1].FuzzyTrend.TrendName); if (xLast == Converter.TrendWeightNotFound) { throw new Exception(string.Format("Не найден вес для тенденции {0}", _points[_points.Count - 1].FuzzyTrend.TrendName)); } var xLastLast = Converter.ToFuzzyTrendLabelWeight(_points[_points.Count - 2].FuzzyTrend.TrendName); if (xLastLast == Converter.TrendWeightNotFound) { throw new Exception(string.Format("Не найден вес для тенденции {0}", _points[_points.Count - 2].FuzzyTrend.TrendName)); } // скорость преращения тенденции в предыдущей точке var speedTrendLast = xLastLast - xLast; // скорость преращения тенденции в ткущей точке var speedTrend = xLast - xNow; int beforePoint = ModelCalculator.CalcPointOnPhasePlane(_points[_points.Count - 1].FuzzyTrend.TrendName, speedTrendLast); int nextPoint = ModelCalculator.CalcPointOnPhasePlane(point.FuzzyTrend.TrendName, speedTrend); var pointTrend = _context.PointTrends.FirstOrDefault(p => p.StartPoint == beforePoint && p.FinishPoint == nextPoint && p.SeriesDiscriptionId == seriesId); if (pointTrend == null) { pointTrend = new PointTrend { StartPoint = beforePoint, FinishPoint = nextPoint, Count = 1, Weight = 0, SeriesDiscriptionId = seriesId, Trends = point.FuzzyTrend.TrendName.ToString() }; _context.PointTrends.Add(pointTrend); } else { if (!pointTrend.Trends.Contains(point.FuzzyTrend.TrendName.ToString())) { pointTrend.Trends += string.Format(", {0}", point.FuzzyTrend.TrendName); } pointTrend.Count++; } } } else { point = ModelCalculator.CalcFUX(point, seriesId); } if (_points.Count == 5) { _points.RemoveAt(0); } _points.Add(point);//занести точку return(true); } catch (Exception) { throw; } } }