Exemple #1
0
        private void toolStripMenuItemCreateDividePlane_Click(object sender, EventArgs e)
        {
            if (plane_dividing_list.Count == 0)
                for (int i = 0; i < polygon_list.Count - 1; i++)
                {
                    for (int j = i + 1; j < polygon_list.Count; j++)
                    {
                        PlaneDividing plane_dividing = new PlaneDividing(new Polygon2d.Iterator(0, polygon_list[i], 0), new Polygon2d.Iterator(0, polygon_list[j], 0));
                        plane_dividing.Find();
                        plane_dividing_list.Add(plane_dividing);
                    }
                }
            else
                plane_dividing_list.Clear();

            Invalidate();
        }
Exemple #2
0
        /// <summary>
        /// Метод подготовки данных и запуска алгоритма размещения многоугольников.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Barriers_Click(object sender, RoutedEventArgs e)
        {
            List<Polygon2d> polygons = new List<Polygon2d>(this.polygons.List);

            #region Шаг 1. Создаём начальную точку.
            #region Шаг 1.1. Заполняем координаты полюсов.
            double[] X = new double[2 * polygons.Count + 1];
            for (int i = 0; i < polygons.Count; i++)
            {
                X[2 * i] = polygons[i].Pole.X;
                X[2 * i + 1] = polygons[i].Pole.Y;
            }
            #endregion
            #region Шаг 1.2. Заполняем длину занятой части полосы.
            X[2 * polygons.Count] = 0;
            for (int i = 0; i < polygons.Count; i++)
            {
                double max_x = double.NegativeInfinity;
                for (int j = 0; j < polygons[i].Count; j++)
                    if (max_x < polygons[i][j].X)
                        max_x = polygons[i][j].X;
                if (X[2 * polygons.Count] < polygons[i].Pole.X + max_x)
                    X[2 * polygons.Count] = polygons[i].Pole.X + max_x;
            }
            X[2 * polygons.Count] *= 2;
            #endregion
            #endregion

            #region Шаг 2. Создаём функцию цели.
            double[] F = new double[2 * polygons.Count + 2];
            F[2 * polygons.Count] = 1;
            #endregion

            #region Шаг 3. Создаём набор ограничений.
            List<double[]> G = new List<double[]>();
            #region Шаг 3.1. Для каждого многоугольника...
            for (int i = 0; i < polygons.Count; i++)
            {
                #region Шаг 3.1.1. Находим минимальное и максимальное значение прямоугольной оболочки для многоугольника.
                Point min = new Point { X = double.PositiveInfinity, Y = double.PositiveInfinity };
                Point max = new Point { X = double.NegativeInfinity, Y = double.NegativeInfinity };
                for (int j = 0; j < polygons[i].Count; j++)
                {
                    if (min.X > polygons[i][j].X)
                        min.X = polygons[i][j].X;
                    if (max.X < polygons[i][j].X)
                        max.X = polygons[i][j].X;
                    if (min.Y > polygons[i][j].Y)
                        min.Y = polygons[i][j].Y;
                    if (max.Y < polygons[i][j].Y)
                        max.Y = polygons[i][j].Y;
                }
                #endregion
                #region Шаг 3.1.2. Создаём набор ограничений по полосе. Проверить!!
                double[] g;
                #region Шаг 3.1.2.1. Ограничение по нижней границе. // Y-min.Y>=0  -->  -Y+min.Y<=0
                g = new double[2 * polygons.Count + 2];
                g[2 * i + 1] = -1;
                g[2 * polygons.Count + 1] = min.Y;
                G.Add(g);
                #endregion
                #region Шаг 3.1.2.2. Ограничение по левой границе. // X-min.X>=0  -->  -X+min.X<=0
                g = new double[2 * polygons.Count + 2];
                g[2 * i] = -1;
                g[2 * polygons.Count + 1] = min.X;
                G.Add(g);
                #endregion
                #region Шаг 3.1.2.3. Ограничение по верхней границе. // Y+max.Y<=H  -->  Y+max.Y-H<=0
                g = new double[2 * polygons.Count + 2];
                g[2 * i + 1] = 1;
                g[2 * polygons.Count + 1] = max.Y - strip.Height;
                G.Add(g);
                #endregion
                #region Шаг 3.1.2.4. Ограничение по правой границе. // X+max.X<=Z  -->  X-Z+max.X<=0
                g = new double[2 * polygons.Count + 2];
                g[2 * i] = 1;
                g[2 * polygons.Count] = -1;
                g[2 * polygons.Count + 1] = max.X;
                G.Add(g);
                #endregion
                #endregion
            }
            #endregion
            #region Шаг 3.2. Для каждой пары многоугольников...
            for (int i = 0; i < polygons.Count - 1; i++)
                for (int j = i + 1; j < polygons.Count; j++)
                {
                    #region Шаг 3.2.1. Создаём и находим разделяющую.
                    PlaneDividing pd = new PlaneDividing(new Polygon2d.Iterator(i, polygons[i], 0), new Polygon2d.Iterator(j, polygons[j], 0));
                    pd.Find();
                    #endregion
                    #region Шаг 3.2.2. Создаём ограничение. !!Проверить!!
                    Vector2d vector = pd.IteratorPlane.Point(1) - pd.IteratorPlane.Point(0);
                    Vector2d normal = new Vector2d { X = -vector.Y, Y = vector.X };
                    double length = Math.Sqrt(normal * normal);
                    normal.X /= length; normal.Y /= length;
                    double[] g = new double[2 * polygons.Count + 2];
                    g[2 * pd.IteratorPoint.IndexPolygon] = normal.X;
                    g[2 * pd.IteratorPoint.IndexPolygon + 1] = normal.Y;
                    g[2 * pd.IteratorPlane.IndexPolygon] = -normal.X;
                    g[2 * pd.IteratorPlane.IndexPolygon + 1] = -normal.Y;
                    g[2 * polygons.Count + 1] = ((pd.IteratorPoint.Polygon[pd.IteratorPoint.Index] - pd.IteratorPlane.Polygon[pd.IteratorPlane.Index]) * normal);
                    G.Add(g);
                    #endregion
                }
            #endregion
            #endregion

            #region Шаг 6. Выполняем поиск локального минимума с заданными ограничениями.
            double mu = 1000; // Должно вводиться с формы!
            double beta = 0.5; // Должно вводиться с формы!
            double eps = 1e-3; // Должно вводиться с формы!
            Calculate(F, G, ref X, mu, beta, eps);
            #endregion

            #region Шаг 7. Преобразуем результат метода барьеров в результат задачи размещения и возвращаем длину занятой части полосы.
            for (int i = 0; i < polygons.Count; i++)
            {
                polygons[i].Pole.X = X[2 * i];
                polygons[i].Pole.Y = X[2 * i + 1];
            }
            strip_length.Text = X[X.Length - 1].ToString();
            #endregion

            this.polygons.InvalidateVisual();
        }
Exemple #3
0
        /// <summary>
        /// Метод подготовки данных и запуска алгоритма размещения многоугольников (метод барьерных функций).
        /// </summary>
        /// <param name="mu"></param>
        /// <param name="beta"></param>
        /// <param name="eps"></param>
        public void CalculateStart(double mu, double beta, double eps)
        {
            double width_old;
            do
            {
                width_old = strip_vector.X;

                #region Шаг 1. Создаём начальную точку.
                FillPoint();
                #endregion

                #region Шаг 2. Создаём функцию цели.
                Clear(F);
                F[index_strip] = 1;
                #endregion

                #region Шаг 3. Создаём набор ограничений.
                Clear(Gs);
                int k = 0;
                #region Шаг 3.1. Для каждого многоугольника...
                for (int i = 0; i < polygons.Length; i++)
                {
                    #region Шаг 3.1.1. Создаём набор ограничений (G >= 0) по полосе.
                    #region Шаг 3.1.1.1. Ограничение по нижней границе. //  Y - min.Y >= 0
                    Gs[k][2 * i + 1] = 1;
                    Gs[k][index_strip + 1] = -polygons[i].MinY;
                    k++;
                    #endregion
                    #region Шаг 3.1.1.2. Ограничение по левой границе. //   X - min.X >= 0
                    Gs[k][2 * i] = 1;
                    Gs[k][index_strip + 1] = -polygons[i].MinX;
                    k++;
                    #endregion
                    #region Шаг 3.1.1.3. Ограничение по верхней границе. // Y + max.Y <= H  --> -Y - max.Y + H >= 0
                    Gs[k][2 * i + 1] = -1;
                    Gs[k][index_strip + 1] = -polygons[i].MaxY + strip_vector.Y;
                    k++;
                    #endregion
                    #region Шаг 3.1.1.4. Ограничение по правой границе. //  X + max.X <= Z  --> -X + Z - max.X >= 0
                    Gs[k][2 * i] = -1;
                    Gs[k][index_strip] = 1;
                    Gs[k][index_strip + 1] = -polygons[i].MaxX;
                    k++;
                    #endregion
                    #endregion
                }
                #endregion
                #region Шаг 3.2. Для каждой пары многоугольников...
                for (int i = 0; i < polygons.Length - 1; i++)
                    for (int j = i + 1; j < polygons.Length; j++)
                    {
                        #region Шаг 3.2.1. Создаём и находим разделяющую.
                        //PlaneDividing pd = new PlaneDividing(new Polygon2d.Iterator(i, polygons[i], 0), new Polygon2d.Iterator(j, polygons[j], 0));
                        //pd.Find();

                        #region Временный код.
                        PlaneDividing pd;
                        Polygon2d.Iterator it1i = new Polygon2d.Iterator(i, polygons[i], 0);
                        Polygon2d.Iterator it1j = new Polygon2d.Iterator(j, polygons[j], 0);
                        double ed1 = Find(it1i, it1j);

                        Polygon2d.Iterator it2i = new Polygon2d.Iterator(i, polygons[i], 0);
                        Polygon2d.Iterator it2j = new Polygon2d.Iterator(j, polygons[j], 0);
                        double ed2 = Find(it2j, it2i);

                        if (ed1 > ed2)
                            pd = new PlaneDividing(it1i, it1j);
                        else
                            pd = new PlaneDividing(it2j, it2i);
                        #endregion

                        #endregion

                        #region Шаг 3.2.2. Создаём ограничение.
                        Vector2d vector = pd.IteratorPlane.Point(1) - pd.IteratorPlane.Point(0);
                        Vector2d normal = new Vector2d { X = -vector.Y, Y = vector.X };
                        //normal.Normalize(); // Нужна ли нормализация вектора?

                        Gs[k][2 * pd.IteratorPoint.IndexPolygon] = -normal.X;
                        Gs[k][2 * pd.IteratorPoint.IndexPolygon + 1] = -normal.Y;
                        Gs[k][2 * pd.IteratorPlane.IndexPolygon] = normal.X;
                        Gs[k][2 * pd.IteratorPlane.IndexPolygon + 1] = normal.Y;
                        Gs[k][index_strip + 1] = -((pd.IteratorPoint.Polygon[pd.IteratorPoint.Index] - pd.IteratorPlane.Polygon[pd.IteratorPlane.Index]) * normal);
                        k++;
                        #endregion
                    }
                #endregion
                #endregion

                #region Шаг 4. Выполняем поиск локального минимума с заданными ограничениями.
                Calculate(mu, beta, eps);
                #endregion

                #region Шаг 5. Преобразуем результат метода барьеров в результат задачи размещения.
                FillPolygons();
                #endregion

            } while (Math.Abs(strip_vector.X - width_old) > eps);
        }