/// <summary> /// Create a fuzzy set with new y-intercept. Each points will have y-intercept = 1 - point.Y /// </summary> /// <param name="_fuzzySet">The fuzzy set to change</param> /// <returns>the new fuzzy set</returns> public static FuzzySet operator !(FuzzySet _fuzzySet) { FuzzySet newFuzzySet = new FuzzySet(_fuzzySet.getMin(), _fuzzySet.getMax()); foreach (Point2D aPoint in _fuzzySet.getPoints()) { newFuzzySet.Add(new Point2D(aPoint.getX(), 1 - aPoint.getY())); } return newFuzzySet; }
/// <summary> /// This function will multiply each y coordinate's points of a Fuzzy Set by the coefficent /// </summary> /// <param name="_fuzzySet">A fuzzy set</param> /// <param name="_coefficient">the coefficient will mutiply each y coordinate's points</param> /// <returns>the new fuzzy set</returns> public static FuzzySet operator *(FuzzySet _fuzzySet, double _coefficient) { FuzzySet multipliedFuzzySet = new FuzzySet(_fuzzySet.getMin(), _fuzzySet.getMax()); foreach (Point2D aPoint in _fuzzySet.getPoints()) { multipliedFuzzySet.Add(new Point2D(aPoint.getX(), aPoint.getY() * _coefficient)); } return multipliedFuzzySet; }
public double Solve() { // Apply the rules then calculate the fuzzy set FuzzySet res = new FuzzySet(Output.getMinValue(), Output.getMaxValue()); res.Add(Output.getMinValue(), 0); res.Add(Output.getMaxValue(), 0); foreach (FuzzyRule rule in Rules) { // Calculate res = res | rule.Apply(Problem); } // Defuzzification ! return res.Centroid(); }
/// <summary> /// Merge two fuzzy set into one /// </summary> /// <param name="_fuzzySetA">A fuzzy set</param> /// <param name="_fuzzySetB">Another fuzzy set</param> /// <param name="_mergeFonction">Function for merging (Min or Max for example), /// 3 doubles parameters : /// - 2 paramters for two double paramters /// - 1 paramter for a double to keep /// </param> /// <returns>the merged fuzzy set</returns> private static FuzzySet Merge(FuzzySet _fuzzySetA, FuzzySet _fuzzySetB, Func<double, double, double> _mergeFonction) { // ==== 1. Init FuzzySet mergedFuzzySet = new FuzzySet(Math.Min(_fuzzySetA.Min, _fuzzySetB.Min), Math.Max(_fuzzySetA.Max, _fuzzySetB.Max)); List<Point2D>.Enumerator enumeratorA = _fuzzySetA.Points.GetEnumerator(); List<Point2D>.Enumerator enumeratorB = _fuzzySetB.Points.GetEnumerator(); enumeratorA.MoveNext(); enumeratorB.MoveNext(); Point2D oldPointA = enumeratorA.Current; int relativePosition = 0; // When do the fuzzy sets intersect ? int newRelativePosition = GetSignDifference(enumeratorA.Current, enumeratorB.Current); // ==== 2. Loop until the end of one enumerator Boolean endOfListA = false; Boolean endOfListB = false; while (!endOfListA && !endOfListB) { // Currents values double xA = enumeratorA.Current.getX(); double xB = enumeratorB.Current.getX(); relativePosition = newRelativePosition; newRelativePosition = GetSignDifference(enumeratorA.Current, enumeratorB.Current); if (ArePositionDifferent(relativePosition, newRelativePosition)) { // Calcule the points coordinates double xMin = (xA == xB ? oldPointA.getX() : Math.Min(xA, xB)); double xMax = Math.Max(xA, xB); // Find the intersection point double slopeA = (_fuzzySetA.DegreeAtValue(xMax) - _fuzzySetA.DegreeAtValue(xMin)) / (xMax - xMin); double slopeB = (_fuzzySetB.DegreeAtValue(xMax) - _fuzzySetB.DegreeAtValue(xMin)) / (xMax - xMin); double delta = (_fuzzySetB.DegreeAtValue(xMin) - _fuzzySetA.DegreeAtValue(xMin)) / (slopeA - slopeB); // Add the intersection point mergedFuzzySet.Add(xMin + delta, _fuzzySetA.DegreeAtValue(xMin + delta)); // Update numerators if (xA < xB) { oldPointA = enumeratorA.Current; endOfListA = !(enumeratorA.MoveNext()); } else if (xA > xB) { endOfListB = !(enumeratorB.MoveNext()); } } else if (xA == xB) { // They both share the same X coordinate // We use the merge function to choose wich Y value we keep mergedFuzzySet.Add(xA, _mergeFonction(enumeratorA.Current.getY(), enumeratorB.Current.getY())); oldPointA = enumeratorA.Current; endOfListA = !(enumeratorA.MoveNext()); endOfListB = !(enumeratorB.MoveNext()); } else if (xA < xB) { // The point from _fuzzySetA is the first // We had its X value with the Y value returned by the merge fonction // The merge function will choose beetween the Y enumeratorA's point and the _fuzzySetB's degreee mergedFuzzySet.Add(xA, _mergeFonction(enumeratorA.Current.getY(), _fuzzySetB.DegreeAtValue(xA))); oldPointA = enumeratorA.Current; endOfListA = !(enumeratorA.MoveNext()); } else { // The point from _fuzzySetB is the first // We had its X value with the Y value returned by the merge fonction // The merge function will choose beetween the Y enumeratorB's point and the _fuzzySetA's degreee mergedFuzzySet.Add(xB, _mergeFonction(enumeratorB.Current.getY(), _fuzzySetA.DegreeAtValue(xB))); endOfListB = !(enumeratorB.MoveNext()); } } // ==== 3. Merge the end of the other enumerator if needed if (!endOfListA) { while (!endOfListA) { mergedFuzzySet.Add(enumeratorA.Current.getX(), _mergeFonction(enumeratorA.Current.getY(), 0)); endOfListA = !enumeratorA.MoveNext(); } } else if (!endOfListB) { while (!endOfListB) { mergedFuzzySet.Add(enumeratorB.Current.getX(), _mergeFonction(enumeratorB.Current.getY(), 0)); endOfListB = !enumeratorB.MoveNext(); } } return mergedFuzzySet; }