Пример #1
0
        /// <summary>
        /// Calculates the defuzzification value with the CoG (Center of Gravity) technique.
        /// </summary>
        /// <returns>The defuzzification value.</returns>
        public double Defuzzify()
        {
            double numerator   = 0;
            double denominator = 0;

            // Reset values
            foreach (MembershipFunction membershipFunction in this.GetConsequent().MembershipFunctionCollection)
            {
                membershipFunction.Value = 0;
            }

            foreach (FuzzyRule fuzzyRule in this.fuzzyRuleCollection)
            {
                fuzzyRule.Value = Parse(fuzzyRule.Conditions());

                string[]           tokens             = fuzzyRule.Text.Split();
                MembershipFunction membershipFunction = this.GetConsequent().MembershipFunctionCollection.Find(tokens[tokens.Length - 1]);

                if (fuzzyRule.Value > membershipFunction.Value)
                {
                    membershipFunction.Value = fuzzyRule.Value;
                }
            }

            foreach (MembershipFunction membershipFunction in this.GetConsequent().MembershipFunctionCollection)
            {
                numerator   += membershipFunction.Centorid() * membershipFunction.Area();
                denominator += membershipFunction.Area();
            }

            return(numerator / denominator);
        }
Пример #2
0
        /// <summary>
        /// Implements the fuzzification of the linguistic variable.
        /// </summary>
        /// <param name="membershipFunctionName">The membership function for which fuzzify the variable.</param>
        /// <returns>The degree of membership.</returns>
        public double Fuzzify(string membershipFunctionName)
        {
            MembershipFunction membershipFunction = this.membershipFunctionCollection.Find(membershipFunctionName);

            /*
             *          if ((membershipFunction.X0 <= this.Value) && (this.Value < membershipFunction.X1))
             *              return (this.Value - membershipFunction.X0) / (membershipFunction.X1 - membershipFunction.X0);
             *          else if ((membershipFunction.X1 <= this.Value) && (this.Value <= membershipFunction.X2))
             *              return 1;
             *          else if ((membershipFunction.X2 < this.Value) && (this.Value <= membershipFunction.X3))
             *              return (membershipFunction.X3 - this.Value) / (membershipFunction.X3 - membershipFunction.X2);
             *          else
             */
            return(0);
        }
Пример #3
0
        /// <summary>
        /// Implements the fuzzification of the linguistic variable.
        /// </summary>
        /// <param name="membershipFunctionName">The membership function for which fuzzify the variable.</param>
        /// <returns>The degree of membership.</returns>
        public double Fuzzify(string membershipFunctionName)
        {
            MembershipFunction membershipFunction = this.membershipFunctionCollection.Find(membershipFunctionName);

            if ((membershipFunction.X0 <= this.InputValue) && (this.InputValue < membershipFunction.X1))
            {
                return((this.InputValue - membershipFunction.X0) / (membershipFunction.X1 - membershipFunction.X0));
            }
            else if ((membershipFunction.X1 <= this.InputValue) && (this.InputValue <= membershipFunction.X2))
            {
                return(1);
            }
            else if ((membershipFunction.X2 < this.InputValue) && (this.InputValue <= membershipFunction.X3))
            {
                return((membershipFunction.X3 - this.InputValue) / (membershipFunction.X3 - membershipFunction.X2));
            }
            else
            {
                return(0);
            }
        }
        /// <summary>
        /// Compute Activation of membership function.
        /// </summary>
        public void ComputeActivation(double activation)
        {
            if (Double.IsNaN(activation))
            {
                throw new Exception("ComputeActivation: LinguisticVariable " + lvar.Name + " Activation is NaN !");
            }
            activated_pointCollection.Clear();
            if (Double.IsNaN(lvar.Range_min))
            {
                throw new Exception("ComputeArea: LinguisticVariable " + lvar.Name + " Range_min is NaN !");
            }
            if (Double.IsNaN(lvar.Range_max))
            {
                throw new Exception("ComputeArea: LinguisticVariable " + lvar.Name + " Range_max is NaN !");
            }
            this.Act_value = activation;
            bool   first    = true;
            Point  previous = null;
            double rise;
            double run;
            double slope;
            double dist;

            activated_pointCollection.Clear();
            foreach (Point pnt in this.pointCollection)
            {
                if (Double.IsNaN(pnt.P1_val))
                {
                    throw new Exception("ComputeArea: LinguisticVariable " + lvar.Name + " Membership Function " + this.Name + " Point.P1_val is NaN !");
                }
                if (Double.IsNaN(pnt.P2_val))
                {
                    throw new Exception("ComputeArea: LinguisticVariable " + lvar.Name + " Membership Function " + this.Name + " Point.P2_val is NaN !");
                }
                if (first)
                {
                    if (pnt.P2_val > 0 && pnt.P1_val > lvar.Range_min)
                    {
                        Point start = new Point(lvar.Range_min, Math.Min(pnt.P2_val, activation));
                        activated_pointCollection.Add(start);
                    }
                    activated_pointCollection.Add(pnt.ClonePoint(activation));
                }
                else // not first
                {
                    rise = Math.Abs(pnt.P2_val - previous.P2_val);
                    run  = Math.Abs(pnt.P1_val - previous.P1_val);
                    if ((activation == 0) || // activation == 0
                        (run == 0) || // pnt.P1_val == previous.P1_val
                        (rise == 0)) // no slope
                    {
                        activated_pointCollection.Add(pnt.ClonePoint(activation));
                    }
                    else if (previous.P2_val <= activation && pnt.P2_val <= activation) // both <= activation
                    {
                        activated_pointCollection.Add(pnt.ClonePoint(activation));
                    }
                    else if (previous.P2_val > activation && pnt.P2_val > activation) // both > activation
                    {
                        activated_pointCollection.Add(pnt.ClonePoint(activation));
                    }
                    else if (previous.P2_val <= activation) // previous below, pnt above activation
                    {
                        slope = rise / run;
                        dist  = (activation - previous.P2_val) / slope;
                        Point intersect = new Point(previous.P1_val + dist, activation);
                        activated_pointCollection.Add(intersect);
                        activated_pointCollection.Add(pnt.ClonePoint(activation));
                    }
                    else // previous above, pnt below activation
                    {
                        slope = rise / run;
                        dist  = (activation - pnt.P2_val) / slope;
                        Point intersect = new Point(pnt.P1_val - dist, activation);
                        activated_pointCollection.Add(intersect);
                        activated_pointCollection.Add(pnt.ClonePoint(activation));
                    }
                }
                first    = false;
                previous = pnt;
            }
            if (previous.P2_val > 0 && previous.P1_val < lvar.Range_max)
            {
                Point last = new Point(lvar.Range_max, Math.Min(previous.P2_val, activation));
                activated_pointCollection.Add(last);
            }
            Console.WriteLine("ComputeActivation:  LinguisticVariable " + lvar.Name + " Membership Function " + this.Name + " Point.Count=" + activated_pointCollection.Count + " activation=" + activation);
            MembershipFunction mfunc = this;

            this.activated_pointCollection.ComputeArea(ref lvar, ref mfunc);
        }
Пример #5
0
        /// <summary>
        /// Accumulate the results of Membership functions.
        /// </summary>
        public void Accumulate()
        {
            Console.WriteLine("Accumulate: lvar = " + this.Name);
            double previousLoc = Double.NegativeInfinity;
            double location;
            int    index;
            int    index2;
            int    prevMfunc  = -1;
            int    mfuncIndex = -1;
            bool   finished   = false;

            index2 = 0;
            this.accumulation.Clear();
            foreach (MembershipFunction mfunc in this.MembershipFunctionCollection)
            {
                mfunc.index = index2++;
                index       = 0;
                foreach (Point pnt in mfunc.activated_pointCollection)
                {
                    pnt.index = index++;
                }
            }
            while (previousLoc < this.Range_max)
            {
                location = Double.PositiveInfinity;
                finished = false;
                while (!finished)
                {
                    foreach (MembershipFunction mfunc in this.MembershipFunctionCollection)
                    {
                        finished = true;
                        if (mfunc.Act_value > 0)
                        {
                            foreach (Point pnt in mfunc.activated_pointCollection)
                            {
                                if (pnt.P1_val >= location)
                                {
                                    break;
                                }
                                if (pnt.P1_val > previousLoc)
                                {
                                    location       = pnt.P1_val;
                                    mfunc.pntIndex = pnt.index;
                                    finished       = false;
                                    break;
                                }
                            }
                        }
                    }
                }
                double maximum = Double.NegativeInfinity;
                foreach (MembershipFunction mfunc in this.MembershipFunctionCollection)
                {
                    if (mfunc.Act_value == 0)
                    {
                        continue;
                    }
                    if (mfunc.activated_pointCollection.Count == 0)
                    {
                        continue;
                    }
                    double value = mfunc.FindValue(ref mfunc.activated_pointCollection, location);
                    if (value >= maximum)
                    {
                        maximum        = Math.Round(value, 6);
                        mfuncIndex     = mfunc.index;
                        mfunc.pntIndex = mfunc.loc1;
                        if (prevMfunc < 0)
                        {
                            prevMfunc = mfuncIndex;
                        }
                    }
                }
                if (prevMfunc < 0)
                {
                    throw new Exception("Accumulate: LinguisticVariable " + this.Name + " All MembershipFunction.Act_value == 0 !");
                }
                if (mfuncIndex != prevMfunc) // Intersection
                {
                    MembershipFunction mfunc  = this.membershipFunctionCollection[mfuncIndex];
                    MembershipFunction mfunc2 = this.membershipFunctionCollection[prevMfunc];
                    Point thePoint            = mfunc.activated_pointCollection[mfunc.pntIndex];
                    Point thePoint2           = mfunc2.activated_pointCollection[mfunc2.pntIndex];
                    if (mfunc.pntIndex == 0) // first point
                    {
                        if (location > previousLoc)
                        {
                            this.accumulation.Add(new Point(location, maximum));
                        }
                    }
                    else if (mfunc2.pntIndex == mfunc2.activated_pointCollection.Count - 1) // last point
                    {
                        if (location > previousLoc)
                        {
                            this.accumulation.Add(new Point(location, maximum));
                        }
                    }
                    else // get Intersection
                    {
                        Point  thePoint1 = mfunc.activated_pointCollection[mfunc.pntIndex - 1];
                        Point  thePoint3 = (mfunc2.pntIndex == 0) ? mfunc2.activated_pointCollection[mfunc2.pntIndex + 1] : mfunc2.activated_pointCollection[mfunc2.pntIndex - 1];
                        double run       = Math.Abs(thePoint.P1_val - thePoint1.P1_val);
                        double run2      = Math.Abs(thePoint3.P1_val - thePoint2.P1_val);
                        double rise      = thePoint.P2_val - thePoint1.P2_val;
                        double rise2     = thePoint3.P2_val - thePoint2.P2_val;
                        if (run == 0 || run2 == 0 || rise2 == 0)
                        {
                            if (location > previousLoc)
                            {
                                this.accumulation.Add(new Point(location, Math.Max(thePoint.P2_val, thePoint1.P2_val)));
                            }
                        }
                        else
                        {
                            double x1   = thePoint2.P1_val;
                            double x2   = thePoint3.P1_val;
                            double x3   = thePoint1.P1_val;
                            double x4   = thePoint.P1_val;
                            double y1   = thePoint2.P2_val;
                            double y2   = thePoint3.P2_val;
                            double y3   = thePoint1.P2_val;
                            double y4   = thePoint.P2_val;
                            double num1 = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4);
                            double num2 = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4);
                            double den1 = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
                            double den2 = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
                            if (den1 == 0 || den2 == 0)
                            {
                                throw new Exception("Accumulate: Intersection is Undefined !");
                            }
                            location = Math.Round(num1 / den1, 6);
                            maximum  = Math.Round(num2 / den1, 6);
                            if (location > previousLoc)
                            {
                                this.accumulation.Add(new Point(location, maximum));
                            }
                        }
                    }
                }
                else // no Intersection
                {
                    if (location > previousLoc)
                    {
                        this.accumulation.Add(new Point(location, maximum));
                    }
                }
                prevMfunc   = mfuncIndex;
                previousLoc = location;
            }
        }
        /// <summary>
        /// Compute Area of membership function.
        /// </summary>
        public double ComputeArea(ref LinguisticVariable lvar, ref MembershipFunction mfunc)
        {
            double area = 0;

            if (Double.IsNaN(lvar.Range_min))
            {
                throw new Exception("ComputeArea: LinguisticVariable " + lvar.Name + " Range_min is NaN !");
            }
            if (Double.IsNaN(lvar.Range_max))
            {
                throw new Exception("ComputeArea: LinguisticVariable " + lvar.Name + " Range_max is NaN !");
            }
            bool   first    = true;
            bool   extend   = false;
            bool   extend2  = false;
            Point  previous = null;
            double rise;
            double run;

            foreach (Point pnt in this)
            {
                if (Double.IsNaN(pnt.P1_val))
                {
                    throw new Exception("ComputeArea: LinguisticVariable " + lvar.Name + " Membership Function "
                                        + ((Object.ReferenceEquals(mfunc, null)) ? "" : mfunc.Name) + " Point.P1_val is NaN !");
                }
                if (Double.IsNaN(pnt.P2_val))
                {
                    throw new Exception("ComputeArea: LinguisticVariable " + lvar.Name + " Membership Function "
                                        + ((Object.ReferenceEquals(mfunc, null)) ? "" : mfunc.Name) + " Point.P2_val is NaN !");
                }
                if (first)
                {
                    if (pnt.P2_val > 0)
                    {
                        area += Math.Abs(pnt.P1_val - lvar.Range_min) * pnt.P2_val; // extend area to min
                        if (!Object.ReferenceEquals(mfunc, null))
                        {
                            extend = true;
                        }
                    }
                }
                else // not first
                {
                    run = Math.Abs(pnt.P1_val - previous.P1_val);
                    if (run > 0)
                    {
                        rise = Math.Abs(pnt.P2_val - previous.P2_val);
                        if (rise == 0)                // equal
                        {
                            area += pnt.P2_val * run; // rectangle
                        }
                        else
                        {
                            area += Math.Min(pnt.P2_val, previous.P2_val) * run; // base
                            area += rise * run / 2;                              // triangle
                        }
                    }
                }
                first    = false;
                previous = pnt;
            } // foreach pnt
            if (previous.P1_val <= lvar.Range_max)
            {
                if (previous.P2_val > 0)
                {
                    area += Math.Abs(previous.P1_val - lvar.Range_max) * previous.P2_val; // extend area to Range_max
                    if (!Object.ReferenceEquals(mfunc, null))
                    {
                        extend2 = true;
                    }
                }
            }
            if (!Object.ReferenceEquals(mfunc, null))
            {
                if ((extend || extend2) && lvar.Method == "COG_EXTEND")
                {
                    mfunc.addArea = area; // Additional area
                    Console.WriteLine("ComputeArea:  LinguisticVariable " + lvar.Name + " Membership Function " + mfunc.Name + " addArea=" + area);
                    if (extend)
                    {
                        lvar.addArea = area;
                    }
                    else
                    {
                        lvar.addArea2 = area;
                    }
                }
            }
            Console.WriteLine("ComputeArea:  LinguisticVariable " + lvar.Name + " Membership Function "
                              + ((Object.ReferenceEquals(mfunc, null)) ? "" : mfunc.Name) + " Area=" + area);
            return(area);
        }