Пример #1
0
        private void IncludeValues_Checked(object sender, RoutedEventArgs e)
        {
            if (fuzzySystem == null)
            {
                return;
            }

            FuzzyBox.Text = fuzzySystem.ToString(true);
        }
Пример #2
0
        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;
        }
Пример #3
0
        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);
        }