2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 Обход доски конём
Сообщение02.05.2006, 15:44 
Есть задача: нужно обойти доску конём (каждую клетку ровно один раз) и вернуться в исходную клетку. Реализовывать предполагается на чистом функциональном языке? Как бы это лучше организовать.. Тут всё, по-моему, сводится к полному перебору. Какой вариант посоветуете? Я думал о рекурсивном переборе с возвратом... Тем не менее, реализация у меня страдает -- так как с computer science туго. Может быть кто-то может написать решение псевдокодом?

 
 
 
 
Сообщение02.05.2006, 15:54 
Аватара пользователя
Если найдете в инете книгу Вирт Н. — Алгоритмы+структуры данных=программы, то посмотрите там пункт 3.4. В нем все подробно написано.

 
 
 
 
Сообщение02.05.2006, 16:04 
Аватара пользователя
Не знаю, что советует Вирт, я бы реализовал для перебора рекурсивную функцию, на вход которой подается текущее положение и перечень клеток, на которых уже побывал конь. А в теле функции искал бы возможные ходы, по каждому возможному ходу снова запуская эту функцию. Если ходов нет и еще не все клетки обошли - эта ветка закрывается. Если ходов нет и все клетки обошли - ура - найдено решение, записываем результат.

 
 
 
 
Сообщение02.05.2006, 19:01 
Аватара пользователя
:evil:
Если язык очень чисто функциональный, то списка посещений нет. Вместо него используется функция, возвращающая побывали ли мы на этом поле. А во время рекурсии эта функция "поправляется" (на весьма условно языке-гибриде):
Код:
travest = lambda(current, length, checkvisited, printtrace) (
  newcheck = lambda(pos) (
       (pos == current) OR checkvisited(pos)
  )
  newprint = lambda() (
     print(current)
     printtrace()
  )
  if (validpos(current) AND NOT checkvisited(current),
     if(length >= 64, complete_execution(newprint))
     travest(move1(current), length + 1, newcheck, newprint)
     travest(move2(current), length + 1, newcheck, newprint)
     travest(move3(current), length + 1, newcheck, newprint)
     ...
  )
)

validpos() проверяет, что мы не вышли за пределы доски, move1() и ей подобные делает ход, не глядя, попадаем ли мы на доску или нет. Идея все та же -- перебор с возвратом. Но функциональная тонкость -- то, что newcheck() на каждом этапе рекурсии своя (хотя и называется также). Она определяется каждый раз в новом контексте, с новыми current и checkvisited(). Тоже относится и к printtrace().

 
 
 [ Сообщений: 4 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group