Более эффективный поход состоит в поиске только
Это будет означать, что последнего ферзя мы разместили неправильно. Потому нам придется
function queens(board)
····if board.has_8_queens
········return board
····for each position in board.unattacked_positions
········board.place_queen(position)
········solution ← queens(board)
········if solution
············return solution
········board.remove_queen(position)
····return False
Рис. 3.7. Размещение ферзей ограничивает число приемлемых клеток для следующих фигур
Если требуемое по условию сочетание позиций на доске еще не найдено, функция обходит все приемлемые позиции для следующего ферзя. Она использует рекурсию, чтобы проверить, даст ли размещение ферзя в каждой из этих позиций решение. Как работает процесс, показано на рис. 3.8.
Поиск с возвратом лучше всего подходит для задач, где решением является последовательность вариантов, и выбор одного из них ограничивает выбор последующих. Этот подход позволяет выявлять варианты, которые не дают желаемого решения, так что вы можете отступить и попробовать что-то еще.
Рис. 3.8. Поиск с возвратом в «Задаче о восьми ферзях»
3.5. Эвристические алгоритмы
В обычных шахматах — 32 фигуры шести типов и 64 клетки, по которым они ходят. После каких-то четырех первых ходов число возможных дальнейших позиций достигает 288 млрд. Даже самые сильные игроки в мире не в состоянии найти идеальный ход. Они полагаются на интуицию, чтобы найти тот, который окажется
«Жадные» алгоритмы
Очень распространенный эвристический подход к решению задач — использование так называемых
Жадный грабитель и рюкзак
В сущности, оптимальное решение здесь должно быть ровно таким же, что и в задаче о рюкзаке. Однако у грабителя нет времени для перебора всех комбинаций упаковки рюкзака, ему некогда постоянно откатываться назад и вынимать уже уложенные в рюкзак вещи! Жадина будет совать в рюкзак самые дорогие предметы, пока не заполнит его:
function greedy_knapsack(items, max_weight)
····bag_weight ← 0
····bag_items ← List.new
····for each item in sort_by_value(items)
········if max_weight ≤ bag_weight + item.weight
············bag_weight ← bag_weight + item.weight