Exemplo n.º 1
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();
        }
Exemplo n.º 2
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();
        }