Скачиваний:
0
Добавлен:
22.09.2026
Размер:
292 Кб
Скачать
☆

ФЕДЕРАЛЬНОЕ АГЕНТСТВО СВЯЗИ

ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ

«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ТЕЛЕКОММУНИКАЦИЙ ИМ. ПРОФ. М.А. БОНЧ-БРУЕВИЧА»

(СПбГУТ)

Дисциплина: «Алгоритмы и структуры данных»

Лабораторная работа №4.

Выполнил: Студент группы ИКПИ-41

Летягина Е. А.

Проверил: Кандидат технических наук, доцент кафедры ПИиВТ

Дагаев А. В.

г. Санкт-Петербург

2026

  1. Описание алгоритмов

Для сравнения были выбраны два алгоритма поиска кратчайших расстояний на графах:

  • Алгоритм Флойда–Уоршелла (нахождение кратчайших путей между всеми парами вершин);

  • Алгоритм Дейкстры (нахождение расстояний от одной вершины до всех остальных, с многократным запуском для получения всех пар).

    1. Алгоритм Флойда–Уоршелла

Алгоритм Флойда–Уоршелла решает задачу поиска кратчайших путей между всеми парами вершин во взвешенном графе. Он может работать с рёбрами, имеющими отрицательные веса, при условии отсутствия отрицательных циклов (циклов, сумма весов которых отрицательна).

Для поиска используется метод динамического программирования. Пусть вершины графа пронумерованы числами от 1 до  . Введём обозначение: который в качестве промежуточных может использовать только вершины из множества  .

Изначально, при  , никакие промежуточные вершины не разрешены, поэтому:

Рекуррентное соотношение:

Смысл: кратчайший путь от   до   с промежуточными вершинами из   либо не использует вершину   (тогда он равен  ), либо использует её (тогда он состоит из кратчайшего пути от   до   и от   до  , каждый из которых использует вершины только до  ).

Алгоритм выполняет три вложенных цикла:

Внешний цикл по   от 1 до   (перебор разрешённых промежуточных вершин).

Внутренние циклы по   и   от 1 до   (перебор всех пар вершин).

На каждой итерации   для каждой пары   выполняется проверка и, если необходимо, обновление расстояния:

После завершения внешнего цикла ( ) матрица   содержит кратчайшие расстояния между всеми парами вершин.

Временная сложность –  , так как выполняются три вложенных цикла, каждый длиной  .

    1. Алгоритм Дейкстры

Алгоритм Дейкстры находит кратчайшие расстояния от одной заданной вершины (источника) до всех остальных вершин графа.

Алгоритм является жадным. На каждом шаге выбирается вершина с наименьшим текущим известным расстоянием от источника, которая ещё не была обработана. Затем эта вершина «закрывается» (считается, что её кратчайшее расстояние уже найдено), и пытаются улучшить расстояния до её соседей через неё.

Расстояние до источника   полагается равным 0:  , расстояния до всех остальных вершин устанавливаются равными бесконечности:  . Все вершины считаются непосещёнными.

Основной цикл (повторяется   раз): выбирается непосещённая вершина   с минимальным значением  и помечается как посещённая. Для каждой непосещённой вершины  , смежной с  , выполняется релаксация:

После обработки всех вершин массив   содержит кратчайшие расстояния от источника до всех вершин.

Благодаря неотрицательности весов рёбер, когда вершина   выбирается как имеющая минимальное расстояние среди непосещённых, это расстояние уже является окончательным. Любой другой путь до   проходил бы через какую-то другую непосещённую вершину с не меньшим расстоянием, что привело бы к большему или равному суммарному весу.

Поиск вершины с минимальным   выполняется линейным просмотром всех вершин, что даёт сложность  .

  1. Описание программы

Программа написана на C++. Основные компоненты:

  • generate_sparse_graph(n, avg_deg) – создаёт неориентированный граф с n вершинами и средней степенью avg_deg (по умолчанию 6). Рёбра добавляются случайно, веса от 1 до 100. Граф хранится в матрице смежности vector<vector<int>>.

  • floyd_warshall(dist) – реализует алгоритм Флойда–Уоршелла, изменяя переданную матрицу.

  • dijkstra(graph, start) – возвращает вектор кратчайших расстояний от start до всех вершин.

  • В функции main задаются параметры эксперимента: число вершин от 100 до 1000 с шагом 50, количество повторений для усреднения – 5 раз. Время измеряется с помощью std::chrono::high_resolution_clock в миллисекундах. Для каждого размера графа:

    1. Генерируется случайный граф.

    2. Замеряется время работы floyd_warshall.

    3. Замеряется суммарное время n запусков dijkstra (чтобы получить полную матрицу).

  • Результаты сохраняются в файл results.csv для построения графика.

Соседние файлы в папке Отчёты Дагаев