SICP содержит частично полный пример решений с n ферзями, путем обхода дерева всех возможных размещений ферзей в последней строке, генерирования большего количества возможных позиций в следующей строке для объединения результатов на данный момент, фильтрации возможностей для сохранения только тех, где новейшая королева безопасна и повторяется рекурсивно.
Эта стратегия взрывается примерно после n = 11 с максимальной ошибкой рекурсии.
Я реализовал альтернативную стратегию, которая делает более разумный обход дерева из первого столбца, генерируя возможные позиции из списка неиспользуемых строк, объединяя каждый список позиций в обновленный список еще неиспользованных строк. Фильтрация тех пар, которые считаются безопасными, и рекурсивное сопоставление этих пар для следующего столбца. Это не взорвалось (пока), но n = 12 занимает минуту, а n = 13 занимает около 10 минут.
(define (queens board-size)
(let loop ((k 1) (pp-pair (cons '() (enumerate-interval 1 board-size))))
(let ((position (car pp-pair))
(potential-rows (cdr pp-pair)))
(if (> k board-size)
(list position)
(flatmap (lambda (pp-pair) (loop (++ k) pp-pair))
(filter (lambda (pp-pair) (safe? k (car pp-pair))) ;keep only safe
(map (lambda (new-row)
(cons (adjoin-position new-row k position)
(remove-row new-row potential-rows))) ;make pp-pair
potential-rows)))))))
;auxiliary functions not listed
На самом деле не ищу кода, а просто объясняю пару стратегий, которые менее наивны и хорошо подходят для функционального подхода.
mit-scheme --stack <number-of-1024-blocks>
. Я знаю, это не отвечает на ваш вопрос об алгоритме. - person GoZoner   schedule 10.06.2013