コード例 #1
0
ファイル: FormMain.cs プロジェクト: Ring-r/opt
        private void ReadFromFile(string filename)
        {
            StreamReader sr = new StreamReader(filename);

            strip_vector = new Vector2d();

            string[] s = sr.ReadLine().Split(' ');
            strip_vector.X = double.Parse(s[0]);
            strip_vector.Y = double.Parse(s[1]);

            polygons = new PolygonWithMinMax[int.Parse(sr.ReadLine())];
            for (int i = 0; i < polygons.Length; i++)
            {
                polygons[i] = new PolygonWithMinMax();

                s = sr.ReadLine().Split(' ');
                polygons[i].Pole.X = double.Parse(s[0]);
                polygons[i].Pole.Y = double.Parse(s[1]);

                for (int j = 2; j < s.Length; j += 2)
                    polygons[i].Add(new Point2d() { X = double.Parse(s[j]), Y = double.Parse(s[j + 1]) });

                polygons[i].Check();
            }

            sr.Close();
        }
コード例 #2
0
ファイル: Model.cs プロジェクト: Ring-r/opt
 } // !!!Дописать!!!
 public static Point2d Calc(StripLine strip_line_i, StripLine strip_line_j)
 {
     Vector2d vector_i = strip_line_i.Vector;
     Vector2d vector_j_ = new Vector2d() { X = -strip_line_j.VY, Y = strip_line_j.VX };
     double d = vector_i * vector_j_;
     if (d == 0)
         return null;
     else
         return strip_line_i.Point + vector_i * ((strip_line_j.Point - strip_line_i.Point) * vector_j_ / d);
 } // !!Проверить!!
コード例 #3
0
ファイル: PlacingOpt.cs プロジェクト: Ring-r/opt
        public PlacingOpt(PolygonWithMinMax[] polygons, Vector2d strip_vector)
        {
            this.polygons = polygons;
            this.strip_vector = strip_vector;

            int n = polygons.Length;
            X = new double[2 * n + 1];
            Gs = new double[4 * n + n * (n - 1) / 2][];
            for (int i = 0; i < Gs.Length; i++)
                Gs[i] = new double[10];

            index_strip = 2 * n;
        }
コード例 #4
0
ファイル: Vector2d.cs プロジェクト: Ring-r/opt
 /// <summary>
 /// Вычесть вектор из текущего.
 /// </summary>
 /// <param name="vector">Вектор.</param>
 public void _Deduct(Vector2d vector)
 {
     this.x -= vector.x;
     this.y -= vector.y;
 }
コード例 #5
0
ファイル: Vector2d.cs プロジェクト: Ring-r/opt
 /// <summary>
 /// Добавить вектор к текущему.
 /// </summary>
 /// <param name="vector">Вектор.</param>
 public void _Add(Vector2d vector)
 {
     this.x += vector.x;
     this.y += vector.y;
 }
コード例 #6
0
ファイル: MainWindow.xaml.cs プロジェクト: Ring-r/opt
        /// <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();
        }
コード例 #7
0
ファイル: Placing.cs プロジェクト: Ring-r/opt
        /// <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);
        }
コード例 #8
0
ファイル: FormMain.cs プロジェクト: Ring-r/opt
 public static void FillAndDraw(this Plane2d plane, System.Drawing.Graphics graphics, System.Drawing.Color color_brush, System.Drawing.Color color_pen)
 {
     //graphics.FillEllipse(new System.Drawing.SolidBrush(color_brush), (float)(circle.Pole.X - circle.R), (float)(circle.Pole.Y - circle.R), (float)(2 * circle.R), (float)(2 * circle.R));
     Vector2d vector = new Vector2d() { X = -plane.Normal.Y, Y = plane.Normal.X };
     Point2d point_prev = plane.Pole - vector * 1000;
     Point2d point_next = plane.Pole + vector * 1000;
     graphics.DrawLine(new System.Drawing.Pen(color_pen), (float)(point_prev.X), (float)(point_prev.Y), (float)(point_next.X), (float)(point_next.Y));
 }
コード例 #9
0
ファイル: Placement.cs プロジェクト: Ring-r/opt
 protected Placement()
 {
     region_size = new Vector2d();
 }
コード例 #10
0
ファイル: Placement.cs プロジェクト: Ring-r/opt
 private bool CheckIntersectBetweenRectangles(Point2d point_i, Vector2d size_i, Point2d point_j, Vector2d size_j)
 {
     double eps = 1e-4f;
     return
         point_i.X + size_i.X <= point_j.X + eps ||
         point_i.Y + size_i.Y <= point_j.Y + eps ||
         point_j.X + size_j.X <= point_i.X + eps ||
         point_j.Y + size_j.Y <= point_i.Y + eps;
 }
コード例 #11
0
ファイル: Placement.cs プロジェクト: Ring-r/opt
 private bool CheckIntersectWithRectangles(Point2d point, Vector2d size)
 {
     bool without_intersect = true;
     for (int i = 0; i < objects_busy_numbers.Count && without_intersect; i++)
         without_intersect = without_intersect && CheckIntersectBetweenRectangles(point, size, objects_busy_points[i], objects_sizes[objects_busy_numbers[i]]);
     return without_intersect;
 }
コード例 #12
0
ファイル: Placement.cs プロジェクト: Ring-r/opt
 private bool CheckIntersectWithRegion(Point2d point, Vector2d size)
 {
     double eps = 1e-4f;
     return point.X + size.X <= task.RegionWidth + eps && point.Y + size.Y <= task.RegionHeight + eps;
 }
コード例 #13
0
ファイル: Task.cs プロジェクト: Ring-r/opt
 public void ObjectsSizesAdd(int index, Vector2d object_size)
 {
     objects_sizes.Insert(index, object_size);
     Initialize();
 }