了解C ++中的回溯


12

我对C ++的基础知识有很好的基本了解,也对递归的工作方式也有了解。我遇到了一些问题,例如经典的八皇后问题和使用回溯法解决数独问题

我意识到我对此一无所知,似乎无法回想起递归堆栈并重新开始以解决问题的想法。用笔和纸似乎很容易,但是在为此编写代码时,我对如何开始解决这些问题感到困惑。

如果有一个针对初学者的教程,或者有一本很好的书涵盖了这些内容,那将是很有帮助的。如果有人可以阐明这个话题或给我一些有关体面参考的链接,我将不胜感激。

是的,我确实知道使用功能语言会更容易,但是我也想了解命令式语言的实现。


我认为这是一个很好的问题,但是我认为最好强调有人要求解释回溯而不是寻求教程或其他资源的要求。每天都有详尽的解释类答案胜过参考文献列表。
亚当李尔

如果有人可以给出详细的解释,那将是完美的,但是我也不介意阅读任何参考文献。只是我不知道从哪里开始。
nikhil 2011年

Answers:


9

...我似乎无法让我回想起递归堆栈并重新开始以解决问题的概念。

在回溯中,您不会再次开始。相反,您会在当前情况下遍历所有选项。

考虑为迷宫寻找解决方案。在有两条不同路径的一个点上,首先尝试左一条。如果左边的那条路没有将您引向出口,则返回该点并尝试另一条路。这就是回溯的工作方式。在8 Q和其他可以使用回溯的问题中,令人困惑的部分是问题域-如何在给定情况下以确定性方式遍历选项。

编辑:以下是帮助理解回溯的伪代码。

# depending on the problem, backtracking is not necessarily calling the
# method itself directly. for now, let's just stick with the simple case.

def backtracking(state)
  option_list = state.get_all_options
  option_list.each {|option|
    state.apply option
    return resolved if state.is_resolved
    return resolved if backtracking(state) == resolved
    state.undo option
  }
  return not_resolved
end

对于8Q问题:

  • state.get_all_options将返回下一个女王的可能位置的列表
  • state.is_resolved将测试所有皇后是否都在棋盘上,以及彼此是否相处得好。
  • state.apply和state.undo将修改板以应用或撤消定位。

我为分配编写的第一个递归代码(1984年使用Pascal)是迷宫求解算法。
格里

知道一些简单的任务,在这里我可以实际编写代码来获得这些东西的实际感觉。
nikhil 2011年

@nikhil:您是否在问一些简单的问题?最好编写一些伪代码来演示回溯的通用路由。我将在稍后的回复中尝试一个。
Codism 2011年

是的,那将是最有帮助的。
nikhil 2011年

非常感谢,最近我一直在阅读一些东西。渐渐地,我的理解力正在逐步提高。
nikhil 2011年

5

您看过一个程序来遍历二叉树,对吗?看起来像这样:

void walk(node* p){
  if (p == NULL) return;  // this is backtracking
  else if (WeWin(p)){
    // print We Win !!
    // do a Throw, or otherwise quit
  }
  else {
    walk(p->left);   // first try moving to the left
    walk(p->right);  // if we didn't win, try moving to the right
                     // if we still didn't win, just return (i.e. backtrack)
  }
}

有您的回溯。

您实际上不需要物理树。您所需要的只是一种举动,以后撤消,或者告诉您是否获胜,或者告诉自己是否无法继续前进。


1
您不能返回布尔/整数来检查是否在子树中找到了解决方案?else{return walk(p->left)||walk(p->right));}无需抛出即可获得预期的结果
棘轮怪胎

@ratchet:绝对。这也是一种完美的方法。(我只是想弄清楚这个例子。实际上我会按照您的方式做。)
Mike Dunlavey

但是,@ MikeDunlavey切割在实践中很重要。
jupp0r
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.