//Функция начертит граф 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; }
private void загрузитьИзФайлаToolStripMenuItem_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = "grph-files (*.grp)|*.grp"; if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK && ofd.FileName.Length > 0) { BinaryFormatter formatter = new BinaryFormatter(); FileStream inputStream = File.OpenRead(ofd.FileName); try { grph = (Graph)formatter.Deserialize(inputStream); } catch (Exception ex) { System.Windows.Forms.MessageBox.Show("Ошибка:\n" + ex.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Error); } inputStream.Close(); } print_graph(grph, cr_con, start_end, Canvas); }
//Исследуемый граф //Функция поиска кратчайшего пути, возвращает грани, которые можно вывести на экран 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; }