Когда целесообразно использовать поиск в глубину (DFS) по сравнению с поиском в ширину (BFS)?

Я понимаю разницу между DFS и BFS, но мне интересно знать, когда практичнее использовать один поверх другого?

Может ли кто-нибудь привести примеры того, как DFS превзойдет BFS и наоборот?

Ответ 1

Это в значительной степени зависит от структуры дерева поиска, количества и местоположения решений (ака поиск предметов).

  • Если вы знаете, что решение находится недалеко от корня дерева, более широкий поиск по ширине (BFS) может быть лучше.
  • Если дерево очень глубокое и решения редки, сначала поиск глубины (DFS) может занять очень много времени, но BFS может быть быстрее.

  • Если дерево очень широкое, BFS может потребоваться слишком много памяти, поэтому может быть совершенно непрактичным.

  • Если решения часты, но расположены глубоко в дереве, BFS может быть непрактично.

  • Если дерево поиска очень глубокое, вам нужно будет ограничить поиск глубина для первого поиска глубины (DFS), в любом случае (например, с итерационное углубление).

Но это просто эмпирические правила; вам, вероятно, придется экспериментировать.

Ответ 2

Поиск по глубине

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

введите описание изображения здесь

Например, в таких играх, как Chess, tic-tac-toe, когда вы решаете, что делать, вы можете мысленно представить себе ход, затем ваши оппоненты, возможные ответы, ваши ответы и т.д. Вы можете решить, что делать, видя, какой шаг ведет к лучшему результату.

Только некоторые пути в игровом дереве приводят к вашей победе. Некоторые приводят к победе вашего оппонента, когда вы достигаете такого окончания, вы должны сделать резервную копию или вернуться к предыдущему node и попробовать другой путь. Таким образом, вы исследуете дерево, пока не найдете путь с успешным завершением. Затем вы делаете первый шаг по этому пути.


Поиск по ширине

Поиск по ширине имеет интересное свойство: он сначала находит все вершины, которые находятся на одном ребре от начальной точки, затем все вершины, которые являются двумя ребрами, и так далее. Это полезно, если вы пытаетесь найти кратчайший путь от начальной вершины до заданной вершины. Вы запускаете BFS, и когда вы найдете указанную вершину, вы знаете, что путь, который вы прослеживали до сих пор, является самым коротким путем к node. Если бы был более короткий путь, BFS уже нашел бы его.

Поиск по ширине и ширине может использоваться для поиска соседних узлов в одноранговых сетях, таких как BitTorrent, GPS-системы, чтобы найти соседние местоположения, сайты социальных сетей, чтобы найти людей на указанном расстоянии и тому подобное.

Ответ 3

Хорошее Объяснение из http://www.programmerinterview.com/index.php/data-structures/dfs-vs-bfs/

Пример BFS

Вот пример того, как будет выглядеть BFS. Это что-то похожее на Traversal Order Order, где мы будем использовать QUEUE с подходом ITERATIVE (в основном RECURSION закончится с DFS). Цифры представляют порядок, в котором узлы обращаются в BFS:

enter image description here

В глубине первого поиска вы начинаете с корня и следуете по одной из ветвей дерева до тех пор, пока не найдете либо найденный node, либо вы ударите лист node (a node без детей). Если вы нажмете лист node, вы продолжите поиск у ближайшего предка с неисследованными детьми.

Пример DFS

Вот пример того, как будет выглядеть DFS. Я думаю, что после обхода порядка в двоичном дереве сначала начнется работа с уровня Leaf. Цифры представляют собой порядок доступа к узлам в DFS:

enter image description here

Различия между DFS и BFS

Сравнивая BFS и DFS, большое преимущество DFS заключается в том, что он имеет гораздо более низкие требования к памяти, чем BFS, потому что не нужно хранить все дочерние указатели на каждом уровне. В зависимости от данных и того, что вы ищете, может быть выгодно использовать DFS или BFS.

Например, учитывая родовое дерево, если кто-то искал кого-то на дереве, все еще живом, тогда было бы безопасно предположить, что человек будет на дне дерева. Это означает, что BFS займет очень много времени, чтобы достичь этого последнего уровня. Однако DFS быстрее найдет цель. Но если бы кто-то искал члена семьи, который умер очень давно, тогда этот человек будет ближе к вершине дерева. Затем BFS обычно будет быстрее, чем DFS. Таким образом, преимущества либо варьируются в зависимости от данных и того, что вы ищете.

Еще один пример - Facebook; Предложение о друзьях друзей. Нам нужны непосредственные друзья для предложения, где мы можем использовать BFS. Можно найти кратчайший путь или определить цикл (используя рекурсию), мы можем использовать DFS.

Ответ 4

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

Глубина Первый поиск обычно используется, когда вам нужно искать по всему дереву. Это проще реализовать (используя рекурсию), чем BFS, и требует меньше состояния: хотя BFS требует, чтобы вы хранили всю "границу", DFS требует, чтобы вы сохранили список родительских узлов текущего элемента.

Ответ 5

DFS более экономичен по площади, чем BFS, но может идти на ненужные глубины.

Их имена раскрываются: если имеется большая ширина (т.е. большой коэффициент ветвления), но очень ограниченная глубина (например, ограниченное количество "ходов" ), то DFS может быть более предпочтительным для BFS.


В IDDFS

Следует отметить, что существует менее известный вариант, который объединяет пространственную эффективность DFS, но (cummulatively) посещение BFS уровня, является итеративный углубленный поиск глубины - первый поиск. Этот алгоритм пересматривает некоторые узлы, но он лишь способствует постоянному коэффициенту асимптотической разности.

Ответ 6

Когда вы подходите к этому вопросу в качестве программиста, выделяется один фактор: если вы используете рекурсию, то поиск по глубине проще для реализации, поскольку вам не нужно поддерживать дополнительная структура данных, содержащая узлы, которые еще предстоит исследовать.

Здесь поиск по глубине для неориентированного графика, если вы храните информацию о "уже посещенных" в узлах:

def dfs(origin):                               # DFS from origin:
    origin.visited = True                      # Mark the origin as visited
    for neighbor in origin.neighbors:          # Loop over the neighbors
        if not neighbor.visited: dfs(next)     # Visit each neighbor if not already visited

Если вы сохраняете информацию о "уже посещенной" в отдельной структуре данных:

def dfs(node, visited):                        # DFS from origin, with already-visited set:
    visited.add(node)                          # Mark the origin as visited
    for neighbor in node.neighbors:            # Loop over the neighbors
        if not neighbor in visited:            # If the neighbor hasn't been visited yet,
            dfs(node, visited)                 # then visit the neighbor
dfs(origin, set())

Контрастируйте это с поиском в первом порядке, где вам нужно поддерживать отдельную структуру данных для списка узлов, которые еще не посетили, независимо от того, что.

Ответ 7

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

Ответ 8

Для BFS мы можем рассмотреть пример Facebook. Мы получаем предложение добавить друзей из профиля FB из другого профиля других друзей. Предположим, что A- > B, а B- > E и B- > F, поэтому A получит предложение для E и F. Они должны использовать BFS для чтения до второго уровня. DFS больше основан на сценариях, в которых мы хотим прогнозировать что-то на основе данных, которые мы имеем от источника к месту назначения. Как уже упоминалось о шахматах или судоку. Если у меня есть разные вещи, я считаю, что DFS следует использовать для кратчайшего пути, потому что DFS сначала охватит весь путь, а затем мы сможем решить все. Но поскольку BFS будет использовать жадный подход, возможно, это выглядит как кратчайший путь, но конечный результат может отличаться. Дайте мне знать, не ошибается ли мое понимание.

Ответ 9

Некоторые алгоритмы зависят от конкретных свойств DFS (или BFS) для работы. Например, алгоритм Hopcroft и Tarjan для поиска 2-связанных компонентов использует тот факт, что каждый уже посетивший node, встречающийся DFS, находится на пути от корня до изученного в настоящее время node.

Ответ 10

В соответствии со свойствами DFS и BFS. Например, когда мы хотим найти кратчайший путь. мы обычно используем bfs, он может гарантировать "кратчайший". но dfs только может гарантировать, что мы можем исходить из этого момента, может достичь этого момента, не может гарантировать "кратчайший".

Ответ 11

Так как поиски глубины-первого используют стек при обработке узлов, обратная трассировка предоставляется с помощью DFS. Поскольку Breadth-First Searches используют очередь, а не стек, чтобы отслеживать, какие узлы обрабатываются, backtracking не предоставляется с BFS.

Ответ 12

Когда ширина дерева очень велика, а глубина низкая, используйте DFS, поскольку стек рекурсии не будет переполняться. Используйте BFS, когда ширина мала, а глубина очень велика, чтобы пересечь дерево.

Ответ 13

Ниже приведен исчерпывающий ответ на ваш вопрос.

Проще говоря:

Алгоритм поиска в ширину (BFS), от его имени "Ширина", обнаруживает всех соседей узла через внешние ребра узла, затем он обнаруживает невидимых соседей ранее упомянутых соседей через их внешние ребра и так далее, пока все посещаются узлы, достижимые из исходного источника (мы можем продолжить и взять другой исходный источник, если есть оставшиеся не посещенные узлы и т.д.). Поэтому его можно использовать для нахождения кратчайшего пути (если он есть) от узла (исходного источника) к другому узлу, если вес ребер одинаков.

Алгоритм поиска в глубину (DFS) по имени "Глубина" обнаруживает невидимые соседи самого последнего обнаруженного узла x через его внешние ребра. Если нет невидимого соседа от узла x, алгоритм возвращает назад, чтобы обнаружить не посещенных соседей узла (через его внешние края), из которого был обнаружен узел x, и так далее, пока все узлы, достижимые из исходного источника, не будут посещены (мы можем продолжить и взять другой исходный источник, если останутся не посещенные узлы и т.д.).

И BFS, и DFS могут быть неполными. Например, если коэффициент ветвления узла бесконечен или очень велик для ресурсов (памяти) для поддержки (например, при хранении узлов, которые будут обнаружены следующими), то BFS не завершена, даже если искомый ключ может находиться на расстоянии несколько ребер из оригинального источника. Этот бесконечный фактор ветвления может быть из-за бесконечного выбора (соседних узлов) от данного узла для обнаружения. Если глубина бесконечна или очень велика для поддержки ресурсов (памяти) (например, при хранении узлов, которые должны быть обнаружены следующими), то DFS не завершена, даже если искомый ключ может быть третьим соседом исходного источника. Эта бесконечная глубина может быть вызвана ситуацией, когда для каждого узла алгоритм обнаруживает, по крайней мере, новый выбор (соседний узел), который ранее не посещался.

Поэтому мы можем сделать вывод, когда использовать BFS и DFS. Предположим, мы имеем дело с управляемым ограниченным фактором ветвления и управляемой ограниченной глубиной. Если искомый узел неглубокий, то есть достижимый после некоторых ребер от исходного источника, тогда лучше использовать BFS. С другой стороны, если искомый узел является глубоким, то есть достижимым после большого количества ребер из исходного источника, тогда лучше использовать DFS.

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

Приложения BFS и DFS могут различаться также из-за механизма поиска в каждом из них. Например, мы можем использовать либо BFS (при условии, что фактор ветвления является управляемым), либо DFS (при условии, что глубина управляема), когда мы просто хотим проверить достижимость от одного узла к другому, не имея информации о том, где этот узел может находиться. Также они оба могут решать одни и те же задачи, такие как топологическая сортировка графа (если он есть). С помощью BFS можно найти кратчайший путь с ребрами удельного веса от узла (исходного источника) к другому. Принимая во внимание, что DFS может использоваться для исчерпания всех вариантов выбора из-за его характера углубления, например, обнаружения самого длинного пути между двумя узлами в ациклическом графе. Также DFS, может использоваться для обнаружения цикла в графике.

В конце концов, если мы имеем бесконечную глубину и бесконечный коэффициент ветвления, мы можем использовать Итеративный Углубленный Поиск (IDS).

Ответ 14

Это хороший пример, чтобы продемонстрировать, что BFS лучше, чем DFS, в определенном случае. https://leetcode.com/problems/01-matrix/

При правильном внедрении оба решения должны посещать ячейки, которые расположены дальше, чем текущая ячейка +1. Но DFS неэффективен и неоднократно посещает ту же самую ячейку, что и сложность O (n * n).

Например,

1,1,1,1,1,1,1,1, 
1,1,1,1,1,1,1,1, 
1,1,1,1,1,1,1,1, 
0,0,0,0,0,0,0,0,

Ответ 15

Этот вопрос несколько стар, но отличный пример из современной видеоигры "Бит-героев". В типичном подземелье босса ваша цель - победить босса, после чего у вас есть возможность либо выйти из этой конкретной подземелья, либо продолжить изучение ее для добычи. Но в общем, боссы далеки от вашего места появления. Игра предлагает автоматическую функцию обхода подземелья, которая в основном захватывает вашего персонажа через подземелье, встречая врагов, когда они идут. Это реализовано с помощью алгоритма поиска по глубине, поскольку цель заключается в том, чтобы как можно глубже погрузиться в подземелье перед откатом.

Ответ 16

Это зависит от ситуации, в которой он используется. Всякий раз, когда у нас возникает проблема обхода графа, мы делаем это для какой-то цели. Когда существует проблема поиска кратчайшего пути в невзвешенном графе или определения, является ли граф двудольным, мы можем использовать BFS. Для задач обнаружения цикла или любой логики, требующей возврата, мы можем использовать DFS.

Ответ 17

Я думаю, это зависит от того, с какими проблемами вы сталкиваетесь.

  1. кратчайший путь на простом графе → BFS
  2. все возможные результаты → DFS
  3. поиск по графику (трактуйте дерево, мартикс как график) → dfs....