|
2507 / 1483 / 37
Регистрация: 14.09.2009
Сообщений: 2,740
|
||||||||||||||||||||||||||||||||||||||||||||||
Поиск в пространстве состояний (поиск по графам тоже сюда!)01.03.2011, 19:19. Показов 37654. Ответов 4
Метки нет (Все метки)
Поскольку данные темы очень часто появляются на форуме, то тут будут подробно рассмотрены стандартные виды поиска. Многое взято из книги Сошникова "Парадигма логического программирования", куда очень советую заглянуть. Буду выкладывать коды на SWI прологе и Visual Prolog 5.2/Turbo Prolog.
Поиск в глубину. Данный поиск просто ищет любой путь между двумя состояниями, поэтому нет никаких гарантий, что он окажется кратчайшим. Можно использовать для нахождения всех путей между двумя состояниями. Применяется для не взвешенных графов. Итак, допустим у нас есть неориентированный граф И мы хотим найти все пути от вершины а до вершины с. Для начала надо задать правило одного шага move
Чтобы продлить путь на один ход, то надо найти какой шаг мы можем сделать, и во избежание зацикливания проверить, чтобы этот шаг не привел к состоянию, в котором мы уже побывали.
?- search_dpth(a,c). a -> b b -> c true Нахождение всех путей
?- search_dpth(a,c),nl,nl,nl,fail.
a -> b b -> c a -> b b -> d d -> e e -> c a -> b b -> d d -> c a -> d d -> e e -> c a -> d d -> b b -> c a -> d d -> c false. Чтобы изменить под другую задачу, то в большинстве случаев достаточно будет просто поменять предикат move. Например у нас есть шарики: Каждый из них может перемещаться только в соседнее пустой поле, или перепрыгивать в пустое поле через один шарик противоположного цвета. Надо поменять шарики местами.
Результат работы программы
?- search_dpth([b,b,b,'_',w,w,w],[w,w,w,'_',b,b,b]).
[b, b, b, _, w, w, w] -> [b, b, _, b, w, w, w] [b, b, _, b, w, w, w] -> [b, b, w, b, _, w, w] [b, b, w, b, _, w, w] -> [b, b, w, b, w, _, w] [b, b, w, b, w, _, w] -> [b, b, w, _, w, b, w] [b, b, w, _, w, b, w] -> [b, _, w, b, w, b, w] [b, _, w, b, w, b, w] -> [_, b, w, b, w, b, w] [_, b, w, b, w, b, w] -> [w, b, _, b, w, b, w] [w, b, _, b, w, b, w] -> [w, b, w, b, _, b, w] [w, b, w, b, _, b, w] -> [w, b, w, b, w, b, _] [w, b, w, b, w, b, _] -> [w, b, w, b, w, _, b] [w, b, w, b, w, _, b] -> [w, b, w, _, w, b, b] [w, b, w, _, w, b, b] -> [w, _, w, b, w, b, b] [w, _, w, b, w, b, b] -> [w, w, _, b, w, b, b] [w, w, _, b, w, b, b] -> [w, w, w, b, _, b, b] [w, w, w, b, _, b, b] -> [w, w, w, _, b, b, b] true Код целиком для SWI Prolog
Код целиком для Визуал Пролог 5.2/Турбо Пролог для графа
Код целиком для Визуал Пролог 5.2/Турбо Пролог для шариков
16
|
||||||||||||||||||||||||||||||||||||||||||||||
| 01.03.2011, 19:19 | |
|
Ответы с готовыми решениями:
4
Составление кубиков, поиск в пространстве состояний, монотонный поиск в ширину [Turbo Prolog] Поиск в пространстве состояний Задача на поиск плана в пространстве состояний |
|
2507 / 1483 / 37
Регистрация: 14.09.2009
Сообщений: 2,740
|
|||||||||||||||||||||||||||||||
| 02.03.2011, 22:02 [ТС] | |||||||||||||||||||||||||||||||
|
Поиск в ширину
Данный поиск также применяется только для не взвешенных графов, но может находить самый короткий (или при желании самый длинный) путь. Теперь у нас будет храниться не один пройденный путь, а список всех возможных путей, которые мы могли пройти. Они будет располагаться от более коротких к более длинным. Каждый из них, так же как и в поиске в ширину будет записан в обратном порядке
Также немного надо изменить вспомогательный предикат
Все пути в графе в порядке возрастания длины
?- search_bdth(a,c),nl,nl,nl,fail.
a -> d d -> c a -> b b -> c a -> d d -> e e -> c a -> d d -> b b -> c a -> b b -> d d -> c a -> b b -> d d -> e e -> c false. Если хотим наоборот, самый длинный путь, то надо поменять местами правила bdth. Все пути в графе в порядке уменьшения длины
?- search_bdth(a,c),nl,nl,nl,fail.
a -> b b -> d d -> e e -> c a -> b b -> d d -> c a -> d d -> b b -> c a -> d d -> e e -> c a -> b b -> c a -> d d -> c false. Опять же для большинства задач надо будет только переопределить предикат move, например для задачи о ханойских башнях он будет иметь вид
Результат работы программы
?- search_bdth([[1,2,3],[],[]],[[],[],[1,2,3]]).
[[1, 2, 3], [], []] -> [[2, 3], [], [1]] [[2, 3], [], [1]] -> [[3], [2], [1]] [[3], [2], [1]] -> [[3], [1, 2], []] [[3], [1, 2], []] -> [[], [1, 2], [3]] [[], [1, 2], [3]] -> [[1], [2], [3]] [[1], [2], [3]] -> [[1], [], [2, 3]] [[1], [], [2, 3]] -> [[], [], [1, 2, 3]] true Код целиком для SWI Prolog
Код целиком для Визуал Пролог 5.2/Турбо Пролог для графа
Код целиком для Визуал Пролог 5.2/Турбо Пролог про башни
10
|
|||||||||||||||||||||||||||||||
|
2507 / 1483 / 37
Регистрация: 14.09.2009
Сообщений: 2,740
|
|||||||||||||||||||||||||||||||
| 03.03.2011, 00:25 [ТС] | |||||||||||||||||||||||||||||||
|
Поиск с итерационным заглублением
Также создан для не взвешенных графов. Главным недостатком поиска в ширину является большой объем используемой памяти, а поиск с итерационным заглублением наоборот использует ее экономно. Смысл данного поиска заключается в том, что мы перебираем максимальную глубину поиска начиная от 1 и до какого-то ограничивающего числа, и для каждой такой максимальной глубины запускаем поиск в глубину с соответствующим ограничением. Таким образом сначала ищутся все пути длины 1, потом все пути длины 2, все пути длины 3 и тд. Как только обнаружиться решений, то данный найденный путь и будет кратчайший. Для начала определим предикат, генерирующий максимальную глубину поиска, т.е целые числа от 1 и дальше.
В качестве примера могу привести результат, что для ханойских башен с 5 дисками данный алгоритм работает (хотя подождать придется), а поиск в ширину уже вылетает с переполнением стека памяти. Продолжительное время работы вызвано тем, что на каждом шаге (т.е при каждом новом ограничением глубины погружения) все предыдущие результаты забываются. Рассмотрим задачу переправы через реку отца и двух сыновей. Предикат одного шага будет выглядеть так:
Результат работы программы
?- search_id([otec(left),sin1(left),sin2(left),plot(le ft)],[otec(right),sin1(right),sin2(right),plot (right)]),nl,nl,nl,fail.
[otec(left), sin1(left), sin2(left), plot(left)] -> [otec(left), sin1(right), sin2(right), plot(right)] [otec(left), sin1(right), sin2(right), plot(right)] -> [otec(left), sin1(left), sin2(right), plot(left)] [otec(left), sin1(left), sin2(right), plot(left)] -> [otec(right), sin1(left), sin2(right), plot(right)] [otec(right), sin1(left), sin2(right), plot(right)] -> [otec(right), sin1(left), sin2(left), plot(left)] [otec(right), sin1(left), sin2(left), plot(left)] -> [otec(right), sin1(right), sin2(right), plot(right)] [otec(left), sin1(left), sin2(left), plot(left)] -> [otec(left), sin1(right), sin2(right), plot(right)] [otec(left), sin1(right), sin2(right), plot(right)] -> [otec(left), sin1(right), sin2(left), plot(left)] [otec(left), sin1(right), sin2(left), plot(left)] -> [otec(right), sin1(right), sin2(left), plot(right)] [otec(right), sin1(right), sin2(left), plot(right)] -> [otec(right), sin1(left), sin2(left), plot(left)] [otec(right), sin1(left), sin2(left), plot(left)] -> [otec(right), sin1(right), sin2(right), plot(right)] Код целиком для SWI Prolog
Код целиком для Визуал Пролог 5.2/Турбо Пролог
8
|
|||||||||||||||||||||||||||||||
|
2507 / 1483 / 37
Регистрация: 14.09.2009
Сообщений: 2,740
|
||||||||||||||||||||||||||||||||||||
| 07.03.2011, 00:46 [ТС] | ||||||||||||||||||||||||||||||||||||
|
Поиск на основе весовой функции
Теперь рассмотрим поиски для нагруженных графов. Расставим веса для рассмотренного нами графа. Теперь на прологе он будет выглядеть так
Длина:[ТекущаяВершина, ПредыдущаяВершина.....НачальнаяВершина]. На Visual Prolog так нельзя, поэтому в виде w(Длина, [ТекущаяВершина, ПредыдущаяВершина.....НачальнаяВершина]), но это я только в конечном коде выложу. Теперь у нас все рассмотренные пути будут отсортированы в списке не по количество узлов, а по их длине, для этого введем дополнительные предикаты. Предикат, добавляющий новый путь в список уже сгенерированных путей на нужное место.
?- search_bst(a,c). a -> d d -> e e -> c Length of way: 15 true Все пути в порядке возрастания длины
?- search_bst(a,c),nl,nl,nl,fail.
a -> d d -> e e -> c Length of way: 15 a -> d d -> b b -> c Length of way: 15 a -> b b -> c Length of way: 17 a -> d d -> c Length of way: 18 a -> b b -> d d -> e e -> c Length of way: 27 a -> b b -> d d -> c Length of way: 30 false. Код целиком для SWI Prolog
Код целиком для Визуал Пролог 5.2/Турбо Пролог
6
|
||||||||||||||||||||||||||||||||||||
|
2507 / 1483 / 37
Регистрация: 14.09.2009
Сообщений: 2,740
|
|||||||||||||||||||||||||||||||
| 07.03.2011, 23:29 [ТС] | |||||||||||||||||||||||||||||||
|
Жадный алгоритм поиска
При поиске пути можно как-то учитывать насколько близко от финишного состояния(в смысле какого-то критерия) находиться текущее состояние. Этот критерий называется эвристической функцией или просто эвристикой. Он ставит в соответствие двум состоянием определенное число, которое характеризует "расстояние" между ними. Например для известной задачи о передвижении мебели эвристикой может быть количество предметов, которые на данном этапе стоят не на желаемых местах, а для точек на плоскости просто геометрическое расстояние между ними. В данном алгоритме поиска приоритет пути определяется не его суммарной длиной (она вообще не подсчитывается), а близостью конечной вершиной пути и заданной финишной вершиной. Допустим у нас есть набор точек на плоскости, некоторые из которых соединены между собой Эвристикой будем выступать геометрическое расстояние между ними. Данную структуру можно задать как набор точек с их координатами, и набор связывающих их линий
Результат работы программы: ?- search_grd(g,a). g -> b b -> c c -> a true . Но этот результат не правилен, правильным ответом является ?- search_bst(g,a). g -> d d -> e e -> a Length of way: 21.0984 true Т.е как мы видим, данный алгоритм не гарантирует правильности результатов. Программа получила такой ответ потому что из путей в одну дорогу наиболее приоритетным является путь g-b, т.к b ближе к финишной вершине, чем f или d. Путь g-b можно продлить только единственным способом g-b-c, и вершина c опять же оказывается не менее приоритетной, чем f или d, после чего мы просто завершаем путь. И вот получилось, что b близка к финишной, c не далеко от финишной, а то, что они друг от друга далеки, совсем не учитывалось, что и привело к ошибке. Но на практике такой алгоритм часто можно использовать, ведь, например, если бы выполнялся поиск пути между двумя реальными городами, то результат был бы скорее всего верным, из-за равномерного распределения городков/поселков/деревень и соответствующих дорог между ними. Сравнение порядка путей, полученных разными алгоритмами
Результат жадного алгоритма
?- search_grd(g,a),nl,nl,nl,fail. g -> b b -> c c -> a g -> d d -> e e -> a g -> f f -> d d -> e e -> a Результат поиска на основе весовой функции ?- search_bst(g,a),nl,nl,nl,fail. g -> d d -> e e -> a Length of way: 21.0984 g -> f f -> d d -> e e -> a Length of way: 21.5861 g -> b b -> c c -> a Length of way: 21.8382 Код целиком для SWI Prolog
Код целиком для Визуал Пролог 5.2/Турбо Пролог
13
|
|||||||||||||||||||||||||||||||
| 07.03.2011, 23:29 | |
|
Помогаю со студенческими работами здесь
5
Поиск в пространстве состояния Планирование состояний в пространстве. Задача о кувшинах Поиск в пространстве состояний Задача на переливание (поиск в пространстве состояний) Реализовать схему в пространстве состояний Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
||||
|
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
|
Новый ноутбук
volvo 07.12.2025
Всем привет.
По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне:
Ryzen 5 7533HS
64 Gb DDR5
1Tb NVMe
16" Full HD Display
Win11 Pro
|
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
|
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
|
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов
На странице:
https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/
нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
|
|
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов.
. . .
|
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
|
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
|
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут.
В век Веб все очень привыкли к дизайну Single-Page-Application .
Быстренько разберем подход "на фреймах".
Мы делаем одну. . .
|
Фото: Daniel Greenwood
kumehtar 13.11.2025
|