Найти в Дзене
Python. Алгоритмы

Графы и обход в ширину

Наконец после долгого вступления добрались и до самих алгоритмов. Первый на очереди – алгоритм обхода в ширину.

Наконец после долгого вступления (1, 2) добрались и до самих алгоритмов. Первый на очереди – алгоритм обхода в ширину.

Описание:

Алгоритм обхода в ширину (Breadth first search, BFS) применяется для поиска кратчайшего пути в НЕВЗВЕШЕННЫХ графах. При этом кратчайшим путем он считает путь с наименьшим числом ребер.

Суть алгоритма в последовательном осмотре всех вершин начиная со «стартовой». Происходит это следующим образом: Сначала осматриваем соседей стартовой вершины, затем в качестве стартовой принимаем первого соседа и так до тех пор, пока не осмотрим все вершины.

В данной реализации мы просто посетим все вершины в ДАННОЙ компоненте связности и можем посчитать их количество: print(len(visited)).

Как теперь найти путь?

Используем алгоритм обратного восстановления пути:

В нем все строиться на идее запоминания вершин из которых мы пришли в текущую и обратного движения от текущей в стартовую. Несмотря на простоту описания смысл доходит не сразу (это я про себя).

Модифицируем принцип действия, описанный выше, заодно дополним счетчиком расстояний:

-2

Программная реализация

Создадим простой граф
Создадим простой граф
Без поиска пути
Без поиска пути
С поиском пути и расстояний
С поиском пути и расстояний

Для закрепления "как искался путь":

-6

Алгоритмическая сложность

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

О(|V|+|E|), где |V|— число вершин, |E|— число рёбер.

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

Данный случай стоит воспринимать как худший – полный обход графа

Соответственно для ускорения работы алгоритма можно добавить условие остановки алгоритма при достижении искомой вершины:

По памяти нам так же требуется О(|V|+|E|)

Что дает данный алгоритм?

1. Кратчайший путь – кратчайший по количеству ребер

2. Поиск компонент связности (если забыл что это тебе сюда).

Для проверки числа КС нам требуется создать не пустой лист visited со значениями False ( их должно быть ровно |V|) и при работе алгоритма менять соответствующее по номеру вершины значение на True. Если после работы алгоритма в списке будут значения False, то просто ещё раз запускаем от этих вершин алгоритм. Т.о. количество запусков алгоритма = количеству компонент связности.

3. Остовное дерево(об этом буду говорить в следующих статьях)

P.S.

Немного поиграв с библиотекой pygame, получилось сделать такую анимацию работы алгоритма:

Синий - стартовая точка, Зеленый - посещенные вершины, Красный - вершины в очереди, Фиолетовый - текущая вершина
Синий - стартовая точка, Зеленый - посещенные вершины, Красный - вершины в очереди, Фиолетовый - текущая вершина