Дискретная математика и теория алгоритмов. Учебное пособие
.pdf
§ 4. Поиск в ширину |
21 |
|
|
Доказательство. Непосредственно после инициализации все вершины { } имеют белый цвет, и поэтому [ ] = ∞ > ( , ). Кроме этого, для вершины справедливо [ ] = 0 = ( , ).
Из кода процедуры BFS видно, что значение [ ] может измениться только у белой вершины , причём после такого изменения вершина помещается операцией inject в очередь, окрашивается в серый цвет и никогда уже не станет белой, и значит, после этого значение [ ] больше не изменяется.
Таким образом, достаточно доказать утверждение леммы для вершин , у которых значение [ ] меняется с бесконечного на конечное. Доказательство проведём индукцией по числу применений операции inject.
Впервые операция inject используется в строке 09 для исходной вершины . После её применения, как было установлено выше, неравенство [ ] > ( , ) выполняется для всех .
Пусть после -го применения операции inject справедливо [ ] > ( , ) для всех. Рассмотрим ( +1)-е применение операции inject (строка 17), которое помещает некоторую вершину в очередь. В этом случае вершина смежна вершине , цвет которой отличен от белого. Следовательно, значение [ ] уже стабилизировалось, и, в силу индукционного предположения, справедливо [ ] > ( , ). Тогда в силу присвоения в строке 15 и леммы 5 получаем
[ ] = [ ] + 1 > ( , ) + 1 > ( , ).
Следующая лемма показывает, что в любой момент времени в очереди находится не более двух различных значений расстояния .
Лемма 7. Предположим, что в процессе выполнения процедуры BFS( , ) очередь находится в состоянии = 1, 2, . . . , . Тогда [ ] 6 [ 1] + 1 и [ ] 6 [ +1] для всех 1 6 6 − 1.
Доказательство. Докажем утверждение леммы индукцией по числу операций с очередью. Когда очередь пуста или состоит из одной исходной вершины , утверждение очевидно.
Если из очереди извлекается её голова 1, новой головой очереди становится вершина 2. В силу индукционного предположения, [ 1] 6 [ 2]. Тогда [ ] 6 [ 1]+1 6 6 [ 2] + 1, а все остальные неравенства не изменяются.
Если в очередь помещается вершина после исполнения строки 17, то становится вершиной +1 в хвосте очереди. Следовательно, вершина смежна некоторой вершине , которая в текущей итерации цикла while была удалена из очереди. Пусть непосредственно перед удалением из очереди её состояние имело вид, 1, 2, . . . , для некоторого 6 . Следовательно, вершины +1, . . . , тоже бы- ли добавлены в очередь в текущей итерации цикла while, и значит, +1, . . . , тоже смежны вершине . Если = 0, то [ 1] = · · · = [ +1] = [ ] + 1 и утверждение леммы очевидно. Если же > 1, то, в силу индукционного предположения для состояния очереди , 1, 2, . . . , , справедливы неравенства [ ] 6 [ 1] и [ ] 6 [ ] + 1. Тогда [ +1] = [ ] = [ ] + 1 6 [ 1] + 1. Кроме этого, [ ] 6 [ ] + 1 = [ +1] = = · · · = [ +1], а все остальные неравенства не изменяются. 
Приведённое ниже следствие показывает, что значения помещаемых в очередь вершин монотонно возрастают.
22 |
Глава II. Алгоритмы для работы с графами |
|
|
Следствие 8. Предположим, что в процессе выполнения процедуры BFS( , ) вершины и помещаются в очередь , причём попадает в очередь до . Тогда в момент помещения в очередь выполняется неравенство [ ] 6 [ ].
Доказательство. Вытекает из леммы 7 и того факта, что в процессе выполнения процедуры BFS каждая вершина получает конечное значение [ ] не более одного раза. 

Дерево поиска в ширину однозначно определяется функцией предшественников.
Определение. Пусть — функция предшественников, вычисленная в результате применения процедуры BFS( , ) к графу = , с исходной вершиной . Определим неориентированный граф = , , где
= { } { | [ ] ↓},
= {( [ ], ) | { }}.
Граф является деревом (доказательство этого факта приведено ниже в теореме 9) и называется деревом поиска в ширину.
Теорема 9 (о корректности поиска в ширину). Пусть = , — ориентированный или неориентированный граф и пусть процедура BFS выполняется над графом
с исходной вершиной . Тогда справедливы следующие утверждения:
(1)По окончании работы BFS( , ) для всех выполняется [ ] = ( , ).
(2)В процессе работы BFS( , ) открываются все вершины, достижимые из .
(3)Граф является деревом, состоящим из всех вершин, достижимых из в графе .
(4)Для всех в дереве имеется единственный простой путь из в , который одновременно является кратчайшим путём из в в графе .
Доказательство. (1) Допустим, напротив, существуют вершины такие, что[ ] ̸= ( , ). Среди всех таких вершин выберем вершину с минимальной длиной( , ). Очевидно, что ̸= . В силу леммы 6, имеет место [ ] > ( , ). Следовательно, в силу нашего предположения, [ ] > ( , ). Тогда вершина должна быть достижима из , так как иначе ( , ) = ∞ > [ ]. Выберем в графе какой-нибудь кратчайший путь из в . Так как ̸= , на этом пути есть вершина , непосредственно предшествующая вершине . Следовательно, ( , ) = ( , ) + 1. Таким образом,( , ) < ( , ) и, значит, в силу выбора вершины , заключаем, что [ ] = ( , ). Объединяя найденные соотношения, получаем
[ ] > ( , ) = ( , ) + 1 = [ ] + 1. |
(*) |
Ясно, что вершина тоже достижима из . Следовательно, значение ( , ) конечно, и значит, [ ] тоже конечно. Из кода процедуры BFS видно, что если [ ] присваивается конечное значение, то попадает в очередь . Следовательно, наступит момент, когда будет удалена из очереди (строка 11). В этот момент вершинаможет быть белой, серой или чёрной. Покажем, что в любом из этих трёх случаев получается противоречие с неравенством (*). Если белая, то в строке 15 выполняется присваивание [ ] = [ ] + 1, противоречащее (*). Если чёрная, то она уже
§ 4. Поиск в ширину |
23 |
|
|
удалена из очереди и, в силу следствия 8, [ ] 6 [ ], что опять противоречит (*). Если серая, то она была покрашена в этот цвет при удалении из очереди некоторой вершины , которая была удалена раньше вершины и для которой выполняется[ ] = [ ]+1. Однако из следствия 8 вытекает, что [ ] 6 [ ], поэтому [ ] 6 [ ]+1, что тоже противоречит (*).
(2) Допустим, существует достижимая из вершина , которая не открывается процедурой BFS( , ). Тогда [ ] = ∞, но при этом значение ( , ) конечно, что противоречит доказанному выше свойству [ ] = ( , ).
(3) Заметим, что для вершины ̸= условие равносильно тому, что значение [ ] становится определённым в строке 16 процедуры BFS, что, в свою очередь, происходит тогда и только тогда, когда значение [ ] становится конечным в строке 15. Поскольку [ ] = ( , ), заключаем, что тогда и только тогда, когда( , ) < ∞, т.е. достижима из в графе . Также отметим, что если [ ] = , то[ ] = [ ] + 1, и следовательно, из условия [ ] = ( , ) < ∞ вытекает соотношение[ ] = ( , ) < ∞, т.е. , а ребро ( [ ], ) действительно соединяет вершины из .
Таким образом, граф определён корректно и состоит из всех вершин, достижи- мых из в . Тогда — связный граф, поскольку любые две его вершины связаны путями с . Кроме этого, из определения графа следует, что | | = | | − 1. Следовательно, в силу теоремы 4, граф является деревом.
(4) Пусть . Поскольку является деревом, в силу теоремы 4, заключаем, что в существует единственный простой путь = 0, . . . , от корня = 0 к вершине = . Докажем, что для всех 1 6 6 справедливо свойство −1 = [ ] (т.е. случай [ −1] = невозможен). Действительно, для = 1 это свойство справедливо, поскольку [ ] не определено. Далее, рассуждая по индукции, допустим, что для фиксированного > 1 справедливо свойство −1 = [ ]. Если тождество= [ +1] неверно, то [ ] = +1, откуда следует, что −1 = +1, а это противоре- чит простоте пути . Следовательно, = [ +1], что и требовалось.
Теперь индукцией по длине пути докажем, что этот путь одновременно является кратчайшим путём из в в графе . Если = 0, то путь, состоящий из одной вершины , очевидно, является кратчайшим в . Если же > 0, то ̸= , и
значит, определено значение [ ] = . Отсюда, в силу условий = и −1 = [ ], вытекает, что = −1. Ясно, что путь = 0, . . . , −1 является простым путём от к в дереве . Следовательно, в силу индукционного предположения, яв- ляется кратчайшим путём из в в графе , и значит, длина пути совпадает со значением ( , ). Тогда длина пути равна ( , ) + 1. Заметим, что по построению[ ] = [ ] + 1, откуда следует, что ( , ) = ( , ) + 1. Тогда длина пути равна( , ), т.е. — кратчайший путь из в в графе . 
Время работы алгоритма
Инициализация в строках 01–07 расходует одно и то же постоянное количество операций на каждую из вершин. Поэтому общее время выполнения инициализации
равно (| |). После инициализации ни одна вершина не окрашивается в белый цвет,
поэтому проверка в строке 13 гарантирует, что каждая вершина вносится в очередь не более одного раза, а следовательно, и удаляется из очереди не более одного ра-
за. Операции внесения в очередь и удаления из неё требуют (1) времени, так что общее количество операций с очередью составляет (| |). Все оставшиеся операции производятся в цикле while, внутри которого для каждой вершины , извлекаемой
24 |
Глава II. Алгоритмы для работы с графами |
|
|
из очереди, сканируется список всех выходящих из рёбер, для каждого из которых осуществляется (1) операций. Если граф ориентированный, то ребро в цикле
просматривается один раз; если неориентированный — то два раза. Поскольку суммарное количество рёбер равно | |, общее время выполнения всех итераций цикла
while равно (| |). Таким образом, общее время работы процедуры BFS составляет(| |+| |), т.е. время поиска в ширину линейно зависит от размера входного графа.
Упражнения
1.Применить алгоритм поиска в ширину к следующему ориентированному графу, взяв в качестве исходной вершину 3.
1n - |
2n |
|
3n |
|
||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
n |
|
|
n |
|
|
n |
|
||||
|
|
|
|
|||||||||
|
? |
|
|
? |
|
? |
|
|
||||
|
|
|
|
|
|
|
||||||
|
|
|
|
|
|
|
|
|
|
|
||
4 |
|
|
5 |
|
6 |
|
|
|||||
|
|
|
||||||||||
2.Применить алгоритм поиска в ширину к следующему неориентированному графу, взяв в качестве исходной вершину .
n |
n |
|
|
n |
|
n |
||
n |
n |
|
n |
|
||||
|
|
n |
||||||
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
Применить алгоритм поиска в ширину к этому же графу, изменив порядок просмотра вершин, смежных с данной.
3.Привести пример ориентированного графа = , , исходной вершины и множества рёбер ′ таких, что граф ′ = , ′ является деревом, для каждой вершины единственный путь в дереве ′ от к будет
кратчайшим путём из к в графе , но дерево ′ невозможно получить как дерево поиска процедуры BFS( , ) ни при каком порядке просмотра вершин. (Считаем, что в графе ′ рёбра из ′ подвергаются операции дезориентации, т.е. превращаются из упорядоченных пар в неупорядоченные.)
4.Используя процедуру BFS, разработать алгоритм нахождения всех связных компонентов неориентированного графа.
§5. Поиск в глубину
Обход графа методом поиска в глубину (depth-first search) часто используется в качестве подпрограммы в других алгоритмах. Так же как и обход в ширину, алгоритм поиска в глубину даёт важную информацию о структуре графа. Основное отличие поиска в глубину от поиска в ширину заключается в том, что множество открытых к данному моменту вершин организовано не в виде очереди, как это было сделано в
§ 5. Поиск в глубину |
25 |
|
|
процедуре BFS, а в виде стека. В процедуре поиска в глубину, изложенной в данном параграфе, вместо явного стека используется рекурсия.
Описание алгоритма
Стратегия поиска в глубину состоит в том, чтобы идти вглубь графа, насколько это возможно. Поиск в глубину исследует все рёбра, выходящие из вершины , открытой последней, при этом открываются новые вершины, что означает запуск рекурсии. Когда не останется неисследованных рёбер, выходящих из , поиск по-
кидает вершину и возвращается в ту, из которой была открыта . Этот процесс
продолжается до тех пор, пока не будут открыты все вершины, достижимые из исходной. Если при этом остаются неоткрытые вершины, то одна из них выбирается в качестве новой исходной вершины и поиск повторяется уже из неё. Поиск в глубину продолжается до тех пор, пока не будут открыты все вершины графа.
Алгоритм раскрашивает каждую вершину графа последовательно в белый, потом в серый и наконец в чёрный цвета. Изначально каждая вершина белая, затем при открытии она окрашивается в серый цвет, а по завершении, т.е. когда исследо-
ваны все выходящие из неё рёбра, становится чёрной. Цвет вершины хранится в переменной [ ].
Алгоритм также проставляет в вершинах метки времени. Каждая вершина имеет две такие метки. В первой метке [ ] указывается время открытия вершины . Вторая метка [ ] фиксирует время завершения исследования выходящих из рёбер. Метки времени представляют собой целые числа от 1 до 2·| |. Для проставления меток времени используется глобальная переменная .
Как и в случае поиска в ширину, когда вершина открывается в процессе сканирования вершин, смежных с уже открытой вершиной , алгоритм поиска в глубину объявляет предшественником вершины . Предшественник вершины хранится в
переменной [ ], а рёбра вида ( [ ], ) образуют лес поиска, который может состоять
из нескольких деревьев поиска.
Представленная ниже процедура поиска в глубину DFS работает как для ориентированных, так и для неориентированных графов.
DFS( )
{Вход: граф = , .} {Выход: время открытия [ ] и время завершения [ ] для всех , предшественник [ ] для некоторых .}
01 |
for каждой вершины |
02 |
do [ ] ← white |
03 |
[ ] ↑ |
04 |
← 0 |
05 |
for каждой вершины |
06 |
do if [ ] = white |
07 |
then DFS_Visit( ) |
DFS_Visit( ) |
|
01 |
[ ] ← gray |
02 |
← + 1 |
03 |
[ ] ← |
04 |
for каждого ребра ( , ) |
05 |
do if [ ] = white |
06 |
then [ ] ← |
26 |
Глава II. Алгоритмы для работы с графами |
|
|
07 |
DFS_Visit( ) |
08 |
[ ] ← black |
09← + 1
10[ ] ←
Процедура DFS работает следующим образом. В строках 01–03 все вершины окрашиваются в белый цвет, а их предшественники объявляются неопределёнными. В строке 04 выполняется сброс глобального счётчика времени. В строках 05–07
поочерёдно проверяются все вершины из , и, когда обнаруживается белая вершина, она обрабатывается с помощью процедуры DFS_Visit, которая вызывается
встроке 07, при этом вершина становится корнем нового дерева из леса поиска.
Вмомент вызова процедуры DFS_Visit( ) вершина имеет белый цвет. В строках 01–03 она окрашивается в серый цвет, глобальная переменная увеличивается на единицу, и новое значение фиксируется как время открытия [ ] вершины . В строках 04–07 исследуются все вершины , смежные с , и, если вершина белая, её предшественником объявляется вершина , и выполняется рекурсивное посещение вершины . Наконец, после того как исследованы все вершины, смежные с , в строках 08–10 вершина окрашивается в чёрный цвет, переменная увеличивается
на единицу и записывается время завершения [ ] работы с вершиной .
Результаты поиска в глубину могут зависеть от порядка просмотра вершин в строке 05 процедуры DFS, а также от порядка посещения смежных вершин в строке 04 процедуры DFS_Visit.
Пример. Ниже проиллюстрирована работа процедуры DFS на примере шестиэлементного ориентированного графа. В вершинах указаны метки времени в формате открытие/завершение. Рёбра, исследованные процедурой в строке 04, либо выделяются серым цветом (если это рёбра деревьев), либо помечены буквами F (прямые рёбра), B (обратные рёбра) или C (перекрёстные рёбра). (Разметка рёбер не входит в функции процедуры DFS. Определение типов рёбер будет приведено позже.)
(а) 1/ |
|
- |
|
|
|
|
|
|
|
|
|
(б) 1/ |
|
- |
2/ |
|
|
|
|
|
|||||||||||||||||||
|
~~ |
|
|
|
|
|
|
|
~~ ~~ |
|
|
|
|
||||||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||
|
|
|
|
|
|
||||||||||||||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||||||||||
|
|
? |
|
|
|
|
|
|
? |
? |
|
|
|
|
|
? |
|
|
|
|
|
|
? |
? |
|
|
|
||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(в) 1/ |
|
- |
2/ |
|
|
|
|
|
(г) 1/ |
|
- |
2/ |
|
|
|
|
|
||||||||||||||||||||||
|
~~ ~~ |
|
|
|
|
|
~~ ~~ |
|
|
|
|
||||||||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||||
|
|
|
|
3/ |
|
|
|
|
|
|
|
4/ |
|
|
|
3/ |
|
|
|
|
|
|
|
|
|||||||||||||||
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||||||||||||||
|
|
~~ |
|
|
~~ ~~ |
|
|
||||||||||||||||||||||||||||||||
|
|
? |
|
|
|
|
|
|
? |
? |
|
|
|
|
|
? |
|
|
|
|
|
|
? |
? |
|
|
|
||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(д) 1/ |
|
- |
2/ |
|
|
|
|
|
(е) 1/ |
|
- |
2/ |
|
|
|
|
|
||||||||||||||||||||||
|
~~B ~~ |
|
|
|
|
|
~~B ~~ |
|
|
|
|
||||||||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||||
4/ |
|
|
3/ |
|
|
|
|
|
|
|
|
|
|
|
|
3/ |
|
|
|
|
|
|
|
|
|||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||||||
~~ ~~ |
|
|
~~ ~~ |
|
|
||||||||||||||||||||||||||||||||||
|
|
? |
|
|
|
|
|
|
? |
? |
|
|
|
|
|
? |
|
|
|
|
|
|
? |
? |
|
|
|
||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
§ 5. Поиск в глубину |
27 |
|
|
(ж) 1/ |
|
- |
2/ |
|
|
|
|
|
|
||||||
~~B ~~ |
|
|
|
|
|||||||||||
|
|
|
|
|
|
|
|
|
|||||||
|
|
|
|
|
|
|
|
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
||||
~~ ~~ |
|
|
|
||||||||||||
|
? |
|
|
|
? |
? |
|
|
|
||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(и) 1/ |
|
- |
|
|
|
|
|
|
|
|
|||||
~~B ~~ |
|
|
|
|
|||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
||||
F |
|
|
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
|
|
|
|
|
|
||||
~~ ~~ |
|
|
|
||||||||||||
|
? |
|
|
|
? |
? |
|
|
|
||||||
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(л) |
|
|
|
|
- |
|
|
|
9/ |
|
|
||||
~~B ~~ ~~ |
|||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
F |
|
|
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
|
|
|
|
|
|
||||
~~ ~~ |
? |
|
|
||||||||||||
|
? |
|
|
|
? |
|
|
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(з) 1/ |
|
- |
|
|
|
|
|
|
|
|
|||||||
|
~~B ~~ |
|
|
|
|
||||||||||||
|
|
|
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
|
|
|
|
|
|
||||||
~~ ~~ |
|
|
|
||||||||||||||
|
|
? |
|
|
|
|
? |
? |
|
|
|
||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(к) |
|
|
- |
|
|
|
|
|
|
||||||||
|
|
|
|
|
|
|
|||||||||||
|
~ |
~B |
~~ |
|
|
|
|
|
|||||||||
|
|
|
|
|
|||||||||||||
F |
|
|
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
|
|
|
|
|
|
||||||
|
|
|
|
|
|
|
|||||||||||
~~ ~~ |
|
|
|||||||||||||||
|
|
? |
|
|
|
|
? |
? |
|
|
|
||||||
|
|
|
|
|
|
|
|
|
|
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(м) |
|
|
|
|
- |
|
|
|
9/ |
|
|
||||||
|
~~B ~~ ~~ |
||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
F |
|
|
|
|
|
|
|
|
|
|
|
||||||
|
|
|
|
|
|
|
|||||||||||
|
|
|
|
|
|
|
C |
|
|
|
|
||||||
~~ ~~ |
? |
|
|
||||||||||||||
|
|
? |
|
|
|
|
? |
|
|
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(н) |
|
|
- |
|
|
9/ |
|
|
|||
~~B ~~ ~~ |
|||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
F |
|
|
|
|
|
|
|
||||
~~ |
~~ ~~ |
||||||||||
|
|
|
|
|
|
|
? |
|
|
||
|
|
? |
|
? C |
|
|
|
||||
|
|
|
|
|
10/ |
|
|
|
|||
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|||
(о) |
|
|
|
- |
|
|
|
9/ |
|
|
|||||
~~B ~~ ~~ |
|||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
||||
F |
|
|
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
B |
|||
~~ |
~~ ~~ |
||||||||||||||
|
|
|
|
|
|
|
|
|
? |
|
|
||||
|
|
? |
|
? C |
|
|
|
||||||||
|
|
|
|
|
10/ |
|
|
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
|||||
(п) |
|
|
- |
|
|
|
9/ |
|
|
(р) |
|
|
- |
|
|
|
|
|
|
|
|
|||||
~~B ~~ ~~ |
~~B ~~ ~~ |
|||||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||
F |
|
|
|
|
|
|
|
|
|
|
F |
|
|
|
|
|
|
|
|
|
||||||
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||
|
|
|
|
|
|
C |
|
|
B |
|
|
|
|
|
C |
|
|
B |
||||||||
|
|
|
|
|
|
|
|
|
||||||||||||||||||
~~ |
~~ ~~ |
~~ |
~~ ~~ |
|||||||||||||||||||||||
|
|
? |
|
|
|
|
|
? |
|
|
|
|
? |
|
|
|
|
? |
|
|
||||||
|
|
|
|
? |
|
|
|
|
|
|
|
? |
|
|
|
|||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Свойства алгоритма
Наиболее фундаментальное свойство поиска в глубину заключается в том, что определённый с помощью функции предшественников лес поиска в глубину в точности отражает структуру рекурсивных вызовов процедуры DFS_Visit.
Определение. Пусть — функция предшественников, вычисленная в результате применения процедуры DFS( ) к графу = , . Определим неориентированный граф = , , где
= {( [ ], ) | и [ ] ↓}.
Граф является лесом (доказательство этого факта приведено ниже в теореме 11), называется лесом поиска в глубину и состоит из нескольких деревьев поиска в глубину. Вершины , для которых не определено значение [ ], будем называть
корнями деревьев поиска в глубину.
Лемма 10. Пусть = , — ориентированный или неориентированный граф,, и [ ] 6 [ ] < [ ]. Тогда в графе существует путь из вершины в вершину .
28 Глава II. Алгоритмы для работы с графами
Доказательство. Докажем утверждение леммы индукцией по значению[ ] = [ ], то = и утверждение очевидно.
Пусть [ ] > [ ]. Поскольку [ ] < [ ] < [ ], заключаем, что вершина открывается в процессе исполнения процедуры DFS_Visit( ). Следовательно, в процессе исполнения DFS_Visit( ) для некоторой вершины ′ происходит рекурсивный вы- зов процедуры DFS_Visit( ′), при исполнении которой вершина открывается как смежная с ′. Таким образом, по построению [ ] = ′ и ребро ( ′, ) добавляется
в граф . Ясно, что [ ] 6 [ ′] < [ ]. Тогда, в силу индукционного предположения, в графе существует путь из в ′. Дополнив путь ребром ( ′, ) ,
получаем искомый путь из в .
Теорема 11 (о корректности поиска в глубину) . Пусть = , — ориентированный или неориентированный граф и пусть процедура DFS выполняется над графом. Тогда справедливы следующие утверждения:
(1)В процессе работы DFS( ) открываются все вершины графа .
(2)Граф является лесом, состоящим из нескольких деревьев.
Доказательство. (1) Цикл for в строках 05–07 процедуры DFS просматривает все вершины , и если вершина белая, то она открывается вызовом процедуры
DFS_Visit( ), а если не белая, то уже была открыта ранее. Таким образом, к моменту окончания работы DFS( ) все вершины графа будут открыты.
(2) Пусть 1, . . . , — набор всех вершин из , которые при проверке в строке 06 процедуры DFS оказались белыми, при этом будем считать, что при < вершина просматривается процедурой раньше, чем . Процедура DFS_Visit( ) не изменяет значение [ ], поэтому к моменту окончания поиска в глубину значе-
ние [ ] не определено для всех 1 6 6 . Все остальные вершины, т.е. вершины
{ 1, . . . , }, открываются рекурсивным вызовом DFS_Visit( ) в строке 07 процедуры DFS_Visit, а значит, в строке 06 для них определяется предшественник
[ ].
Для каждого 1 6 6 обозначим через множество вершин , которые открываются в процессе работы процедуры DFS_Visit( ), т.е. [ ] 6 [ ] < [ ]. Заметим, что для < в момент запуска процедуры DFS_Visit( ) все вершины из уже окрашены в чёрный цвет, а в процессе работы DFS_Visit( ) открываются только белые вершины. Следовательно, ∩ = ? для всех ̸= . Таким образом, { 1, . . . , } является разбиением на непересекающиеся подмножества, причём , 1 6 6 .
Для каждого 1 6 6 положим = {( [ ], ) | { }}. Заметим, что для любой вершины { } в момент определения её предшественника [ ] вершина= [ ] должна быть серой. Поскольку в этот момент все вершины из 1 · · · −1 уже окрашены в чёрный цвет, а все вершины из +1 · · · пока остаются белыми, заключаем, что . Таким образом, замкнуто относительно предшественников, и значит, × .
Обозначим = , , 1 6 6 . Мы установили, что граф разбивается на попарно несвязанные графы 1, . . . , . Докажем, что для всех 1 6 6 граф — связный. Для этого достаточно показать, что для любой вершины в графе существует путь из в . Из неравенства [ ] 6 [ ] < [ ] по лемме 10 следует, что в графе существует путь из в . Поскольку и замкнуто относительно предшественников, заключаем, что данный путь полностью содержится в графе .
|
§ 5. Поиск в глубину |
|
29 |
|
|
|
|
Итак, для всех 1 6 |
6 граф связный и при этом |
| | |
= | | − 1. Следо- |
вательно, по теореме 4 графы 1, . . . , являются деревьями с корнями 1, . . . , соответственно, а их объединение, т.е. граф , — лесом. 
Тот факт, что граф является лесом, позволяет нам говорить о потомках и предках в деревьях данного леса.
Пусть — лес поиска, полученный в результате применения процедуры DFS к ориентированному или неориентированному графу = , , и пусть, , ̸= . Вершина является потомком вершины в лесу тогда и только тогда, когда вершина была серой в момент открытия вершины .
Доказательство. (= ) Поскольку , заключаем, что в одном из деревьев поиска с корнем существует путь 0, . . . , такой, что 0 = , = и = [ +1] для всех < . Достаточно показать, что в момент открытия вершины все вер-
шины 0, . . . , −1 окрашены в серый цвет. Докажем это утверждение индукцией по значению , изменяющемуся от − 1 до 1. Очевидно, в момент открытия вершины
её предшественник −1 должен иметь серый цвет. Допустим теперь, что в момент открытия вершина +1 имеет серый цвет. Из условия = [ +1] следует, что+1 была открыта при исполнении строки 07 процедуры DFS_Visit( ), при этом произошёл рекурсивный вызов процедуры DFS_Visit( +1). Поскольку в рассматриваемый момент вершина +1 всё ещё серая, процедура DFS_Visit( +1) ещё не завершила свою работу, и значит, процедура DFS_Visit( ) ещё не перешла к ис-
полнению строки 08. Таким образом, вершина в рассматриваемый момент тоже серая.
( =) Пусть в момент открытия вершины вершина имеет серый цвет. Следовательно, ранее была вызвана процедура DFS_Visit( ), которая в момент открытия вершины ещё не закончила свою работу. Отсюда следует, что [ ] < [ ] < [ ]. В силу леммы 10 в графе найдётся путь из в . Тогда путь полностью содержится в одном из деревьев поиска с некоторым корнем . В этом дереве существует единственный путь из в , дополнив который путём , мы получим путь из в , показывающий, что является потомком в данном дереве. 
Ещё одно важное свойство поиска в глубину заключается в том, что метки открытия и завершения образуют скобочную структуру. Если представить открытие
вершины в виде открывающейся скобки “ ( ”, а завершение — в виде закрывающейся скобки “ )”, то хронологический список открытий и завершений образует корректное выражение в смысле сбалансированности скобок.
Пример. Пусть результат поиска в глубину имеет вид, изображённый на рисунке.
~~ ~~ ~~ ~~
|
|
|
|
|
6 |
|
|
|
6 |
|||
|
|
|
|
|
||||||||
|
B |
|
|
F |
C |
|
|
|
B |
|||
|
|
|
|
|
|
~ |
~ |
|||||
~~ ~~ ~~ |
||||||||||||
? |
? |
|
? |
|
||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
C |
|
|
C |
|
C |
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
Тогда соответствующее ему скобочное выражение имеет вид
( ) ( )
( )
( ( ) )( ) ( )( ) .
30 |
Глава II. Алгоритмы для работы с графами |
|
|
Теорема 13 (о скобках). Пусть процедура DFS применяется к ориентированному или неориентированному графу = , . Тогда для любых различных вершин
, выполняется ровно одно из следующих трёх утверждений:
(1)Отрезки [ [ ], [ ]] и [ [ ], [ ]] не пересекаются, и ни не является потомкомв лесу поиска , ни не является потомком .
(2)Отрезок [ [ ], [ ]] полностью содержится в отрезке [ [ ], [ ]], и является потомком в лесу поиска .
(3)Отрезок [ [ ], [ ]] полностью содержится в отрезке [ [ ], [ ]], и является потомком в лесу поиска .
Доказательство. Из условия ̸= следует, что [ ] < [ ] или [ ] > [ ]. Рассмотрим случай [ ] < [ ], в котором имеется два подслучая, в зависимости от того, справедливо неравенство [ ] < [ ] или нет. Если [ ] < [ ], то вершина была открыта, когда вершина была окрашена в серый цвет. Отсюда по лемме 12 заключаем, что является потомком вершины в лесу . Кроме этого, поскольку вершина открыта позже, чем , перед тем как вернуться для завершения поиска к вершине , процедурой DFS будут исследованы все выходящие из рёбра. В таком случае отрезок [ [ ], [ ]] полностью содержится в отрезке [ [ ], [ ]], т.е. выполняется утверждение (3). Если же [ ] < [ ], то отрезки [ [ ], [ ]] и [ [ ], [ ]] не пересекаются, а значит, когда открывается одна их вершин или , другая имеет
белый или чёрный цвет. Следовательно, в силу леммы 12, ни одна из данных вершин не является потомком другой, т.е. выполняется утверждение (1).
Случай [ ] > [ ] рассматривается аналогично. Здесь будет справедливо либо утверждение (1), либо утверждение (2). 
Поиск в глубину можно использовать для классификации рёбер входного графа.
Определение. Пусть — лес поиска, полученный в результате применения процедуры DFS к ориентированному или неориентированному графу = , . Опре-
делим следующие четыре типа рёбер графа :
(а) Рёбра деревьев — это рёбра графа .
(б)Обратные рёбра — это рёбра ( , ) , соединяющие вершину с её предкомв дереве поиска. Рёбра-петли, которые могут встречаться в ориентированных графах, считаются обратными рёбрами.
(в)Прямые рёбра — это рёбра ( , ) , не являющиеся рёбрами деревьев и соединяющие вершину с её потомком в дереве поиска.
(г)Перекрёстные рёбра — все остальные рёбра. Они могут соединять вершины из разных деревьев поиска или вершины одного и того же дерева поиска, когда ни одна из вершин не является предком другой.
Замечание. В неориентированных графах при классификации рёбер может возникнуть неоднозначность, связанная с тем, что алгоритм просматривает каждое ребро
дважды: в виде ( , ) и ( , ). В таком случае, когда ребро удовлетворяет нескольким
категориям из списка (а)–(г), оно классифицируется в соответствии с первой категорией в списке, применимой для данного ребра. Приняв данное соглашение, можно
