簡體   English   中英

回溯N皇后算法

[英]Backtracking N queen Algorithm

我看到了下面的代碼並試圖了解它是如何工作的。 我陷入了回溯。 有人能解釋一下 r 值是如何從 2 變為 1 的。當它未能找到適合女王放置的位置時。 ` 下面是調試部分:

nQueen (mat=0x7fffffffddb0, r=2) at N_Queens_problem.cpp:47
47      for (int i = 0; i < N; i++) 
(gdb) print i
$1 = 3
(gdb) n
62  }
(gdb) print i
No symbol "i" in current context.
(gdb) print i
No symbol "i" in current context.
**(gdb) print r
$2 = 2**
(gdb) n
nQueen (mat=0x7fffffffddb0, r=1) at N_Queens_problem.cpp:47
47      for (int i = 0; i < N; i++) 
**(gdb) print r
$3 = 1**
(gdb)

下面是 nqueen 函數:

void nQueen(char mat[][N], int r)
{
    // if N queens are placed successfully, print the solution
    if (r == N)
    {
        for (int i = 0; i < N; i++) 
        {
            for (int j = 0; j < N; j++)
                cout << mat[i][j] << " ";
            cout << endl;
        }
        cout << endl;

        return;
    }

    // place Queen at every square in current row r
    // and recur for each valid movement    
    for (int i = 0; i < N; i++) 
    {
        // if no two queens threaten each other
        if (isSafe(mat, r, i)) 
        {
            // place queen on current square
            mat[r][i] = 'Q';

            // recur for next row
            nQueen(mat, r + 1);

            // backtrack and remove queen from current square
            mat[r][i] = '-';
        }
    }
}

下面是檢查女王是否可以安全放置的功能:

bool isSafe(char mat[][N], int r, int c)
{
    // return false if two queens share the same column
    for (int i = 0; i < r; i++)
        if (mat[i][c] == 'Q')
            return false;

    // return false if two queens share the same \ diagonal
    for (int i = r, j = c; i >= 0 && j >= 0; i--, j--)
        if (mat[i][j] == 'Q')
            return false;

    // return false if two queens share the same / diagonal
    for (int i = r, j = c; i >= 0 && j < N; i--, j++)
        if (mat[i][j] == 'Q')
            return false;

    return true;
}

假設您已經放置了兩個皇后,並將放置第三個皇后。

  1. 到目前為止,堆棧中將有兩次對nQueens()遞歸調用。 一為皇后0,一為皇后3。
  2. nQueen(mat, r + 1); 將使用nQueen(mat, 2)調用,第三個 nQueens() 將被推入堆棧。

考慮到將皇后放在第三排的 N 個位置中的任何一個都是不安全的,並且

  1. if (isSafe(mat, r, i))將為所有列 0 到 N 返回 false。
  2. 最終for (int i = 0; i < N; i++)的循環將以r == 2結束並且堆棧將展開。
  3. 堆棧將刪除最頂層的調用,我們將在堆棧中留下函數調用(回到第 1 步)。
  4. 並且循環for (int i = 0; i < N; i++)將嘗試重新定位第二個皇后。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM