Нижегородский государственный университет им. Н.И.Лобачевского
Опубликован: 27.09.2006 | Доступ: свободный | Студентов: 3533 / 125 | Оценка: 4.44 / 4.11 | Длительность: 13:45:00
Специальности: Программист, Математик
Лекция 4:

Поиск в ширину

< Лекция 3 || Лекция 4: 12 || Лекция 5 >

BFS-дерево и вычисление расстояний

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

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

Предположим, что алгоритм поиска в ширину применяется к связному графу. Покажем, что в этом случае по окончании обхода множество всех прямых ребер образует дерево. Действительно, допустим, что на некотором шаге работы алгоритма обнаруживается новое прямое ребро (x,y), а множество прямых ребер, накопленных к этому шагу, образует дерево F. Тогда вершина x принадлежит дереву F, а вершина y не принадлежит ему. Поэтому при добавлении к дереву F ребра (x,y) связность сохранится, а циклов не появится.

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

Каркас, который будет построен описанным образом в результате поиска в ширину в связном графе, называется BFS-деревом. Его можно рассматривать как корневое дерево с корнем в стартовой вершине a. BFS-дерево с заданным корнем a, вообще говоря, не единственное - зависит от того, в каком порядке просматриваются окрестности вершин. Однако всякое BFS-дерево обладает свойством, на котором и основаны наиболее важные применения поиска в ширину. Каркас T связного графа G с корнем a назовем геодезическим деревом, если для любой вершины x путь из x в a в дереве T является кратчайшим путем между x и a в графе G.

Теорема 1. Любое BFS-дерево является геодезическим деревом.

Доказательство. Обозначим через D(i) множество всех вершин графа, находящихся на расстоянии i от стартовой вершины a. Работа алгоритма начинается с посещения стартовой вершины, т.е. единственной вершины, составляющей множество D(0). При первом выполнении цикла while будут посещены и помещены в очередь все вершины из множества D(1). Затем эти вершины будут одна за другой извлекаться из очереди, становиться активными, и для каждой из них будут исследоваться все смежные вершины. Те из них, которые еще не посещались, будут посещены и помещены в очередь. Но это как раз все вершины из множества D(2) (когда начинается исследование окрестностей вершин из D(1), ни одна вершина из D(2) еще не посещалась и каждая из них смежна хотя бы с одной вершиной из D(1) ). Следовательно, каждая вершина из D(2) будет посещена после всех вершин из D(1). Рассуждая далее таким образом, приходим к следующему выводу.

(А) Все вершины из D(i+1) будут посещены после всех вершин из D(i), i=0,1,\ldots.

Строгое доказательство легко провести индукцией по i. Отметим еще следующий факт.

(Б) Если активной является вершина из D(i), то в этот момент все вершины из D(i) уже посещены.

В самом деле, из (А) следует, что вершины из D(i) попадут в очередь после вершин из D(i-1). Поэтому, когда первая вершина из D(i) становится активной, все вершины из D(i-1) уже закрыты. Значит, к этому моменту окрестности всех вершин из D(i-1) полностью исследованы, и, следовательно, все вершины из D(i) посещены.

Рассмотрим теперь момент работы алгоритма, когда активной является вершина x\in D(i) и обнаруживается смежная с ней новая вершина y. В BFS-дереве расстояние между y и a на 1 больше, чем расстояние между x и a. В графе расстояние между y и a не больше, чем i+1, так как x и y смежны. Ввиду (А) это расстояние не может быть меньше i, а ввиду (Б) оно не может быть равно i. Значит, y\in D(i+1), т.е. в графе расстояние между y и a тоже на 1 больше, чем расстояние между x и a. Следовательно, если до какого-то момента работы алгоритма расстояния от каждой из посещенных вершин до стартовой вершины в графе и в дереве были равны, то это будет верно и для вновь посещаемой вершины. Поскольку это верно вначале, когда имеется единственная посещенная вершина a (оба расстояния равны 0 ), то это останется верным и тогда, когда будут посещены все вершины.

Итак, мы можем применить поиск в ширину для вычисления расстояний от стартовой вершины a до всех остальных вершин графа - нужно только в процессе обхода для каждой посещаемой вершины y определять расстояние от y до a в BFS-дереве. Это сделать легко: d(a,y)=d(a,x)+1, где x - активная вершина. Вначале устанавливаем d(a,a)=0.

Если граф несвязен, некоторые расстояния будут бесконечными. Чтобы учесть эту возможность, положим вначале d(a,x)=\infty для всех x\ne a. Пока вершина x остается новой, для нее сохраняется значение d(a,x)=\infty, когда же она посещается, d(a,x) становится равным расстоянию между a и x и больше не меняется. Таким образом, бесконечность расстояния можно использовать как признак того, что вершина новая. Если по окончании работы d(a,x)=\infty для некоторой вершины x, это означает, что x не достижима из a, то есть принадлежит другой компоненте связности.

Для того чтобы не только определять расстояния, но и находить кратчайшие пути от a до остальных вершин, достаточно для каждой вершины y знать ее отца F(y) в BFS-дереве. Очевидно, что F(y)=x, где x - вершина, активная в момент посещения вершины y. Заполнение таблицы F фактически означает построение BFS-дерева.

Модифицируя процедуру BFS с учетом сделанных замечаний, получаем следующий алгоритм:

Алгоритм 2. Построение BFS-дерева и вычисление расстояний от вершины a до всех остальных вершин:

  1. for x\in V do d(a,x)\; :=\;
\infty
  2. d(a,a)\; :=\; 0
  3. a\Rightarrow Q
  4. while Q\ne \varnothing
\quad do
  5. x\Leftarrow Q
  6. for y\in
V\left(x\right)\quad \quad do
  7. if d(a,y)=\infty
  8. then d(a,y):=d(a,x)+1
  9. F(y):=x
  10. y\Rightarrow Q
< Лекция 3 || Лекция 4: 12 || Лекция 5 >
Петр Петров
Петр Петров

произведение графов К(2)*О(4) фактически 4 отдельных графа К(2)?

Александр Лаврентьев
Александр Лаврентьев

много инструкций вида if - then - else

Например Procedure DFS(a) опишите каким образом следует понимать вложенность инструкций. Как в языке С ? 

т.е. следующее 

if (...) then (...)

if (...) then (...)

else(...)

 

раскрывается как 

if (...) then (...)

if (...) then (...)

         else(...)

или так :

if (...) then

 {  (...)

     if (...) then (...)

              else(...)

}

обьясните пожалуйста.

 

 

Константин Дементьев
Константин Дементьев
Россия, г. Мичуринск