Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторная работа №1.doc
Скачиваний:
8
Добавлен:
01.05.2014
Размер:
176.13 Кб
Скачать

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

/**

* Поиск минимального остового дерева.

* Главный предикат: magicTree(Graph, Tree).

* Тесты: go.

*/

/**

* magicTree(Graph, Tree).

* Строит минимальное остовное дерево для связного графа Graph.

* Параметр: Graph граф.

* Возвращает: Tree минимальное остовное дерево для графа Graph.

*/

magicTree(Graph, Tree):-sortGraph(Graph, SortedGraph), treeBuilder(SortedGraph, Tree).

/**

* treeBuilder(Graph, Tree).

* Доказывает, что дерево Tree получено путем последовательного добавления ребер из графа Graph.

* Параметр: Graph граф.

* Параметр: Tree дерево, множество вершин которого совпадает с множеством вершин графа Graph.

*/

treeBuilder(Graph, Tree):- Graph = [Edge|RestEdges], spread([Edge], Tree, RestEdges).

/**

* spread(Tree, UpdatedTree, Graph).

* На основе дерева Tree строит дерево UpdatedTree, покрывающее все вершины графа Graph и содержащее ребра

* только из графа Graph.

* Параметр: Tree исходное дерево.

* Возвращает: UpdatedTree дерево покрывающее все вершины графа Graph.

* Параметр: Graph граф из которого берутся возможные ребра для расширения дерева.

*/

spread(Tree1, Tree, Graph):-

addedge(Tree1, Tree2, Graph),

Graph = [_ | RestEdges],

spread(Tree2, Tree, RestEdges).

spread(Tree, Tree, Graph):-not(addedge(Tree, _, Graph)).

/**

* addedge(Forest, updatedForest, Graph).

* Расширяет лес Forest до леса UpdatedForest путем добавления следующего допустимого ребра из графа Graph.

* Параметр: Forest исходный лес.

* Возвращает: UpdatedForest расширенный исходный лес.

* Параметр: Graph граф из которого берутся возможные ребра для расширения леса.

*/

addedge(_,_,[]):-fail.

addedge(Forest, UpdatedForest, [Edge|LastEdges]):-

[A, B, _] = Edge,

saveForest(A, B, Forest),

UpdatedForest = [Edge | Forest], !;

addedge(Forest,UpdatedForest, LastEdges).

/**

* saveForest(Vertex0, Vertex1, Forest).

* Проверяет, что добавление ребра между вершинами Vertex0 и Vertex1 не нарушает свойство леса у Forest.

* Параметр: Vertex0 вершина.

* Параметр: Vertex1 вершина.

* Параметр: Forest лес.

*/

saveForest(A, B, Forest):-not(path(A, B, Forest,_)).

/**

* not(P).

* Предикат отрицания.

* Параметр: P предикат, чьё доказательство будет отрицаться.

*/

not(P) :- P, !, fail.

not(_) :- true.

/**

* longer(Edge0, Edge1).

* Предикат доказывает, что вес ребра Edge0 больше, чем вес ребра Edge1.

* Параметр: Edge0 ребро графа.

* Параметр: Edge1 ребро графа.

*/

longer([_, _, X], [_, _, Y]) :- X > Y.

/**

* sortGraph(Graph, SortedGraph).

* Сортирует представление графа по возрастанию веса ребер.

* Параметр: Graph представление графа в виде списка его ребер

* ([E1, E2,...En], где Ei=[Vertex0, Vertex1, Weight]).

* Возвращает: SortedGraph список ребер графа, отсортированный по возрастанию

* веса ребер.

*

*/

sortGraph(Graph, SortedGraph) :-

swap(Graph, Tmp), !,

sortGraph(Tmp, SortedGraph).

sortGraph(SortedGraph, SortedGraph).

/**

* swap(List1, List2).

* Вспомогательный предикат для "пузырьковой" сортировки.

* Переставляет местами первые два элемента списка, если их порядок не удовлетворяет

* условию сортировки.

*/

swap([X, Y | Tail], [Y, X | Tail]) :- longer(X, Y).

swap([Z | Tail], [Z | Tail1]) :- swap(Tail, Tail1).

/**

* adjacent(Vertex0, Vertex1, Graph).

* Доказывает наличие ребра между двумя вершинами в графе.

* Параметр: Vertex0 вершина графа.

* Параметр: Vertex1 вершина графа.

* Параметр: Graph граф.

*/

adjacent(V0, V1, Graph):-

member([V0, V1, W], Graph);

member([V1, V0, W], Graph).

/**

* node(Vertex, Graph).

* Доказывает принадлежность вершины к графу.

* Параметр: Vertex вершина графа.

* Параметр: Graph граф.

*/

node(V, Graph):-adjacent(V, _, Graph).

/**

* path(Vertex0, Vertex1, Graph, Path).

* Доказывает наличие в графе пути между двумя вершинами и сохраняет этот

* ациклический путь.

* Параметр: Vertex0 вершина отправления.

* Параметр: Vertex1 вершина назначения.

* Параметр: Graph граф.

* Возвращает: Path ациклический путь между вершинами.

*/

path(V0, V1, Graph, Path) :- path1(V0, [V1], Graph, Path).

path1(V, [V|Path1], _, [V|Path1]).

path1(V, [Y|Path1], Graph, Path) :-

adjacent(X, Y, Graph),

not(member(X, Path1)),

path1(V, [X, Y | Path1], Graph, Path).

/**

* Тестовые сценарии

*/

runTestCase(N):- N > -1, N1 is N - 1, runTestCase(N1), !, testMod(N).

runTestCase(-1).

modTestTemplate(Graph):-magicTree(Graph, X), write(X), nl.

modAssertTemplate(Graph, Mod):-magicTree(Graph, Mod), write('assert '), write(Mod), nl.

testMod(0):-modTestTemplate([[a,b,12], [b,c,10], [c,a,2]]).

testMod(1):-modTestTemplate([[a,b,1], [b,c,1], [c,a,1], [b,d,3], [a,d,2], [c, d, 0]]).

testMod(2):-modTestTemplate([[a,b,1], [b,c,3], [c,a,20], [b,d,4], [a,d,3], [c, d, 0]]).

testMod(3):-modTestTemplate([[a, b, 2]]).

testMod(4):-modAssertTemplate([[a,b,2]], [[a,b,2]]).

testMod(5):-modAssertTemplate([[a, b,1], [b, c,2], [c, a,3]], [[b,c,2], [a,b,1]]).

testMod(6):-modAssertTemplate([[a, b,3], [b, c,2], [c, a,1]], [[b,c,2], [c,a,1]]).

testMod(7):-modAssertTemplate([[a, b,2], [b, c,3], [c, a,1]], [[a,b,2], [c,a,1]]).

testMod(8):-

modAssertTemplate([[a, b,1], [b, c,2], [c, d,3], [d, a,4], [d, b,5], [a, c,6]],

[[c,d,3], [b,c,2], [a,b,1]]).

testMod(9):-

modAssertTemplate([[a, b,1], [b, c,2], [c, d,4], [d, a,54], [d, b,55], [a, c,3]],

[[c,d,4], [b,c,2], [a,b,1]]).

testMod(10):-

modAssertTemplate([[a, b,1], [b, c,7], [c, d,2], [d, a,4], [d, b,5], [a, c,6]],

[[d,a,4], [c,d,2], [a,b,1]]).

testMod(11):-

modAssertTemplate([[a, b,0], [b, c,0], [c, d,0], [d, a,0], [d, b,0], [a, c,0]],

[[c,d,0], [b,c,0], [a,b,0]]).

testMod(12):-

modTestTemplate([[a,b,10], [a,i,7], [a,h,11], [b,i,2], [b,j,5], [b,c,10], [c,j,4], [c,d,1],

[d,e,3], [e,j,8], [e,i,2], [f,g,16], [f,i,17], [f,j,3], [g,h,22], [g,i,4], [i,j,6]]).

testMod(13):-

modTestTemplate([[a,b,10], [b,c,10], [c,d,10], [d,e,10], [e,f,10], [f,g,10], [g,h,10], [h,a,10],

[a,i,1], [b,j,1], [c,j,1], [d,j,1], [e,j,1], [f,i,1], [g,i,1], [h,i,1], [i,j,1]]).

testMod(14):-

modTestTemplate([[a,b,1], [a,g,30], [a,f,100], [b,g,28], [b,c,5], [b,h,2], [c,h,2], [c,i,4],

[c,d,10], [d,i,5], [d,j,23], [d,e,25], [e,j,1], [j,i,17], [i,h,11], [h,g,27], [g,f,70]]).

/**

* Предикат для запуска всех сценариев тестирования.

*/

go:-runTestCase(14).