/// <summary> /// Объединение результатов функций и правил /// </summary> /// <param name="ruleWeights">Весовые правила (Результат вычислений)</param> /// <param name="functionResults">Результат вычисления функций</param> /// <returns>Результат вычислений</returns> public Dictionary <SugenoVariable, double> CombineResult(Dictionary <SugenoFuzzyRule, double> ruleWeights, Dictionary <SugenoVariable, Dictionary <ISugenoFunction, double> > functionResults) { Dictionary <SugenoVariable, double> numerators = new Dictionary <SugenoVariable, double>(); Dictionary <SugenoVariable, double> denominators = new Dictionary <SugenoVariable, double>(); Dictionary <SugenoVariable, double> results = new Dictionary <SugenoVariable, double>(); // // Вычисление числителя и знаменателя для каждого входа // foreach (SugenoVariable var in Output) { numerators.Add(var, 0.0); denominators.Add(var, 0.0); } foreach (SugenoFuzzyRule rule in ruleWeights.Keys) { SugenoVariable var = rule.Conclusion.Var; double z = functionResults[var][rule.Conclusion.Term]; double w = ruleWeights[rule]; numerators[var] += z * w; denominators[var] += w; } // // Расчет фракций // foreach (SugenoVariable var in Output) { if (denominators[var] == 0.0) { results[var] = 0.0; } else { results[var] = numerators[var] / denominators[var]; } } return(results); }
/// <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())); // Парсим правило } }