Example #1
0
        public SearchResults Search(HexagonalTileSearchProblem Problem)
        {
            /* ----- SETUP ----- */
            SearchResults r = new SearchResults();

            Dictionary <MapTile, MapTile> Paths = new Dictionary <MapTile, MapTile>();
            DateTime start_time = DateTime.Now;
            /* ----- SEARCH ----- */
            MapTile current      = Problem.Start;
            double  current_cost = Heuristic.Calculate(current, Problem.Goal);

            do
            {
                r.TimeComplexity++;
                /* Find neighour with the lowest h cost */
                MapTile best = null;
                double  cost;
                double  best_cost = 0;
                foreach (MapTile neighbour in current.GetNeighbours())
                {
                    cost = Heuristic.Calculate(neighbour, Problem.Goal);
                    if (cost < current_cost)
                    {
                        best      = neighbour;
                        best_cost = cost;
                    }
                }

                /* No neighbour is better than the current tile, so it */
                if (best == null)
                {
                    break;
                }
                current_cost = best_cost;
                Paths.Add(best, current);
                current = best;
            } while (true);
            DateTime end_time = DateTime.Now;

            r.TimeInMilliseconds = (int)(end_time - start_time).TotalMilliseconds;
            //Regardless of whether we found the goal, we want to path to the
            //local maxima we did find.
            r.Path = SearchHelper.GetPathFromStart(current, Paths, Problem.Start);

            if (current == Problem.Goal)
            {
                r.Solved = true;
            }
            return(r);
        }
Example #2
0
        private static void Run20Tests(Tuple <HexagonalTileSearchProblem, ManualResetEvent, int, int> Param)
        {
            HexagonalTileSearchProblem problem   = Param.Item1;
            ManualResetEvent           doneEvent = Param.Item2;
            int ConfigurationNumber = Param.Item3;
            int TestSequenceNumber  = Param.Item4;
            int RegenPaths          = 5;

            SearchResults[] results = new SearchResults[Algos.Count()];
            for (int i = 0; i < 20; i++, TestSequenceNumber++)
            {
                RegenPaths = 5;
                Log.Status(string.Format("Test({0}) - Generating Problem {1}...", ConfigurationNumber, TestSequenceNumber));
                problem.Reset();
                SearchResults sr = Algos[0].Search(problem);
                while (sr.Solved != true)
                {
                    if (RegenPaths == 0)
                    {
                        Log.Status(string.Format("Test({0}) - Problem {1} Not Solvable, regenerating...", ConfigurationNumber, TestSequenceNumber));
                        problem.Reset();
                        RegenPaths = 5;
                    }
                    else
                    {
                        Log.Status(string.Format("Test({0}) - Reselecting Start/Goal...", ConfigurationNumber, TestSequenceNumber));
                        problem.SelectRandomStartAndGoal();
                    }

                    sr = Algos[0].Search(problem);
                    RegenPaths--;
                }

                Log.Status(string.Format("Test({0} : {1}) - Applying Search Algorithms...", ConfigurationNumber, TestSequenceNumber));
                int a = 0;
                foreach (ISearchAlgorithm al in Algos)
                {
                    results[a] = al.Search(problem);
                    CompleteTests++;
                    Log.Success(string.Format("# {0:000.000}% #", (CompleteTests * 1.0) / TotalTests * 100));
                    a++;
                }
                WriteResultsToCSV(TestSequenceNumber, problem, results);
            }


            doneEvent.Set();
        }
        public SearchResults Search(HexagonalTileSearchProblem Problem)
        {
            //The result we will return from the search.
            SearchResults r = new SearchResults();

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

            //The results of the last iteration.
            SearchResults      lastResult = null;
            BreadthFirstSearch BFS        = new BreadthFirstSearch();

            DateTime start_time = DateTime.Now;
            uint     currentDepthLimit;

            for (currentDepthLimit = 0; currentDepthLimit < Problem.SearchSpace.Size; currentDepthLimit++)
            {
                lastResult = BFS.Search(Problem, currentDepthLimit);

                r.TimeComplexity += lastResult.TimeComplexity;
                if (lastResult.SpaceComplexity > r.SpaceComplexity)
                {
                    r.SpaceComplexity = lastResult.SpaceComplexity;
                }

                if (lastResult.Solved == true)
                {
                    r.Solved = true;
                    break;
                }
            }

            DateTime end_time = DateTime.Now;

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

            if (r.Solved)
            {
                r.Path = new List <Model.MapTile>(lastResult.Path);
            }

            return(r);
        }
Example #4
0
        private static void WriteResultsToCSV(int Prob, HexagonalTileSearchProblem Problem, SearchResults[] Results)
        {
            StringBuilder sb = new StringBuilder(1024);

            sb.AppendFormat("{0},{1},", Prob, Problem.ToString());
            foreach (SearchResults sr in Results)
            {
                sb.AppendFormat("{0},", sr.ToString());
            }
            sb.Append("\n");
            string o = sb.ToString();

            byte[] b = System.Text.Encoding.UTF8.GetBytes(o);
            lock (output)
            {
                output.Write(b, 0, b.Count());
                output.Flush();
            }
        }
Example #5
0
        public SearchResults Search(HexagonalTileSearchProblem Problem, uint DepthLimit)
        {
            SearchResults r = new SearchResults();

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


            Stack <Tuple <MapTile, uint> > Frontier = new Stack <Tuple <MapTile, uint> >();

            Frontier.Push(new Tuple <MapTile, uint>(Problem.Start, DepthLimit));

            //Initialize the Path
            Dictionary <MapTile, MapTile> Paths = new Dictionary <MapTile, MapTile>();

            //Initialize our explored Table.
            Dictionary <MapTile, bool> Explored = new Dictionary <MapTile, bool>((int)Problem.SearchSpace.Size);

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

            MapTile  current = null;
            uint     currentDepth;
            DateTime start_time = DateTime.Now;

            while (Frontier.Count != 0)
            {
                if (Frontier.Count > r.SpaceComplexity)
                {
                    r.SpaceComplexity = Frontier.Count;
                }
                current      = Frontier.Peek().Item1;
                currentDepth = Frontier.Pop().Item2;

                Explored[current] = true;
                r.TimeComplexity++;

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

                if (currentDepth == 0)
                {
                    //If we have hit our limit in depth, we ignore the addition of the
                    //children nodes to our frontier.
                    continue;
                }

                foreach (MapTile mt in current.GetNeighbours())
                {
                    if (Explored[mt] == false)
                    {
                        Frontier.Push(new Tuple <MapTile, uint>(mt, currentDepth - 1));
                        Paths[mt] = current; //Remember which way we came from to reach this tile.
                    }
                }
            }
            DateTime end_time = DateTime.Now;

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

            if (r.Solved)
            {
                r.Path = SearchHelper.GetPathFromStart(current, Paths, Problem.Start);
            }

            Log.Info(string.Format("DFS: Search Complete - Solution {0}", r.Solved ? "Found" : "Not Found"));

            return(r);
        }
Example #6
0
 public SearchResults Search(HexagonalTileSearchProblem Problem)
 {
     return(Search(Problem, uint.MaxValue));
 }
Example #7
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);
        }
Example #8
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);
        }
Example #9
0
        /// <summary>
        /// In this method we run each of our search methods against
        /// 100 random instances of 4 configurations. Each
        /// search algorithm is given the same 100 instances of each configuration
        /// and each instance is first checked to ensure it has a valid path using
        /// BFS.
        /// </summary>
        public static void RunTestSuite()
        {
            DateTime start_time = DateTime.Now;

            output = File.Open("Output.txt", FileMode.Create);
            Log.Success(string.Format("Preparing to Utilize {0} logical processors", THREADS));
            Log.Success("Press enter to begin...");
            Console.ReadLine();

            HexagonalTileSearchProblem[] Configs = new HexagonalTileSearchProblem[]
            {
                new HexagonalTileSearchProblem(4, 3, 0.2),
                new HexagonalTileSearchProblem(4, 3, 0.5),
                new HexagonalTileSearchProblem(5, 4, 0.2),
                new HexagonalTileSearchProblem(5, 4, 0.5),
                new HexagonalTileSearchProblem(6, 6, 0.2),
                new HexagonalTileSearchProblem(6, 6, 0.5),

                new HexagonalTileSearchProblem(10, 10, 0.2),
                new HexagonalTileSearchProblem(10, 10, 0.5),
                new HexagonalTileSearchProblem(15, 15, 0.2),
                new HexagonalTileSearchProblem(15, 15, 0.5)
            };


            TotalTests = (uint)Configs.Count() * (uint)Algos.Count() * 100;
            ManualResetEvent[] doneEvents = new ManualResetEvent[Configs.Count() * 5];
            List <Thread>      threads    = new List <Thread>();
            int    i        = 0;
            int    test_num = 0;
            Thread t;

            Tuple <HexagonalTileSearchProblem, ManualResetEvent, int, int> param;

            tasks = new Queue <Tuple <HexagonalTileSearchProblem, ManualResetEvent, int, int> >();

            foreach (HexagonalTileSearchProblem p in Configs)
            {
                for (int x = 0; x < 5; x++)
                {
                    doneEvents[i] = new ManualResetEvent(false);
                    param         = new Tuple <HexagonalTileSearchProblem, ManualResetEvent, int, int>(
                        p.Clone(), doneEvents[i], i++, test_num);
                    tasks.Enqueue(param);
                    test_num += 20;
                }
            }

            for (i = 0; i < THREADS; i++)
            {
                t = new Thread(() =>
                {
                    TaskThread();
                });
                threads.Add(t);
                t.Start();
            }
            WaitHandle.WaitAll(doneEvents);

            Log.Status("Flushing results to file...");
            output.Flush();
            output.Close();

            DateTime end_time = DateTime.Now;

            Log.Status(string.Format("Complete Test Suite executed in {0:0.000} seconds.", (end_time - start_time).TotalMilliseconds / 1000.0));
            Log.Success("All Tests Complete - Press Enter to Exit");
            Console.ReadLine();
        }
Example #10
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);
        }