1 / 28

Логическое программирование

Логическое программирование. Факультет Прикладной математики и физики Кафедра Вычислительной математики и программирования Московский авиационный институт (государственный технический университет). Пример. Описание условия. door(a,b). door(b,c). door(b,d). door(c,d). door(d,e).

feryal
Download Presentation

Логическое программирование

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Логическое программирование Факультет Прикладной математики и физики Кафедра Вычислительной математики и программирования Московский авиационный институт (государственный технический университет)

  2. Пример

  3. Описание условия door(a,b). door(b,c). door(b,d). door(c,d). door(d,e). door(d,f). door(f,g). door(h,i). move(X,Y) :- door(X,Y); door(Y,X).

  4. Наивное решение path(X,X). path(X,Y) :- move(X,Z), path(Z,Y).

  5. Предотвращение петель • Идея борьбы с зацикливанием – использовать список уже посещённых вершин и не посещать их повторно path(X,Y) :- path(X,Y,[X]). path(X,X,_). path(X,Y,L) :- move(X,Z), not(member(Z,L)), path(Z,Y,[Z|L]).

  6. Задача поиска пути в графе • Графом (точнее, направленным графом) называется пара <U,V>, где U — множество вершин, VU× U — множество дуг. • В отличие от конечных графов, которые могут быть заданы матрицей смежности, мы будем рассматривать потенциально бесконечные графы, задаваемые генератором вершин move/2(in,out) • Путем в графе G=<U,V> из вершины aU в вершину bU называется последовательность {xi}i=0n, xi U, где x0=a, xn=b, и  i  <xi-1,xi> V. Задача поиска в графе ставится следующим образом: Пусть имеется граф G, заданный предикатом move/2. Необходимо по двум заданным вершинам a и b найти все пути (один путь, кратчайший путь и т.д.) из a в b в графе G.

  7. Представление задачи в виде графа door(a,b). door(b,c). door(b,d). door(c,d). door(d,e). door(d,f). door(f,g). door(h,i). move(X,Y) :- door(X,Y); door(Y,X).

  8. Совершенствуем поиск - 1 path(X,Y) :- path(X,Y,[X]). path(X,X,_). path(X,Y,L) :- move(X,Z), not(member(Z,L)), path(Z,Y,[Z|L]). path(X,Y,P) :- path(X,Y,[X],P). path(X,X,L,L). path(X,Y,L,R) :- move(X,Z), not(member(Z,L)), path(Z,Y,[Z|L],R).

  9. Совершенствуем поиск - 2 path(X,Y,P) :- path(X,Y,[X],P). path(X,X,L,L). path(X,Y,L,R) :- move(X,Z), not(member(Z,L)), path(Z,Y,[Z|L],R). path(X,Y,P) :- path1([X],Y,P). path1([X|T],X,[X|T]). path1([X|T],Y,R) :- move(X,Z), not(member(Z,[X|T])), path([Z,X|T],Y,R).

  10. Совершенствуем поиск - 3 path(X,Y,P) :- path1([X],Y,P). path1([X|T],X,[X|T]). path1([X|T],Y,R) :- move(X,Z), not(member(Z,[X|T])), path1([Z,X|T],Y,R). path(X,Y,P) :- path1([X],Y,P). prolong([X|T],[Y,X|T]) :- move(X,Y), not(member(Y,[X|T])). path1([X|T],X,[X|T]). path1(P,Y,R) :- prolong(P,P1), path1(P1,Y,R).

  11. Поиск в глубину (Depth-First Search, DFS) • Поиск в глубину напоминает алгоритм действий заблудившегося в лабиринте человека • На каждом перекрестке идем по первой стене • В случае неудачи возвращаемся на шаг назад и пробуем другое направление path(X,Y,P) :- path1([X],Y,P). prolong([X|T],[Y,X|T]) :- move(X,Y), not(member(Y,[X|T])). path1([X|T],X,[X|T]). path1(P,Y,R) :- prolong(P,P1), path1(P1,Y,R).

  12. Поиск в глубину – дерево обхода

  13. Особенности • Расход по памяти – O(n) • Первым находится не обязательно кратчайший путь • Даже есть есть короткий путь к решению – он может быть не найден, а будут исследоваться длинные тупиковые ветки • Пример – кубик рубика • Естественная (простая) реализация алгоритма – за счет схожести механизмов обхода и вывода • Обход дерева вывода также делается в глубину!

  14. Алгоритм фронта волны (Форда-Фалкерсона) • Идея – параллельно рассматривать все возможные пути по мере возрастания длины • [a] • [ab] • [abc] [abd] • [abcd] [abdc] [abdf] [abde] • [abcde] [abcdf] [abdfg] • [abcdfg] • Изначально алгоритм ФФ формулировался для матриц смежности => не подходит для потенциально бесконечных графов

  15. Поиск в ширину - идея • Алгоритм ФФ подразумевает построение по множеству путей (фронту) длины n следующего фронта длины (n+1) • Такое продление требует на каждом шаге: • Рассматривать все текущие пути длины n • Для каждого генерировать множества всех продлений • Объединять результат • Идея свести двойное продление к одинарному • Вводим очередь путей на продление!

  16. Поиск в ширину • [a] — очередь из одной исходной вершины • [a,b] • [a,b,c], [a,b,d] • [a,b,d], [a,b,c,d] • [a,b,c,d], [a,b,d,e], [a,b,d,f] • [a,b,d,e], [a,b,d,f], [a,b,c,d,e], [a,b,c,d,f] • [a,b,d,f], [a,b,c,d,e], [a,b,c,d,f] — тупиковый путь [a,b,d,e] убирается из очереди • [a,b,c,d,e], [a,b,c,d,f], [a,b,d,f,g] • [a,b,c,d,f], [a,b,d,f,g] — тупиковый путь [a,b,c,d,e] убирается из очереди • [a,b,d,f,g], [a,b,c,d,f,g] • [a,b,c,d,f,g] — получено первое решение [a,b,d,f,g], убирается из очереди • [] — получено второе решение [a,b,c,d,f,g], убирается из очереди

  17. Как построить список всех продлений пути P? • Если prolong завершается неуспехом (тупик), то findall также завершается неуспехом • Хотя логичнее было бы возвращять [] ?- finall(X, prolong(P,X), L).

  18. Поиск в ширину • Первым находит кратчайший путь • Алгоритм выглядит менее естественно, требует явного хранения путей в очереди и рассмотрения множественных вариантов • Низкая степень декларативности • Позволяет искать в путях с циклами path(X,Y,P):- bdth([[X]],Y,P). bdth([[X|T]|_],X,[X|T]). bdth([P|QI],X,R) :- findall(Z,prolong(P,Z),T), append(QI,T,QO),!, bdth(QO,X,R). bdth([_|T],Y,L) :- bdth(T,Y,L).

  19. Сравнение

  20. Сравнение

  21. Найдите отличие! path(X,Y,P):- bdth([[X]],Y,P). bdth([[X|T]|_],X,[X|T]). bdth([P|QI],X,R) :- findall(Z,prolong(P,Z),T), append(QI,T,QO),!, bdth(QO,X,R). bdth([_|T],Y,L) :- bdth(T,Y,L). path(X,Y,P):- bdth([[X]],Y,P). bdth([[X|T]|_],X,[X|T]). bdth([P|QI],X,R) :- findall(Z,prolong(P,Z),T), append(Т,QI,QO),!, bdth(QO,X,R). bdth([_|T],Y,L) :- bdth(T,Y,L).

  22. Можно ли достичь идеала? • Нахождение кратчайших путей первыми? • Требования по памяти – O(lmax) • Поиск в графах с циклами

  23. Поиск с ограничением длины • Чтобы избежать зацикливания поиска в ширину, ограничим глубину погружения параметром DepthLimit • Если постепенно увеличивать этот параметр на 1, то получим поиск, в котором находится первым кратчайший путь search_id(Start,Finish,Path,DepthLimit) :- depth_id([Start],Finish,Path,DepthLimit). depth_id([Finish|T],Finish,[Finish|T],_). depth_id(Path,Finish,R,N) :- N>0, prolong(Path,NewPath), N1 is N-1, depth_id(NewPath,Finish,R,N1).

  24. Поиск с итерационным заглублением • Сложность: • Для пути длины l поиск происходит l+1раз • Первая вершина обходится (l+1) раз, второй уровень – l раз и т.д. • (l+1)*1 + l*b + (l-1)*b2 + … + 1*bl = O(bl) • Поиск в глубину по сложности не сильно превосходит поиск в ширину, сохраняя все его положительные стороны и исключая требования к памями. search_id(Start,Finish,Path):- integer(Level), search_id(Start,Finish,Path,Level). integer(1). integer(M) :- integer(N), M is N+1.

  25. Библиотека поиска на Mercury :- module search. :- interface. :- import_module std_util, list. • Основные типы данных и сопутствующие элементы: :- type path(N) == list(N). :- type graph(N) == pred(N,N). :- inst graph == (pred(in,out) is nondet). :- pred search_dpth(graph(N),N,N,path(N)). :- mode search_dpth(in(graph), in,in,out) is nondet. :- pred search_bdth(graph(N),N,N,path(N)). :- mode search_bdth(in(graph), in,in,out) is nondet.

  26. Реализация поиска на Mercury :- implementation. :- import_module queue. :- pred prolong(graph(N), path(N), path(N)). :- mode prolong(in(graph), in, out) is nondet. prolong(G,[X|T],[Y,X|T]) :- G(X,Y), not(member(Y,[X|T])). search_dpth(G,A,B,R) :- dpth(G,[A],B,R).:- pred dpth(graph(N),path(N),N,path(N)). dpth(_,[X|T],X,[X|T]). dpth(G,P,F,L) :- prolong(G,P,P1), dpth(G,P1,F,L). search_bdth(G,A,B,R) :- bdth(G,put(init,[A]),B,R).:- pred bdth(graph(N), queue(path(N)), N, path(N)). bdth(_,Q,X,[X|T]) :- first(Q,[X|T]). bdth(G,Q,Y,R) :- get(Q,P,T), solutions(lambda([Z::out] is nondet,prolong(G,P,Z)),L), bdth(G,put_list(T,L),Y,R).

  27. Решение задач методом поиска в пространстве состояний B C E D A s(<положение обезьяны>,<полож.ящика>,<внизу/вверху>,<есть ли банан>) s(a,c,down,no)

  28. Обезьяна и банан • Проследите за перемещением обезьяны! • Реальные перемещение не будут совпадать с последовательностью вызовов move, поскольку будут откаты • В ширину vs. в глубину vs.погружение – ответ сразу не очевиден! move(s(A,B,down,YN),s(C,B,down,YN)) :- vertex(C). move(s(A,A,down,YN),s(B,B,down,YN)) :- vertex(B). move(s(A,A,UD,YN),s(A,A,DU,YN)) :- permute([DU,UD],[down,up]). move(s(e,e,up,no),s(e,e,up,yes)).

More Related