回溯算法(Backtracking)说明与实例

回溯算法是一种用于解决约束满足问题的通用算法,通过递归构建可能的解并回溯不可能的解。本文介绍了回溯算法的定义、通用算法思想,并详细解释了N皇后问题、数独问题以及集合问题的经典应用示例,展示了如何用C++实现这些问题的解法。
摘要由CSDN通过智能技术生成

定义

回溯算法(Backtracking)在很多场景中会使用,如N皇后,数迷,集合等,其是暴力求解的一种优化。参考https://en.wikipedia.org/wiki/Backtracking 中的说明,定义如下:

Backtracking is a general algorithm for finding all (or some) solutions to some computational problems, notably constraint satisfaction problems, that incrementally builds candidates to the solutions, and abandons each partial candidate c (“backtracks”) as soon as it determines that c cannot possibly be completed to a valid solution

从上文中可以得出, 核心的含义是 回溯算法是通过一步一步(通常是用递归)构建可能”解”,并且回溯不可能”解”来求所有或者部分解决方案的通用算法。其中“回溯”的具体意思就是将不可能解或者部分解的候选尽早的舍弃掉,“解”需要满足一定的限制条件(constraint satisfaction)

通用算法

这里介绍一下回溯算法的通用思想,一般来讲,会设置一个递归函数,函数的参数会携带一些当前的可能解的信息,根据这些参数得出可能解或者不可能而回溯。
参考 http://web.cse.ohio-state.edu/~gurari/course/cis680/cis680Ch19.html 这里面有一个通用的算法

ALGORITHM try(v1,...,vi)  // 这里的V1.....V2携带的参数说明 “可能解”  
   // 入口处验证是否是全局解,如果是,直接返回。 
   // 实际编程中也需要查看是否是无效解,如果是,也是直接返回
   IF (v1,...,vi) is a solution THEN RETURN (v1,...,vi)  
   FOR each v DO  // 对于每一个可能的解,进行查看
      // 下面的含义是形成一个可能解 进行递归
      IF (v1,...,vi,v) is acceptable vector  THEN 
        sol = try(v1,...,vi,v) 
        IF sol != () THEN RETURN sol 
        // 这个地方其实需要增加“回溯” 处理,实际编程中通常是函数参数的变化
      END 
   END 
   RETURN () 

经典算法

  • N皇后问题

这个是一个比较经典的问题, 意思是将N个“皇后”放在N*N的棋盘上,每个皇后不能再同一列,同一行,和斜对角 (这个就是限制条件constraint satisfaction)。 下面是回溯算法的需求所有的可能解。
算法基本的步骤思想为:
1)从第一行开始
2 )如果所有的皇后已经放置完成, 生成解,并且返回true
3)尝试当前行的所有列,如果当前行与列是合法的
3.1 修改棋盘让其成为部分解,
3.2 然后递归查看(主要是2, 3,4)该解是否合法
3.3 Backtrack 棋盘进行回溯
4) 如果上述所有的组合都为非法,返回false

    // 寻找N皇后问题的可能解, 我们用 '.' 表示不放置皇后,用'Q'表示放置皇后
    // 利用vector<string> 表示一个解决方案, vector<vector<string>> 表示                                 
    // 所有的解决方案。
    // 在递归初,我们可以生成一个待解的棋盘
    vector<vector<string>> solveNQueens(int n) {
        string tmp (n, '.');
        //生成一个N*N待解的棋盘,没有任何皇后
        vector<string> broad (n, tmp);
        nQueue = n;
        vector<vector<string>>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值