Санкт-Петербургский государственный электротехнический университет
Кафедра МОЭВМ
Логическое программирование
Отчет по лабораторной работе № 1:
“Построение минимального остового дерева”
Выполнили:
студенты гр. 4305
Агамов З.Г.
Белкин И.А.
СПб 15 октября 2007 г.
-
Постановка задачи
Дан связный, взвешенный, неориентированный граф. Необходимо вычислить связный подграф, включающий все вершины исходного графа, суммарный вес вершин которого минимален.
2. Описание алгоритма решения
Основой для решения поставленной задачи является алгоритм Краскала нахождения минимального остового дерева. При программирования решения на языке Prolog использовался алгоритмический подход.
Описание алгоритма Краскала нахождения минимального остового дерева:
Исходные данные:
-
G = (V, E) - связный граф.
-
E* - последовательность всех ребер из множества E, упорядоченных по возрастанию веса.
Шаги алгоритма:
}
}
Выходные данные:
-
T = (V, R) - минимальное остовое дерево графа G = (V, E).
3. Формат исходных данных
Сущность |
Представление |
Комментарий |
Граф |
Graph = [E0, E1, … En]. |
|
Ребро |
E = [V0, V1, W]. |
|
4. Тестовые примеры
5. Трассировка программы
Для трассировки выберем следующий тестовый пример:
G = [[b, c, 2], [a, b, 1], [a, c, 3]].
| ?- trace, testMod(0).
The debugger will first creep -- showing everything (trace)
1 1 Call: testMod(0) ?
2 2 Call: modTestTemplate([[b,c,2],[a,b,1],[a,c,3]]) ?
3 3 Call: magicTree([[b,c,2],[a,b,1],[a,c,3]],_129) ?
4 4 Call: sortGraph([[b,c,2],[a,b,1],[a,c,3]],_153) ?
5 5 Call: swap([[b,c,2],[a,b,1],[a,c,3]],_177) ?
6 6 Call: longer([b,c,2],[a,b,1]) ?
7 7 Call: 2>1 ?
7 7 Exit: 2>1 ?
6 6 Exit: longer([b,c,2],[a,b,1]) ?
5 5 Exit: swap([[b,c,2],[a,b,1],[a,c,3]],[[a,b,1],[b,c,2],[a,c,3]]) ?
8 5 Call: sortGraph([[a,b,1],[b,c,2],[a,c,3]],_256) ?
9 6 Call: swap([[a,b,1],[b,c,2],[a,c,3]],_280) ?
10 7 Call: longer([a,b,1],[b,c,2]) ?
11 8 Call: 1>2 ?
11 8 Fail: 1>2 ?
10 7 Fail: longer([a,b,1],[b,c,2]) ?
10 7 Call: swap([[b,c,2],[a,c,3]],_267) ?
11 8 Call: longer([b,c,2],[a,c,3]) ?
12 9 Call: 2>3 ?
12 9 Fail: 2>3 ?
11 8 Fail: longer([b,c,2],[a,c,3]) ?
11 8 Call: swap([[a,c,3]],_293) ?
12 9 Call: swap([],_319) ?
12 9 Fail: swap([],_319) ?
11 8 Fail: swap([[a,c,3]],_293) ?
10 7 Fail: swap([[b,c,2],[a,c,3]],_267) ?
9 6 Fail: swap([[a,b,1],[b,c,2],[a,c,3]],_268) ?
8 5 Exit: sortGraph([[a,b,1],[b,c,2],[a,c,3]],[[a,b,1],[b,c,2],[a,c,3]]) ?
4 4 Exit: sortGraph([[b,c,2],[a,b,1],[a,c,3]],[[a,b,1],[b,c,2],[a,c,3]]) ?
9 4 Call: treeBuilder([[a,b,1],[b,c,2],[a,c,3]],_282) ?
10 5 Call: spread([[a,b,1]],_309,[[b,c,2],[a,c,3]]) ?
11 6 Call: addedge([[a,b,1]],_334,[[b,c,2],[a,c,3]]) ?
12 7 Call: saveForest(b,c,[[a,b,1]]) ?
13 8 Call: not(path(b,c,[[a,b,1]],_349)) ?
14 9 Call: '$call'(path(b,c,[[a,b,1]],_349),not,1,true) ?
15 10 Call: path(b,c,[[a,b,1]],_349) ?
16 11 Call: path1(b,[c],[[a,b,1]],_349) ?
17 12 Call: adjacent(_487,c,[[a,b,1]]) ?
18 13 Call: member([_473,c,_477],[[a,b,1]]) ?
18 13 Fail: member([_473,c,_477],[[a,b,1]]) ?
18 13 Call: member([c,_475,_477],[[a,b,1]]) ?
18 13 Fail: member([c,_475,_477],[[a,b,1]]) ?
17 12 Fail: adjacent(_475,c,[[a,b,1]]) ?
16 11 Fail: path1(b,[c],[[a,b,1]],_349) ?
15 10 Fail: path(b,c,[[a,b,1]],_349) ?
14 9 Fail: '$call'(path(b,c,[[a,b,1]],_349),not,1,true) ?
13 8 Exit: not(path(b,c,[[a,b,1]],_349)) ?
12 7 Exit: saveForest(b,c,[[a,b,1]]) ?
11 6 Exit: addedge([[a,b,1]],[[b,c,2],[a,b,1]],[[b,c,2],[a,c,3]]) ?
14 6 Call: spread([[b,c,2],[a,b,1]],_417,[[a,c,3]]) ?
15 7 Call: addedge([[b,c,2],[a,b,1]],_442,[[a,c,3]]) ?
16 8 Call: saveForest(a,c,[[b,c,2],[a,b,1]]) ?
17 9 Call: not(path(a,c,[[b,c,2],[a,b,1]],_457)) ?
18 10 Call: '$call'(path(a,c,[[b,c,2],[a,b,1]],_457),not,1,true) ?
19 11 Call: path(a,c,[[b,c,2],[a,b,1]],_457) ?
20 12 Call: path1(a,[c],[[b,c,2],[a,b,1]],_457) ?
21 13 Call: adjacent(_595,c,[[b,c,2],[a,b,1]]) ?
22 14 Call: member([_581,c,_585],[[b,c,2],[a,b,1]]) ?
22 14 Exit: member([b,c,2],[[b,c,2],[a,b,1]]) ?
21 13 Exit: adjacent(b,c,[[b,c,2],[a,b,1]]) ?
23 13 Call: not(member(b,[])) ?
24 14 Call: '$call'(member(b,[]),not,1,true) ?
25 15 Call: member(b,[]) ?
25 15 Fail: member(b,[]) ?
24 14 Fail: '$call'(member(b,[]),not,1,true) ?
23 13 Exit: not(member(b,[])) ?
24 13 Call: path1(a,[b,c],[[b,c,2],[a,b,1]],_457) ?
25 14 Call: adjacent(_709,b,[[b,c,2],[a,b,1]]) ?
26 15 Call: member([_695,b,_699],[[b,c,2],[a,b,1]]) ?
26 15 Exit: member([a,b,1],[[b,c,2],[a,b,1]]) ?
25 14 Exit: adjacent(a,b,[[b,c,2],[a,b,1]]) ?
27 14 Call: not(member(a,[c])) ?
28 15 Call: '$call'(member(a,[c]),not,1,true) ?
29 16 Call: member(a,[c]) ?
29 16 Fail: member(a,[c]) ?
28 15 Fail: '$call'(member(a,[c]),not,1,true) ?
27 14 Exit: not(member(a,[c])) ?
28 14 Call: path1(a,[a,b,c],[[b,c,2],[a,b,1]],_457) ?
28 14 Exit: path1(a,[a,b,c],[[b,c,2],[a,b,1]],[a,b,c]) ?
24 13 Exit: path1(a,[b,c],[[b,c,2],[a,b,1]],[a,b,c]) ?
20 12 Exit: path1(a,[c],[[b,c,2],[a,b,1]],[a,b,c]) ?
19 11 Exit: path(a,c,[[b,c,2],[a,b,1]],[a,b,c]) ?
18 10 Exit: '$call'(path(a,c,[[b,c,2],[a,b,1]],[a,b,c]),not,1,true) ?
29 10 Call: fail ?
29 10 Fail: fail ?
17 9 Fail: not(path(a,c,[[b,c,2],[a,b,1]],_457)) ?
16 8 Fail: saveForest(a,c,[[b,c,2],[a,b,1]]) ?
16 8 Call: addedge([[b,c,2],[a,b,1]],_467,[]) ?
17 9 Call: fail ?
17 9 Fail: fail ?
16 8 Fail: addedge([[b,c,2],[a,b,1]],_455,[]) ?
15 7 Fail: addedge([[b,c,2],[a,b,1]],_430,[[a,c,3]]) ?
15 7 Call: not(addedge([[b,c,2],[a,b,1]],_405,[[a,c,3]])) ?
16 8 Call: '$call'(addedge([[b,c,2],[a,b,1]],_405,[[a,c,3]]),not,1,true) ?
17 9 Call: addedge([[b,c,2],[a,b,1]],_405,[[a,c,3]]) ?
18 10 Call: saveForest(a,c,[[b,c,2],[a,b,1]]) ?
19 11 Call: not(path(a,c,[[b,c,2],[a,b,1]],_506)) ?
20 12 Call: '$call'(path(a,c,[[b,c,2],[a,b,1]],_506),not,1,true) ?
21 13 Call: path(a,c,[[b,c,2],[a,b,1]],_506) ?
22 14 Call: path1(a,[c],[[b,c,2],[a,b,1]],_506) ?
23 15 Call: adjacent(_644,c,[[b,c,2],[a,b,1]]) ?
24 16 Call: member([_630,c,_634],[[b,c,2],[a,b,1]]) ?
24 16 Exit: member([b,c,2],[[b,c,2],[a,b,1]]) ?
23 15 Exit: adjacent(b,c,[[b,c,2],[a,b,1]]) ?
25 15 Call: not(member(b,[])) ?
26 16 Call: '$call'(member(b,[]),not,1,true) ?
27 17 Call: member(b,[]) ?
27 17 Fail: member(b,[]) ?
26 16 Fail: '$call'(member(b,[]),not,1,true) ?
25 15 Exit: not(member(b,[])) ?
26 15 Call: path1(a,[b,c],[[b,c,2],[a,b,1]],_506) ?
27 16 Call: adjacent(_758,b,[[b,c,2],[a,b,1]]) ?
28 17 Call: member([_744,b,_748],[[b,c,2],[a,b,1]]) ?
28 17 Exit: member([a,b,1],[[b,c,2],[a,b,1]]) ?
27 16 Exit: adjacent(a,b,[[b,c,2],[a,b,1]]) ?
29 16 Call: not(member(a,[c])) ?
30 17 Call: '$call'(member(a,[c]),not,1,true) ?
31 18 Call: member(a,[c]) ?
31 18 Fail: member(a,[c]) ?
30 17 Fail: '$call'(member(a,[c]),not,1,true) ?
29 16 Exit: not(member(a,[c])) ?
30 16 Call: path1(a,[a,b,c],[[b,c,2],[a,b,1]],_506) ?
30 16 Exit: path1(a,[a,b,c],[[b,c,2],[a,b,1]],[a,b,c]) ?
26 15 Exit: path1(a,[b,c],[[b,c,2],[a,b,1]],[a,b,c]) ?
22 14 Exit: path1(a,[c],[[b,c,2],[a,b,1]],[a,b,c]) ?
21 13 Exit: path(a,c,[[b,c,2],[a,b,1]],[a,b,c]) ?
20 12 Exit: '$call'(path(a,c,[[b,c,2],[a,b,1]],[a,b,c]),not,1,true) ?
31 12 Call: fail ?
31 12 Fail: fail ?
19 11 Fail: not(path(a,c,[[b,c,2],[a,b,1]],_506)) ?
18 10 Fail: saveForest(a,c,[[b,c,2],[a,b,1]]) ?
18 10 Call: addedge([[b,c,2],[a,b,1]],_405,[]) ?
19 11 Call: fail ?
19 11 Fail: fail ?
18 10 Fail: addedge([[b,c,2],[a,b,1]],_405,[]) ?
17 9 Fail: addedge([[b,c,2],[a,b,1]],_405,[[a,c,3]]) ?
16 8 Fail: '$call'(addedge([[b,c,2],[a,b,1]],_405,[[a,c,3]]),not,1,true) ?
15 7 Exit: not(addedge([[b,c,2],[a,b,1]],_405,[[a,c,3]])) ?
14 6 Exit: spread([[b,c,2],[a,b,1]],[[b,c,2],[a,b,1]],[[a,c,3]]) ?
10 5 Exit: spread([[a,b,1]],[[b,c,2],[a,b,1]],[[b,c,2],[a,c,3]]) ?
9 4 Exit: treeBuilder([[a,b,1],[b,c,2],[a,c,3]],[[b,c,2],[a,b,1]]) ?
3 3 Exit: magicTree([[b,c,2],[a,b,1],[a,c,3]],[[b,c,2],[a,b,1]]) ?
16 3 Call: write([[b,c,2],[a,b,1]]) ?
[[b,c,2],[a,b,1]]
16 3 Exit: write([[b,c,2],[a,b,1]]) ?
17 3 Call: nl ?
17 3 Exit: nl ?
2 2 Exit: modTestTemplate([[b,c,2],[a,b,1],[a,c,3]]) ?
1 1 Exit: testMod(0) ?