Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ii_otvety_2012.doc
Скачиваний:
23
Добавлен:
27.09.2019
Размер:
551.42 Кб
Скачать

16. Поиск с итерационным погружением (id).

Программа поиска в глубину с ограничением по глубине вглубину2( Верш, [Верш], _ ) :-

цель( Верш).

вглубину2(Верш, [Верш | Реш], МаксГлуб) :-

МаксГлуб > 0,

после( Верш, Верш1), Maкс1 is МаксГлуб - 1, вглубину2( Верш1, Реш, Maкс1).

Для того, чтобы предотвратить бесцельное блуждание по бесконечным ветвям, мы можем добавить в базовую процедуру поиска в глубину еще одно усовершенствование, а именно, ввести ограничение на глубину поиска. Процедура поиска в глубину будет тогда иметь следующие аргументы:вглубину2( Верш, Решение, МаксГлуб)Не разрешается вести поиск на глубине большей, чем МаксГлуб. Программная реализация этого ограничения

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

17. Различные способы повышения эффективности алгоритмов поиска: поиск с использованием списка пар пройденных вершин, представление путей деревьями.

Пр: t(a, [t(b,[l(c),t(d, l(e), l(f)])])]) Сам алгоритм: search_t(A,B, P):-t_search(B, l(A), P). T_search(F, T, P):-expand(F,[ ], T, T1, P), (nonvar(P); var(P), t_search(F, T1,P)). //продление дерева, вторая переменная – текущий путь в рассматрив. Дереве// expand(F, Past, l(F), _ , [F|Past]). Expand(_, Past, l(C), t(c, S), _ ):- findall(X, t_prolong([C | Past], X), S). T_prolong([C

| P], l(z)):-move(C, Z), not (member(Z, [C | P])). Expand(F, P, t(C, S), t(C, S1), P):- expand_all(F, [C | P], S, [ ], S1, P). Expand_all( _ , _ , [ ] , X, X, _). Expand_all(F, PD, [T | TT

], TT), S1, P) :- expand(F, PD, T, T1, P), (nonvar P); var(P), expand_all ( F, PD, T, [ T | TT1], S, P), expand_all(F, PD, TT , TT1, S, P)).Search(A, D, P):-search([p(A, nil)], [], B, R, C ), reconstruct(R, C, P). //R-последняя пара вершин, C – список посещенных пар вершин, котор. Получаются после поиска // search([ p (Y, Z) | _], C, Y, p(Y, Z), C). Search( [ p(S, P) | Q ], C, Y, R, CC):-findall(Z, prolong1(S, Q, C, Z), L), append(Q, L, Q1), ! , search(Q1, [p(S, P) | C], T, R, CC). //в пролонге S – мн-во пар посещ. В-н, Q – мн-во пар в очереди, C – текущая вершина Z – возвр. мн-во пар для возвр. в очередь. // prolong1(S, A, C, p(X, S)):-move(S, X), not (member(p(X, _ | Q)), not (member ( p (X, _ ), C )). reconstruct ( p(X, nil), _, [ X ]). Reconstruct( p(X, Y), L, [X|T]):-member (p(Y, Z), L), reconsturct (p(Y, Z), L, T).

Древовидное представление множества кандидатов программы поиска в ширину. 1) Дерево состоит только из одной вершины В; В этом случае оно имеет вид терма л( В); Функтор л указывает на то, что В - это лист дерева. 2) Дерево состоит из корневой вершины В и множества поддеревьев Д1, Д2, ... . Такое дерево представляется термом д( В, Пд), где Пд - список поддеревьев: Пд = [ Д1, Д2, ...] Множество путей-кандидатов в случае спискового представления имеет вид: [ [d, b, a], [e, b, а], [f, c, a], [g, c, a] ]. В виде дерева это множество выглядит так: д( а, [д( b, [л( d), л( е)] ), д( с, [л( f), л( g)] )]).

Ключевую роль в нашей программе будет играть отношение .расширить( Путь, Дер, Дер1, ЕстьРеш, Решение)-При каждом обращении к расширить переменные Путь и Дер будут уже конкретизированы. Дер - поддерево всего дерева поиска, одновременно оно служит для представления множества путей-кандидатов внутри этого поддерева. Путь - это путь, ведущий из стартовой вершины в корень поддерева Дер. Самая общая идея алгоритма.

Отношение paсширить(Путь, Дер, Дер1, ЕстьРеш, Решение): s - стартовая вершина, g - целевая вершина. Решение - это Путь, продолженный вплоть до g. Дер1 - результат расширения дерева Дер на один уровень вниз.получить поддерево Дер1 как результат расширения Дер на один уровень. Но в случае, когда в процессе расширения поддерева Дер встретится целевая вершина, процедура расширить должна сформировать соответствующий решающий путь.Итак, процедура расширить будет порождать два типа результатов.

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

2) ЕстьРеш = нет , Дер1 = результат расширения поддерева Дер на один уровень вниз от своего "подножья". Дер1 не содержит ни одной "тупиковой" ветви из Дер, т. е. такой ветви, что она либо не может быть продолжена из-за отсутствия преемников, либо любое ее продолжение приводит к циклу. Решение = неконкретизировано.

Если в дереве Дер нет ни одной целевой вершины и, кроме того, оно не может быть расширено, то процедура расширить терпит неудачу. Процедура верхнего уровня для поиска в ширину вширину(Дер, Решение)отыскивает Решение либо среди множества кандидатов Дер, либо в его расширении. Расширитьвсе- расширяет все деревья из некоторого списка, и затем, выбросив все "тупиковые" деревья", собирает все полученные расширенные деревья в один новый список.

решить( Старт, Решение) :-

вширину( л( Старт), Решение). вширину( Дер, Решение) :-

расширить( [ ], Дер, Дер1, ЕстьРеш, Решение), ( ЕстьРеш = да;

ЕстьРеш = нет, вширину( Дер1, Решение) ).

расширить( П, Л( В), _, да, [В | П] ) :-

цель( В).

расширить( П, Л( В), д( В, Пд), нет, _ ) :- bagof( л( B1),

( после( В, B1), not принадлежит( В1, П)), Пд).

расширить( П, д( В, Пд), д( В, Пд1), ЕстьРеш, Реш) :-

расширитьвсе( [В | П], Пд, [ ], Пд1, ЕстьРеш, Реш).

расширитьвсе( _, [ ], [Д | ДД], [Д | ДД], нет, _ ).

% По крайней мере одно дерево должно вырасти расширитьвсе( П, [Д | ДД], ДД1, Пд1, ЕстьРеш, Реш) :-

расширить ( П, Д, Д1, ЕстьРеш1, Реш), ( ЕстьРеш 1= да, ЕстьРеш = да;

ЕстьРеш1 = нет, !,расширитьвсе( П, ДД, [Д1 | ДД1], Пд1, ЕстьРеш, Реш));

расширитьвсе( П, ДД, ДД1, Пд1, ЕстьРеш, Реш ).

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