2014 dxdy logo

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

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




Начать новую тему Ответить на тему
 
 Обход доски конём
Сообщение02.05.2006, 15:44 


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

 Профиль  
                  
 
 
Сообщение02.05.2006, 15:54 
Основатель
Аватара пользователя


11/05/05
4312
Если найдете в инете книгу Вирт Н. — Алгоритмы+структуры данных=программы, то посмотрите там пункт 3.4. В нем все подробно написано.

 Профиль  
                  
 
 
Сообщение02.05.2006, 16:04 
Экс-модератор
Аватара пользователя


23/12/05
12064
Не знаю, что советует Вирт, я бы реализовал для перебора рекурсивную функцию, на вход которой подается текущее положение и перечень клеток, на которых уже побывал конь. А в теле функции искал бы возможные ходы, по каждому возможному ходу снова запуская эту функцию. Если ходов нет и еще не все клетки обошли - эта ветка закрывается. Если ходов нет и все клетки обошли - ура - найдено решение, записываем результат.

 Профиль  
                  
 
 
Сообщение02.05.2006, 19:01 
Заслуженный участник
Аватара пользователя


17/10/05
3709
: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 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group