Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Conspekt.doc
Скачиваний:
11
Добавлен:
31.08.2019
Размер:
1.39 Mб
Скачать

5.18.5 Поиск в глубину

Будем представлять пространство состояний при помощи отношения:

after(X,Y) - после(X,Y) - выполняется, если Y на графе

будет находиться после X.

Т.е. существует разрешенный

ход из Х в У.

after(a,b). - можно описать граф.

after(b,c).

after(c,d).

after(c,e).

Если граф простой, то нужно так и поступить. Можно также граф ввести в виде списка и с помощью assert() добавить в БД. Однако такой способ нереален для достаточно сложных пространств. Поэтому отношение 2 после 0 определяют неявно при помощи правил вычисления вершин приемников. Другая проблема – способ представления самих вершин, т.е. состояний.

Существует много различных подходов к проблеме поиска решающего пути. Начнем с поиска в глубину. Будем использовать предикат  2решить 0 для нахождения пути из вершины В в целевую вершину:

solve(B,R) - решить(B,Реш) - здесь B - исходная вершина

R - путь от В до цели

Реш

B ЗКР B1 ОТК G

Решение м. найти, если существует вершина В1 после В и существует путь от вершины В1 к целевой вершине G.

Реш - последовательность вершин в обратном порядке.

solve(B, [ B|R ]) :- goal(B).

solve(B, [ B1|R ]) :- after(B,B1), solve(B1,R).

B B1 G

- Наличие такой петли в графе

приведет к зацикливанию пре-

диката т.к. after(B1,B1) всег-

да истинно.

Модифицируем алгоритм : введем список, в котором будут накапливаться имена вершин, через которые мы прошли, и будем проверять, содержится ли очередная вершина в этом списке. Т.о., мы приходим к ранее рассмотренным понятиям списков открытых и закрытых вершин (ОТК и ЗКР), которые содержат соответственно уже пройденные вершины и вершины, которые еще только предстоит пройти.

solve(B,R) :-

deep_sch( [], B, R).

deep_sch(ZKR, B, [ B|R ]) :-

goal(B).

deep_sch(ZKR, B, R) :-

after(B,B1),

not element(B1,ZKR), deep_sch( [ B|ZKR], B1,R).

Этот алгоритм можно более приблизить к алгоритму поиска в глубину, написанному на ЛИСПе, если исходную вершину сразу помещать в начало списка ЗКР, т.е. [ B|ZKR ].

было:

deep_sch( ZKR, B, R).

станет:

deep_sch( [B,ZKR], R)

W - (way) - назовем это " путь "

deep_sch( W, R).

Еще один вариант программы, если Аргумент ЗКР и Верш можно объединить в один список:

deep_sch_1( [B|ZKR], [B|R]):- goal(B).

deep_sch_1( [B|ZKR], R) :-

after(B,B1),

not element(B1,[B|ZKR]),

deep_sch_1(B1, [B|ZKR], R).

Устранение тупиков: ограничим поиск в глубину уровнем поиска:

L - уровень поиска = 3

_______________________________1_

_______________________2_

____3_

Определим такой предикат, причем проверку на петлю теперь можно устранить, т.к. нам не важно из-за чего произошел тупик, а выход из тупика после 3-х прохождений по ветвям мы предусмотрим.

в_глубину_2(Верш, Реш, МаксГлуб).

deep_sch_2(B, [B], _) :- goal(B).

deep_sch_2(B, R, MaxDeep) :-

MaxDeep > 0,

after(B,B1),

Max is MaxDeep - 1,

deep_sch(B1, [B|R], Max).

Программная реализация этого ограничения сводится к уменьшению на 1 величины предела глубины при каждом рекурсивном обращении и проверке того, что этот предел не стал отрицательным.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]