Идея двунаправленного поиска заключается в том, что одновременно осуществляются два поисковых процесса: вперед из начального состояния и назад из целевого состояния. Оба процесса завершаются одновременно в момент "встречи".
При практической реализации двунаправленного поиска необходимо решить ряд проблем.
§ Что такое поиск в обратном направлении от целевого состояния? Предками (predecessors) узла n называются все те узлы, для которых n является наследником (successor). Поиск в обратном направлении означает последовательную генерацию предков, начиная с целевого узла.
§ Когда все операторы обратимы, множества предков и наследников идентичны, однако для некоторых проблем генерация узлов-предков может быть очень трудной задачей.
§ Что делать, если имеется несколько целевых состояний?
§ Должен существовать эффективный способ проверки каждого нового узла, чтобы обнаружить, не появился ли он на противоположном дереве поиска.
Необходимо решить какой тип поиска применять для каждого из деревьев.
|
|
Рекурсия
В математике рекурсивное определение объекта — это его описание в терминах частей этого же определения. В информатике рекурсия используется для определения и анализа структур данных и процедур. Рекурсивная процедура состоит из следующих этапов.
1. Рекурсивный шаг: вызов процедуры из этой же процедуры для повторения после
довательности действий.
2. Условие, которое обеспечивает выход из процедуры и таким образом предотвра
щает зацикливание (рекурсивная версия бесконечного цикла).
Оба этих компонента необходимы и появляются во всех рекурсивных определениях и алгоритмах. Рекурсия — естественный инструмент управления массивами данных, которые имеют правильную структуру и неопределенный размер, например, списками, деревьями и графами. Рекурсия особенно удобна для поиска в пространстве состояний.
Прямое преобразование алгоритма поиска в глубину в рекур-
сивную форму иллюстрирует эквивалентность рекурсии и итерационного подхода.
Этот алгоритм для поддержки списка состояний использует глобальные переменные
open и closed:
function depthsearch; %переменные open и closed глобальные
Begin
if список open пуст
then return FAIL;
current_state:= первый элемент списка open;
if current_state равно целевому состоянию
then return SUCCESS
else
Begin
open:= хвост списка open;
closed:= closed с добавлением current_state;
для каждого потомка current_state
if не в списке closed или open
%построение стека
then добавить потомок в начало списка open
end;
depthsearch %рекурсивный вызов
End.
Поиск в ширину можно описать фактически тем же самым алгоритмом. При этом не-
обходимо сохранять список closed как глобальную структуру данных и рассматривать
список open как очередь, а не как стек.
|
|
Из представленного алгоритма ясно, что поиск в глубину не использует все возмож-
ности рекурсии. Процедуру можно упростить, используя рекурсию непосредственно (а
не через список open) для рассмотрения состояний и нахождения путей в их простран-
стве. В новой версии алгоритма глобальная переменная closed используется для обна-
ружения повторяющихся состояний и предотвращения циклов. Список open неявно ис-
пользуется в записях активации рекурсивной среды.
function depthsearch (current__state);
%closed — глобальная переменная
begin
if current_state равно целевому состоянию
then return SUCCESS;
добавить current_state в список closed;
while current_state имеет непроверенные потомки
begin
child:= следующий непроверенный потомок;
if потомок не член списка closed
then if depthsearch(child) = SUCCESS
then return SUCCESS
end;
return FAIL %поиск исчерпан
end
Вместо того чтобы находить все потомки данного состояния, а затем помещать их в список open, этот алгоритм рассматривает потомки по одному. Для каждого из них ре-
курсивно находятся все потомки, а затем рассматривается очередной потомок исходного
состояния. Следует заметить, что алгоритм предполагает определенный порядок опера-
торов генерации состояний. Если при рекурсивном поиске некоторый потомок является
целевым состоянием, то процедура поиска успешно завершается, и, естественно, алго-
ритм игнорирует братьев данного потомка. Если рекурсивный вызов для одного из по-
томков приведет в тупик, то будет рассмотрен брат этого потомка, а также все его по-
томки.
Заданиe:
В приведенном ниже плане лабиринте буквой А помечен мобильный агент, буквой В выход из лабиринта. Цель агента – выйти из лабиринта.
Список возможных действий агента в порядке уменьшения приоритета:
<ШагНаСевер (), ШагНаВосток(®), ШагНаЮг(¯), ШагНаЗапад(), ШагНазад>.
Из всех возможных действий агент выбирает самое приоритетное.
При выполнении каждого шага, не являющегося шагом назад, Агент отмечает его стрелочкой. Действие невозможно, если есть препятствие, мешающее его выполнению. Такими препятствиям являются: стены и границы лабиринта, а также стрелочки. Действие «ШагНазад» реализует шаг бэктрекинга (возврата по ранее пройденному пути).
В | |||||||||
А | |||||||||
а) Начертить траекторию движения агента.
б) Указать, какая стратегия поиска целевого состояния им используется (по варианту).
в) Написать программу реализующую поведение агента.(программирование реалитзовать в среде Delphi).
Варианты:
- поиск от цели в ширину;
- поиск от цели в глубину;
- поиск на основе данных в ширину;
- поиск на основе данных в глубину;
- рекурсивный поиск от цели в ширину;
- рекурсивный поиск от цели в глубину;
- рекурсивный поиск на основе данных в ширину;
- рекурсивный поиск на основе данных в глубину;
- двунаправленный поиск;
- рекурсивный поиск от цели в ширину;