public MinMaxRule(SetOfSigns _X, SetOfSigns _Y)
 {
     X = _X;
     Y = _Y;
     x0 = X[0];
     y0 = Y[0];
 }
Example #2
0
        public static vectorObject[] GetNewCoords(vectorObject x, vectorObject y)
        {
            vectorObject[] be = new vectorObject[2];

            be[0] = ReCoord2D(x);
            be[1] = ReCoord2D(y);

            return be;
        }
Example #3
0
        /// <summary> Определяет координатную четверть</summary>
        public static vectorObject GetCoords2D(vectorObject vec)
        {
            vectorObject tmp = new vectorObject(2);

            tmp[0] = vec[0] - Boards[0].Width / 2;
            tmp[1] = vec[1] - Boards[0].Height / 2;

            return tmp;
        }
Example #4
0
        /// <summary> Определяет координатную четверть</summary>
        public static vectorObject GetCoords2D(float x, float y)
        {
            vectorObject tmp = new vectorObject(2);

            tmp[0] = x - Boards[0].Width / 2;
            tmp[1] = y - Boards[0].Height / 2;

            return tmp;
        }
Example #5
0
 public vectorObject this[int ObjN]
 {
     get { return objects[ObjN]; }
     set
     {
         if (ObjN >= count)
         {
             vectorObject[] New = new vectorObject[ObjN+1];
             for(int i=0; i<count; i++)
             {
                 New[i] = objects[i];
             }
             objects = New;
             count = ObjN + 1;
         }
         objects[ObjN] = value;
     }
 }
Example #6
0
        public static vectorObject[] GetNewCoords(vectorObject w, vectorObject x1, vectorObject y1)
        {
            vectorObject p = new vectorObject((x1[0] + y1[0]) / 2, (x1[1] + y1[1]) / 2);
            float A = y1[0] - x1[0];
            float B = y1[1] - x1[1];
            float C = -(A * p[0] + B * p[1]);

            float[] p4 = new float[2];

            p4[0] = -Utilities.Boards[0].Width / 2;
            p4[1] = -(A * p4[0] + C) / B;

            float[] p3 = { Utilities.Boards[0].Width / 2, -(A * (Utilities.Boards[0].Width / 2) + C) / B };

            vectorObject[] be = new vectorObject[2];

            be[0] = new vectorObject(p3);
            be[1] = new vectorObject(p4);

            return be;
        }
        //Критерий останова
        private bool StoppingCriterion(vectorObject x1, vectorObject y1, double gamma)
        {
            Utilities.Message("Проверяем критерий останова");
            Thread.Sleep(1500);
            double p = (x1-y1).Norm();

            double min = Math.Abs((W * X[0]) / W.Norm());
            for (int i = 0; i < X.Count; i++)
            {
                if (Math.Abs((W * X[i]) / W.Norm()) < min)
                {
                    min = Math.Abs((W * X[i]) / W.Norm());
                }
            }
            for (int i = 0; i < Y.Count; i++)
            {
                if (Math.Abs((W * Y[i]) / W.Norm()) < min)
                {
                    min = Math.Abs((W * Y[i]) / W.Norm());
                }
            }

            return (2*min>=gamma*p);
        }
        //Вычисляем коэфициенты по т. Куна-Такера
        private void KuhnTucker(ref float l1, ref float l2, vectorObject xp, vectorObject yq)
        {
            #region объявление и инициализация переменных
            float a = (y0 - x0) * (xp - x0);
            float b = (y0 - yq) * (y0 - yq);
            float c = (y0 - x0) * (y0 - yq);
            float d = (xp - x0) * (y0 - yq);
            float e = (xp - x0) * (xp - x0);
            float f = (y0 - xp) * (y0 - yq);
            float h = (yq - x0) * (xp - x0);
            #endregion
            //36
            if ((b * e) - (d * d) != 0)
            {
                //37
                l1 = ((a * b) - (c * d)) / ((b * e) - (d * d));
                l2 = ((c * e) - (a * d)) / ((b * e) - (d * d));

                if (l1<=0)
                {
                    //38
                    l2 = c / b;
                }
                else
                {
                    if (l1>=1)
                    {
                        //41
                        l2 = f / b;
                    }
                }
            }
            else
            {
                l1 = 0;
                l2 = c / b;
            }
            //40
            if (l2 <= 0)
            {
                //42
                l1 = a / e;
            }
            else
            {
                //43
                if (l2>=1)
                {
                    //45
                    l1 = h / e;
                }
            }
            //55
            if (l1 <= 0)
            {
                //56
                l1 = 0;
            }
            else
            {
                if (l1 > 1)
                {
                    l1 = 1;
                }
            }
            //58
            if (l2<=0)
            {
                l2 = 0;
            }
            else
            {
                if (l2>1)
                {
                    l2 = 1;
                }
            }

            //if (!((l1 > 0 & l1 < 1) & (l2 > 0 & l2 < 1)))
            //{
            //    KuhnTucker(ref l1, ref l2, xp, yq);
            //}
        }
        //Проверка является ли гиперплоскость разделяющей
        private bool IsRightPlane(vectorObject x1, vectorObject y1)
        {
            Utilities.Message("Проверяем является ли правило разделяющим");
            Thread.Sleep(1500);

            for (int i = 0; i < X.Count; i++)
            {
                if ((W * X[i] - W * (x1 + y1) / 2) < 0)
                    return false;
            }
            for (int i = 0; i < Y.Count; i++)
            {
                if ((W * Y[i] - W * (x1 + y1) / 2) > 0)
                    return false;
            }
            return true;
        }
        //Поиск минимального расстояния между прямыми xp-x0 и yq-y0
        private void FindMinLength(ref vectorObject xp, ref vectorObject yq, 
            ref vectorObject x1, ref vectorObject y1)
        {
            float l1 = 0;
            float l2 = 0;

            KuhnTucker(ref l1, ref l2, xp, yq);

            x1 = x0 + l1 * (xp - x0);
            y1 = y0 + l2 * (yq - y0);
        }
Example #11
0
        /// <summary> Превращает нормальные координаты в координаты для отрисовки </summary>
        public static vectorObject ReCoord2D(vectorObject OldCoord)
        {
            vectorObject NewCoord = new vectorObject(OldCoord.Size);

            NewCoord[0] = OldCoord[0];

            if (OldCoord[1] > 0)
                NewCoord[1] = -OldCoord[1];
            else
                NewCoord[1] = -OldCoord[1];

            return NewCoord;
        }
Example #12
0
        public vectorObject Normalized()
        {
            vectorObject tmp = new vectorObject(this.coords);

            float norm = tmp.Norm();

            for (int i = 0; i < n; i++)
            {
                tmp[i] = tmp[i] / norm;
            }

            return tmp;
        }
Example #13
0
        public static vectorObject operator *(float alpha, vectorObject v)
        {
            vectorObject tmp = new vectorObject(v.n);

            for (int i = 0; i < v.n; i++)
            {
                tmp[i] = alpha * v[i];
            }

            return tmp;
        }
Example #14
0
        public static SetOfSigns[] ReadTask(out int cellsize)
        {
            SetOfSigns[] imgs;
            OpenFileDialog of = new OpenFileDialog();
            of.Title = "Выберите файл";
            of.Filter = "Текстовые файлы|*.txt";

            cellsize = 1;

            if (of.ShowDialog() == DialogResult.OK)
            {
                TextReader tr = new StreamReader(of.FileName);
                cellsize = Int32.Parse(NextString(tr));
                int n = Int32.Parse(NextString(tr));
                imgs = new SetOfSigns[n];
                for (int i = 0; i < n; i++)
                {
                    string tmp = NextString(tr);
                    string[] objs = tmp.Split(';');
                    imgs[i] = new SetOfSigns(objs.Count() - 1);
                    for (int j = 0; j < objs.Count() - 1; j++)
                    {
                        string[] coords = objs[j].Split(',');
                        float[] crds = new float[coords.Count()];
                        for (int k = 0; k < crds.Count(); k++)
                        {
                            crds[k] = float.Parse(coords[k]);
                        }
                        imgs[i][j] = new vectorObject(crds);
                    }
                }
                tr.Close();
                return imgs;
            }

            return null;
        }
Example #15
0
        public static vectorObject LineCross(vectorObject x0, vectorObject y0, vectorObject p)
        {
            float A = y0[0] - x0[0];
            float B = y0[1] - x0[1];
            float C = -(A * p[0] + B * p[1]);

            float[] p4 = new float[2];

            p4[0] = -Utilities.Boards[0].Width/2;
            p4[1] = -(A * p4[0] + C) / B;

            float[] p1 = {x0[0], x0[1]};
            float[] p2 = {y0[0], y0[1]};
            float[] p3 = { Utilities.Boards[0].Width / 2, -(A * (Utilities.Boards[0].Width / 2) + C) / B };

            vectorObject rez = new vectorObject(SegmentCross(p1, p2, p3, p4));

            return rez;
        }
        public void BuildRule()
        {
            Utilities.Boards.Add(new GraphicsBoard(Utilities.Boards[0].Width, Utilities.Boards[0].Height,
                Utilities.Boards[0].Graphics));  //инициализируем класс-список объектов текущего состояния экрана
            Utilities.Boards[Utilities.Boards.Count - 1].AddElem(Utilities.Boards[0]);  //Добавляем на экран отображение точек множеств
            Pen dpen = new Pen(Brushes.Black, 2);
            dpen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash; //пунктирная линия

            vectorObject x1;
            vectorObject y1;
            vectorObject[] XXPcrds = new vectorObject[2];
            vectorObject[] YYQcrds = new vectorObject[2];
            vectorObject[] XYcrds1 = new vectorObject[2];
            vectorObject[] G = new vectorObject[2];

            while (true)
            {
                vectorObject xp = null;
                vectorObject yq = null;

                FindMaxPrs(ref xp, ref yq);

                if (xp == x0 || yq == y0)
                {
                    try
                    {
                        Utilities.Message("Нет новых точек");
                        Utilities.Boards.Add(new GraphicsBoard(Utilities.Boards[0].Width, Utilities.Boards[0].Height,
                            Utilities.Boards[0].Graphics)); //инициализируем класс-список объектов текущего состояния экрана
                        Utilities.Boards[Utilities.Boards.Count - 1].AddElem(Utilities.Boards[0]); //Добавляем на экран отображение точек множеств
                        Utilities.Boards[Utilities.Boards.Count - 1].AddElem(new Line(Utilities.Boards[0].Graphics, dpen,
                            new Point2f(XXPcrds[0][0], XXPcrds[0][1], new Pen(Brushes.Green, 3)),
                            new Point2f(XXPcrds[1][0], XXPcrds[1][1], new Pen(Brushes.Green, 3)))); //прямая (x0,xp)
                        Utilities.Boards[Utilities.Boards.Count - 1].AddElem(new Line(Utilities.Boards[0].Graphics, dpen,
                            new Point2f(YYQcrds[0][0], YYQcrds[0][1], new Pen(Brushes.Green, 3)),
                            new Point2f(YYQcrds[1][0], YYQcrds[1][1], new Pen(Brushes.Green, 3)))); //прямая (y0,yq)
                        Utilities.Boards[Utilities.Boards.Count - 1].AddElem(new Line(Utilities.Boards[0].Graphics, dpen,
                            new Point2f(XYcrds1[0][0], XYcrds1[0][1], new Pen(Brushes.Green, 3)),
                            new Point2f(XYcrds1[1][0], XYcrds1[1][1], new Pen(Brushes.Green, 3))));
                        Utilities.Boards[Utilities.Boards.Count - 1].AddElem(new Line(Utilities.Boards[0].Graphics, new Pen(Brushes.Black, 3),
                            new Point2f(G[0][0], G[0][1]), new Point2f(G[1][0], G[1][1])));
                        Utilities.Boards[Utilities.Boards.Count - 1].Draw(Utilities.Boards[0].cellsize);//прямая (y1,x1)
                        Utilities.drawDone.Set();
                        Thread.Sleep(1500);
                    }
                    catch(Exception e)
                    {
                        Utilities.Message("Нет точек для построения симплекса");
                    }
                    break;
                }

                x1 = new vectorObject(x0.Size);
                y1 = new vectorObject(y0.Size);

                FindMinLength(ref xp, ref yq, ref x1, ref y1);
                W = FindHyperplane(x1, y1);

                if (IsSeparating(delta))
                {
                    if (IsRightPlane(x1, y1))
                    {
                        if (StoppingCriterion(x1, y1, gamma))
                        {
                            Utilities.Message("Найдено линейное разделяющее правило");

                            XXPcrds[0] = x0;
                            XXPcrds[1] = xp;
                            YYQcrds[0] = y0;
                            YYQcrds[1] = yq;
                            XYcrds1[0] = x1;
                            XYcrds1[1] = y1;
                            G = Utilities.GetNewCoords(W, x1, y1);
                            if (Utilities.Boards[0].cellsize > 1)
                            {
                                XXPcrds = Utilities.GetNewCoords(x0, xp);  //Получаем координаты для отрисовки
                                YYQcrds = Utilities.GetNewCoords(y0, yq);
                                XYcrds1 = Utilities.GetNewCoords(x1, y1);
                                G = Utilities.GetNewCoords2(W, x1, y1);
                            }
                            Utilities.Boards.Add(new GraphicsBoard(Utilities.Boards[0].Width, Utilities.Boards[0].Height,
                                        Utilities.Boards[0].Graphics)); //инициализируем класс-список объектов текущего состояния экрана
                            Utilities.Boards[Utilities.Boards.Count - 1].AddElem(Utilities.Boards[0]); //Добавляем на экран отображение точек множеств
                            Utilities.Boards[Utilities.Boards.Count - 1].AddElem(new Line(Utilities.Boards[0].Graphics, dpen,
                                new Point2f(XXPcrds[0][0], XXPcrds[0][1], new Pen(Brushes.Green, 3)),
                                new Point2f(XXPcrds[1][0], XXPcrds[1][1], new Pen(Brushes.Green, 3)))); //прямая (x0,xp)
                            Utilities.Boards[Utilities.Boards.Count - 1].AddElem(new Line(Utilities.Boards[0].Graphics, dpen,
                                new Point2f(YYQcrds[0][0], YYQcrds[0][1], new Pen(Brushes.Green, 3)),
                                new Point2f(YYQcrds[1][0], YYQcrds[1][1], new Pen(Brushes.Green, 3)))); //прямая (y0,yq)
                            Utilities.Boards[Utilities.Boards.Count - 1].AddElem(new Line(Utilities.Boards[0].Graphics, dpen,
                                new Point2f(XYcrds1[0][0], XYcrds1[0][1], new Pen(Brushes.Green, 3)),
                                new Point2f(XYcrds1[1][0], XYcrds1[1][1], new Pen(Brushes.Green, 3))));
                            Utilities.Boards[Utilities.Boards.Count - 1].AddElem(new Line(Utilities.Boards[0].Graphics, new Pen(Brushes.Black, 3),
                                new Point2f(G[0][0], G[0][1]), new Point2f(G[1][0], G[1][1])));
                            Utilities.Boards[Utilities.Boards.Count - 1].Draw(Utilities.Boards[0].cellsize);//прямая (y1,x1)
                            Utilities.drawDone.Set();
                            Thread.Sleep(1500);

                            Utilities.drawing = false;
                            Thread.Sleep(1500);
                            break;
                        }
                    }

                    XXPcrds[0] = x0;
                    XXPcrds[1] = xp;
                    YYQcrds[0] = y0;
                    YYQcrds[1] = yq;
                    XYcrds1[0] = x1;
                    XYcrds1[1] = y1;
                    G = Utilities.GetNewCoords(W, x1, y1);
                    if (Utilities.Boards[0].cellsize > 1)
                    {
                        XXPcrds = Utilities.GetNewCoords(x0, xp);  //Получаем координаты для отрисовки
                        YYQcrds = Utilities.GetNewCoords(y0, yq);
                        XYcrds1 = Utilities.GetNewCoords(x1, y1);
                        G = Utilities.GetNewCoords2(W, x1, y1);
                    }
                    Utilities.Boards.Add(new GraphicsBoard(Utilities.Boards[0].Width, Utilities.Boards[0].Height,
                                Utilities.Boards[0].Graphics)); //инициализируем класс-список объектов текущего состояния экрана
                    Utilities.Boards[Utilities.Boards.Count - 1].AddElem(Utilities.Boards[0]); //Добавляем на экран отображение точек множеств
                    Utilities.Boards[Utilities.Boards.Count - 1].AddElem(new Line(Utilities.Boards[0].Graphics, dpen,
                        new Point2f(XXPcrds[0][0], XXPcrds[0][1], new Pen(Brushes.Green, 3)),
                        new Point2f(XXPcrds[1][0], XXPcrds[1][1], new Pen(Brushes.Green, 3)))); //прямая (x0,xp)
                    Utilities.Boards[Utilities.Boards.Count - 1].AddElem(new Line(Utilities.Boards[0].Graphics, dpen,
                        new Point2f(YYQcrds[0][0], YYQcrds[0][1], new Pen(Brushes.Green, 3)),
                        new Point2f(YYQcrds[1][0], YYQcrds[1][1], new Pen(Brushes.Green, 3)))); //прямая (y0,yq)
                    Utilities.Boards[Utilities.Boards.Count - 1].AddElem(new Line(Utilities.Boards[0].Graphics, dpen,
                        new Point2f(XYcrds1[0][0], XYcrds1[0][1], new Pen(Brushes.Green, 3)),
                        new Point2f(XYcrds1[1][0], XYcrds1[1][1], new Pen(Brushes.Green, 3))));
                    Utilities.Boards[Utilities.Boards.Count - 1].AddElem(new Line(Utilities.Boards[0].Graphics, new Pen(Brushes.Black, 3),
                        new Point2f(G[0][0], G[0][1]), new Point2f(G[1][0], G[1][1])));
                    Utilities.Boards[Utilities.Boards.Count - 1].Draw(Utilities.Boards[0].cellsize);//прямая (y1,x1)
                    Utilities.drawDone.Set();
                    Thread.Sleep(1500);

                    x0 = x1;
                    y0 = y1;
                }
                else
                {
                    Utilities.Message("Множества линейно не разделимы");
                    Utilities.drawing = false;
                    break;
                }
                if (!Utilities.multi)
                {
                    Utilities.nextStep.WaitOne();
                    Utilities.nextStep.Reset();
                }
            }
        }
Example #17
0
        public static vectorObject[] GetNewCoords2(vectorObject w, vectorObject x1, vectorObject y1)
        {
            vectorObject[] be = new vectorObject[2];

            be[0] = x1 + y1;
            float a = (w * be[0]) / 2;
            float yk = (a - w[0] * Boards[0].Width) / w[1];
            float y0 = a / w[1];

            be[0] = new vectorObject(0, y0);
            be[1] = new vectorObject(Boards[0].Width, yk);

            be[0] = ReCoord2D(be[0]);
            be[1] = ReCoord2D(be[1]);

            return be;
        }
Example #18
0
        public static vectorObject operator -(vectorObject v1, vectorObject v2)
        {
            vectorObject tmp = new vectorObject(v1.n);

            for (int i = 0; i < v1.n; i++)
            {
                tmp[i] = v1[i] - v2[i];
            }
            return tmp;
        }
 //Поиск гиперплоскости
 private vectorObject FindHyperplane(vectorObject x1, vectorObject y1)
 {
     Utilities.Message("Ищем результирующий направляющий вектор W");
     Thread.Sleep(1500);
     vectorObject _w = new vectorObject(x1.Size);
     _w = x1 - y1;
     return _w.Normalized();
 }
Example #20
0
 public vectorObject(vectorObject v)
 {
     coords = v.coords;
     n = v.n;
 }
        //Поиск Xp и Yq
        private void FindMaxPrs(ref vectorObject xp, ref vectorObject yq)
        {
            Utilities.Message("Ищем одномерные симплексы");
            Pen dpen = new Pen(Brushes.Black, 2);
            dpen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash; //пунктирная линия

            double maxX = 0;
            double maxY = 0;
            for (int i = 0; i < Math.Max(X.Count, Y.Count); i++)
            {
                Utilities.Boards.Add(new GraphicsBoard(Utilities.Boards[0].Width, Utilities.Boards[0].Height,
                            Utilities.Boards[0].Graphics)); //инициализируем класс-список объектов текущего состояния экрана
                Utilities.Boards[Utilities.Boards.Count - 1].AddElem(Utilities.Boards[0]); //Добавляем на экран отображение точек множеств
                vectorObject Xcrds = x0;
                vectorObject Ycrds = y0;
                if (Utilities.Boards[0].cellsize > 1)
                {
                    Xcrds = Utilities.ReCoord2D(x0); //Получаем координаты для отрисовки
                    Ycrds = Utilities.ReCoord2D(y0);
                }
                Utilities.Boards[Utilities.Boards.Count - 1].AddElem(new Point2f(Xcrds[0], Xcrds[1],
                    new Pen(Brushes.HotPink, 3))); //добавляем на экран точку x0
                Utilities.Boards[Utilities.Boards.Count - 1].AddElem(new Point2f(Ycrds[0], Ycrds[1],
                    new Pen(Brushes.HotPink, 3))); //добавляем на экран точку y0
                Utilities.Boards[Utilities.Boards.Count - 1].AddElem(new Line(Utilities.Boards[0].Graphics, new Pen(Brushes.Orchid, 2),
                    new Point2f(Xcrds[0], Xcrds[1]), new Point2f(Ycrds[0], Ycrds[1]))); // рисуем линию от x0 до y0
                if (i < X.Count)
                {
                    if ((X[i] - x0) * (y0 - x0) > maxX)
                    {
                        maxX = (X[i] - x0) * (y0 - x0);
                        xp = X[i];
                    }
                    if (x0 != X[i])
                    {
                        vectorObject crds = MathUtils.LineCross(x0, y0, X[i]);
                        vectorObject tmp = X[i];
                        if (Utilities.Boards[0].cellsize > 1)
                        {
                            crds = Utilities.ReCoord2D(crds);
                            tmp = Utilities.ReCoord2D(X[i]);
                        }
                        Utilities.Boards[Utilities.Boards.Count - 1].AddElem(new Line(Utilities.Boards[0].Graphics, new Pen(Brushes.Black, 2),
                        new Point2f(Xcrds[0], Xcrds[1]), new Point2f(tmp[0], tmp[1])));//рисуем линию от x0 до Xi
                        Utilities.Boards[Utilities.Boards.Count - 1].AddElem(new Line(Utilities.Boards[0].Graphics, dpen,
                        new Point2f(tmp[0], tmp[1]), new Point2f(crds[0], crds[1])));//рисуем линию от Xi до проекции Xi на прямую (x0,y0)
                    }
                }
                if (i < Y.Count)
                {
                    if ((Y[i] - y0) * (x0 - y0) > maxY)
                    {
                        maxY = (Y[i] - y0) * (x0 - y0);
                        yq = Y[i];
                    }
                    if (y0 != Y[i])
                    {
                        vectorObject crds = MathUtils.LineCross(x0, y0, Y[i]);
                        vectorObject tmp = Y[i];
                        if (Utilities.Boards[0].cellsize > 1)
                        {
                            crds = Utilities.ReCoord2D(crds);
                            tmp = Utilities.ReCoord2D(Y[i]);
                        }
                        Utilities.Boards[Utilities.Boards.Count - 1].AddElem(new Line(Utilities.Boards[0].Graphics, new Pen(Brushes.Black, 2),
                        new Point2f(Ycrds[0], Ycrds[1]), new Point2f(tmp[0], tmp[1])));//рисуем линию от y0 до Yi
                        Utilities.Boards[Utilities.Boards.Count - 1].AddElem(new Line(Utilities.Boards[0].Graphics, dpen,
                        new Point2f(tmp[0], tmp[1]), new Point2f(crds[0], crds[1])));//рисуем линию от Yi до проекции Yi на прямую (x0,y0)
                    }
                }
                try
                {
                    int f = xp.Size;
                }
                catch(Exception e)
                {
                    xp = x0;
                }
                try
                {
                    int f = yq.Size;
                }
                catch(Exception e)
                {
                    yq = y0;
                }
                Utilities.Boards[Utilities.Boards.Count - 1].Draw(Utilities.Boards[0].cellsize);
                Utilities.drawDone.Set();
                Thread.Sleep(1000);
                if (!Utilities.multi)
                {
                    Utilities.nextStep.WaitOne();
                    //Utilities.nextStep.Reset();
                }
            }
            Utilities.Message("");
        }