Поиск кратчайших путей в графе методом динамического программирования

Алгоритмы динамического программирования в теории графов. Основы теории графов. Сравнение алгоритмов Дейкстры и Беллмана-Форда. Реализация алгоритма Беллмана-Форда в задаче поиска наикратчайшего пути в графе. Иллюстрация алгоритма на примере графа.

Рубрика Математика
Вид курсовая работа
Язык русский
Дата добавления 04.12.2023
Размер файла 180,6 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://allbest.ru

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

«МОСКОВСКИЙ ГОСУДАРСТВЕННЫЙ ГУМАНИТАРНО-ЭКОНОМИЧЕСКИЙ УНИВЕРСИТЕТ»

Факультет Цифровых технологий и кибербезопасности

Кафедра информационных технологий и кибербезопасности

Курсовая работа по дисциплине:

«Дискретная математика»

на тему: «Поиск кратчайших путей в графе методом динамического программирования»

Выполнил:

Студент группы ПИ-0221

Орехов С.В.

Проверил:

Ст. преп. Кафедры ЦТ

Труб Н. В.

Москва 2023

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

ИНКЛЮЗИВНОГО ВЫСШЕГО ОБРАЗОВАНИЯ

МОСКОВСКИЙ ГОСУДАРСТВЕННЫЙ

ГУМАНИТАРНО-ЭКОНОМИЧЕСКИЙ УНИВЕРСИТЕТ

Кафедра Информационных технологий и кибербезопасности

ЗАДАНИЕ

на курсовую работу

по дисциплине «ДИСКРЕТНАЯ МАТЕМАТИКА»

Студенту 2 курса группы ПИ-0221

факультета «Цифровых технологий и кибербезопасности»

Орехову Савве Витальевичу

1. Тема _Поиск кратчайших путей в графе методом динамического программирования.

2. Исходные данные к работе ___В ориентированном взвешенном графе G=(V,E), вес рёбер которого может включать отрицательные веса и определяется весовой функцией , алгоритмы Дейкстры и Беллмана-Форда находят длины кратчайших путей между всеми вершинами взвешенного ориентированного графа. Целью данной работы является изучение этих алгоритмов, а также разработка программы, реализующей любой из них методом динамического программирования.

3. Содержание пояснительной записки (перечень подлежащих разработке вопросов) Рекомендуется следующий план работы.

1). Изучить такие основополагающие понятия теории графов, как орграф, ориентированный маршрут и орцепь.

2). Разобрать алгоритм Дейкстры, нахождения кратчайшего расстояния между всеми вершинами в графе.

3). Разобрать алгоритм Беллмана-Форда нахождения кратчайшего расстояния между всеми вершинами в графе.

4). Применить один из этих алгоритмов к представлению блок-схемой.

5). Разработать программу, реализующую этот алгоритм.

4. Перечень графического материала с точным указанием обязательных чертежей ___нет, только требуемые в качестве иллюстраций.

5. Литература, пособия:

1. Остин Оре Графы и их применение - М.: 2020. - 175 с.

2. Ф.Харари Теория графов. - Ленанд, 2019

3. Голицына О. Л., Попов И. И. Основы алгоритмизации и программирования: Учебное пособие, М.: ФОРУМ. 2017. 432 с.

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

http://works.doklad.ru/view/Oikoq6JYpOY/all.html

5. "Библиотека алгоритмов на графах", http://urban-sanjoo.narod.ru/kruskal.html

6. Р. Седжвик. Фундаментальные алгоритмы на С++: Алгоритмы на графах / пер. с англ. - СПб.: Диасофт, 2019. - 496 с.

Содержание

Введение

Глава 1. Алгоритмы динамического программирования в теории графов

1.1 Основы теории графов

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

1.3 Алгоритм Беллмана-Форда

1.4 Сравнение алгоритмов Дейкстры и Беллмана-Форда

Глава 2. Реализация алгоритма Беллмана-Форда в задаче поиска наикратчайшего пути в графе

2.1 Описание IDE

2.2 Формулировка задачи. Представление графов в ЭВМ

2.3 Иллюстрация алгоритма на примере графа

2.4 Алгоритмизация задачи

2.5 Разработка программы

2.6 Тестирование и отладка

Заключение

Библиографический список

Блок-схема

Исходный код

Введение

Теория графов - раздел дискретной математики, который изучает модели и свойства совокупностей точек, называемых вершинами, соединенных друг с другом линиями, называемыми ребрами. Графы используются для моделирования множества различных процессов, включая представление компьютерных сетей, транспортных систем, социальных сетей и многих других.

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

Теория графов также применяется в изучении различных алгоритмов. Это могут быть алгоритмы распределения ресурсов, поиска путей, оптимизации и многих других. Графы являются удобным инструментом для моделирования алгоритмов и выявления их слабых мест. Наконец, теория графов применяется в социологии и экономике. С помощью графов можно анализировать социальные связи и отношения, а также оценивать взаимодействия и влияние факторов в экономике.

Актуальность применения теории графов на сегодняшний день очень высока благодаря своей универсальности и широкому спектру применения.

теория графы алгоритм динамическое программирование

Глава 1. Алгоритмы динамического программирования в теории графов

1.1. Основы теории графов

Граф - математический объект, состоящий из двух множеств. Одно из них - любое конечное множество, его элементы называются вершинами графа. Другое множество состоит из пар вершин, эти пары называются ребрами графа. Рис. 1.

Рис. 1. Изображение графа.

Ребру могут быть присвоены такие параметры как вес и направление, тем самым определяя тип графа и наделяя его свойствами, позволяющими решать задачи оптимизации использования графа. Если ребра - упорядоченные пары, то такой граф называется ориентированным (сокращенно орграф), если же неупорядоченные, то неориентированным.

Стоит отметить, что в графе может быть не более одного ребра, соединяющего две вершины. Ребро типа (a, a), т.е. соединяющее вершину с ней же самой, называют петлей. Иногда петли разрешаются, иногда запрещаются. В последнем случае говорят, что рассматриваются графы без петель.

В дальнейшем, если не оговаривается иное, под графом понимается неориентированный граф без петель, такие графы называют обыкновенными.

Мультиграф - обобщение понятия графа. В мультиграфе могут быть кратные ребра, то есть несколько ребер, соединяющих одну и ту же пару вершин. Иначе говоря, в мультиграфе Е является мультимножеством, то есть одна пара может входить в него несколько раз.

Если в графе есть ребро (a, b), то говорят, что вершины a и b в нем смежны. Ребро e = (a, b) называют инцидентным каждой из вершин a и b, а каждая из этих вершин инцидентна ребру e.

Множество вершин, смежных с данной вершиной x в некотором графе, называется окрестностью этой вершины и обозначается через N(x). Число вершин в N(x) называется степенью вершины x.

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

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

Алгоритм Дейкстры - это один из примеров алгоритмов, которые можно реализовать с использование динамического программирования. Алгоритм Дейкстры используется для нахождения кратчайшего пути во взвешенном графе от заданной вершины до всех остальных. Он основывается на посещении вершин в порядке возрастания их расстояния от начальной вершины (расстояние от начальной вершины до себя же равно нулю). При реализации этого алгоритма в форме динамического программирования, для каждой вершины сохраняется значение минимального расстояния от начальной вершины до этой вершины. На каждом шаге при обработке вершины, алгоритм сравнивает сохраненное значение этого расстояния с текущим расстоянием. Если текущее расстояние меньше сохраненного, то значение сохраненного расстояния обновляется. Этот подход позволяет находить кратчайшие расстояния до всех вершин графа с минимальными затратами времени и ресурсов.

1.3 Алгоритм Беллмана-Форда

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

1.4 Сравнение алгоритмов Дейкстры и Беллмана-Форда

Алгоритм Дейкстры и алгоритм Беллмана-Форда являются алгоритмами поиска наикратчайшего пути в графе. Однако, они имеют свои отличительные черты.

Алгоритм Дейкстры является алгоритмом расчетливой оптимизации и решает задачу только для графов без циклов с отрицательными весами. Он начинает с заданной вершины и строит дерево кратчайших путей. В каждом шаге алгоритма выбирается следующая вершина с минимальной длиной пути до нее и обновляются пути через эту вершину. Алгоритм Дейкстры обладает усредненной временной сложностью O(E*log(V)), а наихудшая временная сложность - О(V2).

Алгоритм Беллмана-Форда способен решать более широкий класс задач. Он также может обрабатывать графы с отрицательными весовыми ребрами, но при этом обладает более высокой сложностью. Алгоритм Беллмана-Форда начинается с заданной вершины и выполняет релаксацию для каждого ребра графа V-1 раз, где V - число вершин в графе. После этого он проводит проверку на наличие отрицательных циклов. Если такой цикл существует, то алгоритм оповещает о невозможности вычисления наикратчайшего пути. Временная сложность алгоритма Беллмана-Форда равна O(V*E).

Таким образом, если граф не содержит отрицательных весовых ребер, то алгоритм Дейкстры является более эффективным. Если же граф содержит отрицательные весовые ребра, то алгоритм Беллмана-Форда может решить задачу поиска наикратчайшего пути, но при этом является менее эффективным, чем алгоритм Дейкстры.

Глава 2. Реализация алгоритма Беллмана-Форда в задаче поиска наикратчайшего пути в графе

2.1 Описание IDE

IDE - интегрированная среда разработки, предоставляющая широкий спектр функциональных возможностей, включающая в себя графический интерфейс, визуальную отладку, форматирование и проверку синтаксиса кода, анализ и исправление ошибок в реальном времени. В ходе решения задачи будет использоваться облачный аналог IDE в представлении компании Google в виде Google Colabotary Python. Преимущество Google Colab заключается в универсальности платформы, которая работает в браузере, и исполнения кода на облачных серверах без необходимости иметь на компьютере нужные для работы языка программирования Python библиотеки.

2.2 Формулировка задачи

Задача о поиске наикратчайшего пути в связном графе заключается в поиске самого короткого пути между двумя точками, в которой минимизируется сумма весов ребер (или их количество), составляющих путь. Эта задача является одной из важнейших классических задач в теории графов. Практические применения решений задач представлены в GPS-навигаторах, в проектировании сетей, городской инфраструктуры и д. р.

В ЭВМ существует два основных способа представления графов:

1. Матрица смежности вершин: при помощи двумерного массива, где каждый узел графа представлен строкой и столбцом в массиве. Если узлы i и j связаны, то значение в ячейке [i][j] и [j][i] будет равно 1 (или весу ребра), а если узлы не связаны, то значение будет равно 0.

2. Список ребер: это список узлов, связанных с определенным узлом, где каждый узел списка содержит информацию о соседнем узле и весе ребра.

При решении задачи поиска наикратчайшего пути будет использоваться модифицированный алгоритм Беллмана-Форда.

Задача: дан взвешенный, ориентированный граф G = (V, E) включающий ребра с отрицательными весами. Необходимо найти кратчайшие путь между двумя вершинами, заданными пользователем. При наличии отрицательного цикла вывести соответствующее сообщение.

Рис. 2. Исходный граф.

Таб. 1. Матрица смежности вершин для графа G.

1

2

3

4

5

6

1

0

-16

13

0

0

0

2

0

0

10

0

12

0

3

0

4

0

14

0

0

4

0

0

0

0

7

-4

5

0

0

-9

0

0

20

6

0

0

0

0

0

0

2.3. Иллюстрация алгоритма на примере графа

Найдем наикратчайший путь между вершинами 1 и 6.

1. Создаем таблицу путей, где столбцы обозначают вершины, а строки количество вершин в пути до заданной вершины. В пересечении запишем наименьшее значение текущего пути до соответствующей вершины. Начальную вершину обозначим как 0, а расстояние до остальных ?.

Таб. 2. Матрица смежности вершин на стадии инициализации графа.

1

2

3

4

5

6

0

0

?

?

?

?

?

2. Проверяем вершину 1 и инцидентные ей ребра. Из вершины 1 есть прямые пути в вершину 2 по ребру с весом -16 и вершину 3 по ребру с весом 13. Расстояние до остальных вершин остается равным ?, потому что из вершины 1 нет прямых ребер до остальных вершин. Поскольку путь 1>2 = -16 < ?, то добавим соответствующее значение в таблицу. Тот же алгоритм применяется к вершине 3: 1>3 = 13 < ?. Добавим в таблицу строку, содержащую пути, имеющие 1 ребро и веса до соответствующих вершин.

Таб. 3. Матрица смежности вершин при обработке вершины №1.

1

2

3

4

5

6

0

0

?

?

?

?

?

1

0

-16

13

?

?

?

3. У вершины 1 больше нет инцидентных ребер, поэтому проверяем ребра 2 и 3. Из вершины 3 в вершину 2 есть прямой путь, содержащий ребро с весом 4. Проверяем, можно ли провести релаксацию ребра (процесс уменьшения суммы весов ребер до целевой вершины) т.к. путь в вершину 2 уже существует. Для этого из таблицы возьмем значение длины пути до вершины 3 = 13 и добавим к этому значению ребро с весом 4. Итоговая сумма больше, чем существующий путь в таблице для вершины 2: 13+4 = 15>-16, поэтому текущее значение пути для вершины 2 остается неизменным.

Проводим такую же операцию из вершины 2 в вершину 3: из вершины 2 в вершину 3 есть прямой путь, содержащий ребро с весом 10. Релаксируем ребро: 2(-16) + 10 < 3(13). Обновляем соответствующую ячейку в таблице:

Таб. 4. Матрица смежности вершин при обработке вершин №2 и №3.

1

2

3

4

5

6

0

0

?

?

?

?

?

1

0

-16

13

?

?

?

2

0

-16

-6

?

?

?

Таким же образом проверяем ребра 3 >4 = -6 + 14 = 8; 2 >5 = -16 +

+ (-12) = -4.

Таб. 5. Матрица смежности вершин при обработке вершин №2 и №3.

1

2

3

4

5

6

0

0

?

?

?

?

?

1

0

-16

13

?

?

?

2

0

-16

-6

8

-4

?

4. Проверяем ребра смежные с вершинами 4 и 5:

5>3 = -4 + (-9) = -13 < -6, расстояние до вершины 3 = -13;

5>6 = -4 + 20 = 16 > 4.

4>5 = 8 + 7 = 13 > -4;

4>6 = 8 + (-4) = 4 < ?;

Обновим таблицу в соответствии с полученными значениями:

Таб. 6. Матрица смежности вершин при обработке вершин №4 и №5.

1

2

3

4

5

6

0

0

?

?

?

?

?

1

0

-16

13

?

?

?

2

0

-16

-6

8

-4

?

3

0

-16

-13

8

-4

4

5. После того как получена таблица наименьших весов ребер из вершины 1 до остальных вершин, проверим еще раз все ребра на релаксацию с использованием данных из последней строчки текущей таблицы:

1>2 = -16; 1>3 = -13; 3>2 = -16; 2>3 = -13;

3>4 = -13 + 14 < 8 = 1;

2>5 = -4; 5>3 = -13; 4>5 = -4; 5>6 = 4;

4>6 = 1 + (-4) < 4 = -3;

Обновляем таблицу:

Таб. 7. Матрица смежности вершин при релаксации ребер графа.

1

2

3

4

5

6

0

0

?

?

?

?

?

1

0

-16

13

?

?

?

2

0

-16

-6

8

-4

?

3

0

-16

-13

8

-4

4

4

0

-16

-13

1

-4

4

5

0

-16

-13

1

-4

-3

6. Итоговая таблица содержит значения наикратчайших путей из вершины 1 до остальных вершин. Составим наикратчайший путь:

1>2>5>3>4>6. Сумма пути равна -3.

2.4 Алгоритмизация задачи

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

Рассмотрим работу алгоритма:

1. Стартовую вершину обозначим как a и все расстояния до остальных вершин графа будут определены как бесконечные, а расстояние (a, a) = 0. Создается массив dist[] размера V со всеми значениями равными бесконечности, за исключением элемента dist[a].

2. Запускаем цикл V-1, где на каждой итерации для каждого ребра производится релаксация: проверяется, можно ли улучшить текущее расстояние до вершины, через которую проходит ребро. Если это возможно, то расстояние обновляется.

3. Если после завершения цикла V-1 на следующей итерации расстояние до какой-либо вершины уменьшилось, то это означает наличие отрицательного цикла в графе. В этом случае алгоритм Беллмана-Форда возвращает сообщение о наличии такого цикла.

2.5 Разработка программы

Создаем функцию инициализации графа через матрицу смежности вершин и преобразуем в список ребер для оптимального использования алгоритма:

def get_adjacency_matrix():

    n = int(input("Введите количество вершин в графе: "))

    adj_matrix = []

    for i in range(n):

        row = list(map(int, input(f"Введите значения для вершины {i + 1}: ").split()))

        adj_matrix.append(row)

    edges = []

    for i in range(n):

        for j in range(n):

            if adj_matrix[i][j] != 0:

                edge = f"{i + 1}, {j + 1}, {adj_matrix[i][j]}"

                edges.append(edge)

    return edges

Данная функция запрашивает у пользователя размерность квадратной матрицы, построчно добавляет значения строки матрицы row в список adj_matrix. Далее матрица преобразуется в список ребер вида u, v, w, где w - значение веса ребра, инцидентного вершинам u и v.

Опишем функцию работы модифицированного алгоритма Беллмана-Форда:

from typing import List, Tuple, Union, Any

def bellman_ford_algorithm(edges: List[str], start_node: int, end_node: int) -> Union

[tuple[list[Any], list[Any]], tuple[list[int], list[float]]]:  

    inf = float("inf")

    n = len(edges)

    dist = [inf] * n

    prev = [-1] * n

    dist[start_node - 1] = 0

В данном элементе кода в функцию bellman_ford_algoritm инициализируем на вход следующие данные: стартовую вершину - start_node, конечную вершину - end_node, и список ребер - edges. Далее при помощи подключаемого модуля typing проверяем входные данные. Список edges должен иметь тип данных list, а стартовая и конечная вершины целочисленные значения int.

Переменная inf равна бесконечности и используется для инициализации списка dist, который содержит текущее кратчайшее расстояние от начальной вершины до каждой вершины в графе. Список prev инициализируется нулями и будет использоваться для хранения предыдущих вершин на кратчайшем пути.

Код последней строки dist[start_node - 1] = 0 устанавливает начальное расстояние до начального узла (список dist индексируется с 0, поэтому мы вычитаем 1 из start_node). Таким образом, мы можем начать поиск кратчайшего пути от начального узла и обновлять расстояние до остальных узлов по мере прохождения алгоритма Беллмана-Форда.

    for i in range(n - 1):

        for j in range(n):

            u, v, w = map(int, edges[j].split(","))

            if dist[u - 1] + w < dist[v - 1]:

                dist[v - 1] = dist[u - 1] + w

                prev[v - 1] = u - 1

Следующим шагом на каждой итерации алгоритма длины присвоим переменным u, v и w значения из списка edges при помощи оператора map, который позволяет присваивать переменным соответствующие входные значения, где u и v - номера вершин, соединенных ребром, а w - вес ребра. Инструкция for i in range(n-1) означает, что алгоритм будет проходить n-1 раз, так как кратчайший путь между двумя вершинами может содержать не более n-1 ребер. Инструкция for j in range(n) перебирает все ребра в графе на каждом шаге итерации.

Условие if dist[u - 1] + w < dist[v - 1] проверяет, можно ли улучшить текущий кратчайший путь от начальной вершины до вершины v через ребро (u, v) с учетом веса w. Если условие выполняется, то значения в массивах dist и prev обновляются, что дает новый кратчайший путь от начальной вершины до вершины v.

    for j in range(n):

        u, v, w = map(int, edges[j].split(","))

        if dist[u - 1] + w < dist[v - 1]:

            path = [end_node]

            node = prev[end_node - 1]

            while node != -1 and node not in path:

                path.append(node + 1)

                node = prev[node]

            path.append(node + 1)

            return list(reversed(path)), [dist[end_node-1]], True

    path = []

    node = end_node - 1

    while node != -1:

        path.append(node + 1)

        node = prev[node]

    return list(reversed(path)), [dist[end_node-1]], False

После того как все ребра в графе были рассмотрены, удостоверимся в отсутствии отрицательного цикла. Для этого снова проверяем список edges на наличие более короткого пути до вершины v, чем уже найденное значение в списке dist. Если такой путь существует, то функция возвращает в последнем значении True, которое используется для соответствующего сообщения о наличии отрицательного цикла. В ином случае функция в последнем значении возвращает False.

Независимо от наличия отрицательного цикла, функция возвращает список dist и отсортированный в обратном порядке список path, так как заполнение последнего списка было от конечной вершины к начальной.

def print_result(path: List[int], dist: List[int], k: bool):

    if not path:

        print("Невозможно найти путь между заданными вершинами.")

    elif k is True:

        print("В графе есть отрицательный цикл.")

    else:

        print(f"Длина кратчайшего пути: {dist[-1]}")

        print(f"Кратчайший путь: {' -> '.join(str(node) for node in path)}")

В последней функции опишем инструкцию для вывода полученного результата. В первую очередь проверим наличие пути между двумя заданными вершинами, и если он существует, то проверяется следующий блок elif, который сообщает о наличии отрицательного цикла, и если функция bellman_ford_algoritm вернула значение True в переменную k, то пользователь получит соответствующее сообщение. Последний блок else выполнится только при наличии маршрута между вершинами, тем самым вернет значения списков dist и path.

edges = get_adjacency_matrix()

start_node = int(input('Введите начальную вершину: '))

end_node = int(input('Введите конечную вершину: '))

path, dist, k = bellman_ford_algorithm(edges, start_node, end_node)

print_result(path, dist, k)

Завершающим этапом в переменные start_node и end_node запросим у пользователя стартовую и конечную вершины, далее последовательно вызовем вышеописанные функции.

2.6. Тестирование и отладка

В ходе работы алгоритма результат совпадает с полученным вручную, тем самым можно сделать вывод о корректности работы программы.

Заключение

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

Библиографический список

1. В.Е. Алексеев, Д.В. Захарова. Теория графов. Учебное пособие. Издатель: ННГУ им. Н.И. Лобачевского, 2017 г. (дата обращения: 26.04.2023)

2. Основные понятия теории графов [Электронный ресурс] режим доступа URL: https://habr.com/ru/companies/otus/articles/568026/ (дата обращения: 19.04.2023)

3. Алгоритм Дейкстры [Электронный ресурс] режим доступа URL: https://habr.com/ru/companies/otus/articles/599621/ (дата обращения: 19.04.2023)

4. Алгоритм Беллмана-Форда [Электронный ресурс] режим доступа URL: https://habr.com/ru/companies/otus/articles/484382/ (дата обращения: 20.04.2023)

5. Кормен Т., Лейзерсон Ч., Ривест Р., Штайн К. Алгоритмы: построение и анализ. / М.: Издательский дом «Вильямс», 2011.-- 1296 с. (дата обращения: 30.04.2023)

Размещено на Allbest.ru

Приложение А

Приложение Б

from typing import List, Tuple, Union, Any

def get_adjacency_matrix():

    n = int(input("Введите количество вершин в графе: "))

    adj_matrix = []

    for i in range(n):

        row = list(map(int, input(f"Введите значения для вершины {i + 1}: ").split()))

        adj_matrix.append(row)

    edges = []

    for i in range(n):

        for j in range(n):

            if adj_matrix[i][j] != 0:

                edge = f"{i + 1}, {j + 1}, {adj_matrix[i][j]}"

                edges.append(edge)

    return edges

def bellman_ford_algorithm(edges: List[str], start_node: int, end_node: int) -> Union[

    tuple[list[Any], list[Any]], tuple[list[int], list[float]]]:

    inf = float("inf")

    n = len(edges)

    dist = [inf] * n

    prev = [-1] * n

    dist[start_node - 1] = 0

    for i in range(n - 1):

        for j in range(n):

            u, v, w = map(int, edges[j].split(","))

            if dist[u - 1] + w < dist[v - 1]:

                dist[v - 1] = dist[u - 1] + w

                prev[v - 1] = u - 1

    for i in range(n - 1):

        for j in range(n):

            u, v, w = map(int, edges[j].split(","))

            if dist[u - 1] + w < dist[v - 1]:

                return [], []

    path = []

    node = end_node - 1

    while node != -1:

        path.append(node + 1)

        node = prev[node]

    return list(reversed(path)), [dist[end_node-1]]

def print_result(path: List[int], dist: List[int]):

    if not path and not dist:

        print("В графе есть отрицательный цикл.")

    elif not path:

        print("Невозможно найти путь между заданными вершинами.")

    else:

        print(f"Длина кратчайшего пути: {dist[-1]}")

        print(f"Кратчайший путь: {' -> '.join(str(node) for node in path)}")


Подобные документы

  • Основные понятия теории графов. Матричные способы задания графов. Выбор алгоритма Форда–Бэллмана для решения задачи поиска минимальных путей (маршрутов) в любую достижимую вершину нагруженного орграфа. Способы выделения пути с наименьшим числом дуг.

    курсовая работа [109,1 K], добавлен 22.01.2016

  • Метод Форда-Беллмана для нахождения расстояния от источника до всех вершин графа. Алгоритмы поиска расстояний и отыскания кратчайших путей в графах. Блочно-диагональный вид и матрица в исследовании системы булевых функций и самодвойственной функции.

    курсовая работа [192,1 K], добавлен 10.10.2011

  • Основные понятия и свойства эйлеровых и гамильтоновых цепей и циклов в теории графов. Изучение алгоритма Дейкстры и Флойда для нахождения кратчайших путей в графе. Оценки для числа ребер с компонентами связанности. Головоломка "Кенигзберзьких мостов".

    курсовая работа [2,4 M], добавлен 08.10.2014

  • Основные понятия теории графов. Содержание метода Дейкстры нахождения расстояния от источника до всех остальных вершин в графе с неотрицательными весами дуг. Программная реализация исследуемого алгоритма. Построение матриц смежности и инцидентности.

    курсовая работа [228,5 K], добавлен 30.01.2012

  • Описание заданного графа множествами вершин V и дуг X, списками смежности, матрицей инцидентности и смежности. Матрица весов соответствующего неориентированного графа. Определение дерева кратчайших путей по алгоритму Дейкстры. Поиск деревьев на графе.

    курсовая работа [625,4 K], добавлен 30.09.2014

  • Понятия теории графов, их связность и задача о кратчайшей цепи. Программная реализация метода Дейкстры, его сравнение с методом простого перебора. Описание логики программного модуля. Примеры работы программы нахождения кратчайшей цепи в связном графе.

    курсовая работа [330,2 K], добавлен 25.11.2011

  • Эйлеровы цепи и циклы, теоремы. Алгоритм построения эйлерова цикла. Обоснование алгоритма. Нахождение кратчайших путей в графе. Алгоритм Форда отыскания кратчайшего пути. Задача отыскания кратчайших расстояний между всеми парами вершин. Алгоритм Флойда.

    реферат [108,4 K], добавлен 01.12.2008

  • Основные понятия теории графов. Маршруты и связность. Задача о кёнигсбергских мостах. Эйлеровы графы. Оценка числа эйлеровых графов. Алгоритм построения эйлеровой цепи в данном эйлеровом графе. Практическое применение теории графов в науке.

    курсовая работа [1006,8 K], добавлен 23.12.2007

  • Основные понятия теории графов. Расстояния в графах, диаметр, радиус и центр. Применение графов в практической деятельности человека. Определение кратчайших маршрутов. Эйлеровы и гамильтоновы графы. Элементы теории графов на факультативных занятиях.

    дипломная работа [145,5 K], добавлен 19.07.2011

  • Теория графов как математический аппарат для решения задач. Характеристика теории графов. Критерий существования обхода всех ребер графа без повторений, полученный Л. Эйлером при решении задачи о Кенигсбергских мостах. Алгоритм на графах Дейкстры.

    контрольная работа [466,3 K], добавлен 11.03.2011

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.