/// <summary> /// Adds a LinguisticValue object to the Values collection property /// </summary> /// <param name="a_name">Name of the linguistic value</param> /// <param name="a_fs">Fuzzy set of the linguitic value</param> public void AddValue(string a_name, FuzzySet a_fs) { Values.Add(new LinguisticValue(a_name, a_fs)); double lastMinValue = minValue; double lastMaxValue = maxValue; ComputeMinMax(); if (minValue > lastMinValue) { minValue = lastMinValue; } if (maxValue < lastMaxValue) { maxValue = lastMaxValue; } }
public double Solve() { FuzzySet result = new FuzzySet(); result.AddPoint(output.MinValue, 0); result.AddPoint(output.MaxValue, 0); foreach (var rule in Rules) { FuzzySet resultingFuzzySet = rule.Apply(Problem); if (resultingFuzzySet != null) { result = result | resultingFuzzySet; } } return(result.Barycenter); }
/// <summary> /// Computes an intersection point /// </summary> /// <param name="a">First FuzzySet a</param> /// <param name="b">First FuzzySet b</param> static protected void AddIntersectionToResult(FuzzySet a, FuzzySet b) { // Calcul des coordonnées des points double x = (x1 == x2 ? oldPt1.X : Math.Min(x1, x2)); double xPrime = Math.Max(x1, x2); // Calcul de l'intersection double slope1 = 0; double slope2 = 0; double delta = 0; if ((xPrime - x) != 0) { slope1 = (a.DegreeAtValue(xPrime) - a.DegreeAtValue(x)) / (xPrime - x); slope2 = (b.DegreeAtValue(xPrime) - b.DegreeAtValue(x)) / (xPrime - x); } if (slope1 != slope2) { delta = (b.DegreeAtValue(x) - a.DegreeAtValue(x)) / (slope1 - slope2); } // Ajout du point result.AddPoint(x + delta, a.DegreeAtValue(x + delta)); }
/// <summary> /// Generic method for fuzzy operators AND and OR to merge 2 fuzzy sets /// </summary> /// <param name="a">First FuzzySet object a</param> /// <param name="b">First FuzzySet object b</param> /// <param name="a_mergeFunction">Computation method corresponding to the required fuzzy operator</param> /// <returns>Computed merged FuzzySet corresponding to a & B or to a | b</returns> static protected FuzzySet Merge(FuzzySet a, FuzzySet b, Func <double, double, double> a_mergeFunction) { // Initialisation de l'ensemble flou à calculer //double minNewFuzzySet = Math.Min(a.Min, b.Min); //double maxNewFuzzySet = Math.Max(a.Max, b.Max); result = new FuzzySet(); // Initialisation des Iterators pour le parcours en parallèle de chacun des points des ensembles flous enum1 = a.Points.GetEnumerator(); enum2 = b.Points.GetEnumerator(); enum1.MoveNext(); enum2.MoveNext(); oldPt1 = enum1.Current; // Initialisation des positions relatives relativePosition = 0; newRelativePosition = Math.Sign(enum1.Current.Y - enum2.Current.Y); // Parcours en parallèle des points des ensembles flous jusqu'à ce que l'on arrive à la fin d'un des 2 ensembles flous // Plusieurs cas de figure se présentent : // 1 - L'abscisse X du point de l'ensemble flou a est égal à l'abscisse X du point de l'ensemble flou b => on ajoute le point // 2 - L'abscisse X du point de l'ensemble flou a est avant l'abscisse X du point de l'ensemble flou b => on ajoute le point de l'ensemble flou a suivant le calcul fourni dans l'argument a_mergeFunction et on passe au point suivant de l'ensemble flou a // 3 - L'abscisse X du point de l'ensemble flou a est après l'abscisse X du point de l'ensemble flou b => on ajoute le point de l'ensemble flou b suivant le calcul fourni dans l'argument a_mergeFunction et on passe au point suivant de l'ensemble flou b // 4 - Un croisement de courbe est détecté => on calcul le point d'intersection et on ajoute le point endOfList1 = false; endOfList2 = false; while (!endOfList1 && !endOfList2) { ComputeNewValuesAndPositions(); if (relativePosition != newRelativePosition && relativePosition != 0 && newRelativePosition != 0) // Détection d'une intersection : cas de figure n°4 { AddIntersectionToResult(a, b); GoToNextPoints(); } else if (x1 == x2) // Les points ont le même abscisse : cas de figure n°1 { result.AddPoint(x1, a_mergeFunction(enum1.Current.Y, enum2.Current.Y)); oldPt1 = enum1.Current; GoToNextPointOnA(); GoToNextPointOnB(); } else if (x1 < x2) // Le point de a est avant le point de b : cas de figure n°2 { result.AddPoint(x1, a_mergeFunction(enum1.Current.Y, b.DegreeAtValue(x1))); oldPt1 = enum1.Current; GoToNextPointOnA(); } else // Le point de b est avant le point de a : cas de figure n°3 { result.AddPoint(x2, a_mergeFunction(a.DegreeAtValue(x2), enum2.Current.Y)); GoToNextPointOnB(); } } // Un des 2 ensembles flous n'a plus de points, on ajoute les points du dernier ensemble flou suivant le calcul fourni dans l'argument a_mergeFunction AddEndPoints(a_mergeFunction); //result.Min = minNewFuzzySet; //result.Max = maxNewFuzzySet; return(result); }