private bool FindRouteAttempt(RouteSeachRegion regionPara, RouteFindingData findRouteData) { findRouteData.Init(regionPara.StartPtIndex); var unvisited = new MinHeap <int, double>(); unvisited.Add(regionPara.StartPtIndex, 0.0); while (unvisited.Count > 0) { var current = unvisited.ExtractMin(); if (current.Key == regionPara.EndPtIndex) { return(true); } UpdateNeighbors( current.Key, regionPara, findRouteData, unvisited, current.Value); } return(false); //Route not found. }
/// <summary> /// Finds a route from the waypoint in wptList with /// index startPtIndex, to endPtIndex. /// The two indices must not be identical. /// </summary> /// <exception cref="RouteNotFoundException"></exception> /// <exception cref="ArgumentException"></exception> private Route GetRoute(int startPtIndex, int endPtIndex) { if (startPtIndex == endPtIndex) { throw new ArgumentException("Start point cannot be the same as end point."); } var FindRouteData = new RouteFindingData(wptList.NodeIndexUpperBound + 1); var region = new RouteSeachRegion(wptList, startPtIndex, endPtIndex); // The max distance must be larger than 0. Otherwise this method cannot // find a route from between two different points with distance zero. region.MaxDistanceSum = Math.Max(50.0, region.DirectDistance * 1.25); bool routeFound = false; while (!routeFound && region.MaxDistanceSum <= RouteSeachRegion.MaxPossibleDistanceSum) { routeFound = FindRouteAttempt(region, FindRouteData); region.MaxDistanceSum *= 1.5; } if (routeFound) { return(ExtractRoute(FindRouteData, startPtIndex, endPtIndex)); } throw new RouteNotFoundException( $"No route exists between {wptList[startPtIndex].ID} " + $"and {wptList[endPtIndex].ID}."); }
private bool WptWithinRange(RouteFindingData findRouteData, int wptIndex, RouteSeachRegion region) { var data = findRouteData.WaypointData; if (data[wptIndex].WithInRange == InRange.Unknown) { // Suppose the orig and dest rwys are already in the wptList var p = region; bool inRange = wptList.Distance(p.StartPtIndex, wptIndex) + wptList.Distance(p.EndPtIndex, wptIndex) < p.MaxDistanceSum; data[wptIndex].WithInRange = inRange ? InRange.Yes : InRange.No; } return((int)data[wptIndex].WithInRange == 1); }
private void UpdateNeighbors( int currentWptIndex, RouteSeachRegion regionPara, RouteFindingData findRouteData, MinHeap <int, double> unvisited, double currentDis) { foreach (var edgeIndex in wptList.EdgesFrom(currentWptIndex)) { var wptData = findRouteData.WaypointData; var edge = wptList.GetEdge(edgeIndex); int index = edge.ToNodeIndex; var countryCode = wptList[index].CountryCode; if (WptWithinRange(findRouteData, index, regionPara) && avoidedCountry.Contains(countryCode) == false) { double newDis = currentDis + GetEdgeDistance(edge); if (wptData[index].CurrentDistance == double.PositiveInfinity) { // The node was never touched. unvisited.Add(index, newDis); wptData[index] = new RouteFindingData.WaypointStatus( edge, newDis, InRange.Yes); } else if (unvisited.ContainsKey(index) && newDis < unvisited[index]) { unvisited.ChangeValue(index, newDis); wptData[index] = new RouteFindingData.WaypointStatus( edge, newDis, InRange.Yes); } } } }
/// <summary> /// Finds a route from the waypoint in wptList with /// index startPtIndex, to endPtIndex. /// </summary> /// <exception cref="RouteNotFoundException"></exception> private Route GetRoute(int startPtIndex, int endPtIndex) { var FindRouteData = new RouteFindingData(wptList.NodeIndexUpperBound + 1); var region = new RouteSeachRegion(wptList, startPtIndex, endPtIndex); region.MaxDistanceSum = region.DirectDistance * 1.25; bool routeFound = false; while (!routeFound && region.MaxDistanceSum <= RouteSeachRegion.MaxPossibleDistanceSum) { routeFound = FindRouteAttempt(region, FindRouteData); region.MaxDistanceSum *= 1.5; } if (routeFound) { return(ExtractRoute(FindRouteData, startPtIndex, endPtIndex)); } throw new RouteNotFoundException( $"No route exists between {wptList[startPtIndex].ID} " + $"and {wptList[endPtIndex].ID}."); }