如何使用回溯法解决 M<N 时的 M 个皇后

Posted

技术标签:

【中文标题】如何使用回溯法解决 M<N 时的 M 个皇后【英文标题】:How to solve M queens when M<N using backtracking approach 【发布时间】:2015-06-06 10:26:02 【问题描述】:

这是N queens problem。我知道N queens 问题及其解决方案,我使用回溯方法用 C++ 编程语言编写了代码:

#include <iostream>

using namespace std;

int col[100];
int n;
int m;

bool check(int i,int k)
    for(int j=1 ; j<k ; j++)
        if(col[j] == i || i-k == col[j] - j || i+k == col[j]+j)return false;
    
    return true;


void queens(int k)
    for(int i=1 ; i<=n ; i++)
        if(check(i,k))
            col[k] = i;
            if(k == n)
                for(int j=1 ; j<=n ; j++)cout<<col[j]<<" ";
                cout<<endl;
            
            else queens(k+1);
        
    


int main()
    n = 4;
    queens(1);

但这是我的问题,如果我们有 m 个皇后而不是 n 其中 m 我如何通过回溯方法解决这个问题我认为对我的代码进行一些更改可以解决问题,但我不确定。

我用谷歌搜索了它,但什么也没找到,所以有没有针对这个问题的回溯解决方案?

【问题讨论】:

【参考方案1】:

答案比您想象的要容易得多!在常规的N-queen 问题中,我们迭代kn 次。所以我们可以在第一列的任何位置(1 到 8 之间)添加我们的第一个皇后,以此类推其他皇后。

但是,如果皇后数 (m) 小于我们的国际象棋大小 (n),我们必须将该皇后(我们的第一个皇后)不仅放在第一列,而且放在任何地方(从 1 到 64)并且对其他皇后做同样的事情。

所以您唯一需要做的就是迭代 kn*n 次而不是 n 次。

【讨论】:

【参考方案2】:

你可以让函数queens 有两个参数:

    您当前达到的列索引 (num_column) 桌上的皇后数 (num_queens)

现在您必须在 [num_column, n] 之间固定一列来放置女王。 让 (i, j) 成为 i 的行和 j 的列 (1 &lt;= i &lt;= nnum_column &lt;= j &lt;= n)。

for j from num_column to n:
    for i from 1 to n:
        if check(i, j):
            col[j] = i
            queens(j + 1, num_queens + 1)
            //resetting the queen on j'th column
            col[j] = 0

您可以在到达 num_queens == m 时停止该功能。

【讨论】:

以上是关于如何使用回溯法解决 M<N 时的 M 个皇后的主要内容,如果未能解决你的问题,请参考以下文章

AI -- 回溯法解决四皇后问题

用回溯法解定和子集问题、0/1背包问题和n皇后问题的算法比较

五大算法-1.回溯法

解决 N 个皇后时的数组索引超出范围异常

八皇后(回溯法)

暴力穷举和回溯法(八皇后问题)