Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ФиЛП_материалы / Материалы / Prolog / ПособиеПролог.doc
Скачиваний:
55
Добавлен:
01.06.2015
Размер:
449.02 Кб
Скачать

8.2. Графы

Граф определяется как множество вершин вместе с множеством ребер, каждое из которых задается парой вершин. К ребрам можно приписывать стоимости, имена или метки произвольного вида в зависимости от конкретного приложения. Существует несколько способов представления графов средствами Пролога.

1. Представление дуги графа в виде факта.

дуга(a, b).

дуга (a, c).

дуга (b, d).

дуга (b, c).

Если дуга имеет вес, то он может быть отображен в виде третьего аргумента предиката.

2. В виде списков вершин и ребер

a) граф([a, b, c, d, e]), [дуга(a, b), дуга(b, c), дуга(b, d) . . .])

б) [верш(a, [b, d]), верш(b, [c, d]), верш(c, [e]) . . .]

Две самые распространённые задачи, которые выполняются с графами:

поиск пути между двумя вершинами;

поиск в графе подграфа, который обладает некоторыми заданными свойствами.

Все процедуры, к которым сводятся эти задачи, являются

рекурсивными.

Рассмотрим два примера решения первой задачи

1. Определение длины пути между двумя вершинами неориентированного размеченного графа, приведенного на рис. 5. В программе граф задан с помощью предиката «дуга/3», третьим аргументом которого является длина дуги. Для того, чтобы отразить возможность перехода из одной вершины в другую как в одну, так и в другую сторону, введен предикат «соседняя». В рекурсивном правиле «пройти» задается исходная и конечная вершины и переменная, которая в результате вычислений конкретизируется длиной всего маршрута. При движении по графу маршрут прокладывается сначала от первой вершины до вершины X, а затем из X до второй вершины.

Рис.5

DOMAINS

вершина = symbol

путь = integer

PREDICATES

nondeterm дуга(вершина, вершина,путь)

nondeterm соседняя(вершина, вершина, путь)

nondeterm пройти(вершина, вершина, путь)

CLAUSES

дуга(a1, a5, 5).

дуга(a1, a4, 7).

дуга(a2, a4, 2).

дуга(a3, a4, 4).

соседняя(X, Y, D):-

дуга(X, Y, D); дуга(Y, X, D).

пройти (Старт, Цель, Путь):-

соседняя(Старт, Цель,Путь).

пройти(Старт, Цель, Путь):-

соседняя(Старт, X, Путь1),

пройти(X, Цель, Путь2),

Путь=Путь1+Путь2,!.

GOAL

пройти(a2, a5, X), write(X).

X=14

(Отсечение после выражения Путь для традиционного Пролога обязательно.)

2. Определим маршрут между 2 вершинами, но постараемся получить его в виде списка пройденных вершин. Граф приведен на рис.6. Усложним задачу введением обязательной для посещения вершину а8 и двух вершин, в которые нельзя заходить – а5 и а7.

Рис. 6

Важная особенность программы – пройденные вершины заносятся в список. Это происходит благодаря предикату «путь», который определяется рекурсивно. В третий аргумент предиката добавляется пройденная вершина в том случае, если она незапрещенная и ранее не посещалась.

DOMAINS

вершина = symbol

список_вершин = вершина*

PREDICATES

nondeterm дуга(вершина,вершина)

nondeterm соседняя(вершина,вершина)

nondeterm избегать(список_вершин)

nondeterm пройти(вершина,вершина)

nondeterm путь(вершина,вершина,список_вершин)

nondeterm member(вершина,список_вершин) /*прове

ряет принадлежность списку*/

CLAUSES

дуга(a1,a7).

дуга(a1,a4).

дуга(a2,a4).

дуга(a3,a4).

дуга(a3,a9).

дуга(a5,a4).

дуга(a5,a8).

дуга(a6,a4).

дуга(a6,a8).

дуга(a7,a8).

дуга(a8,a9).

member(X,[X|_]).

member(X,[_|H]):-member (X,H).

соседняя(X,Y):-дуга(X,Y); дуга(Y,X).

избегать([a5,a7]).

пройти(Старт,Цель):-путь(Старт,Цель,[Старт]).

путь(Вершина, Вершина, Маршрут):-

member(a8, Маршрут), %посетили обязательную

write(Маршрут).

путь(Вершина, Цель, Маршрут):-

соседняя(Вершина, СледВершина),

избегать (Опасные),

/* не заходим в опасные*/

not(member(СледВершина, Опасные)),

/* не заходим в пройденные*/

not(member(СледВершина, Маршрут)),

путь(СледВершина, Цель,

[СледВершина | Маршрут]).

/*пройденная заносится в голову списка как в стеке*/

GOAL

пройти(a1, a9).

Маршрут=[a9, a8, a6, a4, a1 ]

Как обычно, VIP предложит только один вариант маршрута; для поиска всех решений следует применить искусственный откат. Пройденные вершины занесены в Маршрут в обратном порядке, поэтому перед выводом следует использовать процедуру инвертирования списка.

Примеры решения второй задачи работы с графами подробно рассмотрены в [1].

Соседние файлы в папке Prolog