/// <summary> /// Removes pathes longer than result front and back path respectively from processing list /// </summary> /// <param name="process">Processing path list</param> /// <param name="result">Closed path to compare</param> /// <returns>Filtered processing list</returns> private List <Path> RemoveLongerFrontAndBack(List <Path> process, FrontAndBackPath result) { for (int i = 0; i < process.Count; i++) { if (process[i].Reversed && process[i].Distance > result.BackDistance) { process.RemoveAt(i--); } else if (!process[i].Reversed && process[i].Distance > result.FrontDistance) { process.RemoveAt(i--); } } return(process); }
/// <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> /// Removes pathes longer than result front and back path respectively from processing list /// </summary> /// <param name="process">Processing path list</param> /// <param name="result">Closed path to compare</param> /// <returns>Filtered processing list</returns> private List<Path> RemoveLongerFrontAndBack(List<Path> process, FrontAndBackPath result) { for (int i = 0; i < process.Count; i++) { if (process[i].Reversed && process[i].Distance > result.BackDistance) process.RemoveAt(i--); else if (!process[i].Reversed && process[i].Distance > result.FrontDistance) process.RemoveAt(i--); } return process; }
/// <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); }
/// <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)); }