Опубликован: 12.02.2014 | Доступ: свободный | Студентов: 819 / 236 | Длительность: 11:22:00
Специальности: Программист
Лекция 8:

Графы

< Лекция 7 || Лекция 8: 1234 || Лекция 9 >

8.2. Отношение достижимости на графе

Отношению достижимости на графе принадлежат пары вершин, для которых существует соединяющий их путь. Это отношение является рефлексивно-транзитивным замыканием отношения edge. Отношение достижимости на графе является отношением эквивалентности, поэтому все вершины распадаются на классы связанных между собой вершин. В следующей программе находятся вершины, достижимые из заданной вершины, а также классы достижимых друг из друга вершин.

Факт-переменная conn в программе используется, во-первых, для предотвращения зацикливания и, во-вторых, для того чтобы достижимые вершины возвращались по одному разу, без повторов.

open core, console, list

class facts - graph
    arc: (string, string, unsigned).

class facts
    conn : string* := [].

class predicates
    connected: (string) -> string multi.
    connected1: (string) -> string multi.
    edge: (string, string, unsigned) nondeterm (i,o,o).
    components: () -> string**.
    components: (string*) -> string**.
clauses
    edge(X, Y, Dist):-
        arc(X, Y, Dist);
        arc(Y, X, Dist).

    connected(X) = connected1(X):-
        conn := [X].

    connected1(X) = X.
    connected1(X) = connected1(Y):-
        edge(X, Y, _),
        not(isMember(Y, conn)),
        conn := [Y | conn].

    components() = components(VList):-
        VList = removeDuplicates([V || arc(V, _, _); arc(_, V, _)]).

    components([V | L]) = [Cmp | components(difference(L, Cmp))]:-
        Cmp = [Vertex || Vertex = connected(V)].
    components([]) = [].

    run():-
        file::consult("graph.txt", graph),
        write(connected("Самара")), nl,
        fail;
        write("\nВершины компонент связности:\n"),
        forAll(components(), {(L):- write(L), nl}),
        _ = readLine().
Пример 8.3. Отношение достижимости

Предикат removeDuplicates удаляет из списка дубликаты элементов.

Упражнение 3. Найдите вершины, не достижимые из заданной вершины.

8.3. Поиск кратчайших путей

Рассмотрим методы поиска кратчайших путей на графе.

В приведенной ниже программе для поиска кратчайших путей используется самый простой декларативный метод, в котором реализуется определение: путь — кратчайший, если не существует путей короче него2Пример приведен для версии 7.5. В версии 7.4 вместо выражения not(A in B) должно быть not(list::isMember(A, B)). Вместо A и B в листингах стоят разные переменные..

class facts - graph
    arc: (string, string, unsigned).

class predicates
    shortestPath: (string, string, string* [out], unsigned [out])
        nondeterm.
    path: (string, string, string*, string* [out], unsigned, 
        unsigned [out]) nondeterm.
    shorter: (string, string, unsigned) determ.
    edge: (string, string [out], unsigned [out]) nondeterm.
clauses
    edge(X, Y, Dist):-
        arc(X, Y, Dist);
        arc(Y, X, Dist).

    shortestPath(Start, Goal, list::reverse(Path), Dist):-
        path(Start, Goal, [Start], Path, 0, Dist),
        not(shorter(Start, Goal, Dist)).

    shorter(Start, Goal, Dist):-
        path(Start, Goal, [Start], _, 0, Dist1),
        Dist1 < Dist,
        !.

    path(Goal, Goal, Path, Path, Dist, Dist):- !.
    path(V, Goal, CurrPath, Path, CurrDist, Dist):-
        edge(V, NextV, D),
        not(NextV in CurrPath),
        path(NextV, Goal, [NextV | CurrPath], Path, CurrDist + D, Dist).

    run():-
        file::consult("graph.txt", graph),
        shortestPath("Москва", "Новосибирск", Path, D),
            write(string::concatWithDelimiter(Path, " -> "), " : ", D), nl,
        fail;
        _ = readLine().
Пример 8.4. Кратчайшие пути и поиск в глубину

Упражнение 4. Найдите кратчайшие пути из Москвы до Новосибирска, не проходящие через Пермь.

< Лекция 7 || Лекция 8: 1234 || Лекция 9 >
Жаныл Айкын
Жаныл Айкын
Rustam Inatov
Rustam Inatov

Доброго времени суток, подскажите пожалуйста, visual prolog examples, pie, vip7.5 - это все, где я могу скачать? (в смысле) может быть на сайте есть какой-то архив? Увы я не нашел его.

Подскажите, пожалуйста.

С уважением, Рустам.