Beispiel #1
0
 //Функция найдет и удалит указанную связь из списка
 static Boolean delete_exist_line(Connection _con, List<Connection> _cons)
 {
     Boolean result = false;
     int i = _cons.Count - 1;
     if (i >= 0) do
         {
             if ((_con.p1 == _cons[i].p1 && _con.p2 == _cons[i].p2) || (_con.p1 == _cons[i].p2 && _con.p2 == _cons[i].p1))
             {
                 result = true;
                 _cons.RemoveAt(i);
             }
             i--;
         } while (result == false && i >= 0);
     return result;
 }
Beispiel #2
0
        //Функция начертит граф
        static void print_graph(Graph _g, Connection _cr_con, Connection _path, PictureBox _paint)
        {
            Bitmap bmp = new Bitmap(_paint.Width, _paint.Height);
            Graphics _gr = Graphics.FromImage(bmp);

            _gr.Clear(Color.White);
            foreach (S_point _p in _g.Nodes)
            {
                _gr.FillEllipse(Brushes.Black, _p.pnt.X - 4, _p.pnt.Y - 4, 8, 8);
                _gr.DrawString(_p.name, new Font("Arial", 8), Brushes.Black, _p.pnt.X-6, _p.pnt.Y + 8);
            }
            foreach(Connection _c in _g.Lines)
                _gr.DrawLine(new Pen(Color.Black), _c.p1, _c.p2);
            if (_cr_con.p1 != new Point(0, 0)) _gr.DrawEllipse(new Pen(Color.Turquoise),_cr_con.p1.X-8, _cr_con.p1.Y-8, 16, 16);
            if (_path.p1 != new Point(0, 0)) _gr.DrawEllipse(new Pen(Color.Red), _path.p1.X - 8, _path.p1.Y - 8, 16, 16);
            if (_path.p2 != new Point(0, 0)) _gr.DrawEllipse(new Pen(Color.Red), _path.p2.X - 8, _path.p2.Y - 8, 16, 16);

            _paint.Image = bmp;
        }
Beispiel #3
0
 /*
  * Обработка клика мышкой по полю для рисования, выполняет различные действия в зависимости от режима
  * в режиме point проставляет по клику ноды
  * в режиме line создает связи между нодами
  * в режиме path устанавливает точки, между которыми будет рассчитываться кратчайший путь
  */
 private void Canvas_MouseClick(object sender, MouseEventArgs e)
 {
     S_point pnt = new S_point(new Point(e.X, e.Y),0,point_name_man.Text);
     switch ((Canvas.Tag as String))
     {
         case "point":
             S_point p = delete_exist_point(pnt.pnt, grph.Nodes);
             if (p == null)
             {
                 grph.Nodes.Add(pnt);
                 point_name_man.Text = "";
             }
             else delete_node(p, grph.Lines);
             break;
         case "line":
             int i=0;
             if (grph.Nodes.Count > 1)
             {
                 do
                 {
                     if (check_point(pnt.pnt, grph.Nodes[i].pnt)) pnt = grph.Nodes[i];
                     i++;
                 } while (i < grph.Nodes.Count && pnt != grph.Nodes[i - 1]);
                 if (pnt != grph.Nodes[i - 1]) break;
                 if (cr_con.p1 == new Point(0, 0)) cr_con.p1 = pnt.pnt;
                 else
                 {
                     if (cr_con.p1 == pnt.pnt) cr_con.p1 = new Point(0, 0);
                     else
                     {
                         cr_con.p2 = pnt.pnt;
                         cr_con.cost = calc_cost(cr_con.p1, cr_con.p2);
                         if (!delete_exist_line(cr_con, grph.Lines)) grph.Lines.Add(cr_con);
                         cr_con = new Connection(new Point(0, 0), new Point(0, 0), 0);
                     }
                 }
             }
             else System.Windows.Forms.MessageBox.Show("Ошибка:\n" + "Перед созданием граней создайте хотя бы 2 вершины графа.", "",
                       MessageBoxButtons.OK,
                       MessageBoxIcon.Error);
             break;
         case "path":
             i = 0;
             if (grph.Nodes.Count > 1)
             {
                 do
                 {
                     p = grph.Nodes[i];
                     i++;
                     if (check_point(p.pnt, pnt.pnt)) pnt = p;
                 } while (pnt != p && i < grph.Nodes.Count);
                 if (p == pnt)
                     if (start_end.p1 == pnt.pnt || start_end.p2 == pnt.pnt)
                     {
                         if (start_end.p1 == pnt.pnt) start_end.p1 = new Point(0, 0);
                         else start_end.p2 = new Point(0, 0);
                     }
                     else
                         if (start_end.p1 == new Point(0, 0)) start_end.p1 = pnt.pnt;
                         else if (start_end.p2 == new Point(0, 0)) start_end.p2 = pnt.pnt;
             }
             else System.Windows.Forms.MessageBox.Show("Ошибка:\n" + "Перед этим действием нужно создать хотя бы 2 вершины.", "",
                       MessageBoxButtons.OK,
                       MessageBoxIcon.Error);
             break;
     }
     print_graph(grph, cr_con, start_end, Canvas);
 }
Beispiel #4
0
        //Исследуемый граф
        //Функция поиска кратчайшего пути, возвращает грани, которые можно вывести на экран
        static List<Connection> get_path(
                                        Connection _start_end, //Начальная и конечная точки
                                        Graph _g)
        {
            //Список вершин графа со стоимостью
            List<S_point> ch_pnts = new List<S_point>();
            foreach (S_point p in _g.Nodes) ch_pnts.Add(new S_point(p.pnt,0,p.name));

            List<Connection> result = new List<Connection>();
            double fin_cost = 0;

            //Сформируем начальный путь
            snake first = new snake(get_pathes(_start_end.p1, _g.Lines), 0);
            first.head = _start_end.p1;
            List<snake> snakes = new List<snake>();
            snakes.Add(first);
            /*
             * Цикл формирует все возможные пути. Когда будет найден первый путь до конечной точки, будет назначена цена пути.
             * Оставшиеся пути будут продолжать формироваться до тех пор, пока стоимость каждого из них не превысит
             * стоимость уже найденного пути.
             */
            do {
                int i = snakes.Count-1;
                if (snakes.Count > 0)
                do {
                    int j = snakes[i].pathes.Count-1;
                    if (snakes[i].pathes.Count>0)
                    do {
                        Point cur_pnt = new Point();
                        double tmp_cost = snakes[i].cost + snakes[i].pathes[j].cost;
                        if (snakes[i].pathes[j].p1 == snakes[i].head) cur_pnt = snakes[i].pathes[j].p2; else cur_pnt = snakes[i].pathes[j].p1;

                        if ((get_s_point(cur_pnt, ch_pnts).cost > tmp_cost || get_s_point(cur_pnt, ch_pnts).cost == 0) && (tmp_cost<fin_cost || fin_cost==0))
                        {
                            if (cur_pnt == _start_end.p2 && (fin_cost > tmp_cost || fin_cost==0))
                            {
                                fin_cost = tmp_cost;
                                result = snakes[i].body;
                                result.Add(snakes[i].pathes[j]);
                            }
                            else

                                if (cur_pnt != snakes[i].neck)
                                {
                                    snake tmp_snake = new snake(get_pathes(cur_pnt, _g.Lines), tmp_cost);
                                    foreach (Connection c in snakes[i].body) tmp_snake.body.Add(c);
                                    tmp_snake.body.Add(snakes[i].pathes[j]);
                                    tmp_snake.neck = snakes[i].head;
                                    tmp_snake.head = cur_pnt;
                                    set_s_point_cost(cur_pnt, tmp_cost, ch_pnts);
                                    snakes.Add(tmp_snake);
                                }
                        }
                        snakes[i].pathes.RemoveAt(j);
                        j--;
                    } while(j>=0);
                    snakes.RemoveAt(i);
                    i--;
                } while(i>=0);

            } while (snakes.Count!=0);
            return result;
        }