private void IncludeValues_Checked(object sender, RoutedEventArgs e) { if (fuzzySystem == null) { return; } FuzzyBox.Text = fuzzySystem.ToString(true); }
private async void OptimizeButton_Click(object sender, RoutedEventArgs e) { /*if (fuzzySystem.Type == FuzzyType.Sugeno && CheckOutput.IsChecked == true) * { * MessageBox.Show("Output optimization is not valid for Sugeno-type fuzzy systems.", "Warning", MessageBoxButton.OK, MessageBoxImage.Warning); * return; * }*/ // Disable the optimize button and the optimization parameters OptimizeButton.IsEnabled = false; UseButton.IsEnabled = false; RadioBaseRatio.IsEnabled = false; RadioRefPoint.IsEnabled = false; CheckInput.IsEnabled = false; CheckOutput.IsEnabled = false; // Initialize variables ArrayList initParams = new ArrayList(); ArrayList lbp = new ArrayList(); ArrayList ubp = new ArrayList(); // Set up initial parameters if (CheckInput.IsChecked == true) { foreach (InputOutput input in fuzzySystem.Inputs) { foreach (MembershipFunction MF in input.MFs) { if (RadioRefPoint.IsChecked == true) { initParams.Add((double)(MF.GetReferencePoint())); lbp.Add((double)(input.Range[0])); ubp.Add((double)(input.Range[1])); } if (RadioBaseRatio.IsChecked == true) { initParams.Add((double)(MF.GetTrapBaseRatio())); lbp.Add(0.0); ubp.Add(0.95); } } } } if (CheckOutput.IsChecked == true) { foreach (InputOutput output in fuzzySystem.Outputs) { foreach (MembershipFunction MF in output.MFs) { if (RadioRefPoint.IsChecked == true) { initParams.Add((double)(MF.GetReferencePoint())); lbp.Add((double)(output.Range[0])); ubp.Add((double)(output.Range[1])); } if (RadioBaseRatio.IsChecked == true) { initParams.Add((double)(MF.GetTrapBaseRatio())); lbp.Add(0.0); ubp.Add(0.95); } } } } bool[] ints = new bool[initParams.Count]; // Set up the optimizer object depending on the settings switch (MethodId) { case 0: //Firework Optimizer = new Firework { // Number of particles in the swarm. NumberOfElements = NA, m = m, ymax = double.MaxValue, a = a, b = b, Amax = Amax, mhat = mhat, Slow = false }; break; case 1: //Particle Swarm Optimizer = new ParticleSwarm { // Number of particles in the swarm. NumberOfElements = NA, c0 = c0, // Multiplication factor for the distance to the personal best position. cp = cp, // Multiplication factor for the distance to the global best position. cg = cg, Slow = false }; break; case 2: //Clonal generation if (cgn > NA) { MessageBox.Show("Number of antibodies selected for cloning at the end of each generation greater than the number of antibodies.", "ERROR", MessageBoxButton.OK); OptimizeButton.IsEnabled = true; return; } Optimizer = new ClonalGeneration { // Size of the antibody pool. NumberOfElements = NA, // Number of antibodies selected for cloning. NumberSelectedForCloning = cgn, // Parameter determining the number of clones created for an antibody that was selected for cloning. (0,1] Beta = beta, // Number of antibodies created with random parameters in each new generation. RandomAntibodiesPerGeneration = d, // Mutation coefficient (0,1]. Ro = ro, Slow = false }; break; case 3: Optimizer = new GeneticAlgorithm { // Size of the individual pool. NumberOfElements = NA, // Number of parents in each generation. ParentsInEachGeneration = P, // The probability of mutation. MutationProbability = pm, // The number of crossovers in each generation. CrossoverPerGeneration = crossoverCount, Slow = false }; break; case 4: //Clonal generation if (cgn > NA) { MessageBox.Show("Number of antibodies selected for cloning at the end of each generation greater than the number of antibodies.", "ERROR", MessageBoxButton.OK); OptimizeButton.IsEnabled = true; return; } Optimizer = new ClonalGenerationLocal { // Size of the antibody pool. NumberOfElements = NA, // Number of antibodies selected for cloning. NumberSelectedForCloning = cgn, // Parameter determining the number of clones created for an antibody that was selected for cloning. (0,1] Beta = beta, // Number of antibodies created with random parameters in each new generation. RandomAntibodiesPerGeneration = d, // Mutation coefficient (0,1]. Ro = ro, // Local searches per generation LocalSearchesPerGeneration = cgln, Slow = false }; break; } // Set common parameters Optimizer.InitialParameters = initParams; Optimizer.LowerParamBounds = lbp; Optimizer.UpperParamBounds = ubp; // Bounds are required before setting this value if (MethodId == 4) { ((ClonalGenerationLocal)Optimizer).StepSizeRelative = cglssr; } Optimizer.Integer = ints; Optimizer.FitnessFunction = FitnessFunctionMSE; Optimizer.StoppingNumberOfGenerations = StopGenerationNumber; Optimizer.StoppingNumberOfEvaluations = StopAffinityEvaluation; Optimizer.StoppingFitnessTreshold = StopFitnessTreshold; Optimizer.StoppingType = StopType; // Output string string outstr = "Initial parameters: " + List(initParams) + "\r\n"; // Open progress window and begin the optimization ProgressWindow = new OptimizationProgressWindow(); ProgressWindow.OptWindow = this; ProgressWindow.Show(); if (IoputMfWindows != null) { foreach (MFsPreviewWindow window in IoputMfWindows) { window.Close(); } } IoputMfWindows = new List <MFsPreviewWindow>(); foreach (InputOutput input in fuzzySystem.Inputs) { IoputMfWindows.Add(new MFsPreviewWindow(input)); IoputMfWindows[IoputMfWindows.Count - 1].Show(); } foreach (InputOutput output in fuzzySystem.Outputs) { IoputMfWindows.Add(new MFsPreviewWindow(output)); IoputMfWindows[IoputMfWindows.Count - 1].Show(); } Optimizer.GenerationCreated += OnNewGeneration; // <DELAYER> /*var z = Task.Run(() => (delayer())); * int y = await z;*/ // </DELAYER> var x = Task.Run(() => (Optimizer.Optimize())); var Results = await x; ProgressWindow.Close(); // Add results to output string outstr += "Initial MSE: " + Results.InfoList[InfoTypes.InitialFitness] + "\r\n" + "Final parameters: " + List(Results.OptimizedParameters) + "\r\n" + "Final MSE: " + $"{Results.InfoList[InfoTypes.FinalFitness],10:F6}" + "\r\n" + "Number of generations: " + Results.InfoList[InfoTypes.Generations] + "\r\n" + "Number of fitness evaluations: " + Results.InfoList[InfoTypes.Evaluations] + "\r\n" + "Best affinities in each generation: " + List((ArrayList)Results.InfoList[InfoTypes.Affinities]) + "\r\n" + "Optimization time in milliseconds: " + Results.InfoList[InfoTypes.ExecutionTime]; fuzzySystem = GetModifiedFuzzySystem(Results.OptimizedParameters); FuzzyBox.Text = fuzzySystem.ToString(); // Display results and reenable the optimize button MessageBox.Show(outstr, "Optimization finished", MessageBoxButton.OK); OptimizeButton.IsEnabled = true; UseButton.IsEnabled = true; RadioBaseRatio.IsEnabled = true; RadioRefPoint.IsEnabled = true; CheckInput.IsEnabled = true; CheckOutput.IsEnabled = true; }
private void GenerateButton_Click(object sender, RoutedEventArgs e) { InitializeFuzzySystem(); // Make sure the selected values are compatible { bool invalid = true; if (fuzzySystem.Type == FuzzyType.Mamdani || fuzzySystem.Type == FuzzyType.Larsen) { if (fuzzySystem.DefuzzMethod == DefuzzMethodType.COA || fuzzySystem.DefuzzMethod == DefuzzMethodType.COG || fuzzySystem.DefuzzMethod == DefuzzMethodType.MOM || fuzzySystem.DefuzzMethod == DefuzzMethodType.LOM || fuzzySystem.DefuzzMethod == DefuzzMethodType.SOM) { if (fuzzySystem.ImpMethod == ImpMethodType.min || fuzzySystem.ImpMethod == ImpMethodType.max) { invalid = false; } } } if (fuzzySystem.Type == FuzzyType.Sugeno) { if (fuzzySystem.DefuzzMethod == DefuzzMethodType.wtaver || fuzzySystem.DefuzzMethod == DefuzzMethodType.wtsum) { if (fuzzySystem.ImpMethod == ImpMethodType.prod) { invalid = false; } } } if (invalid) { MessageBox.Show("Incompatible fuzzy system type and defuzzification method.", "ERROR", MessageBoxButton.OK, MessageBoxImage.Error); return; } } var watch = System.Diagnostics.Stopwatch.StartNew(); List <Rule> rules = new List <Rule>(); // Generate the rules if (fuzzySystem.Type == FuzzyType.Sugeno) { // Get a list of inputMF-combinations int ruleCount = 1; for (int inputId = 0; inputId < fuzzySystem.Inputs.Length; inputId++) { ruleCount *= fuzzySystem.Inputs[inputId].NumMFs; } for (int i = 0; i < ruleCount; i++) { rules.Add(new Rule()); rules[rules.Count - 1].Inputs = new int[fuzzySystem.Inputs.Length]; rules[rules.Count - 1].Inputs[0] = -1; // Uninitialized rule indicator rules[rules.Count - 1].Outputs = new int[fuzzySystem.Outputs.Length]; rules[rules.Count - 1].Outputs[0] = i + 1; } // Prepare outputs fuzzySystem.Outputs[0].NumMFs = ruleCount; for (int mfId = 0; mfId < fuzzySystem.Outputs[0].NumMFs; mfId++) { fuzzySystem.Outputs[0].MFs[mfId] = new MembershipFunction(); fuzzySystem.Outputs[0].MFs[mfId].Type = MFtype.constant; } Random RNG = new Random(); for (int ruleId = 0; ruleId < rules.Count; ruleId++) { bool newRuleFound = true; do { for (int i = 0; i < rules[ruleId].Inputs.Length; i++) { rules[ruleId].Inputs[i] = RNG.Next(fuzzySystem.Inputs[i].NumMFs) + 1; } newRuleFound = true; for (int r = 0; r < ruleId; r++) { if (rules[r].SameInput(rules[ruleId])) { newRuleFound = false; } } }while (!newRuleFound); // For each input combination we calculate their weights at each of the given coordinates List <int> itrValues = new List <int>(); List <float> weights = new List <float>(); for (int itr = 0; itr < InputCoords[0].Count; itr++) { float weight = 1.0f; for (int inputId = 0; inputId < fuzzySystem.NumInputs; inputId++) { weight = Math.Min(weight, fuzzySystem.Inputs[inputId].MFs[rules[ruleId].Inputs[inputId] - 1].GetMembershipValue(InputCoords[inputId][itr])); } // If both weights are >0, we store these weigths (or their min/avg) and the itr value for this combination if (weight > 0.0f) { weights.Add(weight); itrValues.Add(itr); } } // We get the weighed average of the outputs for each combination // Add a new MF to the output with this value, and set the rule to it float result = 0.0f; for (int i = 0; i < weights.Count; i++) { result += weights[i] * OutputCoords[0][itrValues[i]]; } result /= weights.Sum(); fuzzySystem.Outputs[0].MFs[ruleId].Params[0] = result; } // Remove invalid rules/outputs (NaN output -> no matching input-output values were found) // Make new lists of the valid entries List <Rule> validRules = new List <Rule>(); List <MembershipFunction> validOutputMFs = new List <MembershipFunction>(); for (int i = 0; i < ruleCount; i++) { if (!float.IsNaN(fuzzySystem.Outputs[0].MFs[i].Params[0])) { validRules.Add(rules[i]); validRules[validRules.Count - 1].Outputs[0] = validRules.Count; validOutputMFs.Add(fuzzySystem.Outputs[0].MFs[i]); } } // Overwrite original arrays with the new ones rules = validRules; fuzzySystem.Outputs[0].NumMFs = validOutputMFs.Count; fuzzySystem.Outputs[0].MFs = validOutputMFs.ToArray(); } else if (fuzzySystem.Type == FuzzyType.Mamdani || fuzzySystem.Type == FuzzyType.Larsen) { // for each input-output data we have (rows in the txt) for (int itr = 0; itr < InputCoords[0].Count; itr++) { // Get the value of each input's MFs at the specified points List <List <float> > MFvalues = new List <List <float> >(); //MFvalues[input id][MF id] // Add a list foreach ioput for (int i = 0; i < fuzzySystem.NumInputs + fuzzySystem.NumOutputs; i++) { MFvalues.Add(new List <float>()); } // for each input for (int inputId = 0; inputId < InputCoords.Count; inputId++) { // for each MF for (int mfID = 0; mfID < fuzzySystem.Inputs[inputId].NumMFs; mfID++) { // Get the membership value at the given coordinate MFvalues[inputId].Add(fuzzySystem.Inputs[inputId].MFs[mfID].GetMembershipValue(InputCoords[inputId][itr])); } } // for each output for (int outputId = 0; outputId < OutputCoords.Count; outputId++) { // for each MF for (int mfID = 0; mfID < fuzzySystem.Outputs[outputId].NumMFs; mfID++) { // Get the membership value at the given coordinate MFvalues[fuzzySystem.NumInputs + outputId].Add(fuzzySystem.Outputs[outputId].MFs[mfID].GetMembershipValue(OutputCoords[outputId][itr])); } } // Check if we have a NaN bool hasNaN = false; foreach (List <float> MFlist in MFvalues) { foreach (float f in MFlist) { if (float.IsNaN(f)) { hasNaN = true; } } } if (hasNaN) { continue; } // Get each input's MF where the membership was the highest (randomly chosen if equal) int[] highestMF = new int[fuzzySystem.NumInputs + fuzzySystem.NumOutputs]; for (int k = 0; k < fuzzySystem.NumInputs; k++) { // Find highest membership value float highestVal = MFvalues[k][0]; for (int l = 1; l < fuzzySystem.Inputs[k].NumMFs; l++) { highestVal = Math.Max(MFvalues[k][l], highestVal); } // Find MFs that have the highest membership value we just found List <int> MFsWithHighestVal = new List <int>(); for (int l = 0; l < fuzzySystem.Inputs[k].NumMFs; l++) { if (MFvalues[k][l] == highestVal) { MFsWithHighestVal.Add(l); } } // Choose a random one of them highestMF[k] = MFsWithHighestVal[(new Random()).Next(MFsWithHighestVal.Count)]; } // Get each output's highest MF index for (int k = 0; k < fuzzySystem.NumOutputs; k++) { // Find highest membership value float highestVal = MFvalues[fuzzySystem.NumInputs + k][0]; for (int l = 1; l < fuzzySystem.Outputs[k].NumMFs; l++) { highestVal = Math.Max(MFvalues[fuzzySystem.NumInputs + k][l], highestVal); } // Find MFs that have the highest membership value we just found List <int> MFsWithHighestVal = new List <int>(); for (int l = 0; l < fuzzySystem.Outputs[0].NumMFs; l++) { if (MFvalues[fuzzySystem.NumInputs + k][l] == highestVal) { MFsWithHighestVal.Add(l); } } // Choose a random one of them highestMF[fuzzySystem.NumInputs + k] = MFsWithHighestVal[(new Random()).Next(MFsWithHighestVal.Count)]; } // Create rule Rule newRule = new Rule() { ConnectionType = 1, Inputs = new int[fuzzySystem.NumInputs], Outputs = new int[fuzzySystem.NumOutputs], Weight = 1.0f }; for (int i = 0; i < fuzzySystem.NumInputs; i++) { newRule.Inputs[i] = highestMF[i] + 1; } for (int i = 0; i < fuzzySystem.NumOutputs; i++) { newRule.Outputs[i] = highestMF[fuzzySystem.NumInputs + i] + 1; } // Add to rule list if the inputs don't match any existing rule bool isRuleNew = true; foreach (Rule rule in rules) { if (rule.SameInput(newRule)) { isRuleNew = false; break; } } if (isRuleNew) { rules.Add(newRule); } } } foreach (Rule rule in rules) { rule.ConnectionType = 1; rule.Weight = 1.0f; } fuzzySystem.Rules = rules.ToArray(); watch.Stop(); GeneratedFuzzyBox.Text = fuzzySystem.ToString(IncludeValuesCheckBox.IsChecked == true); SaveButton.IsEnabled = true; OptimizeButton.IsEnabled = true; UseButton.IsEnabled = true; float MSE; try { fuzzySystem.LoadInputsAndSaveOutputs(InputFileTextBox.Text, OutputFileTextBox.Text.Replace(".txt", ".generated.txt")); MSE = FuzzySystem.GetOutputFilesMSE(OutputFileTextBox.Text, OutputFileTextBox.Text.Replace(".txt", ".generated.txt")); } catch (Exception exc) { MessageBox.Show(exc.Message, "Error", MessageBoxButton.OK); return; } MessageBox.Show("MSE: " + MSE.ToString(CultureInfo.InvariantCulture) + "\r\nRMSE: " + Math.Sqrt(MSE).ToString(CultureInfo.InvariantCulture) + "\r\nRMSEP: " + (Math.Sqrt(MSE) / (fuzzySystem.Outputs[0].Range[1] - fuzzySystem.Outputs[0].Range[0]) * 100.0f).ToString(CultureInfo.InvariantCulture) + "%\r\nGeneration time in milliseconds: " + watch.ElapsedMilliseconds, "Generation successful!", MessageBoxButton.OK); }