Re-translate the Japanese version (#1871)

* Retranslate Japanese docs with GPT-5.4

* Retranslate Japanese code with GPT-5.4
This commit is contained in:
Yudong Jin
2026-03-30 07:30:15 +08:00
committed by GitHub
parent fe6443235b
commit d7b2277d2b
1444 changed files with 83312 additions and 8363 deletions
@@ -1,53 +1,53 @@
# Nクイーン問題
# n クイーン問題
!!! question
チェスのルールによると、クイーンは同じ行、列、または対角線上の駒を攻撃できます。$n$ 個のクイーンと $n \times n$ のチェスボードが与えられた場合、2つのクイーンが互いに攻撃できない配置を見つけてください
チェスのルールによれば、クイーンは同じ行、同じ列、または同じ斜線上にある駒を攻撃できます。$n$ 個のクイーンと $n \times n$ サイズの盤面が与えられたとき、すべてのクイーンが互いに攻撃し合わない配置を求めます
以下の図に示すように、$n = 4$ の場合、2つの解があります。バックトラッキングアルゴリズムの観点から、$n \times n$ のチェスボードには $n^2$ 個のマスがあり、すべての可能な選択肢 `choices`示しています。チェスボードの状態 `state` は、各クイーンが配置されるにつれて継続的に変化します。
図に示すように、$n = 4$ のとき、2 つの解を見つけることができます。バックトラッキングの観点から見ると、$n \times n$ サイズの盤面には合計 $n^2$ 個のマスがあり、これがすべての選択肢 `choices`与えます。クイーンを 1 つずつ配置していく過程で、盤面の状態は絶えず変化し、その各時点の盤面が状態 `state`す。
![4クイーン問題の解](n_queens_problem.assets/solution_4_queens.png)
![4 クイーン問題の解](n_queens_problem.assets/solution_4_queens.png)
以下の図は、この問題の3つの制約を示しています**複数のクイーンは同じ行、列、または対角線を占有できません**。対角線は主対角線 `\` と副対角線 `/` に分かれることに注意することが重要です。
下図は本問題の 3 つの制約条件を示しています**複数のクイーンは同じ行、同じ列、同じ対角線上に置けません**。なお、対角線は主対角線 `\` と副対角線 `/` の 2 種類があります。
![Nクイーン問題の制約](n_queens_problem.assets/n_queens_constraints.png)
![n クイーン問題の制約条件](n_queens_problem.assets/n_queens_constraints.png)
### 行ごとの配置戦略
クイーンの数がチェスボードの行数と等しく、どちらも $n$ であるため、**チェスボードの各行には1つのクイーンのみが配置できることが**容易に結論付けられます
クイーンの数と盤面の行数はいずれも $n$ なので、次の推論を容易に得られます:**盤面の各行にはクイーンを 1 つだけ配置できます**
これは、行ごとの配置戦略を採用できることを意味します:最初の行から開始して、最後の行に到達するまで行ごとに1つのクイーンを配置します。
つまり、行ごとの配置戦略を採用できます:最初の行から始めて、各行に 1 つのクイーンを配置し、最後の行まで進みます。
以下の図は、4クイーン問題行ごとの配置プロセスを示しています。スペースの制限により、図は最初の行の1つの検索分岐のみを展開し、列と対角線制約を満たさない配置を剪定します。
下図は 4 クイーン問題における行ごとの配置過程を示しています。図の大きさの都合上、下図では 1 行目における検索分岐の 1 つだけを展開し、列制約と対角線制約を満たさない案はすべて枝刈りしています。
![行ごとの配置戦略](n_queens_problem.assets/n_queens_placing.png)
本質的に、**行ごとの配置戦略は剪定関数として機能し**、同じ行に複数のクイーンを配置するすべての索分岐を除去します。
本質的に、**行ごとの配置戦略は枝刈りとして機能します**。これにより、同じ行に複数のクイーンが現れるすべての索分岐を回避できます。
### 列と対角線の剪定
### 列と対角線の枝刈り
制約を満たすために、長さ $n$ のブール配列 `cols`使用して、各列にクイーンが占有されているかどうかを追跡できます。配置決定の前に、`cols` を使用してすでにクイーンがある列を剪定し、バックトラッキング中に動的に更新されます。
列制約を満たすために、長さ $n$ のブール配列 `cols`用いて、各列にクイーンがるかどうかを記録できます。配置を決めるたびに、`cols` を使って既存のクイーンがある列を枝刈りし、バックトラッキングの中で `cols` の状態を動的に更新ます。
!!! tip
行列の原点は左上にあり、行インデックスは上から下に増加し、列インデックスは左から右増加することに注意してください
注意として、行列の原点は左上にあり、行インデックスは上から下、列インデックスは左から右増加します。
対角線制約はどうでしょうか?チェスボード上の特定のセルの行と列のインデックスを $(row, col)$ とします。特定の主対角線を選択することで、その対角線上のすべてのセルで差 $row - col$ が同じであることに気付きます。**つまり、$row - col$ は主対角線上で定数値です**。
では、対角線制約はどのように扱えばよいのでしょうか。盤面上のあるマスの行列インデックスを $(row, col)$ とし、行列内のある主対角線を選ぶと、その対角線上のすべてのマスで行インデックスから列インデックスを引いた値が等しいことが分かります。**つまり、主対角線上のすべてのマスでは $row - col$ が一定値になります**。
言い換えると、2つのセルが $row_1 - col_1 = row_2 - col_2$ を満たす場合、それらは確実に同じ主対角線上にあります。このパターンを使用して、以下の図に示す配列 `diags1` を利用して、クイーンが主対角線上にあるかどうかを追跡できます。
つまり、2 つのマスが $row_1 - col_1 = row_2 - col_2$ を満たすなら、それらは必ず同じ主対角線上にあります。この性質を利用して、下図の配列 `diags1` により、各主対角線にクイーンがあるかどうかを記録できます。
同様に、**$row + col$ の和は副対角線上のすべてのセルで定数値です**。配列 `diags2` を使用して副対角線の制約も処理できます。
同様に、**副対角線上のすべてのマスでは $row + col$ が一定値です**。副対角線制約も配列 `diags2` を使って処理できます。
![列と対角線制約の処理](n_queens_problem.assets/n_queens_cols_diagonals.png)
![制約と対角線制約の処理](n_queens_problem.assets/n_queens_cols_diagonals.png)
### コード実装
$n$ 次元の正方行列では$row - col$ の範囲は $[-n + 1, n - 1]$ 、$row + col$ の範囲は $[0, 2n - 2]$ であることに注意してください。したがって、主対角線と副対角線の数はどちらも $2n - 1$ で、配列 `diags1``diags2` の長さ $2n - 1$ です。
注意として、$n$ 次正方行列では $row - col$ の範囲は $[-n + 1, n - 1]$ 、$row + col$ の範囲は $[0, 2n - 2]$ で。したがって、主対角線と副対角線の数はいずれも $2n - 1$ であり、配列 `diags1``diags2` の長さもともに $2n - 1$ です。
```src
[file]{n_queens}-[class]{}-[func]{n_queens}
```
$n$ 個のクイーンを行ごとに配置し、列制約を考慮して、最初の行から最後の行まで$n$、$n-1$、$\dots$、$2$、$1$ の選択肢があり、$O(n!)$ 時間を使用します。解を記録する際、行列 `state` をコピーして `res` に追加する必要があり、コピー操作は $O(n^2)$ 時間を使用します。したがって、**全体の時間計算量は $O(n! \cdot n^2)$ です**。実際には、対角線制約に基づく剪定により検索空間を大幅に削減できるため、多くの場合、検索効率は上記の時間計算量よりも優れています。
行ごとに $n$ 回配置し、列制約を考慮すると、1 行目から最行までの選択肢はそれぞれ $n$、$n-1$、$\dots$、$2$、$1$ 個となるため、時間計算量は $O(n!)$ す。解を記録する際には、行列 `state` をコピーして `res` に追加する必要があり、このコピー操作は $O(n^2)$ 時間をします。したがって、**全体の時間計算量は $O(n! \cdot n^2)$** です。実際には、対角線制約による枝刈りも探索空間を大きく縮小できるため、探索効率はしばしば上記の時間計算量より良くなります。
配列 `state` は $O(n^2)$ 空間を使用し、配列 `cols``diags1``diags2`それぞれ $O(n)$ 空間を使用します。最大再帰深は $n$ で、$O(n)$ のスタックフレーム空間を使用します。したがって、**空間計算量は $O(n^2)$ です**
配列 `state` は $O(n^2)$ 空間を使用し、配列 `cols``diags1``diags2`いずれも $O(n)$ 空間を使用します。最大再帰深は $n$ で、スタックフレーム空間として $O(n)$ を使用します。したがって、**空間計算量は $O(n^2)$** です。