Вот простая реализация Java наивного рекурсивного алгоритма;это должно быть поучительно.
public class NQueens {
final static int N = 4;
static int[] position = new int[N];
public static void main(String[] args) {
solve(0);
}
static boolean isSafe(int k, int p) {
// for (int i = 1; i <= k; i++) {
// int other = position[k - i];
// if (other == p || other == p - i || other == p + i) {
// return false;
// }
// }
return true;
}
static void solve(int k) {
if (k == N) {
System.out.println(java.util.Arrays.toString(position));
} else {
for (char p = 0; p < N; p++) {
if (isSafe(k, p)) {
position[k] = p;
solve(k+1);
}
}
}
}
}
Обратите внимание, что isSafe
содержит закомментированные строки прямо сейчас;это сделано специально.С этими комментариями программа становится рекурсивным генератором кортежей N
, где каждое значение находится между 0
(включительно) и N
(эксклюзивом).Таким образом, программа как есть генерирует следующий вывод:
[0, 0, 0, 0]
[0, 0, 0, 1]
[0, 0, 0, 2]
[0, 0, 0, 3]
[0, 0, 1, 0]
[0, 0, 1, 1]
[0, 0, 1, 2]
[0, 0, 1, 3]
:
:
[3, 3, 3, 0]
[3, 3, 3, 1]
[3, 3, 3, 2]
[3, 3, 3, 3]
Эта генерация кортежа N
является конкретной подзадачей проблемы NQueens.Уже есть много вопросов о стековом потоке о том, как написать N
-несложенные циклы, когда вы не знаете, что такое N
.Я чувствую, что необходимо временно остановиться на этой проблеме и сначала понять ее решение, а isSafe
закомментировано просто return true;
, чтобы сначала почувствовать, что делает рекурсия.
Как только выВам удобно, что этот генератор рекурсивных кортежей работает, просто раскомментируйте эти строки, и вы получите простой, наивный, но работающий решатель NQueens.Если строки N=5
и isSafe
не закомментированы, программа генерирует следующий вывод:
[0, 2, 4, 1, 3]
[0, 3, 1, 4, 2]
[1, 3, 0, 2, 4]
[1, 4, 2, 0, 3]
[2, 0, 3, 1, 4]
[2, 4, 1, 3, 0]
[3, 0, 2, 4, 1]
[3, 1, 4, 2, 0]
[4, 1, 3, 0, 2]
[4, 2, 0, 3, 1]
Каждая строка является решением проблемы 5 ферзей.i
-й элемент массива обозначает позицию строки i
-й королевы, помещенной в i
-й столбец (все индексы основаны на 0).Итак, первое решение на доске выглядит следующим образом:
[0,2,4,1,3]
Q · · · ·
· · · Q ·
· Q · · ·
· · · · Q
· · Q · ·
Я оставлю это в качестве упражнения, чтобы понять, почему isSafe
работает, и как печатать макет платы, и как реализовать быстрее, ноболее сложные рекурсивные алгоритмы.
Счастливого обучения.