예제 #1
0
        /// <summary>
        /// Defuzzify a membership function using the Bisector method.
        /// https://www.mathworks.com/help/fuzzy/examples/defuzzification-methods.html
        /// </summary>
        /// <param name="mf"></param>
        /// <returns></returns>
        public static double DefuzzBisect(MemberFunction mf)
        {
            double areaTotal = 0;

            double[] areas = new double[mf.Length];

            // Find the area of each segment
            for (int i = 0; i < mf.Length - 1; i++)
            {
                double x1 = mf.Coords[i][0];
                double x2 = mf.Coords[i + 1][0];
                double y1 = mf.Coords[i][1];
                double y2 = mf.Coords[i + 1][1];
                areas[i]   = 0.5 * (x2 - x1) * (y1 + y2);
                areaTotal += areas[i];
            }
            double halfArea = areaTotal / 2;

            double xMin  = 0;
            double xMax  = 0;
            double yLast = 0;
            double x     = 0;
            double y     = 0;
            double m     = 0;
            // This is our accumulating area
            double tmpArea = 0;

            for (int i = 0; i < mf.Length - 1; i++)
            {
                // Get the area of this segment
                m = areas[i];
                x = xMax = mf.Coords[i][0];
                // Add points in until we cross over to the haldway point
                if (tmpArea + m <= halfArea)
                {
                    tmpArea += m;
                }
                // Cut the distance in hald until we are reasonable close to the point we want
                else
                {
                    xMin  = mf.Coords[i][0];
                    xMax  = mf.Coords[i + 1][0];
                    yLast = mf.Coords[i][1];
                    while (halfArea - tmpArea > 0.000001)
                    {
                        x = xMin + ((xMax - xMin) / 2);
                        y = mf.fuzzify(x);

                        m = Area(new double[2] {
                            xMin, yLast
                        }, new double[2] {
                            x, y
                        });

                        if (tmpArea + m > halfArea)
                        {
                            xMax = x;
                        }

                        else if (tmpArea + m <= halfArea)
                        {
                            tmpArea += m;
                            xMin     = x;
                        }
                    }
                    break;
                }
            }
            return(x);
        }
예제 #2
0
        public void fuzzifyTest()
        {
            MemberFunction mf1 = new MemberFunction(new List <double[]>()
            {
                new double[2] {
                    1, 0
                },                     //0
                new double[2] {
                    2, 1
                },                     //1 <-- horiz
                new double[2] {
                    3, 1
                },                     //2 <-- Vertical
                new double[2] {
                    3, 2
                },                     //3 <-- horiz
                new double[2] {
                    4, 2
                },                     //4
                new double[2] {
                    5, 0
                }                      //5
            });

            Assert.AreEqual(mf1.fuzzify(0), 0);
            Assert.AreEqual(mf1.fuzzify(1), 0);
            Assert.AreEqual(mf1.fuzzify(2), 1);
            Assert.AreEqual(mf1.fuzzify(3), 1);
            Assert.AreEqual(mf1.fuzzify(4), 2);
            Assert.AreEqual(mf1.fuzzify(5), 0);

            Assert.AreEqual(mf1.fuzzify(0.5), 0);
            Assert.AreEqual(mf1.fuzzify(1.5), 0.5);
            Assert.AreEqual(mf1.fuzzify(2.5), 1);
            Assert.AreEqual(mf1.fuzzify(3.5), 2);
            Assert.AreEqual(mf1.fuzzify(4.5), 1);
            Assert.AreEqual(mf1.fuzzify(5.5), 0);

            Assert.AreEqual(mf1.fuzzify(-100), 0);
            Assert.AreEqual(mf1.fuzzify(100), 0);

            Assert.AreEqual(mf1.fuzzify(double.PositiveInfinity), 0);
            Assert.AreEqual(mf1.fuzzify(double.NegativeInfinity), 0);
        }