Скажите, пожалуйста, можно ли еще получить документ о прохождении курса ("Графы и алгоритмы", декабрь 2020) после предоставления всех дополнительных необходимых документов? |
Поиск в ширину
BFS-дерево и вычисление расстояний
Другая простая задача, для решения которой можно применить поиск в ширину, - построение каркаса. Напомним, что каркасом графа называется остовный лес, у которого области связности совпадают с областями связности графа. Каркас связного графа - остовное дерево.
Ребра, исследуемые в процессе обхода графа, можно разделить на две категории: если ребро соединяет активную вершину с новой вершиной , то оно классифицируется как прямое, в противном случае - как обратное. В зависимости от решаемой задачи прямые и обратные ребра могут подвергаться различной обработке.
Предположим, что алгоритм поиска в ширину применяется к связному графу. Покажем, что в этом случае по окончании обхода множество всех прямых ребер образует дерево. Действительно, допустим, что на некотором шаге работы алгоритма обнаруживается новое прямое ребро , а множество прямых ребер, накопленных к этому шагу, образует дерево . Тогда вершина принадлежит дереву , а вершина не принадлежит ему. Поэтому при добавлении к дереву ребра связность сохранится, а циклов не появится.
Итак, если применить поиск в ширину к связному графу и запомнить все прямые ребра, то получим каркас графа. Для произвольного графа будет получен лес, также, очевидно, являющийся каркасом.
Каркас, который будет построен описанным образом в результате поиска в ширину в связном графе, называется BFS-деревом. Его можно рассматривать как корневое дерево с корнем в стартовой вершине . BFS-дерево с заданным корнем , вообще говоря, не единственное - зависит от того, в каком порядке просматриваются окрестности вершин. Однако всякое BFS-дерево обладает свойством, на котором и основаны наиболее важные применения поиска в ширину. Каркас связного графа с корнем назовем геодезическим деревом, если для любой вершины путь из в в дереве является кратчайшим путем между и в графе .
Теорема 1. Любое BFS-дерево является геодезическим деревом.
Доказательство. Обозначим через множество всех вершин графа, находящихся на расстоянии от стартовой вершины . Работа алгоритма начинается с посещения стартовой вершины, т.е. единственной вершины, составляющей множество . При первом выполнении цикла while будут посещены и помещены в очередь все вершины из множества . Затем эти вершины будут одна за другой извлекаться из очереди, становиться активными, и для каждой из них будут исследоваться все смежные вершины. Те из них, которые еще не посещались, будут посещены и помещены в очередь. Но это как раз все вершины из множества (когда начинается исследование окрестностей вершин из , ни одна вершина из еще не посещалась и каждая из них смежна хотя бы с одной вершиной из ). Следовательно, каждая вершина из будет посещена после всех вершин из . Рассуждая далее таким образом, приходим к следующему выводу.
(А) Все вершины из будут посещены после всех вершин из , .
Строгое доказательство легко провести индукцией по . Отметим еще следующий факт.
(Б) Если активной является вершина из , то в этот момент все вершины из уже посещены.
В самом деле, из (А) следует, что вершины из попадут в очередь после вершин из . Поэтому, когда первая вершина из становится активной, все вершины из уже закрыты. Значит, к этому моменту окрестности всех вершин из полностью исследованы, и, следовательно, все вершины из посещены.
Рассмотрим теперь момент работы алгоритма, когда активной является вершина и обнаруживается смежная с ней новая вершина . В BFS-дереве расстояние между и на 1 больше, чем расстояние между и . В графе расстояние между и не больше, чем , так как и смежны. Ввиду (А) это расстояние не может быть меньше , а ввиду (Б) оно не может быть равно . Значит, , т.е. в графе расстояние между и тоже на 1 больше, чем расстояние между и . Следовательно, если до какого-то момента работы алгоритма расстояния от каждой из посещенных вершин до стартовой вершины в графе и в дереве были равны, то это будет верно и для вновь посещаемой вершины. Поскольку это верно вначале, когда имеется единственная посещенная вершина (оба расстояния равны ), то это останется верным и тогда, когда будут посещены все вершины.
Итак, мы можем применить поиск в ширину для вычисления расстояний от стартовой вершины до всех остальных вершин графа - нужно только в процессе обхода для каждой посещаемой вершины определять расстояние от до в BFS-дереве. Это сделать легко: , где - активная вершина. Вначале устанавливаем .
Если граф несвязен, некоторые расстояния будут бесконечными. Чтобы учесть эту возможность, положим вначале для всех . Пока вершина остается новой, для нее сохраняется значение , когда же она посещается, становится равным расстоянию между и и больше не меняется. Таким образом, бесконечность расстояния можно использовать как признак того, что вершина новая. Если по окончании работы для некоторой вершины , это означает, что не достижима из , то есть принадлежит другой компоненте связности.
Для того чтобы не только определять расстояния, но и находить кратчайшие пути от до остальных вершин, достаточно для каждой вершины знать ее отца в BFS-дереве. Очевидно, что , где - вершина, активная в момент посещения вершины . Заполнение таблицы фактически означает построение BFS-дерева.
Модифицируя процедуру BFS с учетом сделанных замечаний, получаем следующий алгоритм:
Алгоритм 2. Построение BFS-дерева и вычисление расстояний от вершины до всех остальных вершин:
- for do
- while do
- for do
- if
- then