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));
     }
 }
Пример #5
0
 public static DissertationDbList getInstance()
 {
     if (instance == null)
     {
         instance = new DissertationDbList();
     }
     return(instance);
 }
        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;
                }
            }
        }