四皇后问题详解:算法原理与回溯法实现

四皇后(4 Queens) 问题是指在一个 4 x 4 的棋盘上放置四个皇后,使得它们之间互不攻击。也就是说,不允许任何两个皇后处于 同一行同一列同一对角线 上。

在本文中,我们将一起探讨如何在 4 x 4 的棋盘上找到当 n=4 时的解决方案。

!N-Queen-Problem

使用 回溯算法(Backtracking Algorithm) 解决四皇后问题:

> 我们从最上面的一行开始,尝试在不同的行中逐个放置皇后。在某一行的特定列放置皇后时,我们会检查它与已放置的皇后是否存在冲突。对于任何一列,如果没有冲突,我们就将皇后放在那里,并将该行和该列标记为解决方案的一部分。如果在放置过程中由于冲突导致找不到安全的格子,那么我们就进行回溯(即撤销最近一次皇后的放置)并返回 false。

四皇后解决方案图解:

步骤 0: 初始化一个 4×4 的棋盘。

!image.png)

步骤 1:

  • 将我们的第一个皇后 (Q1) 放在 (0,0) 格子中。
  • x‘ 代表不安全的格子,即它们处于皇后 (Q1) 的攻击范围内。
  • 完成此操作后,移动到下一行 [ 0 -> 1 ]。

!1

步骤 2:

  • 将我们的下一个皇后 (Q2) 放在 (1,2) 格子中。
  • 完成此操作后,移动到下一行 [ 1 -> 2 ]。

!2

步骤 3:

  • 在第 2 行中,没有安全的格子可以放置皇后 (Q3)。
  • 因此,我们需要回溯,并将皇后 Q2 从格子 ( 1, 2 ) 移除。

步骤 4:

  • 在第 1 行中仍然有一个安全的格子,即格子 ( 1, 3 )。
  • 将皇后 ( Q2 ) 放在格子 ( 1, 3)。

!3

步骤 5:

  • 将皇后 ( Q3 ) 放在格子 ( 2, 1 )。

!4

步骤 6:

  • 在第 3 行没有格子可以放置皇后 ( Q4 )。
  • 回溯并将皇后 ( Q3 ) 从第 2 行移除。
  • 由于第 2 行仍然没有其他安全的格子,所以我们再次回溯,并将皇后 ( Q2 ) 从第 1 行移除。
  • 皇后 ( Q1 ) 将从格子 (0,0) 被移除,并移动到下一个安全的格子,即 (0 , 1)

步骤 7:

  • 将皇后 Q1 放在格子 (0 , 1),然后移动到下一行。

!5

步骤 8:

  • 将皇后 Q2 放在格子 (1 , 3),然后移动到下一行。

!8

步骤 9:

  • 将皇后 Q3 放在格子 (2 , 0),然后移动到下一行。

!9

步骤 10:

  • 将皇后 Q4 放在格子 (3 , 2),然后移动到下一行。
  • 这是解决方案的一种可能配置。

!10

按照以下步骤来实现这个想法:

  • 创建一个递归函数,该函数将棋盘的状态和当前行号作为其参数。
  • 从最上面的一行开始。
  • 如果所有皇后都已放置,则返回 true
  • 对于每一行,执行以下操作:

– 对当前行中的每一列执行以下操作。

– 如果皇后可以安全地放置在这一列

– 那么标记这个 [行, 列] 作为解决方案的一部分,并递归检查将皇后放在这里是否能导出一个解决方案。

– 如果在 [行, 列] 放置皇后能导出一个解决方案,返回 true

– 如果放置皇后没有导出解决方案,则取消标记这个 [行, 列] 并回溯,尝试其他列。

– 如果所有列都已尝试过但都没有成功,返回 false 以触发回溯。

下面是上述回溯解决方案的实现代码:

C++


// C++ program to solve N Queen Problem using backtracking

#include

using namespace std;

#define N 4

// ld is an array where its indices indicate row-col+N-1

// (N-1) is for shifting the difference to store negative

// indices

int ld[30] = { 0 };

// rd is an array where its indices indicate row+col

// and used to check whether a queen can be placed on

// right diagonal or not

int rd[30] = { 0 };

// Column array where its indices indicates column and

// used to check whether a queen can be placed in that

// row or not*/

int cl[30] = { 0 };

// A utility function to print solution

void printSolution(int board[N][N])

{

for (int i = 0; i < N; i++) {

for (int j = 0; j < N; j++)

cout << " " << (board[i][j]==1?'Q':'.') << " ";

cout << endl;

}

}

// A recursive utility function to solve N

// Queen problem

boo

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。如需转载,请注明文章出处豆丁博客和来源网址。https://shluqu.cn/33495.html
点赞
0.00 平均评分 (0% 分数) - 0