Пример #1
0
        /// <summary>
        /// Inserts a node into the priority queue based on Priority value of node
        /// </summary>
        /// <param name="value"></param>
        public void Enqueue(Node value)
        {
            if (IsEmpty())
                nodes.Add(value);
            else
            {
                bool insert = false;
                for (int i = 0; i < nodes.Count; i++)
                {
                    if (value.Priority < nodes[i].Priority)
                    {
                        nodes.Insert(i, value);
                        insert = true;
                        break;
                    }
                    if (nodes[i].Priority == value.Priority)
                    {
                        nodes.Insert(i + 1, value);
                        insert = true;
                        break;
                    }
                }
                if (!insert)
                    nodes.Add(value);

            }
        }
Пример #2
0
 /// <summary>
 /// Checks if the Node child is present in the list of nodes
 /// Returns -1 if not present or returns the index if present
 /// </summary>
 /// <param name="nodes"></param>
 /// <param name="child"></param>
 /// <returns></returns>
 public static int FindNode(List<Node> nodes, Node child)
 {
     int flag = -1;
     for (int i = 0; i < nodes.Count; i++)
     {
         if (nodes[i].Equals(child))
         {
             flag = i;
             break;
         }
     }
     return flag;
 }
Пример #3
0
        /// <summary>
        /// Main method where the program execution starts
        /// </summary>
        /// <param name="args"></param>
        public static void Main(string[] args)
        {
            Node startNode = new Node();
            Node goalNode = new Node();

            //Prompts the user to enter start state and goal state
            Console.WriteLine("Enter the start state:");
            startNode.State = CheckInput();
            Console.WriteLine("Enter the goal state:");
            goalNode.State = CheckInput();

            startNode.PathCost = 0;
            startNode.Parent = null;

            Node bestNode = new Node();

            //Create an object of AStarProgram and call the AStar algorithm
            AStarProgram astar = new AStarProgram();
            bestNode = astar.AStar(startNode, goalNode);

            //Used a stack to display the path of solution
            Stack<Node> result = new Stack<Node>();
            if (bestNode != null)
            {
                while (bestNode.Parent != null)
                {
                    result.Push(bestNode);
                    bestNode = bestNode.Parent;
                }
            }
            else
            {
                //if bestnode is null then display
                Console.WriteLine("Solution does not exist");
            }

            //Print the solution, Number of nodes generated and nodes expanded
            Console.WriteLine("Number of Nodes in solution path : " + result.Count());
            Node tempNode = new Node();
            startNode.PrintState();
            Console.WriteLine();
            while (result.Count != 0)
            {
                tempNode = result.Pop();
                tempNode.PrintState();
                Console.WriteLine();
            }
            Console.WriteLine(); Console.WriteLine();
            Console.WriteLine("Number of Nodes generated : " + AStarProgram.noOfNodesGenerated);
            Console.WriteLine("Number of Nodes Expanded : " + AStarProgram.noOfNodesExpanded);
            Console.Read();
        }
Пример #4
0
        /// <summary>
        /// Moves the blank space to a desired position
        /// Returns a child node
        /// </summary>
        /// <param name="row"></param>
        /// <param name="col"></param>
        /// <param name="flag1"></param>
        /// <param name="flag2"></param>
        /// <returns></returns>
        public Node MoveOperation(int row, int col, bool flag1, bool flag2)
        {
            Node successor = new Node();

            //Copy the current state into a temporary storage
            int[] value = new int[State.Length];
            for (int i = 0; i < State.Length; i++)
            {
                value[i] = this.State[i];
            }

            //Find the required block to move based the bool values flag1 and flag2
            int a;
            if (flag2) a = -1; else a = 1;
            int row1 = row, col1 = col;
            if (flag1) row1 = row + a; else col1 = col + a;

            //set the new Node and return it
            successor.state = value;
            successor.State[puzzleSize * row1 + col1] = successor.State[puzzleSize * row + col];
            successor.State[puzzleSize * row + col] = 0;
            return successor;
        }
Пример #5
0
        /// <summary>
        /// Finds the h-cost which is the Manhattan distance between the calling Node and parameter Node
        /// </summary>
        /// <param name="goalNode"></param>
        /// <returns></returns>
        public int HCost(Node goalNode)
        {
            int distance = 0;
            for (int i = 0; i < this.State.Length; i++)
            {
                for (int j = 0; j < this.State.Length; j++)
                {
                    if (this.State[i] != 0 && this.State[i] == goalNode.State[j])
                    {
                        int x1 = (i) / puzzleSize; int y1 = (i) % puzzleSize;
                        int x2 = j / puzzleSize; int y2 = j % puzzleSize;
                        distance += Math.Abs(x1 - x2) + Math.Abs(y1 - y2);
                    }
                }
            }

            return distance;
        }
Пример #6
0
 /// <summary>
 /// Compares the states of two Nodes and returns true if they are same
 /// </summary>
 /// <param name="current"></param>
 /// <returns></returns>
 public bool Equals(Node current)
 {
     for (int i = 0; i < this.State.Length; i++)
     {
         if (this.State[i] != current.State[i])
             return false;
     }
     return true;
 }
Пример #7
0
        /// <summary>
        /// Implementation of A* Algorithm
        /// Takes the start node and goal node as input and returns the node which matches the goal node
        /// </summary>
        /// <param name="startNode"></param>
        /// <param name="goalNode"></param>
        /// <returns></returns>
        public Node AStar(Node startNode, Node goalNode)
        {
            Node INIT = startNode;

            //Create a list to track the visited nodes
            List<Node> visitedNodes = new List<Node>();

            //Create a Queue for the open nodes
            AlgoImpl.PriorityQueue queue = new AlgoImpl.PriorityQueue();

            //Add the start node to the queue
            INIT.Priority = INIT.HCost(goalNode) + INIT.PathCost;
            queue.Enqueue(INIT);

            //Check the queue for nodes, if empty then return null
            while (queue.nodes.Count != 0)
            {
                //Get the best node with minimum f value from the queue
                Node current = queue.Dequeue();

                //Add the node to visited nodes
                visitedNodes.Add(current);

                //Check if the node is goal node and return the node if true else expand its child nodes
                if (current.Equals(goalNode))
                {
                    return current;
                }
                else
                {
                    //Increment the expanded nodes global variable
                    ++noOfNodesExpanded;

                    //Generated the successor nodes
                    List<Node> childNodes = current.ChildrenNodes();

                    //Traverse the nodes
                    foreach (Node successor in childNodes)
                    {
                        int distanceFromNewNode = successor.HCost(goalNode);

                        //Compute the estimated g-cost of the successor
                        int estGCost = current.GCost() + Math.Abs(distanceFromNewNode - current.HCost(goalNode));
                        int findVisited = FindNode(visitedNodes, successor);

                        //check if the successor is already visited or not, if visted then discard it
                        if (findVisited == -1)
                        {
                            //check if the successor is already in the queue
                            int found = FindNode(queue.nodes, successor);

                            //if true
                            if (found != -1)
                            {
                                //if f cost of old node is greater than f cost of successor node, delete it from the queue
                                //else discard the successor node
                                if ((queue.nodes.ElementAt(found).PathCost > estGCost + distanceFromNewNode))
                                    queue.Delete(found);
                                else
                                    continue;
                            }
                            //Add the node to the queue and set its parent to curren
                            successor.Parent = current;
                            successor.PathCost = estGCost;
                            successor.Priority = successor.PathCost + distanceFromNewNode;
                            queue.Enqueue(successor);
                            ++noOfNodesGenerated;
                        }
                        else
                        {
                            if (estGCost < successor.GCost())
                            {
                                visitedNodes.RemoveAt(findVisited);
                                continue;
                            }
                        }
                    }
                }
                if (queue.nodes.Count == 100000)
                    break;
            }
            return null;
        }