《数据结构和Java集合框架第三版》读书笔记(三)回溯算法

时间:2022-12-07 17:54:00

回溯就是通过一系列位置选择到达目的位置并且在不能到达目的位置时反向退回的策略


回溯法就从开始结点(根结点)出发,以深度优先的方式搜索整个解空间。这个开始结点就成为一个活结点,同时也成为当前的扩展结点。在当前的扩展结点处,搜索向纵深方向移至一个新结点。这个新结点就成为一个新的活结点,并成为当前扩展结点。如果在当前的扩展结点处不能再向纵深方向移动,则当前扩展结点就成为死结点。此时,应往回移动(回溯)至最近的一个活结点处,并使这个活结点成为当前的扩展结点。回溯法即以这种工作方式递归地在解空间中搜索,直至找到所要求的解或解空间中已没有活结点时为止。

回溯算法:Backtrack

 

使用Backtrack类的用户需要提供:

1,应用程序类   实现Application接口。并且要包含内部迭代类,枚举从当前位置开始所有可能的下一步位置

2,Position类  定义“位置”在该应用程序中的意思

 

应用程序类:

import java.util.*;

public interface Application
{
     /**
      * 判定pos是活结点还是死结点.
      *
      * @param pos - the given position.
      *
      * @return true if pos is a legal position and not a dead end.
      */    
     boolean isOK (Position pos);


     /**
      * 标志pos位置是在通往目的地的路径上.
      *
      * @param pos the position that has been marked as possibly being on a
      *                path to a goal.
      */
     void markAsPossible (Position pos);


     /**
      * 表明pos是否为目的位置.
      *
      * @param pos the position that may or may not be a goal position.
      *
      * @return true if pos is a goal position; false otherwise.
      */
     boolean isGoal (Position pos);
 

     /**
      * 表明pos不在任何通往目的地的路径上.
      *
      * @param pos the position that has been marked as not being on any path to
      *                a goal position.
      */
     void markAsDeadEnd (Position pos);
 

     /**
      * Converts this Application object into a String object.
      *
      * @return the String representation of this Application object.
      */
     String toString();


     /**
      * 从给定位置pos开始的迭代器,枚举从当前位置开始所有可能的下一步位置      *
      * @param pos the position the Iterator object starts at.
      *
      * @return an Iterator object that accesses the positions directly
      *               available from pos.            
      */
     Iterator<Position> iterator (Position pos);

} // interface Application


BackTrack类有两个职责——从给定的Application对象初始化一个Backtrack对象;从给定位置出发到达目的位置。对应两个方法

import java.util.*;

public class BackTrack
{
protected Application app;


/**
* Initializes this BackTrack object from an application.
*
* @param app the application
*/
public BackTrack (Application app)
{
this.app = app;
} // constructor


/**
* Attempts to reach a goal through a given position.
*
* @param pos the given position.
*
* @return true if the attempt succeeds; otherwise, false.
*/
public boolean tryToReachGoal (Position pos)
{
Iterator<Position> itr = app.iterator (pos);

while (itr.hasNext())
{
pos = itr.next();
if (app.isOK (pos))
{
app.markAsPossible (pos);
if (app.isGoal (pos) || tryToReachGoal (pos))
return true;
app.markAsDeadEnd (pos);
} // pos may be on a path to a goal
} // while
return false;
} // method tryToReachGoal

} // class BackTrack


tryToReachGoal函数里pos参数移动策略:

pos的下一步有各种可能选择的位置。

1,其中一个选择是目的位置,寻路成功,返回true

2,其中一个选择是有效位置,但不是目的位置。调用tryToReachGoal (pos)方法,从这个有效位置开始寻找路径

3,没有一个选择是有效的位置(要么是已经被判定成死结点,要么是走到死胡同无路可走了)。迭代器的while循环终止,返回false,表示从当前pos出发寻路失败。

tryToReachGoal (pos)返回false后,接下来调用的app.markAsDeadEnd (pos)将这个pos标记为死点

 

 

 

 回溯算法的应用:走迷宫,八皇后问题,马步遍历问题