/// <summary> /// Gets pathes with all adjacent vertices to the "path" last vertex /// </summary> /// <param name="graph">Graph to get data from</param> /// <param name="path">Base path to be continued</param> /// <returns>Pathes with one more last vertex</returns> private List <Path> NextLevel(WeightedGraph graph, Path path) { List <Path> nextLevel = new List <Path>(); if (path.Reversed) { foreach (int next in graph.AdjacentTo(path.Last)) { nextLevel.Add(new Path(path, next, graph.GetDistance(next, path.Last))); } } else { foreach (int next in graph.AdjacentFrom(path.Last)) { nextLevel.Add(new Path(path, next, graph.GetDistance(path.Last, next))); } } return(nextLevel); }
public Path ConnectedPath(WeightedGraph graph) { if (!Connected) { return(null); } Path result = new Path(front[0], false); for (int i = 0; i + 1 < front.Vertices.Count; i++) { if (front.Vertices[i] != commonVertex) { result.Add(front.Vertices[i + 1], graph.GetDistance(front[i], front[i + 1])); } } for (int i = back.Vertices.IndexOf(commonVertex); i > 0; i--) { result.Add(back.Vertices[i - 1], graph.GetDistance(back[i - 1], back[i])); } return(result); }
/// <summary> /// Load graph from file /// </summary> private void toolStripButtonLoadGraph_Click(object sender, EventArgs e) { OpenFileDialog dialog = new OpenFileDialog(); if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { Cursor.Current = Cursors.WaitCursor; graph = new WeightedGraph(); showResult = false; string result = graph.Load(dialog.FileName); if (result != "") { MessageBox.Show(result); } else { nodesLocation = new List <Point>(); pictureBoxGraph.Invalidate(); } Cursor.Current = Cursors.Arrow; } }
public double ConnectedDistance(WeightedGraph graph) { if (!Connected) { return(double.MaxValue); } double result = 0; for (int i = 0; i < front.Vertices.Count; i++) { if (front.Vertices[i] != commonVertex) { result += graph.GetDistance(front.Vertices[i], front.Vertices[i + 1]); } } for (int i = 0; i < back.Vertices.Count; i++) { if (back.Vertices[i] != commonVertex) { result += graph.GetDistance(back.Vertices[i], back.Vertices[i + 1]); } } return(result); }
/// <summary> /// Gets pathes with all adjacent vertices to the "path" last vertex /// </summary> /// <param name="graph">Graph to get data from</param> /// <param name="path">Base path to be continued</param> /// <returns>Pathes with one more last vertex</returns> private List<Path> NextLevel(WeightedGraph graph, Path path) { List<Path> nextLevel = new List<Path>(); if (path.Reversed) { foreach (int next in graph.AdjacentTo(path.Last)) nextLevel.Add(new Path(path, next, graph.GetDistance(next, path.Last))); } else { foreach (int next in graph.AdjacentFrom(path.Last)) nextLevel.Add(new Path(path, next, graph.GetDistance(path.Last, next))); } return nextLevel; }
/// <summary> /// Compares every closed path from table with the currently shortest path and returns the shortest /// </summary> /// <param name="graph">Weights graph</param> /// <param name="tableOfShortest">Path table</param> /// <param name="theShortest">The currently shortest path</param> /// <returns>The shortest path</returns> private FrontAndBackPath FindTheShortestClosedPath(WeightedGraph graph, List<FrontAndBackPath> tableOfShortest, FrontAndBackPath theShortest) { foreach (var current in tableOfShortest) if (current.ConnectedDistance(graph) < theShortest.ConnectedDistance(graph)) theShortest = current; return theShortest; }
/// <summary> /// Searches for the shortest path starting at begin and finishing at end vertex /// </summary> /// <param name="graph">Weights graph</param> /// <param name="begin">Begin vertex index</param> /// <param name="end">End vertex index</param> /// <returns>The shortest path</returns> public Path BidirectionalSearch(WeightedGraph graph, int begin, int end) { // search steps stepByStep.Clear(); // trivial: begin = end if (begin == end) return new Path(begin, end, 0, false); List<FrontAndBackPath> tableOfShortest = new List<FrontAndBackPath>(); // table of the shortest pathes List<Path> process = new List<Path>(); // main processing list FrontAndBackPath result = new FrontAndBackPath(); // result path // add first and last adjacent vertices to the processing list foreach (int adjacent in graph.AdjacentFrom(begin)) process.Add(new Path(begin, adjacent, graph.GetDistance(begin, adjacent), false)); foreach (int adjacent in graph.AdjacentTo(end)) process.Add(new Path(end, adjacent, graph.GetDistance(adjacent, end), true)); // check if process contains wanted path int index = PathIndex(process, begin, end); if (index != -1) return process[index]; while (process.Count != 0) { // get the shortest path and try to add it to the table Path theShortest = Shortest(process); tableOfShortest = AddToTableOfShortestPathes(tableOfShortest, theShortest); process.Remove(theShortest); stepByStep.Add(new Path(theShortest)); // get, filter and add the next level vertices List<Path> nextLevel = NextLevel(graph, theShortest); nextLevel = FilterPathes(process, tableOfShortest, nextLevel); process.AddRange(nextLevel); // check if process contains wanted path index = PathIndex(nextLevel, begin, end); if (index != -1) return nextLevel[index]; // try to find the shortest closed path from begin to end vertex // and exclude longer pathes from the processing list result = FindTheShortestClosedPath(graph, tableOfShortest, result); //if (result.Connected) process = RemoveLongerFrontAndBack(process, result); if (result.Connected) return CheckRemainder(result.ConnectedPath(graph), process); } return result.ConnectedPath(graph); }
public double ConnectedDistance(WeightedGraph graph) { if (!Connected) return double.MaxValue; double result = 0; for (int i = 0; i < front.Vertices.Count; i++) if (front.Vertices[i] != commonVertex) result += graph.GetDistance(front.Vertices[i], front.Vertices[i + 1]); for (int i = 0; i < back.Vertices.Count; i++) if (back.Vertices[i] != commonVertex) result += graph.GetDistance(back.Vertices[i], back.Vertices[i + 1]); return result; }
public Path ConnectedPath(WeightedGraph graph) { if (!Connected) return null; Path result = new Path(front[0], false); for (int i = 0; i + 1 < front.Vertices.Count; i++) if (front.Vertices[i] != commonVertex) result.Add(front.Vertices[i + 1], graph.GetDistance(front[i], front[i + 1])); for (int i = back.Vertices.IndexOf(commonVertex); i > 0; i--) result.Add(back.Vertices[i - 1], graph.GetDistance(back[i - 1], back[i])); return result; }
/// <summary> /// Load graph from file /// </summary> private void toolStripButtonLoadGraph_Click(object sender, EventArgs e) { OpenFileDialog dialog = new OpenFileDialog(); if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { Cursor.Current = Cursors.WaitCursor; graph = new WeightedGraph(); showResult = false; string result = graph.Load(dialog.FileName); if (result != "") MessageBox.Show(result); else { nodesLocation = new List<Point>(); pictureBoxGraph.Invalidate(); } Cursor.Current = Cursors.Arrow; } }
/// <summary> /// Searches for the shortest path starting at begin and finishing at end vertex /// </summary> /// <param name="graph">Weights graph</param> /// <param name="begin">Begin vertex index</param> /// <param name="end">End vertex index</param> /// <returns>The shortest path</returns> public Path BidirectionalSearch(WeightedGraph graph, int begin, int end) { // search steps stepByStep.Clear(); // trivial: begin = end if (begin == end) { return(new Path(begin, end, 0, false)); } List <FrontAndBackPath> tableOfShortest = new List <FrontAndBackPath>(); // table of the shortest pathes List <Path> process = new List <Path>(); // main processing list FrontAndBackPath result = new FrontAndBackPath(); // result path // add first and last adjacent vertices to the processing list foreach (int adjacent in graph.AdjacentFrom(begin)) { process.Add(new Path(begin, adjacent, graph.GetDistance(begin, adjacent), false)); } foreach (int adjacent in graph.AdjacentTo(end)) { process.Add(new Path(end, adjacent, graph.GetDistance(adjacent, end), true)); } // check if process contains wanted path int index = PathIndex(process, begin, end); if (index != -1) { return(process[index]); } while (process.Count != 0) { // get the shortest path and try to add it to the table Path theShortest = Shortest(process); tableOfShortest = AddToTableOfShortestPathes(tableOfShortest, theShortest); process.Remove(theShortest); stepByStep.Add(new Path(theShortest)); // get, filter and add the next level vertices List <Path> nextLevel = NextLevel(graph, theShortest); nextLevel = FilterPathes(process, tableOfShortest, nextLevel); process.AddRange(nextLevel); // check if process contains wanted path index = PathIndex(nextLevel, begin, end); if (index != -1) { return(nextLevel[index]); } // try to find the shortest closed path from begin to end vertex // and exclude longer pathes from the processing list result = FindTheShortestClosedPath(graph, tableOfShortest, result); //if (result.Connected) process = RemoveLongerFrontAndBack(process, result); if (result.Connected) { return(CheckRemainder(result.ConnectedPath(graph), process)); } } return(result.ConnectedPath(graph)); }