Академический Документы
Профессиональный Документы
Культура Документы
САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ
ЭЛЕКТРОТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
«ЛЭТИ» ИМ. В.И. УЛЬЯНОВА (ЛЕНИНА)
Кафедра информационной безопасности
ОТЧЕТ
по лабораторной работе №4
по дисциплине «Алгоритмы и структуры данных»
Тема: Построение минимального остовного дерева
Санкт-Петербург
2022
Цель работы
Ознакомление с вариантами реализации алгоритмов на графах на примере
задачи построения минимального остовного дерева.
Теоретические сведения
Алгоритм Прима
Алгоритм начинается с выбора произвольной вершины. Она принимается
за часть построенного минимального остовного дерева.
Далее в цикле в каждой итерации рассматриваются только те ребра
исходного графа, одна из вершин которых строго принадлежит уже
построенной части, а другая строго не принадлежит (если второе условие не
проверять, то в графе возникнут циклы). Из списка всех ребер,
удовлетворяющих этому условию, выбирается ребро с наименьшим весом и
добавляется к построенной части.
Итерации повторяются до тех пор, пока все вершины не окажутся
включенными в остовное дерево.
Алгоритм Краскала
Алгоритм начинается с того, что каждая вершина исходного графа
помещается в свое множество (состоящее из одной вершины) – компоненту
связности.
Далее в цикле в каждой итерации из всех ребер, которые соединяют
разные компоненты связности, выбирается ребро с наименьшим весом, и с
помощью него две отдельные компоненты связности объединяются в одну.
Итерации повторяются до тех пор, пока количество компонент связности
не уменьшится до одной – она и будет представлять собой остовное дерево.
Оценка быстродействия алгоритмов
В случае «наивной» реализации (хранение информации о наличии и
стоимости ребер в двумерном массиве) асимптотика обоих алгоритмов – O(n2).
В случае применения более сложных структур для хранения сведений об
упорядоченном списке ребер – O(n·log2n).
2
Теоретическая часть
Дан взвешенный связный неориентированный граф «Куб» (Вариант 7):
1. Алгоритмом Прима.
1. 2.
3. 4.
5. 6.
3
7. 8.
9. 10.
11. 12.
13. 14.
15. 16.
4
ТАБЛ. 1 – ПРОЦЕСС СОЗДАНИЯ МИНИМАЛЬНОГО ОСТОВНОГО
ДЕРЕВА АЛГОРИТМОМ ПРИМА
2. Алгоритмом Краскала.
1. 2.
3. 4.
5.
6. 7.
5
8.
6
Практическая часть
Реализовать построение минимального остовного дерева для графа,
содержащего 15 вершин, по алгоритму Краскала.
Алгоритм генерации исходного графа, содержащего 15 вершин.
7
Алгоритма генерации минимального остовного дерева.
8
Рис. 3 – Сумма весов включенных ребер
Выводы
Выполнив и изучив алгоритм Прима и алгоритм Крускала, мы
получаем возможность быстрого построения остовного дерева.
Анализируются длины ребер от каждой вершины фрагмента до оставшихся
невыбранных вершин. Выбирается минимальное ребро и присоединяется к
первоначальному фрагменту, и т. д. Процесс продолжается до тех пор, пока
в остовное дерево не будут включены все вершины исходного графа.
9
Исходный код
#include <iostream>
#include <ctime>
#include <map>
#include <vector>
11
tree[i][j] = 0;
//цикл по ребрам
for (int i = 0; i < E.size(); i++) {
cout << "Iteration number: " << i + 1 << endl;
cout << "Edge to include: " << E[i].u + 1 << "-" << E[i].v + 1 << "-weight: " << E[i].weight << endl;
cout << "Number of vertices in the first component: ";
for (int j = 0; j < n; j++) {
if (Vertex[j] == Vertex[E[i].u])
cout << j + 1 << " ";
}
cout << endl;
cout << "Number of vertices in the second component: ";
for (int j = 0; j < n; j++) {
if (Vertex[j] == Vertex[E[i].v])
cout << j + 1 << " ";
}
cout << endl << endl;
if (Vertex[E[i].u] != Vertex[E[i].v]) {
tree[E[i].u][E[i].v] = E[i].weight;
int v = Vertex[E[i].v];
for (int j = 0; j < n; j++) {
if (Vertex[j] == v)
Vertex[j] = Vertex[E[i].u];
}
if (checkV(Vertex, n) == 0) break;
}
}
cout << endl << "Minimum spanning tree: " << endl;
int minCost = 0;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (tree[i][j] != 0) {
minCost = minCost + tree[i][j];
cout << "Edge: " << i + 1 << "-" << j + 1 << " weight: " << tree[i][j] << endl;
}
}
}
cout << endl << "Minimum sum of weights = " << minCost << endl;
}
int main() {
int n = 15;
int** edge = new int* [n];
for (int i = 0; i < n; i++)
12
edge[i] = new int[n];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
edge[i][j] = 0;
srand(time(NULL));
Graph(edge, n);
Kruskal(edge, n);
delete[] edge;
return 0;
}
13