回溯算法总结.doc

  1. 1、本文档共3页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
回溯算法总结

[转]递归回溯总结 2009年08月30日 星期日 15:528 皇后问题是一道非常经典的题目。题目是说,一个N*N的国际象棋棋盘上主放置N个皇后,使其不能相互攻击,即任何两个皇后都不能处在棋盘的同一行,同一列,同一条斜线上,试问共有多少种摆法? 其实,题目就是要找出所有的可能情况,然后排除其中不符合条件的情况,剩下的情况即为所要求的。怎么找出所有的情况呢?对于8皇后,我们可以使用穷举法,穷举出每一种放置方法,然后判断是否符合题意。如果每次放一行,那就需要8重循环才可以解出来。虽然空间复杂度可以小到为0,但是时间复杂度太高。 书中一般使用回溯法来解此题。仔细分析此题,可以发现:每一行上只能放置一个皇后,然后后面每行放置的皇后,不能与前面的行上放置的皇后在同一列上或者同一对角线上。所以用一个一维数组就可以存放在棋盘上放置的皇后的行列信息:一维数组的第i个位置存放的数值j就表示,在棋盘的第i行、第j列上放着一个皇后。棋盘的一行就用一个元素来表示,所以不能在同一行就不用判断了。知道了皇后在棋盘的行列位置后,判断是否符合后面的两个条件也比较容易了(对角线只要仔细分析下,两个二维坐标点如果在对角线上,他们的行列坐标将会满足何种情况即可)。 搞定了数据结构,接着就要考虑如何进行回溯搜索了。回溯一般借用递归来实现。用我的一个ACM非常牛的一个同学的话来说:回溯就是让计算机自动的去搜索,碰到符合的情况就结束或者保存起来,在一条路径上走到尽头也不能找出解,就回到原来的岔路口,选择一条以前没有走过的路继续探测,直到找到解或者走完所有路径为止。就这一点,回溯和所谓的DFS(深度优先搜索)是一样的。那现在的关键是,怎么实现搜索呢?回溯既然一般使用递归来实现,那个这个递归调用该如何来写呢?我现在的理解就是,进行回溯搜索都会有一系列的步骤,每一步都会进行一些查找。而每一步的情况除了输入会不一样之外,其他的情况都是一致的。这就刚好满足了递归调用的需求。通过把递归结束的条件设置到搜索的最后一步,就可以借用递归的特性来回溯了。因为合法的递归调用总是要回到它的上一层调用的,那么在回溯搜索中,回到上一层调用就是回到了前一个步骤。当在当前步骤找不到一种符合条件情况时,那么后续情况也就不用考虑了,所以就让递归调用返回上一层(也就是回到前一个步骤)找一个以前没有尝试过的情况继续进行。当然有时候为了能够正常的进行继续搜索,需要恢复以前的调用环境。 下面贴出8皇后问题的代码: #include iostream #include cmath using namespace std; void PrintResult(int *arr, int n) { for (int i = 1; i != n + 1; ++i) cout ( i , arr[i] ) ; cout endl; } bool Verify(int *arr, int i) { /* 和前面的i - 1行比较,看当前放置位置是否合法?*/ for (int k = 1; k != i; ++k) if (arr[k] == arr[i] || abs(i - k) == abs(arr[i] - arr[k])) return false; return true; } /* 虽然只用了一个一维数组,但是其中已经保存了足够的信息。 因为每一行只能放一个皇后,所以一维数组的第i个位置存放的 是在第i行的哪一列(第j列)上放置了皇后。这个递归函数 每次处理一行,直到第n行(下标从1开始)。*/ void NQueens(int *arr, int i, int n) { /* 尝试着在第i行的第j列放置一个皇后。*/ for (int j = 1; j != n + 1; ++j) { arr[i] = j; if (Verify(arr, i)) { /* 这个递归程序的结束条件是第n行放置完毕, 所以,当递归函数从调用NQueens(arr, i + 1, n)返回时, 就是回到了第i行,继续搜索合适的位置。当第i + 1行的 所有位置都不能满足的时候,上面的调用就会返回,也就 是进行了所谓的回溯。这个回溯不需要显示的恢复以前的 调用环境,因为所需要的信息没有被破坏。*/

文档评论(0)

haihang2017 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档