深度优先状态搜索法

      继续未完成之事业.
      今天我们要讲的是深度优先搜索,还是以8数码问题为背景.
      简单的说,深度优先就是沿着一条路径走到底,对于8数码的问题,由于空格只能上下左右的移动(有时候也不全然),因此每种移动策略,都会产生一个不同于当前的状态.
(0代表空格)
比如对于状态          左移             上移 
1  2  3                                           1  2  3                                            1  0  3
4  0  5                        0  4  5                          4  2  5 
6  7  8                                           6  7  8                                            6  7  8   

      所以简单的说,每个状态的可能子状态有(平均起来)3个,依据深度优先的策略,深度搜索可以简单的表示成一个递归的过程。
depthSearch(node T)
{
    visit(T); 
    for each sonNode son of T, do depthSearch(node son);
}
      涉及到具体的实现,那么我们就要对其中的求子节点细化并用语言描述。比如在8数码的背景下,怎么求子节点呢?前面提到,上下左右的移动会产生子节点,那么自然的可以想到,有某中方式来表示空格移动方向,因为要对所有的子接点逐个的进行深度搜索。
一个简单的方法,用一个整数来替代方向,比如0代表左,1代表下,2代表右,3代表上。所以求子接点的函数描述如下:
Node sonNode( Node t, int i)
{
//在这里添加代码。
}
所以8数码的深度状态搜索算法描述如下:
boolean depthSearch(node T)
{
   if(is(T))return TRUE;
   else  if( visit(T)) //访问并检查是否还有子节点没有被访问。
   { 
      for(int i=0;i<4;i++)
      {
         if(able(sonNode(T,i)))
            depthSearch(sonNode(T,i));
      }
   }
   else return  FLASE;
}
其中boolean able(Node n)是用于确定节点n是否曾经被访问过。
那么说了这么多,我们需要保存已经访问过的节点吗??因为节点的数量相当大,所以如果存,将会耗费大量的空间。这里有一个特殊的方法,可以用hash表的方法来确定节点是否被访问。但是如果需要记录路径的话,最好还是将节点存起来,因为需要记录父节点。具体程序见我的文集.

posted on 2006-11-04 18:31  空空色色  阅读(589)  评论(0编辑  收藏  举报