Пример #1
0
        public SearchResults Search(HexagonalTileSearchProblem Problem, uint DepthLimit)
        {
            Queue <Tuple <MapTile, uint> > Frontier;
            Dictionary <MapTile, MapTile>  Paths;
            Dictionary <MapTile, bool>     Explored;

            SearchResults r = new SearchResults();

            if (Problem == null)
            {
                return(r);
            }

            Frontier = new Queue <Tuple <MapTile, uint> >();
            Frontier.Enqueue(new Tuple <MapTile, uint>(Problem.Start, DepthLimit));

            //Storage of the Search Tiles mapped to the Tile that Led to Their Discovery.
            Paths = new Dictionary <MapTile, MapTile>();

            Explored = new Dictionary <MapTile, bool>((int)Problem.SearchSpace.Size);
            foreach (MapTile mt in Problem.SearchSpace.XYTiles())
            {
                Explored.Add(mt, false);
            }

            /* **** SEARCH ****** */
            MapTile  current = null;
            uint     currentDepth;
            DateTime start_time = DateTime.Now;

            while (Frontier.Count != 0)
            {
                if (Frontier.Count > r.SpaceComplexity)
                {
                    //We have a new maxmim number of nodes.
                    r.SpaceComplexity = Frontier.Count;
                }

                current           = Frontier.Peek().Item1;
                currentDepth      = Frontier.Dequeue().Item2;
                Explored[current] = true; //Set the current node as explore.
                r.TimeComplexity++;       //We have explored another node.

                //SUCCESS!
                if (current == Problem.Goal)
                {
                    r.Solved = true;
                    break;
                }

                if (currentDepth == 0)
                {
                    //We have reached the limit we are allowed to search on this branch.
                    break;
                }

                foreach (MapTile mt in current.GetNeighbours())
                {
                    if (Frontier.FirstOrDefault(p => p.Item1 == mt) == null && Explored[mt] == false)
                    {
                        try
                        {
                            Paths.Add(mt, current);
                        }
                        catch (ArgumentException)
                        {
                            Paths[mt] = current;
                        }
                        Frontier.Enqueue(new Tuple <MapTile, uint>(mt, currentDepth - 1));
                    }
                }
            }
            DateTime end_time = DateTime.Now;

            r.TimeInMilliseconds = (int)(end_time - start_time).TotalMilliseconds;

            //If we found a solution, find the path we actually discovered.
            if (r.Solved)
            {
                r.Path = SearchHelper.GetPathFromStart(current, Paths, Problem.Start);
            }

            Log.Info(string.Format("BFS: Search Complete - Solution {0}", r.Solved ? "Found" : "Not Found"));
            return(r);
        }
Пример #2
0
        public SearchResults Search(HexagonalTileSearchProblem Problem)
        {
            /* ----- SETUP ----- */
            SearchResults r = new SearchResults();

            if (Problem == null)
            {
                return(r);
            }

            Dictionary <MapTile, MapTile> Paths = new Dictionary <MapTile, MapTile>();

            Dictionary <MapTile, bool> Explored = new Dictionary <MapTile, bool>((int)Problem.SearchSpace.Size);

            foreach (MapTile mt in Problem.SearchSpace.XYTiles())
            {
                Explored.Add(mt, false);
            }

            hSortedList <double, MapTile> Available = new hSortedList <double, MapTile>();

            Available.Add(0, Problem.Start);

            /* ----- SEARCH ----- */

            /* A Star works by evaluating potential paths based on an estimate of
             * there overall path cost to the goal. This is computed as the existing cost
             * from the start to the node, based on the known cost to the current node, and the
             * length of the edge , plus its estimated distance to the goal. If a node has been observed
             * before, or is part of a path already established, the cost via the new route is compared with
             * that of the old, and if cheaper, will be used in placed of the old. In this fashion, the algo is
             * always capable of finding the best route through a graph, but has a fair amount of overhead. */
            MapTile  current = null;
            int      current_cost;
            DateTime start_time = DateTime.Now;

            while (Available.Count != 0)
            {
                if (Available.Count > r.SpaceComplexity)
                {
                    r.SpaceComplexity = Available.Count;
                }

                current      = Available.Pop();
                current_cost = SearchHelper.GetPathLengthFromStart(current, Paths, Problem.Start);

                r.TimeComplexity++;

                Explored[current] = true;

                //If we have recieved the destination, we have completed the search.
                if (current == Problem.Goal)
                {
                    r.Solved = true;
                    break;
                }

                //If we have not found the destination, catalog the available operations
                //from this mapTile.
                foreach (MapTile mt in current.GetNeighbours())
                {
                    if (Explored[mt] == false)
                    {
                        //We have not previously seen this location.
                        if (!Paths.ContainsKey(mt))
                        {
                            Paths.Add(mt, current);
                            Available.Add(
                                current_cost + 1 //All nodes have a distance of one from their neighbour
                                + Heuristic.Calculate(mt, Problem.Goal),
                                mt);
                        }
                        else
                        {
                            int     old_cost  = SearchHelper.GetPathLengthFromStart(mt, Paths, Problem.Start);
                            MapTile oldParent = Paths[mt];
                            Paths[mt] = current;
                            int new_cost = SearchHelper.GetPathLengthFromStart(mt, Paths, Problem.Start);

                            //If the new cost to the tile is more than our previous
                            //path to this tile, we want to keep our previous parent assignment
                            if (new_cost > old_cost)
                            {
                                Paths[mt] = oldParent;
                            }
                            else
                            {
                                Available.Add(
                                    current_cost + 1 +
                                    Heuristic.Calculate(mt, Problem.Goal),
                                    mt);
                            }
                        }
                    }
                }
            }
            DateTime end_time = DateTime.Now;

            r.TimeInMilliseconds = (int)(end_time - start_time).TotalMilliseconds;

            /* ----- BACKTRACK PATH GENERATION ----- */
            if (r.Solved)
            {
                r.Path = SearchHelper.GetPathFromStart(current, Paths, Problem.Start);
            }

            return(r);
        }
Пример #3
0
        public SearchResults Search(HexagonalTileSearchProblem Problem)
        {
            SearchResults r = new SearchResults();

            if (Problem == null)
            {
                return(r);
            }

            Dictionary <MapTile, MapTile> Paths = new Dictionary <MapTile, MapTile>();

            Dictionary <MapTile, bool> Explored = new Dictionary <MapTile, bool>((int)Problem.SearchSpace.Size);

            foreach (MapTile mt in Problem.SearchSpace.XYTiles())
            {
                Explored.Add(mt, false);
            }

            hSortedList <double, MapTile> Available = new hSortedList <double, MapTile>();

            Available.Add(0, Problem.Start);

            /* ***** SEARCH ************ */

            /* In the best first search approach, each node is evaluated based
             * on an estimation of its distance from the goal. In a fashion similar
             * to the A* search, if a node has been view before, or is part of a path,
             * costs are compared and the cheaper used. */
            MapTile  current    = null;
            DateTime start_time = DateTime.Now;

            while (Available.Count != 0)
            {
                if (Available.Count > r.SpaceComplexity)
                {
                    r.SpaceComplexity = Available.Count;
                }

                current = Available.Pop();
                r.TimeComplexity++;

                Explored[current] = true;

                //If we have recieved the destination, we have completed the search.
                if (current == Problem.Goal)
                {
                    r.Solved = true;
                    break;
                }

                //If we have not found the destination, catalog the available operations
                //from this mapTile.
                foreach (MapTile mt in current.GetNeighbours())
                {
                    if (Explored[mt] == false)
                    {
                        if (!Paths.ContainsKey(mt))
                        {
                            Paths[mt] = current;
                            Available.Add(
                                Heuristic.Calculate(mt, Problem.Goal),
                                mt);
                        }
                        else
                        {
                            int     old_cost  = SearchHelper.GetPathLengthFromStart(mt, Paths, Problem.Start);
                            MapTile oldParent = Paths[mt];
                            Paths[mt] = current;
                            int new_cost = SearchHelper.GetPathLengthFromStart(mt, Paths, Problem.Start);
                            //If the new cost to the tile is more than our previous
                            //path to this tile, we want to keep our previous parent.
                            if (new_cost > old_cost)
                            {
                                Paths[mt] = oldParent;
                            }
                            else
                            {
                                Available.Add(
                                    Heuristic.Calculate(mt, Problem.Goal),
                                    mt);
                            }
                        }
                    }
                }
            }

            DateTime end_time = DateTime.Now;

            r.TimeInMilliseconds = (int)(end_time - start_time).TotalMilliseconds;

            /* Backtrack for find path */
            if (r.Solved)
            {
                r.Path = SearchHelper.GetPathFromStart(current, Paths, Problem.Start);
            }

            return(r);
        }