厦门理工算法设计与分析(第五章)解读.ppt

计算机算法设计与分析 第五章 回溯法 计算机求解的过程 求解过程可看成在状态空间从初始状态出发搜索目标状态(解所在状态)的过程。 求解是状态空间的搜索 求解的过程可以描述为对状态空间的搜索 几种搜索方法 状态空间的搜索实际上是一种树/DAG的搜索,常用的方法有: 三种搜索的比较 理论上广度优先搜索与深度优先搜索的时间复杂性都是指数级。但在实际上深度优先搜索的时间复杂性要低,在空间复杂性更要低得多。 广度优先搜索是一定能找到解;而深度优先搜索在理论上存在找不到解的可能。 启发式搜索是最好优先的搜索,若评价函数设计得好则能较快地找到解,降低时间复杂性;因而评价函数的优劣决定了启发式搜索的优劣。另外评价函数本身的开销也是很重要的。 树搜索的一般形式 SearchTree(Space T) {ok = 0; L = T.initial; while (!ok || L≠?) { a = L.first; if (a is goal) ok = 1 else Control-put-in(L, Sons(a)); } 三种搜索的不同之处 其中,深度优先搜索就是回溯法。 递归回溯法的一般形式 Try(s){ 做挑选候选者的准备; while (未成功且还有候选者) { 挑选下一个候选者next; if (next可接受) { 记录next; if (满足成功条件) {成功并输出结果} else Try(s+1); if (不成功) 删去next的记录; }} return 成功与否} 迭代回溯法的一般形式 先让我们回顾解空间搜索的一般形式: 迭代回溯法的一般形式 先让我们回顾解空间搜索的一般形式: 迭代回溯法的一般形式 先让我们回顾解空间搜索的一般形式: 如何判断最后一个儿子? 若只要遍历解空间树的结点,那么将各结点按栈方式控制便可实现深度为主搜索。 在求解问题时,需要记录解的路径,在回溯时还需要删除结点和修改相应信息。 栈中结点应该分层次,而却没有区分其层次。这就增加了回溯判断和操作的困难。 如何判断最后一个儿子? 若只要遍历解空间树的结点,那么将各结点按栈方式控制便可实现深度为主搜索。 在求解问题时,需要记录解的路径,在回溯时还需要删除结点和修改相应信息。 栈中结点应该分层次,而却没有区分其层次。这就增加了回溯判断和操作的困难。 用末尾标记的迭代回溯 Backtrack(Tree T) { Ok = 0; L.Push(T.root); while (!Ok|| L≠?) { a = L.Pop( ); if (a is the last mark) Backastep( ); else if (a is good) {Record(a); if (a is goal) {Ok = 1; Output( )} else if (a has sons) L.Push-Sons(a) else Move-off(a);}}} 用末尾标记的迭代回溯 Backtrack(Tree T) { Ok = 0; L.Push(T.root); while (!Ok|| L≠?) { a = L.Pop( ); if (a is the last mark) Backastep( ); else if (a is good) {Record(a); if (a is goal) {Ok = 1; Output( )} else if (a has sons) L.Push-Sons(a) else Move-off(a);}}} 用末尾标记的迭代回溯 Backtrack(Tree T) { Ok = 0; L.Push(T.root); while (!Ok|| L≠?) { a = L.Pop( ); if (a is the last mark) Backastep( ); else if (a is good) {Record(a); if (a is goal) {Ok = 1; Output( )} else if (a has sons) L.Push-Sons(a) else Move-off(a);}}} 用末尾标记的迭代回溯 Backtrack(Tree T) { Ok = 0; L.Push(T.root); while (!Ok||

您可能关注的文档

文档评论(0)

1亿VIP精品文档

相关文档