C++ 回溯算法 (递归的使用)

来源:互联网 发布:ubuntu下安装apt get 编辑:程序博客网 时间:2024/05/17 06:57

回溯算法的模型就是一种走迷宫问题的解决方法。

按照某个策略不断走下去,直到走到终点或者说走完全图。


这是一个通用的算法,理解透了后可以用在许多app中。下面以一个实例来详细剖析一下这个算法,若有错误处,请各位大神指教。


首先看问题

{

{s,1,1,0,1,1,0,0,0,1,1,1,1},
{1,0,1,1,1,0,1,1,1,1,1,0,1},
{1,0,0,0,1,0,1,0,1,0,1,0,1},
{1,0,0,0,1,1,1,0,1,0,1,1,1},
{1,1,1,1,1,0,0,0,0,0,0,0,0},
{0,0,0,0,1,0,0,0,0,0,0,0,0},
{0,0,0,0,1,1,1,1,1,1,1,1,e}

}


1代表走廊,0代表墙,s代表起点,e代表终点,规则只可以横竖行走,要求从s->e;


解决这个问题需要的三个类:

1.Application  (代表一个应用)

2.BackTrack (回溯类,对其中的方法进行递归)

3.Position (表示位置信息,根据不同应用拥有不同对position的定义,这里相当于一个二维数组)


Application类:

4个通用方法:

  • bool valid(Position pos)             (用来表示某个点是否合法)
  • void record(Position pos)          (用来表示记录这个点已经尝试过,并且可以到达终点)
  • bool done(Position pos)         (表示这个点就是终点)
  • void undo(Position pos) (表示这个点已经尝试过,不可到达终点)
这些方法是接口,对于不同的application 实现了这些方法都可以使用回溯法

1个内部类Iterator:

  • Iterator(); (默认构造方法)
  • Iterator(const Position&pos);    (某个点的构造)
  • Position operator++(int); (怎么走的策略就在这个运算符重载中实现)
  • bool atEnd(); (判断这个点的四个方向是否都走完了)
它还有一个空指针,表示点,针对不同应用会在定义不同的结构体,然后强转为那种结构体
void *fieldPtr


Position类:
就是一个位置,该应用中属性有:行、列。
方法也就是设定行列,得到行列。

BackTrack类:
里面有个很重要的方法
tryToSolve(Position pos)会进行递归的调用来尝试解决问题.


这些基本就是主要用来解决问题的类了。


回溯法解决问题的主要思路:
1.初始化迷宫,起点终点。
2.决定行走策略
3.依照策略一步一步进行尝试,直到终点,或者所有可行点都试完。

行走策略定义在Iterator的++运算符重载中
住方法中调用tryToSolve方法,里面进行递归的调用。(在调用的过程中会用到上述的方法来进行标记某个点可行/不可行,是否已经尝试等等。)