Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
metod_AYaII_buklet_maket (1).doc
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
857.6 Кб
Скачать

7.4. Пример решения задачи

  1. Тема: работа с графами и деревьями в среде Turbo Prolog.

  2. Цель работы: ознакомление с возможностями обработки графов и деревьев в среде Turbo Prolog 2.0 и приобретение практических навыков создания и использования структур данных для представления и обработки деревьев и графов.

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

  4. Разработка метода решения задачи.

Для решения поставленной задачи предлагается представить граф, элементами которого являются факты, содержащие сведения о связи двух вершин между собой и о стоимости такой связи. Такой факт (прил. 7Б) представляется в виде d(вершина1,вершина2,стоимость). Факты целесообразно хранить во внешнем текстовом файле der8_db.pro.

После загрузки фактов, описывающих граф, целесообразно составить отсортированный список вершин, входящих в граф. Эта функция возлагается на предикат р.

У пользователя спросить имена исходной и целевой вершин и проверить, входят ли они в граф. Эти действия выполняет предикат v3(вершина, список_вершин). Если вершина не входит в граф, на экран выводится соответствующее сообщение и работа программы завершается. Если вершины входят в граф, инициируется поиск всех возможных путей между ними (предикат v), подсчет стоимостей путей и вывод на экран результата.

Собственно поиск путей выполняет предикат р1(вершина, путь, стоимость).

  1. Описание предикатов, разработанных для реализации метода решения задачи на языке Turbo Prolog.

Предикаты файла der8.pro

Предикаты

Назначение

b(ii)

База данных найденных путей и их стоимостей

d(i,i,i)

База данных, описывающая граф:

d(вершина1,вершина2,стоимость)

p(ii)

Составление упорядоченного списка вершин графа

p1(i,ii,i)

Предикат поиска пути: р1(вершина, путь, стоимость)

v1(i,i,i)

Проверка наличия связи между двумя вершинами:

v1(вершина1, вершина2, флаг_наличия_связи)

v2(i,ii)

Проверка вхождения вершины в найденный список вершин (путь): v2(вершина, путь)

v3(i,ii)

Проверка вхождения вершины в граф:

v3(вершина, список_вершин)

v

Инициация поиска пути

Предикаты файла sort.pro:

Предикаты

Назначение

men(i,ii,ii,ii)

Деление списка на два результирующих списка относительно значения первого элемента:

men(элемент,исходный_список,рез_список1,рез_список2)

sort_quick(ii,ii)

Выполнение «быстрой сортировки» списка:

sort_quick(исх_список, отсортированный_список)

konk(ii,ii,ii)

Конкатенация двух списков:

konk(список1, список2, объединенный_список)

ud(ii,ii)

Удаление из списка одинаковых элементов:

ud(исх_список, результирующий_список)

  1. Стандартные предикаты, используемые для решения задачи:

Стандартные предикаты для работы с оперативной базой данных взяты из Приложения 2Б.

  1. Текст программы.

%Выполняет поиск всех существующих путей на графе

include "sort.pro" % Подключение файла sort.pro

database

b(ii) % База данных найденных путей и их стоимостей

d(i,i,i) %База данных - граф

% d(вершина1,вершина2,стоимость)

predicates

p(ii) %Составление упорядоченного списка вершин графа

p1(i,ii,i) %Поиск пути

v1(i,i,i) %Проверка наличия связи между двумя вершинами

v2(i,ii) %Проверка вхождения вершины в найденный список

% вершин (путь)

v3(i,ii) %Проверка вхождения вершины в граф

v %Инициализация поиска пути

clauses

%Составление упорядоченного списка вершин графа

p(P):-

findall(X,d(X,_,_),P1), % Составление списка "левых" вершин

findall(Y,d(_,Y,_),P2), % Составление списка "правых" вершин

konk(P1,P2,P3), % Конкатенация списков (см. файл sort.pro)

sort_quick(P3,P4), % Сортировка списка (см. файл sort.pro)

ud(P4,P). % Удаление из списка одинаковых элементов

% (см. файл sort.pro)

Продолжение программы

%Поиск пути

p1(X,[X|P],S):- % Завершение рекурсии, если голова списка

% равна исходной вершине (первый аргумент)

PP=[X|P], %Список вершин пути записывается в переменную РР

write(PP," S=",S), % Вывод на экран пути и его стоимости

nl.

p1(X,[Z|P],S):- % Вершина Z присоединяется к пути после

% выполнения следующих далее проверок

v1(Y,Z,S1), % Проверка наличия связи между вершинами Х и Y

v2(Y,P), % Проверка вхождения вершины Х в путь

S2=S+S1, % Добавление веса ребра к стоимости пути

p1(X,[Y,Z|P],S2). % Рекурсивный вызов

%Проверка наличия связи между вершинами Х и Y

v1(X,Y,S1):- % Определение веса ребра

d(X,Y,S1). % по найденному факту связи вершин

v1(X,Y,S1):-

d(Y,X,S1).

%Проверка вхождения вершины в найденный список вершин (путь)

v2(_,[]). % Если список-путь пуст, то вершина

% в него не входит

v2(X,[Y|P]):- % Проверка вхождения вершины в список

X<>Y, % Если вершина не равна голове списка,

v2(X,P). % то продолжать поиск

%Проверка вхождения вершины в граф

v3(X,[X|_]):-!. % Если вершина равна голове списка,

% то она входит в граф

v3(X,[_|P]):- % Рекурсивное правило

v3(X,P). % (вторая формулировка)

v3(X,[]):- % Во всех остальных случаях вершина

% не входит в граф.

nl,write("Вершина ",X," не входит в граф!"),

nl,write("Путей нет!"),

readint(_),fail.

%Инициация поиска путей

v:-

b(P),write("Список вершин:"),nl,

write(P),nl,

write("Исходная вершина:"),nl,

readint(X),

v3(X,P), %Проверка вхождения исходной вершины в граф

write("Целевая вершина:"),nl,

readint(Y),

v3(Y,P), %Проверка вхождения целевой вершины в граф

write("Найденные пути и их стоимости:"),nl,

p1(X,[Y],0), %Поиск путей

fail.

Продолжение программы

v.

goal

clearwindow, %Очистка экрана

retractall(d(_,_,_)), % Очиска оперативной памяти

retractall(b(_)),

consult("der8_db.pro"),% Загрузка базы данных

p(P), % Составление списка вершин графа

asserta(b(P)), % Добавление списка вершин в опер. память

v,nl, % Инициация поиска путей

write("*****"). % Конец работы

К основной программе подключается файл sort.pro, содержащий вспомогательные предикаты для выполнения конкатенации и сортировки списков и удаления одинаковых элементов из списка:

domains i=integer ii=i*

predicates

men(i,ii,ii,ii) % Делит список на два списка относительно значения

% первого элемента

sort_quick(ii,ii) % Выполнение «быстрой сортировки» списка

konk(ii,ii,ii) % Конкатенация двух списков

ud(ii,ii) % Удаление из списка одинаковых элементов

clauses

men(_,[],[],[]). % Условие завершения рекурсии:

% когда второй параметр-список пуст, третий и четвертый

% параметры – тоже пустые списки.

men(A,[B|X],[B|L1],L2):- %Если голова В списка-второго параметра

B<A,men(A,X,L1,L2). % меньше, чем первый параметр предиката,

% то эта голова сцепляется

% со списком-третьим параметром предиката,

% а четвертый параметр-список остается

% без изменений.

men(A,[B|X],L1,[B|L2]):- %Во всех остальных случаях голова В

men(A,X,L1,L2). % списка-второго параметра сцепляется

% со списком четвертым параметром предиката,

% а третий параметр-список остается

% без изменений.

sort_quick([],[]). % Когда первый список пуст, второй тоже пуст

sort_quick([A|X],R):- % Выделяется голова первого списка

men(A,X,L1,L2), % Вызов предиката men, который

% возвращает два списка –

% L1 (его элементы меньше элемента А), и

% L2 (его элементы больше элемента А).

sort_quick(L1,M1), % Вызов сортировки списка L1. Возвращается

Продолжение программы

% отсортированный список М1

sort_quick(L2,M2), % Вызов сортировки списка L2. Возвращается

% отсортированный список М2

konk(M1,[A|M2],R). % Конкатенация списков М1, М2 и головы А

%Конкатенация списков

konk([],Z,Z). %Когда первый список пуст,

% третий список равен второму

konk([X|Y],Z,[X|R]):- % Голова первого списка присоединяется

% в начало третьего списка

konk(Y,Z,R). % Рекурсивный вызов

%Удаление из списка одинаковых элементов

ud([X],[X]). %Когда первый список состоит из одного элемента,

% второй список состоит из этого же одного элемента.

ud([A|X],P):- % В первом списке выделяется голова А и хвост Х

ud(X,[Y|P1]), % Выполняется рекурсивный вызов и сцепление

% головы Y и хвоста Р1 во втором списке

A<Y, % Если А меньше Y, то

P=[A,Y|P1]. % список Р представляет собой сцепление элементов

% А, Y и хвоста Р1.

ud([_|X],P):- %Рекурсивное правило для перебора всех элементов

% первого списка.

ud(X,P).

База данных, представляющая дерево, хранится в файле der8_db.pro в следующем виде:

d(1,2,2).

d(2,4,1).

d(1,3,3).

d(2,5,5).

d(5,6,1).

d(3,6,2).

d(1,7,1).

d(7,8,3).

d(8,6,2).

  1. Выводы

При выполнении лабораторной работы были изучены особенности представления графов и деревьев в Прологе с помощью структур. Для реализации индивидуального задания были разработаны рекурсивные предикаты. Программа реализована по модульному принципу.

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