Beispiel #1
0
        //Adds to the list
        public void Add(Node b)
        {
            currentFrontier.Add(b);

            //BUBBLE SORT! kinda... Default sorting for list is quicksort
            //which was causing a HUGE performance reduction for only one
            //element out of the list
            for (int x = 1; x < currentFrontier.Count; x++)
            {
                if(currentFrontier[x - 1] > currentFrontier[x])
                {
                    Node temp = currentFrontier[x - 1];
                    currentFrontier[x - 1] = currentFrontier[x];
                    currentFrontier[x] = temp;
                }
            }

            if (currentFrontier.Count > max_size)
                 max_size = currentFrontier.Count;
        }
Beispiel #2
0
 /// <summary>
 /// Tranverses upwards and adds to the list
 /// </summary>
 /// <param name="end"></param>
 /// <returns></returns>
 public static List<Node> pathReconstruction(Node end)
 {
     List<Node> path = new List<Node>();
     Node walker = end;
     while (walker != null)
     {
         path.Add(walker);
         walker = walker.parent;
     }
     return path;
 }
Beispiel #3
0
        /// <summary>
        /// 
        /// Could be easily divided up into four sections, but makes more sense to be one in c#
        /// 
        /// </summary>
        /// <param name="passedNode"></param>
        public static bool generateChildren(Node passedNode){

            Node currentNode = passedNode;
            bool addedNode = false;

            //Valid Directions
            bool up = false;
            bool down = false;
            bool left = false;
            bool right = false;

            if (currentNode.rowVal < (MAX_ROW - 1))
                down = true;
            if (currentNode.colVal < (MAX_COL - 1))
                right = true;
            if (currentNode.rowVal > 0)
                up = true;
            if (currentNode.colVal > 0)
                left = true;

            //These are pretty uniform
            //Creates a new state, Node, assigns values, and adds to the frontier
            if(left == true){
                int[,] newArr = currentNode.copyPuzzle();
                newArr[currentNode.colVal, currentNode.rowVal] = newArr[(currentNode.colVal - 1), currentNode.rowVal];
                newArr[(currentNode.colVal - 1), currentNode.rowVal] = 0;
                Node newNode = new Node(newArr, (currentNode.colVal - 1), currentNode.rowVal, calculateHeuristic(newArr), (currentNode.cValue + 1),  "GO-LEFT");
                if(!listContainsArray(closedList, newArr))
                {
                    addedNode = true;
                    generatedNodes++;
                    newNode.parent = currentNode;
                    frontier.Add(newNode);
                    closedList.Add(newArr);
                }
            }
            if(right == true){
                int[,] newArr = currentNode.copyPuzzle();
                newArr[currentNode.colVal, currentNode.rowVal] = newArr[(currentNode.colVal + 1), currentNode.rowVal];
                newArr[(currentNode.colVal + 1), currentNode.rowVal] = 0;
                Node newNode = new Node(newArr, (currentNode.colVal + 1), currentNode.rowVal, calculateHeuristic(newArr), (currentNode.cValue + 1), "GO-RIGHT");
                if (!listContainsArray(closedList, newArr))
                {
                    addedNode = true;
                    generatedNodes++;
                    newNode.parent = currentNode;
                    frontier.Add(newNode);
                    closedList.Add(newArr);
                }
            }
            if(up == true){
                int [,] newArr = currentNode.copyPuzzle();
                newArr[currentNode.colVal, currentNode.rowVal] = newArr[currentNode.colVal, (currentNode.rowVal - 1)];
                newArr[currentNode.colVal, (currentNode.rowVal - 1)] = 0;
                Node newNode = new Node(newArr, currentNode.colVal, (currentNode.rowVal - 1), calculateHeuristic(newArr), (currentNode.cValue + 1), "GO-UP");
                if (!listContainsArray(closedList, newArr))
                {
                    addedNode = true;
                    generatedNodes++;
                    newNode.parent = currentNode;
                    frontier.Add(newNode);
                    closedList.Add(newArr);
                }
            }
            if (down == true)
            {
                int[,] newArr = currentNode.copyPuzzle();
                newArr[currentNode.colVal, currentNode.rowVal] = newArr[currentNode.colVal, (currentNode.rowVal + 1)];
                newArr[currentNode.colVal, (currentNode.rowVal + 1)] = 0;
                Node newNode = new Node(newArr, currentNode.colVal, (currentNode.rowVal + 1), calculateHeuristic(newArr), (currentNode.cValue + 1), "GO-DOWN");
                if (!listContainsArray(closedList, newArr))
                {
                    addedNode = true;
                    generatedNodes++;
                    newNode.parent = currentNode;
                    frontier.Add(newNode);
                    closedList.Add(newArr);
                }
            }

            return addedNode;
        }
Beispiel #4
0
        /// <summary>
        /// ***As far as I know you cant pass in a function call as a parameter, so I improvised***
        /// 
        /// The heuristic mode is gathered from the global variable "heuristicMode"
        /// The nodes are gathered from the global 2d array "puzValues & goalState"
        /// children function cant be passed in
        /// the f-value function is part of the Node
        /// 
        /// </summary>
        public static void a_StarSearch() {

            //If solved, dont attempt again
            if (solved)
            {
                Console.WriteLine("Puzzle has already been solved. Select new configuration to solve.");
                return;
            }

            //Check to see if we have solved this puzzle configuration
            //
            //Pseudo-Pattern Database, didnt want to check in actual 
            //foreach (List<Node> ln in solvedPuzzleStates)
            //{
            //    Node temp = ln[0];
            //    if (temp.stateEquality(puzValues))
            //    {
            //        Console.WriteLine("Configuration already solved.");
            //        foreach (Node nd in ln)
            //        {
            //            nd.printStructure();
            //        }
            //        Console.WriteLine();
            //        return;
            //    }
            //}
            

            //Configure initial node/state
            Node startingState = new Node(puzValues, Col , Row, calculateHeuristic(puzValues), 0, "INITIAL-STATE");
            frontier.Add(startingState);

            //Members for tracking stats and movement
            int Expansions = 0;
            int Cost = 0;
            int F_Val = 0;
            List<Node> path =  new List<Node>();

            Console.WriteLine("Please wait... (The form may freeze while searching the state space)");
            Console.WriteLine();

            //Start timing the actual process
            System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
            timer.Start();
                      
            //Do the work
            while (!frontier.isEmpty())
            {
                Node temp = frontier.removeFromFrontier();

                if (temp.isGoalState(goalState)) {
                    path = pathReconstruction(temp);
                    solved = true;
                    Cost = temp.cValue;
                    F_Val = temp.getF_Val();
                    break;
                }

                if (generateChildren(temp))
                {
                    Expansions++;
                }
                
            }

            timer.Stop();

            //Stores the currently selected heuristic to display
            string Heuristic;
            if (heuristicMode == 0)
                Heuristic = "Manhattan";
            else if (heuristicMode == 1)
                Heuristic = "Misplaced";
            else
                Heuristic = "Breadth-First";

            double abf = (double)generatedNodes/Expansions;
            int Depth = (path.Count - 1);
            if (Depth == -1) Depth = 0; 

            //Stats
            Console.WriteLine("-------------------------------------------------------------------");
            Console.WriteLine("Statistics on the Solution:");
            Console.WriteLine("-------------------------------------------------------------------");
            Console.WriteLine("Heuristic Used: {0}", Heuristic);
            Console.WriteLine("Time Taken to Expand Nodes: {0}", timer.Elapsed);
            Console.WriteLine("Depth: {0}, Cost: {1}", Depth, Cost);
            Console.WriteLine("Number of Expansions: {0}", Expansions);
            Console.WriteLine("Number of children generated: {0}", generatedNodes);
            Console.WriteLine("Total Memory Consumption: {0}", frontier.max_size);
            Console.WriteLine("Average Branching Factor: {0}", abf);
            Console.WriteLine("Effective Branchiing Factor: {0}", Math.Pow(Expansions, (double)1/Depth));
            Console.WriteLine();
            Console.WriteLine("--------------");
            Console.WriteLine("| Path Taken |");
            Console.WriteLine("--------------");
            //Reverse the path, and print out the results!
            solvedPuzzleStates.Add(path);
            path.Reverse();
            foreach (Node nd in path)
            {
                nd.printStructure();
            }
            Console.WriteLine("-------------------------------------------------------------------");
            Console.WriteLine();
        }