Программирование на языке Пролог для искусственного интеллекта
Шрифт:
Рис. 9.3. Более
9.5. Напишите процедуру слияния двух упорядоченных списков в один третий список. Например:
9.6. Программы сортировки, показанные на рис. 9.2 и 9.3, отличаются друг от друга способом представления списков. Первая из них использует обычное представление, в то время как вторая — разностное представление. Преобразование из одного представления в другое очевидно и может быть автоматизировано. Введите в программу рис. 9.2 необходимые изменения, чтобы преобразовать ее в программу рис. 9.3.
9.7. Наша программа
9.8. Существует еще одна хорошая идея относительно механизма сортировки списков, позволяющая избавиться от недостатков программы
• разбить L на два списка L1 и L2 примерно одинаковой длины;
• произвести сортировку списков L1 и L2,получив списки S1 и S2;
• слить списки S1 и S2, завершив на этом сортировку списка L.
Реализуйте этот принцип сортировки и сравните его эффективность с эффективностью программы
9.2. Представление множеств двоичными деревьями
Списки часто применяют для представления множеств. Такое использование списков имеет тот недостаток, что проверка принадлежности элемента множеству оказывается довольно неэффективной. Обычно предикат
Для того, чтобы найти X в списке L, эта процедура последовательно просматривает список элемент за элементом, пока ей не встретится либо элемент X, либо конец списка. Для длинных списков такой способ крайне неэффективен.
Для облегчения более эффективной реализация отношения принадлежности применяют различные древовидные структуры. В настоящем разделе мы рассмотрим двоичные деревья.
Двоичное дерево либо пусто, либо состоит из следующих трех частей:
• корень
• левое поддерево
правое поддерево
Корень может
Существует много способов представления двоичных деревьев на Прологе. Одна из простых возможностей — сделать корень главным функтором соответствующего терма, а поддеревья — его аргументами. Тогда дерево рис. 9.4 примет вид
Такое представление имеет среди прочих своих недостатков то слабое место, что для каждой вершины дерева нужен свой функтор. Это может привести к неприятностям, если вершины сами являются структурными объектами.
Рис. 9.4. Двоичное дерево.
Существует более эффективный и более привычный способ представления двоичных деревьев: нам нужен специальный символ для обозначения пустого дерева и функтор для построения непустого дерева из трех компонент (корня и двух поддеревьев). Относительно функтора и специального символа сделаем следующий выбор:
• Пусть атом
• В качестве функтора примем
В этом представлении дерево рис. 9.4 выглядит как
Теперь рассмотрим отношение принадлежности, которое будем обозначать
истинна, если
X есть вершина дерева T, если
• корень дерева T совпадает с X, или
• X — это вершина из левого поддерева, или
• X — это вершина из правого поддерева.
Рис. 9.5. Представление двоичных деревьев.
Эти правила непосредственно транслируются на Пролог следующим образом:
Очевидно, что цель
терпит неудачу при любом X.
Посмотрим, как ведет себя наша процедура. Рассмотрим рис. 9.4. Цель
используя механизм возвратов, находит все элементы данных, содержащиеся в множестве, причем обнаруживает их в следующем порядке: