예제 #1
0
        void ReadVariable(XmlNode xmlNode)
        {
            LinguisticVariable linguisticVariable = this.linguisticVariableCollection.Find(xmlNode.Attributes["NAME"].InnerText);

            foreach (XmlNode termNode in xmlNode.ChildNodes)
            {
                string[] points = termNode.Attributes["POINTS"].InnerText.Split();
                linguisticVariable.MembershipFunctionCollection.Add(new MembershipFunction(
                                                                        termNode.Attributes["NAME"].InnerText,
                                                                        Convert.ToDouble(points[0]),
                                                                        Convert.ToDouble(points[1]),
                                                                        Convert.ToDouble(points[2]),
                                                                        Convert.ToDouble(points[3])));
            }
        }
 /// <param name="name">The name that identificates the membership function.</param>
 public MembershipFunction(string name, ref DotFuzzy.FuzzyEngine engine, ref LinguisticVariable lvar)
 {
     this.Name   = name;
     this.lvar   = lvar;
     this.engine = engine;
 }
        /// <summary>
        /// Verify membership function is ordered min to max.
        /// </summary>
        public void Verify()
        {
            double max      = double.NegativeInfinity;
            double theValue = double.NaN;

            foreach (Point pnt in this.pointCollection)
            {
                if (!string.IsNullOrEmpty(pnt.P1_var))
                {
                    LinguisticVariable lvar = engine.linguisticVariableCollection.Find(pnt.P1_var);
                    if (lvar == null)
                    {
                        throw new Exception("Verify: Membership Function " + this.Name + " Point " + pnt.P1_var + " is not found !");
                    }
                    if (Double.IsNaN(lvar.Value))
                    {
                        throw new Exception("Verify: Membership Function " + this.Name + " Point " + pnt.P1_var + " is NaN !");
                    }
                    theValue   = lvar.Value;
                    pnt.P1_val = theValue; // copy pnt.P1_var.Value to pnt.P1_val
                }
                else
                {
                    if (Double.IsNaN(pnt.P1_val))
                    {
                        throw new Exception("Verify: Membership Function " + this.Name + " Point.Val is NaN !");
                    }
                    theValue = pnt.P1_val;
                }
                if (Double.IsNegativeInfinity(max))
                {
                    max      = theValue;
                    this.min = theValue;
                }
                else if (theValue >= max)
                {
                    max = theValue;
                }
                else
                {
                    throw new Exception("Verify: Membership Function " + this.Name + " Point " + pnt.P1_var + " Value " + theValue + " is out of order min to max !");
                }
                if (!string.IsNullOrEmpty(pnt.P2_var))
                {
                    LinguisticVariable lvar = engine.linguisticVariableCollection.Find(pnt.P2_var);
                    if (lvar == null)
                    {
                        throw new Exception("Verify: Membership Function " + this.Name + " Point " + pnt.P2_var + " is not found !");
                    }
                    if (Double.IsNaN(lvar.Value))
                    {
                        throw new Exception("Verify: Membership Function " + this.Name + " Point " + pnt.P2_var + " is NaN !");
                    }
                    theValue   = lvar.Value;
                    pnt.P2_val = theValue; // copy pnt.P2_var.Value to pnt.P2_val
                }
                if (Double.IsNaN(pnt.P2_val))
                {
                    throw new Exception("Verify: Membership Function " + this.Name + " Point  is NaN !");
                }
            }
            this.max = theValue;
        }
        /// <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);
        }
        /// <summary>
        /// Compute Area of membership function.
        /// </summary>
        public double LocateCenterArea(ref LinguisticVariable lvar, string mfuncName)
        {
            double location = Double.NaN;
            double rise     = Double.NaN;
            double run      = Double.NaN;
            double dist     = Double.NaN;
            double sumArea  = 0;
            Point  previous = null;
            bool   first    = true;
            double area     = lvar.area + ((Double.IsNaN(lvar.addArea)) ? 0 : lvar.addArea) + ((Double.IsNaN(lvar.addArea2)) ? 0 : lvar.addArea2);

            if (lvar == null)
            {
                throw new Exception("LocateCenterArea: LinguisticVariable lvar is null !");
            }
            if (Double.IsNaN(area))
            {
                throw new Exception("LocateCenterArea: LinguisticVariable " + lvar.Name + " Membership Function " + mfuncName + " area is NaN !");
            }
            if (this.Count < 1)
            {
                throw new Exception("LocateCenterArea: LinguisticVariable " + lvar.Name + " Membership Function " + mfuncName + " PointCollection Count < 1 !");
            }
            if (this.Count == 1)
            {
                Point thePoint = this.Items[0];
                location = thePoint.P1_val;
            }
            else // this.Count > 1
            {
                foreach (Point pnt in this)
                {
                    if (first)
                    {
                        if (!Double.IsNaN(lvar.addArea))
                        {
                            sumArea += lvar.addArea;
                        }
                    }
                    else
                    {
                        if (Double.IsNaN(previous.P2_val))
                        {
                            throw new Exception("LocateCenterArea: LinguisticVariable " + lvar.Name + " Membership Function " + mfuncName + " P2_val is NaN!");
                        }
                        run = pnt.P1_val - previous.P1_val;
                        if (run <= 0)
                        {
                            continue;
                        }
                        rise = pnt.P2_val - previous.P2_val;
                        switch (Math.Sign(rise))
                        {
                        case 0:     // rise == zero
                            sumArea += run * pnt.P2_val;
                            break;

                        case 1:     // rise > zero
                            sumArea += run * (previous.P2_val + rise / 2);
                            break;

                        case -1:     // rise < zero
                            sumArea += run * (pnt.P2_val - rise / 2);
                            break;

                        default:
                            throw new Exception("LocateCenterArea: LinguisticVariable " + lvar.Name + " Membership Function " + mfuncName + " Math.Sign(rise) is invalid !");
                        }
                        if (sumArea >= area / 2) // pnt is at or past area/2
                        {
                            switch (Math.Sign(rise))
                            {
                            case 0:     // rise == zero
                                if (pnt.P2_val == 0)
                                {
                                    throw new Exception("LocateCenterArea: LinguisticVariable " + lvar.Name + " Membership Function " + mfuncName + " pnt.P2_val == 0 !");
                                }
                                dist = (sumArea - area / 2) / pnt.P2_val;
                                break;

                            case 1:     // rise > zero
                                if (previous.P2_val + rise / 2 <= 0)
                                {
                                    throw new Exception("LocateCenterArea: LinguisticVariable " + lvar.Name + " Membership Function " + mfuncName + " (previous.P2_val + rise / 2) <= 0 !");
                                }
                                dist = (sumArea - area / 2) / (previous.P2_val + rise / 2);
                                break;

                            case -1:     // rise < zero
                                if (pnt.P2_val - rise / 2 <= 0)
                                {
                                    throw new Exception("LocateCenterArea: LinguisticVariable " + lvar.Name + " Membership Function " + mfuncName + " (pnt.P2_val - rise / 2) <= 0 !");
                                }
                                dist = (sumArea - area / 2) / (pnt.P2_val - rise / 2);
                                break;

                            default:
                                throw new Exception("LocateCenterArea: LinguisticVariable " + lvar.Name + " Membership Function " + mfuncName + " Math.Sign(rise) is invalid !");
                            } // switch
                            if (dist > run || dist < 0)
                            {
                                throw new Exception("LocateCenterArea: LinguisticVariable " + lvar.Name + " Membership Function " + mfuncName + " dist " + dist + " is < 0 or > run " + run + " !");
                            }
                            location = Math.Min(Math.Max(pnt.P1_val - dist, lvar.Range_min), lvar.Range_max);
                            break; // foreach
                        } // if (sumArea >= area / 2)
                    } // first
                    previous = pnt;
                    first    = false;
                } // foreach (Point pnt in this)
            }     // this.Count > 1
            return(location);
        }