For faster navigation, this Iframe is preloading the Wikiwand page for Поиск в глубину.

Поиск в глубину

Материал из Википедии — свободной энциклопедии

Порядок обхода дерева в глубину

Поиск в глубину (англ. Depth-first search, DFS) — один из методов обхода графа. Стратегия поиска в глубину, как и следует из названия, состоит в том, чтобы идти «вглубь» графа, насколько это возможно. Алгоритм поиска описывается рекурсивно: перебираем все исходящие из рассматриваемой вершины рёбра. Если ребро ведёт в вершину, которая не была рассмотрена ранее, то запускаем алгоритм от этой нерассмотренной вершины, а после возвращаемся и продолжаем перебирать рёбра. Возврат происходит в том случае, если в рассматриваемой вершине не осталось рёбер, которые ведут в нерассмотренную вершину. Если после завершения алгоритма не все вершины были рассмотрены, то необходимо запустить алгоритм от одной из нерассмотренных вершин[1].

Алгоритм поиска в глубину

[править | править код]

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

  1. Пройдём по всем вершинам .
    • Если вершина белая, выполним для неё DFS(v).

Процедура DFS (параметр — вершина )

  1. Перекрашиваем вершину в серый цвет.
  2. Для всякой вершины , смежной с вершиной и окрашенной в белый цвет, рекурсивно выполняем процедуру DFS(w)[2].
  3. Перекрашиваем вершину в чёрный цвет.

Часто используют двухцветные метки — без серого, на 1-м шаге красят сразу в чёрный цвет.

Нерекурсивные варианты

[править | править код]

На больших графах поиск в глубину серьёзно нагружает стек вызовов. Если есть риск переполнения стека, используют нерекурсивные варианты поиска.

Первый вариант, простейший, но дающий немалый объём стека — до |E|.

  1. Кладём в стек первую вершину.
  2. Пока стек не пуст, берём верхнюю вершину, не извлекая.
    1. Если вершина белая…
      1. Красим в серый цвет.
      2. Кладём в стек всех её белых соседок в порядке, обратном порядку обхода (если таковой важен).
    2. Если вершина серая, красим в чёрный и извлекаем.
    3. Если вершина чёрная, просто извлекаем.

Если хватает двухцветных меток…

  1. Кладём в стек первую вершину.
  2. Пока стек не пуст, извлекаем верхнюю вершину. Если она белая…
    1. Красим в чёрный цвет.
    2. Кладём в стек всех её белых соседок в порядке, обратном порядку обхода.

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

Процедура DFS (параметр — вершина )

  1. Кладём в стек пару . Перекрашиваем вершину в серый цвет.
  2. Пока стек не пуст…
    1. Берём верхнюю пару , не извлекая её из стека.
    2. Находим вершину , смежную с и следующую за .
      1. Если таковой нет, извлекаем из стека, перекрашиваем вершину в чёрный цвет.
      2. В противном случае присваиваем , прямо в стеке.
        • Если к тому же вершина белая, кладём на стек пару , перекрашиваем в серый цвет.

Третий вариант: можно в каждой из «серых» вершин держать текущее и указатель на предыдущую (ту, из которой пришли).

Поиск в глубину с метками времени. Классификация рёбер

[править | править код]
Поиск в глубину с метками времени. Порядок выбора рёбер — слева направо.

Для каждой из вершин установим два числа — «время» входа и «время» выхода .

Модифицируем процедуру DFS так.

  1. Увеличиваем «текущее время» на 1. .
  2. Перекрашиваем вершину в серый цвет.
  3. Для всякой вершины , смежной с вершиной и окрашенной в белый цвет, выполняем процедуру DFS(v).
  4. Перекрашиваем вершину в чёрный цвет.
  5. Увеличиваем «текущее время» на 1. .

Считаем, что граф ориентированный. Очевидно, для любой вершины, из которой мы не вышли в момент t, . Также невозможно скрёстное неравенство: . Просматриваемые на шаге 3 дуги uv могут быть:

  • . В момент выполнения шага 3 (обозначенный как t) вершина v белая. В таком случае мы для вершины v исполняем DFS, а дуга называется дугой дерева поиска.
  • . В момент t вершина v чёрная, сравнение entry говорит, что в v попали из u. Такая дуга называется прямой.
  • . В момент t вершина v также чёрная, но сравнение entry говорит, что в v попали в обход u. Такая дуга называется перекрёстной.
  • . В момент t вершина v серая, то есть в u попали из v. Имеем дело с обратной дугой.

Рёбра неориентированного графа могут быть рёбрами дерева и обратными, но не прямыми и перекрёстными.[3] Чтобы различать рёбра неориентированного графа, достаточно указанных выше трёх- или двухцветных отметок. Ребро, идущее в белую вершину,— ребро дерева. В серую (чёрную в двухцветном варианте) — обратное. В чёрную — такого не бывает.[4]

Алгоритм Косарайю требует сортировки вершин в обратном порядке по времени выхода. Метка входа и типы рёбер нужны в алгоритмах поиска точек сочленения и мостов. Метки выхода в обратном порядке — топологический порядок вершин.

Применение

[править | править код]

Поиск в глубину ограниченно применяется как собственно поиск, чаще всего на древовидных структурах: когда расстояние между точками малó, поиск в глубину может «плутать» где-то далеко.

Зато поиск в глубину — хороший инструмент для исследования топологических свойств графов. Например:

Поиск в глубину — естественный выбор, когда агент (человек или робот) лично ходит по лабиринту и видит то, что непосредственно рядом с ним. «Правило левой руки» (идти, ведя левой рукой по стенке) будет поиском в глубину, если лабиринт древовидный (нет кружных путей).

Примечания

[править | править код]
  1. Cormen, 2005, p. 622.
  2. Обход в глубину, цвета вершин — Викиконспекты. Дата обращения: 26 июля 2022. Архивировано 2 апреля 2022 года.
  3. Если в сторону u→v оно прямое, то ранее его прошли в сторону v→u как обратное. Если в сторону u→v оно перекрёстное, его должны были пройти v→u как ребро дерева.
  4. Cormen, 2005, с. 628—629.

Литература

[править | править код]
  • Левитин А. В. Глава 5. Метод уменьшения размера задачи: Поиск в глубину // Алгоритмы. Введение в разработку и анализМ.: Вильямс, 2006. — С. 212—215. — 576 с. — ISBN 978-5-8459-0987-9
  • Кормен Т., Лейзерсон Ч., Ривест Р. Глава 22. Элементарные алгоритмы для работы с графами // Алгоритмы: построение и анализ(второе издание). — М.: «Вильямс», 2005. — С. 622—632.
Для улучшения этой статьи желательно: Проставить сноски, внести более точные указания на источники.После исправления проблемы исключите её из списка. Удалите шаблон, если устранены все недостатки.
{{bottomLinkPreText}} {{bottomLinkText}}
Поиск в глубину
Listen to this article

This browser is not supported by Wikiwand :(
Wikiwand requires a browser with modern capabilities in order to provide you with the best reading experience.
Please download and use one of the following browsers:

This article was just edited, click to reload
This article has been deleted on Wikipedia (Why?)

Back to homepage

Please click Add in the dialog above
Please click Allow in the top-left corner,
then click Install Now in the dialog
Please click Open in the download dialog,
then click Install
Please click the "Downloads" icon in the Safari toolbar, open the first download in the list,
then click Install
{{::$root.activation.text}}

Install Wikiwand

Install on Chrome Install on Firefox
Don't forget to rate us

Tell your friends about Wikiwand!

Gmail Facebook Twitter Link

Enjoying Wikiwand?

Tell your friends and spread the love:
Share on Gmail Share on Facebook Share on Twitter Share on Buffer

Our magic isn't perfect

You can help our automatic cover photo selection by reporting an unsuitable photo.

This photo is visually disturbing This photo is not a good choice

Thank you for helping!


Your input will affect cover photo selection, along with input from other users.

X

Get ready for Wikiwand 2.0 🎉! the new version arrives on September 1st! Don't want to wait?