25分支限界算法和回溯算法
回溯算法
实际问题:
其中回溯算法也可以用于解决n皇后问题
#include <iostream>
#include <vector>
using namespace std;
const int N = 8;
vector<int> col(N, 0), diag1(2 * N, 0), diag2(2 * N, 0); // 标记列和对角线是否有皇后
vector<vector<string>> solutions;
vector<string> board(N, string(N, '.'));
void backtrack(int row) {
if (row == N) {
solutions.push_back(board); // 保存一个解
return;
}
for (int i = 0; i < N; i++) {
if (col[i] || diag1[row + i] || diag2[row - i + N - 1])
continue; // 如果冲突则跳过
// 做选择
board[row][i] = 'Q';
col[i] = diag1[row + i] = diag2[row - i + N - 1] = 1;
// 递归到下一行
backtrack(row + 1);
// 撤销选择(回溯)
board[row][i] = '.';
col[i] = diag1[row + i] = diag2[row - i + N - 1] = 0;
}
}
int main() {
backtrack(0);
cout << "共有 " << solutions.size() << " 种解法" << endl;
for (auto solution : solutions) {
for (auto line : solution) {
cout << line << endl;
}
cout << endl;
}
return 0;
}
分支限界算法
首先确定一个合理的限界函数,并根据限界函数确定目标函数的界[down,up];然后,按照广度优先策略搜索问题的解空间树:
1.在当前扩展结点处,生成所有儿子结点,估算所有儿子结点对目标函数的可能取值,舍弃不可能通向最优解的结点 (剪枝),将其余的加入到活结点表(用队列组织)中。
2.在当前活结点表中,依据先进先出或某种优先级(最小耗费或最大效益)策略,从当前活结点表中选择一个结点作为扩展结点。
3.重复(1)-(2)步骤,直到找到所需的解或活结点表为空。
分支限界法与回溯法的区别
1.求解目标不同
回溯法的求解目标一般是找出满足约束条件的所有解或最优解
分支限界法的求解目标是找出满足约束条件的一个解或最优解
2.搜索方式不同
回溯法以深度优先的方式搜索解空间树
分支限界法以广度优先或以最小耗费(最大效益)优先的方式搜索解空间树
————————————————
原文链接:https://blog.csdn.net/m0_64403412/article/details/130694294