Beispiel #1
0
    /// <summary>
    /// This function returns an object of the class <see cref="Route"/> if
    /// a route exists bewteen the provided locations. Otherwise, NULL is returned.
    /// </summary>
    /// <returns>A <see cref="Route"/> An object describing the shortest path from the start to end location</returns>
    /// <param name="startLoc">The start location in the desired route.</param>
    /// <param name="endLoc">The destination location of the desired route.</param>
    /// <para>
    /// This function uses and A* search to find the shortest route between the two given locations
    /// on the network.
    /// </para>
    protected Route CalculateRoute(Location startLoc, Location endLoc)
    {
        if (startLoc == null || endLoc == null)
        {
            return(null);
        }

        // Already at the location
        Route retRoute;

        if (startLoc.LocID == endLoc.LocID)
        {
            retRoute = new Route();
            return(retRoute);
        }

        Location start;
        Location goal;

        netLocs.TryGetValue(startLoc.LocID, out start);
        netLocs.TryGetValue(endLoc.LocID, out goal);
        if (start == null || goal == null)
        {
            return(null);
        }

        // Make Lists for search
        List <SearchNode> openList   = new List <SearchNode>();
        List <SearchNode> closedList = new List <SearchNode>();

        // Place starting node in open list list
        openList.Add(new SearchNode(start, null, 0, calculateDistance(start, goal)));

        SearchNode curSearchNode;
        SearchNode goalSearchNode = null;

        while (true)
        {
            //Exit upon empty openList
            if (openList.Count == 0)
            {
                break;
            }

            // Sort openList and choose lowest F
            openList.Sort();

            // Take lowest F in openList and move to closedList
            curSearchNode = openList[0];
            openList.RemoveAt(0);
            closedList.Add(curSearchNode);

            // Check for goal node
            if (curSearchNode.Equals(goal))
            {
                goalSearchNode = curSearchNode;
                break;
            }


            // Add connected nodes to open list if not already listed in closedList, update if on openList
            foreach (Location location in curSearchNode.location)
            {
                bool found = false;

                // Ignore node if on closed list
                foreach (SearchNode searchNode in closedList)
                {
                    if (searchNode.Equals(location))
                    {
                        found = true;
                        break;
                    }
                }

                if (found)
                {
                    continue;
                }

                // Potentially update SearchNode if it is on the openList and the costToNode is less
                foreach (SearchNode searchNode in openList)
                {
                    if (searchNode.Equals(location))
                    {
                        // Compare costToNode, update parent if node has lower cost
                        float newCostToNode = curSearchNode.costToNode + calculateDistance(curSearchNode.location, location);
                        if (newCostToNode < searchNode.costToNode)
                        {
                            searchNode.parentSearchNode = curSearchNode;
                            searchNode.costToNode       = newCostToNode;
                        }

                        found = true;
                        break;
                    }
                }

                if (found)
                {
                    continue;
                }

                openList.Add(new SearchNode(location, curSearchNode, curSearchNode.costToNode + calculateDistance(curSearchNode.location, location), calculateDistance(location, goal)));
            }
        }

        if (goalSearchNode == null)
        {
            return(null);
        }

        // Make a route if the final NodeWrap, a route from start to goal, was found
        retRoute = new Route();
        SearchNode parent = goalSearchNode;

        // Create route from goal to start
        while (parent != null)
        {
            retRoute.AddLocation(parent.location);
            parent = parent.parentSearchNode;
        }

        // Reverse route becuase it was created from goal to start then lock it
        retRoute.Reverse();
        retRoute.Lock();

        return(retRoute);
    }