从广度优先搜索转换到深度优先限制搜索

时间:2014-03-09 19:52:30

标签: c# algorithm depth-first-search breadth-first-search

作为搜索算法的所有新手,我正在研究旧时尚8问题拼图的一个例子,我已经完成了下面代码中的广度优先算法,我想知道如何将它转换为深度优先限制搜索。

如何从广度优先算法转换为深度优先搜索算法?

代码:

 class BFS
    {
        int[] GoalState = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
        private Queue<Node> Frontier;
        private HashSet<Node> Solution;
        private Node RootNode;

        public BFS(int[] StartState)
        {
            this.RootNode = new Node(StartState, -1, "\0");
            Solution = new HashSet<Node>();
            Frontier = new Queue<Node>();
        }

        public void Solve()
        {
            Node ActiveNode = RootNode;
            bool IsSolved = false;
            while (!IsGoalState(ActiveNode.GetState()))
            {
                Solution.Add(ActiveNode);
                foreach (Node successor in GenerateSuccessor(ActiveNode))
                {
                    Frontier.Enqueue(successor);
                    if (IsGoalState(successor.GetState()))
                    {
                        IsSolved = true;
                        Solution.Add(successor);
                        break;
                    }
                }
                if (IsSolved)
                    break;

                ActiveNode = Frontier.Dequeue();
            }
            WriteSolution();
        }

        public IEnumerable<Node> GenerateSuccessor(Node ParentNode)
        {
            int[] ParentState = ParentNode.GetState();
            int EmptySpacePosition = 0;
            int temp;
            for (int x = 0; x < 9; x++)
            {
                if (ParentState[x] == 0)
                {
                    EmptySpacePosition = x;
                    break;
                }
            }

            //Can move empty space to LEFT?
            if (EmptySpacePosition != 0 && EmptySpacePosition != 3 && EmptySpacePosition != 6)
            {
                int[] _State = (int[])ParentState.Clone();
                _State[EmptySpacePosition] = _State[EmptySpacePosition - 1];
                _State[EmptySpacePosition - 1] = 0;
                yield return new Node(_State, ParentNode.GetId(), "Left ");
            }

            //Can move empty space to RIGHT?
            if (EmptySpacePosition != 2 && EmptySpacePosition != 5 && EmptySpacePosition != 8)
            {
                int[] _State = (int[])ParentState.Clone();
                _State[EmptySpacePosition] = _State[EmptySpacePosition + 1];
                _State[EmptySpacePosition + 1] = 0;
                yield return new Node(_State, ParentNode.GetId(),"Right ");
            }

            //Can move empty space to UP?
            if (EmptySpacePosition > 2)
            {
                int[] _State = (int[])ParentState.Clone();
                _State[EmptySpacePosition] = _State[EmptySpacePosition - 3];
                _State[EmptySpacePosition - 3] = 0;
                yield return new Node(_State, ParentNode.GetId(), "Up ");
            }

            //Can move empty space to DOWN?
            if (EmptySpacePosition < 6)
            {
                int[] _State = (int[])ParentState.Clone();
                _State[EmptySpacePosition] = _State[EmptySpacePosition + 3];
                _State[EmptySpacePosition + 3] = 0;
                yield return new Node(_State, ParentNode.GetId(),"Down ");
            }
        }

        public bool IsGoalState(int[] State)
        {
            for (int x = 0; x < 9; x++)
            {
                if (State[x] != GoalState[x])
                    return false;
            }
            return true;
        }

        public void WriteSolution()
        {
            StringBuilder s = new StringBuilder();
            int ParentId = 0;

            #region InfoPrint
            Console.Write("Puzzle= ");
            foreach (int i in RootNode.GetState())
            {
                Console.Write(i);
            }
            Console.WriteLine();
            Console.WriteLine("Nodes Generated= " + (Solution.Count + Frontier.Count));

            #endregion

            foreach (Node n in Solution.Reverse())
            {
                if (ParentId == 0 || n.GetId() == ParentId)
                {
                    s.Append(n.GetMove());
                    ParentId = n.GetParentId();
                }
            }

            Console.WriteLine("Solution Length= " + (s.Length - 1));
            Console.WriteLine("Solution= " + s.ToString());
        }
    }

这是我的班级节点

class Node
    {
        static int _IdCnt = 0;
        private int[] State;
        private int Id;
        private int ParentId;
        private string Move;
        public Node(int[] State, int ParentId, string Move)
        {
            Id = _IdCnt++;
            this.State = State;
            this.ParentId = ParentId;
            this.Move = Move;
        }

        public void SetState(int[] State)
        {
            this.State = State;
        }

        public int[] GetState()
        {
            return (int[])State.Clone();
        }

        public int GetId()
        {
            return Id;
        }

        public int GetParentId()
        {
            return ParentId;
        }

        public string GetMove()
        {
            return Move;
        }
    }

1 个答案:

答案 0 :(得分:1)

在DFS中,您需要使用stack而不是queue。基本上,您将根节点添加到堆栈,并且当堆栈包含节点时,您弹出节点,执行逻辑,将其邻居添加到堆栈并继续。

1. Add root to a stack.
2. while(stack.Count > 0)
{
3. pop the stack
4. if matches, return
5. else add neighbors to stack
}

return not found