RedSenior

导航

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

posted on 2024-12-01 23:36  RedLouie  阅读(14)  评论(0编辑  收藏  举报