Beispiel #1
0
        /// <summary>
        /// This function search the optimal path in graph using
        /// Astar algorithm.
        /// </summary>
        /// <param name="graph">Graph to search</param>
        /// <param name="start">Starting node for search</param>
        /// <param name="end">Goal node</param>
        /// <param name="heuristic">Heuristic use for search</param>
        public void pathfindAStar(Graph graph, Node start, Node end)
        {
            // Initialize the record for the start node
            NodeRecord startRecord = new NodeRecord();
            startRecord.node = start;
            startRecord.connection = null;
            startRecord.costSoFar = 0;
            startRecord.estimateTotalCost = Heuristic.Estimate(start);

            // Initialize the open and closed lists
            open = PathfindingList();
            open.Add(startRecord);
            closed = PathfindingList();

            // Iterate through processing each node
            while (open.Count > 0)
            {
                // Find the smallest element in the open list
                // using (estimatedTotalCost)
                current = open.Find(smallest);

                // if it is the goal node, then terminate
                if (current.node == end) { break; }
                // Otherwise get its outgoing connections
                ArrayList connections = graph.getConnections(current);

                // Loop through each connection in turn
                foreach (Object conn in connections)
                {
                    Connection connection = ((Connection)conn);
                    // get the cost estimate for the end node
                    endNode = connection.getToNode;
                    endNodeCost = current.costSoFar +
                        connection.Cost;

                    // if the node is closed we may have to
                    // skip, or remove it from the closed list.
                    if (closed.Contains(endNode))
                    {
                        // Here we find the record in the closed list
                        // corresponding to the endNode.
                        NodeRecord endNodeRecord = closed.Find(endNode);

                        // if we didn't find a shorter route, skip
                        if (endNodeRecord.costSoFar <= endNodeCost)
                        {
                            continue;
                        }

                        // otherwise remove it from the closed list
                        closed.Remove(endNodeRecord);

                        // We can use the node's old cost values
                        // to calculate its heuristic without calling
                        // the possibly expensive heuristic function
                        endNodeHeuristic = endNodeRecord.cost - endNodeRecord.costSoFar;

                        // Skip if the node is open and we've not
                        // found a better route
                    }
                    else if (open.Contains(endNode))
                    {
                        // Here we find the record in the open list
                        // corresponding to the endNode.
                        endNodeRecord = open.Find(endNode);

                        // if our route is no better, then skip
                        if (endNodeRecord.costSoFar <= endNodeCost)
                        {
                            continue;
                        }
                        // We can use the node's old cost values
                        // to calculate its heuristic without calling
                        // the possibly expensive heuristic function.
                        endNodeHeuristic = endNodeRecord.cost - endNodeRecord.costSoFar;
                        // Otherwise we know we've got an unvisited
                        // node, so make a record for it.
                    }
                    else
                    {
                        endNodeRecord = new NodeRecord();
                        endNodeRecord.node = endNode;

                        // We'll need to calculated the heuristic value
                        // using the function, since we don't have an
                        // existing record to use
                        endNodeHeuristic = heuristic.estimate(endNode);
                    }
                    // We're here if we need to update the node
                    // update the cost, estimate and connection
                    endNodeRecord.cost = endNodeCost;
                    endNodeRecord.connection = conn;
                    endNodeRecord.estimatedTotalCost =
                        endNodeCost + endNodeHeuristic;

                    // And add it to the open list
                    if (!open.Contains(endNode))
                    {
                        open.Add(endNodeRecord);
                    }
                    // We have finished looking at the connections for
                    // current node, so add it to the closed list
                    // and remove it from the open list
                    open.Remove(current);
                    closed.Add(current);
                }
                // We're here if we've either found the goal, or
                // if we've no more nodes to search, find which.
                if (current.node != goal)
                {
                    // we've run out of nodes without finding the
                    // goal, so there is no solution
                    return null;
                }
                else
                {
                    // compile the list of connections in the path
                    List<NodeRecord> path = new List<NodeRecord>();

                    // work along the path, accumulating
                    // connections
                    while (current.node != start)
                    {
                        path.Add(current);
                        current = current.connection.getFromNode();
                    }
                    // reverse the path and return it
                    return path.Reverse();
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// This function implements path finding on the graph
        /// using Dijkstra algorithm. This is not good algorithm
        /// for finding path in the game, but it can be use to
        /// analyze different paths on the complex maps.
        /// </summary>
        /// <param name="graph">graph which represent game level</param>
        /// <param name="start">starting node in graph</param>
        /// <param name="goal">goal node in graph</param>
        public List<NodeRecord> pathfindDijkstra(Graph graph, Node start, Node goal)
        {
            // Initialize the record for the start node
            NodeRecord endNodeRecord;
            NodeRecord startRecord = new NodeRecord();
            startRecord.node = start;
            startRecord.connection = null;
            startRecord.costSoFar = 0.0f;

            float endNodeCost = 0.0f;

            // Initialize the open and closed lists
            open = PathfindingList();
            open.Add(startRecord);
            closed = PathfindingList();

            // Iterate through processing each node
            while (open.Count > 0)
            {
                // Find the smallest element in the list
                NodeRecord current = open.Find(smallest);

                // If it is the goal node, then terminate
                if (current.node == goal) break;

                // Otherwise get its outgoing connections
                ArrayList connections = graph.getConnections(current.node);

                // Loop through each connection in turn
                foreach (Connection connection in connections)
                {
                    // Get the cost estimate in turn
                    NodeRecord endNode = ((Connection)connection).ToNode;
                    endNodeCost = current.costSoFar + connection.Cost;

                    // Skip if the node is closed
                    if (closed.Contains(endNode))
                    {
                        continue;
                    }
                    // .. or if it is open and we've found a worse
                    // route
                    else if (open.Contains(endNode))
                    {
                        // Here we find the record in the open list
                        // corresponding to the endNode.
                        // endNodeRecord = open.Find(endNode);

                        if (endNode.costSoFar <= endNodeCost)
                            continue;

                    }
                    else
                    {
                        endNodeRecord = new NodeRecord();
                        endNodeRecord.node = endNode;

                        // We're here if we need to update the node
                        // update the cost and connection
                        endNodeRecord.costSoFar = endNodeCost;
                        endNodeRecord.connection = connection;

                        // And add if to the the open list
                        if (!open.Contains(endNode))
                        {
                            open.Add(endNodeRecord);
                        }
                    }
                    // We've finished looking at the connections for
                    // the current node, so add it to the closed list
                    // and remove it from the open list
                    open.Remove(current);
                    closed.Add(current);
                }
                // We've here if we've either found the goal, or
                // if we've no more nodes to search, find which.
                if (current.node != goal)
                {
                    // We've run out of nodes without finding the
                    // goal so there is no solution
                    return null;
                }
                else
                {
                    // compile the list of connections in the path
                    List<NodeRecord> path = new List<NodeRecord>();
                    // Work back along the path, accumulating
                    // connections
                    while (current.node != start)
                    {
                        path.Add(current);
                        current = current.connection.FromNode;
                    }

                    // Reverse the path, and return it
                    return path.Reverse();
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// This function implements ant-algorithm.
        /// We start from node and let ants in all directions
        /// if ant comes at empty field it is his. We measure then 
        /// how far the ant is from start node.
        /// </summary>
        /// <param name="graph">Graph to search</param>
        /// <param name="start">starting point</param>
        /// <param name="end">ending point</param>
        public void pathfindAnt(Graph graph, Node start, Node end)
        {
            List<NodeRecord> actualList;
            List<NodeRecord> newList;

            // Initialize
            NodeRecord currentRecord = new NodeRecord();
            NodeRecord startRecord = new NodeRecord();
            startRecord.node = start;
            startRecord.costSoFar = 0.0f;
            startRecord.connection = null;

            NodeRecord endRecord = new NodeRecord();
            endRecord.node = end;

            // add start record to current list
            actualList.Add(startRecord);

            // Iterate through processing each node
            while (actualList.Count > 0)
            {
                for (int nr; nr < current.Count; nr++)
                {
                    currentRecord = actualList[nr];
                    // get all neighbours from currentRecord
                    ArrayList connections = graph.getConnections(current);
                    foreach (Connection connection in connections)
                    {
                        float cost1 = CostFromTo(currentRecord, connection);
                        float cost2 = currentRecord.costSoFar;
                        if (connection.getCost > cost1 + cost2)
                        {
                            NodeRecord neigh = new NodeRecord();
                            neigh.costSoFar = cost1 + cost2;
                            neigh.connection.FromNode = currentRecord;
                            //((NodeRecord)connection.getToNode()).costSoFar = cost1 + cost2;
                            //connection.getFromNode = currentRecord;
                            // add neigh. to new list
                            newList.Add(neigh);
                        }
                    }
                }
            }
            current = newList;

            // construct the real path
            if (endRecord.costSoFar < float.PositiveInfinity)
            {
                nr = 0;
                List<NodeRecord> path = new List<NodeRecord>();
                path.Add(endRecord);
                while (currentRecord.node != start)
                {
                    nr++;
                    path.Add(currentRecord);
                    currentRecord = currentRecord.connection.getFromNode();
                }
            }
        }