/// <summary> /// Получает коэффициент нечеткой переменной /// </summary> /// <param name="var">нечеткая переменная</param> /// <returns>Значение коэффициента</returns> public double GetCoefficient(FuzzyVariable var) { if (var == null) { return(_constValue); } else { return(_coeffs[var]); } }
/// <summary> /// Установить коэффициент нечеткой переменной /// </summary> /// <param name="var">Нечеткая переменная</param> /// <param name="coeff">Новое значение коэффициента</param> public void SetCoefficient(FuzzyVariable var, double coeff) { if (var == null) { _constValue = coeff; } else { _coeffs[var] = coeff; } }
/// <summary> /// Создается единственное состояние /// </summary> /// <param name="var">Лингвистическая переменная к которой привязано условие</param> /// <param name="term">Терм в выражении "Переменная есть терм"</param> /// <param name="not">Содержит ли состояние отрицание</param> /// <param name="type">Модификатор</param> /// <returns>Созданное состояние</returns> public FuzzyCondition CreateCondition(FuzzyVariable var, FuzzyTerm term, bool not, HedgeType type) { return(new FuzzyCondition(var, term, not, type)); }
/// <summary> /// Создается единственное состояние /// </summary> /// <param name="var">Лингвистическая переменная к которой привязано условие</param> /// <param name="term">Терм в выражении "Переменная есть терм"</param> /// <param name="not">Содержит ли состояние отрицание</param> /// <returns>Созданное состояние</returns> public FuzzyCondition CreateCondition(FuzzyVariable var, FuzzyTerm term, bool not) { return(new FuzzyCondition(var, term, not)); }
/// <summary> /// Генерация базы правил на основе субстратной кластеризации /// </summary> private void Genfis() { // // Подготовка данных для кластеризации // int len = xin.Length + 1; // + 1, т.к. входные данне double[][] x = new double[len][]; // Создаем массив данных for (int i = 0; i < x.Length - 1; i++) // Перебираем массивы { x[i] = xin[i]; } x[x.Length - 1] = xout; // // Кластеризация данных // SubtractClustesing subclust = new SubtractClustesing(x, Radii, SqshFactor, AcceptRatio, RejectRatio); subclust.SubClust(); double[][] centers = subclust.Centers; // Центы кластеров double[] sigmas = subclust.Sigmas; // Радиусы кластеров // // Ращипление центров кластеров // // Формирование центров кластеров double[][] centersIn = new double[centers.Length - 1][]; double[] centersOut = centers[centers.Length - 1]; for (int i = 0; i < centersIn.Length; i++) { centersIn[i] = centers[i]; } // Формирование радиусов кластера double[] sigmaIn = new double[sigmas.Length - 1]; for (int i = 0; i < sigmaIn.Length; i++) { sigmaIn[i] = sigmas[i]; } double sigmaOut = sigmas[sigmas.Length - 1]; // // Формируем входные переменные // for (int i = 0; i < centersIn.Length; i++) { // Создаем переменную double min, max; MinMax(xin[i], out max, out min); FuzzyVariable input = new FuzzyVariable(NameInput + (i + 1).ToString(), min, max); // Формируем термы / функции принадлежности for (int j = 0; j < centersIn[i].Length; j++) { input.Terms.Add( new FuzzyTerm( NameMf + (j + 1).ToString(), new NormalMembershipFunction(centersIn[i][j], sigmaIn[i]) ) ); } // Заносим переменную в список Input.Add(input); } // // Формирование выходных переменных // SugenoVariable output = new SugenoVariable(NameOutput); for (int i = 0; i < centersOut.Length; i++) { Dictionary <FuzzyVariable, double> mf = new Dictionary <FuzzyVariable, double>(); for (int j = 0; j < centersIn.Length; j++) // Перебираем входные переменные { mf.Add(InputByName(NameInput + (j + 1).ToString()), 0.0); // По умолчанию 0,0 } // Константа тоже по умолчанию 0.0 output.Functions.Add(CreateSugenoFunction(NameMf + (i + 1).ToString(), mf, 0.0)); } Output.Add(output); // // Формировние базы правил типа // if (input1 is mf1) and (input2 is mf1) then (output1 is mf1) // rulesText = new string[centersOut.Length]; // Текстовое представление правил for (int i = 0; i < centersOut.Length; i++) { StringBuilder sb = new StringBuilder(); sb.Append("if"); for (int j = 0; j < centersIn.Length; j++) { sb.Append(string.Format(" ({0} is {1}) ", NameInput + (j + 1).ToString(), NameMf + (i + 1).ToString())); if (j != centersIn.Length - 1) { sb.Append("and"); } } sb.Append("then"); sb.Append(string.Format(" ({0} is {1})", NameOutput, NameMf + (i + 1).ToString())); rulesText[i] = sb.ToString(); Rules.Add(ParseRule(sb.ToString())); // Парсим правило } }
/// <summary> /// Обучение Fis /// </summary> /// <param name="anfisTrain">Функция обучения</param> public void Train(anfisTrain anfisTrain = null) { // // Генерация Fis // Genfis(); // // Обучение Fis // int epoch = 1; double epochError; if (Rules.Count == 0) { throw new Exception("Должно быть хотя бы одно правило."); } int k = xout.Length; // Количество параметров обучающей выборки int l = (xin.Length + 1) * Rules.Count; // (m+1)n - m - количество входных переменных n - количество правил Matrix C = new Matrix(l, 1); // Столбец весовых коэффициентов Matrix Y = new Matrix(k, 1); // Вектор столбец выходных данных for (int i = 0; i < k; i++) { Y[i, 0] = xout[i]; } errorTrain = new double[Epochs]; while (epoch <= Epochs) { epochError = 0.0; // Ошибка на i эпохе // // Формирование матрицы коэффициентов // Matrix W = new Matrix(k, l); Matrix ew = new Matrix(k, Rules.Count); for (int i = 0; i < k; i++) { Dictionary <FuzzyVariable, double> inputValues = new Dictionary <FuzzyVariable, double>(); // По количеству переменных for (int j = 0; j < xin.Length; j++) { inputValues.Add(InputByName(NameInput + (j + 1).ToString()), xin[j][i]); } // Посылки правил Dictionary <FuzzyVariable, Dictionary <FuzzyTerm, double> > fuzzyInput = Fuzzify(inputValues); // Агрегирование подусловий Dictionary <SugenoFuzzyRule, double> rulesWeight = EvaluateConditions(fuzzyInput); // Заключение правил double Stau = 0.0; List <double> tau = new List <double>(); foreach (double _tau in rulesWeight.Values) { Stau += _tau; tau.Add(_tau); } double[] b = new double[tau.Count]; for (int j = 0; j < b.Length; j++) { b[j] = tau[j] / Stau; ew[i, j] = tau[j]; } // Формирование входных переменных double[] x = new double[xin.Length + 1]; // +1, т.к. x0 = 1 x[0] = 1; // x0 = 1 for (int j = 1; j < x.Length; j++) { x[j] = xin[j - 1][i]; // заполняем x1, x2,...,x3 } int columnW = 0; for (int g = 0; g < b.Length; g++) // перебираем по заключениям { for (int d = 0; d < x.Length; d++) // перебираем по входным данным { W[i, columnW] = b[g] * x[d]; // переменожаем коэффициенты на переменные columnW++; // увеличиваем строку на 1 } } } Matrix Winverse = W.PInverse(); // W+ псевдоинверстная матрица // // Если псевдоинверстная матрица не найдена // bool breakTrain = false; for (int i = 0; i < Winverse.N; i++) { for (int j = 0; j < Winverse.M; j++) { if (double.IsNaN(Winverse[i, j])) { breakTrain = true; break; } } if (breakTrain) { break; } } if (breakTrain) { break; // Прерываем обучение } C = Winverse * Y; // Находим коэффициенты // // Нахождение вектора фактического выхода сети // Matrix Ystrich = W * C; // // Правим коэффициенты // for (int i = 0; i < Input.Count; i++) { FuzzyVariable fv = Input[i]; // Забираем переменную for (int j = 0; j < fv.Terms.Count; j++) { FuzzyTerm term = fv.Terms[j]; // Выбираем j терм i входной переменной // // Меняем в случае если функция принадлежности колоколообразная // IMembershipFunction mf = term.MembershipFunction; if (mf is NormalMembershipFunction) { NormalMembershipFunction mfterm = (NormalMembershipFunction)mf; // Приводим тип // // Перебираем все переменные k - количество выходных параметров // for (int g = 0; g < k; g++) { double b = mfterm.B; double sigma = mfterm.Sigma; double xa = xin[i][g] - b; // xin - b double yyStrih = Ystrich[g, 0] - xout[g]; // y' - y double p = ew[g, j]; double sp = 0.0; for (int q = 0; q < Rules.Count; q++) { sp += ew[g, q]; } double pb = p / (sp / Math.Pow(sigma, 2)); // (t/summt) / sigma^2 // // Инициализируем матрицы для нахождения c // Matrix x = new Matrix(1, xin.Length + 1); Matrix c = new Matrix(xin.Length + 1, 1); x[0, 0] = 1; //x0 = 1 for (int q = 1; q < x.M; q++) { x[0, q] = xin[q - 1][g]; } // Заполняем коэффициенты int start = j * x.M; for (int q = start; q < start + x.M; q++) { c[q - start, 0] = C[q, 0]; } // Перемножаем матрици double cy = ((x * c)[0] - Ystrich[g, 0]); // // Корректируем B // b -= 2 * Nu * xa * yyStrih * cy * pb; // // Корректируем Sigma // sigma -= 2 * Nu * Math.Pow(xa, 2) * yyStrih * cy * pb; // // Условия переобучения и недопустимости применения условий // if (double.IsNaN(mfterm.Sigma) || double.IsNaN(mfterm.B)) { continue; // Идем на следующую итерацию } else { mfterm.B = b; mfterm.Sigma = sigma; } } // // Загоняем терм обратно // fv.Terms[j].MembershipFunction = mfterm; } // // TODO: Настройка остальных функций принадлежности не реализовано // } Input[i] = fv; // Загоняем переменную обратно } // // Находим ошибку выхода // epochError = 0.0; for (int i = 0; i < Ystrich.N; i++) { epochError += 0.5 * Math.Pow(Ystrich[i, 0] - xout[i], 2); } errorTrain[epoch - 1] = epochError; anfisTrain?.Invoke(epoch, Epochs, nu, epochError); Nu *= NuStep; epoch++; } // Конец эпох обучения // // Применяем параметры коэффициентов y = c0 + c1 * x1 + c2 * x2 + ... + ci * xi // SetCoefficient(C); // // Перезаписываем правила в силу архитектуры сети // Rules.Clear(); for (int i = 0; i < rulesText.Length; i++) { Rules.Add(ParseRule(rulesText[i])); } Console.WriteLine(Rules[0].ToString()); }
public string PremierLeague(double x1, double x2, double x3, double x4, double x5) { // // Create empty fuzzy system // MamdaniFuzzySystem fsGols = new MamdaniFuzzySystem(); // // Create input variables for the system // FuzzyVariable fvGamer = new FuzzyVariable("gamerLosses", -6.0, 6.0); fvGamer.Terms.Add(new FuzzyTerm("x1_BS", new NormalMembershipFunction(-6, 2.55))); fvGamer.Terms.Add(new FuzzyTerm("x1_OS", new NormalMembershipFunction(0, 2.55))); fvGamer.Terms.Add(new FuzzyTerm("x1_KS", new NormalMembershipFunction(6, 2.55))); fsGols.Input.Add(fvGamer); FuzzyVariable fvGameDinamics = new FuzzyVariable("gameDinamics", -15.0, 15.0); fvGameDinamics.Terms.Add(new FuzzyTerm("x2_SP", new NormalMembershipFunction(-15, 4.25))); fvGameDinamics.Terms.Add(new FuzzyTerm("x2_P", new NormalMembershipFunction(-5, 4.25))); fvGameDinamics.Terms.Add(new FuzzyTerm("x2_V", new NormalMembershipFunction(5, 4.25))); fvGameDinamics.Terms.Add(new FuzzyTerm("x2_SV", new NormalMembershipFunction(15, 4.25))); fsGols.Input.Add(fvGameDinamics); FuzzyVariable fvClassDifferences = new FuzzyVariable("classDifferences", -19.0, 19.0); fvClassDifferences.Terms.Add(new FuzzyTerm("x3_L", new NormalMembershipFunction(-19, 2.76))); fvClassDifferences.Terms.Add(new FuzzyTerm("x3_VP", new NormalMembershipFunction(-9.5, 2.76))); fvClassDifferences.Terms.Add(new FuzzyTerm("x3_S", new NormalMembershipFunction(0, 2.76))); fvClassDifferences.Terms.Add(new FuzzyTerm("x3_NP", new NormalMembershipFunction(9.5, 2.76))); fvClassDifferences.Terms.Add(new FuzzyTerm("x3_A", new NormalMembershipFunction(-19, 2.76))); fsGols.Input.Add(fvClassDifferences); FuzzyVariable fvFieldFactor = new FuzzyVariable("fieldFactor", -2.0, 3.0); fvFieldFactor.Terms.Add(new FuzzyTerm("x4_ANd", new NormalMembershipFunction(-2, 0.7))); fvFieldFactor.Terms.Add(new FuzzyTerm("x4_Nd", new NormalMembershipFunction(-0.33, 0.7))); fvFieldFactor.Terms.Add(new FuzzyTerm("x4_Pr", new NormalMembershipFunction(1.33, 0.7))); fvFieldFactor.Terms.Add(new FuzzyTerm("x4_APr", new NormalMembershipFunction(3, 0.7))); fsGols.Input.Add(fvFieldFactor); FuzzyVariable fvCommandMatches = new FuzzyVariable("commandMatches", -60.0, 60.0); fvCommandMatches.Terms.Add(new FuzzyTerm("x5_Pz", new NormalMembershipFunction(-60.0, 8.5))); fvCommandMatches.Terms.Add(new FuzzyTerm("x5_R", new NormalMembershipFunction(0, 8.5))); fvCommandMatches.Terms.Add(new FuzzyTerm("x5_Rz", new NormalMembershipFunction(60.0, 8.5))); fsGols.Input.Add(fvCommandMatches); // // Create output variables for the system // FuzzyVariable fvGols = new FuzzyVariable("gols", -3.0, 3.0); fvGols.Terms.Add(new FuzzyTerm("y_KP", new NormalMembershipFunction(-3.0, 0.64))); fvGols.Terms.Add(new FuzzyTerm("y_P", new NormalMembershipFunction(-0.9, 0.44))); fvGols.Terms.Add(new FuzzyTerm("y_N", new NormalMembershipFunction(0, 0.44))); fvGols.Terms.Add(new FuzzyTerm("y_V", new NormalMembershipFunction(0.9, 0.44))); fvGols.Terms.Add(new FuzzyTerm("y_KV", new NormalMembershipFunction(3.0, 0.64))); fsGols.Output.Add(fvGols); // // Create three fuzzy rules // MamdaniFuzzyRule rule11 = fsGols.ParseRule("if ((gamerLosses is x1_BS ) and (gameDinamics is x2_SV ) " + "and (classDifferences is x3_L) and (fieldFactor is x4_APr) and (commandMatches is x5_Rz)) " + "then gols is y_KV"); MamdaniFuzzyRule rule12 = fsGols.ParseRule("if ((gamerLosses is x1_OS) and (gameDinamics is x2_V)" + " and (classDifferences is x3_VP) and (fieldFactor is x4_Pr) and (commandMatches is x5_Rz)) " + "then gols is y_KV"); MamdaniFuzzyRule rule13 = fsGols.ParseRule("if ((gamerLosses is x1_OS) and (gameDinamics is x2_P)" + " and (classDifferences is x3_L) and (fieldFactor is x4_Pr) and (commandMatches is x5_Rz)) " + "then gols is y_KV"); MamdaniFuzzyRule rule14 = fsGols.ParseRule("if ((gamerLosses is x1_BS) and (gameDinamics is x2_V) " + "and (classDifferences is x3_VP) and (fieldFactor is x4_Pr) and (commandMatches is x5_R)) " + "then gols is y_KV"); MamdaniFuzzyRule rule2 = fsGols.ParseRule("if ((gamerLosses is x1_OS ) and (gameDinamics is x2_V ) " + "and (classDifferences is x3_S) and (fieldFactor is x4_Nd) and (commandMatches is x5_Rz)) or " + "((gamerLosses is x1_KS) and (gameDinamics is x2_P) and (classDifferences is x3_VP)" + "and(fieldFactor is x4_Pr) and (commandMatches is x5_R)) or ((gamerLosses is x1_OS) and " + "(gameDinamics is x2_V) and (classDifferences is x3_S) and (fieldFactor is x4_Nd) " + "and (commandMatches is x5_Rz)) or ((gamerLosses is x1_BS) and(gameDinamics is x2_SV) " + "and (classDifferences is x3_NP) and (fieldFactor is x4_Pr) and (commandMatches is x5_R)) " + "then gols is y_V"); MamdaniFuzzyRule rule3 = fsGols.ParseRule("if ((gamerLosses is x1_OS ) and (gameDinamics is x2_V ) " + "and (classDifferences is x3_S) and (fieldFactor is x4_Nd) and (commandMatches is x5_R)) or " + "((gamerLosses is x1_KS) and (gameDinamics is x2_SP) and (classDifferences is x3_S)" + "and(fieldFactor is x4_Nd) and (commandMatches is x5_R)) or ((gamerLosses is x1_OS) and " + "(gameDinamics is x2_P) and (classDifferences is x3_NP) and (fieldFactor is x4_Pr) " + "and (commandMatches is x5_Pz)) or ((gamerLosses is x1_BS) and(gameDinamics is x2_SP) " + "and (classDifferences is x3_VP) and (fieldFactor is x4_Nd) and (commandMatches is x5_R)) " + "then gols is y_N"); MamdaniFuzzyRule rule4 = fsGols.ParseRule("if ((gamerLosses is x1_BS ) and (gameDinamics is x2_P ) " + "and (classDifferences is x3_S) and (fieldFactor is x4_ANd) and (commandMatches is x5_R)) or " + "((gamerLosses is x1_OS) and (gameDinamics is x2_V) and (classDifferences is x3_NP)" + "and(fieldFactor is x4_Nd) and (commandMatches is x5_Pz)) or ((gamerLosses is x1_KS) and " + "(gameDinamics is x2_SP) and (classDifferences is x3_S) and (fieldFactor is x4_Pr) " + "and (commandMatches is x5_Pz)) or ((gamerLosses is x1_OS) and(gameDinamics is x2_P) " + "and (classDifferences is x3_A) and (fieldFactor is x4_Nd) and (commandMatches is x5_R)) " + "then gols is y_P"); MamdaniFuzzyRule rule5 = fsGols.ParseRule("if ((gamerLosses is x1_KS ) and (gameDinamics is x2_SP ) " + "and (classDifferences is x3_A) and (fieldFactor is x4_ANd) and (commandMatches is x5_R)) or " + "((gamerLosses is x1_OS) and (gameDinamics is x2_SP) and (classDifferences is x3_NP)" + "and(fieldFactor is x4_Nd) and (commandMatches is x5_Pz)) or ((gamerLosses is x1_KS) and " + "(gameDinamics is x2_P) and (classDifferences is x3_NP) and (fieldFactor is x4_ANd) " + "and (commandMatches is x5_R)) or ((gamerLosses is x1_BS) and(gameDinamics is x2_SP) " + "and (classDifferences is x3_NP) and (fieldFactor is x4_Nd) and (commandMatches is x5_Pz)) " + "then gols is y_KP"); fsGols.Rules.Add(rule11); fsGols.Rules.Add(rule12); fsGols.Rules.Add(rule13); fsGols.Rules.Add(rule14); fsGols.Rules.Add(rule2); fsGols.Rules.Add(rule3); fsGols.Rules.Add(rule4); // // Associate input values with input variables // Dictionary <FuzzyVariable, double> inputValues = new Dictionary <FuzzyVariable, double>(); inputValues.Add(fvGamer, x1); inputValues.Add(fvGameDinamics, x2); inputValues.Add(fvClassDifferences, x3); inputValues.Add(fvFieldFactor, x4); inputValues.Add(fvCommandMatches, x5); // // Calculate result: one output value for each output variable // Dictionary <FuzzyVariable, double> result = fsGols.Calculate(inputValues); // // Get output value for the 'tips' variable // Console.WriteLine(result[fvGols].ToString("f1")); return(result[fvGols].ToString("f1")); }