/// <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> /// 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> /// 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> /// 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)); }