DFS와 BFS의 차이점을 이해하고 있지만 다른 것을 사용하는 것이 더 실용적인시기에 관심이 있습니까?
누구든지 DFS가 BFS를 능가하는 방법에 대한 예를들 수 있습니까?
DFS와 BFS의 차이점을 이해하고 있지만 다른 것을 사용하는 것이 더 실용적인시기에 관심이 있습니까?
누구든지 DFS가 BFS를 능가하는 방법에 대한 예를들 수 있습니까?
답변:
검색 트리의 구조와 솔루션의 수와 위치 (일명 검색된 항목)에 따라 크게 달라집니다.
트리가 매우 깊고 솔루션이 거의없는 경우 DFS (Depth First Search)는 시간이 오래 걸리지 만 BFS가 더 빠를 수 있습니다.
트리가 매우 넓은 경우 BFS에 너무 많은 메모리가 필요할 수 있으므로 완전히 비현실적 일 수 있습니다.
솔루션이 빈번하지만 트리의 깊은 곳에있는 경우 BFS는 실용적이지 않을 수 있습니다.
그러나 이것들은 단지 경험 법칙입니다. 아마도 실험을해야 할 것입니다.
깊이 우선 검색은 종종 게임 시뮬레이션 (실제 게임과 같은 상황)에 사용됩니다. 일반적인 게임에서는 몇 가지 가능한 동작 중 하나를 선택할 수 있습니다. 각 선택은 추가 선택으로 이어지고, 각 선택은 추가 선택으로 이어지고, 계속 확장되는 나무 모양의 가능성 그래프로 이어집니다.
예를 들어, 체스, 틱택 토와 같은 게임에서 어떤 행동을할지 결정할 때는 정신적으로 움직임을 상상 한 다음 상대방의 가능한 반응과 반응 등을 상상할 수 있습니다. 어떤 움직임이 가장 좋은 결과를 가져 오는지를보고 무엇을해야할지 결정할 수 있습니다.
게임 트리의 일부 경로 만 승리로 이어집니다. 일부는 상대방의 승리로 이어지며, 그러한 결말에 도달하면 이전 노드로 백업하거나 역 추적하고 다른 경로를 시도해야합니다. 이러한 방식으로 성공적인 결론을 내릴 수있을 때까지 트리를 탐색합니다. 그런 다음이 경로를 따라 처음으로 이동하십시오.
너비 우선 탐색에는 흥미로운 특성이 있습니다. 먼저 시작점에서 한 모서리 떨어진 모든 정점을 찾은 다음 두 모서리 떨어진 모든 정점을 찾습니다. 시작 정점에서 주어진 정점까지의 최단 경로를 찾으려고 할 때 유용합니다. BFS를 시작하고 지정된 정점을 찾으면 지금까지 추적 한 경로가 노드의 최단 경로임을 알 수 있습니다. 더 짧은 경로가 있으면 BFS가 이미 찾은 것입니다.
폭 우선 검색은 BitTorrent와 같은 피어 투 피어 네트워크, 인접 위치를 찾기위한 GPS 시스템, 지정된 거리에있는 사람을 찾기위한 소셜 네트워킹 사이트 등을 찾는 데 사용할 수 있습니다.
http://www.programmerinterview.com/index.php/data-structures/dfs-vs-bfs/의 멋진 설명
BFS의 예
다음은 BFS의 모습에 대한 예입니다. 이것은 TERUE를 ITERATIVE 접근법과 함께 사용하는 Level Order Tree Traversal과 같습니다 (대부분 RECURSION은 DFS로 끝납니다). 숫자는 노드가 BFS에서 액세스되는 순서를 나타냅니다.
깊이 우선 검색에서는 루트에서 시작하여 찾고있는 노드를 찾거나 리프 노드 (자식이없는 노드)에 도달 할 때까지 가능한 한 나무의 가지 중 하나를 따릅니다. 리프 노드에 충돌하면 미 탐지 자식이있는 가장 가까운 조상에서 검색을 계속합니다.
DFS의 예
다음은 DFS의 모습에 대한 예입니다. 이진 트리의 포스트 오더 순회는 먼저 리프 레벨에서 작업을 시작한다고 생각합니다. 숫자는 DFS에서 노드에 액세스하는 순서를 나타냅니다.
DFS와 BFS의 차이점
BFS와 DFS를 비교할 때 DFS의 큰 장점은 모든 하위 포인터를 각 레벨에 저장할 필요가 없기 때문에 BFS보다 메모리 요구 사항이 훨씬 적다는 것입니다. 데이터와 찾고있는 내용에 따라 DFS 또는 BFS가 유리할 수 있습니다.
예를 들어, 가계도에서 아직 살아있는 나무에서 누군가를 찾고 있다면 그 사람이 나무 아래에 있다고 가정하는 것이 안전합니다. 이것은 BFS가 마지막 레벨에 도달하는 데 시간이 오래 걸린다는 것을 의미합니다. 그러나 DFS는 목표를 더 빨리 찾을 수 있습니다. 그러나 아주 오래 전에 죽은 가족을 찾고 있다면 그 사람은 나무 꼭대기에 더 가깝습니다. 그러면 BFS는 일반적으로 DFS보다 빠릅니다. 따라서 데이터와 찾고있는 내용에 따라 장점이 달라집니다.
또 다른 예는 Facebook입니다. 친구의 친구에 대한 제안. BFS를 사용할 수있는 곳을 제안하려면 즉시 친구가 필요합니다. DFS를 사용할 수있는 가장 짧은 경로를 찾거나 순환을 감지 (재귀 사용) 할 수 있습니다.
DFS는 BFS보다 공간 효율적이지만 불필요한 깊이로 이동할 수 있습니다.
그들의 이름은 밝힙니다 : 큰 폭 (즉, 큰 분기 인자)이 있지만 깊이가 매우 제한적인 경우 (예 : 제한된 "이동 수") DFS가 BFS보다 선호 될 수 있습니다.
DFS의 공간 효율을 결합한 덜 알려진 변형이 있지만 (누적) BFS의 레벨 순서 방문은 반복 심화 깊이 우선 검색 입니다. 이 알고리즘은 일부 노드를 다시 방문하지만 점근 적 차이의 일정한 요인에만 기여합니다.
프로그래머 로서이 질문에 접근 할 때 한 가지 요소가 눈에.니다. 재귀를 사용 하는 경우 아직 탐색 할 노드가 포함 된 추가 데이터 구조를 유지할 필요가 없기 때문에 깊이 우선 검색 을 구현하는 것이 더 간단 합니다.
노드에 "이미 방문한"정보를 저장하는 경우 방향이없는 그래프에 대한 깊이 우선 검색은 다음과 같습니다.
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())
이것을 우선 검색과 비교하면 아직 방문하지 않은 노드 목록에 대해 별도의 데이터 구조를 유지해야합니다.
BFS의 중요한 장점 중 하나는 비가 중 그래프에서 두 노드 사이의 최단 경로를 찾는 데 사용할 수 있다는 것입니다. 반면 DFS는 같은 용도로 사용할 수 없습니다 .
BFS의 경우 Facebook 예제를 고려할 수 있습니다. 다른 친구 프로필의 FB 프로필에서 친구를 추가하라는 제안을받습니다. A-> B, B-> E 및 B-> F라고 가정하면 A는 E 및 F에 대한 제안을 받게됩니다. 두 번째 레벨까지 읽으려면 BFS를 사용해야합니다. DFS는 소스에서 대상까지의 데이터를 기반으로 무언가를 예측하려는 시나리오를 기반으로합니다. 이미 체스 또는 스도쿠에 대해 언급했듯이. 여기서 내가 다른 점은 DFS가 전체 경로를 먼저 다루고 최선을 결정할 수 있기 때문에 DFS를 최단 경로로 사용해야한다고 생각합니다. 그러나 BFS는 탐욕스러운 접근 방식을 사용하므로 최단 경로처럼 보일 수 있지만 최종 결과는 다를 수 있습니다. 내 이해가 잘못되었는지 알려주세요.
간단히 말해서 :
이름 "Breadth"에서 너비 우선 탐색 (BFS) 알고리즘은 노드의 바깥 쪽 가장자리를 통해 노드의 모든 이웃을 발견 한 다음, 바깥 쪽 가장자리를 통해 이전에 언급 한 이웃의 방문하지 않은 이웃을 모두 발견합니다. 원래 소스에서 도달 할 수있는 노드를 방문합니다 (방문되지 않은 노드 등이 남아있는 경우 계속해서 다른 오리지널 소스를 사용할 수 있음). 따라서 에지의 가중치가 균일 한 경우 노드 (원본 소스)에서 다른 노드로의 최단 경로 (있는 경우)를 찾는 데 사용할 수 있습니다.
"Depth"라는 이름의 DFS (Depth First Search) 알고리즘은 가장 최근에 발견 된 노드 x의 방문하지 않은 이웃을 바깥 쪽 가장자리를 통해 발견합니다. 노드 x에서 미 방문 이웃이없는 경우, 알고리즘 x은 노드 x가 발견 된 노드의 바깥 쪽을 통해 노드의 미 방문 이웃을 발견하기 위해 추적합니다. (방문되지 않은 노드 등이 남아 있으면 다른 원본 소스를 계속 사용할 수 있습니다).
BFS와 DFS 모두 불완전 할 수 있습니다. 예를 들어 노드의 분기 계수가 무한하거나 자원 (메모리)이 지원하기에 매우 큰 경우 (예 : 다음에 발견 할 노드를 저장하는 경우) 검색된 키가 멀리 떨어져 있어도 BFS가 완료되지 않습니다 오리지널 소스에서 약간의 가장자리. 이 무한 분기 요소는 주어진 노드에서 발견 할 무한 선택 (이웃 노드) 때문일 수 있습니다. 깊이가 무한하거나 자원 (메모리)이 지원하기에 매우 큰 경우 (예 : 다음에 발견 할 노드를 저장하는 경우), 검색된 키가 원래 소스의 세 번째 이웃 일 수 있지만 DFS는 완료되지 않습니다. 이 무한 깊이는 알고리즘이 발견 한 모든 노드에 대해 이전에 방문하지 않은 새로운 선택 (이웃 노드)이있는 상황으로 인해 발생할 수 있습니다.
따라서 BFS 및 DFS 사용시기를 결정할 수 있습니다. 관리 가능한 제한 분기 요소와 관리 가능한 제한 깊이를 처리한다고 가정합니다. 검색된 노드가 얕 으면 (예 : 원본 소스에서 일부 가장자리 이후에 도달 할 수있는 경우) BFS를 사용하는 것이 좋습니다. 반면에, 검색된 노드가 원래 소스로부터 많은 에지 후에 도달 할 수있는 경우 DFS를 사용하는 것이 좋습니다.
예를 들어, 소셜 네트워크에서 특정 사람과 비슷한 관심사를 가진 사람들을 검색하려는 경우이 사람들의 BFS를 오리지널 소스로 적용 할 수 있습니다. 대부분의 사람들은 그의 직접적인 친구 또는 친구의 친구입니다. 또는 두 개의 가장자리. 반면에 특정인과 완전히 다른 관심사를 가진 사람들을 검색하려면이 사람의 DFS를 오리지널 소스로 적용 할 수 있습니다. 왜냐하면 대부분이 사람들은 그와 매우 거리가 멀기 때문입니다. .... 즉 가장자리가 너무 많습니다.
BFS 및 DFS의 응용 프로그램은 각 검색 기능에 따라 달라질 수 있습니다. 예를 들어, 노드가있을 수있는 정보가없는 한 노드에서 다른 노드로의 도달 가능성을 확인하려는 경우 BFS (분기 요소를 관리 할 수 있다고 가정) 또는 DFS (깊이를 관리 할 수 있다고 가정)를 사용할 수 있습니다. 또한 두 가지 모두 그래프의 토폴로지 정렬과 같은 동일한 작업을 해결할 수 있습니다 (있는 경우). BFS를 사용하여 노드 (오리지널 소스)에서 다른 노드까지 단위 가중치 가장자리가있는 최단 경로를 찾을 수 있습니다. 반면에 DFS는 비순환 그래프에서 두 노드 사이의 가장 긴 경로를 찾는 것과 같이 심도있는 특성으로 인해 모든 선택을 다 사용하는 데 사용될 수 있습니다. 또한 DFS는 그래프에서 사이클 감지에 사용될 수 있습니다.
결국 우리는 무한 깊이와 무한 분기 요소가 있다면 IDS (Iterative Deepening Search)를 사용할 수 있습니다.
이는 특정 경우에 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,